diff --git a/Android.mk b/Android.mk
index 4d567df..b9157fe 100644
--- a/Android.mk
+++ b/Android.mk
@@ -38,7 +38,6 @@
        core/java/android/content/EventLogTags.logtags \
        core/java/android/speech/tts/EventLogTags.logtags \
        core/java/android/webkit/EventLogTags.logtags \
-       telephony/java/com/android/internal/telephony/EventLogTags.logtags \
 
 # The following filters out code we are temporarily not including at all.
 # TODO: Move AWT and beans (and associated harmony code) back into libcore.
@@ -204,12 +203,10 @@
 	telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
 	telephony/java/com/android/internal/telephony/ITelephony.aidl \
 	telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
-	telephony/java/com/android/internal/telephony/IIccPhoneBook.aidl \
-	telephony/java/com/android/internal/telephony/ISms.aidl \
 	telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
+	telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl \
 	wifi/java/android/net/wifi/IWifiManager.aidl \
 	wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl \
-	telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl \
 	voip/java/android/net/sip/ISipSession.aidl \
 	voip/java/android/net/sip/ISipSessionListener.aidl \
 	voip/java/android/net/sip/ISipService.aidl
@@ -339,7 +336,9 @@
 include external/junit/Common.mk
 
 non_base_dirs := \
-	../../external/apache-http/src/org/apache/http
+	../../external/apache-http/src/org/apache/http \
+	../opt/telephony/src/java/android/telephony \
+	../opt/telephony/src/java/android/telephony/gsm \
 
 # These are relative to frameworks/base
 dirs_to_check_apis := \
@@ -390,6 +389,8 @@
 			core \
 			ext \
 			framework \
+			mms-common \
+			telephony-common \
 
 framework_docs_LOCAL_MODULE_CLASS := JAVA_LIBRARIES
 framework_docs_LOCAL_DROIDDOC_HTML_DIR := docs/html
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 0d8a7cda..61e5b4c 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -133,6 +133,7 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/accessibilityservice/IAccessibilityServiceClientCallback.P)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/accessibilityservice/IAccessibilityServiceClient.P)
 $(call add-clean-step, rm -f $(PRODUCT_OUT)/system/media/video/Disco*)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/api/current.txt b/api/current.txt
index bc97e81..b5fd82b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -20282,6 +20282,7 @@
   public class CdmaCellLocation extends android.telephony.CellLocation {
     ctor public CdmaCellLocation();
     ctor public CdmaCellLocation(android.os.Bundle);
+    method public static double convertQuartSecToDecDegrees(int);
     method public void fillInNotifierBundle(android.os.Bundle);
     method public int getBaseStationId();
     method public int getBaseStationLatitude();
@@ -21525,9 +21526,9 @@
     method public static java.lang.String formatElapsedTime(long);
     method public static java.lang.String formatElapsedTime(java.lang.StringBuilder, long);
     method public static final java.lang.CharSequence formatSameDayTime(long, long, int, int);
-    method public static java.lang.String getAMPMString(int);
-    method public static java.lang.String getDayOfWeekString(int, int);
-    method public static java.lang.String getMonthString(int, int);
+    method public static deprecated java.lang.String getAMPMString(int);
+    method public static deprecated java.lang.String getDayOfWeekString(int, int);
+    method public static deprecated java.lang.String getMonthString(int, int);
     method public static java.lang.CharSequence getRelativeDateTimeString(android.content.Context, long, long, long, int);
     method public static java.lang.CharSequence getRelativeTimeSpanString(long);
     method public static java.lang.CharSequence getRelativeTimeSpanString(long, long, long);
@@ -21535,24 +21536,24 @@
     method public static java.lang.CharSequence getRelativeTimeSpanString(android.content.Context, long, boolean);
     method public static java.lang.CharSequence getRelativeTimeSpanString(android.content.Context, long);
     method public static boolean isToday(long);
-    field public static final java.lang.String ABBREV_MONTH_FORMAT = "%b";
+    field public static final deprecated java.lang.String ABBREV_MONTH_FORMAT = "%b";
     field public static final java.lang.String ABBREV_WEEKDAY_FORMAT = "%a";
     field public static final long DAY_IN_MILLIS = 86400000L; // 0x5265c00L
-    field public static final int FORMAT_12HOUR = 64; // 0x40
-    field public static final int FORMAT_24HOUR = 128; // 0x80
+    field public static final deprecated int FORMAT_12HOUR = 64; // 0x40
+    field public static final deprecated int FORMAT_24HOUR = 128; // 0x80
     field public static final int FORMAT_ABBREV_ALL = 524288; // 0x80000
     field public static final int FORMAT_ABBREV_MONTH = 65536; // 0x10000
     field public static final int FORMAT_ABBREV_RELATIVE = 262144; // 0x40000
     field public static final int FORMAT_ABBREV_TIME = 16384; // 0x4000
     field public static final int FORMAT_ABBREV_WEEKDAY = 32768; // 0x8000
-    field public static final int FORMAT_CAP_AMPM = 256; // 0x100
-    field public static final int FORMAT_CAP_MIDNIGHT = 4096; // 0x1000
-    field public static final int FORMAT_CAP_NOON = 1024; // 0x400
-    field public static final int FORMAT_CAP_NOON_MIDNIGHT = 5120; // 0x1400
+    field public static final deprecated int FORMAT_CAP_AMPM = 256; // 0x100
+    field public static final deprecated int FORMAT_CAP_MIDNIGHT = 4096; // 0x1000
+    field public static final deprecated int FORMAT_CAP_NOON = 1024; // 0x400
+    field public static final deprecated int FORMAT_CAP_NOON_MIDNIGHT = 5120; // 0x1400
     field public static final int FORMAT_NO_MIDNIGHT = 2048; // 0x800
     field public static final int FORMAT_NO_MONTH_DAY = 32; // 0x20
     field public static final int FORMAT_NO_NOON = 512; // 0x200
-    field public static final int FORMAT_NO_NOON_MIDNIGHT = 2560; // 0xa00
+    field public static final deprecated int FORMAT_NO_NOON_MIDNIGHT = 2560; // 0xa00
     field public static final int FORMAT_NO_YEAR = 8; // 0x8
     field public static final int FORMAT_NUMERIC_DATE = 131072; // 0x20000
     field public static final int FORMAT_SHOW_DATE = 16; // 0x10
@@ -21561,12 +21562,12 @@
     field public static final int FORMAT_SHOW_YEAR = 4; // 0x4
     field public static final deprecated int FORMAT_UTC = 8192; // 0x2000
     field public static final long HOUR_IN_MILLIS = 3600000L; // 0x36ee80L
-    field public static final java.lang.String HOUR_MINUTE_24 = "%H:%M";
-    field public static final int LENGTH_LONG = 10; // 0xa
-    field public static final int LENGTH_MEDIUM = 20; // 0x14
-    field public static final int LENGTH_SHORT = 30; // 0x1e
-    field public static final int LENGTH_SHORTER = 40; // 0x28
-    field public static final int LENGTH_SHORTEST = 50; // 0x32
+    field public static final deprecated java.lang.String HOUR_MINUTE_24 = "%H:%M";
+    field public static final deprecated int LENGTH_LONG = 10; // 0xa
+    field public static final deprecated int LENGTH_MEDIUM = 20; // 0x14
+    field public static final deprecated int LENGTH_SHORT = 30; // 0x1e
+    field public static final deprecated int LENGTH_SHORTER = 40; // 0x28
+    field public static final deprecated int LENGTH_SHORTEST = 50; // 0x32
     field public static final long MINUTE_IN_MILLIS = 60000L; // 0xea60L
     field public static final java.lang.String MONTH_DAY_FORMAT = "%-d";
     field public static final java.lang.String MONTH_FORMAT = "%B";
@@ -21577,8 +21578,8 @@
     field public static final java.lang.String YEAR_FORMAT = "%Y";
     field public static final java.lang.String YEAR_FORMAT_TWO_DIGITS = "%g";
     field public static final long YEAR_IN_MILLIS = 31449600000L; // 0x7528ad000L
-    field public static final int[] sameMonthTable;
-    field public static final int[] sameYearTable;
+    field public static final deprecated int[] sameMonthTable;
+    field public static final deprecated int[] sameYearTable;
   }
 
   public final class Formatter {
@@ -24096,6 +24097,7 @@
     method public long getDrawingTime();
     method public boolean getFilterTouchesWhenObscured();
     method public boolean getFitsSystemWindows();
+    method public void getFocusRect(android.graphics.Rect);
     method public java.util.ArrayList<android.view.View> getFocusables(int);
     method public void getFocusedRect(android.graphics.Rect);
     method public boolean getGlobalVisibleRect(android.graphics.Rect, android.graphics.Point);
diff --git a/cmds/installd/Android.mk b/cmds/installd/Android.mk
index f277339..3e722ea 100644
--- a/cmds/installd/Android.mk
+++ b/cmds/installd/Android.mk
@@ -34,6 +34,12 @@
 LOCAL_STATIC_LIBRARIES := \
     libdiskusage
 
+ifeq ($(HAVE_SELINUX),true)
+LOCAL_C_INCLUDES += external/libselinux/include
+LOCAL_SHARED_LIBRARIES += libselinux
+LOCAL_CFLAGS := -DHAVE_SELINUX
+endif # HAVE_SELINUX
+
 LOCAL_MODULE := installd
 
 LOCAL_MODULE_TAGS := optional
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index a509156..41e7b8d 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -17,6 +17,10 @@
 #include "installd.h"
 #include <diskusage/dirsize.h>
 
+#ifdef HAVE_SELINUX
+#include <selinux/android.h>
+#endif
+
 /* Directory records that are used in execution of commands. */
 dir_rec_t android_data_dir;
 dir_rec_t android_asec_dir;
@@ -72,12 +76,31 @@
         return -errno;
     }
 
+#ifdef HAVE_SELINUX
+    if (selinux_android_setfilecon(libdir, pkgname, AID_SYSTEM) < 0) {
+        ALOGE("cannot setfilecon dir '%s': %s\n", libdir, strerror(errno));
+        unlink(libdir);
+        unlink(pkgdir);
+        return -errno;
+    }
+#endif
+
     if (chown(pkgdir, uid, gid) < 0) {
         ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
         unlink(libdir);
         unlink(pkgdir);
         return -errno;
     }
+
+#ifdef HAVE_SELINUX
+    if (selinux_android_setfilecon(pkgdir, pkgname, uid) < 0) {
+        ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
+        unlink(libdir);
+        unlink(pkgdir);
+        return -errno;
+    }
+#endif
+
     return 0;
 }
 
@@ -175,6 +198,15 @@
         unlink(pkgdir);
         return -errno;
     }
+
+#ifdef HAVE_SELINUX
+    if (selinux_android_setfilecon(pkgdir, pkgname, uid) < 0) {
+        ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
+        unlink(pkgdir);
+        return -errno;
+    }
+#endif
+
     return 0;
 }
 
@@ -366,12 +398,18 @@
         ALOGE("failed to chgrp '%s': %s\n", pkgpath, strerror(errno));
         return -1;
     }
-
     if (chmod(pkgpath, S_IRUSR|S_IWUSR|S_IRGRP) < 0) {
         ALOGE("failed to chmod '%s': %s\n", pkgpath, strerror(errno));
         return -1;
     }
 
+#ifdef HAVE_SELINUX
+    if (selinux_android_setfilecon(pkgpath, pkgname, s.st_uid) < 0) {
+        ALOGE("cannot setfilecon dir '%s': %s\n", pkgpath, strerror(errno));
+        return -1;
+    }
+#endif
+
     return 0;
 }
 
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 7242029..b7e0683a 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4728,13 +4728,14 @@
         Process.setArgV0("<pre-initialized>");
 
         Looper.prepareMainLooper();
-        if (sMainThreadHandler == null) {
-            sMainThreadHandler = new Handler();
-        }
 
         ActivityThread thread = new ActivityThread();
         thread.attach(false);
 
+        if (sMainThreadHandler == null) {
+            sMainThreadHandler = thread.getHandler();
+        }
+
         AsyncTask.init();
 
         if (false) {
diff --git a/core/java/android/app/Application.java b/core/java/android/app/Application.java
index dd9ea26..3a67cec 100644
--- a/core/java/android/app/Application.java
+++ b/core/java/android/app/Application.java
@@ -64,11 +64,12 @@
     }
 
     /**
-     * Called when the application is starting, before any other application
-     * objects have been created.  Implementations should be as quick as
-     * possible (for example using lazy initialization of state) since the time
-     * spent in this function directly impacts the performance of starting the
-     * first activity, service, or receiver in a process.
+     * Called when the application is starting, before any activity, service,
+     * or receiver objects (excluding content providers) have been created.
+     * Implementations should be as quick as possible (for example using 
+     * lazy initialization of state) since the time spent in this function
+     * directly impacts the performance of starting the first activity,
+     * service, or receiver in a process.
      * If you override this method, be sure to call super.onCreate().
      */
     public void onCreate() {
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 3e726e0..8e6278d 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -385,6 +385,7 @@
 
         case SCHEDULE_LOW_MEMORY_TRANSACTION:
         {
+            data.enforceInterface(IApplicationThread.descriptor);
             scheduleLowMemory();
             return true;
         }
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index 17700f9..0b1c524 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -344,6 +344,13 @@
          */
         public static final int NETWORK_WIFI = 1 << 1;
 
+        /**
+         * Bit flag for {@link #setAllowedNetworkTypes} corresponding to
+         * {@link ConnectivityManager#TYPE_BLUETOOTH}.
+         * @hide
+         */
+        public static final int NETWORK_BLUETOOTH = 1 << 2;
+
         private Uri mUri;
         private Uri mDestinationUri;
         private List<Pair<String, String>> mRequestHeaders = new ArrayList<Pair<String, String>>();
diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java
index 615e8ce..201d7b2 100644
--- a/core/java/android/app/SharedPreferencesImpl.java
+++ b/core/java/android/app/SharedPreferencesImpl.java
@@ -17,7 +17,6 @@
 package android.app;
 
 import android.content.SharedPreferences;
-import android.os.FileUtils.FileStatus;
 import android.os.FileUtils;
 import android.os.Looper;
 import android.util.Log;
@@ -45,6 +44,11 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
 
+import libcore.io.ErrnoException;
+import libcore.io.IoUtils;
+import libcore.io.Libcore;
+import libcore.io.StructStat;
+
 final class SharedPreferencesImpl implements SharedPreferences {
     private static final String TAG = "SharedPreferencesImpl";
     private static final boolean DEBUG = false;
@@ -105,26 +109,32 @@
         }
 
         Map map = null;
-        FileStatus stat = new FileStatus();
-        if (FileUtils.getFileStatus(mFile.getPath(), stat) && mFile.canRead()) {
-            try {
-                BufferedInputStream str = new BufferedInputStream(
-                        new FileInputStream(mFile), 16*1024);
-                map = XmlUtils.readMapXml(str);
-                str.close();
-            } catch (XmlPullParserException e) {
-                Log.w(TAG, "getSharedPreferences", e);
-            } catch (FileNotFoundException e) {
-                Log.w(TAG, "getSharedPreferences", e);
-            } catch (IOException e) {
-                Log.w(TAG, "getSharedPreferences", e);
+        StructStat stat = null;
+        try {
+            stat = Libcore.os.stat(mFile.getPath());
+            if (mFile.canRead()) {
+                BufferedInputStream str = null;
+                try {
+                    str = new BufferedInputStream(
+                            new FileInputStream(mFile), 16*1024);
+                    map = XmlUtils.readMapXml(str);
+                } catch (XmlPullParserException e) {
+                    Log.w(TAG, "getSharedPreferences", e);
+                } catch (FileNotFoundException e) {
+                    Log.w(TAG, "getSharedPreferences", e);
+                } catch (IOException e) {
+                    Log.w(TAG, "getSharedPreferences", e);
+                } finally {
+                    IoUtils.closeQuietly(str);
+                }
             }
+        } catch (ErrnoException e) {
         }
         mLoaded = true;
         if (map != null) {
             mMap = map;
-            mStatTimestamp = stat.mtime;
-            mStatSize = stat.size;
+            mStatTimestamp = stat.st_mtime;
+            mStatSize = stat.st_size;
         } else {
             mMap = new HashMap<String, Object>();
         }
@@ -155,12 +165,21 @@
                 return false;
             }
         }
-        FileStatus stat = new FileStatus();
-        if (!FileUtils.getFileStatus(mFile.getPath(), stat)) {
+
+        final StructStat stat;
+        try {
+            /*
+             * Metadata operations don't usually count as a block guard
+             * violation, but we explicitly want this one.
+             */
+            BlockGuard.getThreadPolicy().onReadFromDisk();
+            stat = Libcore.os.stat(mFile.getPath());
+        } catch (ErrnoException e) {
             return true;
         }
+
         synchronized (this) {
-            return mStatTimestamp != stat.mtime || mStatSize != stat.size;
+            return mStatTimestamp != stat.st_mtime || mStatSize != stat.st_size;
         }
     }
 
@@ -577,12 +596,14 @@
             FileUtils.sync(str);
             str.close();
             ContextImpl.setFilePermissionsFromMode(mFile.getPath(), mMode, 0);
-            FileStatus stat = new FileStatus();
-            if (FileUtils.getFileStatus(mFile.getPath(), stat)) {
+            try {
+                final StructStat stat = Libcore.os.stat(mFile.getPath());
                 synchronized (this) {
-                    mStatTimestamp = stat.mtime;
-                    mStatSize = stat.size;
+                    mStatTimestamp = stat.st_mtime;
+                    mStatSize = stat.st_size;
                 }
+            } catch (ErrnoException e) {
+                // Do nothing
             }
             // Writing was successful, delete the backup file if there is one.
             mBackupFile.delete();
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
old mode 100644
new mode 100755
index 4ed0766..0b58396
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1008,13 +1008,15 @@
     /**
      * Ask the user date be wiped.  This will cause the device to reboot,
      * erasing all user data while next booting up.  External storage such
-     * as SD cards will not be erased.
+     * as SD cards will be also erased if the flag {@link #WIPE_EXTERNAL_STORAGE}
+     * is set.
      *
      * <p>The calling device admin must have requested
      * {@link DeviceAdminInfo#USES_POLICY_WIPE_DATA} to be able to call
      * this method; if it has not, a security exception will be thrown.
      *
-     * @param flags Bit mask of additional options: currently must be 0.
+     * @param flags Bit mask of additional options: currently 0 and
+     *              {@link #WIPE_EXTERNAL_STORAGE} are supported.
      */
     public void wipeData(int flags) {
         if (mService != null) {
diff --git a/core/java/android/bluetooth/BluetoothDeviceProfileState.java b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
index c9603bf..020f051 100644
--- a/core/java/android/bluetooth/BluetoothDeviceProfileState.java
+++ b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
@@ -304,6 +304,25 @@
         }
     }
 
+    @Override
+    protected void onQuitting() {
+        mContext.unregisterReceiver(mBroadcastReceiver);
+        mBroadcastReceiver = null;
+        mAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mHeadsetService);
+        mBluetoothProfileServiceListener = null;
+        mOutgoingHandsfree = null;
+        mPbap = null;
+        mPbapService.close();
+        mPbapService = null;
+        mIncomingHid = null;
+        mOutgoingHid = null;
+        mIncomingHandsfree = null;
+        mOutgoingHandsfree = null;
+        mIncomingA2dp = null;
+        mOutgoingA2dp = null;
+        mBondedDevice = null;
+    }
+
     private class BondedDevice extends State {
         @Override
         public void enter() {
@@ -416,26 +435,6 @@
                 case TRANSITION_TO_STABLE:
                     // ignore.
                     break;
-                case SM_QUIT_CMD:
-                    mContext.unregisterReceiver(mBroadcastReceiver);
-                    mBroadcastReceiver = null;
-                    mAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mHeadsetService);
-                    mBluetoothProfileServiceListener = null;
-                    mOutgoingHandsfree = null;
-                    mPbap = null;
-                    mPbapService.close();
-                    mPbapService = null;
-                    mIncomingHid = null;
-                    mOutgoingHid = null;
-                    mIncomingHandsfree = null;
-                    mOutgoingHandsfree = null;
-                    mIncomingA2dp = null;
-                    mOutgoingA2dp = null;
-                    mBondedDevice = null;
-                    // There is a problem in the State Machine code
-                    // where things are not cleaned up properly, when quit message
-                    // is handled so return NOT_HANDLED as a workaround.
-                    return NOT_HANDLED;
                 default:
                     return NOT_HANDLED;
             }
@@ -1341,6 +1340,15 @@
         return mDevice;
     }
 
+    /**
+     * Quit the state machine, only to be called by BluetoothService.
+     *
+     * @hide
+     */
+    public void doQuit() {
+        this.quit();
+    }
+
     private void log(String message) {
         if (DBG) {
             Log.i(TAG, "Device:" + mDevice + " Message:" + message);
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index 226e107..7a9fc65 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -26,6 +26,7 @@
 
 import android.accounts.Account;
 import android.accounts.AccountAndUser;
+import android.content.res.Resources;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteException;
@@ -337,6 +338,7 @@
 
     private int mNextHistoryId = 0;
     private SparseArray<Boolean> mMasterSyncAutomatically = new SparseArray<Boolean>();
+    private boolean mDefaultMasterSyncAutomatically;
 
     private OnSyncRequestListener mSyncRequestListener;
 
@@ -346,6 +348,9 @@
 
         mCal = Calendar.getInstance(TimeZone.getTimeZone("GMT+0"));
 
+        mDefaultMasterSyncAutomatically = mContext.getResources().getBoolean(
+               com.android.internal.R.bool.config_syncstorageengine_masterSyncAutomatically);
+
         File systemDir = new File(dataDir, "system");
         File syncDir = new File(systemDir, "sync");
         syncDir.mkdirs();
@@ -781,7 +786,7 @@
     public boolean getMasterSyncAutomatically(int userId) {
         synchronized (mAuthorities) {
             Boolean auto = mMasterSyncAutomatically.get(userId);
-            return auto == null ? true : auto;
+            return auto == null ? mDefaultMasterSyncAutomatically : auto;
         }
     }
 
diff --git a/core/java/android/database/AbstractCursor.java b/core/java/android/database/AbstractCursor.java
index fb04817..e7ff92d 100644
--- a/core/java/android/database/AbstractCursor.java
+++ b/core/java/android/database/AbstractCursor.java
@@ -424,6 +424,9 @@
         if (mSelfObserver != null && mSelfObserverRegistered == true) {
             mContentResolver.unregisterContentObserver(mSelfObserver);
         }
+        try {
+            if (!mClosed) close();
+        } catch(Exception e) { }
     }
 
     /**
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 4d9077f..829620b 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -26,6 +26,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.util.Log;
+import android.text.TextUtils;
 import android.view.Surface;
 import android.view.SurfaceHolder;
 
@@ -34,7 +35,6 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
-import java.util.StringTokenizer;
 import java.util.concurrent.locks.ReentrantLock;
 
 /**
@@ -1905,7 +1905,7 @@
         private HashMap<String, String> mMap;
 
         private Parameters() {
-            mMap = new HashMap<String, String>();
+            mMap = new HashMap<String, String>(64);
         }
 
         /**
@@ -1929,7 +1929,7 @@
          *         semi-colon delimited key-value pairs
          */
         public String flatten() {
-            StringBuilder flattened = new StringBuilder();
+            StringBuilder flattened = new StringBuilder(128);
             for (String k : mMap.keySet()) {
                 flattened.append(k);
                 flattened.append("=");
@@ -1952,9 +1952,9 @@
         public void unflatten(String flattened) {
             mMap.clear();
 
-            StringTokenizer tokenizer = new StringTokenizer(flattened, ";");
-            while (tokenizer.hasMoreElements()) {
-                String kv = tokenizer.nextToken();
+            TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(';');
+            splitter.setString(flattened);
+            for (String kv : splitter) {
                 int pos = kv.indexOf('=');
                 if (pos == -1) {
                     continue;
@@ -3488,11 +3488,11 @@
         private ArrayList<String> split(String str) {
             if (str == null) return null;
 
-            // Use StringTokenizer because it is faster than split.
-            StringTokenizer tokenizer = new StringTokenizer(str, ",");
+            TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
+            splitter.setString(str);
             ArrayList<String> substrings = new ArrayList<String>();
-            while (tokenizer.hasMoreElements()) {
-                substrings.add(tokenizer.nextToken());
+            for (String s : splitter) {
+                substrings.add(s);
             }
             return substrings;
         }
@@ -3502,11 +3502,11 @@
         private ArrayList<Integer> splitInt(String str) {
             if (str == null) return null;
 
-            StringTokenizer tokenizer = new StringTokenizer(str, ",");
+            TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
+            splitter.setString(str);
             ArrayList<Integer> substrings = new ArrayList<Integer>();
-            while (tokenizer.hasMoreElements()) {
-                String token = tokenizer.nextToken();
-                substrings.add(Integer.parseInt(token));
+            for (String s : splitter) {
+                substrings.add(Integer.parseInt(s));
             }
             if (substrings.size() == 0) return null;
             return substrings;
@@ -3515,11 +3515,11 @@
         private void splitInt(String str, int[] output) {
             if (str == null) return;
 
-            StringTokenizer tokenizer = new StringTokenizer(str, ",");
+            TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
+            splitter.setString(str);
             int index = 0;
-            while (tokenizer.hasMoreElements()) {
-                String token = tokenizer.nextToken();
-                output[index++] = Integer.parseInt(token);
+            for (String s : splitter) {
+                output[index++] = Integer.parseInt(s);
             }
         }
 
@@ -3527,11 +3527,11 @@
         private void splitFloat(String str, float[] output) {
             if (str == null) return;
 
-            StringTokenizer tokenizer = new StringTokenizer(str, ",");
+            TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
+            splitter.setString(str);
             int index = 0;
-            while (tokenizer.hasMoreElements()) {
-                String token = tokenizer.nextToken();
-                output[index++] = Float.parseFloat(token);
+            for (String s : splitter) {
+                output[index++] = Float.parseFloat(s);
             }
         }
 
@@ -3558,10 +3558,11 @@
         private ArrayList<Size> splitSize(String str) {
             if (str == null) return null;
 
-            StringTokenizer tokenizer = new StringTokenizer(str, ",");
+            TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
+            splitter.setString(str);
             ArrayList<Size> sizeList = new ArrayList<Size>();
-            while (tokenizer.hasMoreElements()) {
-                Size size = strToSize(tokenizer.nextToken());
+            for (String s : splitter) {
+                Size size = strToSize(s);
                 if (size != null) sizeList.add(size);
             }
             if (sizeList.size() == 0) return null;
diff --git a/core/java/android/net/DhcpStateMachine.java b/core/java/android/net/DhcpStateMachine.java
index 397a12a..cc3e34f 100644
--- a/core/java/android/net/DhcpStateMachine.java
+++ b/core/java/android/net/DhcpStateMachine.java
@@ -163,8 +163,21 @@
         mRegisteredForPreDhcpNotification = true;
     }
 
+    /**
+     * Quit the DhcpStateMachine.
+     *
+     * @hide
+     */
+    public void doQuit() {
+        quit();
+    }
+
     class DefaultState extends State {
         @Override
+        public void exit() {
+            mContext.unregisterReceiver(mBroadcastReceiver);
+        }
+        @Override
         public boolean processMessage(Message message) {
             if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
             switch (message.what) {
@@ -172,10 +185,6 @@
                     Log.e(TAG, "Error! Failed to handle a DHCP renewal on " + mInterfaceName);
                     mDhcpRenewWakeLock.release();
                     break;
-                case SM_QUIT_CMD:
-                    mContext.unregisterReceiver(mBroadcastReceiver);
-                    //let parent kill the state machine
-                    return NOT_HANDLED;
                 default:
                     Log.e(TAG, "Error! unhandled message  " + message);
                     break;
diff --git a/core/java/android/net/EthernetDataTracker.java b/core/java/android/net/EthernetDataTracker.java
index 28bd289..0cc78c9 100644
--- a/core/java/android/net/EthernetDataTracker.java
+++ b/core/java/android/net/EthernetDataTracker.java
@@ -223,7 +223,7 @@
                     mIface = iface;
                     mNMService.setInterfaceUp(iface);
                     InterfaceConfiguration config = mNMService.getInterfaceConfig(iface);
-                    mLinkUp = config.isActive();
+                    mLinkUp = config.hasFlag("up");
                     if (config != null && mHwAddr == null) {
                         mHwAddr = config.getHardwareAddress();
                         if (mHwAddr != null) {
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index 57f8d48..d59fa6a 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -16,11 +16,6 @@
 
 package android.net;
 
-import static com.android.internal.telephony.DataConnectionTracker.CMD_SET_POLICY_DATA_ENABLE;
-import static com.android.internal.telephony.DataConnectionTracker.CMD_SET_USER_DATA_ENABLE;
-import static com.android.internal.telephony.DataConnectionTracker.DISABLED;
-import static com.android.internal.telephony.DataConnectionTracker.ENABLED;
-
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -37,9 +32,9 @@
 import android.text.TextUtils;
 import android.util.Slog;
 
-import com.android.internal.telephony.DataConnectionTracker;
+import com.android.internal.telephony.DctConstants;
 import com.android.internal.telephony.ITelephony;
-import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.util.AsyncChannel;
 
@@ -59,7 +54,7 @@
     private static final boolean DBG = false;
     private static final boolean VDBG = false;
 
-    private Phone.DataState mMobileDataState;
+    private PhoneConstants.DataState mMobileDataState;
     private ITelephony mPhoneService;
 
     private String mApnType;
@@ -108,10 +103,10 @@
         IntentFilter filter = new IntentFilter();
         filter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
         filter.addAction(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
-        filter.addAction(DataConnectionTracker.ACTION_DATA_CONNECTION_TRACKER_MESSENGER);
+        filter.addAction(DctConstants.ACTION_DATA_CONNECTION_TRACKER_MESSENGER);
 
         mContext.registerReceiver(new MobileDataStateReceiver(), filter);
-        mMobileDataState = Phone.DataState.DISCONNECTED;
+        mMobileDataState = PhoneConstants.DataState.DISCONNECTED;
     }
 
     static class MdstHandler extends Handler {
@@ -180,7 +175,7 @@
         public void onReceive(Context context, Intent intent) {
             if (intent.getAction().equals(TelephonyIntents.
                     ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
-                String apnType = intent.getStringExtra(Phone.DATA_APN_TYPE_KEY);
+                String apnType = intent.getStringExtra(PhoneConstants.DATA_APN_TYPE_KEY);
                 if (VDBG) {
                     log(String.format("Broadcast received: ACTION_ANY_DATA_CONNECTION_STATE_CHANGED"
                         + "mApnType=%s %s received apnType=%s", mApnType,
@@ -189,20 +184,29 @@
                 if (!TextUtils.equals(apnType, mApnType)) {
                     return;
                 }
-                mNetworkInfo.setSubtype(TelephonyManager.getDefault().getNetworkType(),
-                        TelephonyManager.getDefault().getNetworkTypeName());
-                Phone.DataState state = Enum.valueOf(Phone.DataState.class,
-                        intent.getStringExtra(Phone.STATE_KEY));
-                String reason = intent.getStringExtra(Phone.STATE_CHANGE_REASON_KEY);
-                String apnName = intent.getStringExtra(Phone.DATA_APN_KEY);
-                mNetworkInfo.setRoaming(intent.getBooleanExtra(Phone.DATA_NETWORK_ROAMING_KEY,
-                        false));
+
+                int oldSubtype = mNetworkInfo.getSubtype();
+                int newSubType = TelephonyManager.getDefault().getNetworkType();
+                String subTypeName = TelephonyManager.getDefault().getNetworkTypeName();
+                mNetworkInfo.setSubtype(newSubType, subTypeName);
+                if (newSubType != oldSubtype && mNetworkInfo.isConnected()) {
+                    Message msg = mTarget.obtainMessage(EVENT_NETWORK_SUBTYPE_CHANGED,
+                                                        oldSubtype, 0, mNetworkInfo);
+                    msg.sendToTarget();
+                }
+
+                PhoneConstants.DataState state = Enum.valueOf(PhoneConstants.DataState.class,
+                        intent.getStringExtra(PhoneConstants.STATE_KEY));
+                String reason = intent.getStringExtra(PhoneConstants.STATE_CHANGE_REASON_KEY);
+                String apnName = intent.getStringExtra(PhoneConstants.DATA_APN_KEY);
+                mNetworkInfo.setRoaming(intent.getBooleanExtra(
+                        PhoneConstants.DATA_NETWORK_ROAMING_KEY, false));
                 if (VDBG) {
                     log(mApnType + " setting isAvailable to " +
-                            intent.getBooleanExtra(Phone.NETWORK_UNAVAILABLE_KEY,false));
+                            intent.getBooleanExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY,false));
                 }
-                mNetworkInfo.setIsAvailable(!intent.getBooleanExtra(Phone.NETWORK_UNAVAILABLE_KEY,
-                        false));
+                mNetworkInfo.setIsAvailable(!intent.getBooleanExtra(
+                        PhoneConstants.NETWORK_UNAVAILABLE_KEY, false));
 
                 if (DBG) {
                     log("Received state=" + state + ", old=" + mMobileDataState +
@@ -232,13 +236,13 @@
                             break;
                         case CONNECTED:
                             mLinkProperties = intent.getParcelableExtra(
-                                    Phone.DATA_LINK_PROPERTIES_KEY);
+                                    PhoneConstants.DATA_LINK_PROPERTIES_KEY);
                             if (mLinkProperties == null) {
                                 loge("CONNECTED event did not supply link properties.");
                                 mLinkProperties = new LinkProperties();
                             }
                             mLinkCapabilities = intent.getParcelableExtra(
-                                    Phone.DATA_LINK_CAPABILITIES_KEY);
+                                    PhoneConstants.DATA_LINK_CAPABILITIES_KEY);
                             if (mLinkCapabilities == null) {
                                 loge("CONNECTED event did not supply link capabilities.");
                                 mLinkCapabilities = new LinkCapabilities();
@@ -248,8 +252,9 @@
                     }
                 } else {
                     // There was no state change. Check if LinkProperties has been updated.
-                    if (TextUtils.equals(reason, Phone.REASON_LINK_PROPERTIES_CHANGED)) {
-                        mLinkProperties = intent.getParcelableExtra(Phone.DATA_LINK_PROPERTIES_KEY);
+                    if (TextUtils.equals(reason, PhoneConstants.REASON_LINK_PROPERTIES_CHANGED)) {
+                        mLinkProperties = intent.getParcelableExtra(
+                                PhoneConstants.DATA_LINK_PROPERTIES_KEY);
                         if (mLinkProperties == null) {
                             loge("No link property in LINK_PROPERTIES change event.");
                             mLinkProperties = new LinkProperties();
@@ -264,7 +269,7 @@
                 }
             } else if (intent.getAction().
                     equals(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED)) {
-                String apnType = intent.getStringExtra(Phone.DATA_APN_TYPE_KEY);
+                String apnType = intent.getStringExtra(PhoneConstants.DATA_APN_TYPE_KEY);
                 if (!TextUtils.equals(apnType, mApnType)) {
                     if (DBG) {
                         log(String.format(
@@ -273,17 +278,18 @@
                     }
                     return;
                 }
-                String reason = intent.getStringExtra(Phone.FAILURE_REASON_KEY);
-                String apnName = intent.getStringExtra(Phone.DATA_APN_KEY);
+                String reason = intent.getStringExtra(PhoneConstants.FAILURE_REASON_KEY);
+                String apnName = intent.getStringExtra(PhoneConstants.DATA_APN_KEY);
                 if (DBG) {
                     log("Received " + intent.getAction() +
                                 " broadcast" + reason == null ? "" : "(" + reason + ")");
                 }
                 setDetailedState(DetailedState.FAILED, reason, apnName);
-            } else if (intent.getAction().
-                    equals(DataConnectionTracker.ACTION_DATA_CONNECTION_TRACKER_MESSENGER)) {
+            } else if (intent.getAction().equals(DctConstants
+                    .ACTION_DATA_CONNECTION_TRACKER_MESSENGER)) {
                 if (VDBG) log(mApnType + " got ACTION_DATA_CONNECTION_TRACKER_MESSENGER");
-                mMessenger = intent.getParcelableExtra(DataConnectionTracker.EXTRA_MESSENGER);
+                mMessenger =
+                    intent.getParcelableExtra(DctConstants.EXTRA_MESSENGER);
                 AsyncChannel ac = new AsyncChannel();
                 ac.connect(mContext, MobileDataStateTracker.this.mHandler, mMessenger);
             } else {
@@ -332,6 +338,9 @@
         case TelephonyManager.NETWORK_TYPE_HSPA:
             networkTypeStr = "hspa";
             break;
+        case TelephonyManager.NETWORK_TYPE_HSPAP:
+            networkTypeStr = "hspap";
+            break;
         case TelephonyManager.NETWORK_TYPE_CDMA:
             networkTypeStr = "cdma";
             break;
@@ -369,7 +378,7 @@
      */
     public boolean teardown() {
         setTeardownRequested(true);
-        return (setEnableApn(mApnType, false) != Phone.APN_REQUEST_FAILED);
+        return (setEnableApn(mApnType, false) != PhoneConstants.APN_REQUEST_FAILED);
     }
 
     /**
@@ -418,17 +427,17 @@
         boolean retValue = false; //connected or expect to be?
         setTeardownRequested(false);
         switch (setEnableApn(mApnType, true)) {
-            case Phone.APN_ALREADY_ACTIVE:
+            case PhoneConstants.APN_ALREADY_ACTIVE:
                 // need to set self to CONNECTING so the below message is handled.
                 retValue = true;
                 break;
-            case Phone.APN_REQUEST_STARTED:
+            case PhoneConstants.APN_REQUEST_STARTED:
                 // set IDLE here , avoid the following second FAILED not sent out
                 mNetworkInfo.setDetailedState(DetailedState.IDLE, null, null);
                 retValue = true;
                 break;
-            case Phone.APN_REQUEST_FAILED:
-            case Phone.APN_TYPE_NOT_AVAILABLE:
+            case PhoneConstants.APN_REQUEST_FAILED:
+            case PhoneConstants.APN_TYPE_NOT_AVAILABLE:
                 break;
             default:
                 loge("Error in reconnect - unexpected response.");
@@ -470,7 +479,8 @@
         if (DBG) log("setUserDataEnable: E enabled=" + enabled);
         final AsyncChannel channel = mDataConnectionTrackerAc;
         if (channel != null) {
-            channel.sendMessage(CMD_SET_USER_DATA_ENABLE, enabled ? ENABLED : DISABLED);
+            channel.sendMessage(DctConstants.CMD_SET_USER_DATA_ENABLE,
+                    enabled ? DctConstants.ENABLED : DctConstants.DISABLED);
             mUserDataEnabled = enabled;
         }
         if (VDBG) log("setUserDataEnable: X enabled=" + enabled);
@@ -481,7 +491,8 @@
         if (DBG) log("setPolicyDataEnable(enabled=" + enabled + ")");
         final AsyncChannel channel = mDataConnectionTrackerAc;
         if (channel != null) {
-            channel.sendMessage(CMD_SET_POLICY_DATA_ENABLE, enabled ? ENABLED : DISABLED);
+            channel.sendMessage(DctConstants.CMD_SET_POLICY_DATA_ENABLE,
+                    enabled ? DctConstants.ENABLED : DctConstants.DISABLED);
             mPolicyDataEnabled = enabled;
         }
     }
@@ -491,12 +502,12 @@
      * @param met
      */
     public void setDependencyMet(boolean met) {
-        Bundle bundle = Bundle.forPair(DataConnectionTracker.APN_TYPE_KEY, mApnType);
+        Bundle bundle = Bundle.forPair(DctConstants.APN_TYPE_KEY, mApnType);
         try {
             if (DBG) log("setDependencyMet: E met=" + met);
             Message msg = Message.obtain();
-            msg.what = DataConnectionTracker.CMD_SET_DEPENDENCY_MET;
-            msg.arg1 = (met ? DataConnectionTracker.ENABLED : DataConnectionTracker.DISABLED);
+            msg.what = DctConstants.CMD_SET_DEPENDENCY_MET;
+            msg.arg1 = (met ? DctConstants.ENABLED : DctConstants.DISABLED);
             msg.setData(bundle);
             mDataConnectionTrackerAc.sendMessage(msg);
             if (VDBG) log("setDependencyMet: X met=" + met);
@@ -546,27 +557,27 @@
         }
 
         loge("Could not " + (enable ? "enable" : "disable") + " APN type \"" + apnType + "\"");
-        return Phone.APN_REQUEST_FAILED;
+        return PhoneConstants.APN_REQUEST_FAILED;
     }
 
     public static String networkTypeToApnType(int netType) {
         switch(netType) {
             case ConnectivityManager.TYPE_MOBILE:
-                return Phone.APN_TYPE_DEFAULT;  // TODO - use just one of these
+                return PhoneConstants.APN_TYPE_DEFAULT;  // TODO - use just one of these
             case ConnectivityManager.TYPE_MOBILE_MMS:
-                return Phone.APN_TYPE_MMS;
+                return PhoneConstants.APN_TYPE_MMS;
             case ConnectivityManager.TYPE_MOBILE_SUPL:
-                return Phone.APN_TYPE_SUPL;
+                return PhoneConstants.APN_TYPE_SUPL;
             case ConnectivityManager.TYPE_MOBILE_DUN:
-                return Phone.APN_TYPE_DUN;
+                return PhoneConstants.APN_TYPE_DUN;
             case ConnectivityManager.TYPE_MOBILE_HIPRI:
-                return Phone.APN_TYPE_HIPRI;
+                return PhoneConstants.APN_TYPE_HIPRI;
             case ConnectivityManager.TYPE_MOBILE_FOTA:
-                return Phone.APN_TYPE_FOTA;
+                return PhoneConstants.APN_TYPE_FOTA;
             case ConnectivityManager.TYPE_MOBILE_IMS:
-                return Phone.APN_TYPE_IMS;
+                return PhoneConstants.APN_TYPE_IMS;
             case ConnectivityManager.TYPE_MOBILE_CBS:
-                return Phone.APN_TYPE_CBS;
+                return PhoneConstants.APN_TYPE_CBS;
             default:
                 sloge("Error mapping networkType " + netType + " to apnType.");
                 return null;
diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java
index 7df0193..0d6dcd6 100644
--- a/core/java/android/net/NetworkStateTracker.java
+++ b/core/java/android/net/NetworkStateTracker.java
@@ -69,6 +69,12 @@
     public static final int EVENT_RESTORE_DEFAULT_NETWORK = 6;
 
     /**
+     * msg.what = EVENT_NETWORK_SUBTYPE_CHANGED
+     * msg.obj = NetworkInfo object
+     */
+    public static final int EVENT_NETWORK_SUBTYPE_CHANGED = 7;
+
+    /**
      * -------------------------------------------------------------
      * Control Interface
      * -------------------------------------------------------------
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index fb5263d..65d3f2b 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -329,7 +329,7 @@
                 throw new IllegalArgumentException("Bad address");
             }
 
-            mAddresses.append(String.format(" %s/%d", address.getHostAddress(), prefixLength));
+            mAddresses.append(' ' + address.getHostAddress() + '/' +  prefixLength);
             return this;
         }
 
diff --git a/core/java/android/net/arp/ArpPeer.java b/core/java/android/net/arp/ArpPeer.java
index 8e666bc..6ba1e7c 100644
--- a/core/java/android/net/arp/ArpPeer.java
+++ b/core/java/android/net/arp/ArpPeer.java
@@ -53,9 +53,11 @@
         mInterfaceName = interfaceName;
         mMyAddr = myAddr;
 
-        for (int i = 0; i < MAC_ADDR_LENGTH; i++) {
-            mMyMac[i] = (byte) Integer.parseInt(mac.substring(
-                        i*3, (i*3) + 2), 16);
+        if (mac != null) {
+            for (int i = 0; i < MAC_ADDR_LENGTH; i++) {
+                mMyMac[i] = (byte) Integer.parseInt(mac.substring(
+                            i*3, (i*3) + 2), 16);
+            }
         }
 
         if (myAddr instanceof Inet6Address || peer instanceof Inet6Address) {
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 6c1445d..0941d71 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -28,9 +28,6 @@
 import java.util.zip.CRC32;
 import java.util.zip.CheckedInputStream;
 
-import libcore.io.Os;
-import libcore.io.StructStat;
-
 /**
  * Tools for managing files.  Not for public consumption.
  * @hide
@@ -50,60 +47,12 @@
     public static final int S_IROTH = 00004;
     public static final int S_IWOTH = 00002;
     public static final int S_IXOTH = 00001;
-    
-    
-    /**
-     * File status information. This class maps directly to the POSIX stat structure.
-     * @deprecated use {@link StructStat} instead.
-     * @hide
-     */
-    @Deprecated
-    public static final class FileStatus {
-        public int dev;
-        public int ino;
-        public int mode;
-        public int nlink;
-        public int uid;
-        public int gid;
-        public int rdev;
-        public long size;
-        public int blksize;
-        public long blocks;
-        public long atime;
-        public long mtime;
-        public long ctime;
-    }
-    
-    /**
-     * Get the status for the given path. This is equivalent to the POSIX stat(2) system call. 
-     * @param path The path of the file to be stat'd.
-     * @param status Optional argument to fill in. It will only fill in the status if the file
-     * exists. 
-     * @return true if the file exists and false if it does not exist. If you do not have 
-     * permission to stat the file, then this method will return false.
-     * @deprecated use {@link Os#stat(String)} instead.
-     */
-    @Deprecated
-    public static boolean getFileStatus(String path, FileStatus status) {
-        StrictMode.noteDiskRead();
-        return getFileStatusNative(path, status);
-    }
-
-    private static native boolean getFileStatusNative(String path, FileStatus status);
 
     /** Regular expression for safe filenames: no spaces or metacharacters */
     private static final Pattern SAFE_FILENAME_PATTERN = Pattern.compile("[\\w%+,./=_-]+");
 
     public static native int setPermissions(String file, int mode, int uid, int gid);
 
-    /**
-     * @deprecated use {@link Os#stat(String)} instead.
-     */
-    @Deprecated
-    public static native int getPermissions(String file, int[] outPermissions);
-
-    public static native int setUMask(int mask);
-
     /** returns the FAT file system volume ID for the volume mounted 
      * at the given mount point, or -1 for failure
      * @param mountPoint point for FAT volume
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 8eaeb1d..6ab4dc1 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -359,6 +359,7 @@
      * @param gids Additional group-ids associated with the process.
      * @param debugFlags Additional flags.
      * @param targetSdkVersion The target SDK version for the app.
+     * @param seInfo null-ok SE Android information for the new process.
      * @param zygoteArgs Additional arguments to supply to the zygote process.
      * 
      * @return An object that describes the result of the attempt to start the process.
@@ -370,10 +371,11 @@
                                   final String niceName,
                                   int uid, int gid, int[] gids,
                                   int debugFlags, int targetSdkVersion,
+                                  String seInfo,
                                   String[] zygoteArgs) {
         try {
             return startViaZygote(processClass, niceName, uid, gid, gids,
-                    debugFlags, targetSdkVersion, zygoteArgs);
+                    debugFlags, targetSdkVersion, seInfo, zygoteArgs);
         } catch (ZygoteStartFailedEx ex) {
             Log.e(LOG_TAG,
                     "Starting VM process through Zygote failed");
@@ -536,6 +538,7 @@
      * new process should setgroup() to.
      * @param debugFlags Additional flags.
      * @param targetSdkVersion The target SDK version for the app.
+     * @param seInfo null-ok SE Android information for the new process.
      * @param extraArgs Additional arguments to supply to the zygote process.
      * @return An object that describes the result of the attempt to start the process.
      * @throws ZygoteStartFailedEx if process start failed for any reason
@@ -545,6 +548,7 @@
                                   final int uid, final int gid,
                                   final int[] gids,
                                   int debugFlags, int targetSdkVersion,
+                                  String seInfo,
                                   String[] extraArgs)
                                   throws ZygoteStartFailedEx {
         synchronized(Process.class) {
@@ -595,6 +599,10 @@
                 argsForZygote.add("--nice-name=" + niceName);
             }
 
+            if (seInfo != null) {
+                argsForZygote.add("--seinfo=" + seInfo);
+            }
+
             argsForZygote.add(processClass);
 
             if (extraArgs != null) {
diff --git a/core/java/android/os/SELinux.java b/core/java/android/os/SELinux.java
new file mode 100644
index 0000000..c05a974
--- /dev/null
+++ b/core/java/android/os/SELinux.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import android.util.Slog;
+
+import java.io.IOException;
+import java.io.File;
+import java.io.FileDescriptor;
+
+/**
+ * This class provides access to the centralized jni bindings for
+ * SELinux interaction.
+ * {@hide}
+ */
+public class SELinux {
+
+    private static final String TAG = "SELinux";
+
+    /**
+     * Determine whether SELinux is disabled or enabled.
+     * @return a boolean indicating whether SELinux is enabled.
+     */
+    public static final native boolean isSELinuxEnabled();
+
+    /**
+     * Determine whether SELinux is permissive or enforcing.
+     * @return a boolean indicating whether SELinux is enforcing.
+     */
+    public static final native boolean isSELinuxEnforced();
+
+    /**
+     * Set whether SELinux is permissive or enforcing.
+     * @param boolean representing whether to set SELinux to enforcing
+     * @return a boolean representing whether the desired mode was set
+     */
+    public static final native boolean setSELinuxEnforce(boolean value);
+
+    /**
+     * Sets the security context for newly created file objects.
+     * @param context a security context given as a String.
+     * @return a boolean indicating whether the operation succeeded.
+     */
+    public static final native boolean setFSCreateContext(String context);
+
+    /**
+     * Change the security context of an existing file object.
+     * @param path representing the path of file object to relabel.
+     * @param con new security context given as a String.
+     * @return a boolean indicating whether the operation succeeded.
+     */
+    public static final native boolean setFileContext(String path, String context);
+
+    /**
+     * Get the security context of a file object.
+     * @param path the pathname of the file object.
+     * @return a security context given as a String.
+     */
+    public static final native String getFileContext(String path);
+
+    /**
+     * Get the security context of a peer socket.
+     * @param fd FileDescriptor class of the peer socket.
+     * @return a String representing the peer socket security context.
+     */
+    public static final native String getPeerContext(FileDescriptor fd);
+
+    /**
+     * Gets the security context of the current process.
+     * @return a String representing the security context of the current process.
+     */
+    public static final native String getContext();
+
+    /**
+     * Gets the security context of a given process id.
+     * Use of this function is discouraged for Binder transactions.
+     * Use Binder.getCallingSecctx() instead.
+     * @param pid an int representing the process id to check.
+     * @return a String representing the security context of the given pid.
+     */
+    public static final native String getPidContext(int pid);
+
+    /**
+     * Gets a list of the SELinux boolean names.
+     * @return an array of strings containing the SELinux boolean names.
+     */
+    public static final native String[] getBooleanNames();
+
+    /**
+     * Gets the value for the given SELinux boolean name.
+     * @param String The name of the SELinux boolean.
+     * @return a boolean indicating whether the SELinux boolean is set.
+     */
+    public static final native boolean getBooleanValue(String name);
+
+    /**
+     * Sets the value for the given SELinux boolean name.
+     * @param String The name of the SELinux boolean.
+     * @param Boolean The new value of the SELinux boolean.
+     * @return a boolean indicating whether or not the operation succeeded.
+     */
+    public static final native boolean setBooleanValue(String name, boolean value);
+
+    /**
+     * Check permissions between two security contexts.
+     * @param scon The source or subject security context.
+     * @param tcon The target or object security context.
+     * @param tclass The object security class name.
+     * @param perm The permission name.
+     * @return a boolean indicating whether permission was granted.
+     */
+    public static final native boolean checkSELinuxAccess(String scon, String tcon, String tclass, String perm);
+
+    /**
+     * Restores a file to its default SELinux security context.
+     * If the system is not compiled with SELinux, then {@code true}
+     * is automatically returned.
+     * If SELinux is compiled in, but disabled, then {@code true} is
+     * returned.
+     *
+     * @param pathname The pathname of the file to be relabeled.
+     * @return a boolean indicating whether the relabeling succeeded.
+     * @exception NullPointerException if the pathname is a null object.
+     */
+    public static boolean restorecon(String pathname) throws NullPointerException {
+        if (pathname == null) { throw new NullPointerException(); }
+        return native_restorecon(pathname);
+    }
+
+    /**
+     * Restores a file to its default SELinux security context.
+     * If the system is not compiled with SELinux, then {@code true}
+     * is automatically returned.
+     * If SELinux is compiled in, but disabled, then {@code true} is
+     * returned.
+     *
+     * @param pathname The pathname of the file to be relabeled.
+     * @return a boolean indicating whether the relabeling succeeded.
+     */
+    private static native boolean native_restorecon(String pathname);
+
+    /**
+     * Restores a file to its default SELinux security context.
+     * If the system is not compiled with SELinux, then {@code true}
+     * is automatically returned.
+     * If SELinux is compiled in, but disabled, then {@code true} is
+     * returned.
+     *
+     * @param file The File object representing the path to be relabeled.
+     * @return a boolean indicating whether the relabeling succeeded.
+     * @exception NullPointerException if the file is a null object.
+     */
+    public static boolean restorecon(File file) throws NullPointerException {
+        try {
+            return native_restorecon(file.getCanonicalPath());
+        } catch (IOException e) {
+            Slog.e(TAG, "Error getting canonical path. Restorecon failed for " +
+                   file.getPath(), e);
+            return false;
+        }
+    }
+}
diff --git a/core/java/android/os/StatFs.java b/core/java/android/os/StatFs.java
index 912bfdf..ca7fdba 100644
--- a/core/java/android/os/StatFs.java
+++ b/core/java/android/os/StatFs.java
@@ -16,59 +16,77 @@
 
 package android.os;
 
+import libcore.io.ErrnoException;
+import libcore.io.Libcore;
+import libcore.io.StructStatFs;
+
 /**
- * Retrieve overall information about the space on a filesystem.  This is a
- * Wrapper for Unix statfs().
+ * Retrieve overall information about the space on a filesystem. This is a
+ * wrapper for Unix statfs().
  */
 public class StatFs {
-    /**
-     * Construct a new StatFs for looking at the stats of the
-     * filesystem at <var>path</var>.  Upon construction, the stat of
-     * the file system will be performed, and the values retrieved available
-     * from the methods on this class.
-     * 
-     * @param path A path in the desired file system to state.
-     */
-    public StatFs(String path) { native_setup(path); }
-    
-    /**
-     * Perform a restat of the file system referenced by this object.  This
-     * is the same as re-constructing the object with the same file system
-     * path, and the new stat values are available upon return.
-     */
-    public void restat(String path) { native_restat(path); }
-
-    @Override
-    protected void finalize() { native_finalize(); }
+    private StructStatFs mStat;
 
     /**
-     * The size, in bytes, of a block on the file system.  This corresponds
-     * to the Unix statfs.f_bsize field.
+     * Construct a new StatFs for looking at the stats of the filesystem at
+     * {@code path}. Upon construction, the stat of the file system will be
+     * performed, and the values retrieved available from the methods on this
+     * class.
+     *
+     * @param path path in the desired file system to stat.
      */
-    public native int getBlockSize();
+    public StatFs(String path) {
+        mStat = doStat(path);
+    }
+
+    private static StructStatFs doStat(String path) {
+        try {
+            return Libcore.os.statfs(path);
+        } catch (ErrnoException e) {
+            throw new IllegalArgumentException("Invalid path: " + path, e);
+        }
+    }
 
     /**
-     * The total number of blocks on the file system.  This corresponds
-     * to the Unix statfs.f_blocks field.
+     * Perform a restat of the file system referenced by this object. This is
+     * the same as re-constructing the object with the same file system path,
+     * and the new stat values are available upon return.
      */
-    public native int getBlockCount();
+    public void restat(String path) {
+        mStat = doStat(path);
+    }
+
+    /**
+     * The size, in bytes, of a block on the file system. This corresponds to
+     * the Unix {@code statfs.f_bsize} field.
+     */
+    public int getBlockSize() {
+        return (int) mStat.f_bsize;
+    }
+
+    /**
+     * The total number of blocks on the file system. This corresponds to the
+     * Unix {@code statfs.f_blocks} field.
+     */
+    public int getBlockCount() {
+        return (int) mStat.f_blocks;
+    }
 
     /**
      * The total number of blocks that are free on the file system, including
-     * reserved blocks (that are not available to normal applications).  This
-     * corresponds to the Unix statfs.f_bfree field.  Most applications will
-     * want to use {@link #getAvailableBlocks()} instead.
+     * reserved blocks (that are not available to normal applications). This
+     * corresponds to the Unix {@code statfs.f_bfree} field. Most applications
+     * will want to use {@link #getAvailableBlocks()} instead.
      */
-    public native int getFreeBlocks();
+    public int getFreeBlocks() {
+        return (int) mStat.f_bfree;
+    }
 
     /**
      * The number of blocks that are free on the file system and available to
-     * applications.  This corresponds to the Unix statfs.f_bavail field.
+     * applications. This corresponds to the Unix {@code statfs.f_bavail} field.
      */
-    public native int getAvailableBlocks();    
-    
-    private int mNativeContext;
-    private native void native_restat(String path);
-    private native void native_setup(String path);
-    private native void native_finalize();
+    public int getAvailableBlocks() {
+        return (int) mStat.f_bavail;
+    }
 }
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index ce213fb..f682abe 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -407,17 +407,17 @@
             }
 
             /**
-             * Enable detection of disk reads.
+             * Enable detection of slow calls.
              */
             public Builder detectCustomSlowCalls() {
                 return enable(DETECT_CUSTOM);
             }
 
             /**
-             * Enable detection of disk reads.
+             * Disable detection of slow calls.
              */
             public Builder permitCustomSlowCalls() {
-                return enable(DETECT_CUSTOM);
+                return disable(DETECT_CUSTOM);
             }
 
             /**
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index cb6c1dc..8a20a6e 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -56,7 +56,7 @@
     /*
      * Our internal MountService binder reference
      */
-    private IMountService mMountService;
+    final private IMountService mMountService;
 
     /*
      * The looper target for callbacks
@@ -304,8 +304,6 @@
             return;
         }
         mTgtLooper = tgtLooper;
-        mBinderListener = new MountServiceBinderListener();
-        mMountService.registerListener(mBinderListener);
     }
 
 
@@ -322,6 +320,15 @@
         }
 
         synchronized (mListeners) {
+            if (mBinderListener == null ) {
+                try {
+                    mBinderListener = new MountServiceBinderListener();
+                    mMountService.registerListener(mBinderListener);
+                } catch (RemoteException rex) {
+                    Log.e(TAG, "Register mBinderListener failed");
+                    return;
+                }
+            }
             mListeners.add(new ListenerDelegate(listener));
         }
     }
@@ -347,7 +354,15 @@
                     break;
                 }
             }
-        }
+            if (mListeners.size() == 0 && mBinderListener != null) {
+                try {
+                    mMountService.unregisterListener(mBinderListener);
+                } catch (RemoteException rex) {
+                    Log.e(TAG, "Unregister mBinderListener failed");
+                    return;
+                }
+            }
+       }
     }
 
     /**
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 7824724..22b68bc 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -18,7 +18,7 @@
 package android.provider;
 
 import com.android.internal.telephony.CallerInfo;
-import com.android.internal.telephony.Connection;
+import com.android.internal.telephony.PhoneConstants;
 
 import android.content.ContentResolver;
 import android.content.ContentValues;
@@ -267,14 +267,14 @@
 
             // If this is a private number then set the number to Private, otherwise check
             // if the number field is empty and set the number to Unavailable
-            if (presentation == Connection.PRESENTATION_RESTRICTED) {
+            if (presentation == PhoneConstants.PRESENTATION_RESTRICTED) {
                 number = CallerInfo.PRIVATE_NUMBER;
                 if (ci != null) ci.name = "";
-            } else if (presentation == Connection.PRESENTATION_PAYPHONE) {
+            } else if (presentation == PhoneConstants.PRESENTATION_PAYPHONE) {
                 number = CallerInfo.PAYPHONE_NUMBER;
                 if (ci != null) ci.name = "";
             } else if (TextUtils.isEmpty(number)
-                    || presentation == Connection.PRESENTATION_UNKNOWN) {
+                    || presentation == PhoneConstants.PRESENTATION_UNKNOWN) {
                 number = CallerInfo.UNKNOWN_NUMBER;
                 if (ci != null) ci.name = "";
             }
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
old mode 100644
new mode 100755
index 8e123ac..e7b0579
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -8362,7 +8362,7 @@
                 // Line contains the query string - now search for it at the start of tokens.
                 List<String> lineTokens = new ArrayList<String>();
                 List<Integer> tokenOffsets = new ArrayList<Integer>();
-                split(contentLine.trim(), lineTokens, tokenOffsets);
+                split(contentLine, lineTokens, tokenOffsets);
 
                 // As we find matches against the query, we'll populate this list with the marked
                 // (or unchanged) tokens.
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
deleted file mode 100755
index 19d8d5c..0000000
--- a/core/java/android/provider/Telephony.java
+++ /dev/null
@@ -1,2037 +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 android.provider;
-
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.database.sqlite.SqliteWrapper;
-import android.net.Uri;
-import android.os.Environment;
-import android.telephony.SmsMessage;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.Patterns;
-
-
-import java.util.HashSet;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * The Telephony provider contains data related to phone operation.
- *
- * @hide
- */
-public final class Telephony {
-    private static final String TAG = "Telephony";
-    private static final boolean DEBUG = true;
-    private static final boolean LOCAL_LOGV = false;
-
-    // Constructor
-    public Telephony() {
-    }
-
-    /**
-     * 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 received
-         * <P>Type: INTEGER (long)</P>
-         */
-        public static final String DATE = "date";
-
-        /**
-         * The date the message was sent
-         * <P>Type: INTEGER (long)</P>
-         */
-        public static final String DATE_SENT = "date_sent";
-
-        /**
-         * 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 = 32;
-        public static final int STATUS_FAILED = 64;
-
-        /**
-         * 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";
-
-        /**
-         * Meta data used externally.
-         * <P>Type: TEXT</P>
-         */
-        public static final String META_DATA = "meta_data";
-}
-
-    /**
-     * 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>
-             */
-            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-            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[] of 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>
-             */
-            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-            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>
-             *   <li><em>contentTypeParameters (HashMap&lt;String,String&gt;)</em>
-             *   - Any parameters associated with the content type
-             *   (decoded from the WSP Content-Type header)</li>
-             * </ul>
-             *
-             * <p>If a BroadcastReceiver encounters an error while processing
-             * this intent it should set the result code appropriately.</p>
-             *
-             * <p>The contentTypeParameters extra value is map of content parameters keyed by
-             * their names.</p>
-             *
-             * <p>If any unassigned well-known parameters are encountered, the key of the map will
-             * be 'unassigned/0x...', where '...' is the hex value of the unassigned parameter.  If
-             * a parameter has No-Value the value in the map will be null.</p>
-             */
-            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-            public static final String WAP_PUSH_RECEIVED_ACTION =
-                    "android.provider.Telephony.WAP_PUSH_RECEIVED";
-
-            /**
-             * Broadcast Action: A new Cell Broadcast message has been received
-             * by the device. The intent will have the following extra
-             * values:</p>
-             *
-             * <ul>
-             *   <li><em>message</em> - An SmsCbMessage object containing the broadcast message
-             *   data. This is not an emergency alert, so ETWS and CMAS data will be null.</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>
-             */
-            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-            public static final String SMS_CB_RECEIVED_ACTION =
-                    "android.provider.Telephony.SMS_CB_RECEIVED";
-
-            /**
-             * Broadcast Action: A new Emergency Broadcast message has been received
-             * by the device. The intent will have the following extra
-             * values:</p>
-             *
-             * <ul>
-             *   <li><em>message</em> - An SmsCbMessage object containing the broadcast message
-             *   data, including ETWS or CMAS warning notification info if present.</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>
-             */
-            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-            public static final String SMS_EMERGENCY_CB_RECEIVED_ACTION =
-                    "android.provider.Telephony.SMS_EMERGENCY_CB_RECEIVED";
-
-            /**
-             * Broadcast Action: A new CDMA SMS has been received containing Service Category
-             * Program Data (updates the list of enabled broadcast channels). The intent will
-             * have the following extra values:</p>
-             *
-             * <ul>
-             *   <li><em>operations</em> - An array of CdmaSmsCbProgramData objects containing
-             *   the service category operations (add/delete/clear) to perform.</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>
-             */
-            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-            public static final String SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED_ACTION =
-                    "android.provider.Telephony.SMS_SERVICE_CATEGORY_PROGRAM_DATA_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.
-             */
-            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-            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>
-
-             */
-            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-            public static final String SMS_REJECTED_ACTION =
-                "android.provider.Telephony.SMS_REJECTED";
-
-            /**
-             * 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 SmsMessage[] getMessagesFromIntent(
-                    Intent intent) {
-                Object[] messages = (Object[]) intent.getSerializableExtra("pdus");
-                String format = intent.getStringExtra("format");
-                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], format);
-                }
-                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 received.
-         * <P>Type: INTEGER (long)</P>
-         */
-        public static final String DATE = "date";
-
-        /**
-         * The date the message was sent.
-         * <P>Type: INTEGER (long)</P>
-         */
-        public static final String DATE_SENT = "date_sent";
-
-        /**
-         * 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";
-
-        /**
-         * Meta data used externally.
-         * <P>Type: TEXT</P>
-         */
-        public static final String META_DATA = "meta_data";
-    }
-
-    /**
-     * 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 (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 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 INACTIVE_TIMER = "inactivetimer";
-
-        // Only if enabled try Data Connection.
-        public static final String ENABLED = "enabled";
-
-        // Rules apply based on class.
-        public static final String CLASS = "class";
-
-        /**
-         * The protocol to be used to connect to this APN.
-         *
-         * One of the PDP_type values in TS 27.007 section 10.1.1.
-         * For example, "IP", "IPV6", "IPV4V6", or "PPP".
-         */
-        public static final String PROTOCOL = "protocol";
-
-        /**
-          * The protocol to be used to connect to this APN when roaming.
-          *
-          * The syntax is the same as protocol.
-          */
-        public static final String ROAMING_PROTOCOL = "roaming_protocol";
-
-        public static final String CURRENT = "current";
-
-        /**
-          * Current status of APN
-          * true : enabled APN, false : disabled APN.
-          */
-        public static final String CARRIER_ENABLED = "carrier_enabled";
-
-        /**
-          * Radio Access Technology info
-          * To check what values can hold, refer to ServiceState.java.
-          * This should be spread to other technologies,
-          * but currently only used for LTE(14) and EHRPD(13).
-          */
-        public static final String BEARER = "bearer";
-    }
-
-    /**
-     * Contains received SMS cell broadcast messages.
-     */
-    public static final class CellBroadcasts implements BaseColumns {
-
-        /** Not instantiable. */
-        private CellBroadcasts() {}
-
-        /**
-         * The content:// style URL for this table
-         */
-        public static final Uri CONTENT_URI =
-            Uri.parse("content://cellbroadcasts");
-
-        /**
-         * Message geographical scope.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String GEOGRAPHICAL_SCOPE = "geo_scope";
-
-        /**
-         * Message serial number.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String SERIAL_NUMBER = "serial_number";
-
-        /**
-         * PLMN of broadcast sender. (SERIAL_NUMBER + PLMN + LAC + CID) uniquely identifies a
-         * broadcast for duplicate detection purposes.
-         * <P>Type: TEXT</P>
-         */
-        public static final String PLMN = "plmn";
-
-        /**
-         * Location Area (GSM) or Service Area (UMTS) of broadcast sender. Unused for CDMA.
-         * Only included if Geographical Scope of message is not PLMN wide (01).
-         * <P>Type: INTEGER</P>
-         */
-        public static final String LAC = "lac";
-
-        /**
-         * Cell ID of message sender (GSM/UMTS). Unused for CDMA. Only included when the
-         * Geographical Scope of message is cell wide (00 or 11).
-         * <P>Type: INTEGER</P>
-         */
-        public static final String CID = "cid";
-
-        /**
-         * Message code (OBSOLETE: merged into SERIAL_NUMBER).
-         * <P>Type: INTEGER</P>
-         */
-        public static final String V1_MESSAGE_CODE = "message_code";
-
-        /**
-         * Message identifier (OBSOLETE: renamed to SERVICE_CATEGORY).
-         * <P>Type: INTEGER</P>
-         */
-        public static final String V1_MESSAGE_IDENTIFIER = "message_id";
-
-        /**
-         * Service category (GSM/UMTS message identifier, CDMA service category).
-         * <P>Type: INTEGER</P>
-         */
-        public static final String SERVICE_CATEGORY = "service_category";
-
-        /**
-         * Message language code.
-         * <P>Type: TEXT</P>
-         */
-        public static final String LANGUAGE_CODE = "language";
-
-        /**
-         * Message body.
-         * <P>Type: TEXT</P>
-         */
-        public static final String MESSAGE_BODY = "body";
-
-        /**
-         * Message delivery time.
-         * <P>Type: INTEGER (long)</P>
-         */
-        public static final String DELIVERY_TIME = "date";
-
-        /**
-         * Has the message been viewed?
-         * <P>Type: INTEGER (boolean)</P>
-         */
-        public static final String MESSAGE_READ = "read";
-
-        /**
-         * Message format (3GPP or 3GPP2).
-         * <P>Type: INTEGER</P>
-         */
-        public static final String MESSAGE_FORMAT = "format";
-
-        /**
-         * Message priority (including emergency).
-         * <P>Type: INTEGER</P>
-         */
-        public static final String MESSAGE_PRIORITY = "priority";
-
-        /**
-         * ETWS warning type (ETWS alerts only).
-         * <P>Type: INTEGER</P>
-         */
-        public static final String ETWS_WARNING_TYPE = "etws_warning_type";
-
-        /**
-         * CMAS message class (CMAS alerts only).
-         * <P>Type: INTEGER</P>
-         */
-        public static final String CMAS_MESSAGE_CLASS = "cmas_message_class";
-
-        /**
-         * CMAS category (CMAS alerts only).
-         * <P>Type: INTEGER</P>
-         */
-        public static final String CMAS_CATEGORY = "cmas_category";
-
-        /**
-         * CMAS response type (CMAS alerts only).
-         * <P>Type: INTEGER</P>
-         */
-        public static final String CMAS_RESPONSE_TYPE = "cmas_response_type";
-
-        /**
-         * CMAS severity (CMAS alerts only).
-         * <P>Type: INTEGER</P>
-         */
-        public static final String CMAS_SEVERITY = "cmas_severity";
-
-        /**
-         * CMAS urgency (CMAS alerts only).
-         * <P>Type: INTEGER</P>
-         */
-        public static final String CMAS_URGENCY = "cmas_urgency";
-
-        /**
-         * CMAS certainty (CMAS alerts only).
-         * <P>Type: INTEGER</P>
-         */
-        public static final String CMAS_CERTAINTY = "cmas_certainty";
-
-        /**
-         * The default sort order for this table
-         */
-        public static final String DEFAULT_SORT_ORDER = DELIVERY_TIME + " DESC";
-
-        /**
-         * Query columns for instantiating {@link android.telephony.CellBroadcastMessage} objects.
-         */
-        public static final String[] QUERY_COLUMNS = {
-                _ID,
-                GEOGRAPHICAL_SCOPE,
-                PLMN,
-                LAC,
-                CID,
-                SERIAL_NUMBER,
-                SERVICE_CATEGORY,
-                LANGUAGE_CODE,
-                MESSAGE_BODY,
-                DELIVERY_TIME,
-                MESSAGE_READ,
-                MESSAGE_FORMAT,
-                MESSAGE_PRIORITY,
-                ETWS_WARNING_TYPE,
-                CMAS_MESSAGE_CLASS,
-                CMAS_CATEGORY,
-                CMAS_RESPONSE_TYPE,
-                CMAS_SEVERITY,
-                CMAS_URGENCY,
-                CMAS_CERTAINTY
-        };
-    }
-
-    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";
-    }
-}
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 97c0209..6296b11 100755
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -2448,7 +2448,7 @@
         BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
         if (state == null) return;
 
-        state.quit();
+        state.doQuit();
         mDeviceProfileState.remove(address);
     }
 
diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java
index da10311..2e962a0 100644
--- a/core/java/android/text/format/DateUtils.java
+++ b/core/java/android/text/format/DateUtils.java
@@ -161,12 +161,17 @@
     public static final int FORMAT_NO_YEAR = 0x00008;
     public static final int FORMAT_SHOW_DATE = 0x00010;
     public static final int FORMAT_NO_MONTH_DAY = 0x00020;
+    @Deprecated
     public static final int FORMAT_12HOUR = 0x00040;
+    @Deprecated
     public static final int FORMAT_24HOUR = 0x00080;
+    @Deprecated
     public static final int FORMAT_CAP_AMPM = 0x00100;
     public static final int FORMAT_NO_NOON = 0x00200;
+    @Deprecated
     public static final int FORMAT_CAP_NOON = 0x00400;
     public static final int FORMAT_NO_MIDNIGHT = 0x00800;
+    @Deprecated
     public static final int FORMAT_CAP_MIDNIGHT = 0x01000;
     /**
      * @deprecated Use
@@ -181,19 +186,25 @@
     public static final int FORMAT_NUMERIC_DATE = 0x20000;
     public static final int FORMAT_ABBREV_RELATIVE = 0x40000;
     public static final int FORMAT_ABBREV_ALL = 0x80000;
+    @Deprecated
     public static final int FORMAT_CAP_NOON_MIDNIGHT = (FORMAT_CAP_NOON | FORMAT_CAP_MIDNIGHT);
+    @Deprecated
     public static final int FORMAT_NO_NOON_MIDNIGHT = (FORMAT_NO_NOON | FORMAT_NO_MIDNIGHT);
 
     // Date and time format strings that are constant and don't need to be
     // translated.
     /**
      * This is not actually the preferred 24-hour date format in all locales.
+     * @deprecated use {@link java.text.SimpleDateFormat} instead.
      */
+    @Deprecated
     public static final String HOUR_MINUTE_24 = "%H:%M";
     public static final String MONTH_FORMAT = "%B";
     /**
      * This is not actually a useful month name in all locales.
+     * @deprecated use {@link java.text.SimpleDateFormat} instead.
      */
+    @Deprecated
     public static final String ABBREV_MONTH_FORMAT = "%b";
     public static final String NUMERIC_MONTH_FORMAT = "%m";
     public static final String MONTH_DAY_FORMAT = "%-d";
@@ -207,6 +218,7 @@
     // The index is constructed from a bit-wise OR of the boolean values:
     // {showTime, showYear, showWeekDay}.  For example, if showYear and
     // showWeekDay are both true, then the index would be 3.
+    /** @deprecated do not use. */
     public static final int sameYearTable[] = {
         com.android.internal.R.string.same_year_md1_md2,
         com.android.internal.R.string.same_year_wday1_md1_wday2_md2,
@@ -233,6 +245,7 @@
     // The index is constructed from a bit-wise OR of the boolean values:
     // {showTime, showYear, showWeekDay}.  For example, if showYear and
     // showWeekDay are both true, then the index would be 3.
+    /** @deprecated do not use. */
     public static final int sameMonthTable[] = {
         com.android.internal.R.string.same_month_md1_md2,
         com.android.internal.R.string.same_month_wday1_md1_wday2_md2,
@@ -259,7 +272,9 @@
      *
      * @more <p>
      *       e.g. "Sunday" or "January"
+     * @deprecated use {@link java.text.SimpleDateFormat} instead.
      */
+    @Deprecated
     public static final int LENGTH_LONG = 10;
 
     /**
@@ -268,7 +283,9 @@
      *
      * @more <p>
      *       e.g. "Sun" or "Jan"
+     * @deprecated use {@link java.text.SimpleDateFormat} instead.
      */
+    @Deprecated
     public static final int LENGTH_MEDIUM = 20;
 
     /**
@@ -278,14 +295,18 @@
      * <p>e.g. "Su" or "Jan"
      * <p>In most languages, the results returned for LENGTH_SHORT will be the same as
      * the results returned for {@link #LENGTH_MEDIUM}.
+     * @deprecated use {@link java.text.SimpleDateFormat} instead.
      */
+    @Deprecated
     public static final int LENGTH_SHORT = 30;
 
     /**
      * Request an even shorter abbreviated version of the name.
      * Do not use this.  Currently this will always return the same result
      * as {@link #LENGTH_SHORT}.
+     * @deprecated use {@link java.text.SimpleDateFormat} instead.
      */
+    @Deprecated
     public static final int LENGTH_SHORTER = 40;
 
     /**
@@ -295,7 +316,9 @@
      * <p>e.g. "S", "T", "T" or "J"
      * <p>In some languages, the results returned for LENGTH_SHORTEST will be the same as
      * the results returned for {@link #LENGTH_SHORT}.
+     * @deprecated use {@link java.text.SimpleDateFormat} instead.
      */
+    @Deprecated
     public static final int LENGTH_SHORTEST = 50;
 
     /**
@@ -309,7 +332,9 @@
      *               Undefined lengths will return {@link #LENGTH_MEDIUM}
      *               but may return something different in the future.
      * @throws IndexOutOfBoundsException if the dayOfWeek is out of bounds.
+     * @deprecated use {@link java.text.SimpleDateFormat} instead.
      */
+    @Deprecated
     public static String getDayOfWeekString(int dayOfWeek, int abbrev) {
         int[] list;
         switch (abbrev) {
@@ -330,7 +355,9 @@
      * @param ampm Either {@link Calendar#AM Calendar.AM} or {@link Calendar#PM Calendar.PM}.
      * @throws IndexOutOfBoundsException if the ampm is out of bounds.
      * @return Localized version of "AM" or "PM".
+     * @deprecated use {@link java.text.SimpleDateFormat} instead.
      */
+    @Deprecated
     public static String getAMPMString(int ampm) {
         Resources r = Resources.getSystem();
         return r.getString(sAmPm[ampm - Calendar.AM]);
@@ -345,7 +372,9 @@
      *               Undefined lengths will return {@link #LENGTH_MEDIUM}
      *               but may return something different in the future.
      * @return Localized month of the year.
+     * @deprecated use {@link java.text.SimpleDateFormat} instead.
      */
+    @Deprecated
     public static String getMonthString(int month, int abbrev) {
         // Note that here we use sMonthsMedium for MEDIUM, SHORT and SHORTER.
         // This is a shortcut to not spam the translators with too many variations
@@ -378,7 +407,9 @@
      *               but may return something different in the future.
      * @return Localized month of the year.
      * @hide Pending API council approval
+     * @deprecated use {@link java.text.SimpleDateFormat} instead.
      */
+    @Deprecated
     public static String getStandaloneMonthString(int month, int abbrev) {
         // Note that here we use sMonthsMedium for MEDIUM, SHORT and SHORTER.
         // This is a shortcut to not spam the translators with too many variations
@@ -1618,7 +1649,7 @@
 
         String result;
         long now = System.currentTimeMillis();
-        long span = now - millis;
+        long span = Math.abs(now - millis);
 
         synchronized (DateUtils.class) {
             if (sNowTime == null) {
diff --git a/core/java/android/view/FocusFinder.java b/core/java/android/view/FocusFinder.java
index 9063cea..31a9f05 100644
--- a/core/java/android/view/FocusFinder.java
+++ b/core/java/android/view/FocusFinder.java
@@ -250,8 +250,8 @@
             // only interested in other non-root views
             if (focusable == focused || focusable == root) continue;
 
-            // get visible bounds of other view in same coordinate system
-            focusable.getDrawingRect(mOtherRect);
+            // get focus bounds of other view in same coordinate system
+            focusable.getFocusRect(mOtherRect);
             root.offsetDescendantRectToMyCoords(focusable, mOtherRect);
 
             if (isBetterCandidate(direction, focusedRect, mOtherRect, mBestCandidateRect)) {
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index fd302dc..ed4c75c 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -531,7 +531,7 @@
 
                     mSurface.transferFrom(mNewSurface);
 
-                    if (visible) {
+                    if (visible && mSurface.isValid()) {
                         if (!mSurfaceCreated && (surfaceChanged || visibleChanged)) {
                             mSurfaceCreated = true;
                             mIsCreating = true;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index f0ca302..f2a80d0 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8737,6 +8737,18 @@
     }
 
     /**
+     * When searching for a view to focus this rectangle is used when considering if this view is
+     * a good candidate for receiving focus.
+     *
+     * By default, the rectangle is the {@link #getDrawingRect}) of the view.
+     *
+     * @param r The rectangle to fill in, in this view's coordinates.
+     */
+    public void getFocusRect(Rect r) {
+        getDrawingRect(r);
+    }
+
+   /**
      * Utility method to retrieve the inverse of the current mMatrix property.
      * We cache the matrix to avoid recalculating it when transform properties
      * have not changed.
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index d1d867c..c624a87 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -686,6 +686,10 @@
     // It's used to dismiss the dialog in destroy if not done before.
     private AlertDialog mListBoxDialog = null;
 
+    // Reference to the save password dialog so it can be dimissed in
+    // destroy if not done before.
+    private AlertDialog mSavePasswordDialog = null;
+
     static final String LOGTAG = "webview";
 
     private ZoomManager mZoomManager;
@@ -1826,7 +1830,7 @@
             neverRemember.getData().putString("password", password);
             neverRemember.obj = resumeMsg;
 
-            new AlertDialog.Builder(mContext)
+            mSavePasswordDialog = new AlertDialog.Builder(mContext)
                     .setTitle(com.android.internal.R.string.save_password_label)
                     .setMessage(com.android.internal.R.string.save_password_message)
                     .setPositiveButton(com.android.internal.R.string.save_password_notnow,
@@ -1837,6 +1841,7 @@
                                 resumeMsg.sendToTarget();
                                 mResumeMsg = null;
                             }
+                            mSavePasswordDialog = null;
                         }
                     })
                     .setNeutralButton(com.android.internal.R.string.save_password_remember,
@@ -1847,6 +1852,7 @@
                                 remember.sendToTarget();
                                 mResumeMsg = null;
                             }
+                            mSavePasswordDialog = null;
                         }
                     })
                     .setNegativeButton(com.android.internal.R.string.save_password_never,
@@ -1857,6 +1863,7 @@
                                 neverRemember.sendToTarget();
                                 mResumeMsg = null;
                             }
+                            mSavePasswordDialog = null;
                         }
                     })
                     .setOnCancelListener(new OnCancelListener() {
@@ -1866,6 +1873,7 @@
                                 resumeMsg.sendToTarget();
                                 mResumeMsg = null;
                             }
+                            mSavePasswordDialog = null;
                         }
                     }).show();
             // Return true so that WebViewCore will pause while the dialog is
@@ -2105,6 +2113,10 @@
             mListBoxDialog.dismiss();
             mListBoxDialog = null;
         }
+        if (mSavePasswordDialog != null) {
+            mSavePasswordDialog.dismiss();
+            mSavePasswordDialog = null;
+        }
         if (mWebViewCore != null) {
             // Tell WebViewCore to destroy itself
             synchronized (this) {
diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java
index 323fcf0..b72b8cb 100644
--- a/core/java/android/widget/Gallery.java
+++ b/core/java/android/widget/Gallery.java
@@ -1192,15 +1192,15 @@
         case KeyEvent.KEYCODE_DPAD_LEFT:
             if (movePrevious()) {
                 playSoundEffect(SoundEffectConstants.NAVIGATION_LEFT);
+                return true;
             }
-            return true;
-
+            break;
         case KeyEvent.KEYCODE_DPAD_RIGHT:
             if (moveNext()) {
                 playSoundEffect(SoundEffectConstants.NAVIGATION_RIGHT);
+                return true;
             }
-            return true;
-
+            break;
         case KeyEvent.KEYCODE_DPAD_CENTER:
         case KeyEvent.KEYCODE_ENTER:
             mReceivedInvokeKeyDown = true;
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index ff8c0a1..37e0b90 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -2207,8 +2207,13 @@
             int height = view.getHeight();
             if (height > 0) {
                 final int numColumns = mNumColumns;
-                final int whichRow = mFirstPosition / numColumns;
                 final int rowCount = (mItemCount + numColumns - 1) / numColumns;
+                // In case of stackFromBottom the calculation of whichRow needs
+                // to take into account that counting from the top the first row
+                // might not be entirely filled.
+                final int oddItemsOnFirstRow = isStackFromBottom() ? ((rowCount * numColumns) -
+                        mItemCount) : 0;
+                final int whichRow = (mFirstPosition + oddItemsOnFirstRow) / numColumns;
                 return Math.max(whichRow * 100 - (top * 100) / height +
                         (int) ((float) mScrollY / getHeight() * rowCount * 100), 0);
             }
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 18c4fe6..ff0579c 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -22,6 +22,7 @@
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.FocusFinder;
 import android.view.InputDevice;
 import android.view.KeyEvent;
@@ -62,6 +63,7 @@
 
     private static final float MAX_SCROLL_FACTOR = ScrollView.MAX_SCROLL_FACTOR;
 
+    private static final String TAG = "HorizontalScrollView";
 
     private long mLastScroll;
 
@@ -456,6 +458,12 @@
                 }
 
                 final int pointerIndex = ev.findPointerIndex(activePointerId);
+                if (pointerIndex == -1) {
+                    Log.e(TAG, "Invalid pointerId=" + activePointerId
+                            + " in onInterceptTouchEvent");
+                    break;
+                }
+
                 final int x = (int) ev.getX(pointerIndex);
                 final int xDiff = (int) Math.abs(x - mLastMotionX);
                 if (xDiff > mTouchSlop) {
@@ -557,6 +565,11 @@
             }
             case MotionEvent.ACTION_MOVE:
                 final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
+                if (activePointerIndex == -1) {
+                    Log.e(TAG, "Invalid pointerId=" + mActivePointerId + " in onTouchEvent");
+                    break;
+                }
+
                 final int x = (int) ev.getX(activePointerIndex);
                 int deltaX = mLastMotionX - x;
                 if (!mIsBeingDragged && Math.abs(deltaX) > mTouchSlop) {
diff --git a/core/java/android/widget/MediaController.java b/core/java/android/widget/MediaController.java
index fc35f05..f76ab2b 100644
--- a/core/java/android/widget/MediaController.java
+++ b/core/java/android/widget/MediaController.java
@@ -477,7 +477,8 @@
             return true;
         } else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
                 || keyCode == KeyEvent.KEYCODE_VOLUME_UP
-                || keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) {
+                || keyCode == KeyEvent.KEYCODE_VOLUME_MUTE
+                || keyCode == KeyEvent.KEYCODE_CAMERA) {
             // don't show the controls for volume adjustment
             return super.dispatchKeyEvent(event);
         } else if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU) {
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index ebc54f4..8747dc3 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -25,6 +25,7 @@
 import android.os.Bundle;
 import android.os.StrictMode;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.FocusFinder;
 import android.view.InputDevice;
 import android.view.KeyEvent;
@@ -69,6 +70,8 @@
 
     static final float MAX_SCROLL_FACTOR = 0.5f;
 
+    private static final String TAG = "ScrollView";
+
     private long mLastScroll;
 
     private final Rect mTempRect = new Rect();
@@ -478,6 +481,12 @@
                 }
 
                 final int pointerIndex = ev.findPointerIndex(activePointerId);
+                if (pointerIndex == -1) {
+                    Log.e(TAG, "Invalid pointerId=" + activePointerId
+                            + " in onInterceptTouchEvent");
+                    break;
+                }
+
                 final int y = (int) ev.getY(pointerIndex);
                 final int yDiff = Math.abs(y - mLastMotionY);
                 if (yDiff > mTouchSlop) {
@@ -585,6 +594,11 @@
             }
             case MotionEvent.ACTION_MOVE:
                 final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
+                if (activePointerIndex == -1) {
+                    Log.e(TAG, "Invalid pointerId=" + mActivePointerId + " in onTouchEvent");
+                    break;
+                }
+
                 final int y = (int) ev.getY(activePointerIndex);
                 int deltaY = mLastMotionY - y;
                 if (!mIsBeingDragged && Math.abs(deltaY) > mTouchSlop) {
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index a0e961f..86433d4 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -1506,6 +1506,9 @@
         // because the voice search activity will always need to insert "QUERY" into
         // it anyway.
         Bundle queryExtras = new Bundle();
+        if (mAppSearchData != null) {
+            queryExtras.putParcelable(SearchManager.APP_DATA, mAppSearchData);
+        }
 
         // Now build the intent to launch the voice search.  Add all necessary
         // extras to launch the voice recognizer, and then all the necessary extras
@@ -1595,8 +1598,8 @@
             } catch (RuntimeException e2 ) {
                 rowNum = -1;
             }
-            Log.w(LOG_TAG, "Search Suggestions cursor at row " + rowNum +
-                            " returned exception" + e.toString());
+            Log.w(LOG_TAG, "Search suggestions cursor at row " + rowNum +
+                            " returned exception.", e);
             return null;
         }
     }
diff --git a/core/java/android/widget/SimpleExpandableListAdapter.java b/core/java/android/widget/SimpleExpandableListAdapter.java
index 015c169..f514374 100644
--- a/core/java/android/widget/SimpleExpandableListAdapter.java
+++ b/core/java/android/widget/SimpleExpandableListAdapter.java
@@ -38,6 +38,8 @@
  */
 public class SimpleExpandableListAdapter extends BaseExpandableListAdapter {
     private List<? extends Map<String, ?>> mGroupData;
+    // Keeps track of if a group is currently expanded or not
+    private boolean[] mIsGroupExpanded;
     private int mExpandedGroupLayout;
     private int mCollapsedGroupLayout;
     private String[] mGroupFrom;
@@ -196,6 +198,8 @@
             int childLayout, int lastChildLayout, String[] childFrom,
             int[] childTo) {
         mGroupData = groupData;
+        // Initially all groups are not expanded
+        mIsGroupExpanded = new boolean[groupData.size()];
         mExpandedGroupLayout = expandedGroupLayout;
         mCollapsedGroupLayout = collapsedGroupLayout;
         mGroupFrom = groupFrom;
@@ -298,4 +302,52 @@
         return true;
     }
 
+    /**
+     * {@inheritDoc}
+     * @return 1 for the last child in a group, 0 for the other children.
+     */
+    @Override
+    public int getChildType(int groupPosition, int childPosition) {
+        final int childrenInGroup = getChildrenCount(groupPosition);
+        return childPosition == childrenInGroup - 1 ? 1 : 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @return 2, one type for the last child in a group, one for the other children.
+     */
+    @Override
+    public int getChildTypeCount() {
+        return 2;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @return 1 for an expanded group view, 0 for a collapsed one.
+     */
+    @Override
+    public int getGroupType(int groupPosition) {
+        return mIsGroupExpanded[groupPosition] ? 1 : 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @return 2, one for a collapsed group view, one for an expanded one.
+     */
+    @Override
+    public int getGroupTypeCount() {
+        return 2;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void onGroupCollapsed(int groupPosition) {
+        mIsGroupExpanded[groupPosition] = false;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void onGroupExpanded(int groupPosition) {
+        mIsGroupExpanded[groupPosition] = true;
+    }
 }
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index 56f6651..cea613f 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -686,7 +686,7 @@
     @Override
     public void setChecked(boolean checked) {
         super.setChecked(checked);
-        mThumbPosition = checked ? getThumbScrollRange() : 0;
+        mThumbPosition = isChecked() ? getThumbScrollRange() : 0;
         invalidate();
     }
 
diff --git a/core/java/android/widget/TabHost.java b/core/java/android/widget/TabHost.java
index 8bb9348..238dc55 100644
--- a/core/java/android/widget/TabHost.java
+++ b/core/java/android/widget/TabHost.java
@@ -48,6 +48,10 @@
  */
 public class TabHost extends FrameLayout implements ViewTreeObserver.OnTouchModeChangeListener {
 
+    private static final int TABWIDGET_LOCATION_LEFT = 0;
+    private static final int TABWIDGET_LOCATION_TOP = 1;
+    private static final int TABWIDGET_LOCATION_RIGHT = 2;
+    private static final int TABWIDGET_LOCATION_BOTTOM = 3;
     private TabWidget mTabWidget;
     private FrameLayout mTabContent;
     private List<TabSpec> mTabSpecs = new ArrayList<TabSpec>(2);
@@ -293,22 +297,73 @@
         return mTabContent;
     }
 
+    /**
+     * Get the location of the TabWidget.
+     *
+     * @return The TabWidget location.
+     */
+    private int getTabWidgetLocation() {
+        int location = TABWIDGET_LOCATION_TOP;
+
+        switch (mTabWidget.getOrientation()) {
+            case LinearLayout.VERTICAL:
+                location = (mTabContent.getLeft() < mTabWidget.getLeft()) ? TABWIDGET_LOCATION_RIGHT
+                        : TABWIDGET_LOCATION_LEFT;
+                break;
+            case LinearLayout.HORIZONTAL:
+            default:
+                location = (mTabContent.getTop() < mTabWidget.getTop()) ? TABWIDGET_LOCATION_BOTTOM
+                        : TABWIDGET_LOCATION_TOP;
+                break;
+        }
+        return location;
+    }
+
     @Override
     public boolean dispatchKeyEvent(KeyEvent event) {
         final boolean handled = super.dispatchKeyEvent(event);
 
-        // unhandled key ups change focus to tab indicator for embedded activities
-        // when there is nothing that will take focus from default focus searching
+        // unhandled key events change focus to tab indicator for embedded
+        // activities when there is nothing that will take focus from default
+        // focus searching
         if (!handled
                 && (event.getAction() == KeyEvent.ACTION_DOWN)
-                && (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP)
                 && (mCurrentView != null)
                 && (mCurrentView.isRootNamespace())
-                && (mCurrentView.hasFocus())
-                && (mCurrentView.findFocus().focusSearch(View.FOCUS_UP) == null)) {
-            mTabWidget.getChildTabViewAt(mCurrentTab).requestFocus();
-            playSoundEffect(SoundEffectConstants.NAVIGATION_UP);
-            return true;
+                && (mCurrentView.hasFocus())) {
+            int keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_UP;
+            int directionShouldChangeFocus = View.FOCUS_UP;
+            int soundEffect = SoundEffectConstants.NAVIGATION_UP;
+
+            switch (getTabWidgetLocation()) {
+                case TABWIDGET_LOCATION_LEFT:
+                    keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_LEFT;
+                    directionShouldChangeFocus = View.FOCUS_LEFT;
+                    soundEffect = SoundEffectConstants.NAVIGATION_LEFT;
+                    break;
+                case TABWIDGET_LOCATION_RIGHT:
+                    keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_RIGHT;
+                    directionShouldChangeFocus = View.FOCUS_RIGHT;
+                    soundEffect = SoundEffectConstants.NAVIGATION_RIGHT;
+                    break;
+                case TABWIDGET_LOCATION_BOTTOM:
+                    keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_DOWN;
+                    directionShouldChangeFocus = View.FOCUS_DOWN;
+                    soundEffect = SoundEffectConstants.NAVIGATION_DOWN;
+                    break;
+                case TABWIDGET_LOCATION_TOP:
+                default:
+                    keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_UP;
+                    directionShouldChangeFocus = View.FOCUS_UP;
+                    soundEffect = SoundEffectConstants.NAVIGATION_UP;
+                    break;
+            }
+            if (event.getKeyCode() == keyCodeShouldChangeFocus
+                    && mCurrentView.findFocus().focusSearch(directionShouldChangeFocus) == null) {
+                mTabWidget.getChildTabViewAt(mCurrentTab).requestFocus();
+                playSoundEffect(soundEffect);
+                return true;
+            }
         }
         return handled;
     }
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index 2061c90..56b5937 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -347,6 +347,18 @@
         }
     }
 
+    /**
+     * @param attrId the attributeId of the theme-specific drawable
+     * to resolve the resourceId for.
+     *
+     * @return resId the resourceId of the theme-specific drawable
+     */
+    public int getIconAttributeResId(int attrId) {
+        TypedValue out = new TypedValue();
+        mContext.getTheme().resolveAttribute(attrId, out, true);
+        return out.resourceId;
+    }
+
     public void setInverseBackgroundForced(boolean forceInverseBackground) {
         mForceInverseBackground = forceInverseBackground;
     }
@@ -740,6 +752,7 @@
         
         public int mIconId = 0;
         public Drawable mIcon;
+        public int mIconAttrId = 0;
         public CharSequence mTitle;
         public View mCustomTitleView;
         public CharSequence mMessage;
@@ -806,6 +819,9 @@
                 if (mIconId >= 0) {
                     dialog.setIcon(mIconId);
                 }
+                if (mIconAttrId > 0) {
+                    dialog.setIcon(dialog.getIconAttributeResId(mIconAttrId));
+                }
             }
             if (mMessage != null) {
                 dialog.setMessage(mMessage);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 5157385..db752e9 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -2302,8 +2302,8 @@
                 batteryRealtime, which);
     }
 
-    @Override public int getPhoneSignalStrengthCount(int dataType, int which) {
-        return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
+    @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) {
+        return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which);
     }
 
     @Override public long getPhoneDataConnectionTime(int dataType,
diff --git a/core/java/com/android/internal/os/ProcessStats.java b/core/java/com/android/internal/os/ProcessStats.java
index 1923b86..b1bb8c1 100644
--- a/core/java/com/android/internal/os/ProcessStats.java
+++ b/core/java/com/android/internal/os/ProcessStats.java
@@ -154,7 +154,7 @@
 
     private boolean mFirst = true;
 
-    private byte[] mBuffer = new byte[256];
+    private byte[] mBuffer = new byte[4096];
 
     /**
      * The time in microseconds that the CPU has been running at each speed.
@@ -556,7 +556,7 @@
     private long[] getCpuSpeedTimes(long[] out) {
         long[] tempTimes = out;
         long[] tempSpeeds = mCpuSpeeds;
-        final int MAX_SPEEDS = 20;
+        final int MAX_SPEEDS = 60;
         if (out == null) {
             tempTimes = new long[MAX_SPEEDS]; // Hopefully no more than that
             tempSpeeds = new long[MAX_SPEEDS];
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 9af7e96..b016e99 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -26,6 +26,8 @@
 import dalvik.system.PathClassLoader;
 import dalvik.system.Zygote;
 
+import android.os.SELinux;
+
 import java.io.BufferedReader;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
@@ -73,6 +75,7 @@
     private final DataOutputStream mSocketOutStream;
     private final BufferedReader mSocketReader;
     private final Credentials peer;
+    private final String peerSecurityContext;
 
     /**
      * A long-lived reference to the original command socket used to launch
@@ -109,6 +112,8 @@
             Log.e(TAG, "Cannot read peer credentials", ex);
             throw ex;
         }
+
+        peerSecurityContext = SELinux.getPeerContext(mSocket.getFileDescriptor());
     }
 
     /**
@@ -207,10 +212,11 @@
         try {
             parsedArgs = new Arguments(args);
 
-            applyUidSecurityPolicy(parsedArgs, peer);
-            applyRlimitSecurityPolicy(parsedArgs, peer);
-            applyCapabilitiesSecurityPolicy(parsedArgs, peer);
-            applyInvokeWithSecurityPolicy(parsedArgs, peer);
+            applyUidSecurityPolicy(parsedArgs, peer, peerSecurityContext);
+            applyRlimitSecurityPolicy(parsedArgs, peer, peerSecurityContext);
+            applyCapabilitiesSecurityPolicy(parsedArgs, peer, peerSecurityContext);
+            applyInvokeWithSecurityPolicy(parsedArgs, peer, peerSecurityContext);
+            applyseInfoSecurityPolicy(parsedArgs, peer, peerSecurityContext);
 
             applyDebuggerSystemProperty(parsedArgs);
             applyInvokeWithSystemProperty(parsedArgs);
@@ -229,7 +235,8 @@
             }
 
             pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
-                    parsedArgs.gids, parsedArgs.debugFlags, rlimits);
+                    parsedArgs.gids, parsedArgs.debugFlags, rlimits,
+                    parsedArgs.seInfo, parsedArgs.niceName);
         } catch (IOException ex) {
             logAndPrintError(newStderr, "Exception creating pipe", ex);
         } catch (ErrnoException ex) {
@@ -352,6 +359,10 @@
         long permittedCapabilities;
         long effectiveCapabilities;
 
+        /** from --seinfo */
+        boolean seInfoSpecified;
+        String seInfo;
+
         /** from all --rlimit=r,c,m */
         ArrayList<int[]> rlimits;
 
@@ -429,6 +440,13 @@
                     peerWait = true;
                 } else if (arg.equals("--runtime-init")) {
                     runtimeInit = true;
+                } else if (arg.startsWith("--seinfo=")) {
+                    if (seInfoSpecified) {
+                        throw new IllegalArgumentException(
+                                "Duplicate arg specified");
+                    }
+                    seInfoSpecified = true;
+                    seInfo = arg.substring(arg.indexOf('=') + 1);
                 } else if (arg.startsWith("--capabilities=")) {
                     if (capabilitiesSpecified) {
                         throw new IllegalArgumentException(
@@ -591,7 +609,8 @@
      * @param peer non-null; peer credentials
      * @throws ZygoteSecurityException
      */
-    private static void applyUidSecurityPolicy(Arguments args, Credentials peer)
+    private static void applyUidSecurityPolicy(Arguments args, Credentials peer,
+            String peerSecurityContext)
             throws ZygoteSecurityException {
 
         int peerUid = peer.getUid();
@@ -624,6 +643,17 @@
             }
         }
 
+        if (args.uidSpecified || args.gidSpecified || args.gids != null) {
+            boolean allowed = SELinux.checkSELinuxAccess(peerSecurityContext,
+                                                         peerSecurityContext,
+                                                         "zygote",
+                                                         "specifyids");
+            if (!allowed) {
+                throw new ZygoteSecurityException(
+                        "Peer may not specify uid's or gid's");
+            }
+        }
+
         // If not otherwise specified, uid and gid are inherited from peer
         if (!args.uidSpecified) {
             args.uid = peer.getUid();
@@ -664,7 +694,7 @@
      * @throws ZygoteSecurityException
      */
     private static void applyRlimitSecurityPolicy(
-            Arguments args, Credentials peer)
+            Arguments args, Credentials peer, String peerSecurityContext)
             throws ZygoteSecurityException {
 
         int peerUid = peer.getUid();
@@ -676,6 +706,17 @@
                         "This UID may not specify rlimits.");
             }
         }
+
+        if (args.rlimits != null) {
+            boolean allowed = SELinux.checkSELinuxAccess(peerSecurityContext,
+                                                         peerSecurityContext,
+                                                         "zygote",
+                                                         "specifyrlimits");
+            if (!allowed) {
+                throw new ZygoteSecurityException(
+                        "Peer may not specify rlimits");
+            }
+         }
     }
 
     /**
@@ -689,7 +730,7 @@
      * @throws ZygoteSecurityException
      */
     private static void applyCapabilitiesSecurityPolicy(
-            Arguments args, Credentials peer)
+            Arguments args, Credentials peer, String peerSecurityContext)
             throws ZygoteSecurityException {
 
         if (args.permittedCapabilities == 0
@@ -698,6 +739,15 @@
             return;
         }
 
+        boolean allowed = SELinux.checkSELinuxAccess(peerSecurityContext,
+                                                     peerSecurityContext,
+                                                     "zygote",
+                                                     "specifycapabilities");
+        if (!allowed) {
+            throw new ZygoteSecurityException(
+                    "Peer may not specify capabilities");
+        }
+
         if (peer.getUid() == 0) {
             // root may specify anything
             return;
@@ -747,7 +797,8 @@
      * @param peer non-null; peer credentials
      * @throws ZygoteSecurityException
      */
-    private static void applyInvokeWithSecurityPolicy(Arguments args, Credentials peer)
+    private static void applyInvokeWithSecurityPolicy(Arguments args, Credentials peer,
+            String peerSecurityContext)
             throws ZygoteSecurityException {
         int peerUid = peer.getUid();
 
@@ -755,6 +806,52 @@
             throw new ZygoteSecurityException("Peer is not permitted to specify "
                     + "an explicit invoke-with wrapper command");
         }
+
+        if (args.invokeWith != null) {
+            boolean allowed = SELinux.checkSELinuxAccess(peerSecurityContext,
+                                                         peerSecurityContext,
+                                                         "zygote",
+                                                         "specifyinvokewith");
+            if (!allowed) {
+                throw new ZygoteSecurityException("Peer is not permitted to specify "
+                    + "an explicit invoke-with wrapper command");
+            }
+        }
+    }
+
+    /**
+     * Applies zygote security policy for SEAndroid information.
+     *
+     * @param args non-null; zygote spawner arguments
+     * @param peer non-null; peer credentials
+     * @throws ZygoteSecurityException
+     */
+    private static void applyseInfoSecurityPolicy(
+            Arguments args, Credentials peer, String peerSecurityContext)
+            throws ZygoteSecurityException {
+        int peerUid = peer.getUid();
+
+        if (args.seInfo == null) {
+            // nothing to check
+            return;
+        }
+
+        if (!(peerUid == 0 || peerUid == Process.SYSTEM_UID)) {
+            // All peers with UID other than root or SYSTEM_UID
+            throw new ZygoteSecurityException(
+                    "This UID may not specify SEAndroid info.");
+        }
+
+        boolean allowed = SELinux.checkSELinuxAccess(peerSecurityContext,
+                                                     peerSecurityContext,
+                                                     "zygote",
+                                                     "specifyseinfo");
+        if (!allowed) {
+            throw new ZygoteSecurityException(
+                    "Peer may not specify SEAndroid info");
+        }
+
+        return;
     }
 
     /**
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 998c037..4924326 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -16,16 +16,17 @@
 
 package com.android.internal.os;
 
+import static libcore.io.OsConstants.S_IRWXG;
+import static libcore.io.OsConstants.S_IRWXO;
+
 import android.content.pm.ActivityInfo;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
 import android.net.LocalServerSocket;
 import android.os.Debug;
-import android.os.FileUtils;
 import android.os.Process;
 import android.os.SystemClock;
-import android.os.SystemProperties;
 import android.util.EventLog;
 import android.util.Log;
 
@@ -33,6 +34,7 @@
 import dalvik.system.Zygote;
 
 import libcore.io.IoUtils;
+import libcore.io.Libcore;
 
 import java.io.BufferedReader;
 import java.io.FileDescriptor;
@@ -447,7 +449,7 @@
         closeServerSocket();
 
         // set umask to 0077 so new files and directories will default to owner-only permissions.
-        FileUtils.setUMask(FileUtils.S_IRWXG | FileUtils.S_IRWXO);
+        Libcore.os.umask(S_IRWXG | S_IRWXO);
 
         if (parsedArgs.niceName != null) {
             Process.setArgV0(parsedArgs.niceName);
diff --git a/core/java/com/android/internal/util/AsyncChannel.java b/core/java/com/android/internal/util/AsyncChannel.java
index d1c2d2e..5093b4d 100644
--- a/core/java/com/android/internal/util/AsyncChannel.java
+++ b/core/java/com/android/internal/util/AsyncChannel.java
@@ -444,6 +444,16 @@
         if ((mConnection != null) && (mSrcContext != null)) {
             mSrcContext.unbindService(mConnection);
         }
+        try {
+            // Send the DISCONNECTED, although it may not be received
+            // but its the best we can do.
+            Message msg = Message.obtain();
+            msg.what = CMD_CHANNEL_DISCONNECTED;
+            msg.replyTo = mSrcMessenger;
+            mDstMessenger.send(msg);
+        } catch(Exception e) {
+        }
+        // Tell source we're disconnected.
         if (mSrcHandler != null) {
             replyDisconnected(STATUS_SUCCESSFUL);
         }
diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java
index 1391ac3..0ea7b83 100644
--- a/core/java/com/android/internal/util/StateMachine.java
+++ b/core/java/com/android/internal/util/StateMachine.java
@@ -80,9 +80,9 @@
  * and invoke <code>halting</code>. Any message subsequently received by the state
  * machine will cause <code>haltedProcessMessage</code> to be invoked.</p>
  *
- * <p>If it is desirable to completely stop the state machine call <code>quit</code>. This
- * will exit the current state and its parent and then exit from the controlling thread
- * and no further messages will be processed.</p>
+ * <p>If it is desirable to completely stop the state machine call <code>quit</code> or
+ * <code>abort</code>. These will call <code>exit</code> of the current state and its parents, call
+ * <code>onQuiting</code> and then exit Thread/Loopers.</p>
  *
  * <p>In addition to <code>processMessage</code> each <code>State</code> has
  * an <code>enter</code> method and <code>exit</exit> method which may be overridden.</p>
@@ -362,7 +362,7 @@
     }
 
     &#64;Override
-    void halting() {
+    void onHalting() {
         Log.d(TAG, "halting");
         synchronized (this) {
             this.notifyAll();
@@ -423,10 +423,10 @@
     private String mName;
 
     /** Message.what value when quitting */
-    public static final int SM_QUIT_CMD = -1;
+    private static final int SM_QUIT_CMD = -1;
 
     /** Message.what value when initializing */
-    public static final int SM_INIT_CMD = -2;
+    private static final int SM_INIT_CMD = -2;
 
     /**
      * Convenience constant that maybe returned by processMessage
@@ -443,11 +443,10 @@
     public static final boolean NOT_HANDLED = false;
 
     /**
+     * StateMachine logging record.
      * {@hide}
-     *
-     * The information maintained for a processed message.
      */
-    public static class ProcessedMessageInfo {
+    public static class LogRec {
         private long mTime;
         private int mWhat;
         private String mInfo;
@@ -456,12 +455,13 @@
 
         /**
          * Constructor
-         * @param message
+         *
+         * @param msg
          * @param state that handled the message
          * @param orgState is the first state the received the message but
          * did not processes the message.
          */
-        ProcessedMessageInfo(Message msg, String info, State state, State orgState) {
+        LogRec(Message msg, String info, State state, State orgState) {
             update(msg, info, state, orgState);
         }
 
@@ -473,7 +473,7 @@
          */
         public void update(Message msg, String info, State state, State orgState) {
             mTime = System.currentTimeMillis();
-            mWhat = msg.what;
+            mWhat = (msg != null) ? msg.what : 0;
             mInfo = info;
             mState = state;
             mOrgState = orgState;
@@ -517,8 +517,7 @@
         /**
          * @return as string
          */
-        @Override
-        public String toString() {
+        public String toString(StateMachine sm) {
             StringBuilder sb = new StringBuilder();
             sb.append("time=");
             Calendar c = Calendar.getInstance();
@@ -529,10 +528,15 @@
             sb.append(" orgState=");
             sb.append(mOrgState == null ? "<null>" : mOrgState.getName());
             sb.append(" what=");
-            sb.append(mWhat);
-            sb.append("(0x");
-            sb.append(Integer.toHexString(mWhat));
-            sb.append(")");
+            String what = sm.getWhatToString(mWhat);
+            if (TextUtils.isEmpty(what)) {
+                sb.append(mWhat);
+                sb.append("(0x");
+                sb.append(Integer.toHexString(mWhat));
+                sb.append(")");
+            } else {
+                sb.append(what);
+            }
             if ( ! TextUtils.isEmpty(mInfo)) {
                 sb.append(" ");
                 sb.append(mInfo);
@@ -542,21 +546,21 @@
     }
 
     /**
-     * A list of messages recently processed by the state machine.
+     * A list of log records including messages recently processed by the state machine.
      *
-     * The class maintains a list of messages that have been most
+     * The class maintains a list of log records including messages
      * recently processed. The list is finite and may be set in the
      * constructor or by calling setSize. The public interface also
-     * includes size which returns the number of recent messages,
-     * count which is the number of message processed since the
-     * the last setSize, get which returns a processed message and
-     * add which adds a processed messaged.
+     * includes size which returns the number of recent records,
+     * count which is the number of records processed since the
+     * the last setSize, get which returns a record and
+     * add which adds a record.
      */
-    private static class ProcessedMessages {
+    private static class LogRecords {
 
         private static final int DEFAULT_SIZE = 20;
 
-        private Vector<ProcessedMessageInfo> mMessages = new Vector<ProcessedMessageInfo>();
+        private Vector<LogRec> mLogRecords = new Vector<LogRec>();
         private int mMaxSize = DEFAULT_SIZE;
         private int mOldestIndex = 0;
         private int mCount = 0;
@@ -564,39 +568,39 @@
         /**
          * private constructor use add
          */
-        private ProcessedMessages() {
+        private LogRecords() {
         }
 
         /**
-         * Set size of messages to maintain and clears all current messages.
+         * Set size of messages to maintain and clears all current records.
          *
-         * @param maxSize number of messages to maintain at anyone time.
+         * @param maxSize number of records to maintain at anyone time.
         */
-        void setSize(int maxSize) {
+        synchronized void setSize(int maxSize) {
             mMaxSize = maxSize;
             mCount = 0;
-            mMessages.clear();
+            mLogRecords.clear();
         }
 
         /**
-         * @return the number of recent messages.
+         * @return the number of recent records.
          */
-        int size() {
-            return mMessages.size();
+        synchronized int size() {
+            return mLogRecords.size();
         }
 
         /**
-         * @return the total number of messages processed since size was set.
+         * @return the total number of records processed since size was set.
          */
-        int count() {
+        synchronized int count() {
             return mCount;
         }
 
         /**
-         * Clear the list of Processed Message Info.
+         * Clear the list of records.
          */
-        void cleanup() {
-            mMessages.clear();
+        synchronized void cleanup() {
+            mLogRecords.clear();
         }
 
         /**
@@ -604,7 +608,7 @@
          * record and size()-1 is the newest record. If the index is to
          * large null is returned.
          */
-        ProcessedMessageInfo get(int index) {
+        synchronized LogRec get(int index) {
             int nextIndex = mOldestIndex + index;
             if (nextIndex >= mMaxSize) {
                 nextIndex -= mMaxSize;
@@ -612,7 +616,7 @@
             if (nextIndex >= size()) {
                 return null;
             } else {
-                return mMessages.get(nextIndex);
+                return mLogRecords.get(nextIndex);
             }
         }
 
@@ -625,12 +629,12 @@
          * @param orgState is the first state the received the message but
          * did not processes the message.
          */
-        void add(Message msg, String messageInfo, State state, State orgState) {
+        synchronized void add(Message msg, String messageInfo, State state, State orgState) {
             mCount += 1;
-            if (mMessages.size() < mMaxSize) {
-                mMessages.add(new ProcessedMessageInfo(msg, messageInfo, state, orgState));
+            if (mLogRecords.size() < mMaxSize) {
+                mLogRecords.add(new LogRec(msg, messageInfo, state, orgState));
             } else {
-                ProcessedMessageInfo pmi = mMessages.get(mOldestIndex);
+                LogRec pmi = mLogRecords.get(mOldestIndex);
                 mOldestIndex += 1;
                 if (mOldestIndex >= mMaxSize) {
                     mOldestIndex = 0;
@@ -652,8 +656,8 @@
         /** The current message */
         private Message mMsg;
 
-        /** A list of messages that this state machine has processed */
-        private ProcessedMessages mProcessedMessages = new ProcessedMessages();
+        /** A list of log records including messages this state machine has processed */
+        private LogRecords mLogRecords = new LogRecords();
 
         /** true if construction of the state machine has not been completed */
         private boolean mIsConstructionCompleted;
@@ -814,15 +818,18 @@
              */
             if (destState != null) {
                 if (destState == mQuittingState) {
+                    /**
+                     * Call onQuitting to let subclasses cleanup.
+                     */
+                    mSm.onQuitting();
                     cleanupAfterQuitting();
-
                 } else if (destState == mHaltingState) {
                     /**
-                     * Call halting() if we've transitioned to the halting
+                     * Call onHalting() if we've transitioned to the halting
                      * state. All subsequent messages will be processed in
                      * in the halting state which invokes haltedProcessMessage(msg);
                      */
-                    mSm.halting();
+                    mSm.onHalting();
                 }
             }
         }
@@ -831,7 +838,6 @@
          * Cleanup all the static variables and the looper after the SM has been quit.
          */
         private final void cleanupAfterQuitting() {
-            mSm.quitting();
             if (mSm.mSmThread != null) {
                 // If we made the thread then quit looper which stops the thread.
                 getLooper().quit();
@@ -841,7 +847,7 @@
             mSm.mSmHandler = null;
             mSm = null;
             mMsg = null;
-            mProcessedMessages.cleanup();
+            mLogRecords.cleanup();
             mStateStack = null;
             mTempStateStack = null;
             mStateInfo.clear();
@@ -892,36 +898,38 @@
             if (mDbg) {
                 Log.d(TAG, "processMsg: " + curStateInfo.state.getName());
             }
-            while (!curStateInfo.state.processMessage(msg)) {
-                /**
-                 * Not processed
-                 */
-                curStateInfo = curStateInfo.parentStateInfo;
-                if (curStateInfo == null) {
-                    /**
-                     * No parents left so it's not handled
-                     */
-                    mSm.unhandledMessage(msg);
-                    if (isQuit(msg)) {
-                        transitionTo(mQuittingState);
-                    }
-                    break;
-                }
-                if (mDbg) {
-                    Log.d(TAG, "processMsg: " + curStateInfo.state.getName());
-                }
-            }
 
-            /**
-             * Record that we processed the message
-             */
-            if (mSm.recordProcessedMessage(msg)) {
-                if (curStateInfo != null) {
-                    State orgState = mStateStack[mStateStackTopIndex].state;
-                    mProcessedMessages.add(msg, mSm.getMessageInfo(msg), curStateInfo.state,
-                            orgState);
-                } else {
-                    mProcessedMessages.add(msg, mSm.getMessageInfo(msg), null, null);
+            if (isQuit(msg)) {
+                transitionTo(mQuittingState);
+            } else {
+                while (!curStateInfo.state.processMessage(msg)) {
+                    /**
+                     * Not processed
+                     */
+                    curStateInfo = curStateInfo.parentStateInfo;
+                    if (curStateInfo == null) {
+                        /**
+                         * No parents left so it's not handled
+                         */
+                        mSm.unhandledMessage(msg);
+                        break;
+                    }
+                    if (mDbg) {
+                        Log.d(TAG, "processMsg: " + curStateInfo.state.getName());
+                    }
+                }
+
+                /**
+                 * Record that we processed the message
+                 */
+                if (mSm.recordLogRec(msg)) {
+                    if (curStateInfo != null) {
+                        State orgState = mStateStack[mStateStackTopIndex].state;
+                        mLogRecords.add(msg, mSm.getLogRecString(msg), curStateInfo.state,
+                                orgState);
+                    } else {
+                        mLogRecords.add(msg, mSm.getLogRecString(msg), null, null);
+                    }
                 }
             }
         }
@@ -1141,13 +1149,19 @@
             mDeferredMessages.add(newMsg);
         }
 
-        /** @see StateMachine#deferMessage(Message) */
+        /** @see StateMachine#quit() */
         private final void quit() {
             if (mDbg) Log.d(TAG, "quit:");
             sendMessage(obtainMessage(SM_QUIT_CMD, mSmHandlerObj));
         }
 
-        /** @see StateMachine#isQuit(Message) */
+        /** @see StateMachine#quitNow() */
+        private final void quitNow() {
+            if (mDbg) Log.d(TAG, "abort:");
+            sendMessageAtFrontOfQueue(obtainMessage(SM_QUIT_CMD, mSmHandlerObj));
+        }
+
+        /** Validate that the message was sent by quit or abort. */
         private final boolean isQuit(Message msg) {
             return (msg.what == SM_QUIT_CMD) && (msg.obj == mSmHandlerObj);
         }
@@ -1162,26 +1176,6 @@
             mDbg = dbg;
         }
 
-        /** @see StateMachine#setProcessedMessagesSize(int) */
-        private final void setProcessedMessagesSize(int maxSize) {
-            mProcessedMessages.setSize(maxSize);
-        }
-
-        /** @see StateMachine#getProcessedMessagesSize() */
-        private final int getProcessedMessagesSize() {
-            return mProcessedMessages.size();
-        }
-
-        /** @see StateMachine#getProcessedMessagesCount() */
-        private final int getProcessedMessagesCount() {
-            return mProcessedMessages.count();
-        }
-
-        /** @see StateMachine#getProcessedMessageInfo(int) */
-        private final ProcessedMessageInfo getProcessedMessageInfo(int index) {
-            return mProcessedMessages.get(index);
-        }
-
     }
 
     private SmHandler mSmHandler;
@@ -1282,8 +1276,8 @@
     /**
      * transition to halt state. Upon returning
      * from processMessage we will exit all current
-     * states, execute the halting() method and then
-     * all subsequent messages haltedProcessMesage
+     * states, execute the onHalting() method and then
+     * for all subsequent messages haltedProcessMessage
      * will be called.
      */
     protected final void transitionToHaltingState() {
@@ -1303,7 +1297,6 @@
         mSmHandler.deferMessage(msg);
     }
 
-
     /**
      * Called when message wasn't handled
      *
@@ -1325,7 +1318,7 @@
      * transitionToHalting. All subsequent messages will invoke
      * {@link StateMachine#haltedProcessMessage(Message)}
      */
-    protected void halting() {
+    protected void onHalting() {
     }
 
     /**
@@ -1334,7 +1327,7 @@
      * ignored. In addition, if this StateMachine created the thread, the thread will
      * be stopped after this method returns.
      */
-    protected void quitting() {
+    protected void onQuitting() {
     }
 
     /**
@@ -1345,33 +1338,77 @@
     }
 
     /**
-     * Set size of messages to maintain and clears all current messages.
+     * Set number of log records to maintain and clears all current records.
      *
      * @param maxSize number of messages to maintain at anyone time.
      */
-    public final void setProcessedMessagesSize(int maxSize) {
-        mSmHandler.setProcessedMessagesSize(maxSize);
+    public final void setLogRecSize(int maxSize) {
+        mSmHandler.mLogRecords.setSize(maxSize);
     }
 
     /**
-     * @return number of messages processed
+     * @return number of log records
      */
-    public final int getProcessedMessagesSize() {
-        return mSmHandler.getProcessedMessagesSize();
+    public final int getLogRecSize() {
+        return mSmHandler.mLogRecords.size();
     }
 
     /**
-     * @return the total number of messages processed
+     * @return the total number of records processed
      */
-    public final int getProcessedMessagesCount() {
-        return mSmHandler.getProcessedMessagesCount();
+    public final int getLogRecCount() {
+        return mSmHandler.mLogRecords.count();
     }
 
     /**
-     * @return a processed message information
+     * @return a log record
      */
-    public final ProcessedMessageInfo getProcessedMessageInfo(int index) {
-        return mSmHandler.getProcessedMessageInfo(index);
+    public final LogRec getLogRec(int index) {
+        return mSmHandler.mLogRecords.get(index);
+    }
+
+    /**
+     * Add the string to LogRecords.
+     *
+     * @param string
+     */
+    protected void addLogRec(String string) {
+        mSmHandler.mLogRecords.add(null, string, null, null);
+    }
+
+    /**
+     * Add the string and state to LogRecords
+     *
+     * @param string
+     * @param state current state
+     */
+    protected void addLogRec(String string, State state) {
+        mSmHandler.mLogRecords.add(null, string, state, null);
+    }
+
+    /**
+     * @return true if msg should be saved in the log, default is true.
+     */
+    protected boolean recordLogRec(Message msg) {
+        return true;
+    }
+
+    /**
+     * Return a string to be logged by LogRec, default
+     * is an empty string. Override if additional information is desired.
+     *
+     * @param msg that was processed
+     * @return information to be logged as a String
+     */
+    protected String getLogRecString(Message msg) {
+        return "";
+    }
+
+    /**
+     * @return the string for msg.what
+     */
+    protected String getWhatToString(int what) {
+        return null;
     }
 
     /**
@@ -1548,43 +1585,23 @@
     }
 
     /**
-     * Conditionally quit the looper and stop execution.
-     *
-     * This sends the SM_QUIT_MSG to the state machine and
-     * if not handled by any state's processMessage then the
-     * state machine will be stopped and no further messages
-     * will be processed.
+     * Quit the state machine after all currently queued up messages are processed.
      */
-    public final void quit() {
-        // mSmHandler can be null if the state machine has quit.
+    protected final void quit() {
+        // mSmHandler can be null if the state machine is already stopped.
         if (mSmHandler == null) return;
 
         mSmHandler.quit();
     }
 
     /**
-     * @return ture if msg is quit
+     * Quit the state machine immediately all currently queued messages will be discarded.
      */
-    protected final boolean isQuit(Message msg) {
-        return mSmHandler.isQuit(msg);
-    }
+    protected final void quitNow() {
+        // mSmHandler can be null if the state machine is already stopped.
+        if (mSmHandler == null) return;
 
-    /**
-     * @return true if msg should be saved in ProcessedMessage, default is true.
-     */
-    protected boolean recordProcessedMessage(Message msg) {
-        return true;
-    }
-
-    /**
-     * Return message info to be logged by ProcessedMessageInfo, default
-     * is an empty string. Override if additional information is desired.
-     *
-     * @param msg that was processed
-     * @return information to be logged as a String
-     */
-    protected String getMessageInfo(Message msg) {
-        return "";
+        mSmHandler.quitNow();
     }
 
     /**
@@ -1629,9 +1646,9 @@
      */
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println(getName() + ":");
-        pw.println(" total messages=" + getProcessedMessagesCount());
-        for (int i=0; i < getProcessedMessagesSize(); i++) {
-            pw.printf(" msg[%d]: %s\n", i, getProcessedMessageInfo(i));
+        pw.println(" total records=" + getLogRecCount());
+        for (int i=0; i < getLogRecSize(); i++) {
+            pw.printf(" rec[%d]: %s\n", i, getLogRec(i).toString(this));
             pw.flush();
         }
         pw.println("curState=" + getCurrentState().getName());
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
index 73324c0..cf6029e 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -278,7 +278,7 @@
      */
     public boolean showOverflowMenu() {
         if (mReserveOverflow && !isOverflowMenuShowing() && mMenu != null && mMenuView != null &&
-                mPostedOpenRunnable == null) {
+                mPostedOpenRunnable == null && !mMenu.getNonActionItems().isEmpty()) {
             OverflowPopup popup = new OverflowPopup(mContext, mMenu, mOverflowButton, true);
             mPostedOpenRunnable = new OpenOverflowRunnable(popup);
             // Post this for later; we might still need a layout for the anchor to be right.
diff --git a/core/java/com/android/internal/view/menu/ActionMenuView.java b/core/java/com/android/internal/view/menu/ActionMenuView.java
index f54575b..cef6a8f 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuView.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuView.java
@@ -524,6 +524,9 @@
 
     @Override
     protected boolean hasDividerBeforeChildAt(int childIndex) {
+        if (childIndex == 0) {
+            return false;
+        }
         final View childBefore = getChildAt(childIndex - 1);
         final View child = getChildAt(childIndex);
         boolean result = false;
diff --git a/core/java/com/google/android/mms/ContentType.java b/core/java/com/google/android/mms/ContentType.java
deleted file mode 100644
index 12a1343..0000000
--- a/core/java/com/google/android/mms/ContentType.java
+++ /dev/null
@@ -1,229 +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.google.android.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 IMAGE_X_MS_BMP    = "image/x-ms-bmp";
-
-    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_X_WAV       = "audio/x-wav";
-    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);
-        sSupportedContentTypes.add(IMAGE_X_MS_BMP);
-        //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_X_WAV);
-        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);
-        sSupportedImageTypes.add(IMAGE_X_MS_BMP);
-
-        // 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_X_WAV);
-        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/core/java/com/google/android/mms/InvalidHeaderValueException.java b/core/java/com/google/android/mms/InvalidHeaderValueException.java
deleted file mode 100644
index 73d7832..0000000
--- a/core/java/com/google/android/mms/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.google.android.mms;
-
-/**
- * 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/core/java/com/google/android/mms/MmsException.java b/core/java/com/google/android/mms/MmsException.java
deleted file mode 100644
index 6ca0c7e..0000000
--- a/core/java/com/google/android/mms/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.google.android.mms;
-
-/**
- * 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/core/java/com/google/android/mms/package.html b/core/java/com/google/android/mms/package.html
deleted file mode 100755
index c9f96a6..0000000
--- a/core/java/com/google/android/mms/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<body>
-
-{@hide}
-
-</body>
diff --git a/core/java/com/google/android/mms/pdu/AcknowledgeInd.java b/core/java/com/google/android/mms/pdu/AcknowledgeInd.java
deleted file mode 100644
index 0e96c60..0000000
--- a/core/java/com/google/android/mms/pdu/AcknowledgeInd.java
+++ /dev/null
@@ -1,89 +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.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-/**
- * 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/core/java/com/google/android/mms/pdu/Base64.java b/core/java/com/google/android/mms/pdu/Base64.java
deleted file mode 100644
index 604bee0..0000000
--- a/core/java/com/google/android/mms/pdu/Base64.java
+++ /dev/null
@@ -1,167 +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.google.android.mms.pdu;
-
-public class Base64 {
-    /**
-     * Used to get the number of Quadruples.
-     */
-    static final int FOURBYTE = 4;
-
-    /**
-     * Byte used to pad output.
-     */
-    static final byte PAD = (byte) '=';
-
-    /**
-     * The base length.
-     */
-    static final int BASELENGTH = 255;
-
-    // Create arrays to hold the base64 characters
-    private static byte[] base64Alphabet = new byte[BASELENGTH];
-
-    // Populating the character arrays
-    static {
-        for (int i = 0; i < BASELENGTH; i++) {
-            base64Alphabet[i] = (byte) -1;
-        }
-        for (int i = 'Z'; i >= 'A'; i--) {
-            base64Alphabet[i] = (byte) (i - 'A');
-        }
-        for (int i = 'z'; i >= 'a'; i--) {
-            base64Alphabet[i] = (byte) (i - 'a' + 26);
-        }
-        for (int i = '9'; i >= '0'; i--) {
-            base64Alphabet[i] = (byte) (i - '0' + 52);
-        }
-
-        base64Alphabet['+'] = 62;
-        base64Alphabet['/'] = 63;
-    }
-
-    /**
-     * Decodes Base64 data into octects
-     *
-     * @param base64Data Byte array containing Base64 data
-     * @return Array containing decoded data.
-     */
-    public static byte[] decodeBase64(byte[] base64Data) {
-        // RFC 2045 requires that we discard ALL non-Base64 characters
-        base64Data = discardNonBase64(base64Data);
-
-        // handle the edge case, so we don't have to worry about it later
-        if (base64Data.length == 0) {
-            return new byte[0];
-        }
-
-        int numberQuadruple = base64Data.length / FOURBYTE;
-        byte decodedData[] = null;
-        byte b1 = 0, b2 = 0, b3 = 0, b4 = 0, marker0 = 0, marker1 = 0;
-
-        // Throw away anything not in base64Data
-
-        int encodedIndex = 0;
-        int dataIndex = 0;
-        {
-            // this sizes the output array properly - rlw
-            int lastData = base64Data.length;
-            // ignore the '=' padding
-            while (base64Data[lastData - 1] == PAD) {
-                if (--lastData == 0) {
-                    return new byte[0];
-                }
-            }
-            decodedData = new byte[lastData - numberQuadruple];
-        }
-
-        for (int i = 0; i < numberQuadruple; i++) {
-            dataIndex = i * 4;
-            marker0 = base64Data[dataIndex + 2];
-            marker1 = base64Data[dataIndex + 3];
-
-            b1 = base64Alphabet[base64Data[dataIndex]];
-            b2 = base64Alphabet[base64Data[dataIndex + 1]];
-
-            if (marker0 != PAD && marker1 != PAD) {
-                //No PAD e.g 3cQl
-                b3 = base64Alphabet[marker0];
-                b4 = base64Alphabet[marker1];
-
-                decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
-                decodedData[encodedIndex + 1] =
-                    (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
-                decodedData[encodedIndex + 2] = (byte) (b3 << 6 | b4);
-            } else if (marker0 == PAD) {
-                //Two PAD e.g. 3c[Pad][Pad]
-                decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
-            } else if (marker1 == PAD) {
-                //One PAD e.g. 3cQ[Pad]
-                b3 = base64Alphabet[marker0];
-
-                decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
-                decodedData[encodedIndex + 1] =
-                    (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
-            }
-            encodedIndex += 3;
-        }
-        return decodedData;
-    }
-
-    /**
-     * Check octect wheter it is a base64 encoding.
-     *
-     * @param octect to be checked byte
-     * @return ture if it is base64 encoding, false otherwise.
-     */
-    private static boolean isBase64(byte octect) {
-        if (octect == PAD) {
-            return true;
-        } else if (base64Alphabet[octect] == -1) {
-            return false;
-        } else {
-            return true;
-        }
-    }
-
-    /**
-     * Discards any characters outside of the base64 alphabet, per
-     * the requirements on page 25 of RFC 2045 - "Any characters
-     * outside of the base64 alphabet are to be ignored in base64
-     * encoded data."
-     *
-     * @param data The base-64 encoded data to groom
-     * @return The data, less non-base64 characters (see RFC 2045).
-     */
-    static byte[] discardNonBase64(byte[] data) {
-        byte groomedData[] = new byte[data.length];
-        int bytesCopied = 0;
-
-        for (int i = 0; i < data.length; i++) {
-            if (isBase64(data[i])) {
-                groomedData[bytesCopied++] = data[i];
-            }
-        }
-
-        byte packedData[] = new byte[bytesCopied];
-
-        System.arraycopy(groomedData, 0, packedData, 0, bytesCopied);
-
-        return packedData;
-    }
-}
diff --git a/core/java/com/google/android/mms/pdu/CharacterSets.java b/core/java/com/google/android/mms/pdu/CharacterSets.java
deleted file mode 100644
index 4e22ca5..0000000
--- a/core/java/com/google/android/mms/pdu/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.google.android.mms.pdu;
-
-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/core/java/com/google/android/mms/pdu/DeliveryInd.java b/core/java/com/google/android/mms/pdu/DeliveryInd.java
deleted file mode 100644
index dafa8d1..0000000
--- a/core/java/com/google/android/mms/pdu/DeliveryInd.java
+++ /dev/null
@@ -1,138 +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.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-/**
- * 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/core/java/com/google/android/mms/pdu/EncodedStringValue.java b/core/java/com/google/android/mms/pdu/EncodedStringValue.java
deleted file mode 100644
index 9495c1c..0000000
--- a/core/java/com/google/android/mms/pdu/EncodedStringValue.java
+++ /dev/null
@@ -1,283 +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.google.android.mms.pdu;
-
-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 = false;
-
-    /**
-     * 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/core/java/com/google/android/mms/pdu/GenericPdu.java b/core/java/com/google/android/mms/pdu/GenericPdu.java
deleted file mode 100644
index 705de6a..0000000
--- a/core/java/com/google/android/mms/pdu/GenericPdu.java
+++ /dev/null
@@ -1,113 +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.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-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/core/java/com/google/android/mms/pdu/MultimediaMessagePdu.java b/core/java/com/google/android/mms/pdu/MultimediaMessagePdu.java
deleted file mode 100644
index 5a85e0e..0000000
--- a/core/java/com/google/android/mms/pdu/MultimediaMessagePdu.java
+++ /dev/null
@@ -1,150 +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.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-/**
- * 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/core/java/com/google/android/mms/pdu/NotificationInd.java b/core/java/com/google/android/mms/pdu/NotificationInd.java
deleted file mode 100644
index c56cba6..0000000
--- a/core/java/com/google/android/mms/pdu/NotificationInd.java
+++ /dev/null
@@ -1,285 +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.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-/**
- * 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/core/java/com/google/android/mms/pdu/NotifyRespInd.java b/core/java/com/google/android/mms/pdu/NotifyRespInd.java
deleted file mode 100644
index 2cc2fce..0000000
--- a/core/java/com/google/android/mms/pdu/NotifyRespInd.java
+++ /dev/null
@@ -1,114 +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.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-/**
- * 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/core/java/com/google/android/mms/pdu/PduBody.java b/core/java/com/google/android/mms/pdu/PduBody.java
deleted file mode 100644
index fa0416c..0000000
--- a/core/java/com/google/android/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.google.android.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/core/java/com/google/android/mms/pdu/PduComposer.java b/core/java/com/google/android/mms/pdu/PduComposer.java
deleted file mode 100644
index d426f89..0000000
--- a/core/java/com/google/android/mms/pdu/PduComposer.java
+++ /dev/null
@@ -1,1179 +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.google.android.mms.pdu;
-
-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
-        return makeMessageBody();
-    }
-
-    /**
-     * 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/core/java/com/google/android/mms/pdu/PduContentTypes.java b/core/java/com/google/android/mms/pdu/PduContentTypes.java
deleted file mode 100644
index 7799e0e..0000000
--- a/core/java/com/google/android/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.google.android.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/core/java/com/google/android/mms/pdu/PduHeaders.java b/core/java/com/google/android/mms/pdu/PduHeaders.java
deleted file mode 100644
index 4313815..0000000
--- a/core/java/com/google/android/mms/pdu/PduHeaders.java
+++ /dev/null
@@ -1,721 +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.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-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.
-     */
-    protected 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.
-     */
-    protected 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
-     */
-    protected 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.
-     */
-    protected 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
-     */
-    protected 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
-     */
-    protected 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.
-     */
-    protected 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.
-     */
-    protected 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.
-     */
-    protected 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.
-     */
-    protected 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
-     */
-    protected 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/core/java/com/google/android/mms/pdu/PduParser.java b/core/java/com/google/android/mms/pdu/PduParser.java
deleted file mode 100755
index 015d864..0000000
--- a/core/java/com/google/android/mms/pdu/PduParser.java
+++ /dev/null
@@ -1,1912 +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.google.android.mms.pdu;
-
-import com.google.android.mms.ContentType;
-import com.google.android.mms.InvalidHeaderValueException;
-
-import android.util.Log;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.Arrays;
-import java.util.HashMap;
-
-import android.content.res.Resources;
-
-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 = false;
-
-    /**
-     * 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;
-                } else if (ctTypeStr.equals(ContentType.MULTIPART_ALTERNATIVE)) {
-                    // "application/vnd.wap.multipart.alternative"
-                    // should take only the first part.
-                    PduPart firstPart = mBody.getPart(0);
-                    mBody.removeAll();
-                    mBody.addPart(0, firstPart);
-                    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)) {
-            pduDataStream.mark(1);
-            int headerField = extractByteValue(pduDataStream);
-            /* parse custom text header */
-            if ((headerField >= TEXT_MIN) && (headerField <= TEXT_MAX)) {
-                pduDataStream.reset();
-                byte [] bVal = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-                if (LOCAL_LOGV) {
-                    Log.v(LOG_TAG, "TextHeader: " + new String(bVal));
-                }
-                /* we should ignore it at the moment */
-                continue;
-            }
-            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];
-                String partContentType = new String(part.getContentType());
-                pduDataStream.read(partData, 0, dataLength);
-                if (partContentType.equalsIgnoreCase(ContentType.MULTIPART_ALTERNATIVE)) {
-                    // parse "multipart/vnd.wap.multipart.alternative".
-                    PduBody childBody = parseParts(new ByteArrayInputStream(partData));
-                    // take the first part of children.
-                    part = childBody.getPart(0);
-                } else {
-                    // 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.decodeBase64(partData);
-                        } 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;
-        if (first == 0) {
-            return null;    //  Blank subject, bail.
-        }
-
-        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>
-                         */
-
-                        /*
-                         * some carrier mmsc servers do not support content_disposition
-                         * field correctly
-                         */
-                        boolean contentDisposition = Resources.getSystem().getBoolean(com
-                                .android.internal.R.bool.config_mms_content_disposition_support);
-
-                        if (contentDisposition) {
-                            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/core/java/com/google/android/mms/pdu/PduPart.java b/core/java/com/google/android/mms/pdu/PduPart.java
deleted file mode 100644
index b43e388..0000000
--- a/core/java/com/google/android/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.google.android.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/core/java/com/google/android/mms/pdu/PduPersister.java b/core/java/com/google/android/mms/pdu/PduPersister.java
deleted file mode 100644
index ee285aa..0000000
--- a/core/java/com/google/android/mms/pdu/PduPersister.java
+++ /dev/null
@@ -1,1477 +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.google.android.mms.pdu;
-
-import com.google.android.mms.ContentType;
-import com.google.android.mms.InvalidHeaderValueException;
-import com.google.android.mms.MmsException;
-import com.google.android.mms.util.DownloadDrmHelper;
-import com.google.android.mms.util.DrmConvertSession;
-import com.google.android.mms.util.PduCache;
-import com.google.android.mms.util.PduCacheEntry;
-import com.google.android.mms.util.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.database.sqlite.SQLiteException;
-import android.drm.DrmManagerClient;
-import android.net.Uri;
-import android.os.FileUtils;
-import android.provider.MediaStore;
-import android.provider.Telephony;
-import android.provider.Telephony.Mms;
-import android.provider.Telephony.MmsSms;
-import android.provider.Telephony.Threads;
-import android.provider.Telephony.Mms.Addr;
-import android.provider.Telephony.Mms.Part;
-import android.provider.Telephony.MmsSms.PendingMessages;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-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;
-
-import com.google.android.mms.pdu.EncodedStringValue;
-
-/**
- * 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 = false;
-
-    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 final DrmManagerClient mDrmManagerClient;
-
-    private PduPersister(Context context) {
-        mContext = context;
-        mContentResolver = context.getContentResolver();
-        mDrmManagerClient = new DrmManagerClient(context);
-     }
-
-    /** 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);
-                        byte [] blob = new EncodedStringValue(text != null ? 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 {
-        GenericPdu pdu = null;
-        PduCacheEntry cacheEntry = null;
-        int msgBox = 0;
-        long threadId = -1;
-        try {
-            synchronized(PDU_CACHE_INSTANCE) {
-                if (PDU_CACHE_INSTANCE.isUpdating(uri)) {
-                    if (LOCAL_LOGV) {
-                        Log.v(TAG, "load: " + uri + " blocked by isUpdating()");
-                    }
-                    try {
-                        PDU_CACHE_INSTANCE.wait();
-                    } catch (InterruptedException e) {
-                        Log.e(TAG, "load: ", e);
-                    }
-                    cacheEntry = PDU_CACHE_INSTANCE.get(uri);
-                    if (cacheEntry != null) {
-                        return cacheEntry.getPdu();
-                    }
-                }
-                // Tell the cache to indicate to other callers that this item
-                // is currently being updated.
-                PDU_CACHE_INSTANCE.setUpdating(uri, true);
-            }
-
-            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);
-
-            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]);
-                    }
-                }
-            }
-
-            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));
-            }
-        } finally {
-            synchronized(PDU_CACHE_INSTANCE) {
-                if (pdu != null) {
-                    assert(PDU_CACHE_INSTANCE.get(uri) == null);
-                    // Update the cache entry with the real info
-                    cacheEntry = new PduCacheEntry(pdu, msgBox, threadId);
-                    PDU_CACHE_INSTANCE.put(uri, cacheEntry);
-                }
-                PDU_CACHE_INSTANCE.setUpdating(uri, false);
-                PDU_CACHE_INSTANCE.notifyAll(); // tell anybody waiting on this entry to go ahead
-            }
-        }
-        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());
-
-            // There is no "image/jpg" in Android (and it's an invalid mimetype).
-            // Change it to "image/jpeg"
-            if (ContentType.IMAGE_JPG.equals(contentType)) {
-                contentType = ContentType.IMAGE_JPEG;
-            }
-
-            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;
-        DrmConvertSession drmConvertSession = null;
-        Uri dataUri = null;
-        String path = 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(Telephony.Mms.Part.TEXT, new EncodedStringValue(data).getString());
-                if (mContentResolver.update(uri, cv, null, null) != 1) {
-                    throw new MmsException("unable to update " + uri.toString());
-                }
-            } else {
-                boolean isDrm = DownloadDrmHelper.isDrmConvertNeeded(contentType);
-                if (isDrm) {
-                    if (uri != null) {
-                        try {
-                            path = convertUriToPath(mContext, uri);
-                            if (LOCAL_LOGV) {
-                                Log.v(TAG, "drm uri: " + uri + " path: " + path);
-                            }
-                            File f = new File(path);
-                            long len = f.length();
-                            if (LOCAL_LOGV) {
-                                Log.v(TAG, "drm path: " + path + " len: " + len);
-                            }
-                            if (len > 0) {
-                                // we're not going to re-persist and re-encrypt an already
-                                // converted drm file
-                                return;
-                            }
-                        } catch (Exception e) {
-                            Log.e(TAG, "Can't get file info for: " + part.getDataUri(), e);
-                        }
-                    }
-                    // We haven't converted the file yet, start the conversion
-                    drmConvertSession = DrmConvertSession.open(mContext, contentType);
-                    if (drmConvertSession == null) {
-                        throw new MmsException("Mimetype " + contentType +
-                                " can not be converted.");
-                    }
-                }
-                os = mContentResolver.openOutputStream(uri);
-                if (data == null) {
-                    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[8192];
-                    for (int len = 0; (len = is.read(buffer)) != -1; ) {
-                        if (!isDrm) {
-                            os.write(buffer, 0, len);
-                        } else {
-                            byte[] convertedData = drmConvertSession.convert(buffer, len);
-                            if (convertedData != null) {
-                                os.write(convertedData, 0, convertedData.length);
-                            } else {
-                                throw new MmsException("Error converting drm data.");
-                            }
-                        }
-                    }
-                } else {
-                    if (LOCAL_LOGV) {
-                        Log.v(TAG, "Saving data to: " + uri);
-                    }
-                    if (!isDrm) {
-                        os.write(data);
-                    } else {
-                        dataUri = uri;
-                        byte[] convertedData = drmConvertSession.convert(data, data.length);
-                        if (convertedData != null) {
-                            os.write(convertedData, 0, convertedData.length);
-                        } else {
-                            throw new MmsException("Error converting drm 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
-            }
-            if (drmConvertSession != null) {
-                drmConvertSession.close(path);
-
-                // Reset the permissions on the encrypted part file so everyone has only read
-                // permission.
-                File f = new File(path);
-                ContentValues values = new ContentValues(0);
-                SqliteWrapper.update(mContext, mContentResolver,
-                                     Uri.parse("content://mms/resetFilePerm/" + f.getName()),
-                                     values, null, null);
-            }
-        }
-    }
-
-    /**
-     * This method expects uri in the following format
-     *     content://media/<table_name>/<row_index> (or)
-     *     file://sdcard/test.mp4
-     *     http://test.com/test.mp4
-     *
-     * Here <table_name> shall be "video" or "audio" or "images"
-     * <row_index> the index of the content in given table
-     */
-    static public String convertUriToPath(Context context, Uri uri) {
-        String path = null;
-        if (null != uri) {
-            String scheme = uri.getScheme();
-            if (null == scheme || scheme.equals("") ||
-                    scheme.equals(ContentResolver.SCHEME_FILE)) {
-                path = uri.getPath();
-
-            } else if (scheme.equals("http")) {
-                path = uri.toString();
-
-            } else if (scheme.equals(ContentResolver.SCHEME_CONTENT)) {
-                String[] projection = new String[] {MediaStore.MediaColumns.DATA};
-                Cursor cursor = null;
-                try {
-                    cursor = context.getContentResolver().query(uri, projection, null,
-                            null, null);
-                    if (null == cursor || 0 == cursor.getCount() || !cursor.moveToFirst()) {
-                        throw new IllegalArgumentException("Given Uri could not be found" +
-                                " in media store");
-                    }
-                    int pathIndex = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
-                    path = cursor.getString(pathIndex);
-                } catch (SQLiteException e) {
-                    throw new IllegalArgumentException("Given Uri is not formatted in a way " +
-                            "so that it can be found in media store.");
-                } finally {
-                    if (null != cursor) {
-                        cursor.close();
-                    }
-                }
-            } else {
-                throw new IllegalArgumentException("Given Uri scheme is not supported");
-            }
-        }
-        return path;
-    }
-
-    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) {
-        synchronized(PDU_CACHE_INSTANCE) {
-            // If the cache item is getting updated, wait until it's done updating before
-            // purging it.
-            if (PDU_CACHE_INSTANCE.isUpdating(uri)) {
-                if (LOCAL_LOGV) {
-                    Log.v(TAG, "updateHeaders: " + uri + " blocked by isUpdating()");
-                }
-                try {
-                    PDU_CACHE_INSTANCE.wait();
-                } catch (InterruptedException e) {
-                    Log.e(TAG, "updateHeaders: ", e);
-                }
-            }
-        }
-        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());
-                        }
-                    }
-                }
-            }
-        }
-        if (!recipients.isEmpty()) {
-            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 {
-        try {
-            PduCacheEntry cacheEntry;
-            synchronized(PDU_CACHE_INSTANCE) {
-                if (PDU_CACHE_INSTANCE.isUpdating(uri)) {
-                    if (LOCAL_LOGV) {
-                        Log.v(TAG, "updateParts: " + uri + " blocked by isUpdating()");
-                    }
-                    try {
-                        PDU_CACHE_INSTANCE.wait();
-                    } catch (InterruptedException e) {
-                        Log.e(TAG, "updateParts: ", e);
-                    }
-                    cacheEntry = PDU_CACHE_INSTANCE.get(uri);
-                    if (cacheEntry != null) {
-                        ((MultimediaMessagePdu) cacheEntry.getPdu()).setBody(body);
-                    }
-                }
-                // Tell the cache to indicate to other callers that this item
-                // is currently being updated.
-                PDU_CACHE_INSTANCE.setUpdating(uri, true);
-            }
-
-            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());
-            }
-        } finally {
-            synchronized(PDU_CACHE_INSTANCE) {
-                PDU_CACHE_INSTANCE.setUpdating(uri, false);
-                PDU_CACHE_INSTANCE.notifyAll();
-            }
-        }
-    }
-
-    /**
-     * 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.");
-        }
-        long msgId = -1;
-        try {
-            msgId = ContentUris.parseId(uri);
-        } catch (NumberFormatException e) {
-            // the uri ends with "inbox" or something else like that
-        }
-        boolean existingUri = msgId != -1;
-
-        if (!existingUri && MESSAGE_BOX_MAP.get(uri) == 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.");
-        }
-        synchronized(PDU_CACHE_INSTANCE) {
-            // If the cache item is getting updated, wait until it's done updating before
-            // purging it.
-            if (PDU_CACHE_INSTANCE.isUpdating(uri)) {
-                if (LOCAL_LOGV) {
-                    Log.v(TAG, "persist: " + uri + " blocked by isUpdating()");
-                }
-                try {
-                    PDU_CACHE_INSTANCE.wait();
-                } catch (InterruptedException e) {
-                    Log.e(TAG, "persist1: ", e);
-                }
-            }
-        }
-        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>();
-        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());
-                    }
-                }
-            }
-            if (!recipients.isEmpty()) {
-                long 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);
-                }
-            }
-        }
-
-        Uri res = null;
-        if (existingUri) {
-            res = uri;
-            SqliteWrapper.update(mContext, mContentResolver, res, values, null, null);
-        } else {
-            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.
-            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???
-        if (!existingUri) {
-            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/core/java/com/google/android/mms/pdu/QuotedPrintable.java b/core/java/com/google/android/mms/pdu/QuotedPrintable.java
deleted file mode 100644
index a34ed12..0000000
--- a/core/java/com/google/android/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.google.android.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/core/java/com/google/android/mms/pdu/ReadOrigInd.java b/core/java/com/google/android/mms/pdu/ReadOrigInd.java
deleted file mode 100644
index 1bfc0bb..0000000
--- a/core/java/com/google/android/mms/pdu/ReadOrigInd.java
+++ /dev/null
@@ -1,153 +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.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-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/core/java/com/google/android/mms/pdu/ReadRecInd.java b/core/java/com/google/android/mms/pdu/ReadRecInd.java
deleted file mode 100644
index 880e3ac..0000000
--- a/core/java/com/google/android/mms/pdu/ReadRecInd.java
+++ /dev/null
@@ -1,144 +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.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-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/core/java/com/google/android/mms/pdu/RetrieveConf.java b/core/java/com/google/android/mms/pdu/RetrieveConf.java
deleted file mode 100644
index 98e67c0..0000000
--- a/core/java/com/google/android/mms/pdu/RetrieveConf.java
+++ /dev/null
@@ -1,300 +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.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-/**
- * 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/core/java/com/google/android/mms/pdu/SendConf.java b/core/java/com/google/android/mms/pdu/SendConf.java
deleted file mode 100644
index 0568fe79..0000000
--- a/core/java/com/google/android/mms/pdu/SendConf.java
+++ /dev/null
@@ -1,117 +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.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-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/core/java/com/google/android/mms/pdu/SendReq.java b/core/java/com/google/android/mms/pdu/SendReq.java
deleted file mode 100644
index 597cd00..0000000
--- a/core/java/com/google/android/mms/pdu/SendReq.java
+++ /dev/null
@@ -1,345 +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.google.android.mms.pdu;
-
-import android.util.Log;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-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/core/java/com/google/android/mms/pdu/package.html b/core/java/com/google/android/mms/pdu/package.html
deleted file mode 100755
index c9f96a6..0000000
--- a/core/java/com/google/android/mms/pdu/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<body>
-
-{@hide}
-
-</body>
diff --git a/core/java/com/google/android/mms/util/AbstractCache.java b/core/java/com/google/android/mms/util/AbstractCache.java
deleted file mode 100644
index 39b2abf..0000000
--- a/core/java/com/google/android/mms/util/AbstractCache.java
+++ /dev/null
@@ -1,112 +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.google.android.mms.util;
-
-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 = false;
-
-    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/core/java/com/google/android/mms/util/DownloadDrmHelper.java b/core/java/com/google/android/mms/util/DownloadDrmHelper.java
deleted file mode 100644
index 6852eca..0000000
--- a/core/java/com/google/android/mms/util/DownloadDrmHelper.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2012 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.google.android.mms.util;
-
-import android.content.Context;
-import android.drm.DrmManagerClient;
-import android.util.Log;
-
-public class DownloadDrmHelper {
-    private static final String TAG = "DownloadDrmHelper";
-
-    /** The MIME type of special DRM files */
-    public static final String MIMETYPE_DRM_MESSAGE = "application/vnd.oma.drm.message";
-
-    /** The extensions of special DRM files */
-    public static final String EXTENSION_DRM_MESSAGE = ".dm";
-
-    public static final String EXTENSION_INTERNAL_FWDL = ".fl";
-
-    /**
-     * Checks if the Media Type is a DRM Media Type
-     *
-     * @param drmManagerClient A DrmManagerClient
-     * @param mimetype Media Type to check
-     * @return True if the Media Type is DRM else false
-     */
-    public static boolean isDrmMimeType(Context context, String mimetype) {
-        boolean result = false;
-        if (context != null) {
-            try {
-                DrmManagerClient drmClient = new DrmManagerClient(context);
-                if (drmClient != null && mimetype != null && mimetype.length() > 0) {
-                    result = drmClient.canHandle("", mimetype);
-                }
-            } catch (IllegalArgumentException e) {
-                Log.w(TAG,
-                        "DrmManagerClient instance could not be created, context is Illegal.");
-            } catch (IllegalStateException e) {
-                Log.w(TAG, "DrmManagerClient didn't initialize properly.");
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Checks if the Media Type needs to be DRM converted
-     *
-     * @param mimetype Media type of the content
-     * @return True if convert is needed else false
-     */
-    public static boolean isDrmConvertNeeded(String mimetype) {
-        return MIMETYPE_DRM_MESSAGE.equals(mimetype);
-    }
-
-    /**
-     * Modifies the file extension for a DRM Forward Lock file NOTE: This
-     * function shouldn't be called if the file shouldn't be DRM converted
-     */
-    public static String modifyDrmFwLockFileExtension(String filename) {
-        if (filename != null) {
-            int extensionIndex;
-            extensionIndex = filename.lastIndexOf(".");
-            if (extensionIndex != -1) {
-                filename = filename.substring(0, extensionIndex);
-            }
-            filename = filename.concat(EXTENSION_INTERNAL_FWDL);
-        }
-        return filename;
-    }
-
-    /**
-     * Gets the original mime type of DRM protected content.
-     *
-     * @param context The context
-     * @param path Path to the file
-     * @param containingMime The current mime type of of the file i.e. the
-     *            containing mime type
-     * @return The original mime type of the file if DRM protected else the
-     *         currentMime
-     */
-    public static String getOriginalMimeType(Context context, String path, String containingMime) {
-        String result = containingMime;
-        DrmManagerClient drmClient = new DrmManagerClient(context);
-        try {
-            if (drmClient.canHandle(path, null)) {
-                result = drmClient.getOriginalMimeType(path);
-            }
-        } catch (IllegalArgumentException ex) {
-            Log.w(TAG,
-                    "Can't get original mime type since path is null or empty string.");
-        } catch (IllegalStateException ex) {
-            Log.w(TAG, "DrmManagerClient didn't initialize properly.");
-        }
-        return result;
-    }
-}
diff --git a/core/java/com/google/android/mms/util/DrmConvertSession.java b/core/java/com/google/android/mms/util/DrmConvertSession.java
deleted file mode 100644
index 2d8f274..0000000
--- a/core/java/com/google/android/mms/util/DrmConvertSession.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2012 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.google.android.mms.util;
-
-import android.content.Context;
-import android.drm.DrmConvertedStatus;
-import android.drm.DrmManagerClient;
-import android.util.Log;
-import android.provider.Downloads;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-
-
-public class DrmConvertSession {
-    private DrmManagerClient mDrmClient;
-    private int mConvertSessionId;
-    private static final String TAG = "DrmConvertSession";
-
-    private DrmConvertSession(DrmManagerClient drmClient, int convertSessionId) {
-        mDrmClient = drmClient;
-        mConvertSessionId = convertSessionId;
-    }
-
-    /**
-     * Start of converting a file.
-     *
-     * @param context The context of the application running the convert session.
-     * @param mimeType Mimetype of content that shall be converted.
-     * @return A convert session or null in case an error occurs.
-     */
-    public static DrmConvertSession open(Context context, String mimeType) {
-        DrmManagerClient drmClient = null;
-        int convertSessionId = -1;
-        if (context != null && mimeType != null && !mimeType.equals("")) {
-            try {
-                drmClient = new DrmManagerClient(context);
-                try {
-                    convertSessionId = drmClient.openConvertSession(mimeType);
-                } catch (IllegalArgumentException e) {
-                    Log.w(TAG, "Conversion of Mimetype: " + mimeType
-                            + " is not supported.", e);
-                } catch (IllegalStateException e) {
-                    Log.w(TAG, "Could not access Open DrmFramework.", e);
-                }
-            } catch (IllegalArgumentException e) {
-                Log.w(TAG,
-                        "DrmManagerClient instance could not be created, context is Illegal.");
-            } catch (IllegalStateException e) {
-                Log.w(TAG, "DrmManagerClient didn't initialize properly.");
-            }
-        }
-
-        if (drmClient == null || convertSessionId < 0) {
-            return null;
-        } else {
-            return new DrmConvertSession(drmClient, convertSessionId);
-        }
-    }
-    /**
-     * Convert a buffer of data to protected format.
-     *
-     * @param buffer Buffer filled with data to convert.
-     * @param size The number of bytes that shall be converted.
-     * @return A Buffer filled with converted data, if execution is ok, in all
-     *         other case null.
-     */
-    public byte [] convert(byte[] inBuffer, int size) {
-        byte[] result = null;
-        if (inBuffer != null) {
-            DrmConvertedStatus convertedStatus = null;
-            try {
-                if (size != inBuffer.length) {
-                    byte[] buf = new byte[size];
-                    System.arraycopy(inBuffer, 0, buf, 0, size);
-                    convertedStatus = mDrmClient.convertData(mConvertSessionId, buf);
-                } else {
-                    convertedStatus = mDrmClient.convertData(mConvertSessionId, inBuffer);
-                }
-
-                if (convertedStatus != null &&
-                        convertedStatus.statusCode == DrmConvertedStatus.STATUS_OK &&
-                        convertedStatus.convertedData != null) {
-                    result = convertedStatus.convertedData;
-                }
-            } catch (IllegalArgumentException e) {
-                Log.w(TAG, "Buffer with data to convert is illegal. Convertsession: "
-                        + mConvertSessionId, e);
-            } catch (IllegalStateException e) {
-                Log.w(TAG, "Could not convert data. Convertsession: " +
-                        mConvertSessionId, e);
-            }
-        } else {
-            throw new IllegalArgumentException("Parameter inBuffer is null");
-        }
-        return result;
-    }
-
-    /**
-     * Ends a conversion session of a file.
-     *
-     * @param fileName The filename of the converted file.
-     * @return Downloads.Impl.STATUS_SUCCESS if execution is ok.
-     *         Downloads.Impl.STATUS_FILE_ERROR in case converted file can not
-     *         be accessed. Downloads.Impl.STATUS_NOT_ACCEPTABLE if a problem
-     *         occurs when accessing drm framework.
-     *         Downloads.Impl.STATUS_UNKNOWN_ERROR if a general error occurred.
-     */
-    public int close(String filename) {
-        DrmConvertedStatus convertedStatus = null;
-        int result = Downloads.Impl.STATUS_UNKNOWN_ERROR;
-        if (mDrmClient != null && mConvertSessionId >= 0) {
-            try {
-                convertedStatus = mDrmClient.closeConvertSession(mConvertSessionId);
-                if (convertedStatus == null ||
-                        convertedStatus.statusCode != DrmConvertedStatus.STATUS_OK ||
-                        convertedStatus.convertedData == null) {
-                    result = Downloads.Impl.STATUS_NOT_ACCEPTABLE;
-                } else {
-                    RandomAccessFile rndAccessFile = null;
-                    try {
-                        rndAccessFile = new RandomAccessFile(filename, "rw");
-                        rndAccessFile.seek(convertedStatus.offset);
-                        rndAccessFile.write(convertedStatus.convertedData);
-                        result = Downloads.Impl.STATUS_SUCCESS;
-                    } catch (FileNotFoundException e) {
-                        result = Downloads.Impl.STATUS_FILE_ERROR;
-                        Log.w(TAG, "File: " + filename + " could not be found.", e);
-                    } catch (IOException e) {
-                        result = Downloads.Impl.STATUS_FILE_ERROR;
-                        Log.w(TAG, "Could not access File: " + filename + " .", e);
-                    } catch (IllegalArgumentException e) {
-                        result = Downloads.Impl.STATUS_FILE_ERROR;
-                        Log.w(TAG, "Could not open file in mode: rw", e);
-                    } catch (SecurityException e) {
-                        Log.w(TAG, "Access to File: " + filename +
-                                " was denied denied by SecurityManager.", e);
-                    } finally {
-                        if (rndAccessFile != null) {
-                            try {
-                                rndAccessFile.close();
-                            } catch (IOException e) {
-                                result = Downloads.Impl.STATUS_FILE_ERROR;
-                                Log.w(TAG, "Failed to close File:" + filename
-                                        + ".", e);
-                            }
-                        }
-                    }
-                }
-            } catch (IllegalStateException e) {
-                Log.w(TAG, "Could not close convertsession. Convertsession: " +
-                        mConvertSessionId, e);
-            }
-        }
-        return result;
-    }
-}
diff --git a/core/java/com/google/android/mms/util/PduCache.java b/core/java/com/google/android/mms/util/PduCache.java
deleted file mode 100644
index de83124..0000000
--- a/core/java/com/google/android/mms/util/PduCache.java
+++ /dev/null
@@ -1,261 +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.google.android.mms.util;
-
-import android.content.ContentUris;
-import android.content.UriMatcher;
-import android.net.Uri;
-import android.provider.Telephony.Mms;
-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 = false;
-
-    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 final HashSet<Uri> mUpdating;
-
-    private PduCache() {
-        mMessageBoxes = new HashMap<Integer, HashSet<Uri>>();
-        mThreads = new HashMap<Long, HashSet<Uri>>();
-        mUpdating = new 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);
-        }
-        setUpdating(uri, false);
-        return result;
-    }
-
-    synchronized public void setUpdating(Uri uri, boolean updating) {
-        if (updating) {
-            mUpdating.add(uri);
-        } else {
-            mUpdating.remove(uri);
-        }
-    }
-
-    synchronized public boolean isUpdating(Uri uri) {
-        return mUpdating.contains(uri);
-    }
-
-    @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) {
-        mUpdating.remove(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();
-        mUpdating.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) {
-                    mUpdating.remove(key);
-                    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) {
-                mUpdating.remove(key);
-                PduCacheEntry entry = super.purge(key);
-                if (entry != null) {
-                    removeFromMessageBoxes(key, entry);
-                }
-            }
-        }
-    }
-
-    private void removeFromMessageBoxes(Uri key, PduCacheEntry entry) {
-        HashSet<Uri> msgBox = mThreads.get(Long.valueOf(entry.getMessageBox()));
-        if (msgBox != null) {
-            msgBox.remove(key);
-        }
-    }
-}
diff --git a/core/java/com/google/android/mms/util/PduCacheEntry.java b/core/java/com/google/android/mms/util/PduCacheEntry.java
deleted file mode 100644
index 8b41386..0000000
--- a/core/java/com/google/android/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.google.android.mms.util;
-
-import com.google.android.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/core/java/com/google/android/mms/util/SqliteWrapper.java b/core/java/com/google/android/mms/util/SqliteWrapper.java
deleted file mode 100644
index bcdac22..0000000
--- a/core/java/com/google/android/mms/util/SqliteWrapper.java
+++ /dev/null
@@ -1,120 +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.google.android.mms.util;
-
-import android.app.ActivityManager;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteException;
-import android.net.Uri;
-import android.util.Log;
-import android.widget.Toast;
-
-public final class SqliteWrapper {
-    private static final String TAG = "SqliteWrapper";
-    private static final String SQLITE_EXCEPTION_DETAIL_MESSAGE
-                = "unable to open database file";
-
-    private SqliteWrapper() {
-        // Forbidden being instantiated.
-    }
-
-    // FIXME: It looks like outInfo.lowMemory does not work well as we expected.
-    // after run command: adb shell fillup -p 100, outInfo.lowMemory is still false.
-    private static boolean isLowMemory(Context context) {
-        if (null == context) {
-            return false;
-        }
-
-        ActivityManager am = (ActivityManager)
-                        context.getSystemService(Context.ACTIVITY_SERVICE);
-        ActivityManager.MemoryInfo outInfo = new ActivityManager.MemoryInfo();
-        am.getMemoryInfo(outInfo);
-
-        return outInfo.lowMemory;
-    }
-
-    // FIXME: need to optimize this method.
-    private static boolean isLowMemory(SQLiteException e) {
-        return e.getMessage().equals(SQLITE_EXCEPTION_DETAIL_MESSAGE);
-    }
-
-    public static void checkSQLiteException(Context context, SQLiteException e) {
-        if (isLowMemory(e)) {
-            Toast.makeText(context, com.android.internal.R.string.low_memory,
-                    Toast.LENGTH_SHORT).show();
-        } else {
-            throw e;
-        }
-    }
-
-    public static Cursor query(Context context, ContentResolver resolver, Uri uri,
-            String[] projection, String selection, String[] selectionArgs, String sortOrder) {
-        try {
-            return resolver.query(uri, projection, selection, selectionArgs, sortOrder);
-        } catch (SQLiteException e) {
-            Log.e(TAG, "Catch a SQLiteException when query: ", e);
-            checkSQLiteException(context, e);
-            return null;
-        }
-    }
-
-    public static boolean requery(Context context, Cursor cursor) {
-        try {
-            return cursor.requery();
-        } catch (SQLiteException e) {
-            Log.e(TAG, "Catch a SQLiteException when requery: ", e);
-            checkSQLiteException(context, e);
-            return false;
-        }
-    }
-    public static int update(Context context, ContentResolver resolver, Uri uri,
-            ContentValues values, String where, String[] selectionArgs) {
-        try {
-            return resolver.update(uri, values, where, selectionArgs);
-        } catch (SQLiteException e) {
-            Log.e(TAG, "Catch a SQLiteException when update: ", e);
-            checkSQLiteException(context, e);
-            return -1;
-        }
-    }
-
-    public static int delete(Context context, ContentResolver resolver, Uri uri,
-            String where, String[] selectionArgs) {
-        try {
-            return resolver.delete(uri, where, selectionArgs);
-        } catch (SQLiteException e) {
-            Log.e(TAG, "Catch a SQLiteException when delete: ", e);
-            checkSQLiteException(context, e);
-            return -1;
-        }
-    }
-
-    public static Uri insert(Context context, ContentResolver resolver,
-            Uri uri, ContentValues values) {
-        try {
-            return resolver.insert(uri, values);
-        } catch (SQLiteException e) {
-            Log.e(TAG, "Catch a SQLiteException when insert: ", e);
-            checkSQLiteException(context, e);
-            return null;
-        }
-    }
-}
diff --git a/core/java/com/google/android/mms/util/package.html b/core/java/com/google/android/mms/util/package.html
deleted file mode 100755
index c9f96a6..0000000
--- a/core/java/com/google/android/mms/util/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<body>
-
-{@hide}
-
-</body>
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index c24f6c6..6f3653d 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -66,7 +66,7 @@
 	android_os_MessageQueue.cpp \
 	android_os_ParcelFileDescriptor.cpp \
 	android_os_Parcel.cpp \
-	android_os_StatFs.cpp \
+	android_os_SELinux.cpp \
 	android_os_SystemClock.cpp \
 	android_os_SystemProperties.cpp \
 	android_os_Trace.cpp \
@@ -218,6 +218,12 @@
 	libharfbuzz \
 	libz
 
+ifeq ($(HAVE_SELINUX),true)
+LOCAL_C_INCLUDES += external/libselinux/include
+LOCAL_SHARED_LIBRARIES += libselinux
+LOCAL_CFLAGS += -DHAVE_SELINUX
+endif # HAVE_SELINUX
+
 ifeq ($(USE_OPENGL_RENDERER),true)
 	LOCAL_SHARED_LIBRARIES += libhwui
 endif
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 241a905..d08e651 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -133,7 +133,7 @@
 extern int register_android_os_MessageQueue(JNIEnv* env);
 extern int register_android_os_Parcel(JNIEnv* env);
 extern int register_android_os_ParcelFileDescriptor(JNIEnv *env);
-extern int register_android_os_StatFs(JNIEnv *env);
+extern int register_android_os_SELinux(JNIEnv* env);
 extern int register_android_os_SystemProperties(JNIEnv *env);
 extern int register_android_os_SystemClock(JNIEnv* env);
 extern int register_android_os_Trace(JNIEnv* env);
@@ -1146,7 +1146,7 @@
     REG_JNI(register_android_os_FileUtils),
     REG_JNI(register_android_os_MessageQueue),
     REG_JNI(register_android_os_ParcelFileDescriptor),
-    REG_JNI(register_android_os_StatFs),
+    REG_JNI(register_android_os_SELinux),
     REG_JNI(register_android_os_Trace),
     REG_JNI(register_android_os_UEventObserver),
     REG_JNI(register_android_net_LocalSocketImpl),
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 3c27caf..1bba5b4 100644
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -298,8 +298,18 @@
     }
 
     bool success = false;
-    SkWStream* strm = CreateJavaOutputStreamAdaptor(env, jstream, jstorage);
-    if (NULL != strm) {
+    if (NULL != bitmap) {
+        SkAutoLockPixels alp(*bitmap);
+
+        if (NULL == bitmap->getPixels()) {
+            return false;
+        }
+
+        SkWStream* strm = CreateJavaOutputStreamAdaptor(env, jstream, jstorage);
+        if (NULL == strm) {
+            return false;
+        }
+
         SkImageEncoder* encoder = SkImageEncoder::Create(fm);
         if (NULL != encoder) {
             success = encoder->encodeStream(strm, *bitmap, quality);
diff --git a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
index 6ce3f51..aa4cbde 100644
--- a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
+++ b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
@@ -164,7 +164,7 @@
         RETURN_NULL_IF_NULL(gInputStream_resetMethodID);
         RETURN_NULL_IF_NULL(gInputStream_markMethodID);
         RETURN_NULL_IF_NULL(gInputStream_availableMethodID);
-        RETURN_NULL_IF_NULL(gInputStream_availableMethodID);
+        RETURN_NULL_IF_NULL(gInputStream_readMethodID);
         RETURN_NULL_IF_NULL(gInputStream_skipMethodID);
 
         gInited = true;
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index a65262c..a4d5477 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -750,7 +750,7 @@
     static void doTextBounds(JNIEnv* env, const jchar* text, int count,
                              jobject bounds, const SkPaint& paint)
     {
-        SkRect  r;
+        SkRect  r{0,0,0,0};
         SkIRect ir;
 
         sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(&paint,
diff --git a/core/jni/android_os_FileUtils.cpp b/core/jni/android_os_FileUtils.cpp
index 8d65cbc..a07f5b7 100644
--- a/core/jni/android_os_FileUtils.cpp
+++ b/core/jni/android_os_FileUtils.cpp
@@ -33,19 +33,6 @@
 
 namespace android {
 
-static jfieldID gFileStatusDevFieldID;
-static jfieldID gFileStatusInoFieldID;
-static jfieldID gFileStatusModeFieldID;
-static jfieldID gFileStatusNlinkFieldID;
-static jfieldID gFileStatusUidFieldID;
-static jfieldID gFileStatusGidFieldID;
-static jfieldID gFileStatusSizeFieldID;
-static jfieldID gFileStatusBlksizeFieldID;
-static jfieldID gFileStatusBlocksFieldID;
-static jfieldID gFileStatusAtimeFieldID;
-static jfieldID gFileStatusMtimeFieldID;
-static jfieldID gFileStatusCtimeFieldID;
-
 jint android_os_FileUtils_setPermissions(JNIEnv* env, jobject clazz,
                                          jstring file, jint mode,
                                          jint uid, jint gid)
@@ -68,44 +55,6 @@
     return chmod(file8.string(), mode) == 0 ? 0 : errno;
 }
 
-jint android_os_FileUtils_getPermissions(JNIEnv* env, jobject clazz,
-                                         jstring file, jintArray outArray)
-{
-    const jchar* str = env->GetStringCritical(file, 0);
-    String8 file8;
-    if (str) {
-        file8 = String8(str, env->GetStringLength(file));
-        env->ReleaseStringCritical(file, str);
-    }
-    if (file8.size() <= 0) {
-        return ENOENT;
-    }
-    struct stat st;
-    if (stat(file8.string(), &st) != 0) {
-        return errno;
-    }
-    jint* array = (jint*)env->GetPrimitiveArrayCritical(outArray, 0);
-    if (array) {
-        int len = env->GetArrayLength(outArray);
-        if (len >= 1) {
-            array[0] = st.st_mode;
-        }
-        if (len >= 2) {
-            array[1] = st.st_uid;
-        }
-        if (len >= 3) {
-            array[2] = st.st_gid;
-        }
-    }
-    env->ReleasePrimitiveArrayCritical(outArray, array, 0);
-    return 0;
-}
-
-jint android_os_FileUtils_setUMask(JNIEnv* env, jobject clazz, jint mask)
-{
-    return umask(mask);
-}
-
 jint android_os_FileUtils_getFatVolumeId(JNIEnv* env, jobject clazz, jstring path)
 {
     if (path == NULL) {
@@ -127,63 +76,15 @@
     return result;
 }
 
-jboolean android_os_FileUtils_getFileStatus(JNIEnv* env, jobject clazz, jstring path, jobject fileStatus) {
-    const char* pathStr = env->GetStringUTFChars(path, NULL);
-    jboolean ret = false;
-
-    struct stat s;
-    int res = stat(pathStr, &s);
-    if (res == 0) {
-        ret = true;
-        if (fileStatus != NULL) {
-            env->SetIntField(fileStatus, gFileStatusDevFieldID, s.st_dev);
-            env->SetIntField(fileStatus, gFileStatusInoFieldID, s.st_ino);
-            env->SetIntField(fileStatus, gFileStatusModeFieldID, s.st_mode);
-            env->SetIntField(fileStatus, gFileStatusNlinkFieldID, s.st_nlink);
-            env->SetIntField(fileStatus, gFileStatusUidFieldID, s.st_uid);
-            env->SetIntField(fileStatus, gFileStatusGidFieldID, s.st_gid);
-            env->SetLongField(fileStatus, gFileStatusSizeFieldID, s.st_size);
-            env->SetIntField(fileStatus, gFileStatusBlksizeFieldID, s.st_blksize);
-            env->SetLongField(fileStatus, gFileStatusBlocksFieldID, s.st_blocks);
-            env->SetLongField(fileStatus, gFileStatusAtimeFieldID, s.st_atime);
-            env->SetLongField(fileStatus, gFileStatusMtimeFieldID, s.st_mtime);
-            env->SetLongField(fileStatus, gFileStatusCtimeFieldID, s.st_ctime);
-        }
-    }
-
-    env->ReleaseStringUTFChars(path, pathStr);
-
-    return ret;
-}
-
 static const JNINativeMethod methods[] = {
     {"setPermissions",  "(Ljava/lang/String;III)I", (void*)android_os_FileUtils_setPermissions},
-    {"getPermissions",  "(Ljava/lang/String;[I)I", (void*)android_os_FileUtils_getPermissions},
-    {"setUMask",        "(I)I",                    (void*)android_os_FileUtils_setUMask},
     {"getFatVolumeId",  "(Ljava/lang/String;)I", (void*)android_os_FileUtils_getFatVolumeId},
-    {"getFileStatusNative", "(Ljava/lang/String;Landroid/os/FileUtils$FileStatus;)Z", (void*)android_os_FileUtils_getFileStatus},
 };
 
 static const char* const kFileUtilsPathName = "android/os/FileUtils";
 
 int register_android_os_FileUtils(JNIEnv* env)
 {
-    jclass fileStatusClass = env->FindClass("android/os/FileUtils$FileStatus");
-    LOG_FATAL_IF(fileStatusClass == NULL, "Unable to find class android.os.FileUtils$FileStatus");
-
-    gFileStatusDevFieldID = env->GetFieldID(fileStatusClass, "dev", "I");
-    gFileStatusInoFieldID = env->GetFieldID(fileStatusClass, "ino", "I");
-    gFileStatusModeFieldID = env->GetFieldID(fileStatusClass, "mode", "I");
-    gFileStatusNlinkFieldID = env->GetFieldID(fileStatusClass, "nlink", "I");
-    gFileStatusUidFieldID = env->GetFieldID(fileStatusClass, "uid", "I");
-    gFileStatusGidFieldID = env->GetFieldID(fileStatusClass, "gid", "I");
-    gFileStatusSizeFieldID = env->GetFieldID(fileStatusClass, "size", "J");
-    gFileStatusBlksizeFieldID = env->GetFieldID(fileStatusClass, "blksize", "I");
-    gFileStatusBlocksFieldID = env->GetFieldID(fileStatusClass, "blocks", "J");
-    gFileStatusAtimeFieldID = env->GetFieldID(fileStatusClass, "atime", "J");
-    gFileStatusMtimeFieldID = env->GetFieldID(fileStatusClass, "mtime", "J");
-    gFileStatusCtimeFieldID = env->GetFieldID(fileStatusClass, "ctime", "J");
-
     return AndroidRuntime::registerNativeMethods(
         env, kFileUtilsPathName,
         methods, NELEM(methods));
diff --git a/core/jni/android_os_SELinux.cpp b/core/jni/android_os_SELinux.cpp
new file mode 100644
index 0000000..e813c38
--- /dev/null
+++ b/core/jni/android_os_SELinux.cpp
@@ -0,0 +1,541 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#define LOG_TAG "SELinuxJNI"
+#include <utils/Log.h>
+
+#include "JNIHelp.h"
+#include "jni.h"
+#include "android_runtime/AndroidRuntime.h"
+#ifdef HAVE_SELINUX
+#include "selinux/selinux.h"
+#include "selinux/android.h"
+#endif
+#include <errno.h>
+
+namespace android {
+
+  static jboolean isSELinuxDisabled = true;
+
+  static void throw_NullPointerException(JNIEnv *env, const char* msg) {
+    jclass clazz;
+    clazz = env->FindClass("java/lang/NullPointerException");
+    env->ThrowNew(clazz, msg);
+  }
+
+  /*
+   * Function: isSELinuxEnabled
+   * Purpose:  checks whether SELinux is enabled/disbaled
+   * Parameters: none
+   * Return value : true (enabled) or false (disabled)
+   * Exceptions: none
+   */
+  static jboolean isSELinuxEnabled(JNIEnv *env, jobject classz) {
+
+    return !isSELinuxDisabled;
+  }
+
+  /*
+   * Function: isSELinuxEnforced
+   * Purpose: return the current SELinux enforce mode
+   * Parameters: none
+   * Return value: true (enforcing) or false (permissive)
+   * Exceptions: none
+   */
+  static jboolean isSELinuxEnforced(JNIEnv *env, jobject clazz) {
+#ifdef HAVE_SELINUX
+    return (security_getenforce() == 1) ? true : false;
+#else
+    return false;
+#endif
+  }
+
+  /*
+   * Function: setSELinuxEnforce
+   * Purpose: set the SE Linux enforcing mode
+   * Parameters: true (enforcing) or false (permissive)
+   * Return value: true (success) or false (fail)
+   * Exceptions: none
+   */
+  static jboolean setSELinuxEnforce(JNIEnv *env, jobject clazz, jboolean value) {
+#ifdef HAVE_SELINUX
+    if (isSELinuxDisabled)
+      return false;
+
+    int enforce = (value) ? 1 : 0;
+
+    return (security_setenforce(enforce) != -1) ? true : false;
+#else
+    return false;
+#endif
+  }
+
+  /*
+   * Function: getPeerCon
+   * Purpose: retrieves security context of peer socket
+   * Parameters:
+   *        fileDescriptor: peer socket file as a FileDescriptor object
+   * Returns: jstring representing the security_context of socket or NULL if error
+   * Exceptions: NullPointerException if fileDescriptor object is NULL
+   */
+  static jstring getPeerCon(JNIEnv *env, jobject clazz, jobject fileDescriptor) {
+#ifdef HAVE_SELINUX
+    if (isSELinuxDisabled)
+      return NULL;
+
+    if (fileDescriptor == NULL) {
+      throw_NullPointerException(env, "Trying to check security context of a null peer socket.");
+      return NULL;
+    }
+
+    security_context_t context = NULL;
+    jstring securityString = NULL;
+
+    int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
+
+    if (env->ExceptionOccurred() != NULL) {
+      ALOGE("There was an issue with retrieving the file descriptor");
+      goto bail;
+    }
+
+    if (getpeercon(fd, &context) == -1)
+      goto bail;
+
+    ALOGV("getPeerCon: Successfully retrived context of peer socket '%s'", context);
+
+    securityString = env->NewStringUTF(context);
+
+  bail:
+    if (context != NULL)
+      freecon(context);
+
+    return securityString;
+#else
+    return NULL;
+#endif
+  }
+
+  /*
+   * Function: setFSCreateCon
+   * Purpose: set security context used for creating a new file system object
+   * Parameters:
+   *       context: security_context_t representing the new context of a file system object,
+   *                set to NULL to return to the default policy behavior
+   * Returns: true on success, false on error
+   * Exception: none
+   */
+  static jboolean setFSCreateCon(JNIEnv *env, jobject clazz, jstring context) {
+#ifdef HAVE_SELINUX
+    if (isSELinuxDisabled)
+      return false;
+
+    char * securityContext = NULL;
+    const char *constant_securityContext = NULL;
+
+    if (context != NULL) {
+      constant_securityContext = env->GetStringUTFChars(context, NULL);
+
+      // GetStringUTFChars returns const char * yet setfscreatecon needs char *
+      securityContext = const_cast<char *>(constant_securityContext);
+    }
+
+    int ret;
+    if ((ret = setfscreatecon(securityContext)) == -1)
+      goto bail;
+
+    ALOGV("setFSCreateCon: set new security context to '%s' ", context == NULL ? "default", context);
+
+  bail:
+    if (constant_securityContext != NULL)
+      env->ReleaseStringUTFChars(context, constant_securityContext);
+
+    return (ret == 0) ? true : false;
+#else
+    return false;
+#endif
+  }
+
+  /*
+   * Function: setFileCon
+   * Purpose:  set the security context of a file object
+   * Parameters:
+   *       path: the location of the file system object
+   *       con: the new security context of the file system object
+   * Returns: true on success, false on error
+   * Exception: NullPointerException is thrown if either path or context strign are NULL
+   */
+  static jboolean setFileCon(JNIEnv *env, jobject clazz, jstring path, jstring con) {
+#ifdef HAVE_SELINUX
+    if (isSELinuxDisabled)
+      return false;
+
+    if (path == NULL) {
+      throw_NullPointerException(env, "Trying to change the security context of a NULL file object.");
+      return false;
+    }
+
+    if (con == NULL) {
+      throw_NullPointerException(env, "Trying to set the security context of a file object with NULL.");
+      return false;
+    }
+
+    const char *objectPath = env->GetStringUTFChars(path, NULL);
+    const char *constant_con = env->GetStringUTFChars(con, NULL);
+
+    // GetStringUTFChars returns const char * yet setfilecon needs char *
+    char *newCon = const_cast<char *>(constant_con);
+
+    int ret;
+    if ((ret = setfilecon(objectPath, newCon)) == -1)
+      goto bail;
+
+    ALOGV("setFileCon: Succesfully set security context '%s' for '%s'", newCon, objectPath);
+
+  bail:
+    env->ReleaseStringUTFChars(path, objectPath);
+    env->ReleaseStringUTFChars(con, constant_con);
+    return (ret == 0) ? true : false;
+#else
+    return false;
+#endif
+  }
+
+  /*
+   * Function: getFileCon
+   * Purpose: retrieves the context associated with the given path in the file system
+   * Parameters:
+   *        path: given path in the file system
+   * Returns:
+   *        string representing the security context string of the file object
+   *        the string may be NULL if an error occured
+   * Exceptions: NullPointerException if the path object is null
+   */
+  static jstring getFileCon(JNIEnv *env, jobject clazz, jstring path) {
+#ifdef HAVE_SELINUX
+    if (isSELinuxDisabled)
+      return NULL;
+
+    if (path == NULL) {
+      throw_NullPointerException(env, "Trying to check security context of a null path.");
+      return NULL;
+    }
+
+    const char *objectPath = env->GetStringUTFChars(path, NULL);
+
+    security_context_t context = NULL;
+    jstring securityString = NULL;
+
+    if (getfilecon(objectPath, &context) == -1)
+      goto bail;
+
+    ALOGV("getFileCon: Successfully retrived context '%s' for file '%s'", context, objectPath);
+
+    securityString = env->NewStringUTF(context);
+
+  bail:
+    if (context != NULL)
+      freecon(context);
+
+    env->ReleaseStringUTFChars(path, objectPath);
+
+    return securityString;
+#else
+    return NULL;
+#endif
+  }
+
+  /*
+   * Function: getCon
+   * Purpose: Get the context of the current process.
+   * Parameters: none
+   * Returns: a jstring representing the security context of the process,
+   *          the jstring may be NULL if there was an error
+   * Exceptions: none
+   */
+  static jstring getCon(JNIEnv *env, jobject clazz) {
+#ifdef HAVE_SELINUX
+    if (isSELinuxDisabled)
+      return NULL;
+
+    security_context_t context = NULL;
+    jstring securityString = NULL;
+
+    if (getcon(&context) == -1)
+      goto bail;
+
+    ALOGV("getCon: Successfully retrieved context '%s'", context);
+
+    securityString = env->NewStringUTF(context);
+
+  bail:
+    if (context != NULL)
+      freecon(context);
+
+    return securityString;
+#else
+    return NULL;
+#endif
+  }
+
+  /*
+   * Function: getPidCon
+   * Purpose: Get the context of a process identified by its pid
+   * Parameters:
+   *            pid: a jint representing the process
+   * Returns: a jstring representing the security context of the pid,
+   *          the jstring may be NULL if there was an error
+   * Exceptions: none
+   */
+  static jstring getPidCon(JNIEnv *env, jobject clazz, jint pid) {
+#ifdef HAVE_SELINUX
+    if (isSELinuxDisabled)
+      return NULL;
+
+    security_context_t context = NULL;
+    jstring securityString = NULL;
+
+    pid_t checkPid = (pid_t)pid;
+
+    if (getpidcon(checkPid, &context) == -1)
+      goto bail;
+
+    ALOGV("getPidCon: Successfully retrived context '%s' for pid '%d'", context, checkPid);
+
+    securityString = env->NewStringUTF(context);
+
+  bail:
+    if (context != NULL)
+      freecon(context);
+
+    return securityString;
+#else
+    return NULL;
+#endif
+  }
+
+  /*
+   * Function: getBooleanNames
+   * Purpose: Gets a list of the SELinux boolean names.
+   * Parameters: None
+   * Returns: an array of strings  containing the SELinux boolean names.
+   *          returns NULL string on error
+   * Exceptions: None
+   */
+  static jobjectArray getBooleanNames(JNIEnv *env, JNIEnv clazz) {
+#ifdef HAVE_SELINUX
+    if (isSELinuxDisabled)
+      return NULL;
+
+    char **list;
+    int i, len, ret;
+    jclass stringClass;
+    jobjectArray stringArray = NULL;
+
+    if (security_get_boolean_names(&list, &len) == -1)
+      return NULL;
+
+    stringClass = env->FindClass("java/lang/String");
+    stringArray = env->NewObjectArray(len, stringClass, env->NewStringUTF(""));
+    for (i = 0; i < len; i++) {
+      jstring obj;
+      obj = env->NewStringUTF(list[i]);
+      env->SetObjectArrayElement(stringArray, i, obj);
+      env->DeleteLocalRef(obj);
+      free(list[i]);
+    }
+    free(list);
+
+    return stringArray;
+#else
+    return NULL;
+#endif
+  }
+
+  /*
+   * Function: getBooleanValue
+   * Purpose: Gets the value for the given SELinux boolean name.
+   * Parameters:
+   *            String: The name of the SELinux boolean.
+   * Returns: a boolean: (true) boolean is set or (false) it is not.
+   * Exceptions: None
+   */
+  static jboolean getBooleanValue(JNIEnv *env, jobject clazz, jstring name) {
+#ifdef HAVE_SELINUX
+    if (isSELinuxDisabled)
+      return false;
+
+    const char *boolean_name;
+    int ret;
+
+    if (name == NULL)
+      return false;
+    boolean_name = env->GetStringUTFChars(name, NULL);
+    ret = security_get_boolean_active(boolean_name);
+    env->ReleaseStringUTFChars(name, boolean_name);
+    return (ret == 1) ? true : false;
+#else
+    return false;
+#endif
+  }
+
+  /*
+   * Function: setBooleanNames
+   * Purpose: Sets the value for the given SELinux boolean name.
+   * Parameters:
+   *            String: The name of the SELinux boolean.
+   *            Boolean: The new value of the SELinux boolean.
+   * Returns: a boolean indicating whether or not the operation succeeded.
+   * Exceptions: None
+   */
+  static jboolean setBooleanValue(JNIEnv *env, jobject clazz, jstring name, jboolean value) {
+#ifdef HAVE_SELINUX
+    if (isSELinuxDisabled)
+      return false;
+
+    const char *boolean_name = NULL;
+    int ret;
+
+    if (name == NULL)
+      return false;
+    boolean_name = env->GetStringUTFChars(name, NULL);
+    ret = security_set_boolean(boolean_name, (value) ? 1 : 0);
+    env->ReleaseStringUTFChars(name, boolean_name);
+    if (ret)
+      return false;
+
+    if (security_commit_booleans() == -1)
+      return false;
+
+    return true;
+#else
+    return false;
+#endif
+  }
+
+  /*
+   * Function: checkSELinuxAccess
+   * Purpose: Check permissions between two security contexts.
+   * Parameters: scon: subject security context as a string
+   *             tcon: object security context as a string
+   *             tclass: object's security class name as a string
+   *             perm: permission name as a string
+   * Returns: boolean: (true) if permission was granted, (false) otherwise
+   * Exceptions: None
+   */
+  static jboolean checkSELinuxAccess(JNIEnv *env, jobject clazz, jstring scon, jstring tcon, jstring tclass, jstring perm) {
+#ifdef HAVE_SELINUX
+    if (isSELinuxDisabled)
+      return true;
+
+    int accessGranted = -1;
+
+    const char *const_scon, *const_tcon, *mytclass, *myperm;
+    char *myscon, *mytcon;
+
+    if (scon == NULL || tcon == NULL || tclass == NULL || perm == NULL)
+      goto bail;
+
+    const_scon = env->GetStringUTFChars(scon, NULL);
+    const_tcon = env->GetStringUTFChars(tcon, NULL);
+    mytclass   = env->GetStringUTFChars(tclass, NULL);
+    myperm     = env->GetStringUTFChars(perm, NULL);
+
+    // selinux_check_access needs char* for some
+    myscon = const_cast<char *>(const_scon);
+    mytcon = const_cast<char *>(const_tcon);
+
+    accessGranted = selinux_check_access(myscon, mytcon, mytclass, myperm, NULL);
+
+    ALOGV("selinux_check_access returned %d", accessGranted);
+
+    env->ReleaseStringUTFChars(scon, const_scon);
+    env->ReleaseStringUTFChars(tcon, const_tcon);
+    env->ReleaseStringUTFChars(tclass, mytclass);
+    env->ReleaseStringUTFChars(perm, myperm);
+
+  bail:
+    return (accessGranted == 0) ? true : false;
+
+#else
+    return true;
+#endif
+  }
+
+  /*
+   * Function: native_restorecon
+   * Purpose: restore default SELinux security context
+   * Parameters: pathname: the pathname for the file to be relabeled
+   * Returns: boolean: (true) file label successfully restored, (false) otherwise
+   * Exceptions: none
+   */
+  static jboolean native_restorecon(JNIEnv *env, jobject clazz, jstring pathname) {
+#ifdef HAVE_SELINUX
+    if (isSELinuxDisabled)
+      return true;
+
+    const char *file = const_cast<char *>(env->GetStringUTFChars(pathname, NULL));
+    int ret = selinux_android_restorecon(file);
+    env->ReleaseStringUTFChars(pathname, file);
+    return (ret == 0);
+#else
+    return true;
+#endif
+  }
+
+  /*
+   * JNI registration.
+   */
+  static JNINativeMethod method_table[] = {
+
+    /* name,                     signature,                    funcPtr */
+    { "checkSELinuxAccess"       , "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z" , (void*)checkSELinuxAccess },
+    { "getBooleanNames"          , "()[Ljava/lang/String;"                        , (void*)getBooleanNames  },
+    { "getBooleanValue"          , "(Ljava/lang/String;)Z"                        , (void*)getBooleanValue  },
+    { "getContext"               , "()Ljava/lang/String;"                         , (void*)getCon           },
+    { "getFileContext"           , "(Ljava/lang/String;)Ljava/lang/String;"       , (void*)getFileCon       },
+    { "getPeerContext"           , "(Ljava/io/FileDescriptor;)Ljava/lang/String;" , (void*)getPeerCon       },
+    { "getPidContext"            , "(I)Ljava/lang/String;"                        , (void*)getPidCon        },
+    { "isSELinuxEnforced"        , "()Z"                                          , (void*)isSELinuxEnforced},
+    { "isSELinuxEnabled"         , "()Z"                                          , (void*)isSELinuxEnabled },
+    { "native_restorecon"        , "(Ljava/lang/String;)Z"                        , (void*)native_restorecon},
+    { "setBooleanValue"          , "(Ljava/lang/String;Z)Z"                       , (void*)setBooleanValue  },
+    { "setFileContext"           , "(Ljava/lang/String;Ljava/lang/String;)Z"      , (void*)setFileCon       },
+    { "setFSCreateContext"       , "(Ljava/lang/String;)Z"                        , (void*)setFSCreateCon   },
+    { "setSELinuxEnforce"        , "(Z)Z"                                         , (void*)setSELinuxEnforce},
+  };
+
+  static int log_callback(int type, const char *fmt, ...) {
+    va_list ap;
+    va_start(ap, fmt);
+    LOG_PRI_VA(ANDROID_LOG_ERROR, "SELinux", fmt, ap);
+    va_end(ap);
+    return 0;
+  }
+
+  int register_android_os_SELinux(JNIEnv *env) {
+#ifdef HAVE_SELINUX
+    union selinux_callback cb;
+    cb.func_log = log_callback;
+    selinux_set_callback(SELINUX_CB_LOG, cb);
+
+    isSELinuxDisabled = (is_selinux_enabled() != 1) ? true : false;
+
+#endif
+    return AndroidRuntime::registerNativeMethods(
+         env, "android/os/SELinux",
+         method_table, NELEM(method_table));
+  }
+}
diff --git a/core/jni/android_os_StatFs.cpp b/core/jni/android_os_StatFs.cpp
deleted file mode 100644
index 79d8fef..0000000
--- a/core/jni/android_os_StatFs.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#if INCLUDE_SYS_MOUNT_FOR_STATFS
-#include <sys/mount.h>
-#else
-#include <sys/statfs.h>
-#endif
-
-#include <errno.h>
-
-#include "jni.h"
-#include "JNIHelp.h"
-#include "android_runtime/AndroidRuntime.h"
-
-
-namespace android
-{
-
-// ----------------------------------------------------------------------------
-
-struct fields_t {
-    jfieldID    context;
-};
-static fields_t fields;
-
-// ----------------------------------------------------------------------------
-
-static jint
-android_os_StatFs_getBlockSize(JNIEnv *env, jobject thiz)
-{
-    struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
-    return stat->f_bsize;
-}
-
-static jint
-android_os_StatFs_getBlockCount(JNIEnv *env, jobject thiz)
-{
-    struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
-    return stat->f_blocks;
-}
-
-static jint
-android_os_StatFs_getFreeBlocks(JNIEnv *env, jobject thiz)
-{
-    struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
-    return stat->f_bfree;
-}
-
-static jint
-android_os_StatFs_getAvailableBlocks(JNIEnv *env, jobject thiz)
-{
-    struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
-    return stat->f_bavail;
-}
-
-static void
-android_os_StatFs_native_restat(JNIEnv *env, jobject thiz, jstring path)
-{
-    if (path == NULL) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
-        return;
-    }
-
-    // get the object handle
-    struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
-    if (stat == NULL) {
-        jniThrowException(env, "java/lang/NoSuchFieldException", NULL);
-        return;
-    }
-
-    const char* pathstr = env->GetStringUTFChars(path, NULL);
-    if (pathstr == NULL) {
-        jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
-        return;
-    }
-
-    // note that stat will contain the new file data corresponding to
-    // pathstr
-    if (statfs(pathstr, stat) != 0) {
-        ALOGE("statfs %s failed, errno: %d", pathstr, errno);
-        delete stat;
-        env->SetIntField(thiz, fields.context, 0);
-        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
-    }
-    // Release pathstr
-    env->ReleaseStringUTFChars(path, pathstr);
-}
-
-static void
-android_os_StatFs_native_setup(JNIEnv *env, jobject thiz, jstring path)
-{
-    if (path == NULL) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
-        return;
-    }
-
-    struct statfs* stat = new struct statfs;
-    if (stat == NULL) {
-        jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
-        return;
-    }
-    env->SetIntField(thiz, fields.context, (int)stat);
-    android_os_StatFs_native_restat(env, thiz, path);
-}
-
-static void
-android_os_StatFs_native_finalize(JNIEnv *env, jobject thiz)
-{
-    struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
-    if (stat != NULL) {
-        delete stat;
-        env->SetIntField(thiz, fields.context, 0);
-    }
-}
-
-// ----------------------------------------------------------------------------
-
-static JNINativeMethod gMethods[] = {
-    {"getBlockSize",       "()I",                       (void *)android_os_StatFs_getBlockSize},
-    {"getBlockCount",      "()I",                       (void *)android_os_StatFs_getBlockCount},
-    {"getFreeBlocks",      "()I",                       (void *)android_os_StatFs_getFreeBlocks},
-    {"getAvailableBlocks", "()I",                       (void *)android_os_StatFs_getAvailableBlocks},
-    {"native_setup",       "(Ljava/lang/String;)V",     (void *)android_os_StatFs_native_setup},
-    {"native_finalize",    "()V",                       (void *)android_os_StatFs_native_finalize},
-    {"native_restat",      "(Ljava/lang/String;)V",     (void *)android_os_StatFs_native_restat},
-};
-
-
-int register_android_os_StatFs(JNIEnv *env)
-{
-    jclass clazz;
-
-    clazz = env->FindClass("android/os/StatFs");
-    if (clazz == NULL) {
-        ALOGE("Can't find android/os/StatFs");
-        return -1;
-    }
-
-    fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
-    if (fields.context == NULL) {
-        ALOGE("Can't find StatFs.mNativeContext");
-        return -1;
-    }
-
-    return AndroidRuntime::registerNativeMethods(env,
-            "android/os/StatFs", gMethods, NELEM(gMethods));
-}
-
-}   // namespace android
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml b/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml
index 9c18b7e..2a2dc31 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml
@@ -119,6 +119,6 @@
             android:drawablePadding="8dip"
             android:visibility="gone"/>
 
-    </RelativeLayout>>
+    </RelativeLayout>
 
 </LinearLayout>
diff --git a/core/res/res/layout/transient_notification.xml b/core/res/res/layout/transient_notification.xml
index 21d58aa..5523807 100644
--- a/core/res/res/layout/transient_notification.xml
+++ b/core/res/res/layout/transient_notification.xml
@@ -29,6 +29,7 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_weight="1"
+        android:layout_gravity="center_horizontal"
         android:textAppearance="@style/TextAppearance.Small"
         android:textColor="@color/bright_foreground_dark"
         android:shadowColor="#BB000000"
diff --git a/core/res/res/raw-ar/loaderror.html b/core/res/res/raw-ar/loaderror.html
index aa9805c..5b88558 100644
--- a/core/res/res/raw-ar/loaderror.html
+++ b/core/res/res/raw-ar/loaderror.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>صفحة الويب غير متوفرة</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; direction: rtl; }
diff --git a/core/res/res/raw-ar/nodomain.html b/core/res/res/raw-ar/nodomain.html
index 2e5849f..613c230 100644
--- a/core/res/res/raw-ar/nodomain.html
+++ b/core/res/res/raw-ar/nodomain.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>صفحة الويب غير متوفرة</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; direction: rtl; }
diff --git a/core/res/res/raw-cs/loaderror.html b/core/res/res/raw-cs/loaderror.html
index ce88981..a07970b 100644
--- a/core/res/res/raw-cs/loaderror.html
+++ b/core/res/res/raw-cs/loaderror.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Webov&aacute; str&aacute;nka nen&iacute; dostupn&aacute;</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-cs/nodomain.html b/core/res/res/raw-cs/nodomain.html
index 26479a9..bd78ca3 100644
--- a/core/res/res/raw-cs/nodomain.html
+++ b/core/res/res/raw-cs/nodomain.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Webov&aacute; str&aacute;nka nen&iacute; dostupn&aacute;</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-da/loaderror.html b/core/res/res/raw-da/loaderror.html
index 12a75c6c..8065f1a 100644
--- a/core/res/res/raw-da/loaderror.html
+++ b/core/res/res/raw-da/loaderror.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Websiden er ikke tilg&aelig;ngelig</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-da/nodomain.html b/core/res/res/raw-da/nodomain.html
index 3b8fe78..b24de2b 100644
--- a/core/res/res/raw-da/nodomain.html
+++ b/core/res/res/raw-da/nodomain.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Websiden er ikke tilg&aelig;ngelig</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-de/loaderror.html b/core/res/res/raw-de/loaderror.html
index bece2d7..62d7a13 100644
--- a/core/res/res/raw-de/loaderror.html
+++ b/core/res/res/raw-de/loaderror.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Webseite nicht verf&uuml;gbar</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-de/nodomain.html b/core/res/res/raw-de/nodomain.html
index 9fd8094..7ea8d86d 100644
--- a/core/res/res/raw-de/nodomain.html
+++ b/core/res/res/raw-de/nodomain.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Webseite nicht verf&uuml;gbar</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-en-rGB/loaderror.html b/core/res/res/raw-en-rGB/loaderror.html
index 359a1e7..fd3d766 100644
--- a/core/res/res/raw-en-rGB/loaderror.html
+++ b/core/res/res/raw-en-rGB/loaderror.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Web page not available</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-en-rGB/nodomain.html b/core/res/res/raw-en-rGB/nodomain.html
index 01dd603..4ca403b 100644
--- a/core/res/res/raw-en-rGB/nodomain.html
+++ b/core/res/res/raw-en-rGB/nodomain.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Web page not available</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-es/loaderror.html b/core/res/res/raw-es/loaderror.html
index 8829bf5..0102b8a 100644
--- a/core/res/res/raw-es/loaderror.html
+++ b/core/res/res/raw-es/loaderror.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>P&aacute;gina web no disponible</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-es/nodomain.html b/core/res/res/raw-es/nodomain.html
index a11333e..03a9855 100644
--- a/core/res/res/raw-es/nodomain.html
+++ b/core/res/res/raw-es/nodomain.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>P&aacute;gina web no disponible</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-fi/loaderror.html b/core/res/res/raw-fi/loaderror.html
index 3b1ec97..2ef97f4 100644
--- a/core/res/res/raw-fi/loaderror.html
+++ b/core/res/res/raw-fi/loaderror.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Verkkosivu ei ole k&auml;ytett&auml;viss&auml;</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-fi/nodomain.html b/core/res/res/raw-fi/nodomain.html
index 84fedb4..58abc2d 100644
--- a/core/res/res/raw-fi/nodomain.html
+++ b/core/res/res/raw-fi/nodomain.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Verkkosivu ei ole k&auml;ytett&auml;viss&auml;</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-fr/loaderror.html b/core/res/res/raw-fr/loaderror.html
index f61f50b..f22d1b1 100644
--- a/core/res/res/raw-fr/loaderror.html
+++ b/core/res/res/raw-fr/loaderror.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Page Web non disponible</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-fr/nodomain.html b/core/res/res/raw-fr/nodomain.html
index b3b93b3..3c62aee 100644
--- a/core/res/res/raw-fr/nodomain.html
+++ b/core/res/res/raw-fr/nodomain.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Page Web non disponible</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-hu/loaderror.html b/core/res/res/raw-hu/loaderror.html
index 6b3d45e..4eccb24 100644
--- a/core/res/res/raw-hu/loaderror.html
+++ b/core/res/res/raw-hu/loaderror.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>A weboldal nem &eacute;rhető el</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-hu/nodomain.html b/core/res/res/raw-hu/nodomain.html
index d3465ff..08399e2 100644
--- a/core/res/res/raw-hu/nodomain.html
+++ b/core/res/res/raw-hu/nodomain.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>A weboldal nem &eacute;rhető el</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-it/loaderror.html b/core/res/res/raw-it/loaderror.html
index e81466a..9f78d08 100644
--- a/core/res/res/raw-it/loaderror.html
+++ b/core/res/res/raw-it/loaderror.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Pagina web non disponibile</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-it/nodomain.html b/core/res/res/raw-it/nodomain.html
index a2321c7..6e1876c 100644
--- a/core/res/res/raw-it/nodomain.html
+++ b/core/res/res/raw-it/nodomain.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Pagina web non disponibile</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-iw/loaderror.html b/core/res/res/raw-iw/loaderror.html
index 8d5a53f..08ff28e 100644
--- a/core/res/res/raw-iw/loaderror.html
+++ b/core/res/res/raw-iw/loaderror.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>דף אינטרנט לא זמין</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; direction: rtl; }
diff --git a/core/res/res/raw-iw/nodomain.html b/core/res/res/raw-iw/nodomain.html
index 0dcd7f8..fd89aa0 100644
--- a/core/res/res/raw-iw/nodomain.html
+++ b/core/res/res/raw-iw/nodomain.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>דף אינטרנט לא זמין</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; direction: rtl; }
diff --git a/core/res/res/raw-ja/loaderror.html b/core/res/res/raw-ja/loaderror.html
index 68e568b..819859e 100644
--- a/core/res/res/raw-ja/loaderror.html
+++ b/core/res/res/raw-ja/loaderror.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>ページが見つかりませんでした</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-ja/nodomain.html b/core/res/res/raw-ja/nodomain.html
index 1dff1d4..75495db 100644
--- a/core/res/res/raw-ja/nodomain.html
+++ b/core/res/res/raw-ja/nodomain.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>ページが見つかりませんでした</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-ko/loaderror.html b/core/res/res/raw-ko/loaderror.html
index 59f0f25..0ae687d 100644
--- a/core/res/res/raw-ko/loaderror.html
+++ b/core/res/res/raw-ko/loaderror.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>웹페이지를 표시할 수 없습니다.</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-ko/nodomain.html b/core/res/res/raw-ko/nodomain.html
index 0eadc39..f014845 100644
--- a/core/res/res/raw-ko/nodomain.html
+++ b/core/res/res/raw-ko/nodomain.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>웹페이지를 표시할 수 없습니다.</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-nl/loaderror.html b/core/res/res/raw-nl/loaderror.html
index 76bb07c..819c3ba 100644
--- a/core/res/res/raw-nl/loaderror.html
+++ b/core/res/res/raw-nl/loaderror.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Webpagina niet beschikbaar</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-nl/nodomain.html b/core/res/res/raw-nl/nodomain.html
index ffac947..52c50e8 100644
--- a/core/res/res/raw-nl/nodomain.html
+++ b/core/res/res/raw-nl/nodomain.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Webpagina niet beschikbaar</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-pl/loaderror.html b/core/res/res/raw-pl/loaderror.html
index 9cc1342..085d69d 100644
--- a/core/res/res/raw-pl/loaderror.html
+++ b/core/res/res/raw-pl/loaderror.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Strona internetowa jest niedostępna</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-pl/nodomain.html b/core/res/res/raw-pl/nodomain.html
index 23f529d..c994abe 100644
--- a/core/res/res/raw-pl/nodomain.html
+++ b/core/res/res/raw-pl/nodomain.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Strona internetowa jest niedostępna</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-pt-rBR/loaderror.html b/core/res/res/raw-pt-rBR/loaderror.html
index 3476239..9f363c5 100644
--- a/core/res/res/raw-pt-rBR/loaderror.html
+++ b/core/res/res/raw-pt-rBR/loaderror.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>P&aacute;gina da web n&atilde;o dispon&iacute;vel</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-pt-rBR/nodomain.html b/core/res/res/raw-pt-rBR/nodomain.html
index 546c610..33b76f9 100644
--- a/core/res/res/raw-pt-rBR/nodomain.html
+++ b/core/res/res/raw-pt-rBR/nodomain.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>P&aacute;gina da web n&atilde;o dispon&iacute;vel</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-rm/loaderror.html b/core/res/res/raw-rm/loaderror.html
index 8e4a3fe..e09ed49 100644
--- a/core/res/res/raw-rm/loaderror.html
+++ b/core/res/res/raw-rm/loaderror.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Pagina d'internet betg disponibla</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-rm/nodomain.html b/core/res/res/raw-rm/nodomain.html
index 1e2833b..964f7f4 100644
--- a/core/res/res/raw-rm/nodomain.html
+++ b/core/res/res/raw-rm/nodomain.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Pagina d'internet betg disponibla</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-ru/loaderror.html b/core/res/res/raw-ru/loaderror.html
index 5a0312e..8faf416 100644
--- a/core/res/res/raw-ru/loaderror.html
+++ b/core/res/res/raw-ru/loaderror.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Веб-страница недоступна</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-ru/nodomain.html b/core/res/res/raw-ru/nodomain.html
index 86a42a1..3f606f9 100644
--- a/core/res/res/raw-ru/nodomain.html
+++ b/core/res/res/raw-ru/nodomain.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Веб-страница недоступна</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-th/loaderror.html b/core/res/res/raw-th/loaderror.html
index 05310a7..7e12c57 100644
--- a/core/res/res/raw-th/loaderror.html
+++ b/core/res/res/raw-th/loaderror.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>ไม่มีเว็บเพจนี้</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-th/nodomain.html b/core/res/res/raw-th/nodomain.html
index 37b8593..b94e4a9 100644
--- a/core/res/res/raw-th/nodomain.html
+++ b/core/res/res/raw-th/nodomain.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>ไม่มีเว็บเพจนี้</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-tr/loaderror.html b/core/res/res/raw-tr/loaderror.html
index b6f4890..665c9a8 100644
--- a/core/res/res/raw-tr/loaderror.html
+++ b/core/res/res/raw-tr/loaderror.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Web sayfası yok</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-tr/nodomain.html b/core/res/res/raw-tr/nodomain.html
index a79c21b..90545da 100644
--- a/core/res/res/raw-tr/nodomain.html
+++ b/core/res/res/raw-tr/nodomain.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>Web sayfası yok</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-zh-rCN/loaderror.html b/core/res/res/raw-zh-rCN/loaderror.html
index 809d31f..cab447b 100644
--- a/core/res/res/raw-zh-rCN/loaderror.html
+++ b/core/res/res/raw-zh-rCN/loaderror.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>找不到网页</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-zh-rCN/nodomain.html b/core/res/res/raw-zh-rCN/nodomain.html
index eb03187..ba74131 100644
--- a/core/res/res/raw-zh-rCN/nodomain.html
+++ b/core/res/res/raw-zh-rCN/nodomain.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>找不到网页</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-zh-rTW/loaderror.html b/core/res/res/raw-zh-rTW/loaderror.html
index 0b4695a..cb86ae6 100644
--- a/core/res/res/raw-zh-rTW/loaderror.html
+++ b/core/res/res/raw-zh-rTW/loaderror.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>您所查詢的網頁不存在或已移除</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-zh-rTW/nodomain.html b/core/res/res/raw-zh-rTW/nodomain.html
index 3577a9d..18d786c 100644
--- a/core/res/res/raw-zh-rTW/nodomain.html
+++ b/core/res/res/raw-zh-rTW/nodomain.html
@@ -1,5 +1,6 @@
 <html>
     <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
         <title>您所查詢的網頁不存在或已移除</title>
         <style type="text/css">
             body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 9cd04e4..aa8b643 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2498,7 +2498,7 @@
         <!-- The minimal period in milliseconds between two accessibility events of the same type
              are sent to this serivce. This setting can be changed at runtime by calling
              {@link android.accessibilityservice.AccessibilityService#setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo)
-             android.accessibilityservice.AccessibilityService.setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo)}. -->>
+             android.accessibilityservice.AccessibilityService.setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo)}. -->
         <attr name="notificationTimeout" format="integer" />
         <!-- Additional flags as specified in
              {@link android.accessibilityservice.AccessibilityServiceInfo}.
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index a2e15e6..4d54fd2 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -868,4 +868,7 @@
 
     <!-- Set to true to add links to Cell Broadcast app from Settings and MMS app. -->
     <bool name="config_cellBroadcastAppLinks">false</bool>
+
+    <!-- The default value if the SyncStorageEngine should sync automatically or not -->
+    <bool name="config_syncstorageengine_masterSyncAutomatically">true</bool>
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 0bae0cb..6334f88 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -253,6 +253,7 @@
   <java-symbol type="bool" name="config_sms_capable" />
   <java-symbol type="bool" name="config_sms_utf8_support" />
   <java-symbol type="bool" name="config_swipeDisambiguation" />
+  <java-symbol type="bool" name="config_syncstorageengine_masterSyncAutomatically" />
   <java-symbol type="bool" name="config_telephony_use_own_number_for_voicemail" />
   <java-symbol type="bool" name="config_ui_enableFadingMarquee" />
   <java-symbol type="bool" name="config_use_strict_phone_number_comparation" />
@@ -815,6 +816,13 @@
   <java-symbol type="string" name="sms_control_title" />
   <java-symbol type="string" name="sms_control_no" />
   <java-symbol type="string" name="sms_control_yes" />
+  <java-symbol type="string" name="sms_premium_short_code_confirm_message" />
+  <java-symbol type="string" name="sms_premium_short_code_confirm_title" />
+  <java-symbol type="string" name="sms_short_code_confirm_allow" />
+  <java-symbol type="string" name="sms_short_code_confirm_deny" />
+  <java-symbol type="string" name="sms_short_code_confirm_message" />
+  <java-symbol type="string" name="sms_short_code_confirm_report" />
+  <java-symbol type="string" name="sms_short_code_confirm_title" />
   <java-symbol type="string" name="submit" />
   <java-symbol type="string" name="sync_binding_label" />
   <java-symbol type="string" name="sync_do_nothing" />
@@ -1139,6 +1147,7 @@
   <java-symbol type="xml" name="password_kbd_symbols_shift" />
   <java-symbol type="xml" name="power_profile" />
   <java-symbol type="xml" name="time_zones_by_country" />
+  <java-symbol type="xml" name="sms_short_codes" />
 
   <java-symbol type="raw" name="accessibility_gestures" />
   <java-symbol type="raw" name="incognito_mode_start_page" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 325b6fe..3582768 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2923,6 +2923,22 @@
     <!-- See SMS_DIALOG.  This is a button choice to disallow sending the SMSes. [CHAR LIMIT=30] -->
     <string name="sms_control_no">Deny</string>
 
+    <!-- SMS short code verification dialog. --> <skip />
+    <!-- The dialog title for the SMS short code confirmation dialog. [CHAR LIMIT=30] -->
+    <string name="sms_short_code_confirm_title">Send SMS to short code?</string>
+    <!-- The dialog title for the SMS premium short code confirmation dialog. [CHAR LIMIT=30] -->
+    <string name="sms_premium_short_code_confirm_title">Send premium SMS?</string>
+    <!-- The message text for the SMS short code confirmation dialog. [CHAR LIMIT=NONE] -->
+    <string name="sms_short_code_confirm_message">&lt;b><xliff:g id="app_name">%1$s</xliff:g>&lt;/b> would like to send a text message to &lt;b><xliff:g id="dest_address">%2$s</xliff:g>&lt;/b>, which appears to be an SMS short code.&lt;p>Sending text messages to some short codes may cause your mobile account to be billed for premium services.&lt;p>Do you want to allow this app to send the message?</string>
+    <!-- The message text for the SMS short code confirmation dialog. [CHAR LIMIT=NONE] -->
+    <string name="sms_premium_short_code_confirm_message">&lt;b><xliff:g id="app_name">%1$s</xliff:g>&lt;/b> would like to send a text message to &lt;b><xliff:g id="dest_address">%2$s</xliff:g>&lt;/b>, which is a premium SMS short code.&lt;p>&lt;b>Sending a message to this destination will cause your mobile account to be billed for premium services.&lt;/b>&lt;p>Do you want to allow this app to send the message?</string>
+    <!-- Text of the approval button for the SMS short code confirmation dialog. [CHAR LIMIT=50] -->
+    <string name="sms_short_code_confirm_allow">Send message</string>
+    <!-- Text of the cancel button for the SMS short code confirmation dialog. [CHAR LIMIT=30] -->
+    <string name="sms_short_code_confirm_deny">Don\'t send</string>
+    <!-- Text of the button for the SMS short code confirmation dialog to report a malicious app. [CHAR LIMIT=30] -->
+    <string name="sms_short_code_confirm_report">Report malicious app</string>
+
     <!-- SIM swap and device reboot Dialog --> <skip />
     <!-- See SIM_REMOVED_DIALOG.  This is the title of that dialog. -->
     <string name="sim_removed_title">SIM card removed</string>
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
new file mode 100644
index 0000000..8b395af
--- /dev/null
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2012, 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.
+*/
+-->
+
+<!-- Regex patterns for SMS short codes by country. -->
+<shortcodes>
+
+    <!-- The country attribute is the ISO country code of the user's account (from SIM card or NV).
+         The pattern attribute is a regex that matches all SMS short codes for the country.
+         The premium attribute is a regex that matches premium rate SMS short codes.
+         The free attribute matches short codes that we know will not cost the user, such as
+         emergency numbers. The standard attribute matches short codes that are billed at the
+         standard SMS rate. The user is warned when the destination phone number matches the
+         "pattern" or "premium" regexes, and does not match the "free" or "standard" regexes. -->
+
+    <!-- Harmonised European Short Codes are 6 digit numbers starting with 116 (free helplines).
+         Premium patterns include short codes from: http://aonebill.com/coverage&tariffs
+         and http://mobilcent.com/info-worldwide.asp and extracted from:
+         http://smscoin.net/software/engine/WordPress/Paid+SMS-registration/ -->
+
+    <!-- Albania: 5 digits, known short codes listed -->
+    <shortcode country="al" pattern="\\d{5}" premium="15191|55[56]00" />
+
+    <!-- Armenia: 3-4 digits, emergency numbers 10[123] -->
+    <shortcode country="am" pattern="\\d{3,4}" premium="11[2456]1|3024" free="10[123]" />
+
+    <!-- Austria: 10 digits, premium prefix 09xx, plus EU -->
+    <shortcode country="at" pattern="11\\d{4}" premium="09.*" free="116\\d{3}" />
+
+    <!-- Australia: 6 or 8 digits starting with "19" -->
+    <shortcode country="au" pattern="19(?:\\d{4}|\\d{6})" premium="19998882" />
+
+    <!-- Azerbaijan: 4-5 digits, known premium codes listed -->
+    <shortcode country="az" pattern="\\d{4,5}" premium="330[12]|87744|901[234]|93(?:94|101)|9426|9525" />
+
+    <!-- Belgium: 4 digits, plus EU: http://www.mobileweb.be/en/mobileweb/sms-numberplan.asp -->
+    <shortcode country="be" premium="\\d{4}" free="8\\d{3}|116\\d{3}" />
+
+    <!-- Bulgaria: 4-5 digits, plus EU -->
+    <shortcode country="bg" pattern="\\d{4,5}" premium="18(?:16|423)|19(?:1[56]|35)" free="116\\d{3}" />
+
+    <!-- Belarus: 4 digits -->
+    <shortcode country="by" pattern="\\d{4}" premium="3336|4161|444[4689]|501[34]|7781" />
+
+    <!-- Canada: 5-6 digits -->
+    <shortcode country="ca" pattern="\\d{5,6}" premium="60999|88188" />
+
+    <!-- Switzerland: 3-5 digits: http://www.swisscom.ch/fxres/kmu/thirdpartybusiness_code_of_conduct_en.pdf -->
+    <shortcode country="ch" pattern="[2-9]\\d{2,4}" premium="543|83111" />
+
+    <!-- China: premium shortcodes start with "1066", free shortcodes start with "1065":
+         http://clients.txtnation.com/entries/197192-china-premium-sms-short-code-requirements -->
+    <shortcode country="cn" premium="1066.*" free="1065.*" />
+
+    <!-- Cyprus: 4-6 digits (not confirmed), known premium codes listed, plus EU -->
+    <shortcode country="cy" pattern="\\d{4,6}" premium="7510" free="116\\d{3}" />
+
+    <!-- Czech Republic: 7-8 digits, starting with 9, plus EU:
+         http://www.o2.cz/osobni/en/services-by-alphabet/91670-premium_sms.html -->
+    <shortcode country="cz" premium="9\\d{6,7}" free="116\\d{3}" />
+
+    <!-- Germany: 4-5 digits plus 1232xxx (premium codes from http://www.vodafone.de/infofaxe/537.pdf and http://premiumdienste.eplus.de/pdf/kodex.pdf), plus EU. To keep the premium regex from being too large, it only includes payment processors that have been used by SMS malware, with the regular pattern matching the other premium short codes. -->
+    <shortcode country="de" pattern="\\d{4,5}|1232\\d{3}" premium="11(?:111|833)|1232(?:013|021|060|075|286|358)|118(?:44|80|86)|20[25]00|220(?:21|22|88|99)|221(?:14|21)|223(?:44|53|77)|224[13]0|225(?:20|59|90)|226(?:06|10|20|26|30|40|56|70)|227(?:07|33|39|66|76|78|79|88|99)|228(?:08|11|66|77)|23300|30030|3[12347]000|330(?:33|55|66)|33(?:233|331|366|533)|34(?:34|567)|37000|40(?:040|123|444|[3568]00)|41(?:010|414)|44(?:000|044|344|44[24]|544)|50005|50100|50123|50555|51000|52(?:255|783)|54(?:100|2542)|55(?:077|[24]00|222|333|55|[12369]55)|56(?:789|886)|60800|6[13]000|66(?:[12348]66|566|766|777|88|999)|68888|70(?:07|123|777)|76766|77(?:007|070|222|444|[567]77)|80(?:008|123|888)|82(?:002|[378]00|323|444|472|474|488|727)|83(?:005|[169]00|333|830)|84(?:141|300|32[34]|343|488|499|777|888)|85888|86(?:188|566|640|644|650|677|868|888)|870[24]9|871(?:23|[49]9)|872(?:1[0-8]|49|99)|87499|875(?:49|55|99)|876(?:0[1367]|1[1245678]|54|99)|877(?:00|99)|878(?:15|25|3[567]|8[12])|87999|880(?:08|44|55|77|99)|88688|888(?:03|10|8|89)|8899|90(?:009|999)|99999" free="116\\d{3}" />
+
+    <!-- Denmark: see http://iprs.webspacecommerce.com/Denmark-Premium-Rate-Numbers -->
+    <shortcode country="dk" pattern="\\d{4,5}" premium="1\\d{3}" free="116\\d{3}" />
+
+    <!-- Estonia: short codes 3-5 digits starting with 1, plus premium 7 digit numbers starting with 90, plus EU.
+         http://www.tja.ee/public/documents/Elektrooniline_side/Oigusaktid/ENG/Estonian_Numbering_Plan_annex_06_09_2010.mht -->
+    <shortcode country="ee" pattern="1\\d{2,4}" premium="90\\d{5}|15330|1701[0-3]" free="116\\d{3}" />
+
+    <!-- Spain: 5-6 digits: 25xxx, 27xxx, 280xx, 35xxx, 37xxx, 795xxx, 797xxx, 995xxx, 997xxx, plus EU.
+         http://www.legallink.es/?q=en/content/which-current-regulatory-status-premium-rate-services-spain -->
+    <shortcode country="es" premium="[23][57]\\d{3}|280\\d{2}|[79]9[57]\\d{3}" free="116\\d{3}" />
+
+    <!-- Finland: 5-6 digits, premium 0600, 0700: http://en.wikipedia.org/wiki/Telephone_numbers_in_Finland -->
+    <shortcode country="fi" pattern="\\d{5,6}" premium="0600.*|0700.*|171(?:59|63)" free="116\\d{3}" />
+
+    <!-- France: 5 digits, free: 3xxxx, premium [4-8]xxxx, plus EU:
+         http://clients.txtnation.com/entries/161972-france-premium-sms-short-code-requirements -->
+    <shortcode country="fr" premium="[4-8]\\d{4}" free="3\\d{4}|116\\d{3}" />
+
+    <!-- United Kingdom (Great Britain): 4-6 digits, common codes [5-8]xxxx, plus EU:
+         http://www.short-codes.com/media/Co-regulatoryCodeofPracticeforcommonshortcodes170206.pdf -->
+    <shortcode country="gb" pattern="\\d{4,6}" premium="[5-8]\\d{4}" free="116\\d{3}" />
+
+    <!-- Georgia: 4 digits, known premium codes listed -->
+    <shortcode country="ge" pattern="\\d{4}" premium="801[234]|888[239]" />
+
+    <!-- Greece: 5 digits (54xxx, 19yxx, x=0-9, y=0-5): http://www.cmtelecom.com/premium-sms/greece -->
+    <shortcode country="gr" pattern="\\d{5}" premium="54\\d{3}|19[0-5]\\d{2}" free="116\\d{3}" />
+
+    <!-- Hungary: 4 or 10 digits starting with 1 or 0, plus EU:
+         http://clients.txtnation.com/entries/209633-hungary-premium-sms-short-code-regulations -->
+    <shortcode country="hu" pattern="[01](?:\\d{3}|\\d{9})" premium="0691227910|1784" free="116\\d{3}" />
+
+    <!-- Ireland: 5 digits, 5xxxx (50xxx=free, 5[12]xxx=standard), plus EU:
+         http://www.comreg.ie/_fileupload/publications/ComReg1117.pdf -->
+    <shortcode country="ie" pattern="\\d{5}" premium="5[3-9]\\d{3}" free="50\\d{3}|116\\d{3}" standard="5[12]\\d{3}" />
+
+    <!-- Israel: 4 digits, known premium codes listed -->
+    <shortcode country="il" pattern="\\d{4}" premium="4422|4545" />
+
+    <!-- Italy: 5 digits (premium=4xxxx), plus EU:
+         http://clients.txtnation.com/attachments/token/di5kfblvubttvlw/?name=Italy_CASP_EN.pdf -->
+    <shortcode country="it" pattern="\\d{5}" premium="4\\d{4}" free="116\\d{3}" />
+
+    <!-- Kyrgyzstan: 4 digits, known premium codes listed -->
+    <shortcode country="kg" pattern="\\d{4}" premium="415[2367]|444[69]" />
+
+    <!-- Kazakhstan: 4 digits, known premium codes listed: http://smscoin.net/info/pricing-kazakhstan/ -->
+    <shortcode country="kz" pattern="\\d{4}" premium="335[02]|4161|444[469]|77[2359]0|8444|919[3-5]|968[2-5]" />
+
+    <!-- Lithuania: 3-5 digits, known premium codes listed, plus EU -->
+    <shortcode country="lt" pattern="\\d{3,5}" premium="13[89]1|1394|16[34]5" free="116\\d{3}" />
+
+    <!-- Luxembourg: 5 digits, 6xxxx, plus EU:
+         http://www.luxgsm.lu/assets/files/filepage/file_1253803400.pdf -->
+    <shortcode country="lu" premium="6\\d{4}" free="116\\d{3}" />
+
+    <!-- Latvia: 4 digits, known premium codes listed, plus EU -->
+    <shortcode country="lv" pattern="\\d{4}" premium="18(?:19|63|7[1-4])" free="116\\d{3}" />
+
+    <!-- Mexico: 4-5 digits (not confirmed), known premium codes listed -->
+    <shortcode country="mx" pattern="\\d{4,5}" premium="53035|7766" />
+
+    <!-- Malaysia: 5 digits: http://www.skmm.gov.my/attachment/Consumer_Regulation/Mobile_Content_Services_FAQs.pdf -->
+    <shortcode country="my" pattern="\\d{5}" premium="32298|33776" />
+
+    <!-- The Netherlands, 4 digits, known premium codes listed, plus EU -->
+    <shortcode country="nl" pattern="\\d{4}" premium="4466|5040" free="116\\d{3}" />
+
+    <!-- Norway: 4-5 digits (not confirmed), known premium codes listed -->
+    <shortcode country="no" pattern="\\d{4,5}" premium="2201|222[67]" />
+
+    <!-- New Zealand: 3-4 digits, known premium codes listed -->
+    <shortcode country="nz" pattern="\\d{3,4}" premium="3903|8995" />
+
+    <!-- Poland: 4-5 digits (not confirmed), known premium codes listed, plus EU -->
+    <shortcode country="pl" pattern="\\d{4,5}" premium="74240|79(?:10|866)|92525" free="116\\d{3}" />
+
+    <!-- Portugal: 5 digits, plus EU:
+         http://clients.txtnation.com/entries/158326-portugal-premium-sms-short-code-regulations -->
+    <shortcode country="pt" premium="6[1289]\\d{3}" free="116\\d{3}" />
+
+    <!-- Romania: 4 digits, plus EU: http://www.simplus.ro/en/resources/glossary-of-terms/ -->
+    <shortcode country="ro" pattern="\\d{4}" premium="12(?:63|66|88)|13(?:14|80)" free="116\\d{3}" />
+
+    <!-- Russia: 4 digits, known premium codes listed: http://smscoin.net/info/pricing-russia/ -->
+    <shortcode country="ru" pattern="\\d{4}" premium="1(?:1[56]1|899)|2(?:09[57]|322|47[46]|880|990)|3[589]33|4161|44(?:4[3-9]|81)|77(?:33|81)" />
+
+    <!-- Sweden: 5 digits (72xxx), plus EU: http://www.viatel.se/en/premium-sms/ -->
+    <shortcode country="se" premium="72\\d{3}" free="116\\d{3}" />
+
+    <!-- Singapore: 5 digits: http://clients.txtnation.com/entries/306442-singapore-premium-sms-short-code-requirements
+         Free government directory info at 74688: http://app.sgdi.gov.sg/sms_help.asp -->
+    <shortcode country="sg" pattern="7\\d{4}" premium="73800" standard="74688" />
+
+    <!-- Slovenia: 4 digits (premium=3xxx, 6xxx, 8xxx), plus EU: http://www.cmtelecom.com/premium-sms/slovenia -->
+    <shortcode country="si" pattern="\\d{4}" premium="[368]\\d{3}" free="116\\d{3}" />
+
+    <!-- Slovakia: 4 digits (premium), plus EU: http://www.cmtelecom.com/premium-sms/slovakia -->
+    <shortcode country="sk" premium="\\d{4}" free="116\\d{3}" />
+
+    <!-- Tajikistan: 4 digits, known premium codes listed -->
+    <shortcode country="tj" pattern="\\d{4}" premium="11[3-7]1|4161|4333|444[689]" />
+
+    <!-- Ukraine: 4 digits, known premium codes listed -->
+    <shortcode country="ua" pattern="\\d{4}" premium="444[3-9]|70[579]4|7540" />
+
+    <!-- USA: 5-6 digits (premium codes from https://www.premiumsmsrefunds.com/ShortCodes.htm) -->
+    <shortcode country="us" pattern="\\d{5,6}" premium="20433|21(?:344|472)|22715|23(?:333|847)|24(?:15|28)0|25209|27(?:449|606|663)|28498|305(?:00|83)|32(?:340|941)|33(?:166|786|849)|34746|35(?:182|564)|37975|38(?:135|146|254)|41(?:366|463)|42335|43(?:355|500)|44(?:578|711|811)|45814|46(?:157|173|327)|46666|47553|48(?:221|277|669)|50(?:844|920)|51(?:062|368)|52944|54(?:723|892)|55928|56483|57370|59(?:182|187|252|342)|60339|61(?:266|982)|62478|64(?:219|898)|65(?:108|500)|69(?:208|388)|70877|71851|72(?:078|087|465)|73(?:288|588|882|909|997)|74(?:034|332|815)|76426|79213|81946|83177|84(?:103|685)|85797|86(?:234|236|666)|89616|90(?:715|842|938)|91(?:362|958)|94719|95297|96(?:040|666|835|969)|97(?:142|294|688)|99(?:689|796|807)" />
+
+</shortcodes>
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk
index 88f3f34..b6b15c4 100644
--- a/core/tests/coretests/Android.mk
+++ b/core/tests/coretests/Android.mk
@@ -23,7 +23,7 @@
 
 LOCAL_DX_FLAGS := --core-library
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests android-common frameworks-core-util-lib mockwebserver guava littlemock
-LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common
 LOCAL_PACKAGE_NAME := FrameworksCoreTests
 
 LOCAL_CERTIFICATE := platform
diff --git a/core/tests/coretests/apks/install_complete_package_info/Android.mk b/core/tests/coretests/apks/install_complete_package_info/Android.mk
new file mode 100644
index 0000000..1edccb4
--- /dev/null
+++ b/core/tests/coretests/apks/install_complete_package_info/Android.mk
@@ -0,0 +1,11 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := FrameworkCoreTests_install_complete_package_info
+
+include $(BUILD_PACKAGE)
+
diff --git a/core/tests/coretests/apks/install_complete_package_info/AndroidManifest.xml b/core/tests/coretests/apks/install_complete_package_info/AndroidManifest.xml
new file mode 100644
index 0000000..4b01736
--- /dev/null
+++ b/core/tests/coretests/apks/install_complete_package_info/AndroidManifest.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+<manifest
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.frameworks.coretests.install_complete_package_info">
+
+<!--
+     This manifest declares at least one of each of the components that
+     can be retrieved by PackageManager.getInstalledPackages.
+     All the implementing classes are empty implementations
+-->
+
+    <uses-feature
+        android:name="com.android.frameworks.coretests.nonexistent" />
+    <uses-configuration
+        android:reqFiveWayNav="false" />
+
+    <instrumentation
+        android:name="android.test.InstrumentationTestRunner"
+        android:targetPackage="com.android.frameworks.coretests"
+        android:label="Frameworks Core Tests" />
+
+    <permission
+        android:label="test permission"
+        android:name="test_permission"
+        android:protectionLevel="normal" />
+
+    <application
+        android:hasCode="true">
+        <activity
+            android:name="com.android.frameworks.coretests.TestActivity">
+        </activity>
+        <provider
+            android:name="com.android.frameworks.coretests.TestProvider"
+            android:authorities="com.android.frameworks.coretests.testprovider" />
+        <receiver
+            android:name="com.android.frameworks.coretests.TestReceiver" />
+        <service
+            android:name="com.android.frameworks.coretests.TestService" />
+    </application>
+</manifest>
diff --git a/telephony/java/com/android/internal/telephony/IccException.java b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestActivity.java
similarity index 68%
rename from telephony/java/com/android/internal/telephony/IccException.java
rename to core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestActivity.java
index 1659a4e..10d0551 100644
--- a/telephony/java/com/android/internal/telephony/IccException.java
+++ b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestActivity.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -12,19 +12,13 @@
  * 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.internal.telephony;
+package com.android.frameworks.coretests;
 
-/**
- * {@hide}
- */
-public class IccException extends Exception {
-    public IccException() {
+import android.app.Activity;
 
-    }
+public class TestActivity extends Activity {
 
-    public IccException(String s) {
-        super(s);
-    }
 }
diff --git a/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestProvider.java b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestProvider.java
new file mode 100644
index 0000000..59f9f10
--- /dev/null
+++ b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestProvider.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2011 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.frameworks.coretests;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+
+public class TestProvider extends ContentProvider {
+
+    @Override
+    public boolean onCreate() {
+        return false;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        return null;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        return null;
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        return null;
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        return 0;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        return 0;
+    }
+}
diff --git a/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestReceiver.java b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestReceiver.java
new file mode 100644
index 0000000..21f6263
--- /dev/null
+++ b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestReceiver.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2011 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.frameworks.coretests;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+
+public class TestReceiver extends ContentProvider {
+
+    @Override
+    public boolean onCreate() {
+        return false;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        return null;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        return null;
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        return null;
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        return 0;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        return 0;
+    }
+}
diff --git a/telephony/java/com/android/internal/telephony/cat/CatException.java b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestService.java
similarity index 65%
rename from telephony/java/com/android/internal/telephony/cat/CatException.java
rename to core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestService.java
index 1bf1369..b330e75 100644
--- a/telephony/java/com/android/internal/telephony/cat/CatException.java
+++ b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -12,20 +12,19 @@
  * 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.internal.telephony.cat;
-
-import android.util.AndroidException;
-
-
-/**
- * Base class for all the exceptions in CAT service.
  *
- * {@hide}
  */
-class CatException extends AndroidException {
-    public CatException() {
-        super();
+
+package com.android.frameworks.coretests;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+public class TestService extends Service {
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
     }
 }
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 77e4986..6e1b9d6 100755
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
@@ -50,6 +51,8 @@
 import java.io.IOException;
 import java.io.InputStream;
 
+import java.util.List;
+
 public class PackageManagerTests extends AndroidTestCase {
     private static final boolean localLOGV = true;
     public static final String TAG="PackageManagerTests";
@@ -3162,6 +3165,92 @@
         assertNotNull("Verifier device identity should not be null", id);
     }
 
+    public void testGetInstalledPackages() {
+        List<PackageInfo> packages = getPm().getInstalledPackages(0);
+        assertNotNull("installed packages cannot be null", packages);
+        assertTrue("installed packages cannot be empty", packages.size() > 0);
+    }
+
+    public void testGetUnInstalledPackages() {
+        List<PackageInfo> packages = getPm().getInstalledPackages(
+                PackageManager.GET_UNINSTALLED_PACKAGES);
+        assertNotNull("installed packages cannot be null", packages);
+        assertTrue("installed packages cannot be empty", packages.size() > 0);
+    }
+
+    /**
+     * Test that getInstalledPackages returns all the data specified in
+     * flags.
+     */
+    public void testGetInstalledPackagesAll() {
+        int flags = PackageManager.GET_ACTIVITIES | PackageManager.GET_GIDS
+                | PackageManager.GET_CONFIGURATIONS | PackageManager.GET_INSTRUMENTATION
+                | PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS
+                | PackageManager.GET_RECEIVERS | PackageManager.GET_SERVICES
+                | PackageManager.GET_SIGNATURES | PackageManager.GET_UNINSTALLED_PACKAGES;
+
+        List<PackageInfo> packages = getPm().getInstalledPackages(flags);
+        assertNotNull("installed packages cannot be null", packages);
+        assertTrue("installed packages cannot be empty", packages.size() > 0);
+
+        PackageInfo packageInfo = null;
+
+        // Find the package with all components specified in the AndroidManifest
+        // to ensure no null values
+        for (PackageInfo pi : packages) {
+            if ("com.android.frameworks.coretests.install_complete_package_info"
+                    .equals(pi.packageName)) {
+                packageInfo = pi;
+                break;
+            }
+        }
+        assertNotNull("activities should not be null", packageInfo.activities);
+        assertNotNull("configPreferences should not be null", packageInfo.configPreferences);
+        assertNotNull("instrumentation should not be null", packageInfo.instrumentation);
+        assertNotNull("permissions should not be null", packageInfo.permissions);
+        assertNotNull("providers should not be null", packageInfo.providers);
+        assertNotNull("receivers should not be null", packageInfo.receivers);
+        assertNotNull("services should not be null", packageInfo.services);
+        assertNotNull("signatures should not be null", packageInfo.signatures);
+    }
+
+    /**
+     * Test that getInstalledPackages returns all the data specified in
+     * flags when the GET_UNINSTALLED_PACKAGES flag is set.
+     */
+    public void testGetUnInstalledPackagesAll() {
+        int flags = PackageManager.GET_UNINSTALLED_PACKAGES
+                | PackageManager.GET_ACTIVITIES | PackageManager.GET_GIDS
+                | PackageManager.GET_CONFIGURATIONS | PackageManager.GET_INSTRUMENTATION
+                | PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS
+                | PackageManager.GET_RECEIVERS | PackageManager.GET_SERVICES
+                | PackageManager.GET_SIGNATURES | PackageManager.GET_UNINSTALLED_PACKAGES;
+
+        List<PackageInfo> packages = getPm().getInstalledPackages(flags);
+        assertNotNull("installed packages cannot be null", packages);
+        assertTrue("installed packages cannot be empty", packages.size() > 0);
+
+        PackageInfo packageInfo = null;
+
+        // Find the package with all components specified in the AndroidManifest
+        // to ensure no null values
+        for (PackageInfo pi : packages) {
+            if ("com.android.frameworks.coretests.install_complete_package_info"
+                    .equals(pi.packageName)) {
+                packageInfo = pi;
+                break;
+            }
+        }
+        assertNotNull("activities should not be null", packageInfo.activities);
+        assertNotNull("configPreferences should not be null", packageInfo.configPreferences);
+        assertNotNull("instrumentation should not be null", packageInfo.instrumentation);
+        assertNotNull("permissions should not be null", packageInfo.permissions);
+        assertNotNull("providers should not be null", packageInfo.providers);
+        assertNotNull("receivers should not be null", packageInfo.receivers);
+        assertNotNull("services should not be null", packageInfo.services);
+        assertNotNull("signatures should not be null", packageInfo.signatures);
+    }
+
     /*---------- Recommended install location tests ----*/
     /*
      * TODO's
diff --git a/core/tests/coretests/src/android/os/FileUtilsTest.java b/core/tests/coretests/src/android/os/FileUtilsTest.java
index f12cbe1..4d0b892 100644
--- a/core/tests/coretests/src/android/os/FileUtilsTest.java
+++ b/core/tests/coretests/src/android/os/FileUtilsTest.java
@@ -17,21 +17,13 @@
 package android.os;
 
 import android.content.Context;
-import android.os.FileUtils;
-import android.os.FileUtils.FileStatus;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
 import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.SmallTest;
 
 import java.io.ByteArrayInputStream;
 import java.io.File;
-import java.io.FileWriter;
-import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
-import java.io.IOException;
-
-import junit.framework.Assert;
+import java.io.FileWriter;
 
 public class FileUtilsTest extends AndroidTestCase {
     private static final String TEST_DATA =
@@ -60,60 +52,6 @@
         if (mCopyFile.exists()) mCopyFile.delete();
     }
 
-    @LargeTest
-    public void testGetFileStatus() {
-        final byte[] MAGIC = { 0xB, 0xE, 0x0, 0x5 };
-
-        try {
-            // truncate test file and write MAGIC (4 bytes) to it.
-            FileOutputStream os = new FileOutputStream(mTestFile, false);
-            os.write(MAGIC, 0, 4);
-            os.flush();
-            os.close();
-        } catch (FileNotFoundException e) {
-            Assert.fail("File was removed durning test" + e);
-        } catch (IOException e) {
-            Assert.fail("Unexpected IOException: " + e);
-        }
-        
-        Assert.assertTrue(mTestFile.exists());
-        Assert.assertTrue(FileUtils.getFileStatus(mTestFile.getPath(), null));
-        
-        FileStatus status1 = new FileStatus();
-        FileUtils.getFileStatus(mTestFile.getPath(), status1);
-        
-        Assert.assertEquals(4, status1.size);
-        
-        // Sleep for at least one second so that the modification time will be different.
-        try {
-            Thread.sleep(1000);
-        } catch (InterruptedException e) {
-        }
-
-        try {
-            // append so we don't change the creation time.
-            FileOutputStream os = new FileOutputStream(mTestFile, true);
-            os.write(MAGIC, 0, 4);
-            os.flush();
-            os.close();
-        } catch (FileNotFoundException e) {
-            Assert.fail("File was removed durning test" + e);
-        } catch (IOException e) {
-            Assert.fail("Unexpected IOException: " + e);
-        }
-        
-        FileStatus status2 = new FileStatus();
-        FileUtils.getFileStatus(mTestFile.getPath(), status2);
-        
-        Assert.assertEquals(8, status2.size);
-        Assert.assertTrue(status2.mtime > status1.mtime);
-        
-        mTestFile.delete();
-        
-        Assert.assertFalse(mTestFile.exists());
-        Assert.assertFalse(FileUtils.getFileStatus(mTestFile.getPath(), null));
-    }
-
     // TODO: test setPermissions(), getPermissions()
 
     @MediumTest
diff --git a/core/tests/coretests/src/android/os/SELinuxTest.java b/core/tests/coretests/src/android/os/SELinuxTest.java
new file mode 100644
index 0000000..9b63a6b
--- /dev/null
+++ b/core/tests/coretests/src/android/os/SELinuxTest.java
@@ -0,0 +1,45 @@
+package android.os;
+
+import android.os.Process;
+import android.os.SELinux;
+import android.test.AndroidTestCase;
+import static junit.framework.Assert.assertEquals;
+
+public class SELinuxTest extends AndroidTestCase {
+
+    public void testgetFileCon() {
+        if(SELinux.isSELinuxEnabled() == false)
+            return;
+
+        String ctx = SELinux.getFileContext("/system/bin/toolbox");
+        assertEquals(ctx, "u:object_r:system_file:s0");
+    }
+
+    public void testgetCon() {
+        if(SELinux.isSELinuxEnabled() == false)
+            return;
+
+        String mycon = SELinux.getContext();
+        assertEquals(mycon, "u:r:untrusted_app:s0:c33");
+    }
+
+    public void testgetPidCon() {
+        if(SELinux.isSELinuxEnabled() == false)
+            return;
+
+        String mycon = SELinux.getPidContext(Process.myPid());
+        assertEquals(mycon, "u:r:untrusted_app:s0:c33");
+    }
+
+    public void testcheckSELinuxAccess() {
+        if(SELinux.isSELinuxEnabled() == false)
+            return;
+
+        String mycon = SELinux.getContext();
+        boolean ret;
+        ret = SELinux.checkSELinuxAccess(mycon, mycon, "process", "fork");
+        assertEquals(ret,"true");
+        ret = SELinux.checkSELinuxAccess(mycon, mycon, "memprotect", "mmap_zero");
+        assertEquals(ret,"true");
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java b/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java
index ab6b2b6..418bbd6 100644
--- a/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java
@@ -24,7 +24,7 @@
 
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
-import com.android.internal.util.StateMachine.ProcessedMessageInfo;
+import com.android.internal.util.StateMachine.LogRec;
 
 import android.test.suitebuilder.annotation.MediumTest;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -36,6 +36,10 @@
  * Test for StateMachine.
  */
 public class StateMachineTest extends TestCase {
+    private static final String ENTER = "enter";
+    private static final String EXIT = "exit";
+    private static final String ON_QUITTING = "ON_QUITTING";
+
     private static final int TEST_CMD_1 = 1;
     private static final int TEST_CMD_2 = 2;
     private static final int TEST_CMD_3 = 3;
@@ -47,11 +51,18 @@
     private static final boolean WAIT_FOR_DEBUGGER = false;
     private static final String TAG = "StateMachineTest";
 
+    private void sleep(int millis) {
+        try {
+            Thread.sleep(millis);
+        } catch(InterruptedException e) {
+        }
+    }
+
     /**
-     * Tests that we can quit the state machine.
+     * Tests {@link StateMachine#quit()}.
      */
     class StateMachineQuitTest extends StateMachine {
-        private int mQuitCount = 0;
+        Object mWaitUntilTestDone = new Object();
 
         StateMachineQuitTest(String name) {
             super(name);
@@ -65,29 +76,45 @@
             setInitialState(mS1);
         }
 
-        class S1 extends State {
-            @Override
-            public boolean processMessage(Message message) {
-                if (isQuit(message)) {
-                    mQuitCount += 1;
-                    if (mQuitCount > 2) {
-                        // Returning NOT_HANDLED to actually quit
-                        return NOT_HANDLED;
-                    } else {
-                        // Do NOT quit
-                        return HANDLED;
-                    }
-                } else  {
-                    // All other message are handled
-                    return HANDLED;
+        @Override
+        public void onQuitting() {
+            Log.d(TAG, "onQuitting");
+            addLogRec(ON_QUITTING);
+            synchronized (mThisSm) {
+                mThisSm.notifyAll();
+            }
+
+            // Don't leave onQuitting before the test is done as everything is cleared
+            // including the log records.
+            synchronized (mWaitUntilTestDone) {
+                try {
+                    mWaitUntilTestDone.wait();
+                } catch(InterruptedException e) {
                 }
             }
         }
 
-        @Override
-        protected void quitting() {
-            synchronized (mThisSm) {
-                mThisSm.notifyAll();
+        class S1 extends State {
+            public void exit() {
+                Log.d(TAG, "S1.exit");
+                addLogRec(EXIT, mS1);
+            }
+            @Override
+            public boolean processMessage(Message message) {
+                switch(message.what) {
+                    // Sleep and assume the other messages will be queued up.
+                    case TEST_CMD_1: {
+                        Log.d(TAG, "TEST_CMD_1");
+                        sleep(500);
+                        quit();
+                        break;
+                    }
+                    default: {
+                        Log.d(TAG, "default what=" + message.what);
+                        break;
+                    }
+                }
+                return HANDLED;
             }
         }
 
@@ -96,62 +123,167 @@
     }
 
     @SmallTest
-    public void testStateMachineQuitTest() throws Exception {
+    public void testStateMachineQuit() throws Exception {
         if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
 
         StateMachineQuitTest smQuitTest = new StateMachineQuitTest("smQuitTest");
         smQuitTest.start();
-        if (smQuitTest.isDbg()) Log.d(TAG, "testStateMachineQuitTest E");
+        if (smQuitTest.isDbg()) Log.d(TAG, "testStateMachineQuit E");
 
         synchronized (smQuitTest) {
-            // Send 6 messages
+
+            // Send 6 message we'll quit on the first but all 6 should be processed before quitting.
             for (int i = 1; i <= 6; i++) {
-                smQuitTest.sendMessage(i);
+                smQuitTest.sendMessage(smQuitTest.obtainMessage(i));
             }
 
-            // First two are ignored
-            smQuitTest.quit();
-            smQuitTest.quit();
-
-            // Now we will quit
-            smQuitTest.quit();
-
             try {
                 // wait for the messages to be handled
                 smQuitTest.wait();
             } catch (InterruptedException e) {
-                Log.e(TAG, "testStateMachineQuitTest: exception while waiting " + e.getMessage());
+                Log.e(TAG, "testStateMachineQuit: exception while waiting " + e.getMessage());
             }
         }
 
-        assertTrue(smQuitTest.getProcessedMessagesCount() == 9);
+        assertEquals(8, smQuitTest.getLogRecCount());
 
-        ProcessedMessageInfo pmi;
+        LogRec lr;
 
-        // The first two message didn't quit and were handled by mS1
-        pmi = smQuitTest.getProcessedMessageInfo(6);
-        assertEquals(StateMachine.SM_QUIT_CMD, pmi.getWhat());
-        assertEquals(smQuitTest.mS1, pmi.getState());
-        assertEquals(smQuitTest.mS1, pmi.getOriginalState());
+        for (int i = 0; i < 6; i++) {
+            lr = smQuitTest.getLogRec(i);
+            assertEquals(i+1, lr.getWhat());
+            assertEquals(smQuitTest.mS1, lr.getState());
+            assertEquals(smQuitTest.mS1, lr.getOriginalState());
+        }
+        lr = smQuitTest.getLogRec(6);
+        assertEquals(EXIT, lr.getInfo());
+        assertEquals(smQuitTest.mS1, lr.getState());
 
-        pmi = smQuitTest.getProcessedMessageInfo(7);
-        assertEquals(StateMachine.SM_QUIT_CMD, pmi.getWhat());
-        assertEquals(smQuitTest.mS1, pmi.getState());
-        assertEquals(smQuitTest.mS1, pmi.getOriginalState());
+        lr = smQuitTest.getLogRec(7);
+        assertEquals(ON_QUITTING, lr.getInfo());
 
-        // The last message was never handled so the states are null
-        pmi = smQuitTest.getProcessedMessageInfo(8);
-        assertEquals(StateMachine.SM_QUIT_CMD, pmi.getWhat());
-        assertEquals(null, pmi.getState());
-        assertEquals(null, pmi.getOriginalState());
+        synchronized (smQuitTest.mWaitUntilTestDone) {
+            smQuitTest.mWaitUntilTestDone.notifyAll();
+        }
+        if (smQuitTest.isDbg()) Log.d(TAG, "testStateMachineQuit X");
+    }
 
-        if (smQuitTest.isDbg()) Log.d(TAG, "testStateMachineQuitTest X");
+    /**
+     * Tests {@link StateMachine#quitNow()}
+     */
+    class StateMachineQuitNowTest extends StateMachine {
+        Object mWaitUntilTestDone = new Object();
+
+        StateMachineQuitNowTest(String name) {
+            super(name);
+            mThisSm = this;
+            setDbg(DBG);
+
+            // Setup state machine with 1 state
+            addState(mS1);
+
+            // Set the initial state
+            setInitialState(mS1);
+        }
+
+        @Override
+        public void onQuitting() {
+            Log.d(TAG, "onQuitting");
+            addLogRec(ON_QUITTING);
+            synchronized (mThisSm) {
+                mThisSm.notifyAll();
+            }
+
+            // Don't leave onQuitting before the test is done as everything is cleared
+            // including the log records.
+            synchronized (mWaitUntilTestDone) {
+                try {
+                    mWaitUntilTestDone.wait();
+                } catch(InterruptedException e) {
+                }
+            }
+        }
+
+        class S1 extends State {
+            public void exit() {
+                Log.d(TAG, "S1.exit");
+                addLogRec(EXIT, mS1);
+            }
+            @Override
+            public boolean processMessage(Message message) {
+                switch(message.what) {
+                    // Sleep and assume the other messages will be queued up.
+                    case TEST_CMD_1: {
+                        Log.d(TAG, "TEST_CMD_1");
+                        sleep(500);
+                        quitNow();
+                        break;
+                    }
+                    default: {
+                        Log.d(TAG, "default what=" + message.what);
+                        break;
+                    }
+                }
+                return HANDLED;
+            }
+        }
+
+        private StateMachineQuitNowTest mThisSm;
+        private S1 mS1 = new S1();
+    }
+
+    @SmallTest
+    public void testStateMachineQuitNow() throws Exception {
+        if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
+
+        StateMachineQuitNowTest smQuitNowTest = new StateMachineQuitNowTest("smQuitNowTest");
+        smQuitNowTest.start();
+        if (smQuitNowTest.isDbg()) Log.d(TAG, "testStateMachineQuitNow E");
+
+        synchronized (smQuitNowTest) {
+
+            // Send 6 messages but we'll QuitNow on the first so even though
+            // we send 6 only one will be processed.
+            for (int i = 1; i <= 6; i++) {
+                smQuitNowTest.sendMessage(smQuitNowTest.obtainMessage(i));
+            }
+
+            try {
+                // wait for the messages to be handled
+                smQuitNowTest.wait();
+            } catch (InterruptedException e) {
+                Log.e(TAG, "testStateMachineQuitNow: exception while waiting " + e.getMessage());
+            }
+        }
+
+        // Only three records because we executed quitNow.
+        assertEquals(3, smQuitNowTest.getLogRecCount());
+
+        LogRec lr;
+
+        lr = smQuitNowTest.getLogRec(0);
+        assertEquals(1, lr.getWhat());
+        assertEquals(smQuitNowTest.mS1, lr.getState());
+        assertEquals(smQuitNowTest.mS1, lr.getOriginalState());
+
+        lr = smQuitNowTest.getLogRec(1);
+        assertEquals(EXIT, lr.getInfo());
+        assertEquals(smQuitNowTest.mS1, lr.getState());
+
+        lr = smQuitNowTest.getLogRec(2);
+        assertEquals(ON_QUITTING, lr.getInfo());
+
+        synchronized (smQuitNowTest.mWaitUntilTestDone) {
+            smQuitNowTest.mWaitUntilTestDone.notifyAll();
+        }
+        if (smQuitNowTest.isDbg()) Log.d(TAG, "testStateMachineQuitNow X");
     }
 
     /**
      * Test enter/exit can use transitionTo
      */
     class StateMachineEnterExitTransitionToTest extends StateMachine {
+
         StateMachineEnterExitTransitionToTest(String name) {
             super(name);
             mThisSm = this;
@@ -170,20 +302,15 @@
         class S1 extends State {
             @Override
             public void enter() {
-                // Test that message is HSM_INIT_CMD
-                assertEquals(SM_INIT_CMD, getCurrentMessage().what);
-
-                // Test that a transition in enter and the initial state works
-                mS1EnterCount += 1;
+                // Test transitions in enter on the initial state work
+                addLogRec(ENTER, mS1);
                 transitionTo(mS2);
                 Log.d(TAG, "S1.enter");
             }
             @Override
             public void exit() {
                 // Test that message is HSM_INIT_CMD
-                assertEquals(SM_INIT_CMD, getCurrentMessage().what);
-
-                mS1ExitCount += 1;
+                addLogRec(EXIT, mS1);
                 Log.d(TAG, "S1.exit");
             }
         }
@@ -191,19 +318,15 @@
         class S2 extends State {
             @Override
             public void enter() {
-                // Test that message is HSM_INIT_CMD
-                assertEquals(SM_INIT_CMD, getCurrentMessage().what);
-
-                mS2EnterCount += 1;
+                addLogRec(ENTER, mS2);
                 Log.d(TAG, "S2.enter");
             }
             @Override
             public void exit() {
-                // Test that message is TEST_CMD_1
+                addLogRec(EXIT, mS2);
                 assertEquals(TEST_CMD_1, getCurrentMessage().what);
 
                 // Test transition in exit work
-                mS2ExitCount += 1;
                 transitionTo(mS4);
                 Log.d(TAG, "S2.exit");
             }
@@ -220,36 +343,33 @@
         class S3 extends State {
             @Override
             public void enter() {
-                // Test that we can do halting in an enter/exit
-                transitionToHaltingState();
-                mS3EnterCount += 1;
+                addLogRec(ENTER, mS3);
                 Log.d(TAG, "S3.enter");
             }
             @Override
             public void exit() {
-                mS3ExitCount += 1;
+                addLogRec(EXIT, mS3);
                 Log.d(TAG, "S3.exit");
             }
         }
 
-
         class S4 extends State {
             @Override
             public void enter() {
+                addLogRec(ENTER, mS4);
                 // Test that we can do halting in an enter/exit
                 transitionToHaltingState();
-                mS4EnterCount += 1;
                 Log.d(TAG, "S4.enter");
             }
             @Override
             public void exit() {
-                mS4ExitCount += 1;
+                addLogRec(EXIT, mS4);
                 Log.d(TAG, "S4.exit");
             }
         }
 
         @Override
-        protected void halting() {
+        protected void onHalting() {
             synchronized (mThisSm) {
                 mThisSm.notifyAll();
             }
@@ -260,14 +380,6 @@
         private S2 mS2 = new S2();
         private S3 mS3 = new S3();
         private S4 mS4 = new S4();
-        private int mS1EnterCount = 0;
-        private int mS1ExitCount = 0;
-        private int mS2EnterCount = 0;
-        private int mS2ExitCount = 0;
-        private int mS3EnterCount = 0;
-        private int mS3ExitCount = 0;
-        private int mS4EnterCount = 0;
-        private int mS4ExitCount = 0;
     }
 
     @SmallTest
@@ -293,24 +405,46 @@
             }
         }
 
-        assertTrue(smEnterExitTranstionToTest.getProcessedMessagesCount() == 1);
+        assertEquals(smEnterExitTranstionToTest.getLogRecCount(), 9);
 
-        ProcessedMessageInfo pmi;
+        LogRec lr;
 
-        // Message should be handled by mS2.
-        pmi = smEnterExitTranstionToTest.getProcessedMessageInfo(0);
-        assertEquals(TEST_CMD_1, pmi.getWhat());
-        assertEquals(smEnterExitTranstionToTest.mS2, pmi.getState());
-        assertEquals(smEnterExitTranstionToTest.mS2, pmi.getOriginalState());
+        lr = smEnterExitTranstionToTest.getLogRec(0);
+        assertEquals(ENTER, lr.getInfo());
+        assertEquals(smEnterExitTranstionToTest.mS1, lr.getState());
 
-        assertEquals(smEnterExitTranstionToTest.mS1EnterCount, 1);
-        assertEquals(smEnterExitTranstionToTest.mS1ExitCount, 1);
-        assertEquals(smEnterExitTranstionToTest.mS2EnterCount, 1);
-        assertEquals(smEnterExitTranstionToTest.mS2ExitCount, 1);
-        assertEquals(smEnterExitTranstionToTest.mS3EnterCount, 1);
-        assertEquals(smEnterExitTranstionToTest.mS3ExitCount, 1);
-        assertEquals(smEnterExitTranstionToTest.mS3EnterCount, 1);
-        assertEquals(smEnterExitTranstionToTest.mS3ExitCount, 1);
+        lr = smEnterExitTranstionToTest.getLogRec(1);
+        assertEquals(EXIT, lr.getInfo());
+        assertEquals(smEnterExitTranstionToTest.mS1, lr.getState());
+
+        lr = smEnterExitTranstionToTest.getLogRec(2);
+        assertEquals(ENTER, lr.getInfo());
+        assertEquals(smEnterExitTranstionToTest.mS2, lr.getState());
+
+        lr = smEnterExitTranstionToTest.getLogRec(3);
+        assertEquals(TEST_CMD_1, lr.getWhat());
+        assertEquals(smEnterExitTranstionToTest.mS2, lr.getState());
+        assertEquals(smEnterExitTranstionToTest.mS2, lr.getOriginalState());
+
+        lr = smEnterExitTranstionToTest.getLogRec(4);
+        assertEquals(EXIT, lr.getInfo());
+        assertEquals(smEnterExitTranstionToTest.mS2, lr.getState());
+
+        lr = smEnterExitTranstionToTest.getLogRec(5);
+        assertEquals(ENTER, lr.getInfo());
+        assertEquals(smEnterExitTranstionToTest.mS3, lr.getState());
+
+        lr = smEnterExitTranstionToTest.getLogRec(6);
+        assertEquals(EXIT, lr.getInfo());
+        assertEquals(smEnterExitTranstionToTest.mS3, lr.getState());
+
+        lr = smEnterExitTranstionToTest.getLogRec(7);
+        assertEquals(ENTER, lr.getInfo());
+        assertEquals(smEnterExitTranstionToTest.mS4, lr.getState());
+
+        lr = smEnterExitTranstionToTest.getLogRec(8);
+        assertEquals(EXIT, lr.getInfo());
+        assertEquals(smEnterExitTranstionToTest.mS4, lr.getState());
 
         if (smEnterExitTranstionToTest.isDbg()) {
             Log.d(TAG, "testStateMachineEnterExitTransitionToTest X");
@@ -325,7 +459,7 @@
             super(name);
             mThisSm = this;
             setDbg(DBG);
-            setProcessedMessagesSize(3);
+            setLogRecSize(3);
 
             // Setup state machine with 1 state
             addState(mS1);
@@ -345,7 +479,7 @@
         }
 
         @Override
-        protected void halting() {
+        protected void onHalting() {
             synchronized (mThisSm) {
                 mThisSm.notifyAll();
             }
@@ -377,24 +511,24 @@
             }
         }
 
-        assertTrue(sm0.getProcessedMessagesCount() == 6);
-        assertTrue(sm0.getProcessedMessagesSize() == 3);
+        assertEquals(6, sm0.getLogRecCount());
+        assertEquals(3, sm0.getLogRecSize());
 
-        ProcessedMessageInfo pmi;
-        pmi = sm0.getProcessedMessageInfo(0);
-        assertEquals(TEST_CMD_4, pmi.getWhat());
-        assertEquals(sm0.mS1, pmi.getState());
-        assertEquals(sm0.mS1, pmi.getOriginalState());
+        LogRec lr;
+        lr = sm0.getLogRec(0);
+        assertEquals(TEST_CMD_4, lr.getWhat());
+        assertEquals(sm0.mS1, lr.getState());
+        assertEquals(sm0.mS1, lr.getOriginalState());
 
-        pmi = sm0.getProcessedMessageInfo(1);
-        assertEquals(TEST_CMD_5, pmi.getWhat());
-        assertEquals(sm0.mS1, pmi.getState());
-        assertEquals(sm0.mS1, pmi.getOriginalState());
+        lr = sm0.getLogRec(1);
+        assertEquals(TEST_CMD_5, lr.getWhat());
+        assertEquals(sm0.mS1, lr.getState());
+        assertEquals(sm0.mS1, lr.getOriginalState());
 
-        pmi = sm0.getProcessedMessageInfo(2);
-        assertEquals(TEST_CMD_6, pmi.getWhat());
-        assertEquals(sm0.mS1, pmi.getState());
-        assertEquals(sm0.mS1, pmi.getOriginalState());
+        lr = sm0.getLogRec(2);
+        assertEquals(TEST_CMD_6, lr.getWhat());
+        assertEquals(sm0.mS1, lr.getState());
+        assertEquals(sm0.mS1, lr.getOriginalState());
 
         if (sm0.isDbg()) Log.d(TAG, "testStateMachine0 X");
     }
@@ -444,7 +578,7 @@
         }
 
         @Override
-        protected void halting() {
+        protected void onHalting() {
             synchronized (mThisSm) {
                 mThisSm.notifyAll();
             }
@@ -479,18 +613,18 @@
         assertEquals(2, sm1.mEnterCount);
         assertEquals(2, sm1.mExitCount);
 
-        assertTrue(sm1.getProcessedMessagesSize() == 2);
+        assertEquals(2, sm1.getLogRecSize());
 
-        ProcessedMessageInfo pmi;
-        pmi = sm1.getProcessedMessageInfo(0);
-        assertEquals(TEST_CMD_1, pmi.getWhat());
-        assertEquals(sm1.mS1, pmi.getState());
-        assertEquals(sm1.mS1, pmi.getOriginalState());
+        LogRec lr;
+        lr = sm1.getLogRec(0);
+        assertEquals(TEST_CMD_1, lr.getWhat());
+        assertEquals(sm1.mS1, lr.getState());
+        assertEquals(sm1.mS1, lr.getOriginalState());
 
-        pmi = sm1.getProcessedMessageInfo(1);
-        assertEquals(TEST_CMD_2, pmi.getWhat());
-        assertEquals(sm1.mS1, pmi.getState());
-        assertEquals(sm1.mS1, pmi.getOriginalState());
+        lr = sm1.getLogRec(1);
+        assertEquals(TEST_CMD_2, lr.getWhat());
+        assertEquals(sm1.mS1, lr.getState());
+        assertEquals(sm1.mS1, lr.getOriginalState());
 
         assertEquals(2, sm1.mEnterCount);
         assertEquals(2, sm1.mExitCount);
@@ -550,7 +684,7 @@
         }
 
         @Override
-        protected void halting() {
+        protected void onHalting() {
             synchronized (mThisSm) {
                 mThisSm.notifyAll();
             }
@@ -583,24 +717,24 @@
             }
         }
 
-        assertTrue(sm2.getProcessedMessagesSize() == 4);
+        assertEquals(4, sm2.getLogRecSize());
 
-        ProcessedMessageInfo pmi;
-        pmi = sm2.getProcessedMessageInfo(0);
-        assertEquals(TEST_CMD_1, pmi.getWhat());
-        assertEquals(sm2.mS1, pmi.getState());
+        LogRec lr;
+        lr = sm2.getLogRec(0);
+        assertEquals(TEST_CMD_1, lr.getWhat());
+        assertEquals(sm2.mS1, lr.getState());
 
-        pmi = sm2.getProcessedMessageInfo(1);
-        assertEquals(TEST_CMD_2, pmi.getWhat());
-        assertEquals(sm2.mS1, pmi.getState());
+        lr = sm2.getLogRec(1);
+        assertEquals(TEST_CMD_2, lr.getWhat());
+        assertEquals(sm2.mS1, lr.getState());
 
-        pmi = sm2.getProcessedMessageInfo(2);
-        assertEquals(TEST_CMD_1, pmi.getWhat());
-        assertEquals(sm2.mS2, pmi.getState());
+        lr = sm2.getLogRec(2);
+        assertEquals(TEST_CMD_1, lr.getWhat());
+        assertEquals(sm2.mS2, lr.getState());
 
-        pmi = sm2.getProcessedMessageInfo(3);
-        assertEquals(TEST_CMD_2, pmi.getWhat());
-        assertEquals(sm2.mS2, pmi.getState());
+        lr = sm2.getLogRec(3);
+        assertEquals(TEST_CMD_2, lr.getWhat());
+        assertEquals(sm2.mS2, lr.getState());
 
         assertTrue(sm2.mDidEnter);
         assertTrue(sm2.mDidExit);
@@ -647,7 +781,7 @@
         }
 
         @Override
-        protected void halting() {
+        protected void onHalting() {
             synchronized (mThisSm) {
                 mThisSm.notifyAll();
             }
@@ -677,18 +811,18 @@
             }
         }
 
-        assertTrue(sm3.getProcessedMessagesSize() == 2);
+        assertEquals(2, sm3.getLogRecSize());
 
-        ProcessedMessageInfo pmi;
-        pmi = sm3.getProcessedMessageInfo(0);
-        assertEquals(TEST_CMD_1, pmi.getWhat());
-        assertEquals(sm3.mParentState, pmi.getState());
-        assertEquals(sm3.mChildState, pmi.getOriginalState());
+        LogRec lr;
+        lr = sm3.getLogRec(0);
+        assertEquals(TEST_CMD_1, lr.getWhat());
+        assertEquals(sm3.mParentState, lr.getState());
+        assertEquals(sm3.mChildState, lr.getOriginalState());
 
-        pmi = sm3.getProcessedMessageInfo(1);
-        assertEquals(TEST_CMD_2, pmi.getWhat());
-        assertEquals(sm3.mParentState, pmi.getState());
-        assertEquals(sm3.mChildState, pmi.getOriginalState());
+        lr = sm3.getLogRec(1);
+        assertEquals(TEST_CMD_2, lr.getWhat());
+        assertEquals(sm3.mParentState, lr.getState());
+        assertEquals(sm3.mChildState, lr.getOriginalState());
 
         if (sm3.isDbg()) Log.d(TAG, "testStateMachine3 X");
     }
@@ -742,7 +876,7 @@
         }
 
         @Override
-        protected void halting() {
+        protected void onHalting() {
             synchronized (mThisSm) {
                 mThisSm.notifyAll();
             }
@@ -774,18 +908,18 @@
         }
 
 
-        assertTrue(sm4.getProcessedMessagesSize() == 2);
+        assertEquals(2, sm4.getLogRecSize());
 
-        ProcessedMessageInfo pmi;
-        pmi = sm4.getProcessedMessageInfo(0);
-        assertEquals(TEST_CMD_1, pmi.getWhat());
-        assertEquals(sm4.mChildState1, pmi.getState());
-        assertEquals(sm4.mChildState1, pmi.getOriginalState());
+        LogRec lr;
+        lr = sm4.getLogRec(0);
+        assertEquals(TEST_CMD_1, lr.getWhat());
+        assertEquals(sm4.mChildState1, lr.getState());
+        assertEquals(sm4.mChildState1, lr.getOriginalState());
 
-        pmi = sm4.getProcessedMessageInfo(1);
-        assertEquals(TEST_CMD_2, pmi.getWhat());
-        assertEquals(sm4.mParentState, pmi.getState());
-        assertEquals(sm4.mChildState2, pmi.getOriginalState());
+        lr = sm4.getLogRec(1);
+        assertEquals(TEST_CMD_2, lr.getWhat());
+        assertEquals(sm4.mParentState, lr.getState());
+        assertEquals(sm4.mChildState2, lr.getOriginalState());
 
         if (sm4.isDbg()) Log.d(TAG, "testStateMachine4 X");
     }
@@ -1018,7 +1152,7 @@
         }
 
         @Override
-        protected void halting() {
+        protected void onHalting() {
             synchronized (mThisSm) {
                 mThisSm.notifyAll();
             }
@@ -1073,7 +1207,7 @@
         }
 
 
-        assertTrue(sm5.getProcessedMessagesSize() == 6);
+        assertEquals(6, sm5.getLogRecSize());
 
         assertEquals(1, sm5.mParentState1EnterCount);
         assertEquals(1, sm5.mParentState1ExitCount);
@@ -1090,36 +1224,36 @@
         assertEquals(1, sm5.mChildState5EnterCount);
         assertEquals(1, sm5.mChildState5ExitCount);
 
-        ProcessedMessageInfo pmi;
-        pmi = sm5.getProcessedMessageInfo(0);
-        assertEquals(TEST_CMD_1, pmi.getWhat());
-        assertEquals(sm5.mChildState1, pmi.getState());
-        assertEquals(sm5.mChildState1, pmi.getOriginalState());
+        LogRec lr;
+        lr = sm5.getLogRec(0);
+        assertEquals(TEST_CMD_1, lr.getWhat());
+        assertEquals(sm5.mChildState1, lr.getState());
+        assertEquals(sm5.mChildState1, lr.getOriginalState());
 
-        pmi = sm5.getProcessedMessageInfo(1);
-        assertEquals(TEST_CMD_2, pmi.getWhat());
-        assertEquals(sm5.mChildState2, pmi.getState());
-        assertEquals(sm5.mChildState2, pmi.getOriginalState());
+        lr = sm5.getLogRec(1);
+        assertEquals(TEST_CMD_2, lr.getWhat());
+        assertEquals(sm5.mChildState2, lr.getState());
+        assertEquals(sm5.mChildState2, lr.getOriginalState());
 
-        pmi = sm5.getProcessedMessageInfo(2);
-        assertEquals(TEST_CMD_3, pmi.getWhat());
-        assertEquals(sm5.mChildState5, pmi.getState());
-        assertEquals(sm5.mChildState5, pmi.getOriginalState());
+        lr = sm5.getLogRec(2);
+        assertEquals(TEST_CMD_3, lr.getWhat());
+        assertEquals(sm5.mChildState5, lr.getState());
+        assertEquals(sm5.mChildState5, lr.getOriginalState());
 
-        pmi = sm5.getProcessedMessageInfo(3);
-        assertEquals(TEST_CMD_4, pmi.getWhat());
-        assertEquals(sm5.mChildState3, pmi.getState());
-        assertEquals(sm5.mChildState3, pmi.getOriginalState());
+        lr = sm5.getLogRec(3);
+        assertEquals(TEST_CMD_4, lr.getWhat());
+        assertEquals(sm5.mChildState3, lr.getState());
+        assertEquals(sm5.mChildState3, lr.getOriginalState());
 
-        pmi = sm5.getProcessedMessageInfo(4);
-        assertEquals(TEST_CMD_5, pmi.getWhat());
-        assertEquals(sm5.mChildState4, pmi.getState());
-        assertEquals(sm5.mChildState4, pmi.getOriginalState());
+        lr = sm5.getLogRec(4);
+        assertEquals(TEST_CMD_5, lr.getWhat());
+        assertEquals(sm5.mChildState4, lr.getState());
+        assertEquals(sm5.mChildState4, lr.getOriginalState());
 
-        pmi = sm5.getProcessedMessageInfo(5);
-        assertEquals(TEST_CMD_6, pmi.getWhat());
-        assertEquals(sm5.mParentState2, pmi.getState());
-        assertEquals(sm5.mParentState2, pmi.getOriginalState());
+        lr = sm5.getLogRec(5);
+        assertEquals(TEST_CMD_6, lr.getWhat());
+        assertEquals(sm5.mParentState2, lr.getState());
+        assertEquals(sm5.mParentState2, lr.getOriginalState());
 
         if (sm5.isDbg()) Log.d(TAG, "testStateMachine5 X");
     }
@@ -1161,7 +1295,7 @@
         }
 
         @Override
-        protected void halting() {
+        protected void onHalting() {
             synchronized (mThisSm) {
                 mThisSm.notifyAll();
             }
@@ -1176,7 +1310,6 @@
 
     @MediumTest
     public void testStateMachine6() throws Exception {
-        long sentTimeMsg2;
         final int DELAY_TIME = 250;
         final int DELAY_FUDGE = 20;
 
@@ -1186,7 +1319,6 @@
 
         synchronized (sm6) {
             // Send a message
-            sentTimeMsg2 = SystemClock.elapsedRealtime();
             sm6.sendMessageDelayed(TEST_CMD_2, DELAY_TIME);
 
             try {
@@ -1268,7 +1400,7 @@
         }
 
         @Override
-        protected void halting() {
+        protected void onHalting() {
             synchronized (mThisSm) {
                 mThisSm.notifyAll();
             }
@@ -1285,7 +1417,6 @@
 
     @MediumTest
     public void testStateMachine7() throws Exception {
-        long sentTimeMsg2;
         final int SM7_DELAY_FUDGE = 20;
 
         StateMachine7 sm7 = new StateMachine7("sm7");
@@ -1294,7 +1425,6 @@
 
         synchronized (sm7) {
             // Send a message
-            sentTimeMsg2 = SystemClock.elapsedRealtime();
             sm7.sendMessage(TEST_CMD_1);
 
             try {
@@ -1350,7 +1480,7 @@
         }
 
         @Override
-        protected void halting() {
+        protected void onHalting() {
             synchronized (mThisSm) {
                 mThisSm.notifyAll();
             }
@@ -1383,7 +1513,7 @@
             }
         }
 
-        assertTrue(sm.getProcessedMessagesCount() == 2);
+        assertEquals(sm.getLogRecCount(), 2);
         assertEquals(2, sm.mUnhandledMessageCount);
 
         if (sm.isDbg()) Log.d(TAG, "testStateMachineUnhandledMessage X");
@@ -1420,7 +1550,7 @@
         }
 
         @Override
-        protected void halting() {
+        protected void onHalting() {
             // Update the shared counter, which is OK since all state
             // machines are using the same thread.
             sharedCounter += 1;
@@ -1470,12 +1600,12 @@
         }
 
         for (StateMachineSharedThread sm : sms) {
-            assertTrue(sm.getProcessedMessagesCount() == 4);
-            for (int i = 0; i < sm.getProcessedMessagesCount(); i++) {
-                ProcessedMessageInfo pmi = sm.getProcessedMessageInfo(i);
-                assertEquals(i+1, pmi.getWhat());
-                assertEquals(sm.mS1, pmi.getState());
-                assertEquals(sm.mS1, pmi.getOriginalState());
+            assertEquals(sm.getLogRecCount(), 4);
+            for (int i = 0; i < sm.getLogRecCount(); i++) {
+                LogRec lr = sm.getLogRec(i);
+                assertEquals(i+1, lr.getWhat());
+                assertEquals(sm.mS1, lr.getState());
+                assertEquals(sm.mS1, lr.getOriginalState());
             }
         }
 
@@ -1501,41 +1631,41 @@
             }
         }
 
-        assertEquals(7, sm.getProcessedMessagesCount());
-        ProcessedMessageInfo pmi = sm.getProcessedMessageInfo(0);
-        assertEquals(Hsm1.CMD_1, pmi.getWhat());
-        assertEquals(sm.mS1, pmi.getState());
-        assertEquals(sm.mS1, pmi.getOriginalState());
+        assertEquals(7, sm.getLogRecCount());
+        LogRec lr = sm.getLogRec(0);
+        assertEquals(Hsm1.CMD_1, lr.getWhat());
+        assertEquals(sm.mS1, lr.getState());
+        assertEquals(sm.mS1, lr.getOriginalState());
 
-        pmi = sm.getProcessedMessageInfo(1);
-        assertEquals(Hsm1.CMD_2, pmi.getWhat());
-        assertEquals(sm.mP1, pmi.getState());
-        assertEquals(sm.mS1, pmi.getOriginalState());
+        lr = sm.getLogRec(1);
+        assertEquals(Hsm1.CMD_2, lr.getWhat());
+        assertEquals(sm.mP1, lr.getState());
+        assertEquals(sm.mS1, lr.getOriginalState());
 
-        pmi = sm.getProcessedMessageInfo(2);
-        assertEquals(Hsm1.CMD_2, pmi.getWhat());
-        assertEquals(sm.mS2, pmi.getState());
-        assertEquals(sm.mS2, pmi.getOriginalState());
+        lr = sm.getLogRec(2);
+        assertEquals(Hsm1.CMD_2, lr.getWhat());
+        assertEquals(sm.mS2, lr.getState());
+        assertEquals(sm.mS2, lr.getOriginalState());
 
-        pmi = sm.getProcessedMessageInfo(3);
-        assertEquals(Hsm1.CMD_3, pmi.getWhat());
-        assertEquals(sm.mS2, pmi.getState());
-        assertEquals(sm.mS2, pmi.getOriginalState());
+        lr = sm.getLogRec(3);
+        assertEquals(Hsm1.CMD_3, lr.getWhat());
+        assertEquals(sm.mS2, lr.getState());
+        assertEquals(sm.mS2, lr.getOriginalState());
 
-        pmi = sm.getProcessedMessageInfo(4);
-        assertEquals(Hsm1.CMD_3, pmi.getWhat());
-        assertEquals(sm.mP2, pmi.getState());
-        assertEquals(sm.mP2, pmi.getOriginalState());
+        lr = sm.getLogRec(4);
+        assertEquals(Hsm1.CMD_3, lr.getWhat());
+        assertEquals(sm.mP2, lr.getState());
+        assertEquals(sm.mP2, lr.getOriginalState());
 
-        pmi = sm.getProcessedMessageInfo(5);
-        assertEquals(Hsm1.CMD_4, pmi.getWhat());
-        assertEquals(sm.mP2, pmi.getState());
-        assertEquals(sm.mP2, pmi.getOriginalState());
+        lr = sm.getLogRec(5);
+        assertEquals(Hsm1.CMD_4, lr.getWhat());
+        assertEquals(sm.mP2, lr.getState());
+        assertEquals(sm.mP2, lr.getOriginalState());
 
-        pmi = sm.getProcessedMessageInfo(6);
-        assertEquals(Hsm1.CMD_5, pmi.getWhat());
-        assertEquals(sm.mP2, pmi.getState());
-        assertEquals(sm.mP2, pmi.getOriginalState());
+        lr = sm.getLogRec(6);
+        assertEquals(Hsm1.CMD_5, lr.getWhat());
+        assertEquals(sm.mP2, lr.getState());
+        assertEquals(sm.mP2, lr.getOriginalState());
 
         if (DBG) Log.d(TAG, "testStateMachineSharedThread X");
     }
@@ -1684,7 +1814,7 @@
     }
 
     @Override
-    protected void halting() {
+    protected void onHalting() {
         Log.d(TAG, "halting");
         synchronized (this) {
             this.notifyAll();
diff --git a/core/tests/overlaytests/OverlayTestOverlay/Android.mk b/core/tests/overlaytests/OverlayTestOverlay/Android.mk
index cf32c9f..b1327f71 100644
--- a/core/tests/overlaytests/OverlayTestOverlay/Android.mk
+++ b/core/tests/overlaytests/OverlayTestOverlay/Android.mk
@@ -9,6 +9,4 @@
 
 LOCAL_PACKAGE_NAME := com.android.overlaytest.overlay
 
-LOCAL_AAPT_FLAGS := -o
-
 include $(BUILD_PACKAGE)
diff --git a/core/tests/overlaytests/OverlayTestOverlay/res/drawable/default_wallpaper.jpg b/core/tests/overlaytests/OverlayTestOverlay/res/drawable-nodpi/default_wallpaper.jpg
similarity index 100%
rename from core/tests/overlaytests/OverlayTestOverlay/res/drawable/default_wallpaper.jpg
rename to core/tests/overlaytests/OverlayTestOverlay/res/drawable-nodpi/default_wallpaper.jpg
Binary files differ
diff --git a/core/tests/overlaytests/runtests.sh b/core/tests/overlaytests/runtests.sh
index 0ad9efb..0a721ad40 100755
--- a/core/tests/overlaytests/runtests.sh
+++ b/core/tests/overlaytests/runtests.sh
@@ -18,7 +18,6 @@
 
 log=$(mktemp)
 trap "atexit" EXIT
-failures=0
 
 function compile_module()
 {
@@ -38,6 +37,37 @@
 	$adb wait-for-device logcat | grep -m 1 -e 'PowerManagerService.*bootCompleted' >/dev/null
 }
 
+function mkdir_if_needed()
+{
+	local path="$1"
+
+	if [[ "${path:0:1}" != "/" ]]; then
+		echo "mkdir_if_needed: error: path '$path' does not begin with /" | tee -a $log
+		exit 1
+	fi
+
+	local basename=$(basename "$path")
+	local dirname=$(dirname "$path")
+	local t=$($adb shell ls -l $dirname | tr -d '\r' | grep -e "${basename}$" | grep -oe '^.')
+
+	case "$t" in
+		d) # File exists, and is a directory ...
+			# do nothing
+			;;
+		l) # ... (or symbolic link possibly to a directory).
+			# do nothing
+			;;
+		"") # File does not exist.
+			mkdir_if_needed "$dirname"
+			$adb shell mkdir "$path"
+			;;
+		*) # File exists, but is not a directory.
+			echo "mkdir_if_needed: file '$path' exists, but is not a directory" | tee -a $log
+			exit 1
+			;;
+	esac
+}
+
 function disable_overlay()
 {
 	echo "Disabling overlay"
@@ -48,6 +78,8 @@
 function enable_overlay()
 {
 	echo "Enabling overlay"
+	mkdir_if_needed "/system/vendor"
+	mkdir_if_needed "/vendor/overlay/framework"
 	$adb shell ln -s /data/app/com.android.overlaytest.overlay.apk /vendor/overlay/framework/framework-res.apk
 }
 
@@ -59,13 +91,21 @@
 	$adb shell am instrument -w -e class $class com.android.overlaytest/android.test.InstrumentationTestRunner | tee -a $log
 }
 
+function remount()
+{
+	echo "Remounting file system writable"
+	$adb remount | tee -a $log
+}
+
 function sync()
 {
 	echo "Syncing to device"
-	$adb remount | tee -a $log
 	$adb sync data | tee -a $log
 }
 
+# some commands require write access, remount once and for all
+remount
+
 # build and sync
 compile_module "$PWD/OverlayTest/Android.mk"
 compile_module "$PWD/OverlayTestOverlay/Android.mk"
diff --git a/data/etc/Android.mk b/data/etc/Android.mk
index 71a9a15..134ac0c 100644
--- a/data/etc/Android.mk
+++ b/data/etc/Android.mk
@@ -21,8 +21,6 @@
 
 LOCAL_MODULE := platform.xml
 
-LOCAL_MODULE_TAGS := user
-
 LOCAL_MODULE_CLASS := ETC
 
 # This will install the file in /system/etc/permissions
@@ -38,8 +36,6 @@
 
 #LOCAL_MODULE := required_hardware.xml
 
-#LOCAL_MODULE_TAGS := user
-
 #LOCAL_MODULE_CLASS := ETC
 
 # This will install the file in /system/etc/permissions
diff --git a/drm/jni/Android.mk b/drm/jni/Android.mk
index f8ecc8c..fff7eee 100644
--- a/drm/jni/Android.mk
+++ b/drm/jni/Android.mk
@@ -35,7 +35,8 @@
     $(JNI_H_INCLUDE) \
     $(TOP)/frameworks/av/drm/libdrmframework/include \
     $(TOP)/frameworks/av/drm/libdrmframework/plugins/common/include \
-    $(TOP)/frameworks/av/include
+    $(TOP)/frameworks/av/include \
+    $(TOP)/libcore/include
 
 
 
diff --git a/drm/jni/android_drm_DrmManagerClient.cpp b/drm/jni/android_drm_DrmManagerClient.cpp
index 14ec4d6..fb685a2 100644
--- a/drm/jni/android_drm_DrmManagerClient.cpp
+++ b/drm/jni/android_drm_DrmManagerClient.cpp
@@ -20,6 +20,7 @@
 
 #include <jni.h>
 #include <JNIHelp.h>
+#include <ScopedLocalRef.h>
 #include <android_runtime/AndroidRuntime.h>
 
 #include <drm/DrmInfo.h>
@@ -250,16 +251,18 @@
         = getDrmManagerClientImpl(env, thiz)->getConstraints(uniqueId, &pathString, usage);
 
     jclass localRef = env->FindClass("android/content/ContentValues");
+    jmethodID ContentValues_putByteArray =
+            env->GetMethodID(localRef, "put", "(Ljava/lang/String;[B)V");
+    jmethodID ContentValues_putString =
+            env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V");
+    jmethodID ContentValues_constructor = env->GetMethodID(localRef, "<init>", "()V");
     jobject constraints = NULL;
 
     if (NULL != localRef && NULL != pConstraints) {
-        // Get the constructor id
-        jmethodID constructorId = env->GetMethodID(localRef, "<init>", "()V");
         // create the java DrmConstraints object
-        constraints = env->NewObject(localRef, constructorId);
+        constraints = env->NewObject(localRef, ContentValues_constructor);
 
         DrmConstraints::KeyIterator keyIt = pConstraints->keyIterator();
-
         while (keyIt.hasNext()) {
             String8 key = keyIt.next();
 
@@ -267,18 +270,18 @@
             if (DrmConstraints::EXTENDED_METADATA == key) {
                 const char* value = pConstraints->getAsByteArray(&key);
                 if (NULL != value) {
-                    jbyteArray dataArray = env->NewByteArray(strlen(value));
-                    env->SetByteArrayRegion(dataArray, 0, strlen(value), (jbyte*)value);
-                    env->CallVoidMethod(
-                        constraints, env->GetMethodID(localRef, "put", "(Ljava/lang/String;[B)V"),
-                                     env->NewStringUTF(key.string()), dataArray);
+                    ScopedLocalRef<jbyteArray> dataArray(env, env->NewByteArray(strlen(value)));
+                    ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
+                    env->SetByteArrayRegion(dataArray.get(), 0, strlen(value), (jbyte*)value);
+                    env->CallVoidMethod(constraints, ContentValues_putByteArray,
+                                        keyString.get(), dataArray.get());
                 }
             } else {
                 String8 value = pConstraints->get(key);
-                env->CallVoidMethod(
-                    constraints,
-                    env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V"),
-                env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
+                ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
+                ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string()));
+                env->CallVoidMethod(constraints, ContentValues_putString,
+                                    keyString.get(), valueString.get());
             }
         }
     }
@@ -297,8 +300,10 @@
 
     jobject metadata = NULL;
 
-    jclass localRef = NULL;
-    localRef = env->FindClass("android/content/ContentValues");
+    jclass localRef = env->FindClass("android/content/ContentValues");
+    jmethodID ContentValues_putString =
+            env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V");
+
     if (NULL != localRef && NULL != pMetadata) {
         // Get the constructor id
         jmethodID constructorId = NULL;
@@ -313,9 +318,10 @@
                     // insert the entry<constraintKey, constraintValue>
                     // to newly created java object
                     String8 value = pMetadata->get(key);
-                    env->CallVoidMethod(metadata, env->GetMethodID(localRef, "put",
-                            "(Ljava/lang/String;Ljava/lang/String;)V"),
-                    env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
+                    ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
+                    ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string()));
+                    env->CallVoidMethod(metadata, ContentValues_putString,
+                                        keyString.get(), valueString.get());
                 }
             }
         }
@@ -426,29 +432,30 @@
     DrmInfo drmInfo(mInfoType, buffer, mMimeType);
 
     jclass clazz = env->FindClass("android/drm/DrmInfo");
+    jmethodID DrmInfo_get = env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;");
     jobject keyIterator
         = env->CallObjectMethod(drmInfoObject,
                 env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
 
-    jmethodID hasNextId = env->GetMethodID(env->FindClass("java/util/Iterator"), "hasNext", "()Z");
+    jclass Iterator_class = env->FindClass("java/util/Iterator");
+    jmethodID Iterator_hasNext = env->GetMethodID(Iterator_class, "hasNext", "()Z");
+    jmethodID Iterator_next = env->GetMethodID(Iterator_class, "next", "()Ljava/lang/Object;");
 
-    while (env->CallBooleanMethod(keyIterator, hasNextId)) {
-        jstring key = (jstring) env->CallObjectMethod(keyIterator,
-                env->GetMethodID(env->FindClass("java/util/Iterator"),
-                "next", "()Ljava/lang/Object;"));
+    jclass Object_class = env->FindClass("java/lang/Object");
+    jmethodID Object_toString = env->GetMethodID(Object_class, "toString", "()Ljava/lang/String;");
 
-        jobject valueObject = env->CallObjectMethod(drmInfoObject,
-                env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"), key);
-
-        jstring valString = NULL;
-        if (NULL != valueObject) {
-            valString = (jstring) env->CallObjectMethod(valueObject,
-                env->GetMethodID(env->FindClass("java/lang/Object"),
-                "toString", "()Ljava/lang/String;"));
+    while (env->CallBooleanMethod(keyIterator, Iterator_hasNext)) {
+        ScopedLocalRef<jstring> key(env,
+                (jstring) env->CallObjectMethod(keyIterator, Iterator_next));
+        ScopedLocalRef<jobject> valueObject(env,
+                env->CallObjectMethod(drmInfoObject, DrmInfo_get, key.get()));
+        ScopedLocalRef<jstring> valString(env, NULL);
+        if (NULL != valueObject.get()) {
+            valString.reset((jstring) env->CallObjectMethod(valueObject.get(), Object_toString));
         }
 
-        String8 keyString = Utility::getStringValue(env, key);
-        String8 valueString = Utility::getStringValue(env, valString);
+        String8 keyString = Utility::getStringValue(env, key.get());
+        String8 valueString = Utility::getStringValue(env, valString.get());
         ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
 
         drmInfo.put(keyString, valueString);
@@ -508,20 +515,21 @@
     jobject keyIterator
         = env->CallObjectMethod(drmInfoRequest,
                 env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
+    jmethodID DrmInfoRequest_get = env->GetMethodID(clazz,
+            "get", "(Ljava/lang/String;)Ljava/lang/Object;");
 
-    jmethodID hasNextId = env->GetMethodID(env->FindClass("java/util/Iterator"), "hasNext", "()Z");
+    jclass Iterator_class = env->FindClass("java/util/Iterator");
+    jmethodID Iterator_hasNext = env->GetMethodID(Iterator_class, "hasNext", "()Z");
+    jmethodID Iterator_next = env->GetMethodID(Iterator_class, "next", "()Ljava/lang/Object;");
 
-    while (env->CallBooleanMethod(keyIterator, hasNextId)) {
-        jstring key
-            = (jstring) env->CallObjectMethod(keyIterator,
-                env->GetMethodID(env->FindClass("java/util/Iterator"),
-                                "next", "()Ljava/lang/Object;"));
+    while (env->CallBooleanMethod(keyIterator, Iterator_hasNext)) {
+        ScopedLocalRef<jstring> key(env,
+                (jstring) env->CallObjectMethod(keyIterator, Iterator_next));
+        ScopedLocalRef<jstring> value(env,
+                (jstring) env->CallObjectMethod(drmInfoRequest, DrmInfoRequest_get, key.get()));
 
-        jstring value = (jstring) env->CallObjectMethod(drmInfoRequest,
-                env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"), key);
-
-        String8 keyString = Utility::getStringValue(env, key);
-        String8 valueString = Utility::getStringValue(env, value);
+        String8 keyString = Utility::getStringValue(env, key.get());
+        String8 valueString = Utility::getStringValue(env, value.get());
         ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
 
         drmInfoReq.put(keyString, valueString);
@@ -552,9 +560,10 @@
             while (it.hasNext()) {
                 String8 key = it.next();
                 String8 value = pDrmInfo->get(key);
-
+                ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
+                ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string()));
                 env->CallVoidMethod(drmInfoObject, putMethodId,
-                    env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
+                    keyString.get(), valueString.get());
             }
         }
         delete [] pDrmInfo->getData().data;
diff --git a/keystore/tests/AndroidManifest.xml b/keystore/tests/AndroidManifest.xml
index 1a5f065..415442f 100644
--- a/keystore/tests/AndroidManifest.xml
+++ b/keystore/tests/AndroidManifest.xml
@@ -22,7 +22,7 @@
         <uses-library android:name="android.test.runner" />
     </application>
 
-    <instrumentation android:name=".KeyStoreTestRunner"
+    <instrumentation android:name="android.test.InstrumentationTestRunner"
         android:targetPackage="android.security.tests"
         android:label="KeyStore Tests">
     </instrumentation>
diff --git a/keystore/tests/src/android/security/KeyStoreTest.java b/keystore/tests/src/android/security/KeyStoreTest.java
index 32cd6e2..9f35b8d 100755
--- a/keystore/tests/src/android/security/KeyStoreTest.java
+++ b/keystore/tests/src/android/security/KeyStoreTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.security.tests;
+package android.security;
 
 import android.app.Activity;
 import android.security.KeyStore;
@@ -29,7 +29,11 @@
  *
  * Running the test suite:
  *
- *  adb shell am instrument -w android.security.tests/.KeyStoreTestRunner
+ *  runtest keystore-unit
+ *
+ * Or this individual test case:
+ *
+ *  runtest --path frameworks/base/keystore/tests/src/android/security/KeyStoreTest.java
  */
 @MediumTest
 public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
diff --git a/keystore/tests/src/android/security/KeyStoreTestRunner.java b/keystore/tests/src/android/security/KeyStoreTestRunner.java
deleted file mode 100644
index c56eeb9..0000000
--- a/keystore/tests/src/android/security/KeyStoreTestRunner.java
+++ /dev/null
@@ -1,48 +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.
- */
-
-package android.security.tests;
-
-import junit.framework.TestSuite;
-
-import android.test.InstrumentationTestRunner;
-import android.test.InstrumentationTestSuite;
-
-/**
- * Instrumentation Test Runner for all KeyStore unit tests.
- *
- * Running all tests:
- *
- *   runtest keystore-unit
- * or
- *   adb shell am instrument -w android.security.tests/.KeyStoreTestRunner
- */
-
-public class KeyStoreTestRunner extends InstrumentationTestRunner {
-
-    @Override
-    public TestSuite getAllTests() {
-        TestSuite suite = new InstrumentationTestSuite(this);
-        suite.addTestSuite(android.security.tests.KeyStoreTest.class);
-        suite.addTestSuite(android.security.tests.SystemKeyStoreTest.class);
-        return suite;
-    }
-
-    @Override
-    public ClassLoader getLoader() {
-        return KeyStoreTestRunner.class.getClassLoader();
-    }
-}
diff --git a/keystore/tests/src/android/security/SystemKeyStoreTest.java b/keystore/tests/src/android/security/SystemKeyStoreTest.java
index a4d744b..ecf7cbc 100644
--- a/keystore/tests/src/android/security/SystemKeyStoreTest.java
+++ b/keystore/tests/src/android/security/SystemKeyStoreTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.security.tests;
+package android.security;
 
 import android.app.Activity;
 import android.security.SystemKeyStore;
@@ -26,7 +26,11 @@
  *
  * Running the test suite:
  *
- *  adb shell am instrument -w android.security.tests/.KeyStoreTestRunner
+ *  runtest keystore-unit
+ *
+ * Or this individual test case:
+ *
+ *  runtest --path frameworks/base/keystore/tests/src/android/security/SystemKeyStoreTest.java
  */
 @MediumTest
 public class SystemKeyStoreTest extends ActivityUnitTestCase<Activity> {
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index f3a1d9a..8cce191 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -5159,7 +5159,8 @@
     const uint32_t pkg_id = pkg->package->id << 24;
 
     for (size_t typeIndex = 0; typeIndex < typeCount; ++typeIndex) {
-        ssize_t offset = -1;
+        ssize_t first = -1;
+        ssize_t last = -1;
         const Type* typeConfigs = pkg->getType(typeIndex);
         ssize_t mapIndex = map.add();
         if (mapIndex < 0) {
@@ -5167,12 +5168,14 @@
         }
         Vector<uint32_t>& vector = map.editItemAt(mapIndex);
         for (size_t entryIndex = 0; entryIndex < typeConfigs->entryCount; ++entryIndex) {
-            uint32_t resID = (0xff000000 & ((pkg->package->id)<<24))
+            uint32_t resID = pkg_id
                 | (0x00ff0000 & ((typeIndex+1)<<16))
                 | (0x0000ffff & (entryIndex));
             resource_name resName;
             if (!this->getResourceName(resID, &resName)) {
                 ALOGW("idmap: resource 0x%08x has spec but lacks values, skipping\n", resID);
+                // add dummy value, or trimming leading/trailing zeroes later will fail
+                vector.push(0);
                 continue;
             }
 
@@ -5185,13 +5188,13 @@
                                                               overlayPackage.string(),
                                                               overlayPackage.size());
             if (overlayResID != 0) {
-                // overlay package has package ID == 0, use original package's ID instead
-                overlayResID |= pkg_id;
+                overlayResID = pkg_id | (0x00ffffff & overlayResID);
+                last = Res_GETENTRY(resID);
+                if (first == -1) {
+                    first = Res_GETENTRY(resID);
+                }
             }
             vector.push(overlayResID);
-            if (overlayResID != 0 && offset == -1) {
-                offset = Res_GETENTRY(resID);
-            }
 #if 0
             if (overlayResID != 0) {
                 ALOGD("%s/%s 0x%08x -> 0x%08x\n",
@@ -5202,13 +5205,16 @@
 #endif
         }
 
-        if (offset != -1) {
-            // shave off leading and trailing entries which lack overlay values
-            vector.removeItemsAt(0, offset);
-            vector.insertAt((uint32_t)offset, 0, 1);
-            while (vector.top() == 0) {
-                vector.pop();
+        if (first != -1) {
+            // shave off trailing entries which lack overlay values
+            const size_t last_past_one = last + 1;
+            if (last_past_one < vector.size()) {
+                vector.removeItemsAt(last_past_one, vector.size() - last_past_one);
             }
+            // shave off leading entries which lack overlay values
+            vector.removeItemsAt(0, first);
+            // store offset to first overlaid resource ID of this type
+            vector.insertAt((uint32_t)first, 0, 1);
             // reserve space for number and offset of entries, and the actual entries
             *outSize += (2 + vector.size()) * sizeof(uint32_t);
         } else {
@@ -5246,6 +5252,10 @@
         if (N == 0) {
             continue;
         }
+        if (N == 1) { // vector expected to hold (offset) + (N > 0 entries)
+            ALOGW("idmap: type %d supposedly has entries, but no entries found\n", i);
+            return UNKNOWN_ERROR;
+        }
         *data++ = htodl(N - 1); // do not count the offset (which is vector's first element)
         for (size_t j = 0; j < N; ++j) {
             const uint32_t& overlayResID = vector.itemAt(j);
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 0d6e62a..b51b1e1 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -617,7 +617,7 @@
         uint32_t* retOriginX, uint32_t* retOriginY) {
     cachedGlyph->mIsValid = false;
     // If the glyph is too tall, don't cache it
-    if (glyph.fHeight + TEXTURE_BORDER_SIZE > mCacheLines[mCacheLines.size() - 1]->mMaxHeight) {
+    if (mCacheLines.size() != 0  && (glyph.fHeight + TEXTURE_BORDER_SIZE > mCacheLines[mCacheLines.size() - 1]->mMaxHeight)) {
         ALOGE("Font size to large to fit in cache. width, height = %i, %i",
                 (int) glyph.fWidth, (int) glyph.fHeight);
         return;
@@ -946,6 +946,11 @@
 uint32_t FontRenderer::getRemainingCacheCapacity() {
     uint32_t remainingCapacity = 0;
     float totalPixels = 0;
+
+    //avoid divide by zero if the size is 0
+    if (mCacheLines.size() == 0) {
+        return 0;
+    }
     for(uint32_t i = 0; i < mCacheLines.size(); i ++) {
          remainingCapacity += (mCacheLines[i]->mMaxWidth - mCacheLines[i]->mCurrentCol);
          totalPixels += mCacheLines[i]->mMaxWidth;
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 560c549..99db066 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -33,7 +33,6 @@
  * codec.start();
  * ByteBuffer[] inputBuffers = codec.getInputBuffers();
  * ByteBuffer[] outputBuffers = codec.getOutputBuffers();
- * MediaFormat format = codec.getOutputFormat();
  * for (;;) {
  *   int inputBufferIndex = codec.dequeueInputBuffer(timeoutUs);
  *   if (inputBufferIndex &gt;= 0) {
@@ -51,7 +50,7 @@
  *     outputBuffers = codec.getOutputBuffers();
  *   } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
  *     // Subsequent data will conform to new format.
- *     format = codec.getOutputFormat();
+ *     MediaFormat format = codec.getOutputFormat();
  *     ...
  *   }
  * }
diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index c9bec18..d21ada4 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -172,6 +172,7 @@
 
     static {
         addFileType("MP3", FILE_TYPE_MP3, "audio/mpeg", MtpConstants.FORMAT_MP3);
+        addFileType("MPGA", FILE_TYPE_MP3, "audio/mpeg", MtpConstants.FORMAT_MP3);
         addFileType("M4A", FILE_TYPE_M4A, "audio/mp4", MtpConstants.FORMAT_MPEG);
         addFileType("WAV", FILE_TYPE_WAV, "audio/x-wav", MtpConstants.FORMAT_WAV);
         addFileType("AMR", FILE_TYPE_AMR, "audio/amr");
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 9af201d..613354f 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -351,12 +351,11 @@
      */
     public void setCaptureRate(double fps) {
         // Make sure that time lapse is enabled when this method is called.
-        setParameter(String.format("time-lapse-enable=1"));
+        setParameter("time-lapse-enable=1");
 
         double timeBetweenFrameCapture = 1 / fps;
         int timeBetweenFrameCaptureMs = (int) (1000 * timeBetweenFrameCapture);
-        setParameter(String.format("time-between-time-lapse-frame-capture=%d",
-                    timeBetweenFrameCaptureMs));
+        setParameter("time-between-time-lapse-frame-capture=" + timeBetweenFrameCaptureMs);
     }
 
     /**
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 6f8b809..fd37bcf 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -1399,7 +1399,8 @@
         long lastModifiedSeconds = file.lastModified() / 1000;
 
         if (!MediaFile.isAudioFileType(fileType) && !MediaFile.isVideoFileType(fileType) &&
-            !MediaFile.isImageFileType(fileType) && !MediaFile.isPlayListFileType(fileType)) {
+            !MediaFile.isImageFileType(fileType) && !MediaFile.isPlayListFileType(fileType) &&
+            !MediaFile.isDrmFileType(fileType)) {
 
             // no need to use the media scanner, but we need to update last modified and file size
             ContentValues values = new ContentValues();
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index 7532d79..a0325dd 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -492,6 +492,7 @@
             MtpConstants.FORMAT_MPEG,
             MtpConstants.FORMAT_EXIF_JPEG,
             MtpConstants.FORMAT_TIFF_EP,
+            MtpConstants.FORMAT_BMP,
             MtpConstants.FORMAT_GIF,
             MtpConstants.FORMAT_JFIF,
             MtpConstants.FORMAT_PNG,
diff --git a/media/java/android/mtp/MtpStorage.java b/media/java/android/mtp/MtpStorage.java
index 2f47aad..9cf65a3 100644
--- a/media/java/android/mtp/MtpStorage.java
+++ b/media/java/android/mtp/MtpStorage.java
@@ -39,7 +39,7 @@
         mStorageId = volume.getStorageId();
         mPath = volume.getPath();
         mDescription = context.getResources().getString(volume.getDescriptionId());
-        mReserveSpace = volume.getMtpReserveSpace();
+        mReserveSpace = volume.getMtpReserveSpace() * 1024 * 1024;
         mRemovable = volume.isRemovable();
         mMaxFileSize = volume.getMaxFileSize();
     }
@@ -87,7 +87,7 @@
      * Returns the amount of space to reserve on the storage file system.
      * This can be set to a non-zero value to prevent MTP from filling up the entire storage.
      *
-     * @return the storage unit description
+     * @return reserved space in bytes.
      */
     public final long getReserveSpace() {
         return mReserveSpace;
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index e43e66e..4941ae5 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -96,7 +96,10 @@
 }
 
 JMediaCodec::~JMediaCodec() {
-    mCodec->release();
+    if (mCodec != NULL) {
+        mCodec->release();
+        mCodec.clear();
+    }
 
     JNIEnv *env = AndroidRuntime::getJNIEnv();
 
diff --git a/media/jni/mediaeditor/VideoEditorClasses.cpp b/media/jni/mediaeditor/VideoEditorClasses.cpp
index 4e0e0f2..4982a47 100755
--- a/media/jni/mediaeditor/VideoEditorClasses.cpp
+++ b/media/jni/mediaeditor/VideoEditorClasses.cpp
@@ -1853,6 +1853,9 @@
                             // Get the clip settings.
                             videoEditClasses_getClipSettings(pResult, pEnv, clipSettings,
                                 &pSettings->pClipList[i]);
+
+                            // Free the local references to avoid memory leaks
+                            pEnv->DeleteLocalRef(clipSettings);
                         }
                     }
                 }
@@ -1877,6 +1880,9 @@
                             // Get the transition settings.
                             videoEditClasses_getTransitionSettings(pResult, pEnv,
                                     transitionSettings, &pSettings->pTransitionList[i]);
+
+                            // Free the local references to avoid memory leaks
+                            pEnv->DeleteLocalRef(transitionSettings);
                         }
                     }
                 }
@@ -1900,6 +1906,9 @@
                             // Get the effect settings.
                             videoEditClasses_getEffectSettings(pResult, pEnv, effectSettings,
                                     &pSettings->Effects[i]);
+
+                            // Free the local references to avoid memory leaks
+                            pEnv->DeleteLocalRef(effectSettings);
                         }
                     }
                 }
diff --git a/media/jni/mediaeditor/VideoEditorJava.cpp b/media/jni/mediaeditor/VideoEditorJava.cpp
index ec8050f..bcf9099 100755
--- a/media/jni/mediaeditor/VideoEditorJava.cpp
+++ b/media/jni/mediaeditor/VideoEditorJava.cpp
@@ -387,6 +387,9 @@
                 (*pLength) = length;
             }
         }
+
+        // Delete local references to avoid memory leaks
+        pEnv->DeleteLocalRef(string);
     }
 
     // Return the string.
diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp
index 41ec120..41c28c0 100755
--- a/media/jni/mediaeditor/VideoEditorMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorMain.cpp
@@ -380,6 +380,9 @@
                     pEnv->GetIntField(object,fid);
    M4OSA_TRACE1_1("videoRotation = %d",
                     pSettings->ClipProperties.videoRotationDegrees);
+
+   // Free the local references to avoid memory leaks
+   pEnv->DeleteLocalRef(clazz);
 }
 
 static void jniPreviewProgressCallback (void* cookie, M4OSA_UInt32 msgType,
@@ -1849,7 +1852,9 @@
                 "not initialized");
             if (needToBeLoaded) {
                 getClipSetting(pEnv,properties, pContext->pEditSettings->pClipList[i]);
+                pEnv->DeleteLocalRef(properties);
             } else {
+                pEnv->DeleteLocalRef(properties);
                 goto videoEditor_populateSettings_cleanup;
             }
         }
diff --git a/media/libdrm/mobile1/src/objmng/drm_api.c b/media/libdrm/mobile1/src/objmng/drm_api.c
index 249cdbe..232d9f4 100644
--- a/media/libdrm/mobile1/src/objmng/drm_api.c
+++ b/media/libdrm/mobile1/src/objmng/drm_api.c
@@ -1478,13 +1478,13 @@
 
     if (NULL != s->readBuf && s->readBufLen > 0) { /* read from backup buffer */
         if (leftLen <= s->readBufLen) {
-            memcpy(mediaBuf, s->readBuf + s->readBufOff, leftLen);
+            memcpy(mediaBuf + readBytes, s->readBuf + s->readBufOff, leftLen);
             s->readBufOff += leftLen;
             s->readBufLen -= leftLen;
             readBytes += leftLen;
             leftLen = 0;
         } else {
-            memcpy(mediaBuf, s->readBuf + s->readBufOff, s->readBufLen);
+            memcpy(mediaBuf + readBytes, s->readBuf + s->readBufOff, s->readBufLen);
             s->readBufOff += s->readBufLen;
             leftLen -= s->readBufLen;
             readBytes += s->readBufLen;
diff --git a/packages/SettingsProvider/Android.mk b/packages/SettingsProvider/Android.mk
index bf4ab1b..a2ea554 100644
--- a/packages/SettingsProvider/Android.mk
+++ b/packages/SettingsProvider/Android.mk
@@ -5,7 +5,7 @@
 
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
-LOCAL_JAVA_LIBRARIES := 
+LOCAL_JAVA_LIBRARIES := telephony-common
 
 LOCAL_PACKAGE_NAME := SettingsProvider
 LOCAL_CERTIFICATE := platform
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index cd0da5a..2c9a6fe 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -46,6 +46,8 @@
     <bool name="def_netstats_enabled">true</bool>
     <bool name="def_usb_mass_storage_enabled">true</bool>
     <bool name="def_wifi_on">false</bool>
+    <!-- 0 == default, 1 == never while plugged, 2 == never -->
+    <integer name="def_wifi_sleep_policy">0</integer>
     <bool name="def_networks_available_notification_on">true</bool>
 
     <bool name="def_backup_enabled">false</bool>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 384e8af2..7430f57 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -33,12 +33,14 @@
 import android.os.SystemProperties;
 import android.provider.Settings;
 import android.provider.Settings.Secure;
+import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.internal.content.PackageHelper;
 import com.android.internal.telephony.BaseCommands;
 import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.RILConstants;
 import com.android.internal.util.XmlUtils;
 import com.android.internal.widget.LockPatternUtils;
@@ -1540,6 +1542,8 @@
             loadIntegerSetting(stmt, Settings.System.POINTER_SPEED,
                     R.integer.def_pointer_speed);
 
+            loadIntegerSetting(stmt, Settings.System.WIFI_SLEEP_POLICY,
+                    R.integer.def_wifi_sleep_policy);
         } finally {
             if (stmt != null) stmt.close();
         }
@@ -1603,6 +1607,12 @@
                             SystemProperties.get("ro.com.android.dataroaming",
                                     "false")) ? 1 : 0);
 
+            // Mobile Data default, based on build
+            loadSetting(stmt, Settings.Secure.MOBILE_DATA,
+                    "true".equalsIgnoreCase(
+                            SystemProperties.get("ro.com.android.mobiledata",
+                                    "true")) ? 1 : 0);
+
             loadBooleanSetting(stmt, Settings.Secure.INSTALL_NON_MARKET_APPS,
                     R.bool.def_install_non_market_apps);
 
@@ -1630,7 +1640,7 @@
 
             // Set the preferred network mode to 0 = Global, CDMA default
             int type;
-            if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) {
+            if (TelephonyManager.getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE) {
                 type = Phone.NT_MODE_GLOBAL;
             } else {
                 type = SystemProperties.getInt("ro.telephony.default_network",
diff --git a/packages/SystemUI/Android.mk b/packages/SystemUI/Android.mk
index c23a8a1..6026258 100644
--- a/packages/SystemUI/Android.mk
+++ b/packages/SystemUI/Android.mk
@@ -6,7 +6,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src) \
     ../../../ex/carousel/java/com/android/ex/carousel/carousel.rs
 
-LOCAL_JAVA_LIBRARIES := services
+LOCAL_JAVA_LIBRARIES := services telephony-common
 
 LOCAL_STATIC_JAVA_LIBRARIES := android-common-carousel
 
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 96f83c6..b0a7c4b 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -294,6 +294,13 @@
                 updateWallpaperLocked();
             }
 
+            if (mBackground == null) {
+                // If we somehow got to this point after we have last flushed
+                // the wallpaper, well we really need it to draw again.  So
+                // seems like we need to reload it.  Ouch.
+                updateWallpaperLocked();
+            }
+
             SurfaceHolder sh = getSurfaceHolder();
             final Rect frame = sh.getSurfaceFrame();
             final int dw = frame.width();
@@ -315,7 +322,6 @@
             mLastXTranslation = xPixels;
             mLastYTranslation = yPixels;
 
-
             if (mIsHwAccelerated) {
                 if (!drawWallpaperWithOpenGL(sh, availw, availh, xPixels, yPixels)) {
                     drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CarrierLabel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CarrierLabel.java
index 491fad1..66494e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CarrierLabel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CarrierLabel.java
@@ -20,13 +20,14 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.provider.Telephony;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Slog;
 import android.view.View;
 import android.widget.TextView;
 
+import com.android.internal.telephony.TelephonyIntents;
+
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.TimeZone;
@@ -60,7 +61,7 @@
         if (!mAttached) {
             mAttached = true;
             IntentFilter filter = new IntentFilter();
-            filter.addAction(Telephony.Intents.SPN_STRINGS_UPDATED_ACTION);
+            filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
             getContext().registerReceiver(mIntentReceiver, filter, null, getHandler());
         }
     }
@@ -78,11 +79,11 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
-            if (Telephony.Intents.SPN_STRINGS_UPDATED_ACTION.equals(action)) {
-                updateNetworkName(intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_SPN, false),
-                        intent.getStringExtra(Telephony.Intents.EXTRA_SPN),
-                        intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_PLMN, false),
-                        intent.getStringExtra(Telephony.Intents.EXTRA_PLMN));
+            if (TelephonyIntents.SPN_STRINGS_UPDATED_ACTION.equals(action)) {
+                updateNetworkName(intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false),
+                        intent.getStringExtra(TelephonyIntents.EXTRA_SPN),
+                        intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false),
+                        intent.getStringExtra(TelephonyIntents.EXTRA_PLMN));
             }
         }
     };
@@ -108,7 +109,7 @@
         setText(str);
     }
 
-    
+
 }
 
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 374226d..9b8bd22 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -39,6 +39,7 @@
 import android.util.Slog;
 
 import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.cdma.EriInfo;
 import com.android.internal.telephony.cdma.TtyIntent;
@@ -76,7 +77,7 @@
 
     // Assume it's all good unless we hear otherwise.  We don't always seem
     // to get broadcasts that it *is* there.
-    IccCard.State mSimState = IccCard.State.READY;
+    IccCardConstants.State mSimState = IccCardConstants.State.READY;
 
     // ringer volume
     private boolean mVolumeVisible;
@@ -205,26 +206,27 @@
     }
 
     private final void updateSimState(Intent intent) {
-        String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE);
-        if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
-            mSimState = IccCard.State.ABSENT;
+        String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
+        if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
+            mSimState = IccCardConstants.State.ABSENT;
         }
-        else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
-            mSimState = IccCard.State.READY;
+        else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
+            mSimState = IccCardConstants.State.READY;
         }
-        else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
-            final String lockedReason = intent.getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);
-            if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
-                mSimState = IccCard.State.PIN_REQUIRED;
+        else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
+            final String lockedReason =
+                    intent.getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
+            if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
+                mSimState = IccCardConstants.State.PIN_REQUIRED;
             }
-            else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
-                mSimState = IccCard.State.PUK_REQUIRED;
+            else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
+                mSimState = IccCardConstants.State.PUK_REQUIRED;
             }
             else {
-                mSimState = IccCard.State.NETWORK_LOCKED;
+                mSimState = IccCardConstants.State.NETWORK_LOCKED;
             }
         } else {
-            mSimState = IccCard.State.UNKNOWN;
+            mSimState = IccCardConstants.State.UNKNOWN;
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 8cf7b4a..d94c6b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -51,6 +51,7 @@
 
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.cdma.EriInfo;
 import com.android.server.am.BatteryStatsService;
@@ -68,7 +69,7 @@
     boolean mHspaDataDistinguishable;
     final TelephonyManager mPhone;
     boolean mDataConnected;
-    IccCard.State mSimState = IccCard.State.READY;
+    IccCardConstants.State mSimState = IccCardConstants.State.READY;
     int mPhoneState = TelephonyManager.CALL_STATE_IDLE;
     int mDataNetType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
     int mDataState = TelephonyManager.DATA_DISCONNECTED;
@@ -221,7 +222,7 @@
         filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
         filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
         filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
-        filter.addAction(Telephony.Intents.SPN_STRINGS_UPDATED_ACTION);
+        filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
         filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
         filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);
         filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
@@ -344,11 +345,11 @@
             updateSimState(intent);
             updateDataIcon();
             refreshViews();
-        } else if (action.equals(Telephony.Intents.SPN_STRINGS_UPDATED_ACTION)) {
-            updateNetworkName(intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_SPN, false),
-                        intent.getStringExtra(Telephony.Intents.EXTRA_SPN),
-                        intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_PLMN, false),
-                        intent.getStringExtra(Telephony.Intents.EXTRA_PLMN));
+        } else if (action.equals(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION)) {
+            updateNetworkName(intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false),
+                        intent.getStringExtra(TelephonyIntents.EXTRA_SPN),
+                        intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false),
+                        intent.getStringExtra(TelephonyIntents.EXTRA_PLMN));
             refreshViews();
         } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) ||
                  action.equals(ConnectivityManager.INET_CONDITION_ACTION)) {
@@ -431,26 +432,27 @@
     };
 
     private final void updateSimState(Intent intent) {
-        String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE);
-        if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
-            mSimState = IccCard.State.ABSENT;
+        String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
+        if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
+            mSimState = IccCardConstants.State.ABSENT;
         }
-        else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
-            mSimState = IccCard.State.READY;
+        else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
+            mSimState = IccCardConstants.State.READY;
         }
-        else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
-            final String lockedReason = intent.getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);
-            if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
-                mSimState = IccCard.State.PIN_REQUIRED;
+        else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
+            final String lockedReason =
+                    intent.getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
+            if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
+                mSimState = IccCardConstants.State.PIN_REQUIRED;
             }
-            else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
-                mSimState = IccCard.State.PUK_REQUIRED;
+            else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
+                mSimState = IccCardConstants.State.PUK_REQUIRED;
             }
             else {
-                mSimState = IccCard.State.NETWORK_LOCKED;
+                mSimState = IccCardConstants.State.NETWORK_LOCKED;
             }
         } else {
-            mSimState = IccCard.State.UNKNOWN;
+            mSimState = IccCardConstants.State.UNKNOWN;
         }
     }
 
@@ -655,7 +657,8 @@
 
         if (!isCdma()) {
             // GSM case, we have to check also the sim state
-            if (mSimState == IccCard.State.READY || mSimState == IccCard.State.UNKNOWN) {
+            if (mSimState == IccCardConstants.State.READY ||
+                    mSimState == IccCardConstants.State.UNKNOWN) {
                 if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) {
                     switch (mDataActivity) {
                         case TelephonyManager.DATA_ACTIVITY_IN:
@@ -985,6 +988,8 @@
                 combinedActivityIconId = mMobileActivityIconId;
                 combinedSignalIconId = mDataSignalIconId; // set by updateDataIcon()
                 mContentDescriptionCombinedSignal = mContentDescriptionDataType;
+            } else {
+                mMobileActivityIconId = 0;
             }
         }
 
diff --git a/packages/WAPPushManager/Android.mk b/packages/WAPPushManager/Android.mk
index c1d8f4b..35ec647 100644
--- a/packages/WAPPushManager/Android.mk
+++ b/packages/WAPPushManager/Android.mk
@@ -10,6 +10,7 @@
 
 LOCAL_PACKAGE_NAME := WAPPushManager
 
+LOCAL_JAVA_LIBRARIES += telephony-common
 LOCAL_STATIC_JAVA_LIBRARIES += android-common
 
 LOCAL_PROGUARD_FLAGS := -include $(LOCAL_PATH)/proguard.flags
diff --git a/packages/WAPPushManager/tests/Android.mk b/packages/WAPPushManager/tests/Android.mk
index 0a95b52..7128b0d 100644
--- a/packages/WAPPushManager/tests/Android.mk
+++ b/packages/WAPPushManager/tests/Android.mk
@@ -18,7 +18,7 @@
 # We only want this apk build for tests.
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common
 
 # Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/policy/src/com/android/internal/policy/impl/IconUtilities.java b/policy/src/com/android/internal/policy/impl/IconUtilities.java
index e997355..a47c904 100644
--- a/policy/src/com/android/internal/policy/impl/IconUtilities.java
+++ b/policy/src/com/android/internal/policy/impl/IconUtilities.java
@@ -130,7 +130,7 @@
         int sourceWidth = icon.getIntrinsicWidth();
         int sourceHeight = icon.getIntrinsicHeight();
 
-        if (sourceWidth > 0 && sourceWidth > 0) {
+        if (sourceWidth > 0 && sourceHeight > 0) {
             // There are intrinsic sizes.
             if (width < sourceWidth || height < sourceHeight) {
                 // It's too big, scale it down.
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
index d0fe42d..c1fd515 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
@@ -17,8 +17,7 @@
 package com.android.internal.policy.impl;
 
 import com.android.internal.R;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccCard.State;
+import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.widget.DigitalClock;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.internal.widget.TransportControlView;
@@ -88,7 +87,7 @@
     private int mBatteryLevel = 100;
 
     // last known SIM state
-    protected State mSimState;
+    protected IccCardConstants.State mSimState;
 
     private LockPatternUtils mLockPatternUtils;
     private KeyguardUpdateMonitor mUpdateMonitor;
@@ -435,17 +434,18 @@
     /**
      * Determine the current status of the lock screen given the sim state and other stuff.
      */
-    public StatusMode getStatusForIccState(IccCard.State simState) {
+    public StatusMode getStatusForIccState(IccCardConstants.State simState) {
         // Since reading the SIM may take a while, we assume it is present until told otherwise.
         if (simState == null) {
             return StatusMode.Normal;
         }
 
         final boolean missingAndNotProvisioned = (!mUpdateMonitor.isDeviceProvisioned()
-                && (simState == IccCard.State.ABSENT || simState == IccCard.State.PERM_DISABLED));
+                && (simState == IccCardConstants.State.ABSENT ||
+                        simState == IccCardConstants.State.PERM_DISABLED));
 
         // Assume we're NETWORK_LOCKED if not provisioned
-        simState = missingAndNotProvisioned ? State.NETWORK_LOCKED : simState;
+        simState = missingAndNotProvisioned ? IccCardConstants.State.NETWORK_LOCKED : simState;
         switch (simState) {
             case ABSENT:
                 return StatusMode.SimMissing;
@@ -477,7 +477,7 @@
      *
      * @param simState
      */
-    private void updateCarrierStateWithSimStatus(State simState) {
+    private void updateCarrierStateWithSimStatus(IccCardConstants.State simState) {
         if (DEBUG) Log.d(TAG, "updateCarrierTextWithSimStatus(), simState = " + simState);
 
         CharSequence carrierText = null;
@@ -663,7 +663,7 @@
 
     private SimStateCallback mSimStateCallback = new SimStateCallback() {
 
-        public void onSimStateChanged(State simState) {
+        public void onSimStateChanged(IccCardConstants.State simState) {
             updateCarrierStateWithSimStatus(simState);
         }
     };
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index dfe9134..5cd0349 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -34,14 +34,8 @@
 import android.os.Handler;
 import android.os.Message;
 import android.provider.Settings;
-import android.provider.Telephony;
-import static android.provider.Telephony.Intents.EXTRA_PLMN;
-import static android.provider.Telephony.Intents.EXTRA_SHOW_PLMN;
-import static android.provider.Telephony.Intents.EXTRA_SHOW_SPN;
-import static android.provider.Telephony.Intents.EXTRA_SPN;
-import static android.provider.Telephony.Intents.SPN_STRINGS_UPDATED_ACTION;
 
-import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.telephony.TelephonyIntents;
 
 import android.telephony.TelephonyManager;
@@ -70,7 +64,7 @@
 
     private final Context mContext;
 
-    private IccCard.State mSimState = IccCard.State.READY;
+    private IccCardConstants.State mSimState = IccCardConstants.State.READY;
 
     private boolean mDeviceProvisioned;
 
@@ -115,44 +109,44 @@
      * the intent and provide a {@link SimCard.State} result.
      */
     private static class SimArgs {
-        public final IccCard.State simState;
+        public final IccCardConstants.State simState;
 
-        SimArgs(IccCard.State state) {
+        SimArgs(IccCardConstants.State state) {
             simState = state;
         }
 
         static SimArgs fromIntent(Intent intent) {
-            IccCard.State state;
+            IccCardConstants.State state;
             if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
                 throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
             }
-            String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE);
-            if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
+            String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
+            if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
                 final String absentReason = intent
-                    .getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);
+                    .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
 
-                if (IccCard.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
+                if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
                         absentReason)) {
-                    state = IccCard.State.PERM_DISABLED;
+                    state = IccCardConstants.State.PERM_DISABLED;
                 } else {
-                    state = IccCard.State.ABSENT;
+                    state = IccCardConstants.State.ABSENT;
                 }
-            } else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
-                state = IccCard.State.READY;
-            } else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
+            } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
+                state = IccCardConstants.State.READY;
+            } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
                 final String lockedReason = intent
-                        .getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);
-                if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
-                    state = IccCard.State.PIN_REQUIRED;
-                } else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
-                    state = IccCard.State.PUK_REQUIRED;
+                        .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
+                if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
+                    state = IccCardConstants.State.PIN_REQUIRED;
+                } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
+                    state = IccCardConstants.State.PUK_REQUIRED;
                 } else {
-                    state = IccCard.State.UNKNOWN;
+                    state = IccCardConstants.State.UNKNOWN;
                 }
-            } else if (IccCard.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
-                state = IccCard.State.NETWORK_LOCKED;
+            } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
+                state = IccCardConstants.State.NETWORK_LOCKED;
             } else {
-                state = IccCard.State.UNKNOWN;
+                state = IccCardConstants.State.UNKNOWN;
             }
             return new SimArgs(state);
         }
@@ -253,7 +247,7 @@
         }
 
         // take a guess to start
-        mSimState = IccCard.State.READY;
+        mSimState = IccCardConstants.State.READY;
         mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0);
 
         mTelephonyPlmn = getDefaultPlmn();
@@ -266,7 +260,7 @@
         filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
         filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
         filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
-        filter.addAction(SPN_STRINGS_UPDATED_ACTION);
+        filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
         filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
         filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
         filter.addAction(Intent.ACTION_USER_SWITCHED);
@@ -281,7 +275,7 @@
                         || Intent.ACTION_TIME_CHANGED.equals(action)
                         || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
                     mHandler.sendMessage(mHandler.obtainMessage(MSG_TIME_UPDATE));
-                } else if (SPN_STRINGS_UPDATED_ACTION.equals(action)) {
+                } else if (TelephonyIntents.SPN_STRINGS_UPDATED_ACTION.equals(action)) {
                     mTelephonyPlmn = getTelephonyPlmnFrom(intent);
                     mTelephonySpn = getTelephonySpnFrom(intent);
                     mHandler.sendMessage(mHandler.obtainMessage(MSG_CARRIER_INFO_UPDATE));
@@ -296,7 +290,7 @@
                 } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
                     if (DEBUG_SIM_STATES) {
                         Log.v(TAG, "action " + action + " state" +
-                            intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE));
+                            intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE));
                     }
                     mHandler.sendMessage(mHandler.obtainMessage(
                             MSG_SIM_STATE_CHANGE, SimArgs.fromIntent(intent)));
@@ -405,15 +399,14 @@
      * Handle {@link #MSG_SIM_STATE_CHANGE}
      */
     private void handleSimStateChange(SimArgs simArgs) {
-        final IccCard.State state = simArgs.simState;
+        final IccCardConstants.State state = simArgs.simState;
 
         if (DEBUG) {
             Log.d(TAG, "handleSimStateChange: intentValue = " + simArgs + " "
                     + "state resolved to " + state.toString());
         }
 
-        if (state != IccCard.State.UNKNOWN && state != mSimState) {
-            if (DEBUG_SIM_STATES) Log.v(TAG, "dispatching state: " + state);
+        if (state != IccCardConstants.State.UNKNOWN && state != mSimState) {
             mSimState = state;
             for (int i = 0; i < mSimStateCallbacks.size(); i++) {
                 mSimStateCallbacks.get(i).onSimStateChanged(state);
@@ -466,12 +459,12 @@
     }
 
     /**
-     * @param intent The intent with action {@link Telephony.Intents#SPN_STRINGS_UPDATED_ACTION}
+     * @param intent The intent with action {@link TelephonyIntents#SPN_STRINGS_UPDATED_ACTION}
      * @return The string to use for the plmn, or null if it should not be shown.
      */
     private CharSequence getTelephonyPlmnFrom(Intent intent) {
-        if (intent.getBooleanExtra(EXTRA_SHOW_PLMN, false)) {
-            final String plmn = intent.getStringExtra(EXTRA_PLMN);
+        if (intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false)) {
+            final String plmn = intent.getStringExtra(TelephonyIntents.EXTRA_PLMN);
             if (plmn != null) {
                 return plmn;
             } else {
@@ -494,8 +487,8 @@
      * @return The string to use for the plmn, or null if it should not be shown.
      */
     private CharSequence getTelephonySpnFrom(Intent intent) {
-        if (intent.getBooleanExtra(EXTRA_SHOW_SPN, false)) {
-            final String spn = intent.getStringExtra(EXTRA_SPN);
+        if (intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false)) {
+            final String spn = intent.getStringExtra(TelephonyIntents.EXTRA_SPN);
             if (spn != null) {
                 return spn;
             }
@@ -601,7 +594,7 @@
      * Callback to notify of sim state change.
      */
     interface SimStateCallback {
-        void onSimStateChanged(IccCard.State simState);
+        void onSimStateChanged(IccCardConstants.State simState);
     }
 
     /**
@@ -646,7 +639,7 @@
         mHandler.obtainMessage(MSG_CLOCK_VISIBILITY_CHANGED).sendToTarget();
     }
 
-    public IccCard.State getSimState() {
+    public IccCardConstants.State getSimState() {
         return mSimState;
     }
 
@@ -659,7 +652,7 @@
      * through mHandler, this *must* be called from the UI thread.
      */
     public void reportSimUnlocked() {
-        handleSimStateChange(new SimArgs(IccCard.State.READY));
+        handleSimStateChange(new SimArgs(IccCardConstants.State.READY));
     }
 
     public boolean isDevicePluggedIn() {
@@ -725,8 +718,8 @@
     }
 
     public boolean isSimLocked() {
-        return mSimState == IccCard.State.PIN_REQUIRED
-            || mSimState == IccCard.State.PUK_REQUIRED
-            || mSimState == IccCard.State.PERM_DISABLED;
+        return mSimState == IccCardConstants.State.PIN_REQUIRED
+            || mSimState == IccCardConstants.State.PUK_REQUIRED
+            || mSimState == IccCardConstants.State.PERM_DISABLED;
     }
 }
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index e84e912..5fa6dbf 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -19,7 +19,7 @@
 import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
 
 import com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallbackImpl;
-import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.widget.LockPatternUtils;
 
 import android.app.ActivityManagerNative;
@@ -230,7 +230,7 @@
 
     private KeyguardUpdateMonitor mUpdateMonitor;
 
-    private boolean mScreenOn = false;
+    private boolean mScreenOn;
 
     // last known state of the cellular connection
     private String mPhoneState = TelephonyManager.EXTRA_STATE_IDLE;
@@ -318,6 +318,8 @@
         final ContentResolver cr = mContext.getContentResolver();
         mShowLockIcon = (Settings.System.getInt(cr, "show_status_bar_lock", 0) == 1);
 
+        mScreenOn = mPM.isScreenOn();
+
         mLockSounds = new SoundPool(1, AudioManager.STREAM_SYSTEM, 0);
         String soundPath = Settings.System.getString(cr, Settings.System.LOCK_SOUND);
         if (soundPath != null) {
@@ -621,10 +623,10 @@
         final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim",
                 false);
         final boolean provisioned = mUpdateMonitor.isDeviceProvisioned();
-        final IccCard.State state = mUpdateMonitor.getSimState();
+        final IccCardConstants.State state = mUpdateMonitor.getSimState();
         final boolean lockedOrMissing = state.isPinLocked()
-                || ((state == IccCard.State.ABSENT
-                || state == IccCard.State.PERM_DISABLED)
+                || ((state == IccCardConstants.State.ABSENT
+                || state == IccCardConstants.State.PERM_DISABLED)
                 && requireSim);
 
         if (!lockedOrMissing && !provisioned) {
@@ -727,7 +729,7 @@
     }
 
     /** {@inheritDoc} */
-    public void onSimStateChanged(IccCard.State simState) {
+    public void onSimStateChanged(IccCardConstants.State simState) {
         if (DEBUG) Log.d(TAG, "onSimStateChanged: " + simState);
 
         switch (simState) {
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 35e7820..041211c 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -20,7 +20,7 @@
 import com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallback;
 import com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallbackImpl;
 import com.android.internal.policy.impl.LockPatternKeyguardView.UnlockMode;
-import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.internal.widget.LockScreenWidgetCallback;
 import com.android.internal.widget.LockScreenWidgetInterface;
@@ -267,8 +267,8 @@
     private boolean stuckOnLockScreenBecauseSimMissing() {
         return mRequiresSim
                 && (!mUpdateMonitor.isDeviceProvisioned())
-                && (mUpdateMonitor.getSimState() == IccCard.State.ABSENT ||
-                    mUpdateMonitor.getSimState() == IccCard.State.PERM_DISABLED);
+                && (mUpdateMonitor.getSimState() == IccCardConstants.State.ABSENT ||
+                    mUpdateMonitor.getSimState() == IccCardConstants.State.PERM_DISABLED);
     }
 
     /**
@@ -289,9 +289,9 @@
         }
 
         public void goToUnlockScreen() {
-            final IccCard.State simState = mUpdateMonitor.getSimState();
+            final IccCardConstants.State simState = mUpdateMonitor.getSimState();
             if (stuckOnLockScreenBecauseSimMissing()
-                     || (simState == IccCard.State.PUK_REQUIRED
+                     || (simState == IccCardConstants.State.PUK_REQUIRED
                          && !mLockPatternUtils.isPukUnlockScreenEnable())){
                 // stuck on lock screen when sim missing or
                 // puk'd but puk unlock screen is disabled
@@ -757,7 +757,7 @@
     public void wakeWhenReadyTq(int keyCode) {
         if (DEBUG) Log.d(TAG, "onWakeKey");
         if (keyCode == KeyEvent.KEYCODE_MENU && isSecure() && (mMode == Mode.LockScreen)
-                && (mUpdateMonitor.getSimState() != IccCard.State.PUK_REQUIRED)) {
+                && (mUpdateMonitor.getSimState() != IccCardConstants.State.PUK_REQUIRED)) {
             if (DEBUG) Log.d(TAG, "switching screens to unlock screen because wake key was MENU");
             updateScreen(Mode.UnlockScreen, false);
             getCallback().pokeWakelock();
@@ -811,10 +811,10 @@
                 secure = mLockPatternUtils.isLockPatternEnabled();
                 break;
             case SimPin:
-                secure = mUpdateMonitor.getSimState() == IccCard.State.PIN_REQUIRED;
+                secure = mUpdateMonitor.getSimState() == IccCardConstants.State.PIN_REQUIRED;
                 break;
             case SimPuk:
-                secure = mUpdateMonitor.getSimState() == IccCard.State.PUK_REQUIRED;
+                secure = mUpdateMonitor.getSimState() == IccCardConstants.State.PUK_REQUIRED;
                 break;
             case Account:
                 secure = true;
@@ -1044,9 +1044,9 @@
      * the lock screen (lock or unlock).
      */
     private Mode getInitialMode() {
-        final IccCard.State simState = mUpdateMonitor.getSimState();
+        final IccCardConstants.State simState = mUpdateMonitor.getSimState();
         if (stuckOnLockScreenBecauseSimMissing() ||
-                (simState == IccCard.State.PUK_REQUIRED &&
+                (simState == IccCardConstants.State.PUK_REQUIRED &&
                         !mLockPatternUtils.isPukUnlockScreenEnable())) {
             return Mode.LockScreen;
         } else {
@@ -1062,11 +1062,11 @@
      * Given the current state of things, what should the unlock screen be?
      */
     private UnlockMode getUnlockMode() {
-        final IccCard.State simState = mUpdateMonitor.getSimState();
+        final IccCardConstants.State simState = mUpdateMonitor.getSimState();
         UnlockMode currentMode;
-        if (simState == IccCard.State.PIN_REQUIRED) {
+        if (simState == IccCardConstants.State.PIN_REQUIRED) {
             currentMode = UnlockMode.SimPin;
-        } else if (simState == IccCard.State.PUK_REQUIRED) {
+        } else if (simState == IccCardConstants.State.PUK_REQUIRED) {
             currentMode = UnlockMode.SimPuk;
         } else {
             final int mode = mLockPatternUtils.getKeyguardStoredPasswordQuality();
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java
index 58d14ed..6d3c20a6 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java
@@ -19,7 +19,7 @@
 import com.android.internal.widget.LockPatternUtils;
 
 import android.content.Context;
-import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccCardConstants;
 
 /**
  * Knows how to create a lock pattern keyguard view, and answer questions about
@@ -55,10 +55,11 @@
     }
 
     private boolean isSimPinSecure() {
-        final IccCard.State simState = mUpdateMonitor.getSimState();
-        return (simState == IccCard.State.PIN_REQUIRED
-                || simState == IccCard.State.PUK_REQUIRED
-                || simState == IccCard.State.PERM_DISABLED);
+        final IccCardConstants.State simState = mUpdateMonitor.getSimState();
+        return (simState == IccCardConstants.State.PIN_REQUIRED
+                || simState == IccCardConstants.State.PUK_REQUIRED
+                || simState == IccCardConstants.State.ABSENT
+                || simState == IccCardConstants.State.PERM_DISABLED);
     }
 
 }
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index ec954fe..26078ec 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -19,7 +19,7 @@
 import com.android.internal.R;
 import com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallbackImpl;
 import com.android.internal.policy.impl.KeyguardUpdateMonitor.SimStateCallback;
-import com.android.internal.telephony.IccCard.State;
+import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.internal.widget.SlidingTab;
 import com.android.internal.widget.WaveView;
@@ -105,7 +105,7 @@
     };
 
     SimStateCallback mSimStateCallback = new SimStateCallback() {
-        public void onSimStateChanged(State simState) {
+        public void onSimStateChanged(IccCardConstants.State simState) {
             updateTargets();
         }
     };
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 47703c6..0aa3018 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -1666,7 +1666,9 @@
      */
     private void restorePanelState(SparseArray<Parcelable> icicles) {
         PanelFeatureState st;
-        for (int curFeatureId = icicles.size() - 1; curFeatureId >= 0; curFeatureId--) {
+        int curFeatureId;
+        for (int i = icicles.size() - 1; i >= 0; i--) {
+            curFeatureId = icicles.keyAt(i);
             st = getPanelState(curFeatureId, false /* required */);
             if (st == null) {
                 // The panel must not have been required, and is currently not around, skip it
diff --git a/policy/src/com/android/internal/policy/impl/Policy.java b/policy/src/com/android/internal/policy/impl/Policy.java
index a490729..153ef0f 100644
--- a/policy/src/com/android/internal/policy/impl/Policy.java
+++ b/policy/src/com/android/internal/policy/impl/Policy.java
@@ -41,7 +41,7 @@
         "com.android.internal.policy.impl.PhoneLayoutInflater",
         "com.android.internal.policy.impl.PhoneWindow",
         "com.android.internal.policy.impl.PhoneWindow$1",
-        "com.android.internal.policy.impl.PhoneWindow$ContextMenuCallback",
+        "com.android.internal.policy.impl.PhoneWindow$DialogMenuCallback",
         "com.android.internal.policy.impl.PhoneWindow$DecorView",
         "com.android.internal.policy.impl.PhoneWindow$PanelFeatureState",
         "com.android.internal.policy.impl.PhoneWindow$PanelFeatureState$SavedState",
diff --git a/policy/tests/src/com/android/internal/policy/impl/LockPatternKeyguardViewTest.java b/policy/tests/src/com/android/internal/policy/impl/LockPatternKeyguardViewTest.java
index db71e2b..862e683 100644
--- a/policy/tests/src/com/android/internal/policy/impl/LockPatternKeyguardViewTest.java
+++ b/policy/tests/src/com/android/internal/policy/impl/LockPatternKeyguardViewTest.java
@@ -18,7 +18,7 @@
 
 import android.content.Context;
 import com.android.internal.policy.impl.KeyguardViewCallback;
-import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccCardConstants;
 import android.content.res.Configuration;
 import android.test.AndroidTestCase;
 import android.view.View;
@@ -40,14 +40,14 @@
 
     private static class MockUpdateMonitor extends KeyguardUpdateMonitor {
 
-        public IccCard.State simState = IccCard.State.READY;
+        public IccCardConstants.State simState = IccCardConstants.State.READY;
 
         private MockUpdateMonitor(Context context) {
             super(context);
         }
 
         @Override
-        public IccCard.State getSimState() {
+        public IccCardConstants.State getSimState() {
             return simState;
         }
     }
@@ -318,7 +318,7 @@
 
     public void testMenuDoesntGoToUnlockScreenOnWakeWhenPukLocked() {
         // PUK locked
-        mUpdateMonitor.simState = IccCard.State.PUK_REQUIRED;
+        mUpdateMonitor.simState = IccCardConstants.State.PUK_REQUIRED;
 
         // wake by menu
         mLPKV.wakeWhenReadyTq(KeyEvent.KEYCODE_MENU);
diff --git a/preloaded-classes b/preloaded-classes
index c29ba15..feddbd6 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -38,10 +38,6 @@
 android.animation.TypeEvaluator
 android.animation.ValueAnimator
 android.animation.ValueAnimator$1
-android.animation.ValueAnimator$2
-android.animation.ValueAnimator$3
-android.animation.ValueAnimator$4
-android.animation.ValueAnimator$5
 android.animation.ValueAnimator$AnimationHandler
 android.app.ActionBar
 android.app.ActionBar$LayoutParams
@@ -279,7 +275,6 @@
 android.content.res.ObbInfo$1
 android.content.res.ObbScanner
 android.content.res.Resources
-android.content.res.Resources$1
 android.content.res.Resources$Theme
 android.content.res.StringBlock
 android.content.res.StringBlock$StyleIDs
@@ -318,13 +313,11 @@
 android.database.Observable
 android.database.sqlite.DatabaseObjectNotClosedException
 android.database.sqlite.SQLiteClosable
-android.database.sqlite.SQLiteCompiledSql
 android.database.sqlite.SQLiteCursor
 android.database.sqlite.SQLiteCursorDriver
 android.database.sqlite.SQLiteDatabase
 android.database.sqlite.SQLiteDatabase$1
 android.database.sqlite.SQLiteDatabase$CustomFunction
-android.database.sqlite.SQLiteDatabase$DatabaseReentrantLock
 android.database.sqlite.SQLiteDebug
 android.database.sqlite.SQLiteDebug$PagerStats
 android.database.sqlite.SQLiteDirectCursorDriver
@@ -482,7 +475,6 @@
 android.media.AudioFormat
 android.media.AudioManager
 android.media.AudioManager$1
-android.media.AudioManager$2
 android.media.AudioManager$FocusEventHandlerDelegate
 android.media.AudioManager$FocusEventHandlerDelegate$1
 android.media.AudioRecord
@@ -495,8 +487,6 @@
 android.media.IAudioService
 android.media.IAudioService$Stub
 android.media.IAudioService$Stub$Proxy
-android.media.IRemoteControlClientDispatcher
-android.media.IRemoteControlClientDispatcher$Stub
 android.media.JetPlayer
 android.media.MediaFile
 android.media.MediaPlayer
@@ -605,7 +595,6 @@
 android.os.Parcelable$Creator
 android.os.PatternMatcher
 android.os.PatternMatcher$1
-android.os.Power
 android.os.PowerManager
 android.os.PowerManager$WakeLock
 android.os.PowerManager$WakeLock$1
@@ -698,7 +687,6 @@
 android.text.TextDirectionHeuristics
 android.text.TextDirectionHeuristics$1
 android.text.TextDirectionHeuristics$AnyStrong
-android.text.TextDirectionHeuristics$CharCount
 android.text.TextDirectionHeuristics$FirstStrong
 android.text.TextDirectionHeuristics$TextDirectionAlgorithm
 android.text.TextDirectionHeuristics$TextDirectionHeuristicImpl
@@ -729,7 +717,6 @@
 android.text.method.TransformationMethod
 android.text.method.TransformationMethod2
 android.text.method.WordIterator
-android.text.method.WordIterator$1
 android.text.style.AlignmentSpan
 android.text.style.CharacterStyle
 android.text.style.LeadingMarginSpan
@@ -824,10 +811,9 @@
 android.view.InputEvent$1
 android.view.InputEventConsistencyVerifier
 android.view.InputEventConsistencyVerifier$KeyState
-android.view.InputHandler
+android.view.InputEventReceiver
 android.view.InputQueue
 android.view.InputQueue$Callback
-android.view.InputQueue$FinishedCallback
 android.view.KeyCharacterMap
 android.view.KeyCharacterMap$FallbackAction
 android.view.KeyEvent
@@ -903,7 +889,6 @@
 android.view.ViewParent
 android.view.ViewRootImpl
 android.view.ViewRootImpl$2
-android.view.ViewRootImpl$3
 android.view.ViewRootImpl$AccessibilityInteractionConnectionManager
 android.view.ViewRootImpl$InputMethodCallback
 android.view.ViewRootImpl$ResizedInfo
@@ -1005,8 +990,11 @@
 android.widget.CursorAdapter
 android.widget.CursorFilter$CursorFilterClient
 android.widget.EdgeEffect
-android.widget.EdgeGlow
 android.widget.EditText
+android.widget.Editor$Blink
+android.widget.Editor$EasyEditSpanController
+android.widget.Editor$InputContentType
+android.widget.Editor$InputMethodState
 android.widget.ExpandableListView
 android.widget.FastScroller
 android.widget.FastScroller$1
@@ -1080,17 +1068,12 @@
 android.widget.TextView
 android.widget.TextView$2
 android.widget.TextView$3
-android.widget.TextView$Blink
 android.widget.TextView$BufferType
 android.widget.TextView$ChangeWatcher
 android.widget.TextView$CharWrapper
 android.widget.TextView$Drawables
-android.widget.TextView$EasyEditSpanController
-android.widget.TextView$InputContentType
-android.widget.TextView$InputMethodState
 android.widget.TextView$OnEditorActionListener
 android.widget.TextView$SavedState
-android.widget.TextView$TextAlign
 android.widget.VideoView
 android.widget.ViewAnimator
 com.android.i18n.phonenumbers.AsYouTypeFormatter
@@ -1144,7 +1127,7 @@
 com.android.internal.telephony.ITelephonyRegistry
 com.android.internal.telephony.ITelephonyRegistry$Stub
 com.android.internal.telephony.ITelephonyRegistry$Stub$Proxy
-com.android.internal.telephony.Phone$State
+com.android.internal.telephony.PhoneConstants$State
 com.android.internal.util.ArrayUtils
 com.android.internal.util.FastXmlSerializer
 com.android.internal.util.Preconditions
diff --git a/services/common_time/common_clock_service.h b/services/common_time/common_clock_service.h
index a65e398..bd663f0 100644
--- a/services/common_time/common_clock_service.h
+++ b/services/common_time/common_clock_service.h
@@ -14,11 +14,12 @@
  * limitations under the License.
  */
 
-#include <common_time/ICommonClock.h>
-
 #ifndef ANDROID_COMMON_CLOCK_SERVICE_H
 #define ANDROID_COMMON_CLOCK_SERVICE_H
 
+#include <sys/socket.h>
+#include <common_time/ICommonClock.h>
+
 namespace android {
 
 class CommonTimeServer;
diff --git a/services/common_time/common_time_config_service.h b/services/common_time/common_time_config_service.h
index 8283c24..89806dd 100644
--- a/services/common_time/common_time_config_service.h
+++ b/services/common_time/common_time_config_service.h
@@ -13,11 +13,12 @@
  * limitations under the License.
  */
 
-#include <common_time/ICommonTimeConfig.h>
-
 #ifndef ANDROID_COMMON_TIME_CONFIG_SERVICE_H
 #define ANDROID_COMMON_TIME_CONFIG_SERVICE_H
 
+#include <sys/socket.h>
+#include <common_time/ICommonTimeConfig.h>
+
 namespace android {
 
 class String16;
diff --git a/services/common_time/common_time_server.h b/services/common_time/common_time_server.h
index a0f549f..89bca64 100644
--- a/services/common_time/common_time_server.h
+++ b/services/common_time/common_time_server.h
@@ -19,7 +19,7 @@
 
 #include <arpa/inet.h>
 #include <stdint.h>
-#include <linux/socket.h>
+#include <sys/socket.h>
 
 #include <common_time/ICommonClock.h>
 #include <common_time/local_clock.h>
diff --git a/services/java/Android.mk b/services/java/Android.mk
index c756d29..e70a6c9 100644
--- a/services/java/Android.mk
+++ b/services/java/Android.mk
@@ -11,7 +11,7 @@
 
 LOCAL_MODULE:= services
 
-LOCAL_JAVA_LIBRARIES := android.policy
+LOCAL_JAVA_LIBRARIES := android.policy telephony-common
 
 LOCAL_NO_EMMA_INSTRUMENT := true
 LOCAL_NO_EMMA_COMPILE := true
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 7bbc8b5..86ada40 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -77,6 +77,7 @@
 import com.android.internal.net.LegacyVpnInfo;
 import com.android.internal.net.VpnConfig;
 import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
 import com.android.server.am.BatteryStatsService;
 import com.android.server.connectivity.Tethering;
 import com.android.server.connectivity.Vpn;
@@ -1008,7 +1009,7 @@
         try {
             if (!ConnectivityManager.isNetworkTypeValid(networkType) ||
                     mNetConfigs[networkType] == null) {
-                return Phone.APN_REQUEST_FAILED;
+                return PhoneConstants.APN_REQUEST_FAILED;
             }
 
             FeatureUser f = new FeatureUser(networkType, feature, binder);
@@ -1027,7 +1028,7 @@
                 uidRules = mUidRules.get(Binder.getCallingUid(), RULE_ALLOW_ALL);
             }
             if (networkMetered && (uidRules & RULE_REJECT_METERED) != 0) {
-                return Phone.APN_REQUEST_FAILED;
+                return PhoneConstants.APN_REQUEST_FAILED;
             }
 
             NetworkStateTracker network = mNetTrackers[usedNetworkType];
@@ -1039,7 +1040,7 @@
                     if (ni.isAvailable() == false) {
                         if (!TextUtils.equals(feature,Phone.FEATURE_ENABLE_DUN_ALWAYS)) {
                             if (DBG) log("special network not available ni=" + ni.getTypeName());
-                            return Phone.APN_TYPE_NOT_AVAILABLE;
+                            return PhoneConstants.APN_TYPE_NOT_AVAILABLE;
                         } else {
                             // else make the attempt anyway - probably giving REQUEST_STARTED below
                             if (DBG) {
@@ -1088,10 +1089,10 @@
                             } finally {
                                 Binder.restoreCallingIdentity(token);
                             }
-                            return Phone.APN_ALREADY_ACTIVE;
+                            return PhoneConstants.APN_ALREADY_ACTIVE;
                         }
                         if (VDBG) log("special network already connecting");
-                        return Phone.APN_REQUEST_STARTED;
+                        return PhoneConstants.APN_REQUEST_STARTED;
                     }
 
                     // check if the radio in play can make another contact
@@ -1102,7 +1103,7 @@
                                 feature);
                     }
                     network.reconnect();
-                    return Phone.APN_REQUEST_STARTED;
+                    return PhoneConstants.APN_REQUEST_STARTED;
                 } else {
                     // need to remember this unsupported request so we respond appropriately on stop
                     synchronized(this) {
@@ -1115,7 +1116,7 @@
                     return -1;
                 }
             }
-            return Phone.APN_TYPE_NOT_AVAILABLE;
+            return PhoneConstants.APN_TYPE_NOT_AVAILABLE;
          } finally {
             if (DBG) {
                 final long execTime = SystemClock.elapsedRealtime() - startTime;
@@ -2037,7 +2038,7 @@
         //       @see bug/4455071
         /** Notify TetheringService if interface name has been changed. */
         if (TextUtils.equals(mNetTrackers[netType].getNetworkInfo().getReason(),
-                             Phone.REASON_LINK_PROPERTIES_CHANGED)) {
+                             PhoneConstants.REASON_LINK_PROPERTIES_CHANGED)) {
             if (isTetheringSupported()) {
                 mTethering.handleTetherIfaceChange();
             }
@@ -2489,6 +2490,11 @@
                     //       @see bug/4455071
                     handleConnectivityChange(info.getType(), false);
                     break;
+                case NetworkStateTracker.EVENT_NETWORK_SUBTYPE_CHANGED:
+                    info = (NetworkInfo) msg.obj;
+                    type = info.getType();
+                    updateNetworkSettings(mNetTrackers[type]);
+                    break;
                 case EVENT_CLEAR_NET_TRANSITION_WAKELOCK:
                     String causedBy = null;
                     synchronized (ConnectivityService.this) {
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index 7609613..ea19d6e 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -1691,6 +1691,7 @@
         // Note: we can only do the wipe via ExternalStorageFormatter if the volume is not emulated.
         if ((forceExtWipe || wipeExtRequested) && !Environment.isExternalStorageEmulated()) {
             Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET);
+            intent.putExtra(ExternalStorageFormatter.EXTRA_ALWAYS_RESET, true);
             intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
             mWakeLock.acquire(10000);
             mContext.startService(intent);
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 1482d22..04267a3 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -1221,6 +1221,7 @@
             for(MountServiceBinderListener bl : mListeners) {
                 if (bl.mListener == listener) {
                     mListeners.remove(mListeners.indexOf(bl));
+                    listener.asBinder().unlinkToDeath(bl, 0);
                     return;
                 }
             }
diff --git a/services/java/com/android/server/NsdService.java b/services/java/com/android/server/NsdService.java
index 6ad8bd0..87843d9 100644
--- a/services/java/com/android/server/NsdService.java
+++ b/services/java/com/android/server/NsdService.java
@@ -110,8 +110,8 @@
         private final EnabledState mEnabledState = new EnabledState();
 
         @Override
-        protected String getMessageInfo(Message msg) {
-            return cmdToString(msg.what);
+        protected String getWhatToString(int what) {
+            return cmdToString(what);
         }
 
         /**
@@ -144,7 +144,7 @@
             } else {
                 setInitialState(mDisabledState);
             }
-            setProcessedMessagesSize(25);
+            setLogRecSize(25);
             registerForNsdSetting();
         }
 
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 24c59a5..888ec69 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -1165,6 +1165,8 @@
                         ? "SCREEN_BRIGHT_BIT " : "")
                 + (((state & SCREEN_ON_BIT) != 0)
                         ? "SCREEN_ON_BIT " : "")
+                + (((state & BUTTON_BRIGHT_BIT) != 0)
+                        ? "BUTTON_BRIGHT_BIT " : "")
                 + (((state & BATTERY_LOW_BIT) != 0)
                         ? "BATTERY_LOW_BIT " : "");
     }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 6d0b26f..2676537 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -83,7 +83,7 @@
         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN,
             SystemClock.uptimeMillis());
 
-        Looper.prepare();
+        Looper.prepareMainLooper();
 
         android.os.Process.setThreadPriority(
                 android.os.Process.THREAD_PRIORITY_FOREGROUND);
@@ -693,6 +693,12 @@
             reportWtf("making Vibrator Service ready", e);
         }
 
+        try {
+            lockSettings.systemReady();
+        } catch (Throwable e) {
+            reportWtf("making Lock Settings Service ready", e);
+        }
+
         if (devicePolicy != null) {
             try {
                 devicePolicy.systemReady();
@@ -734,11 +740,6 @@
         } catch (Throwable e) {
             reportWtf("making Package Manager Service ready", e);
         }
-        try {
-            lockSettings.systemReady();
-        } catch (Throwable e) {
-            reportWtf("making Lock Settings Service ready", e);
-        }
 
         // These are needed to propagate to the runnable below.
         final Context contextF = context;
diff --git a/services/java/com/android/server/TelephonyRegistry.java b/services/java/com/android/server/TelephonyRegistry.java
index 1b1638a..c23a1d9 100644
--- a/services/java/com/android/server/TelephonyRegistry.java
+++ b/services/java/com/android/server/TelephonyRegistry.java
@@ -44,6 +44,7 @@
 import com.android.internal.telephony.IPhoneStateListener;
 import com.android.internal.telephony.DefaultPhoneNotifier;
 import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.ServiceStateTracker;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.server.am.BatteryStatsService;
@@ -622,7 +623,8 @@
         }
 
         Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
-        intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertCallState(state).toString());
+        intent.putExtra(PhoneConstants.STATE_KEY,
+                DefaultPhoneNotifier.convertCallState(state).toString());
         if (!TextUtils.isEmpty(incomingNumber)) {
             intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber);
         }
@@ -637,34 +639,35 @@
         // status bar takes care of that after taking into account all of the
         // required info.
         Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
-        intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertDataState(state).toString());
+        intent.putExtra(PhoneConstants.STATE_KEY,
+                DefaultPhoneNotifier.convertDataState(state).toString());
         if (!isDataConnectivityPossible) {
-            intent.putExtra(Phone.NETWORK_UNAVAILABLE_KEY, true);
+            intent.putExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY, true);
         }
         if (reason != null) {
-            intent.putExtra(Phone.STATE_CHANGE_REASON_KEY, reason);
+            intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason);
         }
         if (linkProperties != null) {
-            intent.putExtra(Phone.DATA_LINK_PROPERTIES_KEY, linkProperties);
+            intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties);
             String iface = linkProperties.getInterfaceName();
             if (iface != null) {
-                intent.putExtra(Phone.DATA_IFACE_NAME_KEY, iface);
+                intent.putExtra(PhoneConstants.DATA_IFACE_NAME_KEY, iface);
             }
         }
         if (linkCapabilities != null) {
-            intent.putExtra(Phone.DATA_LINK_CAPABILITIES_KEY, linkCapabilities);
+            intent.putExtra(PhoneConstants.DATA_LINK_CAPABILITIES_KEY, linkCapabilities);
         }
-        if (roaming) intent.putExtra(Phone.DATA_NETWORK_ROAMING_KEY, true);
+        if (roaming) intent.putExtra(PhoneConstants.DATA_NETWORK_ROAMING_KEY, true);
 
-        intent.putExtra(Phone.DATA_APN_KEY, apn);
-        intent.putExtra(Phone.DATA_APN_TYPE_KEY, apnType);
+        intent.putExtra(PhoneConstants.DATA_APN_KEY, apn);
+        intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
         mContext.sendStickyBroadcast(intent);
     }
 
     private void broadcastDataConnectionFailed(String reason, String apnType) {
         Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
-        intent.putExtra(Phone.FAILURE_REASON_KEY, reason);
-        intent.putExtra(Phone.DATA_APN_TYPE_KEY, apnType);
+        intent.putExtra(PhoneConstants.FAILURE_REASON_KEY, reason);
+        intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
         mContext.sendStickyBroadcast(intent);
     }
 
diff --git a/services/java/com/android/server/VibratorService.java b/services/java/com/android/server/VibratorService.java
index b609867..72fde11 100755
--- a/services/java/com/android/server/VibratorService.java
+++ b/services/java/com/android/server/VibratorService.java
@@ -441,7 +441,7 @@
 
         private void delay(long duration) {
             if (duration > 0) {
-                long bedtime = SystemClock.uptimeMillis();
+                long bedtime = duration + SystemClock.uptimeMillis();
                 do {
                     try {
                         this.wait(duration);
@@ -451,8 +451,7 @@
                     if (mDone) {
                         break;
                     }
-                    duration = duration
-                            - SystemClock.uptimeMillis() - bedtime;
+                    duration = bedtime - SystemClock.uptimeMillis();
                 } while (duration > 0);
             }
         }
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index d97d335..8a08277 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -45,6 +45,7 @@
 import android.os.FileObserver;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteCallbackList;
+import android.os.SELinux;
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserId;
@@ -639,8 +640,12 @@
                         FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
                         -1, -1);
             }
-            ParcelFileDescriptor fd = ParcelFileDescriptor.open(new File(dir, WALLPAPER),
+            File file = new File(dir, WALLPAPER);
+            ParcelFileDescriptor fd = ParcelFileDescriptor.open(file,
                     MODE_CREATE|MODE_READ_WRITE);
+            if (!SELinux.restorecon(file)) {
+                return null;
+            }
             wallpaper.name = name;
             return fd;
         } catch (FileNotFoundException e) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 95d3c41..5d74cf3 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -106,6 +106,7 @@
 import android.os.Process;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.os.SELinux;
 import android.os.ServiceManager;
 import android.os.StrictMode;
 import android.os.SystemClock;
@@ -1820,7 +1821,7 @@
                 if (cr.binding != null && cr.binding.service != null
                         && cr.binding.service.app != null
                         && cr.binding.service.app.lruSeq != mLruSeq) {
-                    updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
+                    updateLruProcessInternalLocked(cr.binding.service.app, false,
                             updateActivityTime, i+1);
                 }
             }
@@ -1828,7 +1829,7 @@
         for (int j=app.conProviders.size()-1; j>=0; j--) {
             ContentProviderRecord cpr = app.conProviders.get(j).provider;
             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
-                updateLruProcessInternalLocked(cpr.proc, oomAdj,
+                updateLruProcessInternalLocked(cpr.proc, false,
                         updateActivityTime, i+1);
             }
         }
@@ -2053,7 +2054,7 @@
             // the PID of the new process, or else throw a RuntimeException.
             Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
                     app.processName, uid, uid, gids, debugFlags,
-                    app.info.targetSdkVersion, null);
+                    app.info.targetSdkVersion, null, null);
 
             BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
             synchronized (bs) {
@@ -3032,7 +3033,12 @@
         File tracesFile = new File(tracesPath);
         try {
             File tracesDir = tracesFile.getParentFile();
-            if (!tracesDir.exists()) tracesFile.mkdirs();
+            if (!tracesDir.exists()) {
+                tracesFile.mkdirs();
+                if (!SELinux.restorecon(tracesDir)) {
+                    return null;
+                }
+            }
             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
 
             if (clearTraces && tracesFile.exists()) tracesFile.delete();
@@ -3136,7 +3142,12 @@
             final File tracesDir = tracesFile.getParentFile();
             final File tracesTmp = new File(tracesDir, "__tmp__");
             try {
-                if (!tracesDir.exists()) tracesFile.mkdirs();
+                if (!tracesDir.exists()) {
+                    tracesFile.mkdirs();
+                    if (!SELinux.restorecon(tracesDir.getPath())) {
+                        return;
+                    }
+                }
                 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
 
                 if (tracesFile.exists()) {
@@ -10950,7 +10961,9 @@
                     restart = true;
                 } else {
                     removeDyingProviderLocked(app, cpr, true);
+                    // cpr should have been removed from mLaunchingProviders
                     NL = mLaunchingProviders.size();
+                    i--;
                 }
             }
         }
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 9171e47..b9e63b7 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -2762,7 +2762,8 @@
                         // If the top activity in the task is the root
                         // activity, deliver this new intent to it if it
                         // desires.
-                        if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
+                        if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
+                                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
                                 && taskTop.realActivity.equals(r.realActivity)) {
                             logStartActivity(EventLogTags.AM_NEW_INTENT, r, taskTop.task);
                             if (taskTop.frontOfTask) {
diff --git a/services/java/com/android/server/am/DeviceMonitor.java b/services/java/com/android/server/am/DeviceMonitor.java
index 5f3b0ce..21e7252 100644
--- a/services/java/com/android/server/am/DeviceMonitor.java
+++ b/services/java/com/android/server/am/DeviceMonitor.java
@@ -16,6 +16,7 @@
 
 package com.android.server.am;
 
+import android.os.SELinux;
 import android.util.Slog;
 
 import java.io.*;
@@ -80,6 +81,9 @@
         if (!BASE.isDirectory() && !BASE.mkdirs()) {
             throw new AssertionError("Couldn't create " + BASE + ".");
         }
+        if (!SELinux.restorecon(BASE)) {
+            throw new AssertionError("Couldn't restorecon " + BASE + ".");
+        }
     }
 
     private static final File[] PATHS = {
diff --git a/services/java/com/android/server/am/ProviderMap.java b/services/java/com/android/server/am/ProviderMap.java
index d148ec3..e4608a2 100644
--- a/services/java/com/android/server/am/ProviderMap.java
+++ b/services/java/com/android/server/am/ProviderMap.java
@@ -127,7 +127,12 @@
                 Slog.i(TAG,
                         "Removing from providersByName name=" + name + " user="
                         + (optionalUserId == -1 ? Binder.getOrigCallingUser() : optionalUserId));
-            getProvidersByName(optionalUserId).remove(name);
+            HashMap<String, ContentProviderRecord> map = getProvidersByName(optionalUserId);
+            // map returned by getProvidersByName wouldn't be null
+            map.remove(name);
+            if (map.size() == 0) {
+                mProvidersByNamePerUser.remove(optionalUserId);
+            }
         }
     }
 
@@ -141,7 +146,12 @@
                 Slog.i(TAG,
                         "Removing from providersByClass name=" + name + " user="
                         + (optionalUserId == -1 ? Binder.getOrigCallingUser() : optionalUserId));
-            getProvidersByClass(optionalUserId).remove(name);
+            HashMap<ComponentName, ContentProviderRecord> map = getProvidersByClass(optionalUserId);
+            // map returned by getProvidersByClass wouldn't be null
+            map.remove(name);
+            if (map.size() == 0) {
+                mProvidersByClassPerUser.remove(optionalUserId);
+            }
         }
     }
 
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index 88a0ccb..682ecf8 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -47,6 +47,7 @@
 import android.util.Log;
 
 import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.util.IState;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
@@ -1190,7 +1191,7 @@
                 boolean retValue = true;
                 if (apnType == ConnectivityManager.TYPE_NONE) return false;
                 if (apnType != mMobileApnReserved) turnOffUpstreamMobileConnection();
-                int result = Phone.APN_REQUEST_FAILED;
+                int result = PhoneConstants.APN_REQUEST_FAILED;
                 String enableString = enableString(apnType);
                 if (enableString == null) return false;
                 try {
@@ -1199,14 +1200,14 @@
                 } catch (Exception e) {
                 }
                 switch (result) {
-                case Phone.APN_ALREADY_ACTIVE:
-                case Phone.APN_REQUEST_STARTED:
+                case PhoneConstants.APN_ALREADY_ACTIVE:
+                case PhoneConstants.APN_REQUEST_STARTED:
                     mMobileApnReserved = apnType;
                     Message m = obtainMessage(CMD_CELL_CONNECTION_RENEW);
                     m.arg1 = ++mCurrentConnectionSequence;
                     sendMessageDelayed(m, CELL_CONNECTION_RENEW_MS);
                     break;
-                case Phone.APN_REQUEST_FAILED:
+                case PhoneConstants.APN_REQUEST_FAILED:
                 default:
                     retValue = false;
                     break;
diff --git a/services/java/com/android/server/location/GpsLocationProvider.java b/services/java/com/android/server/location/GpsLocationProvider.java
index ce53499..4ad6140 100755
--- a/services/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/java/com/android/server/location/GpsLocationProvider.java
@@ -60,6 +60,7 @@
 import com.android.internal.location.GpsNetInitiatedHandler;
 import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification;
 import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -1285,8 +1286,8 @@
                 int result = mConnMgr.startUsingNetworkFeature(
                         ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL);
                 mAGpsDataConnectionIpAddr = ipaddr;
-                if (result == Phone.APN_ALREADY_ACTIVE) {
-                    if (DEBUG) Log.d(TAG, "Phone.APN_ALREADY_ACTIVE");
+                if (result == PhoneConstants.APN_ALREADY_ACTIVE) {
+                    if (DEBUG) Log.d(TAG, "PhoneConstants.APN_ALREADY_ACTIVE");
                     if (mAGpsApn != null) {
                         Log.d(TAG, "mAGpsDataConnectionIpAddr " + mAGpsDataConnectionIpAddr);
                         if (mAGpsDataConnectionIpAddr != 0xffffffff) {
@@ -1300,12 +1301,12 @@
                         native_agps_data_conn_open(mAGpsApn);
                         mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN;
                     } else {
-                        Log.e(TAG, "mAGpsApn not set when receiving Phone.APN_ALREADY_ACTIVE");
+                        Log.e(TAG, "mAGpsApn not set when receiving PhoneConstants.APN_ALREADY_ACTIVE");
                         mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED;
                         native_agps_data_conn_failed();
                     }
-                } else if (result == Phone.APN_REQUEST_STARTED) {
-                    if (DEBUG) Log.d(TAG, "Phone.APN_REQUEST_STARTED");
+                } else if (result == PhoneConstants.APN_REQUEST_STARTED) {
+                    if (DEBUG) Log.d(TAG, "PhoneConstants.APN_REQUEST_STARTED");
                     // Nothing to do here
                 } else {
                     if (DEBUG) Log.d(TAG, "startUsingNetworkFeature failed");
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index eb81791..cd7599d 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -96,6 +96,7 @@
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.SELinux;
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.SystemProperties;
@@ -143,6 +144,7 @@
 import libcore.io.ErrnoException;
 import libcore.io.IoUtils;
 import libcore.io.Libcore;
+import libcore.io.StructStat;
 
 /**
  * Keep track of all those .apks everywhere.
@@ -293,8 +295,6 @@
     File mScanningPath;
     int mLastScanError;
 
-    final int[] mOutPermissions = new int[3];
-
     // ----------------------------------------------------------------
 
     // Keys are String (package name), values are Package.  This also serves
@@ -3761,14 +3761,18 @@
             boolean uidError = false;
 
             if (dataPath.exists()) {
-                // XXX should really do this check for each user.
-                mOutPermissions[1] = 0;
-                FileUtils.getPermissions(dataPath.getPath(), mOutPermissions);
+                int currentUid = 0;
+                try {
+                    StructStat stat = Libcore.os.stat(dataPath.getPath());
+                    currentUid = stat.st_uid;
+                } catch (ErrnoException e) {
+                    Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
+                }
 
                 // If we have mismatched owners for the data path, we have a problem.
-                if (mOutPermissions[1] != pkg.applicationInfo.uid) {
+                if (currentUid != pkg.applicationInfo.uid) {
                     boolean recovered = false;
-                    if (mOutPermissions[1] == 0) {
+                    if (currentUid == 0) {
                         // The directory somehow became owned by root.  Wow.
                         // This is probably because the system was stopped while
                         // installd was in the middle of messing with its libs
@@ -3797,7 +3801,7 @@
                                     ? "System package " : "Third party package ";
                             String msg = prefix + pkg.packageName
                                     + " has changed from uid: "
-                                    + mOutPermissions[1] + " to "
+                                    + currentUid + " to "
                                     + pkg.applicationInfo.uid + "; old data erased";
                             reportSettingsProblem(Log.WARN, msg);
                             recovered = true;
@@ -3829,11 +3833,11 @@
                     if (!recovered) {
                         pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
                             + pkg.applicationInfo.uid + "/fs_"
-                            + mOutPermissions[1];
+                            + currentUid;
                         pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
                         String msg = "Package " + pkg.packageName
                                 + " has mismatched uid: "
-                                + mOutPermissions[1] + " on disk, "
+                                + currentUid + " on disk, "
                                 + pkg.applicationInfo.uid + " in settings";
                         // writer
                         synchronized (mPackages) {
@@ -6430,6 +6434,10 @@
                     return false;
                 }
 
+                if (!SELinux.restorecon(newCodeFile)) {
+                    return false;
+                }
+
                 return true;
             }
         }
@@ -7411,6 +7419,9 @@
             FileUtils.setPermissions(
                     tmpPackageFile.getCanonicalPath(), FileUtils.S_IRUSR|FileUtils.S_IWUSR,
                     -1, -1);
+            if (!SELinux.restorecon(tmpPackageFile)) {
+                return null;
+            }
         } catch (IOException e) {
             Slog.e(TAG, "Trouble getting the canoncical path for a temp file.");
             return null;
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index d031686..120b650 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -1241,7 +1241,7 @@
 
                     // Avoid any application that has a space in its path
                     // or that is handled by the system.
-                    if (dataPath.indexOf(" ") >= 0 || ai.uid <= Process.FIRST_APPLICATION_UID)
+                    if (dataPath.indexOf(" ") >= 0 || ai.uid < Process.FIRST_APPLICATION_UID)
                         continue;
 
                     // we store on each line the following information for now:
diff --git a/services/java/com/android/server/pm/ShutdownThread.java b/services/java/com/android/server/pm/ShutdownThread.java
index 69406c8..3675d41 100644
--- a/services/java/com/android/server/pm/ShutdownThread.java
+++ b/services/java/com/android/server/pm/ShutdownThread.java
@@ -84,6 +84,8 @@
     private PowerManager.WakeLock mCpuWakeLock;
     private PowerManager.WakeLock mScreenWakeLock;
     private Handler mHandler;
+
+    private static AlertDialog sConfirmDialog;
     
     private ShutdownThread() {
     }
@@ -124,7 +126,10 @@
 
         if (confirm) {
             final CloseDialogReceiver closer = new CloseDialogReceiver(context);
-            final AlertDialog dialog = new AlertDialog.Builder(context)
+            if (sConfirmDialog != null) {
+                sConfirmDialog.dismiss();
+            }
+            sConfirmDialog = new AlertDialog.Builder(context)
                     .setTitle(mRebootSafeMode
                             ? com.android.internal.R.string.reboot_safemode_title
                             : com.android.internal.R.string.power_off)
@@ -136,10 +141,10 @@
                     })
                     .setNegativeButton(com.android.internal.R.string.no, null)
                     .create();
-            closer.dialog = dialog;
-            dialog.setOnDismissListener(closer);
-            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
-            dialog.show();
+            closer.dialog = sConfirmDialog;
+            sConfirmDialog.setOnDismissListener(closer);
+            sConfirmDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+            sConfirmDialog.show();
         } else {
             beginShutdownSequence(context);
         }
diff --git a/services/java/com/android/server/usb/UsbSettingsManager.java b/services/java/com/android/server/usb/UsbSettingsManager.java
index 7dde340..9b3459b 100644
--- a/services/java/com/android/server/usb/UsbSettingsManager.java
+++ b/services/java/com/android/server/usb/UsbSettingsManager.java
@@ -545,6 +545,10 @@
             defaultPackage = mDevicePreferenceMap.get(new DeviceFilter(device));
         }
 
+        // Send broadcast to running activity with registered intent
+        mContext.sendBroadcast(intent);
+
+        // Start activity with registered intent
         resolveActivity(intent, matches, defaultPackage, device, null);
     }
 
diff --git a/telephony/java/android/telephony/CellBroadcastMessage.java b/telephony/java/android/telephony/CellBroadcastMessage.java
deleted file mode 100644
index 36c238d..0000000
--- a/telephony/java/android/telephony/CellBroadcastMessage.java
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package android.telephony;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.graphics.Typeface;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.provider.Telephony;
-import android.telephony.SmsCbCmasInfo;
-import android.telephony.SmsCbEtwsInfo;
-import android.telephony.SmsCbLocation;
-import android.telephony.SmsCbMessage;
-import android.text.Spannable;
-import android.text.SpannableStringBuilder;
-import android.text.format.DateUtils;
-import android.text.style.StyleSpan;
-
-/**
- * Application wrapper for {@link SmsCbMessage}. This is Parcelable so that
- * decoded broadcast message objects can be passed between running Services.
- * New broadcasts are received by the CellBroadcastReceiver app, which exports
- * the database of previously received broadcasts at "content://cellbroadcasts/".
- * The "android.permission.READ_CELL_BROADCASTS" permission is required to read
- * from the ContentProvider, and writes to the database are not allowed.<p>
- *
- * Use {@link #createFromCursor} to create CellBroadcastMessage objects from rows
- * in the database cursor returned by the ContentProvider.
- *
- * {@hide}
- */
-public class CellBroadcastMessage implements Parcelable {
-
-    /** Identifier for getExtra() when adding this object to an Intent. */
-    public static final String SMS_CB_MESSAGE_EXTRA =
-            "com.android.cellbroadcastreceiver.SMS_CB_MESSAGE";
-
-    /** SmsCbMessage. */
-    private final SmsCbMessage mSmsCbMessage;
-
-    private final long mDeliveryTime;
-    private boolean mIsRead;
-
-    public CellBroadcastMessage(SmsCbMessage message) {
-        mSmsCbMessage = message;
-        mDeliveryTime = System.currentTimeMillis();
-        mIsRead = false;
-    }
-
-    private CellBroadcastMessage(SmsCbMessage message, long deliveryTime, boolean isRead) {
-        mSmsCbMessage = message;
-        mDeliveryTime = deliveryTime;
-        mIsRead = isRead;
-    }
-
-    private CellBroadcastMessage(Parcel in) {
-        mSmsCbMessage = new SmsCbMessage(in);
-        mDeliveryTime = in.readLong();
-        mIsRead = (in.readInt() != 0);
-    }
-
-    /** Parcelable: no special flags. */
-    public int describeContents() {
-        return 0;
-    }
-
-    public void writeToParcel(Parcel out, int flags) {
-        mSmsCbMessage.writeToParcel(out, flags);
-        out.writeLong(mDeliveryTime);
-        out.writeInt(mIsRead ? 1 : 0);
-    }
-
-    public static final Parcelable.Creator<CellBroadcastMessage> CREATOR
-            = new Parcelable.Creator<CellBroadcastMessage>() {
-        public CellBroadcastMessage createFromParcel(Parcel in) {
-            return new CellBroadcastMessage(in);
-        }
-
-        public CellBroadcastMessage[] newArray(int size) {
-            return new CellBroadcastMessage[size];
-        }
-    };
-
-    /**
-     * Create a CellBroadcastMessage from a row in the database.
-     * @param cursor an open SQLite cursor pointing to the row to read
-     * @return the new CellBroadcastMessage
-     * @throws IllegalArgumentException if one of the required columns is missing
-     */
-    public static CellBroadcastMessage createFromCursor(Cursor cursor) {
-        int geoScope = cursor.getInt(
-                cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.GEOGRAPHICAL_SCOPE));
-        int serialNum = cursor.getInt(
-                cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.SERIAL_NUMBER));
-        int category = cursor.getInt(
-                cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.SERVICE_CATEGORY));
-        String language = cursor.getString(
-                cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.LANGUAGE_CODE));
-        String body = cursor.getString(
-                cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.MESSAGE_BODY));
-        int format = cursor.getInt(
-                cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.MESSAGE_FORMAT));
-        int priority = cursor.getInt(
-                cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.MESSAGE_PRIORITY));
-
-        String plmn;
-        int plmnColumn = cursor.getColumnIndex(Telephony.CellBroadcasts.PLMN);
-        if (plmnColumn != -1 && !cursor.isNull(plmnColumn)) {
-            plmn = cursor.getString(plmnColumn);
-        } else {
-            plmn = null;
-        }
-
-        int lac;
-        int lacColumn = cursor.getColumnIndex(Telephony.CellBroadcasts.LAC);
-        if (lacColumn != -1 && !cursor.isNull(lacColumn)) {
-            lac = cursor.getInt(lacColumn);
-        } else {
-            lac = -1;
-        }
-
-        int cid;
-        int cidColumn = cursor.getColumnIndex(Telephony.CellBroadcasts.CID);
-        if (cidColumn != -1 && !cursor.isNull(cidColumn)) {
-            cid = cursor.getInt(cidColumn);
-        } else {
-            cid = -1;
-        }
-
-        SmsCbLocation location = new SmsCbLocation(plmn, lac, cid);
-
-        SmsCbEtwsInfo etwsInfo;
-        int etwsWarningTypeColumn = cursor.getColumnIndex(
-                Telephony.CellBroadcasts.ETWS_WARNING_TYPE);
-        if (etwsWarningTypeColumn != -1 && !cursor.isNull(etwsWarningTypeColumn)) {
-            int warningType = cursor.getInt(etwsWarningTypeColumn);
-            etwsInfo = new SmsCbEtwsInfo(warningType, false, false, null);
-        } else {
-            etwsInfo = null;
-        }
-
-        SmsCbCmasInfo cmasInfo;
-        int cmasMessageClassColumn = cursor.getColumnIndex(
-                Telephony.CellBroadcasts.CMAS_MESSAGE_CLASS);
-        if (cmasMessageClassColumn != -1 && !cursor.isNull(cmasMessageClassColumn)) {
-            int messageClass = cursor.getInt(cmasMessageClassColumn);
-
-            int cmasCategory;
-            int cmasCategoryColumn = cursor.getColumnIndex(
-                    Telephony.CellBroadcasts.CMAS_CATEGORY);
-            if (cmasCategoryColumn != -1 && !cursor.isNull(cmasCategoryColumn)) {
-                cmasCategory = cursor.getInt(cmasCategoryColumn);
-            } else {
-                cmasCategory = SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN;
-            }
-
-            int responseType;
-            int cmasResponseTypeColumn = cursor.getColumnIndex(
-                    Telephony.CellBroadcasts.CMAS_RESPONSE_TYPE);
-            if (cmasResponseTypeColumn != -1 && !cursor.isNull(cmasResponseTypeColumn)) {
-                responseType = cursor.getInt(cmasResponseTypeColumn);
-            } else {
-                responseType = SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN;
-            }
-
-            int severity;
-            int cmasSeverityColumn = cursor.getColumnIndex(
-                    Telephony.CellBroadcasts.CMAS_SEVERITY);
-            if (cmasSeverityColumn != -1 && !cursor.isNull(cmasSeverityColumn)) {
-                severity = cursor.getInt(cmasSeverityColumn);
-            } else {
-                severity = SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN;
-            }
-
-            int urgency;
-            int cmasUrgencyColumn = cursor.getColumnIndex(
-                    Telephony.CellBroadcasts.CMAS_URGENCY);
-            if (cmasUrgencyColumn != -1 && !cursor.isNull(cmasUrgencyColumn)) {
-                urgency = cursor.getInt(cmasUrgencyColumn);
-            } else {
-                urgency = SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN;
-            }
-
-            int certainty;
-            int cmasCertaintyColumn = cursor.getColumnIndex(
-                    Telephony.CellBroadcasts.CMAS_CERTAINTY);
-            if (cmasCertaintyColumn != -1 && !cursor.isNull(cmasCertaintyColumn)) {
-                certainty = cursor.getInt(cmasCertaintyColumn);
-            } else {
-                certainty = SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN;
-            }
-
-            cmasInfo = new SmsCbCmasInfo(messageClass, cmasCategory, responseType, severity,
-                    urgency, certainty);
-        } else {
-            cmasInfo = null;
-        }
-
-        SmsCbMessage msg = new SmsCbMessage(format, geoScope, serialNum, location, category,
-                language, body, priority, etwsInfo, cmasInfo);
-
-        long deliveryTime = cursor.getLong(cursor.getColumnIndexOrThrow(
-                Telephony.CellBroadcasts.DELIVERY_TIME));
-        boolean isRead = (cursor.getInt(cursor.getColumnIndexOrThrow(
-                Telephony.CellBroadcasts.MESSAGE_READ)) != 0);
-
-        return new CellBroadcastMessage(msg, deliveryTime, isRead);
-    }
-
-    /**
-     * Return a ContentValues object for insertion into the database.
-     * @return a new ContentValues object containing this object's data
-     */
-    public ContentValues getContentValues() {
-        ContentValues cv = new ContentValues(16);
-        SmsCbMessage msg = mSmsCbMessage;
-        cv.put(Telephony.CellBroadcasts.GEOGRAPHICAL_SCOPE, msg.getGeographicalScope());
-        SmsCbLocation location = msg.getLocation();
-        if (location.getPlmn() != null) {
-            cv.put(Telephony.CellBroadcasts.PLMN, location.getPlmn());
-        }
-        if (location.getLac() != -1) {
-            cv.put(Telephony.CellBroadcasts.LAC, location.getLac());
-        }
-        if (location.getCid() != -1) {
-            cv.put(Telephony.CellBroadcasts.CID, location.getCid());
-        }
-        cv.put(Telephony.CellBroadcasts.SERIAL_NUMBER, msg.getSerialNumber());
-        cv.put(Telephony.CellBroadcasts.SERVICE_CATEGORY, msg.getServiceCategory());
-        cv.put(Telephony.CellBroadcasts.LANGUAGE_CODE, msg.getLanguageCode());
-        cv.put(Telephony.CellBroadcasts.MESSAGE_BODY, msg.getMessageBody());
-        cv.put(Telephony.CellBroadcasts.DELIVERY_TIME, mDeliveryTime);
-        cv.put(Telephony.CellBroadcasts.MESSAGE_READ, mIsRead);
-        cv.put(Telephony.CellBroadcasts.MESSAGE_FORMAT, msg.getMessageFormat());
-        cv.put(Telephony.CellBroadcasts.MESSAGE_PRIORITY, msg.getMessagePriority());
-
-        SmsCbEtwsInfo etwsInfo = mSmsCbMessage.getEtwsWarningInfo();
-        if (etwsInfo != null) {
-            cv.put(Telephony.CellBroadcasts.ETWS_WARNING_TYPE, etwsInfo.getWarningType());
-        }
-
-        SmsCbCmasInfo cmasInfo = mSmsCbMessage.getCmasWarningInfo();
-        if (cmasInfo != null) {
-            cv.put(Telephony.CellBroadcasts.CMAS_MESSAGE_CLASS, cmasInfo.getMessageClass());
-            cv.put(Telephony.CellBroadcasts.CMAS_CATEGORY, cmasInfo.getCategory());
-            cv.put(Telephony.CellBroadcasts.CMAS_RESPONSE_TYPE, cmasInfo.getResponseType());
-            cv.put(Telephony.CellBroadcasts.CMAS_SEVERITY, cmasInfo.getSeverity());
-            cv.put(Telephony.CellBroadcasts.CMAS_URGENCY, cmasInfo.getUrgency());
-            cv.put(Telephony.CellBroadcasts.CMAS_CERTAINTY, cmasInfo.getCertainty());
-        }
-
-        return cv;
-    }
-
-    /**
-     * Set or clear the "read message" flag.
-     * @param isRead true if the message has been read; false if not
-     */
-    public void setIsRead(boolean isRead) {
-        mIsRead = isRead;
-    }
-
-    public String getLanguageCode() {
-        return mSmsCbMessage.getLanguageCode();
-    }
-
-    public int getServiceCategory() {
-        return mSmsCbMessage.getServiceCategory();
-    }
-
-    public long getDeliveryTime() {
-        return mDeliveryTime;
-    }
-
-    public String getMessageBody() {
-        return mSmsCbMessage.getMessageBody();
-    }
-
-    public boolean isRead() {
-        return mIsRead;
-    }
-
-    public int getSerialNumber() {
-        return mSmsCbMessage.getSerialNumber();
-    }
-
-    public SmsCbCmasInfo getCmasWarningInfo() {
-        return mSmsCbMessage.getCmasWarningInfo();
-    }
-
-    public SmsCbEtwsInfo getEtwsWarningInfo() {
-        return mSmsCbMessage.getEtwsWarningInfo();
-    }
-
-    /**
-     * Return whether the broadcast is an emergency (PWS) message type.
-     * This includes lower priority test messages and Amber alerts.
-     *
-     * All public alerts show the flashing warning icon in the dialog,
-     * but only emergency alerts play the alert sound and speak the message.
-     *
-     * @return true if the message is PWS type; false otherwise
-     */
-    public boolean isPublicAlertMessage() {
-        return mSmsCbMessage.isEmergencyMessage();
-    }
-
-    /**
-     * Returns whether the broadcast is an emergency (PWS) message type,
-     * including test messages, but excluding lower priority Amber alert broadcasts.
-     *
-     * @return true if the message is PWS type, excluding Amber alerts
-     */
-    public boolean isEmergencyAlertMessage() {
-        if (!mSmsCbMessage.isEmergencyMessage()) {
-            return false;
-        }
-        SmsCbCmasInfo cmasInfo = mSmsCbMessage.getCmasWarningInfo();
-        if (cmasInfo != null &&
-                cmasInfo.getMessageClass() == SmsCbCmasInfo.CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Return whether the broadcast is an ETWS emergency message type.
-     * @return true if the message is ETWS emergency type; false otherwise
-     */
-    public boolean isEtwsMessage() {
-        return mSmsCbMessage.isEtwsMessage();
-    }
-
-    /**
-     * Return whether the broadcast is a CMAS emergency message type.
-     * @return true if the message is CMAS emergency type; false otherwise
-     */
-    public boolean isCmasMessage() {
-        return mSmsCbMessage.isCmasMessage();
-    }
-
-    /**
-     * Return the CMAS message class.
-     * @return the CMAS message class, e.g. {@link SmsCbCmasInfo#CMAS_CLASS_SEVERE_THREAT}, or
-     *  {@link SmsCbCmasInfo#CMAS_CLASS_UNKNOWN} if this is not a CMAS alert
-     */
-    public int getCmasMessageClass() {
-        if (mSmsCbMessage.isCmasMessage()) {
-            return mSmsCbMessage.getCmasWarningInfo().getMessageClass();
-        } else {
-            return SmsCbCmasInfo.CMAS_CLASS_UNKNOWN;
-        }
-    }
-
-    /**
-     * Return whether the broadcast is an ETWS popup alert.
-     * This method checks the message ID and the message code.
-     * @return true if the message indicates an ETWS popup alert
-     */
-    public boolean isEtwsPopupAlert() {
-        SmsCbEtwsInfo etwsInfo = mSmsCbMessage.getEtwsWarningInfo();
-        return etwsInfo != null && etwsInfo.isPopupAlert();
-    }
-
-    /**
-     * Return whether the broadcast is an ETWS emergency user alert.
-     * This method checks the message ID and the message code.
-     * @return true if the message indicates an ETWS emergency user alert
-     */
-    public boolean isEtwsEmergencyUserAlert() {
-        SmsCbEtwsInfo etwsInfo = mSmsCbMessage.getEtwsWarningInfo();
-        return etwsInfo != null && etwsInfo.isEmergencyUserAlert();
-    }
-
-    /**
-     * Return whether the broadcast is an ETWS test message.
-     * @return true if the message is an ETWS test message; false otherwise
-     */
-    public boolean isEtwsTestMessage() {
-        SmsCbEtwsInfo etwsInfo = mSmsCbMessage.getEtwsWarningInfo();
-        return etwsInfo != null &&
-                etwsInfo.getWarningType() == SmsCbEtwsInfo.ETWS_WARNING_TYPE_TEST_MESSAGE;
-    }
-
-    /**
-     * Return the abbreviated date string for the message delivery time.
-     * @param context the context object
-     * @return a String to use in the broadcast list UI
-     */
-    public String getDateString(Context context) {
-        int flags = DateUtils.FORMAT_NO_NOON_MIDNIGHT | DateUtils.FORMAT_SHOW_TIME |
-                DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_DATE |
-                DateUtils.FORMAT_CAP_AMPM;
-        return DateUtils.formatDateTime(context, mDeliveryTime, flags);
-    }
-
-    /**
-     * Return the date string for the message delivery time, suitable for text-to-speech.
-     * @param context the context object
-     * @return a String for populating the list item AccessibilityEvent for TTS
-     */
-    public String getSpokenDateString(Context context) {
-        int flags = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE;
-        return DateUtils.formatDateTime(context, mDeliveryTime, flags);
-    }
-}
diff --git a/telephony/java/android/telephony/CellLocation.java b/telephony/java/android/telephony/CellLocation.java
index 5eaa5a0..42c2aff 100644
--- a/telephony/java/android/telephony/CellLocation.java
+++ b/telephony/java/android/telephony/CellLocation.java
@@ -26,7 +26,7 @@
 import android.telephony.cdma.CdmaCellLocation;
 import android.telephony.gsm.GsmCellLocation;
 import com.android.internal.telephony.ITelephony;
-import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
 
 /**
  * Abstract class that represents the location of the device.  {@more}
@@ -64,9 +64,9 @@
         // TelephonyManager.getDefault().getCurrentPhoneType() handles the case when
         // ITelephony interface is not up yet.
         switch(TelephonyManager.getDefault().getCurrentPhoneType()) {
-        case Phone.PHONE_TYPE_CDMA:
+        case PhoneConstants.PHONE_TYPE_CDMA:
             return new CdmaCellLocation(bundle);
-        case Phone.PHONE_TYPE_GSM:
+        case PhoneConstants.PHONE_TYPE_GSM:
             return new GsmCellLocation(bundle);
         default:
             return null;
@@ -92,9 +92,9 @@
         // TelephonyManager.getDefault().getCurrentPhoneType() handles the case when
         // ITelephony interface is not up yet.
         switch(TelephonyManager.getDefault().getCurrentPhoneType()) {
-        case Phone.PHONE_TYPE_CDMA:
+        case PhoneConstants.PHONE_TYPE_CDMA:
             return new CdmaCellLocation();
-        case Phone.PHONE_TYPE_GSM:
+        case PhoneConstants.PHONE_TYPE_GSM:
             return new GsmCellLocation();
         default:
             return null;
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index 698206c..def6939 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -26,7 +26,6 @@
 import android.util.Log;
 
 import com.android.internal.telephony.IPhoneStateListener;
-import com.android.internal.telephony.Phone;
 
 /**
  * A listener class for monitoring changes in specific telephony states
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
old mode 100644
new mode 100755
index 1049669..92b889b
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -48,7 +48,8 @@
     };
 
     /** @hide */
-    public static final int INVALID_SNR = 0x7FFFFFFF;
+    //Use int max, as -1 is a valid value in signal strength
+    public static final int INVALID = 0x7FFFFFFF;
 
     private int mGsmSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5
     private int mGsmBitErrorRate;   // bit error rate (0-7, 99) as defined in TS 27.007 8.5
@@ -64,7 +65,6 @@
     private int mLteCqi;
 
     private boolean isGsm; // This value is set by the ServiceStateTracker onSignalStrengthResult
-
     /**
      * Create a new SignalStrength from a intent notifier Bundle
      *
@@ -96,15 +96,39 @@
         mEvdoDbm = -1;
         mEvdoEcio = -1;
         mEvdoSnr = -1;
-        mLteSignalStrength = -1;
-        mLteRsrp = -1;
-        mLteRsrq = -1;
-        mLteRssnr = INVALID_SNR;
-        mLteCqi = -1;
+        mLteSignalStrength = 99;
+        mLteRsrp = INVALID;
+        mLteRsrq = INVALID;
+        mLteRssnr = INVALID;
+        mLteCqi = INVALID;
         isGsm = true;
     }
 
     /**
+     * This constructor is used to create SignalStrength with default
+     * values and set the isGsmFlag with the value passed in the input
+     *
+     * @param gsmFlag true if Gsm Phone,false if Cdma phone
+     * @return newly created SignalStrength
+     * @hide
+     */
+    public SignalStrength(boolean gsmFlag) {
+        mGsmSignalStrength = 99;
+        mGsmBitErrorRate = -1;
+        mCdmaDbm = -1;
+        mCdmaEcio = -1;
+        mEvdoDbm = -1;
+        mEvdoEcio = -1;
+        mEvdoSnr = -1;
+        mLteSignalStrength = 99;
+        mLteRsrp = INVALID;
+        mLteRsrq = INVALID;
+        mLteRssnr = INVALID;
+        mLteCqi = INVALID;
+        isGsm = gsmFlag;
+    }
+
+    /**
      * Constructor
      *
      * @hide
@@ -138,9 +162,8 @@
             int cdmaDbm, int cdmaEcio,
             int evdoDbm, int evdoEcio, int evdoSnr,
             boolean gsm) {
-        this(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
-                evdoDbm, evdoEcio, evdoSnr, -1, -1,
-                -1, INVALID_SNR, -1, gsm);
+         this(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio, evdoDbm, evdoEcio, evdoSnr, 99,
+                INVALID, INVALID, INVALID, INVALID, gsm);
     }
 
     /**
@@ -236,7 +259,54 @@
     };
 
     /**
-     * Get the GSM Signal Strength, valid values are (0-31, 99) as defined in TS 27.007 8.5
+     * Validate the individual signal strength fields as per the range
+     * specified in ril.h
+     * Set to invalid any field that is not in the valid range
+     * Cdma, evdo, lte rsrp & rsrq values are sign converted
+     * when received from ril interface
+     *
+     * @return
+     *      Valid values for all signalstrength fields
+     * @hide
+     */
+    public void validateInput() {
+        if (DBG) log("Signal before validate=" + this);
+        // TS 27.007 8.5
+        mGsmSignalStrength = mGsmSignalStrength >= 0 ? mGsmSignalStrength : 99;
+        // BER no change;
+
+        mCdmaDbm = mCdmaDbm > 0 ? -mCdmaDbm : -120;
+        mCdmaEcio = (mCdmaEcio > 0) ? -mCdmaEcio : -160;
+
+        mEvdoDbm = (mEvdoDbm > 0) ? -mEvdoDbm : -120;
+        mEvdoEcio = (mEvdoEcio > 0) ? -mEvdoEcio : -1;
+        mEvdoSnr = ((mEvdoSnr > 0) && (mEvdoSnr <= 8)) ? mEvdoSnr : -1;
+
+        // TS 36.214 Physical Layer Section 5.1.3, TS 36.331 RRC
+        mLteSignalStrength = (mLteSignalStrength >= 0) ? mLteSignalStrength : 99;
+        mLteRsrp = ((mLteRsrp >= 44) && (mLteRsrp <= 140)) ? -mLteRsrp : SignalStrength.INVALID;
+        mLteRsrq = ((mLteRsrq >= 3) && (mLteRsrq <= 20)) ? -mLteRsrq : SignalStrength.INVALID;
+        mLteRssnr = ((mLteRssnr >= -200) && (mLteRssnr <= 300)) ? mLteRssnr
+                : SignalStrength.INVALID;
+        // Cqi no change
+        if (DBG) log("Signal after validate=" + this);
+    }
+
+    /**
+     * @param true - Gsm, Lte phones
+     *        false - Cdma phones
+     *
+     * Used by voice phone to set the isGsm
+     *        flag
+     * @hide
+     */
+    public void setGsm(boolean gsmFlag) {
+        isGsm = gsmFlag;
+    }
+
+    /**
+     * Get the GSM Signal Strength, valid values are (0-31, 99) as defined in TS
+     * 27.007 8.5
      */
     public int getGsmSignalStrength() {
         return this.mGsmSignalStrength;
@@ -293,25 +363,19 @@
         int level;
 
         if (isGsm) {
-            // TODO Need solve the discrepancy of invalid values between
-            // RIL_LTE_SignalStrength and here.
-            if ((mLteSignalStrength == -1)
-                    && (mLteRsrp == -1)
-                    && (mLteRsrq == -1)
-                    && (mLteCqi == -1)) {
+            level = getLteLevel();
+            if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
                 level = getGsmLevel();
-            } else {
-                level = getLteLevel();
             }
         } else {
             int cdmaLevel = getCdmaLevel();
             int evdoLevel = getEvdoLevel();
             if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
                 /* We don't know evdo, use cdma */
-                level = getCdmaLevel();
+                level = cdmaLevel;
             } else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
                 /* We don't know cdma, use evdo */
-                level = getEvdoLevel();
+                level = evdoLevel;
             } else {
                 /* We know both, use the lowest level */
                 level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel;
@@ -329,10 +393,7 @@
     public int getAsuLevel() {
         int asuLevel;
         if (isGsm) {
-            if ((mLteSignalStrength == -1)
-                    && (mLteRsrp == -1)
-                    && (mLteRsrq == -1)
-                    && (mLteCqi == -1)) {
+            if (getLteLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
                 asuLevel = getGsmAsuLevel();
             } else {
                 asuLevel = getLteAsuLevel();
@@ -364,16 +425,17 @@
         int dBm;
 
         if(isGsm()) {
-            if ((mLteSignalStrength == -1)
-                    && (mLteRsrp == -1)
-                    && (mLteRsrq == -1)
-                    && (mLteCqi == -1)) {
+            if (getLteLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
                 dBm = getGsmDbm();
             } else {
                 dBm = getLteDbm();
             }
         } else {
-            dBm = getCdmaDbm();
+            int cdmaDbm = getCdmaDbm();
+            int evdoDbm = getEvdoDbm();
+
+            return (evdoDbm == -120) ? cdmaDbm : ((cdmaDbm == -120) ? evdoDbm
+                    : (cdmaDbm < evdoDbm ? cdmaDbm : evdoDbm));
         }
         if (DBG) log("getDbm=" + dBm);
         return dBm;
@@ -568,34 +630,63 @@
      * @hide
      */
     public int getLteLevel() {
-        int levelLteRsrp = 0;
-        int levelLteRssnr = 0;
+        /*
+         * TS 36.214 Physical Layer Section 5.1.3 TS 36.331 RRC RSSI = received
+         * signal + noise RSRP = reference signal dBm RSRQ = quality of signal
+         * dB= Number of Resource blocksxRSRP/RSSI SNR = gain=signal/noise ratio
+         * = -10log P1/P2 dB
+         */
+        int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, rsrpIconLevel = -1, snrIconLevel = -1;
 
-        if (mLteRsrp == -1) levelLteRsrp = 0;
-        else if (mLteRsrp >= -95) levelLteRsrp = SIGNAL_STRENGTH_GREAT;
-        else if (mLteRsrp >= -105) levelLteRsrp = SIGNAL_STRENGTH_GOOD;
-        else if (mLteRsrp >= -115) levelLteRsrp = SIGNAL_STRENGTH_MODERATE;
-        else levelLteRsrp = SIGNAL_STRENGTH_POOR;
+        if (mLteRsrp > -44) rsrpIconLevel = -1;
+        else if (mLteRsrp >= -85) rsrpIconLevel = SIGNAL_STRENGTH_GREAT;
+        else if (mLteRsrp >= -95) rsrpIconLevel = SIGNAL_STRENGTH_GOOD;
+        else if (mLteRsrp >= -105) rsrpIconLevel = SIGNAL_STRENGTH_MODERATE;
+        else if (mLteRsrp >= -115) rsrpIconLevel = SIGNAL_STRENGTH_POOR;
+        else if (mLteRsrp >= -140) rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
 
-        if (mLteRssnr == INVALID_SNR) levelLteRssnr = 0;
-        else if (mLteRssnr >= 45) levelLteRssnr = SIGNAL_STRENGTH_GREAT;
-        else if (mLteRssnr >= 10) levelLteRssnr = SIGNAL_STRENGTH_GOOD;
-        else if (mLteRssnr >= -30) levelLteRssnr = SIGNAL_STRENGTH_MODERATE;
-        else levelLteRssnr = SIGNAL_STRENGTH_POOR;
+        /*
+         * Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5
+         * dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars
+         * -3.0 dB <= RS_SNR < 1.0 dB 1 bar RS_SNR < -3.0 dB/No Service Antenna
+         * Icon Only
+         */
+        if (mLteRssnr > 300) snrIconLevel = -1;
+        else if (mLteRssnr >= 130) snrIconLevel = SIGNAL_STRENGTH_GREAT;
+        else if (mLteRssnr >= 45) snrIconLevel = SIGNAL_STRENGTH_GOOD;
+        else if (mLteRssnr >= 10) snrIconLevel = SIGNAL_STRENGTH_MODERATE;
+        else if (mLteRssnr >= -30) snrIconLevel = SIGNAL_STRENGTH_POOR;
+        else if (mLteRssnr >= -200)
+            snrIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
 
-        int level;
-        if (mLteRsrp == -1)
-            level = levelLteRssnr;
-        else if (mLteRssnr == INVALID_SNR)
-            level = levelLteRsrp;
-        else
-            level = (levelLteRssnr < levelLteRsrp) ? levelLteRssnr : levelLteRsrp;
+        if (DBG) log("getLTELevel - rsrp:" + mLteRsrp + " snr:" + mLteRssnr + " rsrpIconLevel:"
+                + rsrpIconLevel + " snrIconLevel:" + snrIconLevel);
 
-        if (DBG) log("Lte rsrp level: "+levelLteRsrp
-                + " snr level: " + levelLteRssnr + " level: " + level);
-        return level;
+        /* Choose a measurement type to use for notification */
+        if (snrIconLevel != -1 && rsrpIconLevel != -1) {
+            /*
+             * The number of bars displayed shall be the smaller of the bars
+             * associated with LTE RSRP and the bars associated with the LTE
+             * RS_SNR
+             */
+            return (rsrpIconLevel < snrIconLevel ? rsrpIconLevel : snrIconLevel);
+        }
+
+        if (snrIconLevel != -1) return snrIconLevel;
+
+        if (rsrpIconLevel != -1) return rsrpIconLevel;
+
+        /* Valid values are (0-63, 99) as defined in TS 36.331 */
+        if (mLteSignalStrength > 63) rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+        else if (mLteSignalStrength >= 12) rssiIconLevel = SIGNAL_STRENGTH_GREAT;
+        else if (mLteSignalStrength >= 8) rssiIconLevel = SIGNAL_STRENGTH_GOOD;
+        else if (mLteSignalStrength >= 5) rssiIconLevel = SIGNAL_STRENGTH_MODERATE;
+        else if (mLteSignalStrength >= 0) rssiIconLevel = SIGNAL_STRENGTH_POOR;
+        if (DBG) log("getLTELevel - rssi:" + mLteSignalStrength + " rssiIconLevel:"
+                + rssiIconLevel);
+        return rssiIconLevel;
+
     }
-
     /**
      * Get the LTE signal level as an asu value between 0..97, 99 is unknown
      * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
@@ -605,8 +696,20 @@
     public int getLteAsuLevel() {
         int lteAsuLevel = 99;
         int lteDbm = getLteDbm();
-        if (lteDbm <= -140) lteAsuLevel = 0;
-        else if (lteDbm >= -43) lteAsuLevel = 97;
+        /*
+         * 3GPP 27.007 (Ver 10.3.0) Sec 8.69
+         * 0   -140 dBm or less
+         * 1   -139 dBm
+         * 2...96  -138... -44 dBm
+         * 97  -43 dBm or greater
+         * 255 not known or not detectable
+         */
+        /*
+         * validateInput will always give a valid range between -140 t0 -44 as
+         * per ril.h. so RSRP >= -43 & <-140 will fall under asu level 255
+         * and not 97 or 0
+         */
+        if (lteDbm == SignalStrength.INVALID) lteAsuLevel = 255;
         else lteAsuLevel = lteDbm + 140;
         if (DBG) log("Lte Asu level: "+lteAsuLevel);
         return lteAsuLevel;
diff --git a/telephony/java/android/telephony/SmsCbCmasInfo.java b/telephony/java/android/telephony/SmsCbCmasInfo.java
deleted file mode 100644
index 7a89d94..0000000
--- a/telephony/java/android/telephony/SmsCbCmasInfo.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Contains CMAS warning notification Type 1 elements for a {@link SmsCbMessage}.
- * Supported values for each element are defined in TIA-1149-0-1 (CMAS over CDMA) and
- * 3GPP TS 23.041 (for GSM/UMTS).
- *
- * {@hide}
- */
-public class SmsCbCmasInfo implements Parcelable {
-
-    // CMAS message class (in GSM/UMTS message identifier or CDMA service category).
-
-    /** Presidential-level alert (Korean Public Alert System Class 0 message). */
-    public static final int CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT = 0x00;
-
-    /** Extreme threat to life and property (Korean Public Alert System Class 1 message). */
-    public static final int CMAS_CLASS_EXTREME_THREAT = 0x01;
-
-    /** Severe threat to life and property (Korean Public Alert System Class 1 message). */
-    public static final int CMAS_CLASS_SEVERE_THREAT = 0x02;
-
-    /** Child abduction emergency (AMBER Alert). */
-    public static final int CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY = 0x03;
-
-    /** CMAS test message. */
-    public static final int CMAS_CLASS_REQUIRED_MONTHLY_TEST = 0x04;
-
-    /** CMAS exercise. */
-    public static final int CMAS_CLASS_CMAS_EXERCISE = 0x05;
-
-    /** CMAS category for operator defined use. */
-    public static final int CMAS_CLASS_OPERATOR_DEFINED_USE = 0x06;
-
-    /** CMAS category for warning types that are reserved for future extension. */
-    public static final int CMAS_CLASS_UNKNOWN = -1;
-
-    // CMAS alert category (in CDMA type 1 elements record).
-
-    /** CMAS alert category: Geophysical including landslide. */
-    public static final int CMAS_CATEGORY_GEO = 0x00;
-
-    /** CMAS alert category: Meteorological including flood. */
-    public static final int CMAS_CATEGORY_MET = 0x01;
-
-    /** CMAS alert category: General emergency and public safety. */
-    public static final int CMAS_CATEGORY_SAFETY = 0x02;
-
-    /** CMAS alert category: Law enforcement, military, homeland/local/private security. */
-    public static final int CMAS_CATEGORY_SECURITY = 0x03;
-
-    /** CMAS alert category: Rescue and recovery. */
-    public static final int CMAS_CATEGORY_RESCUE = 0x04;
-
-    /** CMAS alert category: Fire suppression and rescue. */
-    public static final int CMAS_CATEGORY_FIRE = 0x05;
-
-    /** CMAS alert category: Medical and public health. */
-    public static final int CMAS_CATEGORY_HEALTH = 0x06;
-
-    /** CMAS alert category: Pollution and other environmental. */
-    public static final int CMAS_CATEGORY_ENV = 0x07;
-
-    /** CMAS alert category: Public and private transportation. */
-    public static final int CMAS_CATEGORY_TRANSPORT = 0x08;
-
-    /** CMAS alert category: Utility, telecom, other non-transport infrastructure. */
-    public static final int CMAS_CATEGORY_INFRA = 0x09;
-
-    /** CMAS alert category: Chem, bio, radiological, nuclear, high explosive threat or attack. */
-    public static final int CMAS_CATEGORY_CBRNE = 0x0a;
-
-    /** CMAS alert category: Other events. */
-    public static final int CMAS_CATEGORY_OTHER = 0x0b;
-
-    /**
-     * CMAS alert category is unknown. The category is only available for CDMA broadcasts
-     * containing a type 1 elements record, so GSM and UMTS broadcasts always return unknown.
-     */
-    public static final int CMAS_CATEGORY_UNKNOWN = -1;
-
-    // CMAS response type (in CDMA type 1 elements record).
-
-    /** CMAS response type: Take shelter in place. */
-    public static final int CMAS_RESPONSE_TYPE_SHELTER = 0x00;
-
-    /** CMAS response type: Evacuate (Relocate). */
-    public static final int CMAS_RESPONSE_TYPE_EVACUATE = 0x01;
-
-    /** CMAS response type: Make preparations. */
-    public static final int CMAS_RESPONSE_TYPE_PREPARE = 0x02;
-
-    /** CMAS response type: Execute a pre-planned activity. */
-    public static final int CMAS_RESPONSE_TYPE_EXECUTE = 0x03;
-
-    /** CMAS response type: Attend to information sources. */
-    public static final int CMAS_RESPONSE_TYPE_MONITOR = 0x04;
-
-    /** CMAS response type: Avoid hazard. */
-    public static final int CMAS_RESPONSE_TYPE_AVOID = 0x05;
-
-    /** CMAS response type: Evaluate the information in this message (not for public warnings). */
-    public static final int CMAS_RESPONSE_TYPE_ASSESS = 0x06;
-
-    /** CMAS response type: No action recommended. */
-    public static final int CMAS_RESPONSE_TYPE_NONE = 0x07;
-
-    /**
-     * CMAS response type is unknown. The response type is only available for CDMA broadcasts
-     * containing a type 1 elements record, so GSM and UMTS broadcasts always return unknown.
-     */
-    public static final int CMAS_RESPONSE_TYPE_UNKNOWN = -1;
-
-    // 4-bit CMAS severity (in GSM/UMTS message identifier or CDMA type 1 elements record).
-
-    /** CMAS severity type: Extraordinary threat to life or property. */
-    public static final int CMAS_SEVERITY_EXTREME = 0x0;
-
-    /** CMAS severity type: Significant threat to life or property. */
-    public static final int CMAS_SEVERITY_SEVERE = 0x1;
-
-    /**
-     * CMAS alert severity is unknown. The severity is available for CDMA warning alerts
-     * containing a type 1 elements record and for all GSM and UMTS alerts except for the
-     * Presidential-level alert class (Korean Public Alert System Class 0).
-     */
-    public static final int CMAS_SEVERITY_UNKNOWN = -1;
-
-    // CMAS urgency (in GSM/UMTS message identifier or CDMA type 1 elements record).
-
-    /** CMAS urgency type: Responsive action should be taken immediately. */
-    public static final int CMAS_URGENCY_IMMEDIATE = 0x0;
-
-    /** CMAS urgency type: Responsive action should be taken within the next hour. */
-    public static final int CMAS_URGENCY_EXPECTED = 0x1;
-
-    /**
-     * CMAS alert urgency is unknown. The urgency is available for CDMA warning alerts
-     * containing a type 1 elements record and for all GSM and UMTS alerts except for the
-     * Presidential-level alert class (Korean Public Alert System Class 0).
-     */
-    public static final int CMAS_URGENCY_UNKNOWN = -1;
-
-    // CMAS certainty (in GSM/UMTS message identifier or CDMA type 1 elements record).
-
-    /** CMAS certainty type: Determined to have occurred or to be ongoing. */
-    public static final int CMAS_CERTAINTY_OBSERVED = 0x0;
-
-    /** CMAS certainty type: Likely (probability > ~50%). */
-    public static final int CMAS_CERTAINTY_LIKELY = 0x1;
-
-    /**
-     * CMAS alert certainty is unknown. The certainty is available for CDMA warning alerts
-     * containing a type 1 elements record and for all GSM and UMTS alerts except for the
-     * Presidential-level alert class (Korean Public Alert System Class 0).
-     */
-    public static final int CMAS_CERTAINTY_UNKNOWN = -1;
-
-    /** CMAS message class. */
-    private final int mMessageClass;
-
-    /** CMAS category. */
-    private final int mCategory;
-
-    /** CMAS response type. */
-    private final int mResponseType;
-
-    /** CMAS severity. */
-    private final int mSeverity;
-
-    /** CMAS urgency. */
-    private final int mUrgency;
-
-    /** CMAS certainty. */
-    private final int mCertainty;
-
-    /** Create a new SmsCbCmasInfo object with the specified values. */
-    public SmsCbCmasInfo(int messageClass, int category, int responseType, int severity,
-            int urgency, int certainty) {
-        mMessageClass = messageClass;
-        mCategory = category;
-        mResponseType = responseType;
-        mSeverity = severity;
-        mUrgency = urgency;
-        mCertainty = certainty;
-    }
-
-    /** Create a new SmsCbCmasInfo object from a Parcel. */
-    SmsCbCmasInfo(Parcel in) {
-        mMessageClass = in.readInt();
-        mCategory = in.readInt();
-        mResponseType = in.readInt();
-        mSeverity = in.readInt();
-        mUrgency = in.readInt();
-        mCertainty = in.readInt();
-    }
-
-    /**
-     * Flatten this object into a Parcel.
-     *
-     * @param dest  The Parcel in which the object should be written.
-     * @param flags Additional flags about how the object should be written (ignored).
-     */
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mMessageClass);
-        dest.writeInt(mCategory);
-        dest.writeInt(mResponseType);
-        dest.writeInt(mSeverity);
-        dest.writeInt(mUrgency);
-        dest.writeInt(mCertainty);
-    }
-
-    /**
-     * Returns the CMAS message class, e.g. {@link #CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT}.
-     * @return one of the {@code CMAS_CLASS} values
-     */
-    public int getMessageClass() {
-        return mMessageClass;
-    }
-
-    /**
-     * Returns the CMAS category, e.g. {@link #CMAS_CATEGORY_GEO}.
-     * @return one of the {@code CMAS_CATEGORY} values
-     */
-    public int getCategory() {
-        return mCategory;
-    }
-
-    /**
-     * Returns the CMAS response type, e.g. {@link #CMAS_RESPONSE_TYPE_SHELTER}.
-     * @return one of the {@code CMAS_RESPONSE_TYPE} values
-     */
-    public int getResponseType() {
-        return mResponseType;
-    }
-
-    /**
-     * Returns the CMAS severity, e.g. {@link #CMAS_SEVERITY_EXTREME}.
-     * @return one of the {@code CMAS_SEVERITY} values
-     */
-    public int getSeverity() {
-        return mSeverity;
-    }
-
-    /**
-     * Returns the CMAS urgency, e.g. {@link #CMAS_URGENCY_IMMEDIATE}.
-     * @return one of the {@code CMAS_URGENCY} values
-     */
-    public int getUrgency() {
-        return mUrgency;
-    }
-
-    /**
-     * Returns the CMAS certainty, e.g. {@link #CMAS_CERTAINTY_OBSERVED}.
-     * @return one of the {@code CMAS_CERTAINTY} values
-     */
-    public int getCertainty() {
-        return mCertainty;
-    }
-
-    @Override
-    public String toString() {
-        return "SmsCbCmasInfo{messageClass=" + mMessageClass + ", category=" + mCategory
-                + ", responseType=" + mResponseType + ", severity=" + mSeverity
-                + ", urgency=" + mUrgency + ", certainty=" + mCertainty + '}';
-    }
-
-    /**
-     * Describe the kinds of special objects contained in the marshalled representation.
-     * @return a bitmask indicating this Parcelable contains no special objects
-     */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /** Creator for unparcelling objects. */
-    public static final Parcelable.Creator<SmsCbCmasInfo>
-            CREATOR = new Parcelable.Creator<SmsCbCmasInfo>() {
-        public SmsCbCmasInfo createFromParcel(Parcel in) {
-            return new SmsCbCmasInfo(in);
-        }
-
-        public SmsCbCmasInfo[] newArray(int size) {
-            return new SmsCbCmasInfo[size];
-        }
-    };
-}
diff --git a/telephony/java/android/telephony/SmsCbEtwsInfo.java b/telephony/java/android/telephony/SmsCbEtwsInfo.java
deleted file mode 100644
index 0890d52..0000000
--- a/telephony/java/android/telephony/SmsCbEtwsInfo.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.format.Time;
-
-import com.android.internal.telephony.IccUtils;
-
-import java.util.Arrays;
-
-/**
- * Contains information elements for a GSM or UMTS ETWS warning notification.
- * Supported values for each element are defined in 3GPP TS 23.041.
- *
- * {@hide}
- */
-public class SmsCbEtwsInfo implements Parcelable {
-
-    /** ETWS warning type for earthquake. */
-    public static final int ETWS_WARNING_TYPE_EARTHQUAKE = 0x00;
-
-    /** ETWS warning type for tsunami. */
-    public static final int ETWS_WARNING_TYPE_TSUNAMI = 0x01;
-
-    /** ETWS warning type for earthquake and tsunami. */
-    public static final int ETWS_WARNING_TYPE_EARTHQUAKE_AND_TSUNAMI = 0x02;
-
-    /** ETWS warning type for test messages. */
-    public static final int ETWS_WARNING_TYPE_TEST_MESSAGE = 0x03;
-
-    /** ETWS warning type for other emergency types. */
-    public static final int ETWS_WARNING_TYPE_OTHER_EMERGENCY = 0x04;
-
-    /** Unknown ETWS warning type. */
-    public static final int ETWS_WARNING_TYPE_UNKNOWN = -1;
-
-    /** One of the ETWS warning type constants defined in this class. */
-    private final int mWarningType;
-
-    /** Whether or not to activate the emergency user alert tone and vibration. */
-    private final boolean mEmergencyUserAlert;
-
-    /** Whether or not to activate a popup alert. */
-    private final boolean mActivatePopup;
-
-    /**
-     * 50-byte security information (ETWS primary notification for GSM only). As of Release 10,
-     * 3GPP TS 23.041 states that the UE shall ignore the ETWS primary notification timestamp
-     * and digital signature if received. Therefore it is treated as a raw byte array and
-     * parceled with the broadcast intent if present, but the timestamp is only computed if an
-     * application asks for the individual components.
-     */
-    private final byte[] mWarningSecurityInformation;
-
-    /** Create a new SmsCbEtwsInfo object with the specified values. */
-    public SmsCbEtwsInfo(int warningType, boolean emergencyUserAlert, boolean activatePopup,
-            byte[] warningSecurityInformation) {
-        mWarningType = warningType;
-        mEmergencyUserAlert = emergencyUserAlert;
-        mActivatePopup = activatePopup;
-        mWarningSecurityInformation = warningSecurityInformation;
-    }
-
-    /** Create a new SmsCbEtwsInfo object from a Parcel. */
-    SmsCbEtwsInfo(Parcel in) {
-        mWarningType = in.readInt();
-        mEmergencyUserAlert = (in.readInt() != 0);
-        mActivatePopup = (in.readInt() != 0);
-        mWarningSecurityInformation = in.createByteArray();
-    }
-
-    /**
-     * Flatten this object into a Parcel.
-     *
-     * @param dest  The Parcel in which the object should be written.
-     * @param flags Additional flags about how the object should be written (ignored).
-     */
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mWarningType);
-        dest.writeInt(mEmergencyUserAlert ? 1 : 0);
-        dest.writeInt(mActivatePopup ? 1 : 0);
-        dest.writeByteArray(mWarningSecurityInformation);
-    }
-
-    /**
-     * Returns the ETWS warning type.
-     * @return a warning type such as {@link #ETWS_WARNING_TYPE_EARTHQUAKE}
-     */
-    public int getWarningType() {
-        return mWarningType;
-    }
-
-    /**
-     * Returns the ETWS emergency user alert flag.
-     * @return true to notify terminal to activate emergency user alert; false otherwise
-     */
-    public boolean isEmergencyUserAlert() {
-        return mEmergencyUserAlert;
-    }
-
-    /**
-     * Returns the ETWS activate popup flag.
-     * @return true to notify terminal to activate display popup; false otherwise
-     */
-    public boolean isPopupAlert() {
-        return mActivatePopup;
-    }
-
-    /**
-     * Returns the Warning-Security-Information timestamp (GSM primary notifications only).
-     * As of Release 10, 3GPP TS 23.041 states that the UE shall ignore this value if received.
-     * @return a UTC timestamp in System.currentTimeMillis() format, or 0 if not present
-     */
-    public long getPrimaryNotificationTimestamp() {
-        if (mWarningSecurityInformation == null || mWarningSecurityInformation.length < 7) {
-            return 0;
-        }
-
-        int year = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[0]);
-        int month = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[1]);
-        int day = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[2]);
-        int hour = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[3]);
-        int minute = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[4]);
-        int second = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[5]);
-
-        // For the timezone, the most significant bit of the
-        // least significant nibble is the sign byte
-        // (meaning the max range of this field is 79 quarter-hours,
-        // which is more than enough)
-
-        byte tzByte = mWarningSecurityInformation[6];
-
-        // Mask out sign bit.
-        int timezoneOffset = IccUtils.gsmBcdByteToInt((byte) (tzByte & (~0x08)));
-
-        timezoneOffset = ((tzByte & 0x08) == 0) ? timezoneOffset : -timezoneOffset;
-
-        Time time = new Time(Time.TIMEZONE_UTC);
-
-        // We only need to support years above 2000.
-        time.year = year + 2000;
-        time.month = month - 1;
-        time.monthDay = day;
-        time.hour = hour;
-        time.minute = minute;
-        time.second = second;
-
-        // Timezone offset is in quarter hours.
-        return time.toMillis(true) - (long) (timezoneOffset * 15 * 60 * 1000);
-    }
-
-    /**
-     * Returns the digital signature (GSM primary notifications only). As of Release 10,
-     * 3GPP TS 23.041 states that the UE shall ignore this value if received.
-     * @return a byte array containing a copy of the primary notification digital signature
-     */
-    public byte[] getPrimaryNotificationSignature() {
-        if (mWarningSecurityInformation == null || mWarningSecurityInformation.length < 50) {
-            return null;
-        }
-        return Arrays.copyOfRange(mWarningSecurityInformation, 7, 50);
-    }
-
-    @Override
-    public String toString() {
-        return "SmsCbEtwsInfo{warningType=" + mWarningType + ", emergencyUserAlert="
-                + mEmergencyUserAlert + ", activatePopup=" + mActivatePopup + '}';
-    }
-
-    /**
-     * Describe the kinds of special objects contained in the marshalled representation.
-     * @return a bitmask indicating this Parcelable contains no special objects
-     */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /** Creator for unparcelling objects. */
-    public static final Creator<SmsCbEtwsInfo> CREATOR = new Creator<SmsCbEtwsInfo>() {
-        public SmsCbEtwsInfo createFromParcel(Parcel in) {
-            return new SmsCbEtwsInfo(in);
-        }
-
-        public SmsCbEtwsInfo[] newArray(int size) {
-            return new SmsCbEtwsInfo[size];
-        }
-    };
-}
diff --git a/telephony/java/android/telephony/SmsCbLocation.java b/telephony/java/android/telephony/SmsCbLocation.java
deleted file mode 100644
index 7b5bd0d..0000000
--- a/telephony/java/android/telephony/SmsCbLocation.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony;
-
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.telephony.gsm.GsmCellLocation;
-
-/**
- * Represents the location and geographical scope of a cell broadcast message.
- * For GSM/UMTS, the Location Area and Cell ID are set when the broadcast
- * geographical scope is cell wide or Location Area wide. For CDMA, the
- * broadcast geographical scope is always PLMN wide.
- *
- * @hide
- */
-public class SmsCbLocation implements Parcelable {
-
-    /** The PLMN. Note that this field may be an empty string, but isn't allowed to be null. */
-    private final String mPlmn;
-
-    private final int mLac;
-    private final int mCid;
-
-    /**
-     * Construct an empty location object. This is used for some test cases, and for
-     * cell broadcasts saved in older versions of the database without location info.
-     */
-    public SmsCbLocation() {
-        mPlmn = "";
-        mLac = -1;
-        mCid = -1;
-    }
-
-    /**
-     * Construct a location object for the PLMN. This class is immutable, so
-     * the same object can be reused for multiple broadcasts.
-     */
-    public SmsCbLocation(String plmn) {
-        mPlmn = plmn;
-        mLac = -1;
-        mCid = -1;
-    }
-
-    /**
-     * Construct a location object for the PLMN, LAC, and Cell ID. This class is immutable, so
-     * the same object can be reused for multiple broadcasts.
-     */
-    public SmsCbLocation(String plmn, int lac, int cid) {
-        mPlmn = plmn;
-        mLac = lac;
-        mCid = cid;
-    }
-
-    /**
-     * Initialize the object from a Parcel.
-     */
-    public SmsCbLocation(Parcel in) {
-        mPlmn = in.readString();
-        mLac = in.readInt();
-        mCid = in.readInt();
-    }
-
-    /**
-     * Returns the MCC/MNC of the network as a String.
-     * @return the PLMN identifier (MCC+MNC) as a String
-     */
-    public String getPlmn() {
-        return mPlmn;
-    }
-
-    /**
-     * Returns the GSM location area code, or UMTS service area code.
-     * @return location area code, -1 if unknown, 0xffff max legal value
-     */
-    public int getLac() {
-        return mLac;
-    }
-
-    /**
-     * Returns the GSM or UMTS cell ID.
-     * @return gsm cell id, -1 if unknown, 0xffff max legal value
-     */
-    public int getCid() {
-        return mCid;
-    }
-
-    @Override
-    public int hashCode() {
-        int hash = mPlmn.hashCode();
-        hash = hash * 31 + mLac;
-        hash = hash * 31 + mCid;
-        return hash;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (o == this) {
-            return true;
-        }
-        if (o == null || !(o instanceof SmsCbLocation)) {
-            return false;
-        }
-        SmsCbLocation other = (SmsCbLocation) o;
-        return mPlmn.equals(other.mPlmn) && mLac == other.mLac && mCid == other.mCid;
-    }
-
-    @Override
-    public String toString() {
-        return '[' + mPlmn + ',' + mLac + ',' + mCid + ']';
-    }
-
-    /**
-     * Test whether this location is within the location area of the specified object.
-     *
-     * @param area the location area to compare with this location
-     * @return true if this location is contained within the specified location area
-     */
-    public boolean isInLocationArea(SmsCbLocation area) {
-        if (mCid != -1 && mCid != area.mCid) {
-            return false;
-        }
-        if (mLac != -1 && mLac != area.mLac) {
-            return false;
-        }
-        return mPlmn.equals(area.mPlmn);
-    }
-
-    /**
-     * Test whether this location is within the location area of the CellLocation.
-     *
-     * @param plmn the PLMN to use for comparison
-     * @param lac the Location Area (GSM) or Service Area (UMTS) to compare with
-     * @param cid the Cell ID to compare with
-     * @return true if this location is contained within the specified PLMN, LAC, and Cell ID
-     */
-    public boolean isInLocationArea(String plmn, int lac, int cid) {
-        if (!mPlmn.equals(plmn)) {
-            return false;
-        }
-
-        if (mLac != -1 && mLac != lac) {
-            return false;
-        }
-
-        if (mCid != -1 && mCid != cid) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Flatten this object into a Parcel.
-     *
-     * @param dest  The Parcel in which the object should be written.
-     * @param flags Additional flags about how the object should be written (ignored).
-     */
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(mPlmn);
-        dest.writeInt(mLac);
-        dest.writeInt(mCid);
-    }
-
-    public static final Parcelable.Creator<SmsCbLocation> CREATOR
-            = new Parcelable.Creator<SmsCbLocation>() {
-        @Override
-        public SmsCbLocation createFromParcel(Parcel in) {
-            return new SmsCbLocation(in);
-        }
-
-        @Override
-        public SmsCbLocation[] newArray(int size) {
-            return new SmsCbLocation[size];
-        }
-    };
-
-    /**
-     * Describe the kinds of special objects contained in the marshalled representation.
-     * @return a bitmask indicating this Parcelable contains no special objects
-     */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-}
diff --git a/telephony/java/android/telephony/SmsCbMessage.java b/telephony/java/android/telephony/SmsCbMessage.java
deleted file mode 100644
index 046bf8c..0000000
--- a/telephony/java/android/telephony/SmsCbMessage.java
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Parcelable object containing a received cell broadcast message. There are four different types
- * of Cell Broadcast messages:
- *
- * <ul>
- * <li>opt-in informational broadcasts, e.g. news, weather, stock quotes, sports scores</li>
- * <li>cell information messages, broadcast on channel 50, indicating the current cell name for
- *  roaming purposes (required to display on the idle screen in Brazil)</li>
- * <li>emergency broadcasts for the Japanese Earthquake and Tsunami Warning System (ETWS)</li>
- * <li>emergency broadcasts for the American Commercial Mobile Alert Service (CMAS)</li>
- * </ul>
- *
- * <p>There are also four different CB message formats: GSM, ETWS Primary Notification (GSM only),
- * UMTS, and CDMA. Some fields are only applicable for some message formats. Other fields were
- * unified under a common name, avoiding some names, such as "Message Identifier", that refer to
- * two completely different concepts in 3GPP and CDMA.
- *
- * <p>The GSM/UMTS Message Identifier field is available via {@link #getServiceCategory}, the name
- * of the equivalent field in CDMA. In both cases the service category is a 16-bit value, but 3GPP
- * and 3GPP2 have completely different meanings for the respective values. For ETWS and CMAS, the
- * application should
- *
- * <p>The CDMA Message Identifier field is available via {@link #getSerialNumber}, which is used
- * to detect the receipt of a duplicate message to be discarded. In CDMA, the message ID is
- * unique to the current PLMN. In GSM/UMTS, there is a 16-bit serial number containing a 2-bit
- * Geographical Scope field which indicates whether the 10-bit message code and 4-bit update number
- * are considered unique to the PLMN, to the current cell, or to the current Location Area (or
- * Service Area in UMTS). The relevant values are concatenated into a single String which will be
- * unique if the messages are not duplicates.
- *
- * <p>The SMS dispatcher does not detect duplicate messages. However, it does concatenate the
- * pages of a GSM multi-page cell broadcast into a single SmsCbMessage object.
- *
- * <p>Interested applications with {@code RECEIVE_SMS_PERMISSION} can register to receive
- * {@code SMS_CB_RECEIVED_ACTION} broadcast intents for incoming non-emergency broadcasts.
- * Only system applications such as the CellBroadcastReceiver may receive notifications for
- * emergency broadcasts (ETWS and CMAS). This is intended to prevent any potential for delays or
- * interference with the immediate display of the alert message and playing of the alert sound and
- * vibration pattern, which could be caused by poorly written or malicious non-system code.
- *
- * @hide
- */
-public class SmsCbMessage implements Parcelable {
-
-    protected static final String LOG_TAG = "SMSCB";
-
-    /** Cell wide geographical scope with immediate display (GSM/UMTS only). */
-    public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE = 0;
-
-    /** PLMN wide geographical scope (GSM/UMTS and all CDMA broadcasts). */
-    public static final int GEOGRAPHICAL_SCOPE_PLMN_WIDE = 1;
-
-    /** Location / service area wide geographical scope (GSM/UMTS only). */
-    public static final int GEOGRAPHICAL_SCOPE_LA_WIDE = 2;
-
-    /** Cell wide geographical scope (GSM/UMTS only). */
-    public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE = 3;
-
-    /** GSM or UMTS format cell broadcast. */
-    public static final int MESSAGE_FORMAT_3GPP = 1;
-
-    /** CDMA format cell broadcast. */
-    public static final int MESSAGE_FORMAT_3GPP2 = 2;
-
-    /** Normal message priority. */
-    public static final int MESSAGE_PRIORITY_NORMAL = 0;
-
-    /** Interactive message priority. */
-    public static final int MESSAGE_PRIORITY_INTERACTIVE = 1;
-
-    /** Urgent message priority. */
-    public static final int MESSAGE_PRIORITY_URGENT = 2;
-
-    /** Emergency message priority. */
-    public static final int MESSAGE_PRIORITY_EMERGENCY = 3;
-
-    /** Format of this message (for interpretation of service category values). */
-    private final int mMessageFormat;
-
-    /** Geographical scope of broadcast. */
-    private final int mGeographicalScope;
-
-    /**
-     * Serial number of broadcast (message identifier for CDMA, geographical scope + message code +
-     * update number for GSM/UMTS). The serial number plus the location code uniquely identify
-     * a cell broadcast for duplicate detection.
-     */
-    private final int mSerialNumber;
-
-    /**
-     * Location identifier for this message. It consists of the current operator MCC/MNC as a
-     * 5 or 6-digit decimal string. In addition, for GSM/UMTS, if the Geographical Scope of the
-     * message is not binary 01, the Location Area is included for comparison. If the GS is
-     * 00 or 11, the Cell ID is also included. LAC and Cell ID are -1 if not specified.
-     */
-    private final SmsCbLocation mLocation;
-
-    /**
-     * 16-bit CDMA service category or GSM/UMTS message identifier. For ETWS and CMAS warnings,
-     * the information provided by the category is also available via {@link #getEtwsWarningInfo()}
-     * or {@link #getCmasWarningInfo()}.
-     */
-    private final int mServiceCategory;
-
-    /** Message language, as a two-character string, e.g. "en". */
-    private final String mLanguage;
-
-    /** Message body, as a String. */
-    private final String mBody;
-
-    /** Message priority (including emergency priority). */
-    private final int mPriority;
-
-    /** ETWS warning notification information (ETWS warnings only). */
-    private final SmsCbEtwsInfo mEtwsWarningInfo;
-
-    /** CMAS warning notification information (CMAS warnings only). */
-    private final SmsCbCmasInfo mCmasWarningInfo;
-
-    /**
-     * Create a new SmsCbMessage with the specified data.
-     */
-    public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber,
-            SmsCbLocation location, int serviceCategory, String language, String body,
-            int priority, SmsCbEtwsInfo etwsWarningInfo, SmsCbCmasInfo cmasWarningInfo) {
-        mMessageFormat = messageFormat;
-        mGeographicalScope = geographicalScope;
-        mSerialNumber = serialNumber;
-        mLocation = location;
-        mServiceCategory = serviceCategory;
-        mLanguage = language;
-        mBody = body;
-        mPriority = priority;
-        mEtwsWarningInfo = etwsWarningInfo;
-        mCmasWarningInfo = cmasWarningInfo;
-    }
-
-    /** Create a new SmsCbMessage object from a Parcel. */
-    public SmsCbMessage(Parcel in) {
-        mMessageFormat = in.readInt();
-        mGeographicalScope = in.readInt();
-        mSerialNumber = in.readInt();
-        mLocation = new SmsCbLocation(in);
-        mServiceCategory = in.readInt();
-        mLanguage = in.readString();
-        mBody = in.readString();
-        mPriority = in.readInt();
-        int type = in.readInt();
-        switch (type) {
-            case 'E':
-                // unparcel ETWS warning information
-                mEtwsWarningInfo = new SmsCbEtwsInfo(in);
-                mCmasWarningInfo = null;
-                break;
-
-            case 'C':
-                // unparcel CMAS warning information
-                mEtwsWarningInfo = null;
-                mCmasWarningInfo = new SmsCbCmasInfo(in);
-                break;
-
-            default:
-                mEtwsWarningInfo = null;
-                mCmasWarningInfo = null;
-        }
-    }
-
-    /**
-     * Flatten this object into a Parcel.
-     *
-     * @param dest  The Parcel in which the object should be written.
-     * @param flags Additional flags about how the object should be written (ignored).
-     */
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mMessageFormat);
-        dest.writeInt(mGeographicalScope);
-        dest.writeInt(mSerialNumber);
-        mLocation.writeToParcel(dest, flags);
-        dest.writeInt(mServiceCategory);
-        dest.writeString(mLanguage);
-        dest.writeString(mBody);
-        dest.writeInt(mPriority);
-        if (mEtwsWarningInfo != null) {
-            // parcel ETWS warning information
-            dest.writeInt('E');
-            mEtwsWarningInfo.writeToParcel(dest, flags);
-        } else if (mCmasWarningInfo != null) {
-            // parcel CMAS warning information
-            dest.writeInt('C');
-            mCmasWarningInfo.writeToParcel(dest, flags);
-        } else {
-            // no ETWS or CMAS warning information
-            dest.writeInt('0');
-        }
-    }
-
-    public static final Parcelable.Creator<SmsCbMessage> CREATOR
-            = new Parcelable.Creator<SmsCbMessage>() {
-        @Override
-        public SmsCbMessage createFromParcel(Parcel in) {
-            return new SmsCbMessage(in);
-        }
-
-        @Override
-        public SmsCbMessage[] newArray(int size) {
-            return new SmsCbMessage[size];
-        }
-    };
-
-    /**
-     * Return the geographical scope of this message (GSM/UMTS only).
-     *
-     * @return Geographical scope
-     */
-    public int getGeographicalScope() {
-        return mGeographicalScope;
-    }
-
-    /**
-     * Return the broadcast serial number of broadcast (message identifier for CDMA, or
-     * geographical scope + message code + update number for GSM/UMTS). The serial number plus
-     * the location code uniquely identify a cell broadcast for duplicate detection.
-     *
-     * @return the 16-bit CDMA message identifier or GSM/UMTS serial number
-     */
-    public int getSerialNumber() {
-        return mSerialNumber;
-    }
-
-    /**
-     * Return the location identifier for this message, consisting of the MCC/MNC as a
-     * 5 or 6-digit decimal string. In addition, for GSM/UMTS, if the Geographical Scope of the
-     * message is not binary 01, the Location Area is included. If the GS is 00 or 11, the
-     * cell ID is also included. The {@link SmsCbLocation} object includes a method to test
-     * if the location is included within another location area or within a PLMN and CellLocation.
-     *
-     * @return the geographical location code for duplicate message detection
-     */
-    public SmsCbLocation getLocation() {
-        return mLocation;
-    }
-
-    /**
-     * Return the 16-bit CDMA service category or GSM/UMTS message identifier. The interpretation
-     * of the category is radio technology specific. For ETWS and CMAS warnings, the information
-     * provided by the category is available via {@link #getEtwsWarningInfo()} or
-     * {@link #getCmasWarningInfo()} in a radio technology independent format.
-     *
-     * @return the radio technology specific service category
-     */
-    public int getServiceCategory() {
-        return mServiceCategory;
-    }
-
-    /**
-     * Get the ISO-639-1 language code for this message, or null if unspecified
-     *
-     * @return Language code
-     */
-    public String getLanguageCode() {
-        return mLanguage;
-    }
-
-    /**
-     * Get the body of this message, or null if no body available
-     *
-     * @return Body, or null
-     */
-    public String getMessageBody() {
-        return mBody;
-    }
-
-    /**
-     * Get the message format ({@link #MESSAGE_FORMAT_3GPP} or {@link #MESSAGE_FORMAT_3GPP2}).
-     * @return an integer representing 3GPP or 3GPP2 message format
-     */
-    public int getMessageFormat() {
-        return mMessageFormat;
-    }
-
-    /**
-     * Get the message priority. Normal broadcasts return {@link #MESSAGE_PRIORITY_NORMAL}
-     * and emergency broadcasts return {@link #MESSAGE_PRIORITY_EMERGENCY}. CDMA also may return
-     * {@link #MESSAGE_PRIORITY_INTERACTIVE} or {@link #MESSAGE_PRIORITY_URGENT}.
-     * @return an integer representing the message priority
-     */
-    public int getMessagePriority() {
-        return mPriority;
-    }
-
-    /**
-     * If this is an ETWS warning notification then this method will return an object containing
-     * the ETWS warning type, the emergency user alert flag, and the popup flag. If this is an
-     * ETWS primary notification (GSM only), there will also be a 7-byte timestamp and 43-byte
-     * digital signature. As of Release 10, 3GPP TS 23.041 states that the UE shall ignore the
-     * ETWS primary notification timestamp and digital signature if received.
-     *
-     * @return an SmsCbEtwsInfo object, or null if this is not an ETWS warning notification
-     */
-    public SmsCbEtwsInfo getEtwsWarningInfo() {
-        return mEtwsWarningInfo;
-    }
-
-    /**
-     * If this is a CMAS warning notification then this method will return an object containing
-     * the CMAS message class, category, response type, severity, urgency and certainty.
-     * The message class is always present. Severity, urgency and certainty are present for CDMA
-     * warning notifications containing a type 1 elements record and for GSM and UMTS warnings
-     * except for the Presidential-level alert category. Category and response type are only
-     * available for CDMA notifications containing a type 1 elements record.
-     *
-     * @return an SmsCbCmasInfo object, or null if this is not a CMAS warning notification
-     */
-    public SmsCbCmasInfo getCmasWarningInfo() {
-        return mCmasWarningInfo;
-    }
-
-    /**
-     * Return whether this message is an emergency (PWS) message type.
-     * @return true if the message is a public warning notification; false otherwise
-     */
-    public boolean isEmergencyMessage() {
-        return mPriority == MESSAGE_PRIORITY_EMERGENCY;
-    }
-
-    /**
-     * Return whether this message is an ETWS warning alert.
-     * @return true if the message is an ETWS warning notification; false otherwise
-     */
-    public boolean isEtwsMessage() {
-        return mEtwsWarningInfo != null;
-    }
-
-    /**
-     * Return whether this message is a CMAS warning alert.
-     * @return true if the message is a CMAS warning notification; false otherwise
-     */
-    public boolean isCmasMessage() {
-        return mCmasWarningInfo != null;
-    }
-
-    @Override
-    public String toString() {
-        return "SmsCbMessage{geographicalScope=" + mGeographicalScope + ", serialNumber="
-                + mSerialNumber + ", location=" + mLocation + ", serviceCategory="
-                + mServiceCategory + ", language=" + mLanguage + ", body=" + mBody
-                + ", priority=" + mPriority
-                + (mEtwsWarningInfo != null ? (", " + mEtwsWarningInfo.toString()) : "")
-                + (mCmasWarningInfo != null ? (", " + mCmasWarningInfo.toString()) : "") + '}';
-    }
-
-    /**
-     * Describe the kinds of special objects contained in the marshalled representation.
-     * @return a bitmask indicating this Parcelable contains no special objects
-     */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-}
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
deleted file mode 100644
index 44bdaeb..0000000
--- a/telephony/java/android/telephony/SmsManager.java
+++ /dev/null
@@ -1,522 +0,0 @@
-/*
- * 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 android.telephony;
-
-import android.app.PendingIntent;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.text.TextUtils;
-
-import com.android.internal.telephony.ISms;
-import com.android.internal.telephony.IccConstants;
-import com.android.internal.telephony.SmsRawData;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/*
- * TODO(code review): Curious question... Why are a lot of these
- * methods not declared as static, since they do not seem to require
- * any local object state?  Presumably this cannot be changed without
- * interfering with the API...
- */
-
-/**
- * Manages SMS operations such as sending data, text, and pdu SMS messages.
- * Get this object by calling the static method SmsManager.getDefault().
- */
-public final class SmsManager {
-    /** Singleton object constructed during class initialization. */
-    private static final SmsManager sInstance = new SmsManager();
-
-    /**
-     * Send a text based SMS.
-     *
-     * @param destinationAddress the address to send the message to
-     * @param scAddress is the service center address or null to use
-     *  the current default SMSC
-     * @param text the body of the message to send
-     * @param sentIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is successfully sent, or failed.
-     *  The result code will be <code>Activity.RESULT_OK</code> for success,
-     *  or one of these errors:<br>
-     *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
-     *  <code>RESULT_ERROR_RADIO_OFF</code><br>
-     *  <code>RESULT_ERROR_NULL_PDU</code><br>
-     *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
-     *  the extra "errorCode" containing a radio technology specific value,
-     *  generally only useful for troubleshooting.<br>
-     *  The per-application based SMS control checks sentIntent. If sentIntent
-     *  is NULL the caller will be checked against all unknown applications,
-     *  which cause smaller number of SMS to be sent in checking period.
-     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is delivered to the recipient.  The
-     *  raw pdu of the status report is in the extended data ("pdu").
-     *
-     * @throws IllegalArgumentException if destinationAddress or text are empty
-     */
-    public void sendTextMessage(
-            String destinationAddress, String scAddress, String text,
-            PendingIntent sentIntent, PendingIntent deliveryIntent) {
-        if (TextUtils.isEmpty(destinationAddress)) {
-            throw new IllegalArgumentException("Invalid destinationAddress");
-        }
-
-        if (TextUtils.isEmpty(text)) {
-            throw new IllegalArgumentException("Invalid message body");
-        }
-
-        try {
-            ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
-            if (iccISms != null) {
-                iccISms.sendText(destinationAddress, scAddress, text, sentIntent, deliveryIntent);
-            }
-        } catch (RemoteException ex) {
-            // ignore it
-        }
-    }
-
-    /**
-     * Divide a message text into several fragments, none bigger than
-     * the maximum SMS message size.
-     *
-     * @param text the original message.  Must not be null.
-     * @return an <code>ArrayList</code> of strings that, in order,
-     *   comprise the original message
-     */
-    public ArrayList<String> divideMessage(String text) {
-        return SmsMessage.fragmentText(text);
-    }
-
-    /**
-     * Send a multi-part text based SMS.  The callee should have already
-     * divided the message into correctly sized parts by calling
-     * <code>divideMessage</code>.
-     *
-     * @param destinationAddress the address to send the message to
-     * @param scAddress is the service center address or null to use
-     *   the current default SMSC
-     * @param parts an <code>ArrayList</code> of strings that, in order,
-     *   comprise the original message
-     * @param sentIntents if not null, an <code>ArrayList</code> of
-     *   <code>PendingIntent</code>s (one for each message part) that is
-     *   broadcast when the corresponding message part has been sent.
-     *   The result code will be <code>Activity.RESULT_OK</code> for success,
-     *   or one of these errors:<br>
-     *   <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
-     *   <code>RESULT_ERROR_RADIO_OFF</code><br>
-     *   <code>RESULT_ERROR_NULL_PDU</code><br>
-     *   For <code>RESULT_ERROR_GENERIC_FAILURE</code> each sentIntent may include
-     *   the extra "errorCode" containing a radio technology specific value,
-     *   generally only useful for troubleshooting.<br>
-     *   The per-application based SMS control checks sentIntent. If sentIntent
-     *   is NULL the caller will be checked against all unknown applications,
-     *   which cause smaller number of SMS to be sent in checking period.
-     * @param deliveryIntents if not null, an <code>ArrayList</code> of
-     *   <code>PendingIntent</code>s (one for each message part) that is
-     *   broadcast when the corresponding message part has been delivered
-     *   to the recipient.  The raw pdu of the status report is in the
-     *   extended data ("pdu").
-     *
-     * @throws IllegalArgumentException if destinationAddress or data are empty
-     */
-    public void sendMultipartTextMessage(
-            String destinationAddress, String scAddress, ArrayList<String> parts,
-            ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {
-        if (TextUtils.isEmpty(destinationAddress)) {
-            throw new IllegalArgumentException("Invalid destinationAddress");
-        }
-        if (parts == null || parts.size() < 1) {
-            throw new IllegalArgumentException("Invalid message body");
-        }
-
-        if (parts.size() > 1) {
-            try {
-                ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
-                if (iccISms != null) {
-                    iccISms.sendMultipartText(destinationAddress, scAddress, parts,
-                            sentIntents, deliveryIntents);
-                }
-            } catch (RemoteException ex) {
-                // ignore it
-            }
-        } else {
-            PendingIntent sentIntent = null;
-            PendingIntent deliveryIntent = null;
-            if (sentIntents != null && sentIntents.size() > 0) {
-                sentIntent = sentIntents.get(0);
-            }
-            if (deliveryIntents != null && deliveryIntents.size() > 0) {
-                deliveryIntent = deliveryIntents.get(0);
-            }
-            sendTextMessage(destinationAddress, scAddress, parts.get(0),
-                    sentIntent, deliveryIntent);
-        }
-    }
-
-    /**
-     * Send a data based SMS to a specific application port.
-     *
-     * @param destinationAddress the address to send the message to
-     * @param scAddress is the service center address or null to use
-     *  the current default SMSC
-     * @param destinationPort the port to deliver the message to
-     * @param data the body of the message to send
-     * @param sentIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is successfully sent, or failed.
-     *  The result code will be <code>Activity.RESULT_OK</code> for success,
-     *  or one of these errors:<br>
-     *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
-     *  <code>RESULT_ERROR_RADIO_OFF</code><br>
-     *  <code>RESULT_ERROR_NULL_PDU</code><br>
-     *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
-     *  the extra "errorCode" containing a radio technology specific value,
-     *  generally only useful for troubleshooting.<br>
-     *  The per-application based SMS control checks sentIntent. If sentIntent
-     *  is NULL the caller will be checked against all unknown applications,
-     *  which cause smaller number of SMS to be sent in checking period.
-     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is delivered to the recipient.  The
-     *  raw pdu of the status report is in the extended data ("pdu").
-     *
-     * @throws IllegalArgumentException if destinationAddress or data are empty
-     */
-    public void sendDataMessage(
-            String destinationAddress, String scAddress, short destinationPort,
-            byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
-        if (TextUtils.isEmpty(destinationAddress)) {
-            throw new IllegalArgumentException("Invalid destinationAddress");
-        }
-
-        if (data == null || data.length == 0) {
-            throw new IllegalArgumentException("Invalid message data");
-        }
-
-        try {
-            ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
-            if (iccISms != null) {
-                iccISms.sendData(destinationAddress, scAddress, destinationPort & 0xFFFF,
-                        data, sentIntent, deliveryIntent);
-            }
-        } catch (RemoteException ex) {
-            // ignore it
-        }
-    }
-
-    /**
-     * Get the default instance of the SmsManager
-     *
-     * @return the default instance of the SmsManager
-     */
-    public static SmsManager getDefault() {
-        return sInstance;
-    }
-
-    private SmsManager() {
-        //nothing
-    }
-
-    /**
-     * Copy a raw SMS PDU to the ICC.
-     * ICC (Integrated Circuit Card) is the card of the device.
-     * For example, this can be the SIM or USIM for GSM.
-     *
-     * @param smsc the SMSC for this message, or NULL for the default SMSC
-     * @param pdu the raw PDU to store
-     * @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD,
-     *               STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT)
-     * @return true for success
-     *
-     * {@hide}
-     */
-    public boolean copyMessageToIcc(byte[] smsc, byte[] pdu, int status) {
-        boolean success = false;
-
-        try {
-            ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
-            if (iccISms != null) {
-                success = iccISms.copyMessageToIccEf(status, pdu, smsc);
-            }
-        } catch (RemoteException ex) {
-            // ignore it
-        }
-
-        return success;
-    }
-
-    /**
-     * Delete the specified message from the ICC.
-     * ICC (Integrated Circuit Card) is the card of the device.
-     * For example, this can be the SIM or USIM for GSM.
-     *
-     * @param messageIndex is the record index of the message on ICC
-     * @return true for success
-     *
-     * {@hide}
-     */
-    public boolean
-    deleteMessageFromIcc(int messageIndex) {
-        boolean success = false;
-        byte[] pdu = new byte[IccConstants.SMS_RECORD_LENGTH-1];
-        Arrays.fill(pdu, (byte)0xff);
-
-        try {
-            ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
-            if (iccISms != null) {
-                success = iccISms.updateMessageOnIccEf(messageIndex, STATUS_ON_ICC_FREE, pdu);
-            }
-        } catch (RemoteException ex) {
-            // ignore it
-        }
-
-        return success;
-    }
-
-    /**
-     * Update the specified message on the ICC.
-     * ICC (Integrated Circuit Card) is the card of the device.
-     * For example, this can be the SIM or USIM for GSM.
-     *
-     * @param messageIndex record index of message to update
-     * @param newStatus new message status (STATUS_ON_ICC_READ,
-     *                  STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT,
-     *                  STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE)
-     * @param pdu the raw PDU to store
-     * @return true for success
-     *
-     * {@hide}
-     */
-    public boolean updateMessageOnIcc(int messageIndex, int newStatus, byte[] pdu) {
-        boolean success = false;
-
-        try {
-            ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
-            if (iccISms != null) {
-                success = iccISms.updateMessageOnIccEf(messageIndex, newStatus, pdu);
-            }
-        } catch (RemoteException ex) {
-            // ignore it
-        }
-
-        return success;
-    }
-
-    /**
-     * Retrieves all messages currently stored on ICC.
-     * ICC (Integrated Circuit Card) is the card of the device.
-     * For example, this can be the SIM or USIM for GSM.
-     *
-     * @return <code>ArrayList</code> of <code>SmsMessage</code> objects
-     *
-     * {@hide}
-     */
-    public static ArrayList<SmsMessage> getAllMessagesFromIcc() {
-        List<SmsRawData> records = null;
-
-        try {
-            ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
-            if (iccISms != null) {
-                records = iccISms.getAllMessagesFromIccEf();
-            }
-        } catch (RemoteException ex) {
-            // ignore it
-        }
-
-        return createMessageListFromRawRecords(records);
-    }
-
-    /**
-     * Enable reception of cell broadcast (SMS-CB) messages with the given
-     * message identifier. Note that if two different clients enable the same
-     * message identifier, they must both disable it for the device to stop
-     * receiving those messages. All received messages will be broadcast in an
-     * intent with the action "android.provider.Telephony.SMS_CB_RECEIVED".
-     * Note: This call is blocking, callers may want to avoid calling it from
-     * the main thread of an application.
-     *
-     * @param messageIdentifier Message identifier as specified in TS 23.041
-     * @return true if successful, false otherwise
-     * @see #disableCellBroadcast(int)
-     *
-     * {@hide}
-     */
-    public boolean enableCellBroadcast(int messageIdentifier) {
-        boolean success = false;
-
-        try {
-            ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
-            if (iccISms != null) {
-                success = iccISms.enableCellBroadcast(messageIdentifier);
-            }
-        } catch (RemoteException ex) {
-            // ignore it
-        }
-
-        return success;
-    }
-
-    /**
-     * Disable reception of cell broadcast (SMS-CB) messages with the given
-     * message identifier. Note that if two different clients enable the same
-     * message identifier, they must both disable it for the device to stop
-     * receiving those messages.
-     * Note: This call is blocking, callers may want to avoid calling it from
-     * the main thread of an application.
-     *
-     * @param messageIdentifier Message identifier as specified in TS 23.041
-     * @return true if successful, false otherwise
-     *
-     * @see #enableCellBroadcast(int)
-     *
-     * {@hide}
-     */
-    public boolean disableCellBroadcast(int messageIdentifier) {
-        boolean success = false;
-
-        try {
-            ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
-            if (iccISms != null) {
-                success = iccISms.disableCellBroadcast(messageIdentifier);
-            }
-        } catch (RemoteException ex) {
-            // ignore it
-        }
-
-        return success;
-    }
-
-    /**
-     * Enable reception of cell broadcast (SMS-CB) messages with the given
-     * message identifier range. Note that if two different clients enable the same
-     * message identifier, they must both disable it for the device to stop
-     * receiving those messages. All received messages will be broadcast in an
-     * intent with the action "android.provider.Telephony.SMS_CB_RECEIVED".
-     * Note: This call is blocking, callers may want to avoid calling it from
-     * the main thread of an application.
-     *
-     * @param startMessageId first message identifier as specified in TS 23.041
-     * @param endMessageId last message identifier as specified in TS 23.041
-     * @return true if successful, false otherwise
-     * @see #disableCellBroadcastRange(int, int)
-     *
-     * {@hide}
-     */
-    public boolean enableCellBroadcastRange(int startMessageId, int endMessageId) {
-        boolean success = false;
-
-        try {
-            ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
-            if (iccISms != null) {
-                success = iccISms.enableCellBroadcastRange(startMessageId, endMessageId);
-            }
-        } catch (RemoteException ex) {
-            // ignore it
-        }
-
-        return success;
-    }
-
-    /**
-     * Disable reception of cell broadcast (SMS-CB) messages with the given
-     * message identifier range. Note that if two different clients enable the same
-     * message identifier, they must both disable it for the device to stop
-     * receiving those messages.
-     * Note: This call is blocking, callers may want to avoid calling it from
-     * the main thread of an application.
-     *
-     * @param startMessageId first message identifier as specified in TS 23.041
-     * @param endMessageId last message identifier as specified in TS 23.041
-     * @return true if successful, false otherwise
-     *
-     * @see #enableCellBroadcastRange(int, int)
-     *
-     * {@hide}
-     */
-    public boolean disableCellBroadcastRange(int startMessageId, int endMessageId) {
-        boolean success = false;
-
-        try {
-            ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
-            if (iccISms != null) {
-                success = iccISms.disableCellBroadcastRange(startMessageId, endMessageId);
-            }
-        } catch (RemoteException ex) {
-            // ignore it
-        }
-
-        return success;
-    }
-
-    /**
-     * Create a list of <code>SmsMessage</code>s from a list of RawSmsData
-     * records returned by <code>getAllMessagesFromIcc()</code>
-     *
-     * @param records SMS EF records, returned by
-     *   <code>getAllMessagesFromIcc</code>
-     * @return <code>ArrayList</code> of <code>SmsMessage</code> objects.
-     */
-    private static ArrayList<SmsMessage> createMessageListFromRawRecords(List<SmsRawData> records) {
-        ArrayList<SmsMessage> messages = new ArrayList<SmsMessage>();
-        if (records != null) {
-            int count = records.size();
-            for (int i = 0; i < count; i++) {
-                SmsRawData data = records.get(i);
-                // List contains all records, including "free" records (null)
-                if (data != null) {
-                    SmsMessage sms = SmsMessage.createFromEfRecord(i+1, data.getBytes());
-                    if (sms != null) {
-                        messages.add(sms);
-                    }
-                }
-            }
-        }
-        return messages;
-    }
-
-    // see SmsMessage.getStatusOnIcc
-
-    /** Free space (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
-    static public final int STATUS_ON_ICC_FREE      = 0;
-
-    /** Received and read (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
-    static public final int STATUS_ON_ICC_READ      = 1;
-
-    /** Received and unread (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
-    static public final int STATUS_ON_ICC_UNREAD    = 3;
-
-    /** Stored and sent (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
-    static public final int STATUS_ON_ICC_SENT      = 5;
-
-    /** Stored and unsent (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
-    static public final int STATUS_ON_ICC_UNSENT    = 7;
-
-    // SMS send failure result codes
-
-    /** Generic failure cause */
-    static public final int RESULT_ERROR_GENERIC_FAILURE    = 1;
-    /** Failed because radio was explicitly turned off */
-    static public final int RESULT_ERROR_RADIO_OFF          = 2;
-    /** Failed because no pdu provided */
-    static public final int RESULT_ERROR_NULL_PDU           = 3;
-    /** Failed because service is currently unavailable */
-    static public final int RESULT_ERROR_NO_SERVICE         = 4;
-    /** Failed because we reached the sending queue limit.  {@hide} */
-    static public final int RESULT_ERROR_LIMIT_EXCEEDED     = 5;
-    /** Failed because FDN is enabled. {@hide} */
-    static public final int RESULT_ERROR_FDN_CHECK_FAILURE  = 6;
-}
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
deleted file mode 100644
index 1410747..0000000
--- a/telephony/java/android/telephony/SmsMessage.java
+++ /dev/null
@@ -1,680 +0,0 @@
-/*
- * 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 android.telephony;
-
-import android.os.Parcel;
-import android.util.Log;
-
-import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.SmsHeader;
-import com.android.internal.telephony.SmsMessageBase;
-import com.android.internal.telephony.SmsMessageBase.SubmitPduBase;
-import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails;
-
-import java.lang.Math;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA;
-
-
-/**
- * A Short Message Service message.
- */
-public class SmsMessage {
-    private static final String LOG_TAG = "SMS";
-
-    /**
-     * SMS Class enumeration.
-     * See TS 23.038.
-     *
-     */
-    public enum MessageClass{
-        UNKNOWN, CLASS_0, CLASS_1, CLASS_2, CLASS_3;
-    }
-
-    /** User data text encoding code unit size */
-    public static final int ENCODING_UNKNOWN = 0;
-    public static final int ENCODING_7BIT = 1;
-    public static final int ENCODING_8BIT = 2;
-    public static final int ENCODING_16BIT = 3;
-    /**
-     * @hide This value is not defined in global standard. Only in Korea, this is used.
-     */
-    public static final int ENCODING_KSC5601 = 4;
-
-    /** The maximum number of payload bytes per message */
-    public static final int MAX_USER_DATA_BYTES = 140;
-
-    /**
-     * The maximum number of payload bytes per message if a user data header
-     * is present.  This assumes the header only contains the
-     * CONCATENATED_8_BIT_REFERENCE element.
-     */
-    public static final int MAX_USER_DATA_BYTES_WITH_HEADER = 134;
-
-    /** The maximum number of payload septets per message */
-    public static final int MAX_USER_DATA_SEPTETS = 160;
-
-    /**
-     * The maximum number of payload septets per message if a user data header
-     * is present.  This assumes the header only contains the
-     * CONCATENATED_8_BIT_REFERENCE element.
-     */
-    public static final int MAX_USER_DATA_SEPTETS_WITH_HEADER = 153;
-
-    /**
-     * Indicates a 3GPP format SMS message.
-     * @hide pending API council approval
-     */
-    public static final String FORMAT_3GPP = "3gpp";
-
-    /**
-     * Indicates a 3GPP2 format SMS message.
-     * @hide pending API council approval
-     */
-    public static final String FORMAT_3GPP2 = "3gpp2";
-
-    /** Contains actual SmsMessage. Only public for debugging and for framework layer.
-     *
-     * @hide
-     */
-    public SmsMessageBase mWrappedSmsMessage;
-
-    public static class SubmitPdu {
-
-        public byte[] encodedScAddress; // Null if not applicable.
-        public byte[] encodedMessage;
-
-        public String toString() {
-            return "SubmitPdu: encodedScAddress = "
-                    + Arrays.toString(encodedScAddress)
-                    + ", encodedMessage = "
-                    + Arrays.toString(encodedMessage);
-        }
-
-        /**
-         * @hide
-         */
-        protected SubmitPdu(SubmitPduBase spb) {
-            this.encodedMessage = spb.encodedMessage;
-            this.encodedScAddress = spb.encodedScAddress;
-        }
-
-    }
-
-    private SmsMessage(SmsMessageBase smb) {
-        mWrappedSmsMessage = smb;
-    }
-
-    /**
-     * Create an SmsMessage from a raw PDU.
-     *
-     * <p><b>This method will soon be deprecated</b> and all applications which handle
-     * incoming SMS messages by processing the {@code SMS_RECEIVED_ACTION} broadcast
-     * intent <b>must</b> now pass the new {@code format} String extra from the intent
-     * into the new method {@code createFromPdu(byte[], String)} which takes an
-     * extra format parameter. This is required in order to correctly decode the PDU on
-     * devices that require support for both 3GPP and 3GPP2 formats at the same time,
-     * such as dual-mode GSM/CDMA and CDMA/LTE phones.
-     */
-    public static SmsMessage createFromPdu(byte[] pdu) {
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-        String format = (PHONE_TYPE_CDMA == activePhone) ? FORMAT_3GPP2 : FORMAT_3GPP;
-        return createFromPdu(pdu, format);
-    }
-
-    /**
-     * Create an SmsMessage from a raw PDU with the specified message format. The
-     * message format is passed in the {@code SMS_RECEIVED_ACTION} as the {@code format}
-     * String extra, and will be either "3gpp" for GSM/UMTS/LTE messages in 3GPP format
-     * or "3gpp2" for CDMA/LTE messages in 3GPP2 format.
-     *
-     * @param pdu the message PDU from the SMS_RECEIVED_ACTION intent
-     * @param format the format extra from the SMS_RECEIVED_ACTION intent
-     * @hide pending API council approval
-     */
-    public static SmsMessage createFromPdu(byte[] pdu, String format) {
-        SmsMessageBase wrappedMessage;
-
-        if (FORMAT_3GPP2.equals(format)) {
-            wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.createFromPdu(pdu);
-        } else if (FORMAT_3GPP.equals(format)) {
-            wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.createFromPdu(pdu);
-        } else {
-            Log.e(LOG_TAG, "createFromPdu(): unsupported message format " + format);
-            return null;
-        }
-
-        return new SmsMessage(wrappedMessage);
-    }
-
-    /**
-     * TS 27.005 3.4.1 lines[0] and lines[1] are the two lines read from the
-     * +CMT unsolicited response (PDU mode, of course)
-     *  +CMT: [&lt;alpha>],<length><CR><LF><pdu>
-     *
-     * Only public for debugging and for RIL
-     *
-     * {@hide}
-     */
-    public static SmsMessage newFromCMT(String[] lines) {
-        // received SMS in 3GPP format
-        SmsMessageBase wrappedMessage =
-                com.android.internal.telephony.gsm.SmsMessage.newFromCMT(lines);
-
-        return new SmsMessage(wrappedMessage);
-    }
-
-    /** @hide */
-    public static SmsMessage newFromParcel(Parcel p) {
-        // received SMS in 3GPP2 format
-        SmsMessageBase wrappedMessage =
-                com.android.internal.telephony.cdma.SmsMessage.newFromParcel(p);
-
-        return new SmsMessage(wrappedMessage);
-    }
-
-    /**
-     * Create an SmsMessage from an SMS EF record.
-     *
-     * @param index Index of SMS record. This should be index in ArrayList
-     *              returned by SmsManager.getAllMessagesFromSim + 1.
-     * @param data Record data.
-     * @return An SmsMessage representing the record.
-     *
-     * @hide
-     */
-    public static SmsMessage createFromEfRecord(int index, byte[] data) {
-        SmsMessageBase wrappedMessage;
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
-        if (PHONE_TYPE_CDMA == activePhone) {
-            wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.createFromEfRecord(
-                    index, data);
-        } else {
-            wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.createFromEfRecord(
-                    index, data);
-        }
-
-        return wrappedMessage != null ? new SmsMessage(wrappedMessage) : null;
-    }
-
-    /**
-     * Get the TP-Layer-Length for the given SMS-SUBMIT PDU Basically, the
-     * length in bytes (not hex chars) less the SMSC header
-     *
-     * FIXME: This method is only used by a CTS test case that isn't run on CDMA devices.
-     * We should probably deprecate it and remove the obsolete test case.
-     */
-    public static int getTPLayerLengthForPDU(String pdu) {
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
-        if (PHONE_TYPE_CDMA == activePhone) {
-            return com.android.internal.telephony.cdma.SmsMessage.getTPLayerLengthForPDU(pdu);
-        } else {
-            return com.android.internal.telephony.gsm.SmsMessage.getTPLayerLengthForPDU(pdu);
-        }
-    }
-
-    /*
-     * TODO(cleanup): It would make some sense if the result of
-     * preprocessing a message to determine the proper encoding (i.e.
-     * the resulting data structure from calculateLength) could be
-     * passed as an argument to the actual final encoding function.
-     * This would better ensure that the logic behind size calculation
-     * actually matched the encoding.
-     */
-
-    /**
-     * Calculates the number of SMS's required to encode the message body and
-     * the number of characters remaining until the next message.
-     *
-     * @param msgBody the message to encode
-     * @param use7bitOnly if true, characters that are not part of the
-     *         radio-specific 7-bit encoding are counted as single
-     *         space chars.  If false, and if the messageBody contains
-     *         non-7-bit encodable characters, length is calculated
-     *         using a 16-bit encoding.
-     * @return an int[4] with int[0] being the number of SMS's
-     *         required, int[1] the number of code units used, and
-     *         int[2] is the number of code units remaining until the
-     *         next message. int[3] is an indicator of the encoding
-     *         code unit size (see the ENCODING_* definitions in this
-     *         class).
-     */
-    public static int[] calculateLength(CharSequence msgBody, boolean use7bitOnly) {
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-        TextEncodingDetails ted = (PHONE_TYPE_CDMA == activePhone) ?
-            com.android.internal.telephony.cdma.SmsMessage.calculateLength(msgBody, use7bitOnly) :
-            com.android.internal.telephony.gsm.SmsMessage.calculateLength(msgBody, use7bitOnly);
-        int ret[] = new int[4];
-        ret[0] = ted.msgCount;
-        ret[1] = ted.codeUnitCount;
-        ret[2] = ted.codeUnitsRemaining;
-        ret[3] = ted.codeUnitSize;
-        return ret;
-    }
-
-    /**
-     * Divide a message text into several fragments, none bigger than
-     * the maximum SMS message text size.
-     *
-     * @param text text, must not be null.
-     * @return an <code>ArrayList</code> of strings that, in order,
-     *   comprise the original msg text
-     *
-     * @hide
-     */
-    public static ArrayList<String> fragmentText(String text) {
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-        TextEncodingDetails ted = (PHONE_TYPE_CDMA == activePhone) ?
-            com.android.internal.telephony.cdma.SmsMessage.calculateLength(text, false) :
-            com.android.internal.telephony.gsm.SmsMessage.calculateLength(text, false);
-
-        // TODO(cleanup): The code here could be rolled into the logic
-        // below cleanly if these MAX_* constants were defined more
-        // flexibly...
-
-        int limit;
-        if (ted.codeUnitSize == ENCODING_7BIT) {
-            int udhLength;
-            if (ted.languageTable != 0 && ted.languageShiftTable != 0) {
-                udhLength = GsmAlphabet.UDH_SEPTET_COST_TWO_SHIFT_TABLES;
-            } else if (ted.languageTable != 0 || ted.languageShiftTable != 0) {
-                udhLength = GsmAlphabet.UDH_SEPTET_COST_ONE_SHIFT_TABLE;
-            } else {
-                udhLength = 0;
-            }
-
-            if (ted.msgCount > 1) {
-                udhLength += GsmAlphabet.UDH_SEPTET_COST_CONCATENATED_MESSAGE;
-            }
-
-            if (udhLength != 0) {
-                udhLength += GsmAlphabet.UDH_SEPTET_COST_LENGTH;
-            }
-
-            limit = MAX_USER_DATA_SEPTETS - udhLength;
-        } else {
-            if (ted.msgCount > 1) {
-                limit = MAX_USER_DATA_BYTES_WITH_HEADER;
-            } else {
-                limit = MAX_USER_DATA_BYTES;
-            }
-        }
-
-        int pos = 0;  // Index in code units.
-        int textLen = text.length();
-        ArrayList<String> result = new ArrayList<String>(ted.msgCount);
-        while (pos < textLen) {
-            int nextPos = 0;  // Counts code units.
-            if (ted.codeUnitSize == ENCODING_7BIT) {
-                if (activePhone == PHONE_TYPE_CDMA && ted.msgCount == 1) {
-                    // For a singleton CDMA message, the encoding must be ASCII...
-                    nextPos = pos + Math.min(limit, textLen - pos);
-                } else {
-                    // For multi-segment messages, CDMA 7bit equals GSM 7bit encoding (EMS mode).
-                    nextPos = GsmAlphabet.findGsmSeptetLimitIndex(text, pos, limit,
-                            ted.languageTable, ted.languageShiftTable);
-                }
-            } else {  // Assume unicode.
-                nextPos = pos + Math.min(limit / 2, textLen - pos);
-            }
-            if ((nextPos <= pos) || (nextPos > textLen)) {
-                Log.e(LOG_TAG, "fragmentText failed (" + pos + " >= " + nextPos + " or " +
-                          nextPos + " >= " + textLen + ")");
-                break;
-            }
-            result.add(text.substring(pos, nextPos));
-            pos = nextPos;
-        }
-        return result;
-    }
-
-    /**
-     * Calculates the number of SMS's required to encode the message body and
-     * the number of characters remaining until the next message, given the
-     * current encoding.
-     *
-     * @param messageBody the message to encode
-     * @param use7bitOnly if true, characters that are not part of the radio
-     *         specific (GSM / CDMA) alphabet encoding are converted to as a
-     *         single space characters. If false, a messageBody containing
-     *         non-GSM or non-CDMA alphabet characters are encoded using
-     *         16-bit encoding.
-     * @return an int[4] with int[0] being the number of SMS's required, int[1]
-     *         the number of code units used, and int[2] is the number of code
-     *         units remaining until the next message. int[3] is the encoding
-     *         type that should be used for the message.
-     */
-    public static int[] calculateLength(String messageBody, boolean use7bitOnly) {
-        return calculateLength((CharSequence)messageBody, use7bitOnly);
-    }
-
-    /*
-     * TODO(cleanup): It looks like there is now no useful reason why
-     * apps should generate pdus themselves using these routines,
-     * instead of handing the raw data to SMSDispatcher (and thereby
-     * have the phone process do the encoding).  Moreover, CDMA now
-     * has shared state (in the form of the msgId system property)
-     * which can only be modified by the phone process, and hence
-     * makes the output of these routines incorrect.  Since they now
-     * serve no purpose, they should probably just return null
-     * directly, and be deprecated.  Going further in that direction,
-     * the above parsers of serialized pdu data should probably also
-     * be gotten rid of, hiding all but the necessarily visible
-     * structured data from client apps.  A possible concern with
-     * doing this is that apps may be using these routines to generate
-     * pdus that are then sent elsewhere, some network server, for
-     * example, and that always returning null would thereby break
-     * otherwise useful apps.
-     */
-
-    /**
-     * Get an SMS-SUBMIT PDU for a destination address and a message.
-     * This method will not attempt to use any GSM national language 7 bit encodings.
-     *
-     * @param scAddress Service Centre address.  Null means use default.
-     * @return a <code>SubmitPdu</code> containing the encoded SC
-     *         address, if applicable, and the encoded message.
-     *         Returns null on encode error.
-     */
-    public static SubmitPdu getSubmitPdu(String scAddress,
-            String destinationAddress, String message, boolean statusReportRequested) {
-        SubmitPduBase spb;
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
-        if (PHONE_TYPE_CDMA == activePhone) {
-            spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
-                    destinationAddress, message, statusReportRequested, null);
-        } else {
-            spb = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
-                    destinationAddress, message, statusReportRequested);
-        }
-
-        return new SubmitPdu(spb);
-    }
-
-    /**
-     * Get an SMS-SUBMIT PDU for a data message to a destination address &amp; port.
-     * This method will not attempt to use any GSM national language 7 bit encodings.
-     *
-     * @param scAddress Service Centre address. null == use default
-     * @param destinationAddress the address of the destination for the message
-     * @param destinationPort the port to deliver the message to at the
-     *        destination
-     * @param data the data for the message
-     * @return a <code>SubmitPdu</code> containing the encoded SC
-     *         address, if applicable, and the encoded message.
-     *         Returns null on encode error.
-     */
-    public static SubmitPdu getSubmitPdu(String scAddress,
-            String destinationAddress, short destinationPort, byte[] data,
-            boolean statusReportRequested) {
-        SubmitPduBase spb;
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
-        if (PHONE_TYPE_CDMA == activePhone) {
-            spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
-                    destinationAddress, destinationPort, data, statusReportRequested);
-        } else {
-            spb = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
-                    destinationAddress, destinationPort, data, statusReportRequested);
-        }
-
-        return new SubmitPdu(spb);
-    }
-
-    /**
-     * Returns the address of the SMS service center that relayed this message
-     * or null if there is none.
-     */
-    public String getServiceCenterAddress() {
-        return mWrappedSmsMessage.getServiceCenterAddress();
-    }
-
-    /**
-     * Returns the originating address (sender) of this SMS message in String
-     * form or null if unavailable
-     */
-    public String getOriginatingAddress() {
-        return mWrappedSmsMessage.getOriginatingAddress();
-    }
-
-    /**
-     * Returns the originating address, or email from address if this message
-     * was from an email gateway. Returns null if originating address
-     * unavailable.
-     */
-    public String getDisplayOriginatingAddress() {
-        return mWrappedSmsMessage.getDisplayOriginatingAddress();
-    }
-
-    /**
-     * Returns the message body as a String, if it exists and is text based.
-     * @return message body is there is one, otherwise null
-     */
-    public String getMessageBody() {
-        return mWrappedSmsMessage.getMessageBody();
-    }
-
-    /**
-     * Returns the class of this message.
-     */
-    public MessageClass getMessageClass() {
-        return mWrappedSmsMessage.getMessageClass();
-    }
-
-    /**
-     * Returns the message body, or email message body if this message was from
-     * an email gateway. Returns null if message body unavailable.
-     */
-    public String getDisplayMessageBody() {
-        return mWrappedSmsMessage.getDisplayMessageBody();
-    }
-
-    /**
-     * Unofficial convention of a subject line enclosed in parens empty string
-     * if not present
-     */
-    public String getPseudoSubject() {
-        return mWrappedSmsMessage.getPseudoSubject();
-    }
-
-    /**
-     * Returns the service centre timestamp in currentTimeMillis() format
-     */
-    public long getTimestampMillis() {
-        return mWrappedSmsMessage.getTimestampMillis();
-    }
-
-    /**
-     * Returns true if message is an email.
-     *
-     * @return true if this message came through an email gateway and email
-     *         sender / subject / parsed body are available
-     */
-    public boolean isEmail() {
-        return mWrappedSmsMessage.isEmail();
-    }
-
-     /**
-     * @return if isEmail() is true, body of the email sent through the gateway.
-     *         null otherwise
-     */
-    public String getEmailBody() {
-        return mWrappedSmsMessage.getEmailBody();
-    }
-
-    /**
-     * @return if isEmail() is true, email from address of email sent through
-     *         the gateway. null otherwise
-     */
-    public String getEmailFrom() {
-        return mWrappedSmsMessage.getEmailFrom();
-    }
-
-    /**
-     * Get protocol identifier.
-     */
-    public int getProtocolIdentifier() {
-        return mWrappedSmsMessage.getProtocolIdentifier();
-    }
-
-    /**
-     * See TS 23.040 9.2.3.9 returns true if this is a "replace short message"
-     * SMS
-     */
-    public boolean isReplace() {
-        return mWrappedSmsMessage.isReplace();
-    }
-
-    /**
-     * Returns true for CPHS MWI toggle message.
-     *
-     * @return true if this is a CPHS MWI toggle message See CPHS 4.2 section
-     *         B.4.2
-     */
-    public boolean isCphsMwiMessage() {
-        return mWrappedSmsMessage.isCphsMwiMessage();
-    }
-
-    /**
-     * returns true if this message is a CPHS voicemail / message waiting
-     * indicator (MWI) clear message
-     */
-    public boolean isMWIClearMessage() {
-        return mWrappedSmsMessage.isMWIClearMessage();
-    }
-
-    /**
-     * returns true if this message is a CPHS voicemail / message waiting
-     * indicator (MWI) set message
-     */
-    public boolean isMWISetMessage() {
-        return mWrappedSmsMessage.isMWISetMessage();
-    }
-
-    /**
-     * returns true if this message is a "Message Waiting Indication Group:
-     * Discard Message" notification and should not be stored.
-     */
-    public boolean isMwiDontStore() {
-        return mWrappedSmsMessage.isMwiDontStore();
-    }
-
-    /**
-     * returns the user data section minus the user data header if one was
-     * present.
-     */
-    public byte[] getUserData() {
-        return mWrappedSmsMessage.getUserData();
-    }
-
-    /**
-     * Returns the raw PDU for the message.
-     *
-     * @return the raw PDU for the message.
-     */
-    public byte[] getPdu() {
-        return mWrappedSmsMessage.getPdu();
-    }
-
-    /**
-     * Returns the status of the message on the SIM (read, unread, sent, unsent).
-     *
-     * @return the status of the message on the SIM.  These are:
-     *         SmsManager.STATUS_ON_SIM_FREE
-     *         SmsManager.STATUS_ON_SIM_READ
-     *         SmsManager.STATUS_ON_SIM_UNREAD
-     *         SmsManager.STATUS_ON_SIM_SEND
-     *         SmsManager.STATUS_ON_SIM_UNSENT
-     * @deprecated Use getStatusOnIcc instead.
-     */
-    @Deprecated public int getStatusOnSim() {
-        return mWrappedSmsMessage.getStatusOnIcc();
-    }
-
-    /**
-     * Returns the status of the message on the ICC (read, unread, sent, unsent).
-     *
-     * @return the status of the message on the ICC.  These are:
-     *         SmsManager.STATUS_ON_ICC_FREE
-     *         SmsManager.STATUS_ON_ICC_READ
-     *         SmsManager.STATUS_ON_ICC_UNREAD
-     *         SmsManager.STATUS_ON_ICC_SEND
-     *         SmsManager.STATUS_ON_ICC_UNSENT
-     */
-    public int getStatusOnIcc() {
-        return mWrappedSmsMessage.getStatusOnIcc();
-    }
-
-    /**
-     * Returns the record index of the message on the SIM (1-based index).
-     * @return the record index of the message on the SIM, or -1 if this
-     *         SmsMessage was not created from a SIM SMS EF record.
-     * @deprecated Use getIndexOnIcc instead.
-     */
-    @Deprecated public int getIndexOnSim() {
-        return mWrappedSmsMessage.getIndexOnIcc();
-    }
-
-    /**
-     * Returns the record index of the message on the ICC (1-based index).
-     * @return the record index of the message on the ICC, or -1 if this
-     *         SmsMessage was not created from a ICC SMS EF record.
-     */
-    public int getIndexOnIcc() {
-        return mWrappedSmsMessage.getIndexOnIcc();
-    }
-
-    /**
-     * GSM:
-     * For an SMS-STATUS-REPORT message, this returns the status field from
-     * the status report.  This field indicates the status of a previously
-     * submitted SMS, if requested.  See TS 23.040, 9.2.3.15 TP-Status for a
-     * description of values.
-     * CDMA:
-     * For not interfering with status codes from GSM, the value is
-     * shifted to the bits 31-16.
-     * The value is composed of an error class (bits 25-24) and a status code (bits 23-16).
-     * Possible codes are described in C.S0015-B, v2.0, 4.5.21.
-     *
-     * @return 0 indicates the previously sent message was received.
-     *         See TS 23.040, 9.9.2.3.15 and C.S0015-B, v2.0, 4.5.21
-     *         for a description of other possible values.
-     */
-    public int getStatus() {
-        return mWrappedSmsMessage.getStatus();
-    }
-
-    /**
-     * Return true iff the message is a SMS-STATUS-REPORT message.
-     */
-    public boolean isStatusReportMessage() {
-        return mWrappedSmsMessage.isStatusReportMessage();
-    }
-
-    /**
-     * Returns true iff the <code>TP-Reply-Path</code> bit is set in
-     * this message.
-     */
-    public boolean isReplyPathPresent() {
-        return mWrappedSmsMessage.isReplyPathPresent();
-    }
-}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index bc50906..fa4b7cd 100755
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -23,15 +23,20 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemProperties;
+import android.util.Log;
 
 import com.android.internal.telephony.IPhoneSubInfo;
 import com.android.internal.telephony.ITelephony;
 import com.android.internal.telephony.ITelephonyRegistry;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.RILConstants;
 import com.android.internal.telephony.TelephonyProperties;
 
+import java.io.FileInputStream;
+import java.io.IOException;
 import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * Provides access to information about the telephony services on
@@ -131,25 +136,25 @@
      * Retrieve with
      * {@link android.content.Intent#getStringExtra(String)}.
      */
-    public static final String EXTRA_STATE = Phone.STATE_KEY;
+    public static final String EXTRA_STATE = PhoneConstants.STATE_KEY;
 
     /**
      * Value used with {@link #EXTRA_STATE} corresponding to
      * {@link #CALL_STATE_IDLE}.
      */
-    public static final String EXTRA_STATE_IDLE = Phone.State.IDLE.toString();
+    public static final String EXTRA_STATE_IDLE = PhoneConstants.State.IDLE.toString();
 
     /**
      * Value used with {@link #EXTRA_STATE} corresponding to
      * {@link #CALL_STATE_RINGING}.
      */
-    public static final String EXTRA_STATE_RINGING = Phone.State.RINGING.toString();
+    public static final String EXTRA_STATE_RINGING = PhoneConstants.State.RINGING.toString();
 
     /**
      * Value used with {@link #EXTRA_STATE} corresponding to
      * {@link #CALL_STATE_OFFHOOK}.
      */
-    public static final String EXTRA_STATE_OFFHOOK = Phone.State.OFFHOOK.toString();
+    public static final String EXTRA_STATE_OFFHOOK = PhoneConstants.State.OFFHOOK.toString();
 
     /**
      * The lookup key used with the {@link #ACTION_PHONE_STATE_CHANGED} broadcast
@@ -279,13 +284,13 @@
     }
 
     /** No phone radio. */
-    public static final int PHONE_TYPE_NONE = Phone.PHONE_TYPE_NONE;
+    public static final int PHONE_TYPE_NONE = PhoneConstants.PHONE_TYPE_NONE;
     /** Phone radio is GSM. */
-    public static final int PHONE_TYPE_GSM = Phone.PHONE_TYPE_GSM;
+    public static final int PHONE_TYPE_GSM = PhoneConstants.PHONE_TYPE_GSM;
     /** Phone radio is CDMA. */
-    public static final int PHONE_TYPE_CDMA = Phone.PHONE_TYPE_CDMA;
+    public static final int PHONE_TYPE_CDMA = PhoneConstants.PHONE_TYPE_CDMA;
     /** Phone is via SIP. */
-    public static final int PHONE_TYPE_SIP = Phone.PHONE_TYPE_SIP;
+    public static final int PHONE_TYPE_SIP = PhoneConstants.PHONE_TYPE_SIP;
 
     /**
      * Returns the current phone type.
@@ -348,8 +353,125 @@
         int mode = SystemProperties.getInt("ro.telephony.default_network", -1);
         if (mode == -1)
             return PHONE_TYPE_NONE;
-        return PhoneFactory.getPhoneType(mode);
+        return getPhoneType(mode);
     }
+
+    /**
+     * This function returns the type of the phone, depending
+     * on the network mode.
+     *
+     * @param network mode
+     * @return Phone Type
+     *
+     * @hide
+     */
+    public static int getPhoneType(int networkMode) {
+        switch(networkMode) {
+        case RILConstants.NETWORK_MODE_CDMA:
+        case RILConstants.NETWORK_MODE_CDMA_NO_EVDO:
+        case RILConstants.NETWORK_MODE_EVDO_NO_CDMA:
+            return PhoneConstants.PHONE_TYPE_CDMA;
+
+        case RILConstants.NETWORK_MODE_WCDMA_PREF:
+        case RILConstants.NETWORK_MODE_GSM_ONLY:
+        case RILConstants.NETWORK_MODE_WCDMA_ONLY:
+        case RILConstants.NETWORK_MODE_GSM_UMTS:
+            return PhoneConstants.PHONE_TYPE_GSM;
+
+        // Use CDMA Phone for the global mode including CDMA
+        case RILConstants.NETWORK_MODE_GLOBAL:
+        case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO:
+        case RILConstants.NETWORK_MODE_LTE_CMDA_EVDO_GSM_WCDMA:
+            return PhoneConstants.PHONE_TYPE_CDMA;
+
+        case RILConstants.NETWORK_MODE_LTE_ONLY:
+            if (getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE) {
+                return PhoneConstants.PHONE_TYPE_CDMA;
+            } else {
+                return PhoneConstants.PHONE_TYPE_GSM;
+            }
+        default:
+            return PhoneConstants.PHONE_TYPE_GSM;
+        }
+    }
+
+    /**
+     * The contents of the /proc/cmdline file
+     */
+    private static String getProcCmdLine()
+    {
+        String cmdline = "";
+        FileInputStream is = null;
+        try {
+            is = new FileInputStream("/proc/cmdline");
+            byte [] buffer = new byte[2048];
+            int count = is.read(buffer);
+            if (count > 0) {
+                cmdline = new String(buffer, 0, count);
+            }
+        } catch (IOException e) {
+            Log.d(TAG, "No /proc/cmdline exception=" + e);
+        } finally {
+            if (is != null) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+        Log.d(TAG, "/proc/cmdline=" + cmdline);
+        return cmdline;
+    }
+
+    /** Kernel command line */
+    private static final String sKernelCmdLine = getProcCmdLine();
+
+    /** Pattern for selecting the product type from the kernel command line */
+    private static final Pattern sProductTypePattern =
+        Pattern.compile("\\sproduct_type\\s*=\\s*(\\w+)");
+
+    /** The ProductType used for LTE on CDMA devices */
+    private static final String sLteOnCdmaProductType =
+        SystemProperties.get(TelephonyProperties.PROPERTY_LTE_ON_CDMA_PRODUCT_TYPE, "");
+
+    /**
+     * Return if the current radio is LTE on CDMA. This
+     * is a tri-state return value as for a period of time
+     * the mode may be unknown.
+     *
+     * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE}
+     * or {@link PhoneConstants#LTE_ON_CDMA_TRUE}
+     *
+     * @hide
+     */
+    public static int getLteOnCdmaModeStatic() {
+        int retVal;
+        int curVal;
+        String productType = "";
+
+        curVal = SystemProperties.getInt(TelephonyProperties.PROPERTY_LTE_ON_CDMA_DEVICE,
+                    PhoneConstants.LTE_ON_CDMA_UNKNOWN);
+        retVal = curVal;
+        if (retVal == PhoneConstants.LTE_ON_CDMA_UNKNOWN) {
+            Matcher matcher = sProductTypePattern.matcher(sKernelCmdLine);
+            if (matcher.find()) {
+                productType = matcher.group(1);
+                if (sLteOnCdmaProductType.equals(productType)) {
+                    retVal = PhoneConstants.LTE_ON_CDMA_TRUE;
+                } else {
+                    retVal = PhoneConstants.LTE_ON_CDMA_FALSE;
+                }
+            } else {
+                retVal = PhoneConstants.LTE_ON_CDMA_FALSE;
+            }
+        }
+
+        Log.d(TAG, "getLteOnCdmaMode=" + retVal + " curVal=" + curVal +
+                " product_type='" + productType +
+                "' lteOnCdmaProductType='" + sLteOnCdmaProductType + "'");
+        return retVal;
+    }
+
     //
     //
     // Current Network
@@ -695,10 +817,10 @@
             return getITelephony().getLteOnCdmaMode();
         } catch (RemoteException ex) {
             // Assume no ICC card if remote exception which shouldn't happen
-            return Phone.LTE_ON_CDMA_UNKNOWN;
+            return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
         } catch (NullPointerException ex) {
             // This could happen before phone restarts due to crashing
-            return Phone.LTE_ON_CDMA_UNKNOWN;
+            return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
         }
     }
 
diff --git a/telephony/java/android/telephony/cdma/CdmaCellLocation.java b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
index 84db830..6cfae6a 100644
--- a/telephony/java/android/telephony/cdma/CdmaCellLocation.java
+++ b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
@@ -81,14 +81,26 @@
     }
 
     /**
-     * @return cdma base station latitude, Integer.MAX_VALUE if unknown
+     * Latitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
+     * (http://www.3gpp2.org/public_html/specs/C.S0005-A_v6.0.pdf)
+     * It is represented in units of 0.25 seconds and ranges from -1296000
+     * to 1296000, both values inclusive (corresponding to a range of -90
+     * to +90 degrees). Integer.MAX_VALUE is considered invalid value.
+     *
+     * @return cdma base station latitude in units of 0.25 seconds, Integer.MAX_VALUE if unknown
      */
     public int getBaseStationLatitude() {
         return this.mBaseStationLatitude;
     }
 
     /**
-     * @return cdma base station longitude, Integer.MAX_VALUE if unknown
+     * Longitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
+     * (http://www.3gpp2.org/public_html/specs/C.S0005-A_v6.0.pdf)
+     * It is represented in units of 0.25 seconds and ranges from -2592000
+     * to 2592000, both values inclusive (corresponding to a range of -180
+     * to +180 degrees). Integer.MAX_VALUE is considered invalid value.
+     *
+     * @return cdma base station longitude in units of 0.25 seconds, Integer.MAX_VALUE if unknown
      */
     public int getBaseStationLongitude() {
         return this.mBaseStationLongitude;
@@ -215,6 +227,22 @@
                 this.mNetworkId == -1);
     }
 
+    /**
+     * Converts latitude or longitude from 0.25 seconds (as defined in the
+     * 3GPP2 C.S0005-A v6.0 standard) to decimal degrees
+     *
+     * @param quartSec latitude or longitude in 0.25 seconds units
+     * @return latitude or longitude in decimal degrees units
+     * @throws IllegalArgumentException if value is less than -2592000,
+     *                                  greater than 2592000, or is not a number.
+     */
+    public static double convertQuartSecToDecDegrees(int quartSec) {
+        if(Double.isNaN(quartSec) || quartSec < -2592000 || quartSec > 2592000){
+            // Invalid value
+            throw new IllegalArgumentException("Invalid coordiante value:" + quartSec);
+        }
+        return ((double)quartSec) / (3600 * 4);
+    }
 
 }
 
diff --git a/telephony/java/android/telephony/gsm/SmsManager.java b/telephony/java/android/telephony/gsm/SmsManager.java
deleted file mode 100644
index 3b75298..0000000
--- a/telephony/java/android/telephony/gsm/SmsManager.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * 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 android.telephony.gsm;
-
-import android.app.PendingIntent;
-
-import java.util.ArrayList;
-
-
-/**
- * Manages SMS operations such as sending data, text, and pdu SMS messages.
- * Get this object by calling the static method SmsManager.getDefault().
- * @deprecated Replaced by android.telephony.SmsManager that supports both GSM and CDMA.
- */
-@Deprecated public final class SmsManager {
-    private static SmsManager sInstance;
-    private android.telephony.SmsManager mSmsMgrProxy;
-
-    /** Get the default instance of the SmsManager
-     *
-     * @return the default instance of the SmsManager
-     * @deprecated Use android.telephony.SmsManager.
-     */
-    @Deprecated
-    public static final SmsManager getDefault() {
-        if (sInstance == null) {
-            sInstance = new SmsManager();
-        }
-        return sInstance;
-    }
-
-    @Deprecated
-    private SmsManager() {
-        mSmsMgrProxy = android.telephony.SmsManager.getDefault();
-    }
-
-    /**
-     * Send a text based SMS.
-     *
-     * @param destinationAddress the address to send the message to
-     * @param scAddress is the service center address or null to use
-     *  the current default SMSC
-     * @param text the body of the message to send
-     * @param sentIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is successfully sent, or failed.
-     *  The result code will be <code>Activity.RESULT_OK<code> for success,
-     *  or one of these errors:
-     *  <code>RESULT_ERROR_GENERIC_FAILURE</code>
-     *  <code>RESULT_ERROR_RADIO_OFF</code>
-     *  <code>RESULT_ERROR_NULL_PDU</code>.
-     *  The per-application based SMS control checks sentIntent. If sentIntent
-     *  is NULL the caller will be checked against all unknown applications,
-     *  which cause smaller number of SMS to be sent in checking period.
-     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is delivered to the recipient.  The
-     *  raw pdu of the status report is in the extended data ("pdu").
-     *
-     * @throws IllegalArgumentException if destinationAddress or text are empty
-     * @deprecated Use android.telephony.SmsManager.
-     */
-    @Deprecated
-    public final void sendTextMessage(
-            String destinationAddress, String scAddress, String text,
-            PendingIntent sentIntent, PendingIntent deliveryIntent) {
-        mSmsMgrProxy.sendTextMessage(destinationAddress, scAddress, text,
-                sentIntent, deliveryIntent);
-    }
-
-    /**
-     * Divide a text message into several messages, none bigger than
-     * the maximum SMS message size.
-     *
-     * @param text the original message.  Must not be null.
-     * @return an <code>ArrayList</code> of strings that, in order,
-     *   comprise the original message
-     * @deprecated Use android.telephony.SmsManager.
-     */
-    @Deprecated
-    public final ArrayList<String> divideMessage(String text) {
-        return mSmsMgrProxy.divideMessage(text);
-    }
-
-    /**
-     * Send a multi-part text based SMS.  The callee should have already
-     * divided the message into correctly sized parts by calling
-     * <code>divideMessage</code>.
-     *
-     * @param destinationAddress the address to send the message to
-     * @param scAddress is the service center address or null to use
-     *   the current default SMSC
-     * @param parts an <code>ArrayList</code> of strings that, in order,
-     *   comprise the original message
-     * @param sentIntents if not null, an <code>ArrayList</code> of
-     *   <code>PendingIntent</code>s (one for each message part) that is
-     *   broadcast when the corresponding message part has been sent.
-     *   The result code will be <code>Activity.RESULT_OK<code> for success,
-     *   or one of these errors:
-     *   <code>RESULT_ERROR_GENERIC_FAILURE</code>
-     *   <code>RESULT_ERROR_RADIO_OFF</code>
-     *   <code>RESULT_ERROR_NULL_PDU</code>.
-     *   The per-application based SMS control checks sentIntent. If sentIntent
-     *   is NULL the caller will be checked against all unknown applicaitons,
-     *   which cause smaller number of SMS to be sent in checking period.
-     * @param deliveryIntents if not null, an <code>ArrayList</code> of
-     *   <code>PendingIntent</code>s (one for each message part) that is
-     *   broadcast when the corresponding message part has been delivered
-     *   to the recipient.  The raw pdu of the status report is in the
-     *   extended data ("pdu").
-     *
-     * @throws IllegalArgumentException if destinationAddress or data are empty
-     * @deprecated Use android.telephony.SmsManager.
-     */
-    @Deprecated
-    public final void sendMultipartTextMessage(
-            String destinationAddress, String scAddress, ArrayList<String> parts,
-            ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {
-        mSmsMgrProxy.sendMultipartTextMessage(destinationAddress, scAddress, parts,
-                sentIntents, deliveryIntents);
-    }
-
-    /**
-     * Send a data based SMS to a specific application port.
-     *
-     * @param destinationAddress the address to send the message to
-     * @param scAddress is the service center address or null to use
-     *  the current default SMSC
-     * @param destinationPort the port to deliver the message to
-     * @param data the body of the message to send
-     * @param sentIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is sucessfully sent, or failed.
-     *  The result code will be <code>Activity.RESULT_OK<code> for success,
-     *  or one of these errors:
-     *  <code>RESULT_ERROR_GENERIC_FAILURE</code>
-     *  <code>RESULT_ERROR_RADIO_OFF</code>
-     *  <code>RESULT_ERROR_NULL_PDU</code>.
-     *  The per-application based SMS control checks sentIntent. If sentIntent
-     *  is NULL the caller will be checked against all unknown applicaitons,
-     *  which cause smaller number of SMS to be sent in checking period.
-     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is delivered to the recipient.  The
-     *  raw pdu of the status report is in the extended data ("pdu").
-     *
-     * @throws IllegalArgumentException if destinationAddress or data are empty
-     * @deprecated Use android.telephony.SmsManager.
-     */
-    @Deprecated
-    public final void sendDataMessage(
-            String destinationAddress, String scAddress, short destinationPort,
-            byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
-        mSmsMgrProxy.sendDataMessage(destinationAddress, scAddress, destinationPort,
-                data, sentIntent, deliveryIntent);
-    }
-
-    /**
-     * Copy a raw SMS PDU to the SIM.
-     *
-     * @param smsc the SMSC for this message, or NULL for the default SMSC
-     * @param pdu the raw PDU to store
-     * @param status message status (STATUS_ON_SIM_READ, STATUS_ON_SIM_UNREAD,
-     *               STATUS_ON_SIM_SENT, STATUS_ON_SIM_UNSENT)
-     * @return true for success
-     * @deprecated Use android.telephony.SmsManager.
-     * {@hide}
-     */
-    @Deprecated
-    public final boolean copyMessageToSim(byte[] smsc, byte[] pdu, int status) {
-        return mSmsMgrProxy.copyMessageToIcc(smsc, pdu, status);
-    }
-
-    /**
-     * Delete the specified message from the SIM.
-     *
-     * @param messageIndex is the record index of the message on SIM
-     * @return true for success
-     * @deprecated Use android.telephony.SmsManager.
-     * {@hide}
-     */
-    @Deprecated
-    public final boolean deleteMessageFromSim(int messageIndex) {
-        return mSmsMgrProxy.deleteMessageFromIcc(messageIndex);
-    }
-
-    /**
-     * Update the specified message on the SIM.
-     *
-     * @param messageIndex record index of message to update
-     * @param newStatus new message status (STATUS_ON_SIM_READ,
-     *                  STATUS_ON_SIM_UNREAD, STATUS_ON_SIM_SENT,
-     *                  STATUS_ON_SIM_UNSENT, STATUS_ON_SIM_FREE)
-     * @param pdu the raw PDU to store
-     * @return true for success
-     * @deprecated Use android.telephony.SmsManager.
-     * {@hide}
-     */
-    @Deprecated
-    public final boolean updateMessageOnSim(int messageIndex, int newStatus, byte[] pdu) {
-        return mSmsMgrProxy.updateMessageOnIcc(messageIndex, newStatus, pdu);
-    }
-
-    /**
-     * Retrieves all messages currently stored on SIM.
-     * @return <code>ArrayList</code> of <code>SmsMessage</code> objects
-     * @deprecated Use android.telephony.SmsManager.
-     * {@hide}
-     */
-    @Deprecated
-    public final ArrayList<android.telephony.SmsMessage> getAllMessagesFromSim() {
-        return mSmsMgrProxy.getAllMessagesFromIcc();
-    }
-
-    /** Free space (TS 51.011 10.5.3).
-     *  @deprecated Use android.telephony.SmsManager. */
-    @Deprecated static public final int STATUS_ON_SIM_FREE      = 0;
-
-    /** Received and read (TS 51.011 10.5.3).
-     * @deprecated Use android.telephony.SmsManager. */
-    @Deprecated static public final int STATUS_ON_SIM_READ      = 1;
-
-    /** Received and unread (TS 51.011 10.5.3).
-     * @deprecated Use android.telephony.SmsManager. */
-    @Deprecated static public final int STATUS_ON_SIM_UNREAD    = 3;
-
-    /** Stored and sent (TS 51.011 10.5.3).
-     * @deprecated Use android.telephony.SmsManager. */
-    @Deprecated static public final int STATUS_ON_SIM_SENT      = 5;
-
-    /** Stored and unsent (TS 51.011 10.5.3).
-     * @deprecated Use android.telephony.SmsManager. */
-    @Deprecated static public final int STATUS_ON_SIM_UNSENT    = 7;
-
-    /** Generic failure cause
-     * @deprecated Use android.telephony.SmsManager. */
-    @Deprecated static public final int RESULT_ERROR_GENERIC_FAILURE    = 1;
-
-    /** Failed because radio was explicitly turned off
-     * @deprecated Use android.telephony.SmsManager. */
-    @Deprecated static public final int RESULT_ERROR_RADIO_OFF          = 2;
-
-    /** Failed because no pdu provided
-     * @deprecated Use android.telephony.SmsManager. */
-    @Deprecated static public final int RESULT_ERROR_NULL_PDU           = 3;
-
-    /** Failed because service is currently unavailable
-     * @deprecated Use android.telephony.SmsManager. */
-    @Deprecated static public final int RESULT_ERROR_NO_SERVICE         = 4;
-
-}
diff --git a/telephony/java/android/telephony/gsm/SmsMessage.java b/telephony/java/android/telephony/gsm/SmsMessage.java
deleted file mode 100644
index 8d86ec2..0000000
--- a/telephony/java/android/telephony/gsm/SmsMessage.java
+++ /dev/null
@@ -1,628 +0,0 @@
-/*
- * 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 android.telephony.gsm;
-
-import android.os.Parcel;
-import android.telephony.TelephonyManager;
-
-import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.EncodeException;
-import com.android.internal.telephony.SmsHeader;
-import com.android.internal.telephony.SmsMessageBase;
-import com.android.internal.telephony.SmsMessageBase.SubmitPduBase;
-
-import java.util.Arrays;
-
-import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA;
-
-
-/**
- * A Short Message Service message.
- * @deprecated Replaced by android.telephony.SmsMessage that supports both GSM and CDMA.
- */
-@Deprecated
-public class SmsMessage {
-    private static final boolean LOCAL_DEBUG = true;
-    private static final String LOG_TAG = "SMS";
-
-    /**
-     * SMS Class enumeration.
-     * See TS 23.038.
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public enum MessageClass{
-        UNKNOWN, CLASS_0, CLASS_1, CLASS_2, CLASS_3;
-    }
-
-    /** Unknown encoding scheme (see TS 23.038)
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated public static final int ENCODING_UNKNOWN = 0;
-
-    /** 7-bit encoding scheme (see TS 23.038)
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated public static final int ENCODING_7BIT = 1;
-
-    /** 8-bit encoding scheme (see TS 23.038)
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated public static final int ENCODING_8BIT = 2;
-
-    /** 16-bit encoding scheme (see TS 23.038)
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated public static final int ENCODING_16BIT = 3;
-
-    /** The maximum number of payload bytes per message
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated public static final int MAX_USER_DATA_BYTES = 140;
-
-    /**
-     * The maximum number of payload bytes per message if a user data header
-     * is present.  This assumes the header only contains the
-     * CONCATENATED_8_BIT_REFERENCE element.
-     *
-     * @deprecated Use android.telephony.SmsMessage.
-     * @hide pending API Council approval to extend the public API
-     */
-    @Deprecated public static final int MAX_USER_DATA_BYTES_WITH_HEADER = 134;
-
-    /** The maximum number of payload septets per message
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated public static final int MAX_USER_DATA_SEPTETS = 160;
-
-    /**
-     * The maximum number of payload septets per message if a user data header
-     * is present.  This assumes the header only contains the
-     * CONCATENATED_8_BIT_REFERENCE element.
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated public static final int MAX_USER_DATA_SEPTETS_WITH_HEADER = 153;
-
-    /** Contains actual SmsMessage. Only public for debugging and for framework layer.
-     * @deprecated Use android.telephony.SmsMessage.
-     * {@hide}
-     */
-    @Deprecated public SmsMessageBase mWrappedSmsMessage;
-
-    /** @deprecated Use android.telephony.SmsMessage. */
-    @Deprecated
-    public static class SubmitPdu {
-        /** @deprecated Use android.telephony.SmsMessage. */
-        @Deprecated public byte[] encodedScAddress; // Null if not applicable.
-        /** @deprecated Use android.telephony.SmsMessage. */
-        @Deprecated public byte[] encodedMessage;
-
-        //Constructor
-        /** @deprecated Use android.telephony.SmsMessage. */
-        @Deprecated
-        public SubmitPdu() {
-        }
-
-        /** @deprecated Use android.telephony.SmsMessage.
-         * {@hide}
-         */
-        @Deprecated
-        protected SubmitPdu(SubmitPduBase spb) {
-            this.encodedMessage = spb.encodedMessage;
-            this.encodedScAddress = spb.encodedScAddress;
-        }
-
-        /** @deprecated Use android.telephony.SmsMessage. */
-        @Deprecated
-        public String toString() {
-            return "SubmitPdu: encodedScAddress = "
-                    + Arrays.toString(encodedScAddress)
-                    + ", encodedMessage = "
-                    + Arrays.toString(encodedMessage);
-        }
-    }
-
-    // Constructor
-    /** @deprecated Use android.telephony.SmsMessage. */
-    @Deprecated
-    public SmsMessage() {
-        this(getSmsFacility());
-    }
-
-    private SmsMessage(SmsMessageBase smb) {
-        mWrappedSmsMessage = smb;
-    }
-
-    /**
-     * Create an SmsMessage from a raw PDU.
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public static SmsMessage createFromPdu(byte[] pdu) {
-        SmsMessageBase wrappedMessage;
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
-        if (PHONE_TYPE_CDMA == activePhone) {
-            wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.createFromPdu(pdu);
-        } else {
-            wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.createFromPdu(pdu);
-        }
-
-        return new SmsMessage(wrappedMessage);
-    }
-
-    /**
-     * Get the TP-Layer-Length for the given SMS-SUBMIT PDU Basically, the
-     * length in bytes (not hex chars) less the SMSC header
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public static int getTPLayerLengthForPDU(String pdu) {
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
-        if (PHONE_TYPE_CDMA == activePhone) {
-            return com.android.internal.telephony.cdma.SmsMessage.getTPLayerLengthForPDU(pdu);
-        } else {
-            return com.android.internal.telephony.gsm.SmsMessage.getTPLayerLengthForPDU(pdu);
-        }
-    }
-
-    /**
-     * Calculates the number of SMS's required to encode the message body and
-     * the number of characters remaining until the next message, given the
-     * current encoding.
-     *
-     * @param messageBody the message to encode
-     * @param use7bitOnly if true, characters that are not part of the GSM
-     *         alphabet are counted as a single space char.  If false, a
-     *         messageBody containing non-GSM alphabet characters is calculated
-     *         for 16-bit encoding.
-     * @return an int[4] with int[0] being the number of SMS's required, int[1]
-     *         the number of code units used, and int[2] is the number of code
-     *         units remaining until the next message. int[3] is the encoding
-     *         type that should be used for the message.
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public static int[] calculateLength(CharSequence messageBody, boolean use7bitOnly) {
-        SmsMessageBase.TextEncodingDetails ted =
-                com.android.internal.telephony.gsm.SmsMessage
-                        .calculateLength(messageBody, use7bitOnly);
-        int ret[] = new int[4];
-        ret[0] = ted.msgCount;
-        ret[1] = ted.codeUnitCount;
-        ret[2] = ted.codeUnitsRemaining;
-        ret[3] = ted.codeUnitSize;
-        return ret;
-    }
-
-    /**
-     * Calculates the number of SMS's required to encode the message body and
-     * the number of characters remaining until the next message, given the
-     * current encoding.
-     *
-     * @param messageBody the message to encode
-     * @param use7bitOnly if true, characters that are not part of the GSM
-     *         alphabet are counted as a single space char.  If false, a
-     *         messageBody containing non-GSM alphabet characters is calculated
-     *         for 16-bit encoding.
-     * @return an int[4] with int[0] being the number of SMS's required, int[1]
-     *         the number of code units used, and int[2] is the number of code
-     *         units remaining until the next message. int[3] is the encoding
-     *         type that should be used for the message.
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public static int[] calculateLength(String messageBody, boolean use7bitOnly) {
-        return calculateLength((CharSequence)messageBody, use7bitOnly);
-    }
-
-    /**
-     * Get an SMS-SUBMIT PDU for a destination address and a message
-     *
-     * @param scAddress Service Centre address.  Null means use default.
-     * @return a <code>SubmitPdu</code> containing the encoded SC
-     *         address, if applicable, and the encoded message.
-     *         Returns null on encode error.
-     * @deprecated Use android.telephony.SmsMessage.
-     * @hide
-     */
-    @Deprecated
-    public static SubmitPdu getSubmitPdu(String scAddress,
-            String destinationAddress, String message,
-            boolean statusReportRequested, byte[] header) {
-        SubmitPduBase spb;
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
-        if (PHONE_TYPE_CDMA == activePhone) {
-            spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
-                    destinationAddress, message, statusReportRequested,
-                    SmsHeader.fromByteArray(header));
-        } else {
-            spb = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
-                    destinationAddress, message, statusReportRequested, header);
-        }
-
-        return new SubmitPdu(spb);
-    }
-
-    /**
-     * Get an SMS-SUBMIT PDU for a destination address and a message
-     *
-     * @param scAddress Service Centre address.  Null means use default.
-     * @return a <code>SubmitPdu</code> containing the encoded SC
-     *         address, if applicable, and the encoded message.
-     *         Returns null on encode error.
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public static SubmitPdu getSubmitPdu(String scAddress,
-            String destinationAddress, String message, boolean statusReportRequested) {
-        SubmitPduBase spb;
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
-        if (PHONE_TYPE_CDMA == activePhone) {
-            spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
-                    destinationAddress, message, statusReportRequested, null);
-        } else {
-            spb = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
-                    destinationAddress, message, statusReportRequested);
-        }
-
-        return new SubmitPdu(spb);
-    }
-
-    /**
-     * Get an SMS-SUBMIT PDU for a data message to a destination address &amp; port
-     *
-     * @param scAddress Service Centre address. null == use default
-     * @param destinationAddress the address of the destination for the message
-     * @param destinationPort the port to deliver the message to at the
-     *        destination
-     * @param data the dat for the message
-     * @return a <code>SubmitPdu</code> containing the encoded SC
-     *         address, if applicable, and the encoded message.
-     *         Returns null on encode error.
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public static SubmitPdu getSubmitPdu(String scAddress,
-            String destinationAddress, short destinationPort, byte[] data,
-            boolean statusReportRequested) {
-        SubmitPduBase spb;
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
-        if (PHONE_TYPE_CDMA == activePhone) {
-            spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
-                    destinationAddress, destinationPort, data, statusReportRequested);
-        } else {
-            spb = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
-                    destinationAddress, destinationPort, data, statusReportRequested);
-        }
-
-        return new SubmitPdu(spb);
-    }
-
-    /**
-     * Returns the address of the SMS service center that relayed this message
-     * or null if there is none.
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public String getServiceCenterAddress() {
-        return mWrappedSmsMessage.getServiceCenterAddress();
-    }
-
-    /**
-     * Returns the originating address (sender) of this SMS message in String
-     * form or null if unavailable
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public String getOriginatingAddress() {
-        return mWrappedSmsMessage.getOriginatingAddress();
-    }
-
-    /**
-     * Returns the originating address, or email from address if this message
-     * was from an email gateway. Returns null if originating address
-     * unavailable.
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public String getDisplayOriginatingAddress() {
-        return mWrappedSmsMessage.getDisplayOriginatingAddress();
-    }
-
-    /**
-     * Returns the message body as a String, if it exists and is text based.
-     * @return message body is there is one, otherwise null
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public String getMessageBody() {
-        return mWrappedSmsMessage.getMessageBody();
-    }
-
-    /**
-     * Returns the class of this message.
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public MessageClass getMessageClass() {
-        int index = mWrappedSmsMessage.getMessageClass().ordinal();
-
-        return MessageClass.values()[index];
-    }
-
-    /**
-     * Returns the message body, or email message body if this message was from
-     * an email gateway. Returns null if message body unavailable.
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public String getDisplayMessageBody() {
-        return mWrappedSmsMessage.getDisplayMessageBody();
-    }
-
-    /**
-     * Unofficial convention of a subject line enclosed in parens empty string
-     * if not present
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public String getPseudoSubject() {
-        return mWrappedSmsMessage.getPseudoSubject();
-    }
-
-    /**
-     * Returns the service centre timestamp in currentTimeMillis() format
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public long getTimestampMillis() {
-        return mWrappedSmsMessage.getTimestampMillis();
-    }
-
-    /**
-     * Returns true if message is an email.
-     *
-     * @return true if this message came through an email gateway and email
-     *         sender / subject / parsed body are available
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public boolean isEmail() {
-        return mWrappedSmsMessage.isEmail();
-    }
-
-     /**
-     * @return if isEmail() is true, body of the email sent through the gateway.
-     *         null otherwise
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public String getEmailBody() {
-        return mWrappedSmsMessage.getEmailBody();
-    }
-
-    /**
-     * @return if isEmail() is true, email from address of email sent through
-     *         the gateway. null otherwise
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public String getEmailFrom() {
-        return mWrappedSmsMessage.getEmailFrom();
-    }
-
-    /**
-     * Get protocol identifier.
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public int getProtocolIdentifier() {
-        return mWrappedSmsMessage.getProtocolIdentifier();
-    }
-
-    /**
-     * See TS 23.040 9.2.3.9 returns true if this is a "replace short message" SMS
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public boolean isReplace() {
-        return mWrappedSmsMessage.isReplace();
-    }
-
-    /**
-     * Returns true for CPHS MWI toggle message.
-     *
-     * @return true if this is a CPHS MWI toggle message See CPHS 4.2 section B.4.2
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public boolean isCphsMwiMessage() {
-        return mWrappedSmsMessage.isCphsMwiMessage();
-    }
-
-    /**
-     * returns true if this message is a CPHS voicemail / message waiting
-     * indicator (MWI) clear message
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public boolean isMWIClearMessage() {
-        return mWrappedSmsMessage.isMWIClearMessage();
-    }
-
-    /**
-     * returns true if this message is a CPHS voicemail / message waiting
-     * indicator (MWI) set message
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public boolean isMWISetMessage() {
-        return mWrappedSmsMessage.isMWISetMessage();
-    }
-
-    /**
-     * returns true if this message is a "Message Waiting Indication Group:
-     * Discard Message" notification and should not be stored.
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public boolean isMwiDontStore() {
-        return mWrappedSmsMessage.isMwiDontStore();
-    }
-
-    /**
-     * returns the user data section minus the user data header if one was present.
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public byte[] getUserData() {
-        return mWrappedSmsMessage.getUserData();
-    }
-
-    /* Not part of the SDK interface and only needed by specific classes:
-       protected SmsHeader getUserDataHeader()
-    */
-
-    /**
-     * Returns the raw PDU for the message.
-     *
-     * @return the raw PDU for the message.
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public byte[] getPdu() {
-        return mWrappedSmsMessage.getPdu();
-    }
-
-    /**
-     * Returns the status of the message on the SIM (read, unread, sent, unsent).
-     *
-     * @return the status of the message on the SIM.  These are:
-     *         SmsManager.STATUS_ON_SIM_FREE
-     *         SmsManager.STATUS_ON_SIM_READ
-     *         SmsManager.STATUS_ON_SIM_UNREAD
-     *         SmsManager.STATUS_ON_SIM_SEND
-     *         SmsManager.STATUS_ON_SIM_UNSENT
-     * @deprecated Use android.telephony.SmsMessage and getStatusOnIcc instead.
-     */
-    @Deprecated
-    public int getStatusOnSim() {
-        return mWrappedSmsMessage.getStatusOnIcc();
-    }
-
-    /**
-     * Returns the status of the message on the ICC (read, unread, sent, unsent).
-     *
-     * @return the status of the message on the ICC.  These are:
-     *         SmsManager.STATUS_ON_ICC_FREE
-     *         SmsManager.STATUS_ON_ICC_READ
-     *         SmsManager.STATUS_ON_ICC_UNREAD
-     *         SmsManager.STATUS_ON_ICC_SEND
-     *         SmsManager.STATUS_ON_ICC_UNSENT
-     * @deprecated Use android.telephony.SmsMessage.
-     * @hide
-     */
-    @Deprecated
-    public int getStatusOnIcc() {
-
-        return mWrappedSmsMessage.getStatusOnIcc();
-    }
-
-    /**
-     * Returns the record index of the message on the SIM (1-based index).
-     * @return the record index of the message on the SIM, or -1 if this
-     *         SmsMessage was not created from a SIM SMS EF record.
-     * @deprecated Use android.telephony.SmsMessage and getIndexOnIcc instead.
-     */
-    @Deprecated
-    public int getIndexOnSim() {
-        return mWrappedSmsMessage.getIndexOnIcc();
-    }
-
-    /**
-     * Returns the record index of the message on the ICC (1-based index).
-     * @return the record index of the message on the ICC, or -1 if this
-     *         SmsMessage was not created from a ICC SMS EF record.
-     * @deprecated Use android.telephony.SmsMessage.
-     * @hide
-     */
-    @Deprecated
-    public int getIndexOnIcc() {
-
-        return mWrappedSmsMessage.getIndexOnIcc();
-    }
-
-    /**
-     * GSM:
-     * For an SMS-STATUS-REPORT message, this returns the status field from
-     * the status report.  This field indicates the status of a previously
-     * submitted SMS, if requested.  See TS 23.040, 9.2.3.15 TP-Status for a
-     * description of values.
-     * CDMA:
-     * For not interfering with status codes from GSM, the value is
-     * shifted to the bits 31-16.
-     * The value is composed of an error class (bits 25-24) and a status code (bits 23-16).
-     * Possible codes are described in C.S0015-B, v2.0, 4.5.21.
-     *
-     * @return 0 indicates the previously sent message was received.
-     *         See TS 23.040, 9.9.2.3.15 and C.S0015-B, v2.0, 4.5.21
-     *         for a description of other possible values.
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public int getStatus() {
-        return mWrappedSmsMessage.getStatus();
-    }
-
-    /**
-     * Return true iff the message is a SMS-STATUS-REPORT message.
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public boolean isStatusReportMessage() {
-        return mWrappedSmsMessage.isStatusReportMessage();
-    }
-
-    /**
-     * Returns true iff the <code>TP-Reply-Path</code> bit is set in
-     * this message.
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    @Deprecated
-    public boolean isReplyPathPresent() {
-        return mWrappedSmsMessage.isReplyPathPresent();
-    }
-
-    /** This method returns the reference to a specific
-     *  SmsMessage object, which is used for accessing its static methods.
-     * @return Specific SmsMessage.
-     * @deprecated Use android.telephony.SmsMessage.
-     */
-    private static final SmsMessageBase getSmsFacility(){
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-        if (PHONE_TYPE_CDMA == activePhone) {
-            return new com.android.internal.telephony.cdma.SmsMessage();
-        } else {
-            return new com.android.internal.telephony.gsm.SmsMessage();
-        }
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/ATParseEx.java b/telephony/java/com/android/internal/telephony/ATParseEx.java
deleted file mode 100644
index c93b875..0000000
--- a/telephony/java/com/android/internal/telephony/ATParseEx.java
+++ /dev/null
@@ -1,35 +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.internal.telephony;
-
-/**
- * {@hide}
- */
-public class ATParseEx extends RuntimeException
-{
-    public
-    ATParseEx()
-    {
-        super();
-    }
-
-    public
-    ATParseEx(String s)
-    {
-        super(s);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/ATResponseParser.java b/telephony/java/com/android/internal/telephony/ATResponseParser.java
deleted file mode 100644
index fdb0526..0000000
--- a/telephony/java/com/android/internal/telephony/ATResponseParser.java
+++ /dev/null
@@ -1,186 +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.internal.telephony;
-
-/**
- * {@hide}
- */
-public class ATResponseParser
-{
-    /*************************** Instance Variables **************************/
-
-    private String line;
-    private int next = 0;
-    private int tokStart, tokEnd;
-
-    /***************************** Class Methods *****************************/
-
-    public
-    ATResponseParser (String line)
-    {
-        this.line = line;
-    }
-
-    public boolean
-    nextBoolean()
-    {
-        // "\s*(\d)(,|$)"
-        // \d is '0' or '1'
-
-        nextTok();
-
-        if (tokEnd - tokStart > 1) {
-            throw new ATParseEx();
-        }
-        char c = line.charAt(tokStart);
-
-        if (c == '0') return false;
-        if (c ==  '1') return true;
-        throw new ATParseEx();
-    }
-
-
-    /** positive int only */
-    public int
-    nextInt()
-    {
-        // "\s*(\d+)(,|$)"
-        int ret = 0;
-
-        nextTok();
-
-        for (int i = tokStart ; i < tokEnd ; i++) {
-            char c = line.charAt(i);
-
-            // Yes, ASCII decimal digits only
-            if (c < '0' || c > '9') {
-                throw new ATParseEx();
-            }
-
-            ret *= 10;
-            ret += c - '0';
-        }
-
-        return ret;
-    }
-
-    public String
-    nextString()
-    {
-        nextTok();
-
-        return line.substring(tokStart, tokEnd);
-    }
-
-    public boolean
-    hasMore()
-    {
-        return next < line.length();
-    }
-
-    private void
-    nextTok()
-    {
-        int len = line.length();
-
-        if (next == 0) {
-            skipPrefix();
-        }
-
-        if (next >= len) {
-            throw new ATParseEx();
-        }
-
-        try {
-            // \s*("([^"]*)"|(.*)\s*)(,|$)
-
-            char c = line.charAt(next++);
-            boolean hasQuote = false;
-
-            c = skipWhiteSpace(c);
-
-            if (c == '"') {
-                if (next >= len) {
-                    throw new ATParseEx();
-                }
-                c = line.charAt(next++);
-                tokStart = next - 1;
-                while (c != '"' && next < len) {
-                    c = line.charAt(next++);
-                }
-                if (c != '"') {
-                    throw new ATParseEx();
-                }
-                tokEnd = next - 1;
-                if (next < len && line.charAt(next++) != ',') {
-                    throw new ATParseEx();
-                }
-            } else {
-                tokStart = next - 1;
-                tokEnd = tokStart;
-                while (c != ',') {
-                    if (!Character.isWhitespace(c)) {
-                        tokEnd = next;
-                    }
-                    if (next == len) {
-                        break;
-                    }
-                    c = line.charAt(next++);
-                }
-            }
-        } catch (StringIndexOutOfBoundsException ex) {
-            throw new ATParseEx();
-        }
-    }
-
-
-    /** Throws ATParseEx if whitespace extends to the end of string */
-    private char
-    skipWhiteSpace (char c)
-    {
-        int len;
-        len = line.length();
-        while (next < len && Character.isWhitespace(c)) {
-            c = line.charAt(next++);
-        }
-
-        if (Character.isWhitespace(c)) {
-            throw new ATParseEx();
-        }
-        return c;
-    }
-
-
-    private void
-    skipPrefix()
-    {
-        // consume "^[^:]:"
-
-        next = 0;
-        int s = line.length();
-        while (next < s){
-            char c = line.charAt(next++);
-
-            if (c == ':') {
-                return;
-            }
-        }
-
-        throw new ATParseEx("missing prefix");
-    }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/AdnRecord.aidl b/telephony/java/com/android/internal/telephony/AdnRecord.aidl
deleted file mode 100644
index b4a1a29..0000000
--- a/telephony/java/com/android/internal/telephony/AdnRecord.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
-** Copyright 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.internal.telephony;
-
-parcelable AdnRecord;
-
diff --git a/telephony/java/com/android/internal/telephony/AdnRecord.java b/telephony/java/com/android/internal/telephony/AdnRecord.java
deleted file mode 100644
index 1bf2d3c..0000000
--- a/telephony/java/com/android/internal/telephony/AdnRecord.java
+++ /dev/null
@@ -1,321 +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.internal.telephony;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.telephony.PhoneNumberUtils;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.util.Arrays;
-
-
-/**
- *
- * Used to load or store ADNs (Abbreviated Dialing Numbers).
- *
- * {@hide}
- *
- */
-public class AdnRecord implements Parcelable {
-    static final String LOG_TAG = "GSM";
-
-    //***** Instance Variables
-
-    String alphaTag = null;
-    String number = null;
-    String[] emails;
-    int extRecord = 0xff;
-    int efid;                   // or 0 if none
-    int recordNumber;           // or 0 if none
-
-
-    //***** Constants
-
-    // In an ADN record, everything but the alpha identifier
-    // is in a footer that's 14 bytes
-    static final int FOOTER_SIZE_BYTES = 14;
-
-    // Maximum size of the un-extended number field
-    static final int MAX_NUMBER_SIZE_BYTES = 11;
-
-    static final int EXT_RECORD_LENGTH_BYTES = 13;
-    static final int EXT_RECORD_TYPE_ADDITIONAL_DATA = 2;
-    static final int EXT_RECORD_TYPE_MASK = 3;
-    static final int MAX_EXT_CALLED_PARTY_LENGTH = 0xa;
-
-    // ADN offset
-    static final int ADN_BCD_NUMBER_LENGTH = 0;
-    static final int ADN_TON_AND_NPI = 1;
-    static final int ADN_DIALING_NUMBER_START = 2;
-    static final int ADN_DIALING_NUMBER_END = 11;
-    static final int ADN_CAPABILITY_ID = 12;
-    static final int ADN_EXTENSION_ID = 13;
-
-    //***** Static Methods
-
-    public static final Parcelable.Creator<AdnRecord> CREATOR
-            = new Parcelable.Creator<AdnRecord>() {
-        public AdnRecord createFromParcel(Parcel source) {
-            int efid;
-            int recordNumber;
-            String alphaTag;
-            String number;
-            String[] emails;
-
-            efid = source.readInt();
-            recordNumber = source.readInt();
-            alphaTag = source.readString();
-            number = source.readString();
-            emails = source.readStringArray();
-
-            return new AdnRecord(efid, recordNumber, alphaTag, number, emails);
-        }
-
-        public AdnRecord[] newArray(int size) {
-            return new AdnRecord[size];
-        }
-    };
-
-
-    //***** Constructor
-    public AdnRecord (byte[] record) {
-        this(0, 0, record);
-    }
-
-    public AdnRecord (int efid, int recordNumber, byte[] record) {
-        this.efid = efid;
-        this.recordNumber = recordNumber;
-        parseRecord(record);
-    }
-
-    public AdnRecord (String alphaTag, String number) {
-        this(0, 0, alphaTag, number);
-    }
-
-    public AdnRecord (String alphaTag, String number, String[] emails) {
-        this(0, 0, alphaTag, number, emails);
-    }
-
-    public AdnRecord (int efid, int recordNumber, String alphaTag, String number, String[] emails) {
-        this.efid = efid;
-        this.recordNumber = recordNumber;
-        this.alphaTag = alphaTag;
-        this.number = number;
-        this.emails = emails;
-    }
-
-    public AdnRecord(int efid, int recordNumber, String alphaTag, String number) {
-        this.efid = efid;
-        this.recordNumber = recordNumber;
-        this.alphaTag = alphaTag;
-        this.number = number;
-        this.emails = null;
-    }
-
-    //***** Instance Methods
-
-    public String getAlphaTag() {
-        return alphaTag;
-    }
-
-    public String getNumber() {
-        return number;
-    }
-
-    public String[] getEmails() {
-        return emails;
-    }
-
-    public void setEmails(String[] emails) {
-        this.emails = emails;
-    }
-
-    public String toString() {
-        return "ADN Record '" + alphaTag + "' '" + number + " " + emails + "'";
-    }
-
-    public boolean isEmpty() {
-        return TextUtils.isEmpty(alphaTag) && TextUtils.isEmpty(number) && emails == null;
-    }
-
-    public boolean hasExtendedRecord() {
-        return extRecord != 0 && extRecord != 0xff;
-    }
-
-    /** Helper function for {@link #isEqual}. */
-    private static boolean stringCompareNullEqualsEmpty(String s1, String s2) {
-        if (s1 == s2) {
-            return true;
-        }
-        if (s1 == null) {
-            s1 = "";
-        }
-        if (s2 == null) {
-            s2 = "";
-        }
-        return (s1.equals(s2));
-    }
-
-    public boolean isEqual(AdnRecord adn) {
-        return ( stringCompareNullEqualsEmpty(alphaTag, adn.alphaTag) &&
-                stringCompareNullEqualsEmpty(number, adn.number) &&
-                Arrays.equals(emails, adn.emails));
-    }
-    //***** Parcelable Implementation
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(efid);
-        dest.writeInt(recordNumber);
-        dest.writeString(alphaTag);
-        dest.writeString(number);
-        dest.writeStringArray(emails);
-    }
-
-    /**
-     * Build adn hex byte array based on record size
-     * The format of byte array is defined in 51.011 10.5.1
-     *
-     * @param recordSize is the size X of EF record
-     * @return hex byte[recordSize] to be written to EF record
-     *          return null for wrong format of dialing number or tag
-     */
-    public byte[] buildAdnString(int recordSize) {
-        byte[] bcdNumber;
-        byte[] byteTag;
-        byte[] adnString;
-        int footerOffset = recordSize - FOOTER_SIZE_BYTES;
-
-        // create an empty record
-        adnString = new byte[recordSize];
-        for (int i = 0; i < recordSize; i++) {
-            adnString[i] = (byte) 0xFF;
-        }
-
-        if (TextUtils.isEmpty(number)) {
-            Log.w(LOG_TAG, "[buildAdnString] Empty dialing number");
-            return adnString;   // return the empty record (for delete)
-        } else if (number.length()
-                > (ADN_DIALING_NUMBER_END - ADN_DIALING_NUMBER_START + 1) * 2) {
-            Log.w(LOG_TAG,
-                    "[buildAdnString] Max length of dialing number is 20");
-            return null;
-        } else if (alphaTag != null && alphaTag.length() > footerOffset) {
-            Log.w(LOG_TAG,
-                    "[buildAdnString] Max length of tag is " + footerOffset);
-            return null;
-        } else {
-            bcdNumber = PhoneNumberUtils.numberToCalledPartyBCD(number);
-
-            System.arraycopy(bcdNumber, 0, adnString,
-                    footerOffset + ADN_TON_AND_NPI, bcdNumber.length);
-
-            adnString[footerOffset + ADN_BCD_NUMBER_LENGTH]
-                    = (byte) (bcdNumber.length);
-            adnString[footerOffset + ADN_CAPABILITY_ID]
-                    = (byte) 0xFF; // Capability Id
-            adnString[footerOffset + ADN_EXTENSION_ID]
-                    = (byte) 0xFF; // Extension Record Id
-
-            if (!TextUtils.isEmpty(alphaTag)) {
-                byteTag = GsmAlphabet.stringToGsm8BitPacked(alphaTag);
-                System.arraycopy(byteTag, 0, adnString, 0, byteTag.length);
-            }
-
-            return adnString;
-        }
-    }
-
-    /**
-     * See TS 51.011 10.5.10
-     */
-    public void
-    appendExtRecord (byte[] extRecord) {
-        try {
-            if (extRecord.length != EXT_RECORD_LENGTH_BYTES) {
-                return;
-            }
-
-            if ((extRecord[0] & EXT_RECORD_TYPE_MASK)
-                    != EXT_RECORD_TYPE_ADDITIONAL_DATA) {
-                return;
-            }
-
-            if ((0xff & extRecord[1]) > MAX_EXT_CALLED_PARTY_LENGTH) {
-                // invalid or empty record
-                return;
-            }
-
-            number += PhoneNumberUtils.calledPartyBCDFragmentToString(
-                                        extRecord, 2, 0xff & extRecord[1]);
-
-            // We don't support ext record chaining.
-
-        } catch (RuntimeException ex) {
-            Log.w(LOG_TAG, "Error parsing AdnRecord ext record", ex);
-        }
-    }
-
-    //***** Private Methods
-
-    /**
-     * alphaTag and number are set to null on invalid format
-     */
-    private void
-    parseRecord(byte[] record) {
-        try {
-            alphaTag = IccUtils.adnStringFieldToString(
-                            record, 0, record.length - FOOTER_SIZE_BYTES);
-
-            int footerOffset = record.length - FOOTER_SIZE_BYTES;
-
-            int numberLength = 0xff & record[footerOffset];
-
-            if (numberLength > MAX_NUMBER_SIZE_BYTES) {
-                // Invalid number length
-                number = "";
-                return;
-            }
-
-            // Please note 51.011 10.5.1:
-            //
-            // "If the Dialling Number/SSC String does not contain
-            // a dialling number, e.g. a control string deactivating
-            // a service, the TON/NPI byte shall be set to 'FF' by
-            // the ME (see note 2)."
-
-            number = PhoneNumberUtils.calledPartyBCDToString(
-                            record, footerOffset + 1, numberLength);
-
-
-            extRecord = 0xff & record[record.length - 1];
-
-            emails = null;
-
-        } catch (RuntimeException ex) {
-            Log.w(LOG_TAG, "Error parsing AdnRecord", ex);
-            number = "";
-            alphaTag = "";
-            emails = null;
-        }
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/AdnRecordCache.java b/telephony/java/com/android/internal/telephony/AdnRecordCache.java
deleted file mode 100644
index db5f4da..0000000
--- a/telephony/java/com/android/internal/telephony/AdnRecordCache.java
+++ /dev/null
@@ -1,364 +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.internal.telephony;
-
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-import android.util.SparseArray;
-
-import com.android.internal.telephony.gsm.UsimPhoneBookManager;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-/**
- * {@hide}
- */
-public final class AdnRecordCache extends Handler implements IccConstants {
-    //***** Instance Variables
-
-    private IccFileHandler mFh;
-    private UsimPhoneBookManager mUsimPhoneBookManager;
-
-    // Indexed by EF ID
-    SparseArray<ArrayList<AdnRecord>> adnLikeFiles
-        = new SparseArray<ArrayList<AdnRecord>>();
-
-    // People waiting for ADN-like files to be loaded
-    SparseArray<ArrayList<Message>> adnLikeWaiters
-        = new SparseArray<ArrayList<Message>>();
-
-    // People waiting for adn record to be updated
-    SparseArray<Message> userWriteResponse = new SparseArray<Message>();
-
-    //***** Event Constants
-
-    static final int EVENT_LOAD_ALL_ADN_LIKE_DONE = 1;
-    static final int EVENT_UPDATE_ADN_DONE = 2;
-
-    //***** Constructor
-
-
-
-    public AdnRecordCache(IccFileHandler fh) {
-        mFh = fh;
-        mUsimPhoneBookManager = new UsimPhoneBookManager(mFh, this);
-    }
-
-    //***** Called from SIMRecords
-
-    /**
-     * Called from SIMRecords.onRadioNotAvailable and SIMRecords.handleSimRefresh.
-     */
-    public void reset() {
-        adnLikeFiles.clear();
-        mUsimPhoneBookManager.reset();
-
-        clearWaiters();
-        clearUserWriters();
-
-    }
-
-    private void clearWaiters() {
-        int size = adnLikeWaiters.size();
-        for (int i = 0; i < size; i++) {
-            ArrayList<Message> waiters = adnLikeWaiters.valueAt(i);
-            AsyncResult ar = new AsyncResult(null, null, new RuntimeException("AdnCache reset"));
-            notifyWaiters(waiters, ar);
-        }
-        adnLikeWaiters.clear();
-    }
-
-    private void clearUserWriters() {
-        int size = userWriteResponse.size();
-        for (int i = 0; i < size; i++) {
-            sendErrorResponse(userWriteResponse.valueAt(i), "AdnCace reset");
-        }
-        userWriteResponse.clear();
-    }
-
-    /**
-     * @return List of AdnRecords for efid if we've already loaded them this
-     * radio session, or null if we haven't
-     */
-    public ArrayList<AdnRecord>
-    getRecordsIfLoaded(int efid) {
-        return adnLikeFiles.get(efid);
-    }
-
-    /**
-     * Returns extension ef associated with ADN-like EF or -1 if
-     * we don't know.
-     *
-     * See 3GPP TS 51.011 for this mapping
-     */
-    int extensionEfForEf(int efid) {
-        switch (efid) {
-            case EF_MBDN: return EF_EXT6;
-            case EF_ADN: return EF_EXT1;
-            case EF_SDN: return EF_EXT3;
-            case EF_FDN: return EF_EXT2;
-            case EF_MSISDN: return EF_EXT1;
-            case EF_PBR: return 0; // The EF PBR doesn't have an extension record
-            default: return -1;
-        }
-    }
-
-    private void sendErrorResponse(Message response, String errString) {
-        if (response != null) {
-            Exception e = new RuntimeException(errString);
-            AsyncResult.forMessage(response).exception = e;
-            response.sendToTarget();
-        }
-    }
-
-    /**
-     * Update an ADN-like record in EF by record index
-     *
-     * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN
-     * @param adn is the new adn to be stored
-     * @param recordIndex is the 1-based adn record index
-     * @param pin2 is required to update EF_FDN, otherwise must be null
-     * @param response message to be posted when done
-     *        response.exception hold the exception in error
-     */
-    public void updateAdnByIndex(int efid, AdnRecord adn, int recordIndex, String pin2,
-            Message response) {
-
-        int extensionEF = extensionEfForEf(efid);
-        if (extensionEF < 0) {
-            sendErrorResponse(response, "EF is not known ADN-like EF:" + efid);
-            return;
-        }
-
-        Message pendingResponse = userWriteResponse.get(efid);
-        if (pendingResponse != null) {
-            sendErrorResponse(response, "Have pending update for EF:" + efid);
-            return;
-        }
-
-        userWriteResponse.put(efid, response);
-
-        new AdnRecordLoader(mFh).updateEF(adn, efid, extensionEF,
-                recordIndex, pin2,
-                obtainMessage(EVENT_UPDATE_ADN_DONE, efid, recordIndex, adn));
-    }
-
-    /**
-     * Replace oldAdn with newAdn in ADN-like record in EF
-     *
-     * The ADN-like records must be read through requestLoadAllAdnLike() before
-     *
-     * @param efid must be one of EF_ADN, EF_FDN, and EF_SDN
-     * @param oldAdn is the adn to be replaced
-     *        If oldAdn.isEmpty() is ture, it insert the newAdn
-     * @param newAdn is the adn to be stored
-     *        If newAdn.isEmpty() is true, it delete the oldAdn
-     * @param pin2 is required to update EF_FDN, otherwise must be null
-     * @param response message to be posted when done
-     *        response.exception hold the exception in error
-     */
-    public void updateAdnBySearch(int efid, AdnRecord oldAdn, AdnRecord newAdn,
-            String pin2, Message response) {
-
-        int extensionEF;
-        extensionEF = extensionEfForEf(efid);
-
-        if (extensionEF < 0) {
-            sendErrorResponse(response, "EF is not known ADN-like EF:" + efid);
-            return;
-        }
-
-        ArrayList<AdnRecord>  oldAdnList;
-
-        if (efid == EF_PBR) {
-            oldAdnList = mUsimPhoneBookManager.loadEfFilesFromUsim();
-        } else {
-            oldAdnList = getRecordsIfLoaded(efid);
-        }
-
-        if (oldAdnList == null) {
-            sendErrorResponse(response, "Adn list not exist for EF:" + efid);
-            return;
-        }
-
-        int index = -1;
-        int count = 1;
-        for (Iterator<AdnRecord> it = oldAdnList.iterator(); it.hasNext(); ) {
-            if (oldAdn.isEqual(it.next())) {
-                index = count;
-                break;
-            }
-            count++;
-        }
-
-        if (index == -1) {
-            sendErrorResponse(response, "Adn record don't exist for " + oldAdn);
-            return;
-        }
-
-        if (efid == EF_PBR) {
-            AdnRecord foundAdn = oldAdnList.get(index-1);
-            efid = foundAdn.efid;
-            extensionEF = foundAdn.extRecord;
-            index = foundAdn.recordNumber;
-
-            newAdn.efid = efid;
-            newAdn.extRecord = extensionEF;
-            newAdn.recordNumber = index;
-        }
-
-        Message pendingResponse = userWriteResponse.get(efid);
-
-        if (pendingResponse != null) {
-            sendErrorResponse(response, "Have pending update for EF:" + efid);
-            return;
-        }
-
-        userWriteResponse.put(efid, response);
-
-        new AdnRecordLoader(mFh).updateEF(newAdn, efid, extensionEF,
-                index, pin2,
-                obtainMessage(EVENT_UPDATE_ADN_DONE, efid, index, newAdn));
-    }
-
-
-    /**
-     * Responds with exception (in response) if efid is not a known ADN-like
-     * record
-     */
-    public void
-    requestLoadAllAdnLike (int efid, int extensionEf, Message response) {
-        ArrayList<Message> waiters;
-        ArrayList<AdnRecord> result;
-
-        if (efid == EF_PBR) {
-            result = mUsimPhoneBookManager.loadEfFilesFromUsim();
-        } else {
-            result = getRecordsIfLoaded(efid);
-        }
-
-        // Have we already loaded this efid?
-        if (result != null) {
-            if (response != null) {
-                AsyncResult.forMessage(response).result = result;
-                response.sendToTarget();
-            }
-
-            return;
-        }
-
-        // Have we already *started* loading this efid?
-
-        waiters = adnLikeWaiters.get(efid);
-
-        if (waiters != null) {
-            // There's a pending request for this EF already
-            // just add ourselves to it
-
-            waiters.add(response);
-            return;
-        }
-
-        // Start loading efid
-
-        waiters = new ArrayList<Message>();
-        waiters.add(response);
-
-        adnLikeWaiters.put(efid, waiters);
-
-
-        if (extensionEf < 0) {
-            // respond with error if not known ADN-like record
-
-            if (response != null) {
-                AsyncResult.forMessage(response).exception
-                    = new RuntimeException("EF is not known ADN-like EF:" + efid);
-                response.sendToTarget();
-            }
-
-            return;
-        }
-
-        new AdnRecordLoader(mFh).loadAllFromEF(efid, extensionEf,
-            obtainMessage(EVENT_LOAD_ALL_ADN_LIKE_DONE, efid, 0));
-    }
-
-    //***** Private methods
-
-    private void
-    notifyWaiters(ArrayList<Message> waiters, AsyncResult ar) {
-
-        if (waiters == null) {
-            return;
-        }
-
-        for (int i = 0, s = waiters.size() ; i < s ; i++) {
-            Message waiter = waiters.get(i);
-
-            AsyncResult.forMessage(waiter, ar.result, ar.exception);
-            waiter.sendToTarget();
-        }
-    }
-
-    //***** Overridden from Handler
-
-    public void
-    handleMessage(Message msg) {
-        AsyncResult ar;
-        int efid;
-
-        switch(msg.what) {
-            case EVENT_LOAD_ALL_ADN_LIKE_DONE:
-                /* arg1 is efid, obj.result is ArrayList<AdnRecord>*/
-                ar = (AsyncResult) msg.obj;
-                efid = msg.arg1;
-                ArrayList<Message> waiters;
-
-                waiters = adnLikeWaiters.get(efid);
-                adnLikeWaiters.delete(efid);
-
-                if (ar.exception == null) {
-                    adnLikeFiles.put(efid, (ArrayList<AdnRecord>) ar.result);
-                }
-                notifyWaiters(waiters, ar);
-                break;
-            case EVENT_UPDATE_ADN_DONE:
-                ar = (AsyncResult)msg.obj;
-                efid = msg.arg1;
-                int index = msg.arg2;
-                AdnRecord adn = (AdnRecord) (ar.userObj);
-
-                if (ar.exception == null) {
-                    adnLikeFiles.get(efid).set(index - 1, adn);
-                    mUsimPhoneBookManager.invalidateCache();
-                }
-
-                Message response = userWriteResponse.get(efid);
-                userWriteResponse.delete(efid);
-
-                AsyncResult.forMessage(response, null, ar.exception);
-                response.sendToTarget();
-                break;
-        }
-
-    }
-
-
-}
diff --git a/telephony/java/com/android/internal/telephony/AdnRecordLoader.java b/telephony/java/com/android/internal/telephony/AdnRecordLoader.java
deleted file mode 100644
index 084fae6..0000000
--- a/telephony/java/com/android/internal/telephony/AdnRecordLoader.java
+++ /dev/null
@@ -1,284 +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.internal.telephony;
-
-import java.util.ArrayList;
-
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-
-public class AdnRecordLoader extends Handler {
-    final static String LOG_TAG = "RIL_AdnRecordLoader";
-
-    //***** Instance Variables
-
-    private IccFileHandler mFh;
-    int ef;
-    int extensionEF;
-    int pendingExtLoads;
-    Message userResponse;
-    String pin2;
-
-    // For "load one"
-    int recordNumber;
-
-    // for "load all"
-    ArrayList<AdnRecord> adns; // only valid after EVENT_ADN_LOAD_ALL_DONE
-
-    // Either an AdnRecord or a reference to adns depending
-    // if this is a load one or load all operation
-    Object result;
-
-    //***** Event Constants
-
-    static final int EVENT_ADN_LOAD_DONE = 1;
-    static final int EVENT_EXT_RECORD_LOAD_DONE = 2;
-    static final int EVENT_ADN_LOAD_ALL_DONE = 3;
-    static final int EVENT_EF_LINEAR_RECORD_SIZE_DONE = 4;
-    static final int EVENT_UPDATE_RECORD_DONE = 5;
-
-    //***** Constructor
-
-    public AdnRecordLoader(IccFileHandler fh) {
-        // The telephony unit-test cases may create AdnRecords
-        // in secondary threads
-        super(Looper.getMainLooper());
-        mFh = fh;
-    }
-
-    /**
-     * Resulting AdnRecord is placed in response.obj.result
-     * or response.obj.exception is set
-     */
-    public void
-    loadFromEF(int ef, int extensionEF, int recordNumber,
-                Message response) {
-        this.ef = ef;
-        this.extensionEF = extensionEF;
-        this.recordNumber = recordNumber;
-        this.userResponse = response;
-
-        mFh.loadEFLinearFixed(
-                    ef, recordNumber,
-                    obtainMessage(EVENT_ADN_LOAD_DONE));
-
-    }
-
-
-    /**
-     * Resulting ArrayList&lt;adnRecord> is placed in response.obj.result
-     * or response.obj.exception is set
-     */
-    public void
-    loadAllFromEF(int ef, int extensionEF,
-                Message response) {
-        this.ef = ef;
-        this.extensionEF = extensionEF;
-        this.userResponse = response;
-
-        mFh.loadEFLinearFixedAll(
-                    ef,
-                    obtainMessage(EVENT_ADN_LOAD_ALL_DONE));
-
-    }
-
-    /**
-     * Write adn to a EF SIM record
-     * It will get the record size of EF record and compose hex adn array
-     * then write the hex array to EF record
-     *
-     * @param adn is set with alphaTag and phone number
-     * @param ef EF fileid
-     * @param extensionEF extension EF fileid
-     * @param recordNumber 1-based record index
-     * @param pin2 for CHV2 operations, must be null if pin2 is not needed
-     * @param response will be sent to its handler when completed
-     */
-    public void
-    updateEF(AdnRecord adn, int ef, int extensionEF, int recordNumber,
-            String pin2, Message response) {
-        this.ef = ef;
-        this.extensionEF = extensionEF;
-        this.recordNumber = recordNumber;
-        this.userResponse = response;
-        this.pin2 = pin2;
-
-        mFh.getEFLinearRecordSize( ef,
-            obtainMessage(EVENT_EF_LINEAR_RECORD_SIZE_DONE, adn));
-    }
-
-    //***** Overridden from Handler
-
-    public void
-    handleMessage(Message msg) {
-        AsyncResult ar;
-        byte data[];
-        AdnRecord adn;
-
-        try {
-            switch (msg.what) {
-                case EVENT_EF_LINEAR_RECORD_SIZE_DONE:
-                    ar = (AsyncResult)(msg.obj);
-                    adn = (AdnRecord)(ar.userObj);
-
-                    if (ar.exception != null) {
-                        throw new RuntimeException("get EF record size failed",
-                                ar.exception);
-                    }
-
-                    int[] recordSize = (int[])ar.result;
-                    // recordSize is int[3] array
-                    // int[0]  is the record length
-                    // int[1]  is the total length of the EF file
-                    // int[2]  is the number of records in the EF file
-                    // So int[0] * int[2] = int[1]
-                   if (recordSize.length != 3 || recordNumber > recordSize[2]) {
-                        throw new RuntimeException("get wrong EF record size format",
-                                ar.exception);
-                    }
-
-                    data = adn.buildAdnString(recordSize[0]);
-
-                    if(data == null) {
-                        throw new RuntimeException("wrong ADN format",
-                                ar.exception);
-                    }
-
-                    mFh.updateEFLinearFixed(ef, recordNumber,
-                            data, pin2, obtainMessage(EVENT_UPDATE_RECORD_DONE));
-
-                    pendingExtLoads = 1;
-
-                    break;
-                case EVENT_UPDATE_RECORD_DONE:
-                    ar = (AsyncResult)(msg.obj);
-                    if (ar.exception != null) {
-                        throw new RuntimeException("update EF adn record failed",
-                                ar.exception);
-                    }
-                    pendingExtLoads = 0;
-                    result = null;
-                    break;
-                case EVENT_ADN_LOAD_DONE:
-                    ar = (AsyncResult)(msg.obj);
-                    data = (byte[])(ar.result);
-
-                    if (ar.exception != null) {
-                        throw new RuntimeException("load failed", ar.exception);
-                    }
-
-                    if (false) {
-                        Log.d(LOG_TAG,"ADN EF: 0x"
-                            + Integer.toHexString(ef)
-                            + ":" + recordNumber
-                            + "\n" + IccUtils.bytesToHexString(data));
-                    }
-
-                    adn = new AdnRecord(ef, recordNumber, data);
-                    result = adn;
-
-                    if (adn.hasExtendedRecord()) {
-                        // If we have a valid value in the ext record field,
-                        // we're not done yet: we need to read the corresponding
-                        // ext record and append it
-
-                        pendingExtLoads = 1;
-
-                        mFh.loadEFLinearFixed(
-                            extensionEF, adn.extRecord,
-                            obtainMessage(EVENT_EXT_RECORD_LOAD_DONE, adn));
-                    }
-                break;
-
-                case EVENT_EXT_RECORD_LOAD_DONE:
-                    ar = (AsyncResult)(msg.obj);
-                    data = (byte[])(ar.result);
-                    adn = (AdnRecord)(ar.userObj);
-
-                    if (ar.exception != null) {
-                        throw new RuntimeException("load failed", ar.exception);
-                    }
-
-                    Log.d(LOG_TAG,"ADN extension EF: 0x"
-                        + Integer.toHexString(extensionEF)
-                        + ":" + adn.extRecord
-                        + "\n" + IccUtils.bytesToHexString(data));
-
-                    adn.appendExtRecord(data);
-
-                    pendingExtLoads--;
-                    // result should have been set in
-                    // EVENT_ADN_LOAD_DONE or EVENT_ADN_LOAD_ALL_DONE
-                break;
-
-                case EVENT_ADN_LOAD_ALL_DONE:
-                    ar = (AsyncResult)(msg.obj);
-                    ArrayList<byte[]> datas = (ArrayList<byte[]>)(ar.result);
-
-                    if (ar.exception != null) {
-                        throw new RuntimeException("load failed", ar.exception);
-                    }
-
-                    adns = new ArrayList<AdnRecord>(datas.size());
-                    result = adns;
-                    pendingExtLoads = 0;
-
-                    for(int i = 0, s = datas.size() ; i < s ; i++) {
-                        adn = new AdnRecord(ef, 1 + i, datas.get(i));
-                        adns.add(adn);
-
-                        if (adn.hasExtendedRecord()) {
-                            // If we have a valid value in the ext record field,
-                            // we're not done yet: we need to read the corresponding
-                            // ext record and append it
-
-                            pendingExtLoads++;
-
-                            mFh.loadEFLinearFixed(
-                                extensionEF, adn.extRecord,
-                                obtainMessage(EVENT_EXT_RECORD_LOAD_DONE, adn));
-                        }
-                    }
-                break;
-            }
-        } catch (RuntimeException exc) {
-            if (userResponse != null) {
-                AsyncResult.forMessage(userResponse)
-                                .exception = exc;
-                userResponse.sendToTarget();
-                // Loading is all or nothing--either every load succeeds
-                // or we fail the whole thing.
-                userResponse = null;
-            }
-            return;
-        }
-
-        if (userResponse != null && pendingExtLoads == 0) {
-            AsyncResult.forMessage(userResponse).result
-                = result;
-
-            userResponse.sendToTarget();
-            userResponse = null;
-        }
-    }
-
-
-}
diff --git a/telephony/java/com/android/internal/telephony/ApnContext.java b/telephony/java/com/android/internal/telephony/ApnContext.java
deleted file mode 100644
index 9746398..0000000
--- a/telephony/java/com/android/internal/telephony/ApnContext.java
+++ /dev/null
@@ -1,246 +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.internal.telephony;
-
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Maintain the Apn context
- */
-public class ApnContext {
-
-    public final String LOG_TAG;
-
-    protected static final boolean DBG = true;
-
-    private final String mApnType;
-
-    private DataConnectionTracker.State mState;
-
-    private ArrayList<ApnSetting> mWaitingApns = null;
-
-    /** A zero indicates that all waiting APNs had a permanent error */
-    private AtomicInteger mWaitingApnsPermanentFailureCountDown;
-
-    private ApnSetting mApnSetting;
-
-    DataConnection mDataConnection;
-
-    DataConnectionAc mDataConnectionAc;
-
-    String mReason;
-
-    int mRetryCount;
-
-    /**
-     * user/app requested connection on this APN
-     */
-    AtomicBoolean mDataEnabled;
-
-    /**
-     * carrier requirements met
-     */
-    AtomicBoolean mDependencyMet;
-
-    public ApnContext(String apnType, String logTag) {
-        mApnType = apnType;
-        mState = DataConnectionTracker.State.IDLE;
-        setReason(Phone.REASON_DATA_ENABLED);
-        setRetryCount(0);
-        mDataEnabled = new AtomicBoolean(false);
-        mDependencyMet = new AtomicBoolean(true);
-        mWaitingApnsPermanentFailureCountDown = new AtomicInteger(0);
-        LOG_TAG = logTag;
-    }
-
-    public String getApnType() {
-        return mApnType;
-    }
-
-    public synchronized DataConnection getDataConnection() {
-        return mDataConnection;
-    }
-
-    public synchronized void setDataConnection(DataConnection dc) {
-        if (DBG) {
-            log("setDataConnection: old dc=" + mDataConnection + " new dc=" + dc + " this=" + this);
-        }
-        mDataConnection = dc;
-    }
-
-
-    public synchronized DataConnectionAc getDataConnectionAc() {
-        return mDataConnectionAc;
-    }
-
-    public synchronized void setDataConnectionAc(DataConnectionAc dcac) {
-        if (DBG) {
-            log("setDataConnectionAc: old dcac=" + mDataConnectionAc + " new dcac=" + dcac);
-        }
-        if (dcac != null) {
-            dcac.addApnContextSync(this);
-        } else {
-            if (mDataConnectionAc != null) {
-                mDataConnectionAc.removeApnContextSync(this);
-            }
-        }
-        mDataConnectionAc = dcac;
-    }
-
-    public synchronized ApnSetting getApnSetting() {
-        return mApnSetting;
-    }
-
-    public synchronized void setApnSetting(ApnSetting apnSetting) {
-        mApnSetting = apnSetting;
-    }
-
-    public synchronized void setWaitingApns(ArrayList<ApnSetting> waitingApns) {
-        mWaitingApns = waitingApns;
-        mWaitingApnsPermanentFailureCountDown.set(mWaitingApns.size());
-    }
-
-    public int getWaitingApnsPermFailCount() {
-        return mWaitingApnsPermanentFailureCountDown.get();
-    }
-
-    public void decWaitingApnsPermFailCount() {
-        mWaitingApnsPermanentFailureCountDown.decrementAndGet();
-    }
-
-    public synchronized ApnSetting getNextWaitingApn() {
-        ArrayList<ApnSetting> list = mWaitingApns;
-        ApnSetting apn = null;
-
-        if (list != null) {
-            if (!list.isEmpty()) {
-                apn = list.get(0);
-            }
-        }
-        return apn;
-    }
-
-    public synchronized void removeWaitingApn(ApnSetting apn) {
-        if (mWaitingApns != null) {
-            mWaitingApns.remove(apn);
-        }
-    }
-
-    public synchronized ArrayList<ApnSetting> getWaitingApns() {
-        return mWaitingApns;
-    }
-
-    public synchronized void setState(DataConnectionTracker.State s) {
-        if (DBG) {
-            log("setState: " + s + ", previous state:" + mState);
-        }
-
-        mState = s;
-
-        if (mState == DataConnectionTracker.State.FAILED) {
-            if (mWaitingApns != null) {
-                mWaitingApns.clear(); // when teardown the connection and set to IDLE
-            }
-        }
-    }
-
-    public synchronized DataConnectionTracker.State getState() {
-        return mState;
-    }
-
-    public boolean isDisconnected() {
-        DataConnectionTracker.State currentState = getState();
-        return ((currentState == DataConnectionTracker.State.IDLE) ||
-                    currentState == DataConnectionTracker.State.FAILED);
-    }
-
-    public synchronized void setReason(String reason) {
-        if (DBG) {
-            log("set reason as " + reason + ",current state " + mState);
-        }
-        mReason = reason;
-    }
-
-    public synchronized String getReason() {
-        return mReason;
-    }
-
-    public synchronized void setRetryCount(int retryCount) {
-        if (DBG) {
-            log("setRetryCount: " + retryCount);
-        }
-        mRetryCount = retryCount;
-        DataConnection dc = mDataConnection;
-        if (dc != null) {
-            dc.setRetryCount(retryCount);
-        }
-    }
-
-    public synchronized int getRetryCount() {
-        return mRetryCount;
-    }
-
-    public boolean isReady() {
-        return mDataEnabled.get() && mDependencyMet.get();
-    }
-
-    public void setEnabled(boolean enabled) {
-        if (DBG) {
-            log("set enabled as " + enabled + ", current state is " + mDataEnabled.get());
-        }
-        mDataEnabled.set(enabled);
-    }
-
-    public boolean isEnabled() {
-        return mDataEnabled.get();
-    }
-
-    public void setDependencyMet(boolean met) {
-        if (DBG) {
-            log("set mDependencyMet as " + met + " current state is " + mDependencyMet.get());
-        }
-        mDependencyMet.set(met);
-    }
-
-    public boolean getDependencyMet() {
-       return mDependencyMet.get();
-    }
-
-    @Override
-    public String toString() {
-        // We don't print mDataConnection because its recursive.
-        return "{mApnType=" + mApnType + " mState=" + getState() + " mWaitingApns=" + mWaitingApns +
-                " mWaitingApnsPermanentFailureCountDown=" + mWaitingApnsPermanentFailureCountDown +
-                " mApnSetting=" + mApnSetting + " mDataConnectionAc=" + mDataConnectionAc +
-                " mReason=" + mReason + " mRetryCount=" + mRetryCount +
-                " mDataEnabled=" + mDataEnabled + " mDependencyMet=" + mDependencyMet + "}";
-    }
-
-    protected void log(String s) {
-        Log.d(LOG_TAG, "[ApnContext:" + mApnType + "] " + s);
-    }
-
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("ApnContext: " + this.toString());
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/ApnSetting.java b/telephony/java/com/android/internal/telephony/ApnSetting.java
deleted file mode 100755
index ad69fdb..0000000
--- a/telephony/java/com/android/internal/telephony/ApnSetting.java
+++ /dev/null
@@ -1,200 +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.internal.telephony;
-
-/**
- * This class represents a apn setting for create PDP link
- */
-public class ApnSetting {
-
-    static final String V2_FORMAT_REGEX = "^\\[ApnSettingV2\\]\\s*";
-
-    public final String carrier;
-    public final String apn;
-    public final String proxy;
-    public final String port;
-    public final String mmsc;
-    public final String mmsProxy;
-    public final String mmsPort;
-    public final String user;
-    public final String password;
-    public final int authType;
-    public final String[] types;
-    public final int id;
-    public final String numeric;
-    public final String protocol;
-    public final String roamingProtocol;
-    /**
-      * Current status of APN
-      * true : enabled APN, false : disabled APN.
-      */
-    public final boolean carrierEnabled;
-    /**
-      * Radio Access Technology info
-      * To check what values can hold, refer to ServiceState.java.
-      * This should be spread to other technologies,
-      * but currently only used for LTE(14) and EHRPD(13).
-      */
-    public final int bearer;
-
-    public ApnSetting(int id, String numeric, String carrier, String apn,
-            String proxy, String port,
-            String mmsc, String mmsProxy, String mmsPort,
-            String user, String password, int authType, String[] types,
-            String protocol, String roamingProtocol, boolean carrierEnabled, int bearer) {
-        this.id = id;
-        this.numeric = numeric;
-        this.carrier = carrier;
-        this.apn = apn;
-        this.proxy = proxy;
-        this.port = port;
-        this.mmsc = mmsc;
-        this.mmsProxy = mmsProxy;
-        this.mmsPort = mmsPort;
-        this.user = user;
-        this.password = password;
-        this.authType = authType;
-        this.types = types;
-        this.protocol = protocol;
-        this.roamingProtocol = roamingProtocol;
-        this.carrierEnabled = carrierEnabled;
-        this.bearer = bearer;
-    }
-
-    /**
-     * Creates an ApnSetting object from a string.
-     *
-     * @param data the string to read.
-     *
-     * The string must be in one of two formats (newlines added for clarity,
-     * spaces are optional):
-     *
-     * v1 format:
-     *   <carrier>, <apn>, <proxy>, <port>, <mmsc>, <mmsproxy>,
-     *   <mmsport>, <user>, <password>, <authtype>, <mcc>,<mnc>,
-     *   <type>[, <type>...]
-     *
-     * v2 format:
-     *   [ApnSettingV2] <carrier>, <apn>, <proxy>, <port>, <mmsc>, <mmsproxy>,
-     *   <mmsport>, <user>, <password>, <authtype>, <mcc>, <mnc>,
-     *   <type>[| <type>...], <protocol>, <roaming_protocol>, <carrierEnabled>, <bearer>
-     *
-     * Note that the strings generated by toString() do not contain the username
-     * and password and thus cannot be read by this method.
-     *
-     * @see ApnSettingTest
-     */
-    public static ApnSetting fromString(String data) {
-        if (data == null) return null;
-
-        int version;
-        // matches() operates on the whole string, so append .* to the regex.
-        if (data.matches(V2_FORMAT_REGEX + ".*")) {
-            version = 2;
-            data = data.replaceFirst(V2_FORMAT_REGEX, "");
-        } else {
-            version = 1;
-        }
-
-        String[] a = data.split("\\s*,\\s*");
-        if (a.length < 14) {
-            return null;
-        }
-
-        int authType;
-        try {
-            authType = Integer.parseInt(a[12]);
-        } catch (Exception e) {
-            authType = 0;
-        }
-
-        String[] typeArray;
-        String protocol, roamingProtocol;
-        boolean carrierEnabled;
-        int bearer;
-        if (version == 1) {
-            typeArray = new String[a.length - 13];
-            System.arraycopy(a, 13, typeArray, 0, a.length - 13);
-            protocol = RILConstants.SETUP_DATA_PROTOCOL_IP;
-            roamingProtocol = RILConstants.SETUP_DATA_PROTOCOL_IP;
-            carrierEnabled = true;
-            bearer = 0;
-        } else {
-            if (a.length < 18) {
-                return null;
-            }
-            typeArray = a[13].split("\\s*\\|\\s*");
-            protocol = a[14];
-            roamingProtocol = a[15];
-            try {
-                carrierEnabled = Boolean.parseBoolean(a[16]);
-            } catch (Exception e) {
-                carrierEnabled = true;
-            }
-            bearer = Integer.parseInt(a[17]);
-        }
-
-        return new ApnSetting(-1,a[10]+a[11],a[0],a[1],a[2],a[3],a[7],a[8],
-                a[9],a[4],a[5],authType,typeArray,protocol,roamingProtocol,carrierEnabled,bearer);
-    }
-
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("[ApnSettingV2] ")
-        .append(carrier)
-        .append(", ").append(id)
-        .append(", ").append(numeric)
-        .append(", ").append(apn)
-        .append(", ").append(proxy)
-        .append(", ").append(mmsc)
-        .append(", ").append(mmsProxy)
-        .append(", ").append(mmsPort)
-        .append(", ").append(port)
-        .append(", ").append(authType).append(", ");
-        for (int i = 0; i < types.length; i++) {
-            sb.append(types[i]);
-            if (i < types.length - 1) {
-                sb.append(" | ");
-            }
-        }
-        sb.append(", ").append(protocol);
-        sb.append(", ").append(roamingProtocol);
-        sb.append(", ").append(carrierEnabled);
-        sb.append(", ").append(bearer);
-        return sb.toString();
-    }
-
-    public boolean canHandleType(String type) {
-        for (String t : types) {
-            // DEFAULT handles all, and HIPRI is handled by DEFAULT
-            if (t.equalsIgnoreCase(type) ||
-                    t.equalsIgnoreCase(Phone.APN_TYPE_ALL) ||
-                    (t.equalsIgnoreCase(Phone.APN_TYPE_DEFAULT) &&
-                    type.equalsIgnoreCase(Phone.APN_TYPE_HIPRI))) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    // TODO - if we have this function we should also have hashCode.
-    // Also should handle changes in type order and perhaps case-insensitivity
-    public boolean equals(Object o) {
-        if (o instanceof ApnSetting == false) return false;
-        return (this.toString().equals(o.toString()));
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java
deleted file mode 100644
index 35cdf9bd..0000000
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ /dev/null
@@ -1,721 +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.internal.telephony;
-
-
-import android.content.Context;
-import android.os.RegistrantList;
-import android.os.Registrant;
-import android.os.Handler;
-import android.os.AsyncResult;
-import android.os.SystemProperties;
-import android.util.Log;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * {@hide}
- */
-public abstract class BaseCommands implements CommandsInterface {
-    static final String LOG_TAG = "RILB";
-
-    //***** Instance Variables
-    protected Context mContext;
-    protected RadioState mState = RadioState.RADIO_UNAVAILABLE;
-    protected Object mStateMonitor = new Object();
-
-    protected RegistrantList mRadioStateChangedRegistrants = new RegistrantList();
-    protected RegistrantList mOnRegistrants = new RegistrantList();
-    protected RegistrantList mAvailRegistrants = new RegistrantList();
-    protected RegistrantList mOffOrNotAvailRegistrants = new RegistrantList();
-    protected RegistrantList mNotAvailRegistrants = new RegistrantList();
-    protected RegistrantList mCallStateRegistrants = new RegistrantList();
-    protected RegistrantList mVoiceNetworkStateRegistrants = new RegistrantList();
-    protected RegistrantList mDataNetworkStateRegistrants = new RegistrantList();
-    protected RegistrantList mVoiceRadioTechChangedRegistrants = new RegistrantList();
-    protected RegistrantList mIccStatusChangedRegistrants = new RegistrantList();
-    protected RegistrantList mVoicePrivacyOnRegistrants = new RegistrantList();
-    protected RegistrantList mVoicePrivacyOffRegistrants = new RegistrantList();
-    protected Registrant mUnsolOemHookRawRegistrant;
-    protected RegistrantList mOtaProvisionRegistrants = new RegistrantList();
-    protected RegistrantList mCallWaitingInfoRegistrants = new RegistrantList();
-    protected RegistrantList mDisplayInfoRegistrants = new RegistrantList();
-    protected RegistrantList mSignalInfoRegistrants = new RegistrantList();
-    protected RegistrantList mNumberInfoRegistrants = new RegistrantList();
-    protected RegistrantList mRedirNumInfoRegistrants = new RegistrantList();
-    protected RegistrantList mLineControlInfoRegistrants = new RegistrantList();
-    protected RegistrantList mT53ClirInfoRegistrants = new RegistrantList();
-    protected RegistrantList mT53AudCntrlInfoRegistrants = new RegistrantList();
-    protected RegistrantList mRingbackToneRegistrants = new RegistrantList();
-    protected RegistrantList mResendIncallMuteRegistrants = new RegistrantList();
-    protected RegistrantList mCdmaSubscriptionChangedRegistrants = new RegistrantList();
-    protected RegistrantList mCdmaPrlChangedRegistrants = new RegistrantList();
-    protected RegistrantList mExitEmergencyCallbackModeRegistrants = new RegistrantList();
-    protected RegistrantList mRilConnectedRegistrants = new RegistrantList();
-    protected RegistrantList mIccRefreshRegistrants = new RegistrantList();
-
-    protected Registrant mGsmSmsRegistrant;
-    protected Registrant mCdmaSmsRegistrant;
-    protected Registrant mNITZTimeRegistrant;
-    protected Registrant mSignalStrengthRegistrant;
-    protected Registrant mUSSDRegistrant;
-    protected Registrant mSmsOnSimRegistrant;
-    protected Registrant mSmsStatusRegistrant;
-    protected Registrant mSsnRegistrant;
-    protected Registrant mCatSessionEndRegistrant;
-    protected Registrant mCatProCmdRegistrant;
-    protected Registrant mCatEventRegistrant;
-    protected Registrant mCatCallSetUpRegistrant;
-    protected Registrant mIccSmsFullRegistrant;
-    protected Registrant mEmergencyCallbackModeRegistrant;
-    protected Registrant mRingRegistrant;
-    protected Registrant mRestrictedStateRegistrant;
-    protected Registrant mGsmBroadcastSmsRegistrant;
-
-    // Preferred network type received from PhoneFactory.
-    // This is used when establishing a connection to the
-    // vendor ril so it starts up in the correct mode.
-    protected int mPreferredNetworkType;
-    // CDMA subscription received from PhoneFactory
-    protected int mCdmaSubscription;
-    // Type of Phone, GSM or CDMA. Set by CDMAPhone or GSMPhone.
-    protected int mPhoneType;
-    // RIL Version
-    protected int mRilVersion = -1;
-
-    public BaseCommands(Context context) {
-        mContext = context;  // May be null (if so we won't log statistics)
-    }
-
-    //***** CommandsInterface implementation
-
-    public RadioState getRadioState() {
-        return mState;
-    }
-
-    public void registerForRadioStateChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        synchronized (mStateMonitor) {
-            mRadioStateChangedRegistrants.add(r);
-            r.notifyRegistrant();
-        }
-    }
-
-    public void unregisterForRadioStateChanged(Handler h) {
-        synchronized (mStateMonitor) {
-            mRadioStateChangedRegistrants.remove(h);
-        }
-    }
-
-    public void registerForOn(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        synchronized (mStateMonitor) {
-            mOnRegistrants.add(r);
-
-            if (mState.isOn()) {
-                r.notifyRegistrant(new AsyncResult(null, null, null));
-            }
-        }
-    }
-    public void unregisterForOn(Handler h) {
-        synchronized (mStateMonitor) {
-            mOnRegistrants.remove(h);
-        }
-    }
-
-
-    public void registerForAvailable(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        synchronized (mStateMonitor) {
-            mAvailRegistrants.add(r);
-
-            if (mState.isAvailable()) {
-                r.notifyRegistrant(new AsyncResult(null, null, null));
-            }
-        }
-    }
-
-    public void unregisterForAvailable(Handler h) {
-        synchronized(mStateMonitor) {
-            mAvailRegistrants.remove(h);
-        }
-    }
-
-    public void registerForNotAvailable(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        synchronized (mStateMonitor) {
-            mNotAvailRegistrants.add(r);
-
-            if (!mState.isAvailable()) {
-                r.notifyRegistrant(new AsyncResult(null, null, null));
-            }
-        }
-    }
-
-    public void unregisterForNotAvailable(Handler h) {
-        synchronized (mStateMonitor) {
-            mNotAvailRegistrants.remove(h);
-        }
-    }
-
-    public void registerForOffOrNotAvailable(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        synchronized (mStateMonitor) {
-            mOffOrNotAvailRegistrants.add(r);
-
-            if (mState == RadioState.RADIO_OFF || !mState.isAvailable()) {
-                r.notifyRegistrant(new AsyncResult(null, null, null));
-            }
-        }
-    }
-    public void unregisterForOffOrNotAvailable(Handler h) {
-        synchronized(mStateMonitor) {
-            mOffOrNotAvailRegistrants.remove(h);
-        }
-    }
-
-    public void registerForCallStateChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        mCallStateRegistrants.add(r);
-    }
-
-    public void unregisterForCallStateChanged(Handler h) {
-        mCallStateRegistrants.remove(h);
-    }
-
-    public void registerForVoiceNetworkStateChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        mVoiceNetworkStateRegistrants.add(r);
-    }
-
-    public void unregisterForVoiceNetworkStateChanged(Handler h) {
-        mVoiceNetworkStateRegistrants.remove(h);
-    }
-
-    public void registerForDataNetworkStateChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        mDataNetworkStateRegistrants.add(r);
-    }
-
-    public void unregisterForDataNetworkStateChanged(Handler h) {
-        mDataNetworkStateRegistrants.remove(h);
-    }
-
-    public void registerForVoiceRadioTechChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mVoiceRadioTechChangedRegistrants.add(r);
-    }
-
-    public void unregisterForVoiceRadioTechChanged(Handler h) {
-        mVoiceRadioTechChangedRegistrants.remove(h);
-    }
-
-    public void registerForIccStatusChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mIccStatusChangedRegistrants.add(r);
-    }
-
-    public void unregisterForIccStatusChanged(Handler h) {
-        mIccStatusChangedRegistrants.remove(h);
-    }
-
-    public void setOnNewGsmSms(Handler h, int what, Object obj) {
-        mGsmSmsRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnNewGsmSms(Handler h) {
-        mGsmSmsRegistrant.clear();
-    }
-
-    public void setOnNewCdmaSms(Handler h, int what, Object obj) {
-        mCdmaSmsRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnNewCdmaSms(Handler h) {
-        mCdmaSmsRegistrant.clear();
-    }
-
-    public void setOnNewGsmBroadcastSms(Handler h, int what, Object obj) {
-        mGsmBroadcastSmsRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnNewGsmBroadcastSms(Handler h) {
-        mGsmBroadcastSmsRegistrant.clear();
-    }
-
-    public void setOnSmsOnSim(Handler h, int what, Object obj) {
-        mSmsOnSimRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnSmsOnSim(Handler h) {
-        mSmsOnSimRegistrant.clear();
-    }
-
-    public void setOnSmsStatus(Handler h, int what, Object obj) {
-        mSmsStatusRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnSmsStatus(Handler h) {
-        mSmsStatusRegistrant.clear();
-    }
-
-    public void setOnSignalStrengthUpdate(Handler h, int what, Object obj) {
-        mSignalStrengthRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnSignalStrengthUpdate(Handler h) {
-        mSignalStrengthRegistrant.clear();
-    }
-
-    public void setOnNITZTime(Handler h, int what, Object obj) {
-        mNITZTimeRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnNITZTime(Handler h) {
-        mNITZTimeRegistrant.clear();
-    }
-
-    public void setOnUSSD(Handler h, int what, Object obj) {
-        mUSSDRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnUSSD(Handler h) {
-        mUSSDRegistrant.clear();
-    }
-
-    public void setOnSuppServiceNotification(Handler h, int what, Object obj) {
-        mSsnRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnSuppServiceNotification(Handler h) {
-        mSsnRegistrant.clear();
-    }
-
-    public void setOnCatSessionEnd(Handler h, int what, Object obj) {
-        mCatSessionEndRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnCatSessionEnd(Handler h) {
-        mCatSessionEndRegistrant.clear();
-    }
-
-    public void setOnCatProactiveCmd(Handler h, int what, Object obj) {
-        mCatProCmdRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnCatProactiveCmd(Handler h) {
-        mCatProCmdRegistrant.clear();
-    }
-
-    public void setOnCatEvent(Handler h, int what, Object obj) {
-        mCatEventRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnCatEvent(Handler h) {
-        mCatEventRegistrant.clear();
-    }
-
-    public void setOnCatCallSetUp(Handler h, int what, Object obj) {
-        mCatCallSetUpRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnCatCallSetUp(Handler h) {
-        mCatCallSetUpRegistrant.clear();
-    }
-
-    public void setOnIccSmsFull(Handler h, int what, Object obj) {
-        mIccSmsFullRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnIccSmsFull(Handler h) {
-        mIccSmsFullRegistrant.clear();
-    }
-
-    public void registerForIccRefresh(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mIccRefreshRegistrants.add(r);
-    }
-    public void setOnIccRefresh(Handler h, int what, Object obj) {
-        registerForIccRefresh(h, what, obj);
-    }
-
-    public void setEmergencyCallbackMode(Handler h, int what, Object obj) {
-        mEmergencyCallbackModeRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unregisterForIccRefresh(Handler h) {
-        mIccRefreshRegistrants.remove(h);
-    }
-    public void unsetOnIccRefresh(Handler h) {
-        unregisterForIccRefresh(h);
-    }
-
-    public void setOnCallRing(Handler h, int what, Object obj) {
-        mRingRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnCallRing(Handler h) {
-        mRingRegistrant.clear();
-    }
-
-    public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mVoicePrivacyOnRegistrants.add(r);
-    }
-
-    public void unregisterForInCallVoicePrivacyOn(Handler h){
-        mVoicePrivacyOnRegistrants.remove(h);
-    }
-
-    public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mVoicePrivacyOffRegistrants.add(r);
-    }
-
-    public void unregisterForInCallVoicePrivacyOff(Handler h){
-        mVoicePrivacyOffRegistrants.remove(h);
-    }
-
-    public void setOnRestrictedStateChanged(Handler h, int what, Object obj) {
-        mRestrictedStateRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnRestrictedStateChanged(Handler h) {
-        mRestrictedStateRegistrant.clear();
-    }
-
-    public void registerForDisplayInfo(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mDisplayInfoRegistrants.add(r);
-    }
-
-    public void unregisterForDisplayInfo(Handler h) {
-        mDisplayInfoRegistrants.remove(h);
-    }
-
-    public void registerForCallWaitingInfo(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mCallWaitingInfoRegistrants.add(r);
-    }
-
-    public void unregisterForCallWaitingInfo(Handler h) {
-        mCallWaitingInfoRegistrants.remove(h);
-    }
-
-    public void registerForSignalInfo(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mSignalInfoRegistrants.add(r);
-    }
-
-    public void setOnUnsolOemHookRaw(Handler h, int what, Object obj) {
-        mUnsolOemHookRawRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnUnsolOemHookRaw(Handler h) {
-        mUnsolOemHookRawRegistrant.clear();
-    }
-
-    public void unregisterForSignalInfo(Handler h) {
-        mSignalInfoRegistrants.remove(h);
-    }
-
-    public void registerForCdmaOtaProvision(Handler h,int what, Object obj){
-        Registrant r = new Registrant (h, what, obj);
-        mOtaProvisionRegistrants.add(r);
-    }
-
-    public void unregisterForCdmaOtaProvision(Handler h){
-        mOtaProvisionRegistrants.remove(h);
-    }
-
-    public void registerForNumberInfo(Handler h,int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mNumberInfoRegistrants.add(r);
-    }
-
-    public void unregisterForNumberInfo(Handler h){
-        mNumberInfoRegistrants.remove(h);
-    }
-
-     public void registerForRedirectedNumberInfo(Handler h,int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mRedirNumInfoRegistrants.add(r);
-    }
-
-    public void unregisterForRedirectedNumberInfo(Handler h) {
-        mRedirNumInfoRegistrants.remove(h);
-    }
-
-    public void registerForLineControlInfo(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mLineControlInfoRegistrants.add(r);
-    }
-
-    public void unregisterForLineControlInfo(Handler h) {
-        mLineControlInfoRegistrants.remove(h);
-    }
-
-    public void registerFoT53ClirlInfo(Handler h,int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mT53ClirInfoRegistrants.add(r);
-    }
-
-    public void unregisterForT53ClirInfo(Handler h) {
-        mT53ClirInfoRegistrants.remove(h);
-    }
-
-    public void registerForT53AudioControlInfo(Handler h,int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mT53AudCntrlInfoRegistrants.add(r);
-    }
-
-    public void unregisterForT53AudioControlInfo(Handler h) {
-        mT53AudCntrlInfoRegistrants.remove(h);
-    }
-
-    public void registerForRingbackTone(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mRingbackToneRegistrants.add(r);
-    }
-
-    public void unregisterForRingbackTone(Handler h) {
-        mRingbackToneRegistrants.remove(h);
-    }
-
-    public void registerForResendIncallMute(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mResendIncallMuteRegistrants.add(r);
-    }
-
-    public void unregisterForResendIncallMute(Handler h) {
-        mResendIncallMuteRegistrants.remove(h);
-    }
-
-    @Override
-    public void registerForCdmaSubscriptionChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mCdmaSubscriptionChangedRegistrants.add(r);
-    }
-
-    @Override
-    public void unregisterForCdmaSubscriptionChanged(Handler h) {
-        mCdmaSubscriptionChangedRegistrants.remove(h);
-    }
-
-    @Override
-    public void registerForCdmaPrlChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mCdmaPrlChangedRegistrants.add(r);
-    }
-
-    @Override
-    public void unregisterForCdmaPrlChanged(Handler h) {
-        mCdmaPrlChangedRegistrants.remove(h);
-    }
-
-    @Override
-    public void registerForExitEmergencyCallbackMode(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mExitEmergencyCallbackModeRegistrants.add(r);
-    }
-
-    @Override
-    public void unregisterForExitEmergencyCallbackMode(Handler h) {
-        mExitEmergencyCallbackModeRegistrants.remove(h);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void registerForRilConnected(Handler h, int what, Object obj) {
-        Log.d(LOG_TAG, "registerForRilConnected h=" + h + " w=" + what);
-        Registrant r = new Registrant (h, what, obj);
-        mRilConnectedRegistrants.add(r);
-        if (mRilVersion != -1) {
-            Log.d(LOG_TAG, "Notifying: ril connected mRilVersion=" + mRilVersion);
-            r.notifyRegistrant(new AsyncResult(null, new Integer(mRilVersion), null));
-        }
-    }
-
-    @Override
-    public void unregisterForRilConnected(Handler h) {
-        mRilConnectedRegistrants.remove(h);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setCurrentPreferredNetworkType() {
-    }
-
-    //***** Protected Methods
-    /**
-     * Store new RadioState and send notification based on the changes
-     *
-     * This function is called only by RIL.java when receiving unsolicited
-     * RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED
-     *
-     * RadioState has 3 values : RADIO_OFF, RADIO_UNAVAILABLE, RADIO_ON.
-     *
-     * @param newState new RadioState decoded from RIL_UNSOL_RADIO_STATE_CHANGED
-     */
-    protected void setRadioState(RadioState newState) {
-        RadioState oldState;
-
-        synchronized (mStateMonitor) {
-            if (false) {
-                Log.v(LOG_TAG, "setRadioState old: " + mState
-                    + " new " + newState);
-            }
-
-            oldState = mState;
-            mState = newState;
-
-            if (oldState == mState) {
-                // no state transition
-                return;
-            }
-
-            mRadioStateChangedRegistrants.notifyRegistrants();
-
-            if (mState.isAvailable() && !oldState.isAvailable()) {
-                Log.d(LOG_TAG,"Notifying: radio available");
-                mAvailRegistrants.notifyRegistrants();
-                onRadioAvailable();
-            }
-
-            if (!mState.isAvailable() && oldState.isAvailable()) {
-                Log.d(LOG_TAG,"Notifying: radio not available");
-                mNotAvailRegistrants.notifyRegistrants();
-            }
-
-            if (mState.isOn() && !oldState.isOn()) {
-                Log.d(LOG_TAG,"Notifying: Radio On");
-                mOnRegistrants.notifyRegistrants();
-            }
-
-            if ((!mState.isOn() || !mState.isAvailable())
-                && !((!oldState.isOn() || !oldState.isAvailable()))
-            ) {
-                Log.d(LOG_TAG,"Notifying: radio off or not available");
-                mOffOrNotAvailRegistrants.notifyRegistrants();
-            }
-        }
-    }
-
-    protected void onRadioAvailable() {
-    }
-
-    /**
-     * The contents of the /proc/cmdline file
-     */
-    private static String getProcCmdLine()
-    {
-        String cmdline = "";
-        FileInputStream is = null;
-        try {
-            is = new FileInputStream("/proc/cmdline");
-            byte [] buffer = new byte[2048];
-            int count = is.read(buffer);
-            if (count > 0) {
-                cmdline = new String(buffer, 0, count);
-            }
-        } catch (IOException e) {
-            Log.d(LOG_TAG, "No /proc/cmdline exception=" + e);
-        } finally {
-            if (is != null) {
-                try {
-                    is.close();
-                } catch (IOException e) {
-                }
-            }
-        }
-        Log.d(LOG_TAG, "/proc/cmdline=" + cmdline);
-        return cmdline;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public int getLteOnCdmaMode() {
-        return getLteOnCdmaModeStatic();
-    }
-
-    /** Kernel command line */
-    private static final String sKernelCmdLine = getProcCmdLine();
-
-    /** Pattern for selecting the product type from the kernel command line */
-    private static final Pattern sProductTypePattern =
-        Pattern.compile("\\sproduct_type\\s*=\\s*(\\w+)");
-
-    /** The ProductType used for LTE on CDMA devices */
-    private static final String sLteOnCdmaProductType =
-        SystemProperties.get(TelephonyProperties.PROPERTY_LTE_ON_CDMA_PRODUCT_TYPE, "");
-
-    /**
-     * Return if the current radio is LTE on CDMA. This
-     * is a tri-state return value as for a period of time
-     * the mode may be unknown.
-     *
-     * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
-     * or {@link Phone#LTE_ON_CDMA_TRUE}
-     */
-    public static int getLteOnCdmaModeStatic() {
-        int retVal;
-        int curVal;
-        String productType = "";
-
-        curVal = SystemProperties.getInt(TelephonyProperties.PROPERTY_LTE_ON_CDMA_DEVICE,
-                    Phone.LTE_ON_CDMA_UNKNOWN);
-        retVal = curVal;
-        if (retVal == Phone.LTE_ON_CDMA_UNKNOWN) {
-            Matcher matcher = sProductTypePattern.matcher(sKernelCmdLine);
-            if (matcher.find()) {
-                productType = matcher.group(1);
-                if (sLteOnCdmaProductType.equals(productType)) {
-                    retVal = Phone.LTE_ON_CDMA_TRUE;
-                } else {
-                    retVal = Phone.LTE_ON_CDMA_FALSE;
-                }
-            } else {
-                retVal = Phone.LTE_ON_CDMA_FALSE;
-            }
-        }
-
-        Log.d(LOG_TAG, "getLteOnCdmaMode=" + retVal + " curVal=" + curVal +
-                " product_type='" + productType +
-                "' lteOnCdmaProductType='" + sLteOnCdmaProductType + "'");
-        return retVal;
-    }
-
-    @Override
-    public void testingEmergencyCall() {}
-}
diff --git a/telephony/java/com/android/internal/telephony/Call.java b/telephony/java/com/android/internal/telephony/Call.java
deleted file mode 100644
index 4967ab8..0000000
--- a/telephony/java/com/android/internal/telephony/Call.java
+++ /dev/null
@@ -1,255 +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.internal.telephony;
-
-import java.util.List;
-
-import android.util.Log;
-
-/**
- * {@hide}
- */
-public abstract class Call {
-    /* Enums */
-
-    public enum State {
-        IDLE, ACTIVE, HOLDING, DIALING, ALERTING, INCOMING, WAITING, DISCONNECTED, DISCONNECTING;
-
-        public boolean isAlive() {
-            return !(this == IDLE || this == DISCONNECTED || this == DISCONNECTING);
-        }
-
-        public boolean isRinging() {
-            return this == INCOMING || this == WAITING;
-        }
-
-        public boolean isDialing() {
-            return this == DIALING || this == ALERTING;
-        }
-    }
-
-
-    /* Instance Variables */
-
-    public State state = State.IDLE;
-
-
-    // Flag to indicate if the current calling/caller information
-    // is accurate. If false the information is known to be accurate.
-    //
-    // For CDMA, during call waiting/3 way, there is no network response
-    // if call waiting is answered, network timed out, dropped, 3 way
-    // merged, etc.
-    protected boolean isGeneric = false;
-
-    protected final String LOG_TAG = "Call";
-
-    /* Instance Methods */
-
-    /** Do not modify the List result!!! This list is not yours to keep
-     *  It will change across event loop iterations            top
-     */
-
-    public abstract List<Connection> getConnections();
-    public abstract Phone getPhone();
-    public abstract boolean isMultiparty();
-    public abstract void hangup() throws CallStateException;
-
-
-    /**
-     * hasConnection
-     *
-     * @param c a Connection object
-     * @return true if the call contains the connection object passed in
-     */
-    public boolean hasConnection(Connection c) {
-        return c.getCall() == this;
-    }
-
-    /**
-     * hasConnections
-     * @return true if the call contains one or more connections
-     */
-    public boolean hasConnections() {
-        List connections = getConnections();
-
-        if (connections == null) {
-            return false;
-        }
-
-        return connections.size() > 0;
-    }
-
-    /**
-     * getState
-     * @return state of class call
-     */
-    public State getState() {
-        return state;
-    }
-
-    /**
-     * isIdle
-     *
-     * FIXME rename
-     * @return true if the call contains only disconnected connections (if any)
-     */
-    public boolean isIdle() {
-        return !getState().isAlive();
-    }
-
-    /**
-     * Returns the Connection associated with this Call that was created
-     * first, or null if there are no Connections in this Call
-     */
-    public Connection
-    getEarliestConnection() {
-        List l;
-        long time = Long.MAX_VALUE;
-        Connection c;
-        Connection earliest = null;
-
-        l = getConnections();
-
-        if (l.size() == 0) {
-            return null;
-        }
-
-        for (int i = 0, s = l.size() ; i < s ; i++) {
-            c = (Connection) l.get(i);
-            long t;
-
-            t = c.getCreateTime();
-
-            if (t < time) {
-                earliest = c;
-                time = t;
-            }
-        }
-
-        return earliest;
-    }
-
-    public long
-    getEarliestCreateTime() {
-        List l;
-        long time = Long.MAX_VALUE;
-
-        l = getConnections();
-
-        if (l.size() == 0) {
-            return 0;
-        }
-
-        for (int i = 0, s = l.size() ; i < s ; i++) {
-            Connection c = (Connection) l.get(i);
-            long t;
-
-            t = c.getCreateTime();
-
-            time = t < time ? t : time;
-        }
-
-        return time;
-    }
-
-    public long
-    getEarliestConnectTime() {
-        long time = Long.MAX_VALUE;
-        List l = getConnections();
-
-        if (l.size() == 0) {
-            return 0;
-        }
-
-        for (int i = 0, s = l.size() ; i < s ; i++) {
-            Connection c = (Connection) l.get(i);
-            long t;
-
-            t = c.getConnectTime();
-
-            time = t < time ? t : time;
-        }
-
-        return time;
-    }
-
-
-    public boolean
-    isDialingOrAlerting() {
-        return getState().isDialing();
-    }
-
-    public boolean
-    isRinging() {
-        return getState().isRinging();
-    }
-
-    /**
-     * Returns the Connection associated with this Call that was created
-     * last, or null if there are no Connections in this Call
-     */
-    public Connection
-    getLatestConnection() {
-        List l = getConnections();
-        if (l.size() == 0) {
-            return null;
-        }
-
-        long time = 0;
-        Connection latest = null;
-        for (int i = 0, s = l.size() ; i < s ; i++) {
-            Connection c = (Connection) l.get(i);
-            long t = c.getCreateTime();
-
-            if (t > time) {
-                latest = c;
-                time = t;
-            }
-        }
-
-        return latest;
-    }
-
-    /**
-     * To indicate if the connection information is accurate
-     * or not. false means accurate. Only used for CDMA.
-     */
-    public boolean isGeneric() {
-        return isGeneric;
-    }
-
-    /**
-     * Set the generic instance variable
-     */
-    public void setGeneric(boolean generic) {
-        isGeneric = generic;
-    }
-
-    /**
-     * Hangup call if it is alive
-     */
-    public void hangupIfAlive() {
-        if (getState().isAlive()) {
-            try {
-                hangup();
-            } catch (CallStateException ex) {
-                Log.w(LOG_TAG, " hangupIfActive: caught " + ex);
-            }
-        }
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/CallForwardInfo.java b/telephony/java/com/android/internal/telephony/CallForwardInfo.java
deleted file mode 100644
index 8b853b0..0000000
--- a/telephony/java/com/android/internal/telephony/CallForwardInfo.java
+++ /dev/null
@@ -1,42 +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.internal.telephony;
-
-import android.telephony.PhoneNumberUtils;
-
-/**
- * See also RIL_CallForwardInfo in include/telephony/ril.h
- *
- * {@hide}
- */
-public class CallForwardInfo {
-    public int             status;      /*1 = active, 0 = not active */
-    public int             reason;      /* from TS 27.007 7.11 "reason" */
-    public int             serviceClass; /* Sum of CommandsInterface.SERVICE_CLASS */
-    public int             toa;         /* "type" from TS 27.007 7.11 */
-    public String          number;      /* "number" from TS 27.007 7.11 */
-    public int             timeSeconds; /* for CF no reply only */
-
-    public String toString() {
-        return super.toString() + (status == 0 ? " not active " : " active ")
-            + " reason: " + reason
-            + " serviceClass: " + serviceClass
-            + " \"" + PhoneNumberUtils.stringFromStringAndTOA(number, toa) + "\" "
-            + timeSeconds + " seconds";
-
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java
deleted file mode 100644
index f825f31..0000000
--- a/telephony/java/com/android/internal/telephony/CallManager.java
+++ /dev/null
@@ -1,1855 +0,0 @@
-/*
- * Copyright (C) 2010 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.internal.telephony;
-
-import com.android.internal.telephony.sip.SipPhone;
-
-import android.content.Context;
-import android.media.AudioManager;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.RegistrantList;
-import android.os.Registrant;
-import android.telephony.PhoneStateListener;
-import android.telephony.ServiceState;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-
-
-/**
- * @hide
- *
- * CallManager class provides an abstract layer for PhoneApp to access
- * and control calls. It implements Phone interface.
- *
- * CallManager provides call and connection control as well as
- * channel capability.
- *
- * There are three categories of APIs CallManager provided
- *
- *  1. Call control and operation, such as dial() and hangup()
- *  2. Channel capabilities, such as CanConference()
- *  3. Register notification
- *
- *
- */
-public final class CallManager {
-
-    private static final String LOG_TAG ="CallManager";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    private static final int EVENT_DISCONNECT = 100;
-    private static final int EVENT_PRECISE_CALL_STATE_CHANGED = 101;
-    private static final int EVENT_NEW_RINGING_CONNECTION = 102;
-    private static final int EVENT_UNKNOWN_CONNECTION = 103;
-    private static final int EVENT_INCOMING_RING = 104;
-    private static final int EVENT_RINGBACK_TONE = 105;
-    private static final int EVENT_IN_CALL_VOICE_PRIVACY_ON = 106;
-    private static final int EVENT_IN_CALL_VOICE_PRIVACY_OFF = 107;
-    private static final int EVENT_CALL_WAITING = 108;
-    private static final int EVENT_DISPLAY_INFO = 109;
-    private static final int EVENT_SIGNAL_INFO = 110;
-    private static final int EVENT_CDMA_OTA_STATUS_CHANGE = 111;
-    private static final int EVENT_RESEND_INCALL_MUTE = 112;
-    private static final int EVENT_MMI_INITIATE = 113;
-    private static final int EVENT_MMI_COMPLETE = 114;
-    private static final int EVENT_ECM_TIMER_RESET = 115;
-    private static final int EVENT_SUBSCRIPTION_INFO_READY = 116;
-    private static final int EVENT_SUPP_SERVICE_FAILED = 117;
-    private static final int EVENT_SERVICE_STATE_CHANGED = 118;
-    private static final int EVENT_POST_DIAL_CHARACTER = 119;
-
-    // Singleton instance
-    private static final CallManager INSTANCE = new CallManager();
-
-    // list of registered phones, which are PhoneBase objs
-    private final ArrayList<Phone> mPhones;
-
-    // list of supported ringing calls
-    private final ArrayList<Call> mRingingCalls;
-
-    // list of supported background calls
-    private final ArrayList<Call> mBackgroundCalls;
-
-    // list of supported foreground calls
-    private final ArrayList<Call> mForegroundCalls;
-
-    // empty connection list
-    private final ArrayList<Connection> emptyConnections = new ArrayList<Connection>();
-
-    // default phone as the first phone registered, which is PhoneBase obj
-    private Phone mDefaultPhone;
-
-    // state registrants
-    protected final RegistrantList mPreciseCallStateRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mNewRingingConnectionRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mIncomingRingRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mDisconnectRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mMmiRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mUnknownConnectionRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mRingbackToneRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mInCallVoicePrivacyOnRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mInCallVoicePrivacyOffRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mCallWaitingRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mDisplayInfoRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mSignalInfoRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mCdmaOtaStatusChangeRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mResendIncallMuteRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mMmiInitiateRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mMmiCompleteRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mEcmTimerResetRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mSubscriptionInfoReadyRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mSuppServiceFailedRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mServiceStateChangedRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mPostDialCharacterRegistrants
-    = new RegistrantList();
-
-    private CallManager() {
-        mPhones = new ArrayList<Phone>();
-        mRingingCalls = new ArrayList<Call>();
-        mBackgroundCalls = new ArrayList<Call>();
-        mForegroundCalls = new ArrayList<Call>();
-        mDefaultPhone = null;
-    }
-
-    /**
-     * get singleton instance of CallManager
-     * @return CallManager
-     */
-    public static CallManager getInstance() {
-        return INSTANCE;
-    }
-
-    /**
-     * Get the corresponding PhoneBase obj
-     *
-     * @param phone a Phone object
-     * @return the corresponding PhoneBase obj in Phone if Phone
-     * is a PhoneProxy obj
-     * or the Phone itself if Phone is not a PhoneProxy obj
-     */
-    private static Phone getPhoneBase(Phone phone) {
-        if (phone instanceof PhoneProxy) {
-            return phone.getForegroundCall().getPhone();
-        }
-        return phone;
-    }
-
-    /**
-     * Check if two phones refer to the same PhoneBase obj
-     *
-     * Note: PhoneBase, not PhoneProxy, is to be used inside of CallManager
-     *
-     * Both PhoneBase and PhoneProxy implement Phone interface, so
-     * they have same phone APIs, such as dial(). The real implementation, for
-     * example in GSM,  is in GSMPhone as extend from PhoneBase, so that
-     * foregroundCall.getPhone() returns GSMPhone obj. On the other hand,
-     * PhoneFactory.getDefaultPhone() returns PhoneProxy obj, which has a class
-     * member of GSMPhone.
-     *
-     * So for phone returned by PhoneFacotry, which is used by PhoneApp,
-     *        phone.getForegroundCall().getPhone() != phone
-     * but
-     *        isSamePhone(phone, phone.getForegroundCall().getPhone()) == true
-     *
-     * @param p1 is the first Phone obj
-     * @param p2 is the second Phone obj
-     * @return true if p1 and p2 refer to the same phone
-     */
-    public static boolean isSamePhone(Phone p1, Phone p2) {
-        return (getPhoneBase(p1) == getPhoneBase(p2));
-    }
-
-    /**
-     * Returns all the registered phone objects.
-     * @return all the registered phone objects.
-     */
-    public List<Phone> getAllPhones() {
-        return Collections.unmodifiableList(mPhones);
-    }
-
-    /**
-     * Get current coarse-grained voice call state.
-     * If the Call Manager has an active call and call waiting occurs,
-     * then the phone state is RINGING not OFFHOOK
-     *
-     */
-    public Phone.State getState() {
-        Phone.State s = Phone.State.IDLE;
-
-        for (Phone phone : mPhones) {
-            if (phone.getState() == Phone.State.RINGING) {
-                s = Phone.State.RINGING;
-            } else if (phone.getState() == Phone.State.OFFHOOK) {
-                if (s == Phone.State.IDLE) s = Phone.State.OFFHOOK;
-            }
-        }
-        return s;
-    }
-
-    /**
-     * @return the service state of CallManager, which represents the
-     * highest priority state of all the service states of phones
-     *
-     * The priority is defined as
-     *
-     * STATE_IN_SERIVCE > STATE_OUT_OF_SERIVCE > STATE_EMERGENCY > STATE_POWER_OFF
-     *
-     */
-
-    public int getServiceState() {
-        int resultState = ServiceState.STATE_OUT_OF_SERVICE;
-
-        for (Phone phone : mPhones) {
-            int serviceState = phone.getServiceState().getState();
-            if (serviceState == ServiceState.STATE_IN_SERVICE) {
-                // IN_SERVICE has the highest priority
-                resultState = serviceState;
-                break;
-            } else if (serviceState == ServiceState.STATE_OUT_OF_SERVICE) {
-                // OUT_OF_SERVICE replaces EMERGENCY_ONLY and POWER_OFF
-                // Note: EMERGENCY_ONLY is not in use at this moment
-                if ( resultState == ServiceState.STATE_EMERGENCY_ONLY ||
-                        resultState == ServiceState.STATE_POWER_OFF) {
-                    resultState = serviceState;
-                }
-            } else if (serviceState == ServiceState.STATE_EMERGENCY_ONLY) {
-                if (resultState == ServiceState.STATE_POWER_OFF) {
-                    resultState = serviceState;
-                }
-            }
-        }
-        return resultState;
-    }
-
-    /**
-     * Register phone to CallManager
-     * @param phone to be registered
-     * @return true if register successfully
-     */
-    public boolean registerPhone(Phone phone) {
-        Phone basePhone = getPhoneBase(phone);
-
-        if (basePhone != null && !mPhones.contains(basePhone)) {
-
-            if (DBG) {
-                Log.d(LOG_TAG, "registerPhone(" +
-                        phone.getPhoneName() + " " + phone + ")");
-            }
-
-            if (mPhones.isEmpty()) {
-                mDefaultPhone = basePhone;
-            }
-            mPhones.add(basePhone);
-            mRingingCalls.add(basePhone.getRingingCall());
-            mBackgroundCalls.add(basePhone.getBackgroundCall());
-            mForegroundCalls.add(basePhone.getForegroundCall());
-            registerForPhoneStates(basePhone);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * unregister phone from CallManager
-     * @param phone to be unregistered
-     */
-    public void unregisterPhone(Phone phone) {
-        Phone basePhone = getPhoneBase(phone);
-
-        if (basePhone != null && mPhones.contains(basePhone)) {
-
-            if (DBG) {
-                Log.d(LOG_TAG, "unregisterPhone(" +
-                        phone.getPhoneName() + " " + phone + ")");
-            }
-
-            mPhones.remove(basePhone);
-            mRingingCalls.remove(basePhone.getRingingCall());
-            mBackgroundCalls.remove(basePhone.getBackgroundCall());
-            mForegroundCalls.remove(basePhone.getForegroundCall());
-            unregisterForPhoneStates(basePhone);
-            if (basePhone == mDefaultPhone) {
-                if (mPhones.isEmpty()) {
-                    mDefaultPhone = null;
-                } else {
-                    mDefaultPhone = mPhones.get(0);
-                }
-            }
-        }
-    }
-
-    /**
-     * return the default phone or null if no phone available
-     */
-    public Phone getDefaultPhone() {
-        return mDefaultPhone;
-    }
-
-    /**
-     * @return the phone associated with the foreground call
-     */
-    public Phone getFgPhone() {
-        return getActiveFgCall().getPhone();
-    }
-
-    /**
-     * @return the phone associated with the background call
-     */
-    public Phone getBgPhone() {
-        return getFirstActiveBgCall().getPhone();
-    }
-
-    /**
-     * @return the phone associated with the ringing call
-     */
-    public Phone getRingingPhone() {
-        return getFirstActiveRingingCall().getPhone();
-    }
-
-    public void setAudioMode() {
-        Context context = getContext();
-        if (context == null) return;
-        AudioManager audioManager = (AudioManager)
-                context.getSystemService(Context.AUDIO_SERVICE);
-
-        // change the audio mode and request/abandon audio focus according to phone state,
-        // but only on audio mode transitions
-        switch (getState()) {
-            case RINGING:
-                if (audioManager.getMode() != AudioManager.MODE_RINGTONE) {
-                    // only request audio focus if the ringtone is going to be heard
-                    if (audioManager.getStreamVolume(AudioManager.STREAM_RING) > 0) {
-                        if (VDBG) Log.d(LOG_TAG, "requestAudioFocus on STREAM_RING");
-                        audioManager.requestAudioFocusForCall(AudioManager.STREAM_RING,
-                                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
-                    }
-                    audioManager.setMode(AudioManager.MODE_RINGTONE);
-                }
-                break;
-            case OFFHOOK:
-                Phone offhookPhone = getFgPhone();
-                if (getActiveFgCallState() == Call.State.IDLE) {
-                    // There is no active Fg calls, the OFFHOOK state
-                    // is set by the Bg call. So set the phone to bgPhone.
-                    offhookPhone = getBgPhone();
-                }
-
-                int newAudioMode = AudioManager.MODE_IN_CALL;
-                if (offhookPhone instanceof SipPhone) {
-                    // enable IN_COMMUNICATION audio mode instead for sipPhone
-                    newAudioMode = AudioManager.MODE_IN_COMMUNICATION;
-                }
-                if (audioManager.getMode() != newAudioMode) {
-                    // request audio focus before setting the new mode
-                    if (VDBG) Log.d(LOG_TAG, "requestAudioFocus on STREAM_VOICE_CALL");
-                    audioManager.requestAudioFocusForCall(AudioManager.STREAM_VOICE_CALL,
-                            AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
-                    audioManager.setMode(newAudioMode);
-                }
-                break;
-            case IDLE:
-                if (audioManager.getMode() != AudioManager.MODE_NORMAL) {
-                    audioManager.setMode(AudioManager.MODE_NORMAL);
-                    if (VDBG) Log.d(LOG_TAG, "abandonAudioFocus");
-                    // abandon audio focus after the mode has been set back to normal
-                    audioManager.abandonAudioFocusForCall();
-                }
-                break;
-        }
-    }
-
-    private Context getContext() {
-        Phone defaultPhone = getDefaultPhone();
-        return ((defaultPhone == null) ? null : defaultPhone.getContext());
-    }
-
-    private void registerForPhoneStates(Phone phone) {
-        // for common events supported by all phones
-        phone.registerForPreciseCallStateChanged(mHandler, EVENT_PRECISE_CALL_STATE_CHANGED, null);
-        phone.registerForDisconnect(mHandler, EVENT_DISCONNECT, null);
-        phone.registerForNewRingingConnection(mHandler, EVENT_NEW_RINGING_CONNECTION, null);
-        phone.registerForUnknownConnection(mHandler, EVENT_UNKNOWN_CONNECTION, null);
-        phone.registerForIncomingRing(mHandler, EVENT_INCOMING_RING, null);
-        phone.registerForRingbackTone(mHandler, EVENT_RINGBACK_TONE, null);
-        phone.registerForInCallVoicePrivacyOn(mHandler, EVENT_IN_CALL_VOICE_PRIVACY_ON, null);
-        phone.registerForInCallVoicePrivacyOff(mHandler, EVENT_IN_CALL_VOICE_PRIVACY_OFF, null);
-        phone.registerForDisplayInfo(mHandler, EVENT_DISPLAY_INFO, null);
-        phone.registerForSignalInfo(mHandler, EVENT_SIGNAL_INFO, null);
-        phone.registerForResendIncallMute(mHandler, EVENT_RESEND_INCALL_MUTE, null);
-        phone.registerForMmiInitiate(mHandler, EVENT_MMI_INITIATE, null);
-        phone.registerForMmiComplete(mHandler, EVENT_MMI_COMPLETE, null);
-        phone.registerForSuppServiceFailed(mHandler, EVENT_SUPP_SERVICE_FAILED, null);
-        phone.registerForServiceStateChanged(mHandler, EVENT_SERVICE_STATE_CHANGED, null);
-
-        // for events supported only by GSM and CDMA phone
-        if (phone.getPhoneType() == Phone.PHONE_TYPE_GSM ||
-                phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) {
-            phone.setOnPostDialCharacter(mHandler, EVENT_POST_DIAL_CHARACTER, null);
-        }
-
-        // for events supported only by CDMA phone
-        if (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA ){
-            phone.registerForCdmaOtaStatusChange(mHandler, EVENT_CDMA_OTA_STATUS_CHANGE, null);
-            phone.registerForSubscriptionInfoReady(mHandler, EVENT_SUBSCRIPTION_INFO_READY, null);
-            phone.registerForCallWaiting(mHandler, EVENT_CALL_WAITING, null);
-            phone.registerForEcmTimerReset(mHandler, EVENT_ECM_TIMER_RESET, null);
-        }
-    }
-
-    private void unregisterForPhoneStates(Phone phone) {
-        //  for common events supported by all phones
-        phone.unregisterForPreciseCallStateChanged(mHandler);
-        phone.unregisterForDisconnect(mHandler);
-        phone.unregisterForNewRingingConnection(mHandler);
-        phone.unregisterForUnknownConnection(mHandler);
-        phone.unregisterForIncomingRing(mHandler);
-        phone.unregisterForRingbackTone(mHandler);
-        phone.unregisterForInCallVoicePrivacyOn(mHandler);
-        phone.unregisterForInCallVoicePrivacyOff(mHandler);
-        phone.unregisterForDisplayInfo(mHandler);
-        phone.unregisterForSignalInfo(mHandler);
-        phone.unregisterForResendIncallMute(mHandler);
-        phone.unregisterForMmiInitiate(mHandler);
-        phone.unregisterForMmiComplete(mHandler);
-        phone.unregisterForSuppServiceFailed(mHandler);
-        phone.unregisterForServiceStateChanged(mHandler);
-
-        // for events supported only by GSM and CDMA phone
-        if (phone.getPhoneType() == Phone.PHONE_TYPE_GSM ||
-                phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) {
-            phone.setOnPostDialCharacter(null, EVENT_POST_DIAL_CHARACTER, null);
-        }
-
-        // for events supported only by CDMA phone
-        if (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA ){
-            phone.unregisterForCdmaOtaStatusChange(mHandler);
-            phone.unregisterForSubscriptionInfoReady(mHandler);
-            phone.unregisterForCallWaiting(mHandler);
-            phone.unregisterForEcmTimerReset(mHandler);
-        }
-    }
-
-    /**
-     * Answers a ringing or waiting call.
-     *
-     * Active call, if any, go on hold.
-     * If active call can't be held, i.e., a background call of the same channel exists,
-     * the active call will be hang up.
-     *
-     * Answering occurs asynchronously, and final notification occurs via
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}.
-     *
-     * @exception CallStateException when call is not ringing or waiting
-     */
-    public void acceptCall(Call ringingCall) throws CallStateException {
-        Phone ringingPhone = ringingCall.getPhone();
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "acceptCall(" +ringingCall + " from " + ringingCall.getPhone() + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if ( hasActiveFgCall() ) {
-            Phone activePhone = getActiveFgCall().getPhone();
-            boolean hasBgCall = ! (activePhone.getBackgroundCall().isIdle());
-            boolean sameChannel = (activePhone == ringingPhone);
-
-            if (VDBG) {
-                Log.d(LOG_TAG, "hasBgCall: "+ hasBgCall + "sameChannel:" + sameChannel);
-            }
-
-            if (sameChannel && hasBgCall) {
-                getActiveFgCall().hangup();
-            } else if (!sameChannel && !hasBgCall) {
-                activePhone.switchHoldingAndActive();
-            } else if (!sameChannel && hasBgCall) {
-                getActiveFgCall().hangup();
-            }
-        }
-
-        ringingPhone.acceptCall();
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End acceptCall(" +ringingCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-    }
-
-    /**
-     * Reject (ignore) a ringing call. In GSM, this means UDUB
-     * (User Determined User Busy). Reject occurs asynchronously,
-     * and final notification occurs via
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}.
-     *
-     * @exception CallStateException when no call is ringing or waiting
-     */
-    public void rejectCall(Call ringingCall) throws CallStateException {
-        if (VDBG) {
-            Log.d(LOG_TAG, "rejectCall(" +ringingCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        Phone ringingPhone = ringingCall.getPhone();
-
-        ringingPhone.rejectCall();
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End rejectCall(" +ringingCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-    }
-
-    /**
-     * Places active call on hold, and makes held call active.
-     * Switch occurs asynchronously and may fail.
-     *
-     * There are 4 scenarios
-     * 1. only active call but no held call, aka, hold
-     * 2. no active call but only held call, aka, unhold
-     * 3. both active and held calls from same phone, aka, swap
-     * 4. active and held calls from different phones, aka, phone swap
-     *
-     * Final notification occurs via
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}.
-     *
-     * @exception CallStateException if active call is ringing, waiting, or
-     * dialing/alerting, or heldCall can't be active.
-     * In these cases, this operation may not be performed.
-     */
-    public void switchHoldingAndActive(Call heldCall) throws CallStateException {
-        Phone activePhone = null;
-        Phone heldPhone = null;
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "switchHoldingAndActive(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (hasActiveFgCall()) {
-            activePhone = getActiveFgCall().getPhone();
-        }
-
-        if (heldCall != null) {
-            heldPhone = heldCall.getPhone();
-        }
-
-        if (activePhone != null) {
-            activePhone.switchHoldingAndActive();
-        }
-
-        if (heldPhone != null && heldPhone != activePhone) {
-            heldPhone.switchHoldingAndActive();
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End switchHoldingAndActive(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-    }
-
-    /**
-     * Hangup foreground call and resume the specific background call
-     *
-     * Note: this is noop if there is no foreground call or the heldCall is null
-     *
-     * @param heldCall to become foreground
-     * @throws CallStateException
-     */
-    public void hangupForegroundResumeBackground(Call heldCall) throws CallStateException {
-        Phone foregroundPhone = null;
-        Phone backgroundPhone = null;
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "hangupForegroundResumeBackground(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (hasActiveFgCall()) {
-            foregroundPhone = getFgPhone();
-            if (heldCall != null) {
-                backgroundPhone = heldCall.getPhone();
-                if (foregroundPhone == backgroundPhone) {
-                    getActiveFgCall().hangup();
-                } else {
-                // the call to be hangup and resumed belongs to different phones
-                    getActiveFgCall().hangup();
-                    switchHoldingAndActive(heldCall);
-                }
-            }
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End hangupForegroundResumeBackground(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-    }
-
-    /**
-     * Whether or not the phone can conference in the current phone
-     * state--that is, one call holding and one call active.
-     * @return true if the phone can conference; false otherwise.
-     */
-    public boolean canConference(Call heldCall) {
-        Phone activePhone = null;
-        Phone heldPhone = null;
-
-        if (hasActiveFgCall()) {
-            activePhone = getActiveFgCall().getPhone();
-        }
-
-        if (heldCall != null) {
-            heldPhone = heldCall.getPhone();
-        }
-
-        return heldPhone.getClass().equals(activePhone.getClass());
-    }
-
-    /**
-     * Conferences holding and active. Conference occurs asynchronously
-     * and may fail. Final notification occurs via
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}.
-     *
-     * @exception CallStateException if canConference() would return false.
-     * In these cases, this operation may not be performed.
-     */
-    public void conference(Call heldCall) throws CallStateException {
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "conference(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-
-        Phone fgPhone = getFgPhone();
-        if (fgPhone instanceof SipPhone) {
-            ((SipPhone) fgPhone).conference(heldCall);
-        } else if (canConference(heldCall)) {
-            fgPhone.conference();
-        } else {
-            throw(new CallStateException("Can't conference foreground and selected background call"));
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End conference(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-    }
-
-    /**
-     * Initiate a new voice connection. This happens asynchronously, so you
-     * cannot assume the audio path is connected (or a call index has been
-     * assigned) until PhoneStateChanged notification has occurred.
-     *
-     * @exception CallStateException if a new outgoing call is not currently
-     * possible because no more call slots exist or a call exists that is
-     * dialing, alerting, ringing, or waiting.  Other errors are
-     * handled asynchronously.
-     */
-    public Connection dial(Phone phone, String dialString) throws CallStateException {
-        Phone basePhone = getPhoneBase(phone);
-        Connection result;
-
-        if (VDBG) {
-            Log.d(LOG_TAG, " dial(" + basePhone + ", "+ dialString + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (!canDial(phone)) {
-            throw new CallStateException("cannot dial in current state");
-        }
-
-        if ( hasActiveFgCall() ) {
-            Phone activePhone = getActiveFgCall().getPhone();
-            boolean hasBgCall = !(activePhone.getBackgroundCall().isIdle());
-
-            if (DBG) {
-                Log.d(LOG_TAG, "hasBgCall: "+ hasBgCall + " sameChannel:" + (activePhone == basePhone));
-            }
-
-            if (activePhone != basePhone) {
-                if (hasBgCall) {
-                    Log.d(LOG_TAG, "Hangup");
-                    getActiveFgCall().hangup();
-                } else {
-                    Log.d(LOG_TAG, "Switch");
-                    activePhone.switchHoldingAndActive();
-                }
-            }
-        }
-
-        result = basePhone.dial(dialString);
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End dial(" + basePhone + ", "+ dialString + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        return result;
-    }
-
-    /**
-     * Initiate a new voice connection. This happens asynchronously, so you
-     * cannot assume the audio path is connected (or a call index has been
-     * assigned) until PhoneStateChanged notification has occurred.
-     *
-     * @exception CallStateException if a new outgoing call is not currently
-     * possible because no more call slots exist or a call exists that is
-     * dialing, alerting, ringing, or waiting.  Other errors are
-     * handled asynchronously.
-     */
-    public Connection dial(Phone phone, String dialString, UUSInfo uusInfo) throws CallStateException {
-        return phone.dial(dialString, uusInfo);
-    }
-
-    /**
-     * clear disconnect connection for each phone
-     */
-    public void clearDisconnected() {
-        for(Phone phone : mPhones) {
-            phone.clearDisconnected();
-        }
-    }
-
-    /**
-     * Phone can make a call only if ALL of the following are true:
-     *        - Phone is not powered off
-     *        - There's no incoming or waiting call
-     *        - There's available call slot in either foreground or background
-     *        - The foreground call is ACTIVE or IDLE or DISCONNECTED.
-     *          (We mainly need to make sure it *isn't* DIALING or ALERTING.)
-     * @param phone
-     * @return true if the phone can make a new call
-     */
-    private boolean canDial(Phone phone) {
-        int serviceState = phone.getServiceState().getState();
-        boolean hasRingingCall = hasActiveRingingCall();
-        boolean hasActiveCall = hasActiveFgCall();
-        boolean hasHoldingCall = hasActiveBgCall();
-        boolean allLinesTaken = hasActiveCall && hasHoldingCall;
-        Call.State fgCallState = getActiveFgCallState();
-
-        boolean result = (serviceState != ServiceState.STATE_POWER_OFF
-                && !hasRingingCall
-                && !allLinesTaken
-                && ((fgCallState == Call.State.ACTIVE)
-                    || (fgCallState == Call.State.IDLE)
-                    || (fgCallState == Call.State.DISCONNECTED)));
-
-        if (result == false) {
-            Log.d(LOG_TAG, "canDial serviceState=" + serviceState
-                            + " hasRingingCall=" + hasRingingCall
-                            + " hasActiveCall=" + hasActiveCall
-                            + " hasHoldingCall=" + hasHoldingCall
-                            + " allLinesTaken=" + allLinesTaken
-                            + " fgCallState=" + fgCallState);
-        }
-        return result;
-    }
-
-    /**
-     * Whether or not the phone can do explicit call transfer in the current
-     * phone state--that is, one call holding and one call active.
-     * @return true if the phone can do explicit call transfer; false otherwise.
-     */
-    public boolean canTransfer(Call heldCall) {
-        Phone activePhone = null;
-        Phone heldPhone = null;
-
-        if (hasActiveFgCall()) {
-            activePhone = getActiveFgCall().getPhone();
-        }
-
-        if (heldCall != null) {
-            heldPhone = heldCall.getPhone();
-        }
-
-        return (heldPhone == activePhone && activePhone.canTransfer());
-    }
-
-    /**
-     * Connects the held call and active call
-     * Disconnects the subscriber from both calls
-     *
-     * Explicit Call Transfer occurs asynchronously
-     * and may fail. Final notification occurs via
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}.
-     *
-     * @exception CallStateException if canTransfer() would return false.
-     * In these cases, this operation may not be performed.
-     */
-    public void explicitCallTransfer(Call heldCall) throws CallStateException {
-        if (VDBG) {
-            Log.d(LOG_TAG, " explicitCallTransfer(" + heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (canTransfer(heldCall)) {
-            heldCall.getPhone().explicitCallTransfer();
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End explicitCallTransfer(" + heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-    }
-
-    /**
-     * Returns a list of MMI codes that are pending for a phone. (They have initiated
-     * but have not yet completed).
-     * Presently there is only ever one.
-     *
-     * Use <code>registerForMmiInitiate</code>
-     * and <code>registerForMmiComplete</code> for change notification.
-     * @return null if phone doesn't have or support mmi code
-     */
-    public List<? extends MmiCode> getPendingMmiCodes(Phone phone) {
-        Log.e(LOG_TAG, "getPendingMmiCodes not implemented");
-        return null;
-    }
-
-    /**
-     * Sends user response to a USSD REQUEST message.  An MmiCode instance
-     * representing this response is sent to handlers registered with
-     * registerForMmiInitiate.
-     *
-     * @param ussdMessge    Message to send in the response.
-     * @return false if phone doesn't support ussd service
-     */
-    public boolean sendUssdResponse(Phone phone, String ussdMessge) {
-        Log.e(LOG_TAG, "sendUssdResponse not implemented");
-        return false;
-    }
-
-    /**
-     * Mutes or unmutes the microphone for the active call. The microphone
-     * is automatically unmuted if a call is answered, dialed, or resumed
-     * from a holding state.
-     *
-     * @param muted true to mute the microphone,
-     * false to activate the microphone.
-     */
-
-    public void setMute(boolean muted) {
-        if (VDBG) {
-            Log.d(LOG_TAG, " setMute(" + muted + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (hasActiveFgCall()) {
-            getActiveFgCall().getPhone().setMute(muted);
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End setMute(" + muted + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-    }
-
-    /**
-     * Gets current mute status. Use
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}
-     * as a change notifcation, although presently phone state changed is not
-     * fired when setMute() is called.
-     *
-     * @return true is muting, false is unmuting
-     */
-    public boolean getMute() {
-        if (hasActiveFgCall()) {
-            return getActiveFgCall().getPhone().getMute();
-        } else if (hasActiveBgCall()) {
-            return getFirstActiveBgCall().getPhone().getMute();
-        }
-        return false;
-    }
-
-    /**
-     * Enables or disables echo suppression.
-     */
-    public void setEchoSuppressionEnabled(boolean enabled) {
-        if (VDBG) {
-            Log.d(LOG_TAG, " setEchoSuppression(" + enabled + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (hasActiveFgCall()) {
-            getActiveFgCall().getPhone().setEchoSuppressionEnabled(enabled);
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End setEchoSuppression(" + enabled + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-    }
-
-    /**
-     * Play a DTMF tone on the active call.
-     *
-     * @param c should be one of 0-9, '*' or '#'. Other values will be
-     * silently ignored.
-     * @return false if no active call or the active call doesn't support
-     *         dtmf tone
-     */
-    public boolean sendDtmf(char c) {
-        boolean result = false;
-
-        if (VDBG) {
-            Log.d(LOG_TAG, " sendDtmf(" + c + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (hasActiveFgCall()) {
-            getActiveFgCall().getPhone().sendDtmf(c);
-            result = true;
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End sendDtmf(" + c + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-        return result;
-    }
-
-    /**
-     * Start to paly a DTMF tone on the active call.
-     * or there is a playing DTMF tone.
-     * @param c should be one of 0-9, '*' or '#'. Other values will be
-     * silently ignored.
-     *
-     * @return false if no active call or the active call doesn't support
-     *         dtmf tone
-     */
-    public boolean startDtmf(char c) {
-        boolean result = false;
-
-        if (VDBG) {
-            Log.d(LOG_TAG, " startDtmf(" + c + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (hasActiveFgCall()) {
-            getActiveFgCall().getPhone().startDtmf(c);
-            result = true;
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End startDtmf(" + c + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        return result;
-    }
-
-    /**
-     * Stop the playing DTMF tone. Ignored if there is no playing DTMF
-     * tone or no active call.
-     */
-    public void stopDtmf() {
-        if (VDBG) {
-            Log.d(LOG_TAG, " stopDtmf()" );
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (hasActiveFgCall()) getFgPhone().stopDtmf();
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End stopDtmf()");
-            Log.d(LOG_TAG, this.toString());
-        }
-    }
-
-    /**
-     * send burst DTMF tone, it can send the string as single character or multiple character
-     * ignore if there is no active call or not valid digits string.
-     * Valid digit means only includes characters ISO-LATIN characters 0-9, *, #
-     * The difference between sendDtmf and sendBurstDtmf is sendDtmf only sends one character,
-     * this api can send single character and multiple character, also, this api has response
-     * back to caller.
-     *
-     * @param dtmfString is string representing the dialing digit(s) in the active call
-     * @param on the DTMF ON length in milliseconds, or 0 for default
-     * @param off the DTMF OFF length in milliseconds, or 0 for default
-     * @param onComplete is the callback message when the action is processed by BP
-     *
-     */
-    public boolean sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) {
-        if (hasActiveFgCall()) {
-            getActiveFgCall().getPhone().sendBurstDtmf(dtmfString, on, off, onComplete);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Notifies when a voice connection has disconnected, either due to local
-     * or remote hangup or error.
-     *
-     *  Messages received from this will have the following members:<p>
-     *  <ul><li>Message.obj will be an AsyncResult</li>
-     *  <li>AsyncResult.userObj = obj</li>
-     *  <li>AsyncResult.result = a Connection object that is
-     *  no longer connected.</li></ul>
-     */
-    public void registerForDisconnect(Handler h, int what, Object obj) {
-        mDisconnectRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for voice disconnection notification.
-     * Extraneous calls are tolerated silently
-     */
-    public void unregisterForDisconnect(Handler h){
-        mDisconnectRegistrants.remove(h);
-    }
-
-    /**
-     * Register for getting notifications for change in the Call State {@link Call.State}
-     * This is called PreciseCallState because the call state is more precise than the
-     * {@link Phone.State} which can be obtained using the {@link PhoneStateListener}
-     *
-     * Resulting events will have an AsyncResult in <code>Message.obj</code>.
-     * AsyncResult.userData will be set to the obj argument here.
-     * The <em>h</em> parameter is held only by a weak reference.
-     */
-    public void registerForPreciseCallStateChanged(Handler h, int what, Object obj){
-        mPreciseCallStateRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for voice call state change notifications.
-     * Extraneous calls are tolerated silently.
-     */
-    public void unregisterForPreciseCallStateChanged(Handler h){
-        mPreciseCallStateRegistrants.remove(h);
-    }
-
-    /**
-     * Notifies when a previously untracked non-ringing/waiting connection has appeared.
-     * This is likely due to some other entity (eg, SIM card application) initiating a call.
-     */
-    public void registerForUnknownConnection(Handler h, int what, Object obj){
-        mUnknownConnectionRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for unknown connection notifications.
-     */
-    public void unregisterForUnknownConnection(Handler h){
-        mUnknownConnectionRegistrants.remove(h);
-    }
-
-
-    /**
-     * Notifies when a new ringing or waiting connection has appeared.<p>
-     *
-     *  Messages received from this:
-     *  Message.obj will be an AsyncResult
-     *  AsyncResult.userObj = obj
-     *  AsyncResult.result = a Connection. <p>
-     *  Please check Connection.isRinging() to make sure the Connection
-     *  has not dropped since this message was posted.
-     *  If Connection.isRinging() is true, then
-     *   Connection.getCall() == Phone.getRingingCall()
-     */
-    public void registerForNewRingingConnection(Handler h, int what, Object obj){
-        mNewRingingConnectionRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for new ringing connection notification.
-     * Extraneous calls are tolerated silently
-     */
-
-    public void unregisterForNewRingingConnection(Handler h){
-        mNewRingingConnectionRegistrants.remove(h);
-    }
-
-    /**
-     * Notifies when an incoming call rings.<p>
-     *
-     *  Messages received from this:
-     *  Message.obj will be an AsyncResult
-     *  AsyncResult.userObj = obj
-     *  AsyncResult.result = a Connection. <p>
-     */
-    public void registerForIncomingRing(Handler h, int what, Object obj){
-        mIncomingRingRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for ring notification.
-     * Extraneous calls are tolerated silently
-     */
-
-    public void unregisterForIncomingRing(Handler h){
-        mIncomingRingRegistrants.remove(h);
-    }
-
-    /**
-     * Notifies when out-band ringback tone is needed.<p>
-     *
-     *  Messages received from this:
-     *  Message.obj will be an AsyncResult
-     *  AsyncResult.userObj = obj
-     *  AsyncResult.result = boolean, true to start play ringback tone
-     *                       and false to stop. <p>
-     */
-    public void registerForRingbackTone(Handler h, int what, Object obj){
-        mRingbackToneRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for ringback tone notification.
-     */
-
-    public void unregisterForRingbackTone(Handler h){
-        mRingbackToneRegistrants.remove(h);
-    }
-
-    /**
-     * Registers the handler to reset the uplink mute state to get
-     * uplink audio.
-     */
-    public void registerForResendIncallMute(Handler h, int what, Object obj){
-        mResendIncallMuteRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for resend incall mute notifications.
-     */
-    public void unregisterForResendIncallMute(Handler h){
-        mResendIncallMuteRegistrants.remove(h);
-    }
-
-    /**
-     * Register for notifications of initiation of a new MMI code request.
-     * MMI codes for GSM are discussed in 3GPP TS 22.030.<p>
-     *
-     * Example: If Phone.dial is called with "*#31#", then the app will
-     * be notified here.<p>
-     *
-     * The returned <code>Message.obj</code> will contain an AsyncResult.
-     *
-     * <code>obj.result</code> will be an "MmiCode" object.
-     */
-    public void registerForMmiInitiate(Handler h, int what, Object obj){
-        mMmiInitiateRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for new MMI initiate notification.
-     * Extraneous calls are tolerated silently
-     */
-    public void unregisterForMmiInitiate(Handler h){
-        mMmiInitiateRegistrants.remove(h);
-    }
-
-    /**
-     * Register for notifications that an MMI request has completed
-     * its network activity and is in its final state. This may mean a state
-     * of COMPLETE, FAILED, or CANCELLED.
-     *
-     * <code>Message.obj</code> will contain an AsyncResult.
-     * <code>obj.result</code> will be an "MmiCode" object
-     */
-    public void registerForMmiComplete(Handler h, int what, Object obj){
-        mMmiCompleteRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for MMI complete notification.
-     * Extraneous calls are tolerated silently
-     */
-    public void unregisterForMmiComplete(Handler h){
-        mMmiCompleteRegistrants.remove(h);
-    }
-
-    /**
-     * Registration point for Ecm timer reset
-     * @param h handler to notify
-     * @param what user-defined message code
-     * @param obj placed in Message.obj
-     */
-    public void registerForEcmTimerReset(Handler h, int what, Object obj){
-        mEcmTimerResetRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregister for notification for Ecm timer reset
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForEcmTimerReset(Handler h){
-        mEcmTimerResetRegistrants.remove(h);
-    }
-
-    /**
-     * Register for ServiceState changed.
-     * Message.obj will contain an AsyncResult.
-     * AsyncResult.result will be a ServiceState instance
-     */
-    public void registerForServiceStateChanged(Handler h, int what, Object obj){
-        mServiceStateChangedRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for ServiceStateChange notification.
-     * Extraneous calls are tolerated silently
-     */
-    public void unregisterForServiceStateChanged(Handler h){
-        mServiceStateChangedRegistrants.remove(h);
-    }
-
-    /**
-     * Register for notifications when a supplementary service attempt fails.
-     * Message.obj will contain an AsyncResult.
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    public void registerForSuppServiceFailed(Handler h, int what, Object obj){
-        mSuppServiceFailedRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregister for notifications when a supplementary service attempt fails.
-     * Extraneous calls are tolerated silently
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForSuppServiceFailed(Handler h){
-        mSuppServiceFailedRegistrants.remove(h);
-    }
-
-    /**
-     * Register for notifications when a sInCall VoicePrivacy is enabled
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){
-        mInCallVoicePrivacyOnRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregister for notifications when a sInCall VoicePrivacy is enabled
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForInCallVoicePrivacyOn(Handler h){
-        mInCallVoicePrivacyOnRegistrants.remove(h);
-    }
-
-    /**
-     * Register for notifications when a sInCall VoicePrivacy is disabled
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){
-        mInCallVoicePrivacyOffRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregister for notifications when a sInCall VoicePrivacy is disabled
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForInCallVoicePrivacyOff(Handler h){
-        mInCallVoicePrivacyOffRegistrants.remove(h);
-    }
-
-    /**
-     * Register for notifications when CDMA call waiting comes
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    public void registerForCallWaiting(Handler h, int what, Object obj){
-        mCallWaitingRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregister for notifications when CDMA Call waiting comes
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForCallWaiting(Handler h){
-        mCallWaitingRegistrants.remove(h);
-    }
-
-
-    /**
-     * Register for signal information notifications from the network.
-     * Message.obj will contain an AsyncResult.
-     * AsyncResult.result will be a SuppServiceNotification instance.
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-
-    public void registerForSignalInfo(Handler h, int what, Object obj){
-        mSignalInfoRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for signal information notifications.
-     * Extraneous calls are tolerated silently
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForSignalInfo(Handler h){
-        mSignalInfoRegistrants.remove(h);
-    }
-
-    /**
-     * Register for display information notifications from the network.
-     * Message.obj will contain an AsyncResult.
-     * AsyncResult.result will be a SuppServiceNotification instance.
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    public void registerForDisplayInfo(Handler h, int what, Object obj){
-        mDisplayInfoRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for display information notifications.
-     * Extraneous calls are tolerated silently
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForDisplayInfo(Handler h) {
-        mDisplayInfoRegistrants.remove(h);
-    }
-
-    /**
-     * Register for notifications when CDMA OTA Provision status change
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj){
-        mCdmaOtaStatusChangeRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregister for notifications when CDMA OTA Provision status change
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForCdmaOtaStatusChange(Handler h){
-        mCdmaOtaStatusChangeRegistrants.remove(h);
-    }
-
-    /**
-     * Registration point for subscription info ready
-     * @param h handler to notify
-     * @param what what code of message when delivered
-     * @param obj placed in Message.obj
-     */
-    public void registerForSubscriptionInfoReady(Handler h, int what, Object obj){
-        mSubscriptionInfoReadyRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregister for notifications for subscription info
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForSubscriptionInfoReady(Handler h){
-        mSubscriptionInfoReadyRegistrants.remove(h);
-    }
-
-    /**
-     * Sets an event to be fired when the telephony system processes
-     * a post-dial character on an outgoing call.<p>
-     *
-     * Messages of type <code>what</code> will be sent to <code>h</code>.
-     * The <code>obj</code> field of these Message's will be instances of
-     * <code>AsyncResult</code>. <code>Message.obj.result</code> will be
-     * a Connection object.<p>
-     *
-     * Message.arg1 will be the post dial character being processed,
-     * or 0 ('\0') if end of string.<p>
-     *
-     * If Connection.getPostDialState() == WAIT,
-     * the application must call
-     * {@link com.android.internal.telephony.Connection#proceedAfterWaitChar()
-     * Connection.proceedAfterWaitChar()} or
-     * {@link com.android.internal.telephony.Connection#cancelPostDial()
-     * Connection.cancelPostDial()}
-     * for the telephony system to continue playing the post-dial
-     * DTMF sequence.<p>
-     *
-     * If Connection.getPostDialState() == WILD,
-     * the application must call
-     * {@link com.android.internal.telephony.Connection#proceedAfterWildChar
-     * Connection.proceedAfterWildChar()}
-     * or
-     * {@link com.android.internal.telephony.Connection#cancelPostDial()
-     * Connection.cancelPostDial()}
-     * for the telephony system to continue playing the
-     * post-dial DTMF sequence.<p>
-     *
-     */
-    public void registerForPostDialCharacter(Handler h, int what, Object obj){
-        mPostDialCharacterRegistrants.addUnique(h, what, obj);
-    }
-
-    public void unregisterForPostDialCharacter(Handler h){
-        mPostDialCharacterRegistrants.remove(h);
-    }
-
-    /* APIs to access foregroudCalls, backgroudCalls, and ringingCalls
-     * 1. APIs to access list of calls
-     * 2. APIs to check if any active call, which has connection other than
-     * disconnected ones, pleaser refer to Call.isIdle()
-     * 3. APIs to return first active call
-     * 4. APIs to return the connections of first active call
-     * 5. APIs to return other property of first active call
-     */
-
-    /**
-     * @return list of all ringing calls
-     */
-    public List<Call> getRingingCalls() {
-        return Collections.unmodifiableList(mRingingCalls);
-    }
-
-    /**
-     * @return list of all foreground calls
-     */
-    public List<Call> getForegroundCalls() {
-        return Collections.unmodifiableList(mForegroundCalls);
-    }
-
-    /**
-     * @return list of all background calls
-     */
-    public List<Call> getBackgroundCalls() {
-        return Collections.unmodifiableList(mBackgroundCalls);
-    }
-
-    /**
-     * Return true if there is at least one active foreground call
-     */
-    public boolean hasActiveFgCall() {
-        return (getFirstActiveCall(mForegroundCalls) != null);
-    }
-
-    /**
-     * Return true if there is at least one active background call
-     */
-    public boolean hasActiveBgCall() {
-        // TODO since hasActiveBgCall may get called often
-        // better to cache it to improve performance
-        return (getFirstActiveCall(mBackgroundCalls) != null);
-    }
-
-    /**
-     * Return true if there is at least one active ringing call
-     *
-     */
-    public boolean hasActiveRingingCall() {
-        return (getFirstActiveCall(mRingingCalls) != null);
-    }
-
-    /**
-     * return the active foreground call from foreground calls
-     *
-     * Active call means the call is NOT in Call.State.IDLE
-     *
-     * 1. If there is active foreground call, return it
-     * 2. If there is no active foreground call, return the
-     *    foreground call associated with default phone, which state is IDLE.
-     * 3. If there is no phone registered at all, return null.
-     *
-     */
-    public Call getActiveFgCall() {
-        Call call = getFirstNonIdleCall(mForegroundCalls);
-        if (call == null) {
-            call = (mDefaultPhone == null)
-                    ? null
-                    : mDefaultPhone.getForegroundCall();
-        }
-        return call;
-    }
-
-    // Returns the first call that is not in IDLE state. If both active calls
-    // and disconnecting/disconnected calls exist, return the first active call.
-    private Call getFirstNonIdleCall(List<Call> calls) {
-        Call result = null;
-        for (Call call : calls) {
-            if (!call.isIdle()) {
-                return call;
-            } else if (call.getState() != Call.State.IDLE) {
-                if (result == null) result = call;
-            }
-        }
-        return result;
-    }
-
-    /**
-     * return one active background call from background calls
-     *
-     * Active call means the call is NOT idle defined by Call.isIdle()
-     *
-     * 1. If there is only one active background call, return it
-     * 2. If there is more than one active background call, return the first one
-     * 3. If there is no active background call, return the background call
-     *    associated with default phone, which state is IDLE.
-     * 4. If there is no background call at all, return null.
-     *
-     * Complete background calls list can be get by getBackgroundCalls()
-     */
-    public Call getFirstActiveBgCall() {
-        Call call = getFirstNonIdleCall(mBackgroundCalls);
-        if (call == null) {
-            call = (mDefaultPhone == null)
-                    ? null
-                    : mDefaultPhone.getBackgroundCall();
-        }
-        return call;
-    }
-
-    /**
-     * return one active ringing call from ringing calls
-     *
-     * Active call means the call is NOT idle defined by Call.isIdle()
-     *
-     * 1. If there is only one active ringing call, return it
-     * 2. If there is more than one active ringing call, return the first one
-     * 3. If there is no active ringing call, return the ringing call
-     *    associated with default phone, which state is IDLE.
-     * 4. If there is no ringing call at all, return null.
-     *
-     * Complete ringing calls list can be get by getRingingCalls()
-     */
-    public Call getFirstActiveRingingCall() {
-        Call call = getFirstNonIdleCall(mRingingCalls);
-        if (call == null) {
-            call = (mDefaultPhone == null)
-                    ? null
-                    : mDefaultPhone.getRingingCall();
-        }
-        return call;
-    }
-
-    /**
-     * @return the state of active foreground call
-     * return IDLE if there is no active foreground call
-     */
-    public Call.State getActiveFgCallState() {
-        Call fgCall = getActiveFgCall();
-
-        if (fgCall != null) {
-            return fgCall.getState();
-        }
-
-        return Call.State.IDLE;
-    }
-
-    /**
-     * @return the connections of active foreground call
-     * return empty list if there is no active foreground call
-     */
-    public List<Connection> getFgCallConnections() {
-        Call fgCall = getActiveFgCall();
-        if ( fgCall != null) {
-            return fgCall.getConnections();
-        }
-        return emptyConnections;
-    }
-
-    /**
-     * @return the connections of active background call
-     * return empty list if there is no active background call
-     */
-    public List<Connection> getBgCallConnections() {
-        Call bgCall = getFirstActiveBgCall();
-        if ( bgCall != null) {
-            return bgCall.getConnections();
-        }
-        return emptyConnections;
-    }
-
-    /**
-     * @return the latest connection of active foreground call
-     * return null if there is no active foreground call
-     */
-    public Connection getFgCallLatestConnection() {
-        Call fgCall = getActiveFgCall();
-        if ( fgCall != null) {
-            return fgCall.getLatestConnection();
-        }
-        return null;
-    }
-
-    /**
-     * @return true if there is at least one Foreground call in disconnected state
-     */
-    public boolean hasDisconnectedFgCall() {
-        return (getFirstCallOfState(mForegroundCalls, Call.State.DISCONNECTED) != null);
-    }
-
-    /**
-     * @return true if there is at least one background call in disconnected state
-     */
-    public boolean hasDisconnectedBgCall() {
-        return (getFirstCallOfState(mBackgroundCalls, Call.State.DISCONNECTED) != null);
-    }
-
-    /**
-     * @return the first active call from a call list
-     */
-    private  Call getFirstActiveCall(ArrayList<Call> calls) {
-        for (Call call : calls) {
-            if (!call.isIdle()) {
-                return call;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * @return the first call in a the Call.state from a call list
-     */
-    private Call getFirstCallOfState(ArrayList<Call> calls, Call.State state) {
-        for (Call call : calls) {
-            if (call.getState() == state) {
-                return call;
-            }
-        }
-        return null;
-    }
-
-
-    private boolean hasMoreThanOneRingingCall() {
-        int count = 0;
-        for (Call call : mRingingCalls) {
-            if (call.getState().isRinging()) {
-                if (++count > 1) return true;
-            }
-        }
-        return false;
-    }
-
-    private Handler mHandler = new Handler() {
-
-        @Override
-        public void handleMessage(Message msg) {
-
-            switch (msg.what) {
-                case EVENT_DISCONNECT:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_DISCONNECT)");
-                    mDisconnectRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_PRECISE_CALL_STATE_CHANGED:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_PRECISE_CALL_STATE_CHANGED)");
-                    mPreciseCallStateRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_NEW_RINGING_CONNECTION:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_NEW_RINGING_CONNECTION)");
-                    if (getActiveFgCallState().isDialing() || hasMoreThanOneRingingCall()) {
-                        Connection c = (Connection) ((AsyncResult) msg.obj).result;
-                        try {
-                            Log.d(LOG_TAG, "silently drop incoming call: " + c.getCall());
-                            c.getCall().hangup();
-                        } catch (CallStateException e) {
-                            Log.w(LOG_TAG, "new ringing connection", e);
-                        }
-                    } else {
-                        mNewRingingConnectionRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    }
-                    break;
-                case EVENT_UNKNOWN_CONNECTION:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_UNKNOWN_CONNECTION)");
-                    mUnknownConnectionRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_INCOMING_RING:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_INCOMING_RING)");
-                    // The event may come from RIL who's not aware of an ongoing fg call
-                    if (!hasActiveFgCall()) {
-                        mIncomingRingRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    }
-                    break;
-                case EVENT_RINGBACK_TONE:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_RINGBACK_TONE)");
-                    mRingbackToneRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_IN_CALL_VOICE_PRIVACY_ON:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_IN_CALL_VOICE_PRIVACY_ON)");
-                    mInCallVoicePrivacyOnRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_IN_CALL_VOICE_PRIVACY_OFF:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_IN_CALL_VOICE_PRIVACY_OFF)");
-                    mInCallVoicePrivacyOffRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_CALL_WAITING:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_CALL_WAITING)");
-                    mCallWaitingRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_DISPLAY_INFO:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_DISPLAY_INFO)");
-                    mDisplayInfoRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_SIGNAL_INFO:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SIGNAL_INFO)");
-                    mSignalInfoRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_CDMA_OTA_STATUS_CHANGE:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_CDMA_OTA_STATUS_CHANGE)");
-                    mCdmaOtaStatusChangeRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_RESEND_INCALL_MUTE:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_RESEND_INCALL_MUTE)");
-                    mResendIncallMuteRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_MMI_INITIATE:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_MMI_INITIATE)");
-                    mMmiInitiateRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_MMI_COMPLETE:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_MMI_COMPLETE)");
-                    mMmiCompleteRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_ECM_TIMER_RESET:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_ECM_TIMER_RESET)");
-                    mEcmTimerResetRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_SUBSCRIPTION_INFO_READY:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SUBSCRIPTION_INFO_READY)");
-                    mSubscriptionInfoReadyRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_SUPP_SERVICE_FAILED:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SUPP_SERVICE_FAILED)");
-                    mSuppServiceFailedRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_SERVICE_STATE_CHANGED:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SERVICE_STATE_CHANGED)");
-                    mServiceStateChangedRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_POST_DIAL_CHARACTER:
-                    // we need send the character that is being processed in msg.arg1
-                    // so can't use notifyRegistrants()
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_POST_DIAL_CHARACTER)");
-                    for(int i=0; i < mPostDialCharacterRegistrants.size(); i++) {
-                        Message notifyMsg;
-                        notifyMsg = ((Registrant)mPostDialCharacterRegistrants.get(i)).messageForRegistrant();
-                        notifyMsg.obj = msg.obj;
-                        notifyMsg.arg1 = msg.arg1;
-                        notifyMsg.sendToTarget();
-                    }
-                    break;
-            }
-        }
-    };
-
-    @Override
-    public String toString() {
-        Call call;
-        StringBuilder b = new StringBuilder();
-
-        b.append("CallManager {");
-        b.append("\nstate = " + getState());
-        call = getActiveFgCall();
-        b.append("\n- Foreground: " + getActiveFgCallState());
-        b.append(" from " + call.getPhone());
-        b.append("\n  Conn: ").append(getFgCallConnections());
-        call = getFirstActiveBgCall();
-        b.append("\n- Background: " + call.getState());
-        b.append(" from " + call.getPhone());
-        b.append("\n  Conn: ").append(getBgCallConnections());
-        call = getFirstActiveRingingCall();
-        b.append("\n- Ringing: " +call.getState());
-        b.append(" from " + call.getPhone());
-
-        for (Phone phone : getAllPhones()) {
-            if (phone != null) {
-                b.append("\nPhone: " + phone + ", name = " + phone.getPhoneName()
-                        + ", state = " + phone.getState());
-                call = phone.getForegroundCall();
-                b.append("\n- Foreground: ").append(call);
-                call = phone.getBackgroundCall();
-                b.append(" Background: ").append(call);
-                call = phone.getRingingCall();
-                b.append(" Ringing: ").append(call);
-            }
-        }
-        b.append("\n}");
-        return b.toString();
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/CallStateException.java b/telephony/java/com/android/internal/telephony/CallStateException.java
deleted file mode 100644
index 6087124..0000000
--- a/telephony/java/com/android/internal/telephony/CallStateException.java
+++ /dev/null
@@ -1,34 +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.internal.telephony;
-
-/**
- * {@hide}
- */
-public class CallStateException extends Exception
-{
-    public
-    CallStateException()
-    {
-    }
-
-    public
-    CallStateException(String string)
-    {
-        super(string);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/CallTracker.java b/telephony/java/com/android/internal/telephony/CallTracker.java
deleted file mode 100644
index 62caf01..0000000
--- a/telephony/java/com/android/internal/telephony/CallTracker.java
+++ /dev/null
@@ -1,182 +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.internal.telephony;
-
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.telephony.CommandException;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-
-/**
- * {@hide}
- */
-public abstract class CallTracker extends Handler {
-
-    private static final boolean DBG_POLL = false;
-
-    //***** Constants
-
-    static final int POLL_DELAY_MSEC = 250;
-
-    protected int pendingOperations;
-    protected boolean needsPoll;
-    protected Message lastRelevantPoll;
-
-    public CommandsInterface cm;
-
-
-    //***** Events
-
-    protected static final int EVENT_POLL_CALLS_RESULT             = 1;
-    protected static final int EVENT_CALL_STATE_CHANGE             = 2;
-    protected static final int EVENT_REPOLL_AFTER_DELAY            = 3;
-    protected static final int EVENT_OPERATION_COMPLETE            = 4;
-    protected static final int EVENT_GET_LAST_CALL_FAIL_CAUSE      = 5;
-
-    protected static final int EVENT_SWITCH_RESULT                 = 8;
-    protected static final int EVENT_RADIO_AVAILABLE               = 9;
-    protected static final int EVENT_RADIO_NOT_AVAILABLE           = 10;
-    protected static final int EVENT_CONFERENCE_RESULT             = 11;
-    protected static final int EVENT_SEPARATE_RESULT               = 12;
-    protected static final int EVENT_ECT_RESULT                    = 13;
-    protected static final int EVENT_EXIT_ECM_RESPONSE_CDMA        = 14;
-    protected static final int EVENT_CALL_WAITING_INFO_CDMA        = 15;
-    protected static final int EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA = 16;
-
-    protected void pollCallsWhenSafe() {
-        needsPoll = true;
-
-        if (checkNoOperationsPending()) {
-            lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
-            cm.getCurrentCalls(lastRelevantPoll);
-        }
-    }
-
-    protected void
-    pollCallsAfterDelay() {
-        Message msg = obtainMessage();
-
-        msg.what = EVENT_REPOLL_AFTER_DELAY;
-        sendMessageDelayed(msg, POLL_DELAY_MSEC);
-    }
-
-    protected boolean
-    isCommandExceptionRadioNotAvailable(Throwable e) {
-        return e != null && e instanceof CommandException
-                && ((CommandException)e).getCommandError()
-                        == CommandException.Error.RADIO_NOT_AVAILABLE;
-    }
-
-    protected abstract void handlePollCalls(AsyncResult ar);
-
-    protected void handleRadioAvailable() {
-        pollCallsWhenSafe();
-    }
-
-    /**
-     * Obtain a complete message that indicates that this operation
-     * does not require polling of getCurrentCalls(). However, if other
-     * operations that do need getCurrentCalls() are pending or are
-     * scheduled while this operation is pending, the invocation
-     * of getCurrentCalls() will be postponed until this
-     * operation is also complete.
-     */
-    protected Message
-    obtainNoPollCompleteMessage(int what) {
-        pendingOperations++;
-        lastRelevantPoll = null;
-        return obtainMessage(what);
-    }
-
-    /**
-     * @return true if we're idle or there's a call to getCurrentCalls() pending
-     * but nothing else
-     */
-    private boolean
-    checkNoOperationsPending() {
-        if (DBG_POLL) log("checkNoOperationsPending: pendingOperations=" +
-                pendingOperations);
-        return pendingOperations == 0;
-    }
-
-    /**
-     * Routine called from dial to check if the number is a test Emergency number
-     * and if so remap the number. This allows a short emergency number to be remapped
-     * to a regular number for testing how the frameworks handles emergency numbers
-     * without actually calling an emergency number.
-     *
-     * This is not a full test and is not a substitute for testing real emergency
-     * numbers but can be useful.
-     *
-     * To use this feature set a system property ril.test.emergencynumber to a pair of
-     * numbers separated by a colon. If the first number matches the number parameter
-     * this routine returns the second number. Example:
-     *
-     * ril.test.emergencynumber=112:1-123-123-45678
-     *
-     * To test Dial 112 take call then hang up on MO device to enter ECM
-     * see RIL#processSolicited RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND
-     *
-     * @param number to test if it should be remapped
-     * @return the same number or the remapped number.
-     */
-    protected String checkForTestEmergencyNumber(String dialString) {
-        String testEn = SystemProperties.get("ril.test.emergencynumber");
-        if (DBG_POLL) {
-            log("checkForTestEmergencyNumber: dialString=" + dialString +
-                " testEn=" + testEn);
-        }
-        if (!TextUtils.isEmpty(testEn)) {
-            String values[] = testEn.split(":");
-            log("checkForTestEmergencyNumber: values.length=" + values.length);
-            if (values.length == 2) {
-                if (values[0].equals(
-                        android.telephony.PhoneNumberUtils.stripSeparators(dialString))) {
-                    cm.testingEmergencyCall();
-                    log("checkForTestEmergencyNumber: remap " +
-                            dialString + " to " + values[1]);
-                    dialString = values[1];
-                }
-            }
-        }
-        return dialString;
-    }
-
-    //***** Overridden from Handler
-    public abstract void handleMessage (Message msg);
-    public abstract void registerForVoiceCallStarted(Handler h, int what, Object obj);
-    public abstract void unregisterForVoiceCallStarted(Handler h);
-    public abstract void registerForVoiceCallEnded(Handler h, int what, Object obj);
-    public abstract void unregisterForVoiceCallEnded(Handler h);
-
-    protected abstract void log(String msg);
-
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("CallTracker:");
-        pw.println(" pendingOperations=" + pendingOperations);
-        pw.println(" needsPoll=" + needsPoll);
-        pw.println(" lastRelevantPoll=" + lastRelevantPoll);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/CommandException.java b/telephony/java/com/android/internal/telephony/CommandException.java
deleted file mode 100644
index 94c544e..0000000
--- a/telephony/java/com/android/internal/telephony/CommandException.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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.internal.telephony;
-
-import com.android.internal.telephony.RILConstants;
-
-import android.util.Log;
-
-/**
- * {@hide}
- */
-public class CommandException extends RuntimeException {
-    private Error e;
-
-    public enum Error {
-        INVALID_RESPONSE,
-        RADIO_NOT_AVAILABLE,
-        GENERIC_FAILURE,
-        PASSWORD_INCORRECT,
-        SIM_PIN2,
-        SIM_PUK2,
-        REQUEST_NOT_SUPPORTED,
-        OP_NOT_ALLOWED_DURING_VOICE_CALL,
-        OP_NOT_ALLOWED_BEFORE_REG_NW,
-        SMS_FAIL_RETRY,
-        SIM_ABSENT,
-        SUBSCRIPTION_NOT_AVAILABLE,
-        MODE_NOT_SUPPORTED,
-        FDN_CHECK_FAILURE,
-        ILLEGAL_SIM_OR_ME,
-    }
-
-    public CommandException(Error e) {
-        super(e.toString());
-        this.e = e;
-    }
-
-    public static CommandException
-    fromRilErrno(int ril_errno) {
-        switch(ril_errno) {
-            case RILConstants.SUCCESS:                       return null;
-            case RILConstants.RIL_ERRNO_INVALID_RESPONSE:
-                return new CommandException(Error.INVALID_RESPONSE);
-            case RILConstants.RADIO_NOT_AVAILABLE:
-                return new CommandException(Error.RADIO_NOT_AVAILABLE);
-            case RILConstants.GENERIC_FAILURE:
-                return new CommandException(Error.GENERIC_FAILURE);
-            case RILConstants.PASSWORD_INCORRECT:
-                return new CommandException(Error.PASSWORD_INCORRECT);
-            case RILConstants.SIM_PIN2:
-                return new CommandException(Error.SIM_PIN2);
-            case RILConstants.SIM_PUK2:
-                return new CommandException(Error.SIM_PUK2);
-            case RILConstants.REQUEST_NOT_SUPPORTED:
-                return new CommandException(Error.REQUEST_NOT_SUPPORTED);
-            case RILConstants.OP_NOT_ALLOWED_DURING_VOICE_CALL:
-                return new CommandException(Error.OP_NOT_ALLOWED_DURING_VOICE_CALL);
-            case RILConstants.OP_NOT_ALLOWED_BEFORE_REG_NW:
-                return new CommandException(Error.OP_NOT_ALLOWED_BEFORE_REG_NW);
-            case RILConstants.SMS_SEND_FAIL_RETRY:
-                return new CommandException(Error.SMS_FAIL_RETRY);
-            case RILConstants.SIM_ABSENT:
-                return new CommandException(Error.SIM_ABSENT);
-            case RILConstants.SUBSCRIPTION_NOT_AVAILABLE:
-                return new CommandException(Error.SUBSCRIPTION_NOT_AVAILABLE);
-            case RILConstants.MODE_NOT_SUPPORTED:
-                return new CommandException(Error.MODE_NOT_SUPPORTED);
-            case RILConstants.FDN_CHECK_FAILURE:
-                return new CommandException(Error.FDN_CHECK_FAILURE);
-            case RILConstants.ILLEGAL_SIM_OR_ME:
-                return new CommandException(Error.ILLEGAL_SIM_OR_ME);
-            default:
-                Log.e("GSM", "Unrecognized RIL errno " + ril_errno);
-                return new CommandException(Error.INVALID_RESPONSE);
-        }
-    }
-
-    public Error getCommandError() {
-        return e;
-    }
-
-
-
-}
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
deleted file mode 100644
index f7757b3..0000000
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ /dev/null
@@ -1,1579 +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.internal.telephony;
-
-import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
-
-import android.os.Message;
-import android.os.Handler;
-import android.util.Log;
-
-/**
- * {@hide}
- */
-public interface CommandsInterface {
-    enum RadioState {
-        RADIO_OFF,         /* Radio explicitly powered off (eg CFUN=0) */
-        RADIO_UNAVAILABLE, /* Radio unavailable (eg, resetting or not booted) */
-        RADIO_ON;          /* Radio is on */
-
-        public boolean isOn() /* and available...*/ {
-            return this == RADIO_ON;
-        }
-
-        public boolean isAvailable() {
-            return this != RADIO_UNAVAILABLE;
-        }
-    }
-
-    //***** Constants
-
-    // Used as parameter to dial() and setCLIR() below
-    static final int CLIR_DEFAULT = 0;      // "use subscription default value"
-    static final int CLIR_INVOCATION = 1;   // (restrict CLI presentation)
-    static final int CLIR_SUPPRESSION = 2;  // (allow CLI presentation)
-
-
-    // Used as parameters for call forward methods below
-    static final int CF_ACTION_DISABLE          = 0;
-    static final int CF_ACTION_ENABLE           = 1;
-//  static final int CF_ACTION_UNUSED           = 2;
-    static final int CF_ACTION_REGISTRATION     = 3;
-    static final int CF_ACTION_ERASURE          = 4;
-
-    static final int CF_REASON_UNCONDITIONAL    = 0;
-    static final int CF_REASON_BUSY             = 1;
-    static final int CF_REASON_NO_REPLY         = 2;
-    static final int CF_REASON_NOT_REACHABLE    = 3;
-    static final int CF_REASON_ALL              = 4;
-    static final int CF_REASON_ALL_CONDITIONAL  = 5;
-
-    // Used for call barring methods below
-    static final String CB_FACILITY_BAOC         = "AO";
-    static final String CB_FACILITY_BAOIC        = "OI";
-    static final String CB_FACILITY_BAOICxH      = "OX";
-    static final String CB_FACILITY_BAIC         = "AI";
-    static final String CB_FACILITY_BAICr        = "IR";
-    static final String CB_FACILITY_BA_ALL       = "AB";
-    static final String CB_FACILITY_BA_MO        = "AG";
-    static final String CB_FACILITY_BA_MT        = "AC";
-    static final String CB_FACILITY_BA_SIM       = "SC";
-    static final String CB_FACILITY_BA_FD        = "FD";
-
-
-    // Used for various supp services apis
-    // See 27.007 +CCFC or +CLCK
-    static final int SERVICE_CLASS_NONE     = 0; // no user input
-    static final int SERVICE_CLASS_VOICE    = (1 << 0);
-    static final int SERVICE_CLASS_DATA     = (1 << 1); //synonym for 16+32+64+128
-    static final int SERVICE_CLASS_FAX      = (1 << 2);
-    static final int SERVICE_CLASS_SMS      = (1 << 3);
-    static final int SERVICE_CLASS_DATA_SYNC = (1 << 4);
-    static final int SERVICE_CLASS_DATA_ASYNC = (1 << 5);
-    static final int SERVICE_CLASS_PACKET   = (1 << 6);
-    static final int SERVICE_CLASS_PAD      = (1 << 7);
-    static final int SERVICE_CLASS_MAX      = (1 << 7); // Max SERVICE_CLASS value
-
-    // Numeric representation of string values returned
-    // by messages sent to setOnUSSD handler
-    static final int USSD_MODE_NOTIFY       = 0;
-    static final int USSD_MODE_REQUEST      = 1;
-
-    // GSM SMS fail cause for acknowledgeLastIncomingSMS. From TS 23.040, 9.2.3.22.
-    static final int GSM_SMS_FAIL_CAUSE_MEMORY_CAPACITY_EXCEEDED    = 0xD3;
-    static final int GSM_SMS_FAIL_CAUSE_USIM_APP_TOOLKIT_BUSY       = 0xD4;
-    static final int GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR    = 0xD5;
-    static final int GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR           = 0xFF;
-
-    // CDMA SMS fail cause for acknowledgeLastIncomingCdmaSms.  From TS N.S0005, 6.5.2.125.
-    static final int CDMA_SMS_FAIL_CAUSE_INVALID_TELESERVICE_ID     = 4;
-    static final int CDMA_SMS_FAIL_CAUSE_RESOURCE_SHORTAGE          = 35;
-    static final int CDMA_SMS_FAIL_CAUSE_OTHER_TERMINAL_PROBLEM     = 39;
-    static final int CDMA_SMS_FAIL_CAUSE_ENCODING_PROBLEM           = 96;
-
-    //***** Methods
-    RadioState getRadioState();
-
-    void getVoiceRadioTechnology(Message result);
-
-    /**
-     * Fires on any RadioState transition
-     * Always fires immediately as well
-     *
-     * do not attempt to calculate transitions by storing getRadioState() values
-     * on previous invocations of this notification. Instead, use the other
-     * registration methods
-     */
-    void registerForRadioStateChanged(Handler h, int what, Object obj);
-    void unregisterForRadioStateChanged(Handler h);
-
-    void registerForVoiceRadioTechChanged(Handler h, int what, Object obj);
-    void unregisterForVoiceRadioTechChanged(Handler h);
-
-    /**
-     * Fires on any transition into RadioState.isOn()
-     * Fires immediately if currently in that state
-     * In general, actions should be idempotent. State may change
-     * before event is received.
-     */
-    void registerForOn(Handler h, int what, Object obj);
-    void unregisterForOn(Handler h);
-
-    /**
-     * Fires on any transition out of RadioState.isAvailable()
-     * Fires immediately if currently in that state
-     * In general, actions should be idempotent. State may change
-     * before event is received.
-     */
-    void registerForAvailable(Handler h, int what, Object obj);
-    void unregisterForAvailable(Handler h);
-
-    /**
-     * Fires on any transition into !RadioState.isAvailable()
-     * Fires immediately if currently in that state
-     * In general, actions should be idempotent. State may change
-     * before event is received.
-     */
-    void registerForNotAvailable(Handler h, int what, Object obj);
-    void unregisterForNotAvailable(Handler h);
-
-    /**
-     * Fires on any transition into RADIO_OFF or !RadioState.isAvailable()
-     * Fires immediately if currently in that state
-     * In general, actions should be idempotent. State may change
-     * before event is received.
-     */
-    void registerForOffOrNotAvailable(Handler h, int what, Object obj);
-    void unregisterForOffOrNotAvailable(Handler h);
-
-    /**
-     * Fires on any change in ICC status
-     */
-    void registerForIccStatusChanged(Handler h, int what, Object obj);
-    void unregisterForIccStatusChanged(Handler h);
-
-    void registerForCallStateChanged(Handler h, int what, Object obj);
-    void unregisterForCallStateChanged(Handler h);
-    void registerForVoiceNetworkStateChanged(Handler h, int what, Object obj);
-    void unregisterForVoiceNetworkStateChanged(Handler h);
-    void registerForDataNetworkStateChanged(Handler h, int what, Object obj);
-    void unregisterForDataNetworkStateChanged(Handler h);
-
-    /** InCall voice privacy notifications */
-    void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj);
-    void unregisterForInCallVoicePrivacyOn(Handler h);
-    void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj);
-    void unregisterForInCallVoicePrivacyOff(Handler h);
-
-    /**
-     * unlike the register* methods, there's only one new 3GPP format SMS handler.
-     * if you need to unregister, you should also tell the radio to stop
-     * sending SMS's to you (via AT+CNMI)
-     *
-     * AsyncResult.result is a String containing the SMS PDU
-     */
-    void setOnNewGsmSms(Handler h, int what, Object obj);
-    void unSetOnNewGsmSms(Handler h);
-
-    /**
-     * unlike the register* methods, there's only one new 3GPP2 format SMS handler.
-     * if you need to unregister, you should also tell the radio to stop
-     * sending SMS's to you (via AT+CNMI)
-     *
-     * AsyncResult.result is a String containing the SMS PDU
-     */
-    void setOnNewCdmaSms(Handler h, int what, Object obj);
-    void unSetOnNewCdmaSms(Handler h);
-
-    /**
-     * Set the handler for SMS Cell Broadcast messages.
-     *
-     * AsyncResult.result is a byte array containing the SMS-CB PDU
-     */
-    void setOnNewGsmBroadcastSms(Handler h, int what, Object obj);
-    void unSetOnNewGsmBroadcastSms(Handler h);
-
-    /**
-     * Register for NEW_SMS_ON_SIM unsolicited message
-     *
-     * AsyncResult.result is an int array containing the index of new SMS
-     */
-    void setOnSmsOnSim(Handler h, int what, Object obj);
-    void unSetOnSmsOnSim(Handler h);
-
-    /**
-     * Register for NEW_SMS_STATUS_REPORT unsolicited message
-     *
-     * AsyncResult.result is a String containing the status report PDU
-     */
-    void setOnSmsStatus(Handler h, int what, Object obj);
-    void unSetOnSmsStatus(Handler h);
-
-    /**
-     * unlike the register* methods, there's only one NITZ time handler
-     *
-     * AsyncResult.result is an Object[]
-     * ((Object[])AsyncResult.result)[0] is a String containing the NITZ time string
-     * ((Object[])AsyncResult.result)[1] is a Long containing the milliseconds since boot as
-     *                                   returned by elapsedRealtime() when this NITZ time
-     *                                   was posted.
-     *
-     * Please note that the delivery of this message may be delayed several
-     * seconds on system startup
-     */
-    void setOnNITZTime(Handler h, int what, Object obj);
-    void unSetOnNITZTime(Handler h);
-
-    /**
-     * unlike the register* methods, there's only one USSD notify handler
-     *
-     * Represents the arrival of a USSD "notify" message, which may
-     * or may not have been triggered by a previous USSD send
-     *
-     * AsyncResult.result is a String[]
-     * ((String[])(AsyncResult.result))[0] contains status code
-     *      "0"   USSD-Notify -- text in ((const char **)data)[1]
-     *      "1"   USSD-Request -- text in ((const char **)data)[1]
-     *      "2"   Session terminated by network
-     *      "3"   other local client (eg, SIM Toolkit) has responded
-     *      "4"   Operation not supported
-     *      "5"   Network timeout
-     *
-     * ((String[])(AsyncResult.result))[1] contains the USSD message
-     * The numeric representations of these are in USSD_MODE_*
-     */
-
-    void setOnUSSD(Handler h, int what, Object obj);
-    void unSetOnUSSD(Handler h);
-
-    /**
-     * unlike the register* methods, there's only one signal strength handler
-     * AsyncResult.result is an int[2]
-     * response.obj.result[0] is received signal strength (0-31, 99)
-     * response.obj.result[1] is  bit error rate (0-7, 99)
-     * as defined in TS 27.007 8.5
-     */
-
-    void setOnSignalStrengthUpdate(Handler h, int what, Object obj);
-    void unSetOnSignalStrengthUpdate(Handler h);
-
-    /**
-     * Sets the handler for SIM/RUIM SMS storage full unsolicited message.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void setOnIccSmsFull(Handler h, int what, Object obj);
-    void unSetOnIccSmsFull(Handler h);
-
-    /**
-     * Sets the handler for SIM Refresh notifications.
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForIccRefresh(Handler h, int what, Object obj);
-    void unregisterForIccRefresh(Handler h);
-
-    void setOnIccRefresh(Handler h, int what, Object obj);
-    void unsetOnIccRefresh(Handler h);
-
-    /**
-     * Sets the handler for RING notifications.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void setOnCallRing(Handler h, int what, Object obj);
-    void unSetOnCallRing(Handler h);
-
-    /**
-     * Sets the handler for RESTRICTED_STATE changed notification,
-     * eg, for Domain Specific Access Control
-     * unlike the register* methods, there's only one signal strength handler
-     *
-     * AsyncResult.result is an int[1]
-     * response.obj.result[0] is a bitmask of RIL_RESTRICTED_STATE_* values
-     */
-
-    void setOnRestrictedStateChanged(Handler h, int what, Object obj);
-    void unSetOnRestrictedStateChanged(Handler h);
-
-    /**
-     * Sets the handler for Supplementary Service Notifications.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void setOnSuppServiceNotification(Handler h, int what, Object obj);
-    void unSetOnSuppServiceNotification(Handler h);
-
-    /**
-     * Sets the handler for Session End Notifications for CAT.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void setOnCatSessionEnd(Handler h, int what, Object obj);
-    void unSetOnCatSessionEnd(Handler h);
-
-    /**
-     * Sets the handler for Proactive Commands for CAT.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void setOnCatProactiveCmd(Handler h, int what, Object obj);
-    void unSetOnCatProactiveCmd(Handler h);
-
-    /**
-     * Sets the handler for Event Notifications for CAT.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void setOnCatEvent(Handler h, int what, Object obj);
-    void unSetOnCatEvent(Handler h);
-
-    /**
-     * Sets the handler for Call Set Up Notifications for CAT.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void setOnCatCallSetUp(Handler h, int what, Object obj);
-    void unSetOnCatCallSetUp(Handler h);
-
-    /**
-     * Enables/disbables supplementary service related notifications from
-     * the network.
-     *
-     * @param enable true to enable notifications, false to disable.
-     * @param result Message to be posted when command completes.
-     */
-    void setSuppServiceNotifications(boolean enable, Message result);
-    //void unSetSuppServiceNotifications(Handler h);
-
-    /**
-     * Sets the handler for Event Notifications for CDMA Display Info.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForDisplayInfo(Handler h, int what, Object obj);
-    void unregisterForDisplayInfo(Handler h);
-
-    /**
-     * Sets the handler for Event Notifications for CallWaiting Info.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForCallWaitingInfo(Handler h, int what, Object obj);
-    void unregisterForCallWaitingInfo(Handler h);
-
-    /**
-     * Sets the handler for Event Notifications for Signal Info.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForSignalInfo(Handler h, int what, Object obj);
-    void unregisterForSignalInfo(Handler h);
-
-    /**
-     * Registers the handler for CDMA number information record
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForNumberInfo(Handler h, int what, Object obj);
-    void unregisterForNumberInfo(Handler h);
-
-    /**
-     * Registers the handler for CDMA redirected number Information record
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForRedirectedNumberInfo(Handler h, int what, Object obj);
-    void unregisterForRedirectedNumberInfo(Handler h);
-
-    /**
-     * Registers the handler for CDMA line control information record
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForLineControlInfo(Handler h, int what, Object obj);
-    void unregisterForLineControlInfo(Handler h);
-
-    /**
-     * Registers the handler for CDMA T53 CLIR information record
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerFoT53ClirlInfo(Handler h, int what, Object obj);
-    void unregisterForT53ClirInfo(Handler h);
-
-    /**
-     * Registers the handler for CDMA T53 audio control information record
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForT53AudioControlInfo(Handler h, int what, Object obj);
-    void unregisterForT53AudioControlInfo(Handler h);
-
-    /**
-     * Fires on if Modem enters Emergency Callback mode
-     */
-    void setEmergencyCallbackMode(Handler h, int what, Object obj);
-
-     /**
-      * Fires on any CDMA OTA provision status change
-      */
-     void registerForCdmaOtaProvision(Handler h,int what, Object obj);
-     void unregisterForCdmaOtaProvision(Handler h);
-
-     /**
-      * Registers the handler when out-band ringback tone is needed.<p>
-      *
-      *  Messages received from this:
-      *  Message.obj will be an AsyncResult
-      *  AsyncResult.userObj = obj
-      *  AsyncResult.result = boolean. <p>
-      */
-     void registerForRingbackTone(Handler h, int what, Object obj);
-     void unregisterForRingbackTone(Handler h);
-
-     /**
-      * Registers the handler when mute/unmute need to be resent to get
-      * uplink audio during a call.<p>
-      *
-      * @param h Handler for notification message.
-      * @param what User-defined message code.
-      * @param obj User object.
-      *
-      */
-     void registerForResendIncallMute(Handler h, int what, Object obj);
-     void unregisterForResendIncallMute(Handler h);
-
-     /**
-      * Registers the handler for when Cdma subscription changed events
-      *
-      * @param h Handler for notification message.
-      * @param what User-defined message code.
-      * @param obj User object.
-      *
-      */
-     void registerForCdmaSubscriptionChanged(Handler h, int what, Object obj);
-     void unregisterForCdmaSubscriptionChanged(Handler h);
-
-     /**
-      * Registers the handler for when Cdma prl changed events
-      *
-      * @param h Handler for notification message.
-      * @param what User-defined message code.
-      * @param obj User object.
-      *
-      */
-     void registerForCdmaPrlChanged(Handler h, int what, Object obj);
-     void unregisterForCdmaPrlChanged(Handler h);
-
-     /**
-      * Registers the handler for when Cdma prl changed events
-      *
-      * @param h Handler for notification message.
-      * @param what User-defined message code.
-      * @param obj User object.
-      *
-      */
-     void registerForExitEmergencyCallbackMode(Handler h, int what, Object obj);
-     void unregisterForExitEmergencyCallbackMode(Handler h);
-
-     /**
-      * Registers the handler for RIL_UNSOL_RIL_CONNECT events.
-      *
-      * When ril connects or disconnects a message is sent to the registrant
-      * which contains an AsyncResult, ar, in msg.obj. The ar.result is an
-      * Integer which is the version of the ril or -1 if the ril disconnected.
-      *
-      * @param h Handler for notification message.
-      * @param what User-defined message code.
-      * @param obj User object.
-      */
-     void registerForRilConnected(Handler h, int what, Object obj);
-     void unregisterForRilConnected(Handler h);
-
-    /**
-     * Supply the ICC PIN to the ICC card
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPin(String pin, Message result);
-
-    /**
-     * Supply the PIN for the app with this AID on the ICC card
-     *
-     *  AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPinForApp(String pin, String aid, Message result);
-
-    /**
-     * Supply the ICC PUK and newPin to the ICC card
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPuk(String puk, String newPin, Message result);
-
-    /**
-     * Supply the PUK, new pin for the app with this AID on the ICC card
-     *
-     *  AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPukForApp(String puk, String newPin, String aid, Message result);
-
-    /**
-     * Supply the ICC PIN2 to the ICC card
-     * Only called following operation where ICC_PIN2 was
-     * returned as a a failure from a previous operation
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPin2(String pin2, Message result);
-
-    /**
-     * Supply the PIN2 for the app with this AID on the ICC card
-     * Only called following operation where ICC_PIN2 was
-     * returned as a a failure from a previous operation
-     *
-     *  AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPin2ForApp(String pin2, String aid, Message result);
-
-    /**
-     * Supply the SIM PUK2 to the SIM card
-     * Only called following operation where SIM_PUK2 was
-     * returned as a a failure from a previous operation
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPuk2(String puk2, String newPin2, Message result);
-
-    /**
-     * Supply the PUK2, newPin2 for the app with this AID on the ICC card
-     * Only called following operation where SIM_PUK2 was
-     * returned as a a failure from a previous operation
-     *
-     *  AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message result);
-
-    void changeIccPin(String oldPin, String newPin, Message result);
-    void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message result);
-    void changeIccPin2(String oldPin2, String newPin2, Message result);
-    void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr, Message result);
-
-    void changeBarringPassword(String facility, String oldPwd, String newPwd, Message result);
-
-    void supplyNetworkDepersonalization(String netpin, Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result contains a List of DriverCall
-     *      The ar.result List is sorted by DriverCall.index
-     */
-    void getCurrentCalls (Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result contains a List of DataCallState
-     *  @deprecated Do not use.
-     */
-    @Deprecated
-    void getPDPContextList(Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result contains a List of DataCallState
-     */
-    void getDataCallList(Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     *
-     * CLIR_DEFAULT     == on "use subscription default value"
-     * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation)
-     * CLIR_INVOCATION  == on "CLIR invocation" (restrict CLI presentation)
-     */
-    void dial (String address, int clirMode, Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     *
-     * CLIR_DEFAULT     == on "use subscription default value"
-     * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation)
-     * CLIR_INVOCATION  == on "CLIR invocation" (restrict CLI presentation)
-     */
-    void dial(String address, int clirMode, UUSInfo uusInfo, Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is String containing IMSI on success
-     */
-    void getIMSI(Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is String containing IMSI on success
-     */
-    void getIMSIForApp(String aid, Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is String containing IMEI on success
-     */
-    void getIMEI(Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is String containing IMEISV on success
-     */
-    void getIMEISV(Message result);
-
-    /**
-     * Hang up one individual connection.
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     *
-     *  3GPP 22.030 6.5.5
-     *  "Releases a specific active call X"
-     */
-    void hangupConnection (int gsmIndex, Message result);
-
-    /**
-     * 3GPP 22.030 6.5.5
-     *  "Releases all held calls or sets User Determined User Busy (UDUB)
-     *   for a waiting call."
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void hangupWaitingOrBackground (Message result);
-
-    /**
-     * 3GPP 22.030 6.5.5
-     * "Releases all active calls (if any exist) and accepts
-     *  the other (held or waiting) call."
-     *
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void hangupForegroundResumeBackground (Message result);
-
-    /**
-     * 3GPP 22.030 6.5.5
-     * "Places all active calls (if any exist) on hold and accepts
-     *  the other (held or waiting) call."
-     *
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void switchWaitingOrHoldingAndActive (Message result);
-
-    /**
-     * 3GPP 22.030 6.5.5
-     * "Adds a held call to the conversation"
-     *
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void conference (Message result);
-
-    /**
-     * Set preferred Voice Privacy (VP).
-     *
-     * @param enable true is enhanced and false is normal VP
-     * @param result is a callback message
-     */
-    void setPreferredVoicePrivacy(boolean enable, Message result);
-
-    /**
-     * Get currently set preferred Voice Privacy (VP) mode.
-     *
-     * @param result is a callback message
-     */
-    void getPreferredVoicePrivacy(Message result);
-
-    /**
-     * 3GPP 22.030 6.5.5
-     * "Places all active calls on hold except call X with which
-     *  communication shall be supported."
-     */
-    void separateConnection (int gsmIndex, Message result);
-
-    /**
-     *
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void acceptCall (Message result);
-
-    /**
-     *  also known as UDUB
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void rejectCall (Message result);
-
-    /**
-     * 3GPP 22.030 6.5.5
-     * "Connects the two calls and disconnects the subscriber from both calls"
-     *
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void explicitCallTransfer (Message result);
-
-    /**
-     * cause code returned as int[0] in Message.obj.response
-     * Returns integer cause code defined in TS 24.008
-     * Annex H or closest approximation.
-     * Most significant codes:
-     * - Any defined in 22.001 F.4 (for generating busy/congestion)
-     * - Cause 68: ACM >= ACMMax
-     */
-    void getLastCallFailCause (Message result);
-
-
-    /**
-     * Reason for last PDP context deactivate or failure to activate
-     * cause code returned as int[0] in Message.obj.response
-     * returns an integer cause code defined in TS 24.008
-     * section 6.1.3.1.3 or close approximation
-     * @deprecated Do not use.
-     */
-    @Deprecated
-    void getLastPdpFailCause (Message result);
-
-    /**
-     * The preferred new alternative to getLastPdpFailCause
-     * that is also CDMA-compatible.
-     */
-    void getLastDataCallFailCause (Message result);
-
-    void setMute (boolean enableMute, Message response);
-
-    void getMute (Message response);
-
-    /**
-     * response.obj is an AsyncResult
-     * response.obj.result is an int[2]
-     * response.obj.result[0] is received signal strength (0-31, 99)
-     * response.obj.result[1] is  bit error rate (0-7, 99)
-     * as defined in TS 27.007 8.5
-     */
-    void getSignalStrength (Message response);
-
-
-    /**
-     * response.obj.result is an int[3]
-     * response.obj.result[0] is registration state 0-5 from TS 27.007 7.2
-     * response.obj.result[1] is LAC if registered or -1 if not
-     * response.obj.result[2] is CID if registered or -1 if not
-     * valid LAC and CIDs are 0x0000 - 0xffff
-     *
-     * Please note that registration state 4 ("unknown") is treated
-     * as "out of service" above
-     */
-    void getVoiceRegistrationState (Message response);
-
-    /**
-     * response.obj.result is an int[3]
-     * response.obj.result[0] is registration state 0-5 from TS 27.007 7.2
-     * response.obj.result[1] is LAC if registered or -1 if not
-     * response.obj.result[2] is CID if registered or -1 if not
-     * valid LAC and CIDs are 0x0000 - 0xffff
-     *
-     * Please note that registration state 4 ("unknown") is treated
-     * as "out of service" above
-     */
-    void getDataRegistrationState (Message response);
-
-    /**
-     * response.obj.result is a String[3]
-     * response.obj.result[0] is long alpha or null if unregistered
-     * response.obj.result[1] is short alpha or null if unregistered
-     * response.obj.result[2] is numeric or null if unregistered
-     */
-    void getOperator(Message response);
-
-    /**
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void sendDtmf(char c, Message result);
-
-
-    /**
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void startDtmf(char c, Message result);
-
-    /**
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void stopDtmf(Message result);
-
-    /**
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void sendBurstDtmf(String dtmfString, int on, int off, Message result);
-
-    /**
-     * smscPDU is smsc address in PDU form GSM BCD format prefixed
-     *      by a length byte (as expected by TS 27.005) or NULL for default SMSC
-     * pdu is SMS in PDU format as an ASCII hex string
-     *      less the SMSC address
-     */
-    void sendSMS (String smscPDU, String pdu, Message response);
-
-    /**
-     * @param pdu is CDMA-SMS in internal pseudo-PDU format
-     * @param response sent when operation completes
-     */
-    void sendCdmaSms(byte[] pdu, Message response);
-
-    /**
-     * Deletes the specified SMS record from SIM memory (EF_SMS).
-     *
-     * @param index index of the SMS record to delete
-     * @param response sent when operation completes
-     */
-    void deleteSmsOnSim(int index, Message response);
-
-    /**
-     * Deletes the specified SMS record from RUIM memory (EF_SMS in DF_CDMA).
-     *
-     * @param index index of the SMS record to delete
-     * @param response sent when operation completes
-     */
-    void deleteSmsOnRuim(int index, Message response);
-
-    /**
-     * Writes an SMS message to SIM memory (EF_SMS).
-     *
-     * @param status status of message on SIM.  One of:
-     *                  SmsManger.STATUS_ON_ICC_READ
-     *                  SmsManger.STATUS_ON_ICC_UNREAD
-     *                  SmsManger.STATUS_ON_ICC_SENT
-     *                  SmsManger.STATUS_ON_ICC_UNSENT
-     * @param pdu message PDU, as hex string
-     * @param response sent when operation completes.
-     *                  response.obj will be an AsyncResult, and will indicate
-     *                  any error that may have occurred (eg, out of memory).
-     */
-    void writeSmsToSim(int status, String smsc, String pdu, Message response);
-
-    void writeSmsToRuim(int status, String pdu, Message response);
-
-    void setRadioPower(boolean on, Message response);
-
-    void acknowledgeLastIncomingGsmSms(boolean success, int cause, Message response);
-
-    void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message response);
-
-    /**
-     * Acknowledge successful or failed receipt of last incoming SMS,
-     * including acknowledgement TPDU to send as the RP-User-Data element
-     * of the RP-ACK or RP-ERROR PDU.
-     *
-     * @param success true to send RP-ACK, false to send RP-ERROR
-     * @param ackPdu the acknowledgement TPDU in hexadecimal format
-     * @param response sent when operation completes.
-     */
-    void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu, Message response);
-
-    /**
-     * parameters equivalent to 27.007 AT+CRSM command
-     * response.obj will be an AsyncResult
-     * response.obj.result will be an IccIoResult on success
-     */
-    void iccIO (int command, int fileid, String path, int p1, int p2, int p3,
-            String data, String pin2, Message response);
-
-    /**
-     * parameters equivalent to 27.007 AT+CRSM command
-     * response.obj will be an AsyncResult
-     * response.obj.userObj will be a IccIoResult on success
-     */
-    void iccIOForApp (int command, int fileid, String path, int p1, int p2, int p3,
-            String data, String pin2, String aid, Message response);
-
-    /**
-     * (AsyncResult)response.obj).result is an int[] with element [0] set to
-     * 1 for "CLIP is provisioned", and 0 for "CLIP is not provisioned".
-     *
-     * @param response is callback message
-     */
-
-    void queryCLIP(Message response);
-
-    /**
-     * response.obj will be a an int[2]
-     *
-     * response.obj[0] will be TS 27.007 +CLIR parameter 'n'
-     *  0 presentation indicator is used according to the subscription of the CLIR service
-     *  1 CLIR invocation
-     *  2 CLIR suppression
-     *
-     * response.obj[1] will be TS 27.007 +CLIR parameter 'm'
-     *  0 CLIR not provisioned
-     *  1 CLIR provisioned in permanent mode
-     *  2 unknown (e.g. no network, etc.)
-     *  3 CLIR temporary mode presentation restricted
-     *  4 CLIR temporary mode presentation allowed
-     */
-
-    void getCLIR(Message response);
-
-    /**
-     * clirMode is one of the CLIR_* constants above
-     *
-     * response.obj is null
-     */
-
-    void setCLIR(int clirMode, Message response);
-
-    /**
-     * (AsyncResult)response.obj).result is an int[] with element [0] set to
-     * 0 for disabled, 1 for enabled.
-     *
-     * @param serviceClass is a sum of SERVICE_CLASS_*
-     * @param response is callback message
-     */
-
-    void queryCallWaiting(int serviceClass, Message response);
-
-    /**
-     * @param enable is true to enable, false to disable
-     * @param serviceClass is a sum of SERVICE_CLASS_*
-     * @param response is callback message
-     */
-
-    void setCallWaiting(boolean enable, int serviceClass, Message response);
-
-    /**
-     * @param action is one of CF_ACTION_*
-     * @param cfReason is one of CF_REASON_*
-     * @param serviceClass is a sum of SERVICE_CLASSS_*
-     */
-    void setCallForward(int action, int cfReason, int serviceClass,
-                String number, int timeSeconds, Message response);
-
-    /**
-     * cfReason is one of CF_REASON_*
-     *
-     * ((AsyncResult)response.obj).result will be an array of
-     * CallForwardInfo's
-     *
-     * An array of length 0 means "disabled for all codes"
-     */
-    void queryCallForwardStatus(int cfReason, int serviceClass,
-            String number, Message response);
-
-    void setNetworkSelectionModeAutomatic(Message response);
-
-    void setNetworkSelectionModeManual(String operatorNumeric, Message response);
-
-    /**
-     * Queries whether the current network selection mode is automatic
-     * or manual
-     *
-     * ((AsyncResult)response.obj).result  is an int[] with element [0] being
-     * a 0 for automatic selection and a 1 for manual selection
-     */
-
-    void getNetworkSelectionMode(Message response);
-
-    /**
-     * Queries the currently available networks
-     *
-     * ((AsyncResult)response.obj).result  is a List of NetworkInfo objects
-     */
-    void getAvailableNetworks(Message response);
-
-    void getBasebandVersion (Message response);
-
-
-    /**
-     * (AsyncResult)response.obj).result will be an Integer representing
-     * the sum of enabled service classes (sum of SERVICE_CLASS_*)
-     *
-     * @param facility one of CB_FACILTY_*
-     * @param password password or "" if not required
-     * @param serviceClass is a sum of SERVICE_CLASS_*
-     * @param response is callback message
-     */
-
-    void queryFacilityLock (String facility, String password, int serviceClass,
-        Message response);
-
-    /**
-     * (AsyncResult)response.obj).result will be an Integer representing
-     * the sum of enabled service classes (sum of SERVICE_CLASS_*) for the
-     * application with appId.
-     *
-     * @param facility one of CB_FACILTY_*
-     * @param password password or "" if not required
-     * @param serviceClass is a sum of SERVICE_CLASS_*
-     * @param appId is application Id or null if none
-     * @param response is callback message
-     */
-
-    void queryFacilityLockForApp(String facility, String password, int serviceClass, String appId,
-        Message response);
-
-    /**
-     * @param facility one of CB_FACILTY_*
-     * @param lockState true means lock, false means unlock
-     * @param password password or "" if not required
-     * @param serviceClass is a sum of SERVICE_CLASS_*
-     * @param response is callback message
-     */
-    void setFacilityLock (String facility, boolean lockState, String password,
-        int serviceClass, Message response);
-
-    /**
-     * Set the facility lock for the app with this AID on the ICC card.
-     *
-     * @param facility one of CB_FACILTY_*
-     * @param lockState true means lock, false means unlock
-     * @param password password or "" if not required
-     * @param serviceClass is a sum of SERVICE_CLASS_*
-     * @param appId is application Id or null if none
-     * @param response is callback message
-     */
-    void setFacilityLockForApp(String facility, boolean lockState, String password,
-        int serviceClass, String appId, Message response);
-
-    void sendUSSD (String ussdString, Message response);
-
-    /**
-     * Cancels a pending USSD session if one exists.
-     * @param response callback message
-     */
-    void cancelPendingUssd (Message response);
-
-    void resetRadio(Message result);
-
-    /**
-     * Assign a specified band for RF configuration.
-     *
-     * @param bandMode one of BM_*_BAND
-     * @param response is callback message
-     */
-    void setBandMode (int bandMode, Message response);
-
-    /**
-     * Query the list of band mode supported by RF.
-     *
-     * @param response is callback message
-     *        ((AsyncResult)response.obj).result  is an int[] with every
-     *        element representing one avialable BM_*_BAND
-     */
-    void queryAvailableBandMode (Message response);
-
-    /**
-     * Set the current preferred network type. This will be the last
-     * networkType that was passed to setPreferredNetworkType.
-     */
-    void setCurrentPreferredNetworkType();
-
-    /**
-     *  Requests to set the preferred network type for searching and registering
-     * (CS/PS domain, RAT, and operation mode)
-     * @param networkType one of  NT_*_TYPE
-     * @param response is callback message
-     */
-    void setPreferredNetworkType(int networkType , Message response);
-
-     /**
-     *  Query the preferred network type setting
-     *
-     * @param response is callback message to report one of  NT_*_TYPE
-     */
-    void getPreferredNetworkType(Message response);
-
-    /**
-     * Query neighboring cell ids
-     *
-     * @param response s callback message to cell ids
-     */
-    void getNeighboringCids(Message response);
-
-    /**
-     * Request to enable/disable network state change notifications when
-     * location information (lac and/or cid) has changed.
-     *
-     * @param enable true to enable, false to disable
-     * @param response callback message
-     */
-    void setLocationUpdates(boolean enable, Message response);
-
-    /**
-     * Gets the default SMSC address.
-     *
-     * @param result Callback message contains the SMSC address.
-     */
-    void getSmscAddress(Message result);
-
-    /**
-     * Sets the default SMSC address.
-     *
-     * @param address new SMSC address
-     * @param result Callback message is empty on completion
-     */
-    void setSmscAddress(String address, Message result);
-
-    /**
-     * Indicates whether there is storage available for new SMS messages.
-     * @param available true if storage is available
-     * @param result callback message
-     */
-    void reportSmsMemoryStatus(boolean available, Message result);
-
-    /**
-     * Indicates to the vendor ril that StkService is running
-     * and is ready to receive RIL_UNSOL_STK_XXXX commands.
-     *
-     * @param result callback message
-     */
-    void reportStkServiceIsRunning(Message result);
-
-    void invokeOemRilRequestRaw(byte[] data, Message response);
-
-    void invokeOemRilRequestStrings(String[] strings, Message response);
-
-
-    /**
-     * Send TERMINAL RESPONSE to the SIM, after processing a proactive command
-     * sent by the SIM.
-     *
-     * @param contents  String containing SAT/USAT response in hexadecimal
-     *                  format starting with first byte of response data. See
-     *                  TS 102 223 for details.
-     * @param response  Callback message
-     */
-    public void sendTerminalResponse(String contents, Message response);
-
-    /**
-     * Send ENVELOPE to the SIM, after processing a proactive command sent by
-     * the SIM.
-     *
-     * @param contents  String containing SAT/USAT response in hexadecimal
-     *                  format starting with command tag. See TS 102 223 for
-     *                  details.
-     * @param response  Callback message
-     */
-    public void sendEnvelope(String contents, Message response);
-
-    /**
-     * Send ENVELOPE to the SIM, such as an SMS-PP data download envelope
-     * for a SIM data download message. This method has one difference
-     * from {@link #sendEnvelope}: The SW1 and SW2 status bytes from the UICC response
-     * are returned along with the response data.
-     *
-     * response.obj will be an AsyncResult
-     * response.obj.result will be an IccIoResult on success
-     *
-     * @param contents  String containing SAT/USAT response in hexadecimal
-     *                  format starting with command tag. See TS 102 223 for
-     *                  details.
-     * @param response  Callback message
-     */
-    public void sendEnvelopeWithStatus(String contents, Message response);
-
-    /**
-     * Accept or reject the call setup request from SIM.
-     *
-     * @param accept   true if the call is to be accepted, false otherwise.
-     * @param response Callback message
-     */
-    public void handleCallSetupRequestFromSim(boolean accept, Message response);
-
-    /**
-     * Activate or deactivate cell broadcast SMS for GSM.
-     *
-     * @param activate
-     *            true = activate, false = deactivate
-     * @param result Callback message is empty on completion
-     */
-    public void setGsmBroadcastActivation(boolean activate, Message result);
-
-    /**
-     * Configure cell broadcast SMS for GSM.
-     *
-     * @param response Callback message is empty on completion
-     */
-    public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response);
-
-    /**
-     * Query the current configuration of cell broadcast SMS of GSM.
-     *
-     * @param response
-     *        Callback message contains the configuration from the modem
-     *        on completion
-     */
-    public void getGsmBroadcastConfig(Message response);
-
-    //***** new Methods for CDMA support
-
-    /**
-     * Request the device ESN / MEID / IMEI / IMEISV.
-     * "response" is const char **
-     *   [0] is IMEI if GSM subscription is available
-     *   [1] is IMEISV if GSM subscription is available
-     *   [2] is ESN if CDMA subscription is available
-     *   [3] is MEID if CDMA subscription is available
-     */
-    public void getDeviceIdentity(Message response);
-
-    /**
-     * Request the device MDN / H_SID / H_NID / MIN.
-     * "response" is const char **
-     *   [0] is MDN if CDMA subscription is available
-     *   [1] is a comma separated list of H_SID (Home SID) in decimal format
-     *       if CDMA subscription is available
-     *   [2] is a comma separated list of H_NID (Home NID) in decimal format
-     *       if CDMA subscription is available
-     *   [3] is MIN (10 digits, MIN2+MIN1) if CDMA subscription is available
-     */
-    public void getCDMASubscription(Message response);
-
-    /**
-     * Send Flash Code.
-     * "response" is is NULL
-     *   [0] is a FLASH string
-     */
-    public void sendCDMAFeatureCode(String FeatureCode, Message response);
-
-    /** Set the Phone type created */
-    void setPhoneType(int phoneType);
-
-    /**
-     *  Query the CDMA roaming preference setting
-     *
-     * @param response is callback message to report one of  CDMA_RM_*
-     */
-    void queryCdmaRoamingPreference(Message response);
-
-    /**
-     *  Requests to set the CDMA roaming preference
-     * @param cdmaRoamingType one of  CDMA_RM_*
-     * @param response is callback message
-     */
-    void setCdmaRoamingPreference(int cdmaRoamingType, Message response);
-
-    /**
-     *  Requests to set the CDMA subscription mode
-     * @param cdmaSubscriptionType one of  CDMA_SUBSCRIPTION_*
-     * @param response is callback message
-     */
-    void setCdmaSubscriptionSource(int cdmaSubscriptionType, Message response);
-
-    /**
-     *  Requests to get the CDMA subscription srouce
-     * @param response is callback message
-     */
-    void getCdmaSubscriptionSource(Message response);
-
-    /**
-     *  Set the TTY mode
-     *
-     * @param ttyMode one of the following:
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
-     * @param response is callback message
-     */
-    void setTTYMode(int ttyMode, Message response);
-
-    /**
-     *  Query the TTY mode
-     * (AsyncResult)response.obj).result is an int[] with element [0] set to
-     * tty mode:
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
-     * @param response is callback message
-     */
-    void queryTTYMode(Message response);
-
-    /**
-     * Setup a packet data connection On successful completion, the result
-     * message will return a {@link DataCallState} object containing the connection
-     * information.
-     *
-     * @param radioTechnology
-     *            indicates whether to setup connection on radio technology CDMA
-     *            (0) or GSM/UMTS (1)
-     * @param profile
-     *            Profile Number or NULL to indicate default profile
-     * @param apn
-     *            the APN to connect to if radio technology is GSM/UMTS.
-     *            Otherwise null for CDMA.
-     * @param user
-     *            the username for APN, or NULL
-     * @param password
-     *            the password for APN, or NULL
-     * @param authType
-     *            the PAP / CHAP auth type. Values is one of SETUP_DATA_AUTH_*
-     * @param protocol
-     *            one of the PDP_type values in TS 27.007 section 10.1.1.
-     *            For example, "IP", "IPV6", "IPV4V6", or "PPP".
-     * @param result
-     *            Callback message
-     */
-    public void setupDataCall(String radioTechnology, String profile,
-            String apn, String user, String password, String authType,
-            String protocol, Message result);
-
-    /**
-     * Deactivate packet data connection
-     *
-     * @param cid
-     *            The connection ID
-     * @param reason
-     *            Data disconnect reason.
-     * @param result
-     *            Callback message is empty on completion
-     */
-    public void deactivateDataCall(int cid, int reason, Message result);
-
-    /**
-     * Activate or deactivate cell broadcast SMS for CDMA.
-     *
-     * @param activate
-     *            true = activate, false = deactivate
-     * @param result
-     *            Callback message is empty on completion
-     */
-    public void setCdmaBroadcastActivation(boolean activate, Message result);
-
-    /**
-     * Configure cdma cell broadcast SMS.
-     *
-     * @param result
-     *            Callback message is empty on completion
-     */
-    // TODO: Change the configValuesArray to a RIL_BroadcastSMSConfig
-    public void setCdmaBroadcastConfig(int[] configValuesArray, Message result);
-
-    /**
-     * Query the current configuration of cdma cell broadcast SMS.
-     *
-     * @param result
-     *            Callback message contains the configuration from the modem on completion
-     */
-    public void getCdmaBroadcastConfig(Message result);
-
-    /**
-     *  Requests the radio's system selection module to exit emergency callback mode.
-     *  This function should only be called from CDMAPHone.java.
-     *
-     * @param response callback message
-     */
-    public void exitEmergencyCallbackMode(Message response);
-
-    /**
-     * Request the status of the ICC and UICC cards.
-     *
-     * @param result
-     *          Callback message containing {@link IccCardStatus} structure for the card.
-     */
-    public void getIccCardStatus(Message result);
-
-    /**
-     * Return if the current radio is LTE on CDMA. This
-     * is a tri-state return value as for a period of time
-     * the mode may be unknown.
-     *
-     * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
-     * or {@link Phone#LTE_ON_CDMA_TRUE}
-     */
-    public int getLteOnCdmaMode();
-
-    /**
-     * Request the ISIM application on the UICC to perform the AKA
-     * challenge/response algorithm for IMS authentication. The nonce string
-     * and challenge response are Base64 encoded Strings.
-     *
-     * @param nonce the nonce string to pass with the ISIM authentication request
-     * @param response a callback message with the String response in the obj field
-     */
-    public void requestIsimAuthentication(String nonce, Message response);
-
-    /**
-     * Notifiy that we are testing an emergency call
-     */
-    public void testingEmergencyCall();
-}
diff --git a/telephony/java/com/android/internal/telephony/Connection.java b/telephony/java/com/android/internal/telephony/Connection.java
deleted file mode 100644
index 07f90cd..0000000
--- a/telephony/java/com/android/internal/telephony/Connection.java
+++ /dev/null
@@ -1,310 +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.internal.telephony;
-import android.util.Log;
-
-/**
- * {@hide}
- */
-public abstract class Connection {
-
-    // Number presentation type for caller id display
-    public static int PRESENTATION_ALLOWED = 1;    // normal
-    public static int PRESENTATION_RESTRICTED = 2; // block by user
-    public static int PRESENTATION_UNKNOWN = 3;    // no specified or unknown by network
-    public static int PRESENTATION_PAYPHONE = 4;   // show pay phone info
-
-    private static String LOG_TAG = "TelephonyConnection";
-
-    public enum DisconnectCause {
-        NOT_DISCONNECTED,               /* has not yet disconnected */
-        INCOMING_MISSED,                /* an incoming call that was missed and never answered */
-        NORMAL,                         /* normal; remote */
-        LOCAL,                          /* normal; local hangup */
-        BUSY,                           /* outgoing call to busy line */
-        CONGESTION,                     /* outgoing call to congested network */
-        MMI,                            /* not presently used; dial() returns null */
-        INVALID_NUMBER,                 /* invalid dial string */
-        NUMBER_UNREACHABLE,             /* cannot reach the peer */
-        SERVER_UNREACHABLE,             /* cannot reach the server */
-        INVALID_CREDENTIALS,            /* invalid credentials */
-        OUT_OF_NETWORK,                 /* calling from out of network is not allowed */
-        SERVER_ERROR,                   /* server error */
-        TIMED_OUT,                      /* client timed out */
-        LOST_SIGNAL,
-        LIMIT_EXCEEDED,                 /* eg GSM ACM limit exceeded */
-        INCOMING_REJECTED,              /* an incoming call that was rejected */
-        POWER_OFF,                      /* radio is turned off explicitly */
-        OUT_OF_SERVICE,                 /* out of service */
-        ICC_ERROR,                      /* No ICC, ICC locked, or other ICC error */
-        CALL_BARRED,                    /* call was blocked by call barring */
-        FDN_BLOCKED,                    /* call was blocked by fixed dial number */
-        CS_RESTRICTED,                  /* call was blocked by restricted all voice access */
-        CS_RESTRICTED_NORMAL,           /* call was blocked by restricted normal voice access */
-        CS_RESTRICTED_EMERGENCY,        /* call was blocked by restricted emergency voice access */
-        UNOBTAINABLE_NUMBER,            /* Unassigned number (3GPP TS 24.008 table 10.5.123) */
-        CDMA_LOCKED_UNTIL_POWER_CYCLE,  /* MS is locked until next power cycle */
-        CDMA_DROP,
-        CDMA_INTERCEPT,                 /* INTERCEPT order received, MS state idle entered */
-        CDMA_REORDER,                   /* MS has been redirected, call is cancelled */
-        CDMA_SO_REJECT,                 /* service option rejection */
-        CDMA_RETRY_ORDER,               /* requested service is rejected, retry delay is set */
-        CDMA_ACCESS_FAILURE,
-        CDMA_PREEMPTED,
-        CDMA_NOT_EMERGENCY,              /* not an emergency call */
-        CDMA_ACCESS_BLOCKED,            /* Access Blocked by CDMA network */
-        ERROR_UNSPECIFIED
-    }
-
-    Object userData;
-
-    /* Instance Methods */
-
-    /**
-     * Gets address (e.g. phone number) associated with connection.
-     * TODO: distinguish reasons for unavailability
-     *
-     * @return address or null if unavailable
-     */
-
-    public abstract String getAddress();
-
-    /**
-     * Gets CDMA CNAP name associated with connection.
-     * @return cnap name or null if unavailable
-     */
-    public String getCnapName() {
-        return null;
-    }
-
-    /**
-     * Get original dial string.
-     * @return original dial string or null if unavailable
-     */
-    public String getOrigDialString(){
-        return null;
-    }
-
-    /**
-     * Gets CDMA CNAP presentation associated with connection.
-     * @return cnap name or null if unavailable
-     */
-
-    public int getCnapNamePresentation() {
-       return 0;
-    };
-
-    /**
-     * @return Call that owns this Connection, or null if none
-     */
-    public abstract Call getCall();
-
-    /**
-     * Connection create time in currentTimeMillis() format
-     * Basically, set when object is created.
-     * Effectively, when an incoming call starts ringing or an
-     * outgoing call starts dialing
-     */
-    public abstract long getCreateTime();
-
-    /**
-     * Connection connect time in currentTimeMillis() format.
-     * For outgoing calls: Begins at (DIALING|ALERTING) -> ACTIVE transition.
-     * For incoming calls: Begins at (INCOMING|WAITING) -> ACTIVE transition.
-     * Returns 0 before then.
-     */
-    public abstract long getConnectTime();
-
-    /**
-     * Disconnect time in currentTimeMillis() format.
-     * The time when this Connection makes a transition into ENDED or FAIL.
-     * Returns 0 before then.
-     */
-    public abstract long getDisconnectTime();
-
-    /**
-     * Returns the number of milliseconds the call has been connected,
-     * or 0 if the call has never connected.
-     * If the call is still connected, then returns the elapsed
-     * time since connect.
-     */
-    public abstract long getDurationMillis();
-
-    /**
-     * If this connection is HOLDING, return the number of milliseconds
-     * that it has been on hold for (approximately).
-     * If this connection is in any other state, return 0.
-     */
-
-    public abstract long getHoldDurationMillis();
-
-    /**
-     * Returns "NOT_DISCONNECTED" if not yet disconnected.
-     */
-    public abstract DisconnectCause getDisconnectCause();
-
-    /**
-     * Returns true of this connection originated elsewhere
-     * ("MT" or mobile terminated; another party called this terminal)
-     * or false if this call originated here (MO or mobile originated).
-     */
-    public abstract boolean isIncoming();
-
-    /**
-     * If this Connection is connected, then it is associated with
-     * a Call.
-     *
-     * Returns getCall().getState() or Call.State.IDLE if not
-     * connected
-     */
-    public Call.State getState() {
-        Call c;
-
-        c = getCall();
-
-        if (c == null) {
-            return Call.State.IDLE;
-        } else {
-            return c.getState();
-        }
-    }
-
-    /**
-     * isAlive()
-     *
-     * @return true if the connection isn't disconnected
-     * (could be active, holding, ringing, dialing, etc)
-     */
-    public boolean
-    isAlive() {
-        return getState().isAlive();
-    }
-
-    /**
-     * Returns true if Connection is connected and is INCOMING or WAITING
-     */
-    public boolean
-    isRinging() {
-        return getState().isRinging();
-    }
-
-    /**
-     *
-     * @return the userdata set in setUserData()
-     */
-    public Object getUserData() {
-        return userData;
-    }
-
-    /**
-     *
-     * @param userdata user can store an any userdata in the Connection object.
-     */
-    public void setUserData(Object userdata) {
-        this.userData = userdata;
-    }
-
-    /**
-     * Hangup individual Connection
-     */
-    public abstract void hangup() throws CallStateException;
-
-    /**
-     * Separate this call from its owner Call and assigns it to a new Call
-     * (eg if it is currently part of a Conference call
-     * TODO: Throw exception? Does GSM require error display on failure here?
-     */
-    public abstract void separate() throws CallStateException;
-
-    public enum PostDialState {
-        NOT_STARTED,    /* The post dial string playback hasn't
-                           been started, or this call is not yet
-                           connected, or this is an incoming call */
-        STARTED,        /* The post dial string playback has begun */
-        WAIT,           /* The post dial string playback is waiting for a
-                           call to proceedAfterWaitChar() */
-        WILD,           /* The post dial string playback is waiting for a
-                           call to proceedAfterWildChar() */
-        COMPLETE,       /* The post dial string playback is complete */
-        CANCELLED,       /* The post dial string playback was cancelled
-                           with cancelPostDial() */
-        PAUSE           /* The post dial string playback is pausing for a
-                           call to processNextPostDialChar*/
-    }
-
-    public void clearUserData(){
-        userData = null;
-    }
-
-    public abstract PostDialState getPostDialState();
-
-    /**
-     * Returns the portion of the post dial string that has not
-     * yet been dialed, or "" if none
-     */
-    public abstract String getRemainingPostDialString();
-
-    /**
-     * See Phone.setOnPostDialWaitCharacter()
-     */
-
-    public abstract void proceedAfterWaitChar();
-
-    /**
-     * See Phone.setOnPostDialWildCharacter()
-     */
-    public abstract void proceedAfterWildChar(String str);
-    /**
-     * Cancel any post
-     */
-    public abstract void cancelPostDial();
-
-    /**
-     * Returns the caller id presentation type for incoming and waiting calls
-     * @return one of PRESENTATION_*
-     */
-    public abstract int getNumberPresentation();
-
-    /**
-     * Returns the User to User Signaling (UUS) information associated with
-     * incoming and waiting calls
-     * @return UUSInfo containing the UUS userdata.
-     */
-    public abstract UUSInfo getUUSInfo();
-
-    /**
-     * Build a human representation of a connection instance, suitable for debugging.
-     * Don't log personal stuff unless in debug mode.
-     * @return a string representing the internal state of this connection.
-     */
-    public String toString() {
-        StringBuilder str = new StringBuilder(128);
-
-        if (Log.isLoggable(LOG_TAG, Log.DEBUG)) {
-            str.append("addr: " + getAddress())
-                    .append(" pres.: " + getNumberPresentation())
-                    .append(" dial: " + getOrigDialString())
-                    .append(" postdial: " + getRemainingPostDialString())
-                    .append(" cnap name: " + getCnapName())
-                    .append("(" + getCnapNamePresentation() + ")");
-        }
-        str.append(" incoming: " + isIncoming())
-                .append(" state: " + getState())
-                .append(" post dial state: " + getPostDialState());
-        return str.toString();
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/DataCallState.java b/telephony/java/com/android/internal/telephony/DataCallState.java
deleted file mode 100644
index efbf608..0000000
--- a/telephony/java/com/android/internal/telephony/DataCallState.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2009 Qualcomm Innovation Center, Inc.  All Rights Reserved.
- * 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.
- */
-
-package com.android.internal.telephony;
-
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.NetworkUtils;
-import android.net.RouteInfo;
-import android.os.SystemProperties;
-import android.util.Log;
-
-import com.android.internal.telephony.DataConnection.FailCause;
-
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-/**
- * This is RIL_Data_Call_Response_v5 from ril.h
- * TODO: Rename to DataCallResponse.
- */
-public class DataCallState {
-    private final boolean DBG = true;
-    private final String LOG_TAG = "GSM";
-
-    public int version = 0;
-    public int status = 0;
-    public int cid = 0;
-    public int active = 0;
-    public String type = "";
-    public String ifname = "";
-    public String [] addresses = new String[0];
-    public String [] dnses = new String[0];
-    public String[] gateways = new String[0];
-    public int suggestedRetryTime = -1;
-
-    /**
-     * Class returned by onSetupConnectionCompleted.
-     */
-    public enum SetupResult {
-        SUCCESS,
-        ERR_BadCommand,
-        ERR_UnacceptableParameter,
-        ERR_GetLastErrorFromRil,
-        ERR_Stale,
-        ERR_RilError;
-
-        public FailCause mFailCause;
-
-        SetupResult() {
-            mFailCause = FailCause.fromInt(0);
-        }
-
-        @Override
-        public String toString() {
-            return name() + "  SetupResult.mFailCause=" + mFailCause;
-        }
-    }
-
-    @Override
-    public String toString() {
-        StringBuffer sb = new StringBuffer();
-        sb.append("DataCallState: {")
-           .append("version=").append(version)
-           .append(" status=").append(status)
-           .append(" retry=").append(suggestedRetryTime)
-           .append(" cid=").append(cid)
-           .append(" active=").append(active)
-           .append(" type=").append(type)
-           .append("' ifname='").append(ifname);
-        sb.append("' addresses=[");
-        for (String addr : addresses) {
-            sb.append(addr);
-            sb.append(",");
-        }
-        if (addresses.length > 0) sb.deleteCharAt(sb.length()-1);
-        sb.append("] dnses=[");
-        for (String addr : dnses) {
-            sb.append(addr);
-            sb.append(",");
-        }
-        if (dnses.length > 0) sb.deleteCharAt(sb.length()-1);
-        sb.append("] gateways=[");
-        for (String addr : gateways) {
-            sb.append(addr);
-            sb.append(",");
-        }
-        if (gateways.length > 0) sb.deleteCharAt(sb.length()-1);
-        sb.append("]}");
-        return sb.toString();
-    }
-
-    public SetupResult setLinkProperties(LinkProperties linkProperties,
-            boolean okToUseSystemPropertyDns) {
-        SetupResult result;
-
-        // Start with clean network properties and if we have
-        // a failure we'll clear again at the bottom of this code.
-        if (linkProperties == null)
-            linkProperties = new LinkProperties();
-        else
-            linkProperties.clear();
-
-        if (status == FailCause.NONE.getErrorCode()) {
-            String propertyPrefix = "net." + ifname + ".";
-
-            try {
-                // set interface name
-                linkProperties.setInterfaceName(ifname);
-
-                // set link addresses
-                if (addresses != null && addresses.length > 0) {
-                    for (String addr : addresses) {
-                        addr = addr.trim();
-                        if (addr.isEmpty()) continue;
-                        LinkAddress la;
-                        int addrPrefixLen;
-
-                        String [] ap = addr.split("/");
-                        if (ap.length == 2) {
-                            addr = ap[0];
-                            addrPrefixLen = Integer.parseInt(ap[1]);
-                        } else {
-                            addrPrefixLen = 0;
-                        }
-                        InetAddress ia;
-                        try {
-                            ia = NetworkUtils.numericToInetAddress(addr);
-                        } catch (IllegalArgumentException e) {
-                            throw new UnknownHostException("Non-numeric ip addr=" + addr);
-                        }
-                        if (! ia.isAnyLocalAddress()) {
-                            if (addrPrefixLen == 0) {
-                                // Assume point to point
-                                addrPrefixLen = (ia instanceof Inet4Address) ? 32 : 128;
-                            }
-                            if (DBG) Log.d(LOG_TAG, "addr/pl=" + addr + "/" + addrPrefixLen);
-                            la = new LinkAddress(ia, addrPrefixLen);
-                            linkProperties.addLinkAddress(la);
-                        }
-                    }
-                } else {
-                    throw new UnknownHostException("no address for ifname=" + ifname);
-                }
-
-                // set dns servers
-                if (dnses != null && dnses.length > 0) {
-                    for (String addr : dnses) {
-                        addr = addr.trim();
-                        if (addr.isEmpty()) continue;
-                        InetAddress ia;
-                        try {
-                            ia = NetworkUtils.numericToInetAddress(addr);
-                        } catch (IllegalArgumentException e) {
-                            throw new UnknownHostException("Non-numeric dns addr=" + addr);
-                        }
-                        if (! ia.isAnyLocalAddress()) {
-                            linkProperties.addDns(ia);
-                        }
-                    }
-                } else if (okToUseSystemPropertyDns){
-                    String dnsServers[] = new String[2];
-                    dnsServers[0] = SystemProperties.get(propertyPrefix + "dns1");
-                    dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2");
-                    for (String dnsAddr : dnsServers) {
-                        dnsAddr = dnsAddr.trim();
-                        if (dnsAddr.isEmpty()) continue;
-                        InetAddress ia;
-                        try {
-                            ia = NetworkUtils.numericToInetAddress(dnsAddr);
-                        } catch (IllegalArgumentException e) {
-                            throw new UnknownHostException("Non-numeric dns addr=" + dnsAddr);
-                        }
-                        if (! ia.isAnyLocalAddress()) {
-                            linkProperties.addDns(ia);
-                        }
-                    }
-                } else {
-                    throw new UnknownHostException("Empty dns response and no system default dns");
-                }
-
-                // set gateways
-                if ((gateways == null) || (gateways.length == 0)) {
-                    String sysGateways = SystemProperties.get(propertyPrefix + "gw");
-                    if (sysGateways != null) {
-                        gateways = sysGateways.split(" ");
-                    } else {
-                        gateways = new String[0];
-                    }
-                }
-                for (String addr : gateways) {
-                    addr = addr.trim();
-                    if (addr.isEmpty()) continue;
-                    InetAddress ia;
-                    try {
-                        ia = NetworkUtils.numericToInetAddress(addr);
-                    } catch (IllegalArgumentException e) {
-                        throw new UnknownHostException("Non-numeric gateway addr=" + addr);
-                    }
-                    if (! ia.isAnyLocalAddress()) {
-                        linkProperties.addRoute(new RouteInfo(ia));
-                    }
-                }
-
-                result = SetupResult.SUCCESS;
-            } catch (UnknownHostException e) {
-                Log.d(LOG_TAG, "setLinkProperties: UnknownHostException " + e);
-                e.printStackTrace();
-                result = SetupResult.ERR_UnacceptableParameter;
-            }
-        } else {
-            if (version < 4) {
-                result = SetupResult.ERR_GetLastErrorFromRil;
-            } else {
-                result = SetupResult.ERR_RilError;
-            }
-        }
-
-        // An error occurred so clear properties
-        if (result != SetupResult.SUCCESS) {
-            if(DBG) {
-                Log.d(LOG_TAG, "setLinkProperties: error clearing LinkProperties " +
-                        "status=" + status + " result=" + result);
-            }
-            linkProperties.clear();
-        }
-
-        return result;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
deleted file mode 100644
index 3f7e71e3..0000000
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ /dev/null
@@ -1,1269 +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.internal.telephony;
-
-
-import com.android.internal.telephony.DataCallState.SetupResult;
-import com.android.internal.util.AsyncChannel;
-import com.android.internal.util.Protocol;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-
-import android.app.PendingIntent;
-import android.net.LinkCapabilities;
-import android.net.LinkProperties;
-import android.net.ProxyProperties;
-import android.os.AsyncResult;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.text.TextUtils;
-import android.util.TimeUtils;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * {@hide}
- *
- * DataConnection StateMachine.
- *
- * This is an abstract base class for representing a single data connection.
- * Instances of this class such as <code>CdmaDataConnection</code> and
- * <code>GsmDataConnection</code>, * represent a connection via the cellular network.
- * There may be multiple data connections and all of them are managed by the
- * <code>DataConnectionTracker</code>.
- *
- * Instances are asynchronous state machines and have two primary entry points
- * <code>connect()</code> and <code>disconnect</code>. The message a parameter will be returned
- * hen the operation completes. The <code>msg.obj</code> will contain an AsyncResult
- * object and <code>AsyncResult.userObj</code> is the original <code>msg.obj</code>. if successful
- * with the <code>AsyncResult.result == null</code> and <code>AsyncResult.exception == null</code>.
- * If an error <code>AsyncResult.result = FailCause</code> and
- * <code>AsyncResult.exception = new Exception()</code>.
- *
- * The other public methods are provided for debugging.
- */
-public abstract class DataConnection extends StateMachine {
-    protected static final boolean DBG = true;
-    protected static final boolean VDBG = false;
-
-    protected static Object mCountLock = new Object();
-    protected static int mCount;
-    protected AsyncChannel mAc;
-
-    protected List<ApnContext> mApnList = null;
-    PendingIntent mReconnectIntent = null;
-
-    private DataConnectionTracker mDataConnectionTracker = null;
-
-    /**
-     * Used internally for saving connecting parameters.
-     */
-    protected static class ConnectionParams {
-        public ConnectionParams(ApnSetting apn, Message onCompletedMsg) {
-            this.apn = apn;
-            this.onCompletedMsg = onCompletedMsg;
-        }
-
-        public int tag;
-        public ApnSetting apn;
-        public Message onCompletedMsg;
-    }
-
-    /**
-     * Used internally for saving disconnecting parameters.
-     */
-    protected static class DisconnectParams {
-        public DisconnectParams(String reason, Message onCompletedMsg) {
-            this.reason = reason;
-            this.onCompletedMsg = onCompletedMsg;
-        }
-        public int tag;
-        public String reason;
-        public Message onCompletedMsg;
-    }
-
-    /**
-     * Returned as the reason for a connection failure as defined
-     * by RIL_DataCallFailCause in ril.h and some local errors.
-     */
-    public enum FailCause {
-        NONE(0),
-
-        // This series of errors as specified by the standards
-        // specified in ril.h
-        OPERATOR_BARRED(0x08),
-        INSUFFICIENT_RESOURCES(0x1A),
-        MISSING_UNKNOWN_APN(0x1B),
-        UNKNOWN_PDP_ADDRESS_TYPE(0x1C),
-        USER_AUTHENTICATION(0x1D),
-        ACTIVATION_REJECT_GGSN(0x1E),
-        ACTIVATION_REJECT_UNSPECIFIED(0x1F),
-        SERVICE_OPTION_NOT_SUPPORTED(0x20),
-        SERVICE_OPTION_NOT_SUBSCRIBED(0x21),
-        SERVICE_OPTION_OUT_OF_ORDER(0x22),
-        NSAPI_IN_USE(0x23),
-        ONLY_IPV4_ALLOWED(0x32),
-        ONLY_IPV6_ALLOWED(0x33),
-        ONLY_SINGLE_BEARER_ALLOWED(0x34),
-        PROTOCOL_ERRORS(0x6F),
-
-        // Local errors generated by Vendor RIL
-        // specified in ril.h
-        REGISTRATION_FAIL(-1),
-        GPRS_REGISTRATION_FAIL(-2),
-        SIGNAL_LOST(-3),
-        PREF_RADIO_TECH_CHANGED(-4),
-        RADIO_POWER_OFF(-5),
-        TETHERED_CALL_ACTIVE(-6),
-        ERROR_UNSPECIFIED(0xFFFF),
-
-        // Errors generated by the Framework
-        // specified here
-        UNKNOWN(0x10000),
-        RADIO_NOT_AVAILABLE(0x10001),
-        UNACCEPTABLE_NETWORK_PARAMETER(0x10002),
-        CONNECTION_TO_DATACONNECTIONAC_BROKEN(0x10003);
-
-        private final int mErrorCode;
-        private static final HashMap<Integer, FailCause> sErrorCodeToFailCauseMap;
-        static {
-            sErrorCodeToFailCauseMap = new HashMap<Integer, FailCause>();
-            for (FailCause fc : values()) {
-                sErrorCodeToFailCauseMap.put(fc.getErrorCode(), fc);
-            }
-        }
-
-        FailCause(int errorCode) {
-            mErrorCode = errorCode;
-        }
-
-        int getErrorCode() {
-            return mErrorCode;
-        }
-
-        public boolean isPermanentFail() {
-            return (this == OPERATOR_BARRED) || (this == MISSING_UNKNOWN_APN) ||
-                   (this == UNKNOWN_PDP_ADDRESS_TYPE) || (this == USER_AUTHENTICATION) ||
-                   (this == SERVICE_OPTION_NOT_SUPPORTED) ||
-                   (this == SERVICE_OPTION_NOT_SUBSCRIBED) || (this == NSAPI_IN_USE) ||
-                   (this == PROTOCOL_ERRORS);
-        }
-
-        public boolean isEventLoggable() {
-            return (this == OPERATOR_BARRED) || (this == INSUFFICIENT_RESOURCES) ||
-                    (this == UNKNOWN_PDP_ADDRESS_TYPE) || (this == USER_AUTHENTICATION) ||
-                    (this == ACTIVATION_REJECT_GGSN) || (this == ACTIVATION_REJECT_UNSPECIFIED) ||
-                    (this == SERVICE_OPTION_NOT_SUBSCRIBED) ||
-                    (this == SERVICE_OPTION_NOT_SUPPORTED) ||
-                    (this == SERVICE_OPTION_OUT_OF_ORDER) || (this == NSAPI_IN_USE) ||
-                    (this == PROTOCOL_ERRORS) ||
-                    (this == UNACCEPTABLE_NETWORK_PARAMETER);
-        }
-
-        public static FailCause fromInt(int errorCode) {
-            FailCause fc = sErrorCodeToFailCauseMap.get(errorCode);
-            if (fc == null) {
-                fc = UNKNOWN;
-            }
-            return fc;
-        }
-    }
-
-    public static class CallSetupException extends Exception {
-        private int mRetryOverride = -1;
-
-        CallSetupException (int retryOverride) {
-            mRetryOverride = retryOverride;
-        }
-
-        public int getRetryOverride() {
-            return mRetryOverride;
-        }
-    }
-
-    // ***** Event codes for driving the state machine
-    protected static final int BASE = Protocol.BASE_DATA_CONNECTION;
-    protected static final int EVENT_CONNECT = BASE + 0;
-    protected static final int EVENT_SETUP_DATA_CONNECTION_DONE = BASE + 1;
-    protected static final int EVENT_GET_LAST_FAIL_DONE = BASE + 2;
-    protected static final int EVENT_DEACTIVATE_DONE = BASE + 3;
-    protected static final int EVENT_DISCONNECT = BASE + 4;
-    protected static final int EVENT_RIL_CONNECTED = BASE + 5;
-    protected static final int EVENT_DISCONNECT_ALL = BASE + 6;
-
-    private static final int CMD_TO_STRING_COUNT = EVENT_DISCONNECT_ALL - BASE + 1;
-    private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
-    static {
-        sCmdToString[EVENT_CONNECT - BASE] = "EVENT_CONNECT";
-        sCmdToString[EVENT_SETUP_DATA_CONNECTION_DONE - BASE] =
-                "EVENT_SETUP_DATA_CONNECTION_DONE";
-        sCmdToString[EVENT_GET_LAST_FAIL_DONE - BASE] = "EVENT_GET_LAST_FAIL_DONE";
-        sCmdToString[EVENT_DEACTIVATE_DONE - BASE] = "EVENT_DEACTIVATE_DONE";
-        sCmdToString[EVENT_DISCONNECT - BASE] = "EVENT_DISCONNECT";
-        sCmdToString[EVENT_RIL_CONNECTED - BASE] = "EVENT_RIL_CONNECTED";
-        sCmdToString[EVENT_DISCONNECT_ALL - BASE] = "EVENT_DISCONNECT_ALL";
-    }
-    protected static String cmdToString(int cmd) {
-        cmd -= BASE;
-        if ((cmd >= 0) && (cmd < sCmdToString.length)) {
-            return sCmdToString[cmd];
-        } else {
-            return null;
-        }
-    }
-
-    //***** Tag IDs for EventLog
-    protected static final int EVENT_LOG_BAD_DNS_ADDRESS = 50100;
-
-    //***** Member Variables
-    protected ApnSetting mApn;
-    protected int mTag;
-    protected PhoneBase phone;
-    protected int mRilVersion = -1;
-    protected int cid;
-    protected LinkProperties mLinkProperties = new LinkProperties();
-    protected LinkCapabilities mCapabilities = new LinkCapabilities();
-    protected long createTime;
-    protected long lastFailTime;
-    protected FailCause lastFailCause;
-    protected int mRetryOverride = -1;
-    protected static final String NULL_IP = "0.0.0.0";
-    protected int mRefCount;
-    Object userData;
-
-    //***** Abstract methods
-    @Override
-    public abstract String toString();
-
-    protected abstract void onConnect(ConnectionParams cp);
-
-    protected abstract boolean isDnsOk(String[] domainNameServers);
-
-    protected abstract void log(String s);
-
-
-   //***** Constructor
-    protected DataConnection(PhoneBase phone, String name, int id, RetryManager rm,
-            DataConnectionTracker dct) {
-        super(name);
-        setProcessedMessagesSize(100);
-        if (DBG) log("DataConnection constructor E");
-        this.phone = phone;
-        this.mDataConnectionTracker = dct;
-        mId = id;
-        mRetryMgr = rm;
-        this.cid = -1;
-
-        setDbg(false);
-        addState(mDefaultState);
-            addState(mInactiveState, mDefaultState);
-            addState(mActivatingState, mDefaultState);
-            addState(mActiveState, mDefaultState);
-            addState(mDisconnectingState, mDefaultState);
-            addState(mDisconnectingErrorCreatingConnection, mDefaultState);
-        setInitialState(mInactiveState);
-
-        mApnList = new ArrayList<ApnContext>();
-        if (DBG) log("DataConnection constructor X");
-    }
-
-    /**
-     * TearDown the data connection.
-     *
-     * @param o will be returned in AsyncResult.userObj
-     *          and is either a DisconnectParams or ConnectionParams.
-     */
-    private void tearDownData(Object o) {
-        int discReason = RILConstants.DEACTIVATE_REASON_NONE;
-        if ((o != null) && (o instanceof DisconnectParams)) {
-            DisconnectParams dp = (DisconnectParams)o;
-            Message m = dp.onCompletedMsg;
-            if (TextUtils.equals(dp.reason, Phone.REASON_RADIO_TURNED_OFF)) {
-                discReason = RILConstants.DEACTIVATE_REASON_RADIO_OFF;
-            } else if (TextUtils.equals(dp.reason, Phone.REASON_PDP_RESET)) {
-                discReason = RILConstants.DEACTIVATE_REASON_PDP_RESET;
-            }
-        }
-        if (phone.mCM.getRadioState().isOn()) {
-            if (DBG) log("tearDownData radio is on, call deactivateDataCall");
-            phone.mCM.deactivateDataCall(cid, discReason, obtainMessage(EVENT_DEACTIVATE_DONE, o));
-        } else {
-            if (DBG) log("tearDownData radio is off sendMessage EVENT_DEACTIVATE_DONE immediately");
-            AsyncResult ar = new AsyncResult(o, null, null);
-            sendMessage(obtainMessage(EVENT_DEACTIVATE_DONE, ar));
-        }
-    }
-
-    /**
-     * Send the connectionCompletedMsg.
-     *
-     * @param cp is the ConnectionParams
-     * @param cause
-     */
-    private void notifyConnectCompleted(ConnectionParams cp, FailCause cause) {
-        Message connectionCompletedMsg = cp.onCompletedMsg;
-        if (connectionCompletedMsg == null) {
-            return;
-        }
-
-        long timeStamp = System.currentTimeMillis();
-        connectionCompletedMsg.arg1 = cid;
-
-        if (cause == FailCause.NONE) {
-            createTime = timeStamp;
-            AsyncResult.forMessage(connectionCompletedMsg);
-        } else {
-            lastFailCause = cause;
-            lastFailTime = timeStamp;
-            AsyncResult.forMessage(connectionCompletedMsg, cause,
-                                   new CallSetupException(mRetryOverride));
-        }
-        if (DBG) log("notifyConnectionCompleted at " + timeStamp + " cause=" + cause);
-
-        connectionCompletedMsg.sendToTarget();
-    }
-
-    /**
-     * Send ar.userObj if its a message, which is should be back to originator.
-     *
-     * @param dp is the DisconnectParams.
-     */
-    private void notifyDisconnectCompleted(DisconnectParams dp, boolean sendAll) {
-        if (VDBG) log("NotifyDisconnectCompleted");
-
-        ApnContext alreadySent = null;
-        String reason = null;
-
-        if (dp.onCompletedMsg != null) {
-            // Get ApnContext, but only valid on GSM devices this is a string on CDMA devices.
-            Message msg = dp.onCompletedMsg;
-            if (msg.obj instanceof ApnContext) {
-                alreadySent = (ApnContext)msg.obj;
-            }
-            reason = dp.reason;
-            if (VDBG) {
-                log(String.format("msg=%s msg.obj=%s", msg.toString(),
-                    ((msg.obj instanceof String) ? (String) msg.obj : "<no-reason>")));
-            }
-            AsyncResult.forMessage(msg);
-            msg.sendToTarget();
-        }
-        if (sendAll) {
-            for (ApnContext a : mApnList) {
-                if (a == alreadySent) continue;
-                if (reason != null) a.setReason(reason);
-                Message msg = mDataConnectionTracker.obtainMessage(
-                        DataConnectionTracker.EVENT_DISCONNECT_DONE, a);
-                AsyncResult.forMessage(msg);
-                msg.sendToTarget();
-            }
-        }
-
-        if (DBG) log("NotifyDisconnectCompleted DisconnectParams=" + dp);
-    }
-
-    protected int getRilRadioTechnology(int defaultRilRadioTechnology) {
-        int rilRadioTechnology;
-        if (mRilVersion < 6) {
-            rilRadioTechnology = defaultRilRadioTechnology;
-        } else {
-            rilRadioTechnology = phone.getServiceState().getRilRadioTechnology() + 2;
-        }
-        return rilRadioTechnology;
-    }
-
-    /*
-     * **************************************************************************
-     * Begin Members and methods owned by DataConnectionTracker but stored
-     * in a DataConnection because there is one per connection.
-     * **************************************************************************
-     */
-
-    /*
-     * The id is owned by DataConnectionTracker.
-     */
-    private int mId;
-
-    /**
-     * Get the DataConnection ID
-     */
-    public int getDataConnectionId() {
-        return mId;
-    }
-
-    /*
-     * The retry manager is currently owned by the DataConnectionTracker but is stored
-     * in the DataConnection because there is one per connection. These methods
-     * should only be used by the DataConnectionTracker although someday the retrying
-     * maybe managed by the DataConnection itself and these methods could disappear.
-     */
-    private RetryManager mRetryMgr;
-
-    /**
-     * @return retry manager retryCount
-     */
-    public int getRetryCount() {
-        return mRetryMgr.getRetryCount();
-    }
-
-    /**
-     * set retry manager retryCount
-     */
-    public void setRetryCount(int retryCount) {
-        if (DBG) log("setRetryCount: " + retryCount);
-        mRetryMgr.setRetryCount(retryCount);
-    }
-
-    /**
-     * @return retry manager retryTimer
-     */
-    public int getRetryTimer() {
-        return mRetryMgr.getRetryTimer();
-    }
-
-    /**
-     * increaseRetryCount of retry manager
-     */
-    public void increaseRetryCount() {
-        mRetryMgr.increaseRetryCount();
-    }
-
-    /**
-     * @return retry manager isRetryNeeded
-     */
-    public boolean isRetryNeeded() {
-        return mRetryMgr.isRetryNeeded();
-    }
-
-    /**
-     * resetRetryCount of retry manager
-     */
-    public void resetRetryCount() {
-        mRetryMgr.resetRetryCount();
-    }
-
-    /**
-     * set retryForeverUsingLasttimeout of retry manager
-     */
-    public void retryForeverUsingLastTimeout() {
-        mRetryMgr.retryForeverUsingLastTimeout();
-    }
-
-    /**
-     * @return retry manager isRetryForever
-     */
-    public boolean isRetryForever() {
-        return mRetryMgr.isRetryForever();
-    }
-
-    /**
-     * @return whether the retry config is set successfully or not
-     */
-    public boolean configureRetry(int maxRetryCount, int retryTime, int randomizationTime) {
-        return mRetryMgr.configure(maxRetryCount, retryTime, randomizationTime);
-    }
-
-    /**
-     * @return whether the retry config is set successfully or not
-     */
-    public boolean configureRetry(String configStr) {
-        return mRetryMgr.configure(configStr);
-    }
-
-    /*
-     * **************************************************************************
-     * End members owned by DataConnectionTracker
-     * **************************************************************************
-     */
-
-    /**
-     * Clear all settings called when entering mInactiveState.
-     */
-    protected void clearSettings() {
-        if (DBG) log("clearSettings");
-
-        createTime = -1;
-        lastFailTime = -1;
-        lastFailCause = FailCause.NONE;
-        mRetryOverride = -1;
-        mRefCount = 0;
-        cid = -1;
-
-        mLinkProperties = new LinkProperties();
-        mApn = null;
-    }
-
-    /**
-     * Process setup completion.
-     *
-     * @param ar is the result
-     * @return SetupResult.
-     */
-    private DataCallState.SetupResult onSetupConnectionCompleted(AsyncResult ar) {
-        DataCallState response = (DataCallState) ar.result;
-        ConnectionParams cp = (ConnectionParams) ar.userObj;
-        DataCallState.SetupResult result;
-
-        if (ar.exception != null) {
-            if (DBG) {
-                log("onSetupConnectionCompleted failed, ar.exception=" + ar.exception +
-                    " response=" + response);
-            }
-
-            if (ar.exception instanceof CommandException
-                    && ((CommandException) (ar.exception)).getCommandError()
-                    == CommandException.Error.RADIO_NOT_AVAILABLE) {
-                result = DataCallState.SetupResult.ERR_BadCommand;
-                result.mFailCause = FailCause.RADIO_NOT_AVAILABLE;
-            } else if ((response == null) || (response.version < 4)) {
-                result = DataCallState.SetupResult.ERR_GetLastErrorFromRil;
-            } else {
-                result = DataCallState.SetupResult.ERR_RilError;
-                result.mFailCause = FailCause.fromInt(response.status);
-            }
-        } else if (cp.tag != mTag) {
-            if (DBG) {
-                log("BUG: onSetupConnectionCompleted is stale cp.tag=" + cp.tag + ", mtag=" + mTag);
-            }
-            result = DataCallState.SetupResult.ERR_Stale;
-        } else if (response.status != 0) {
-            result = DataCallState.SetupResult.ERR_RilError;
-            result.mFailCause = FailCause.fromInt(response.status);
-        } else {
-            if (DBG) log("onSetupConnectionCompleted received DataCallState: " + response);
-            cid = response.cid;
-            result = updateLinkProperty(response).setupResult;
-        }
-
-        return result;
-    }
-
-    private int getSuggestedRetryTime(AsyncResult ar) {
-        int retry = -1;
-        if (ar.exception == null) {
-            DataCallState response = (DataCallState) ar.result;
-            retry =  response.suggestedRetryTime;
-        }
-        return retry;
-    }
-
-    private DataCallState.SetupResult setLinkProperties(DataCallState response,
-            LinkProperties lp) {
-        // Check if system property dns usable
-        boolean okToUseSystemPropertyDns = false;
-        String propertyPrefix = "net." + response.ifname + ".";
-        String dnsServers[] = new String[2];
-        dnsServers[0] = SystemProperties.get(propertyPrefix + "dns1");
-        dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2");
-        okToUseSystemPropertyDns = isDnsOk(dnsServers);
-
-        // set link properties based on data call response
-        return response.setLinkProperties(lp, okToUseSystemPropertyDns);
-    }
-
-    public static class UpdateLinkPropertyResult {
-        public DataCallState.SetupResult setupResult = DataCallState.SetupResult.SUCCESS;
-        public LinkProperties oldLp;
-        public LinkProperties newLp;
-        public UpdateLinkPropertyResult(LinkProperties curLp) {
-            oldLp = curLp;
-            newLp = curLp;
-        }
-    }
-
-    private UpdateLinkPropertyResult updateLinkProperty(DataCallState newState) {
-        UpdateLinkPropertyResult result = new UpdateLinkPropertyResult(mLinkProperties);
-
-        if (newState == null) return result;
-
-        DataCallState.SetupResult setupResult;
-        result.newLp = new LinkProperties();
-
-        // set link properties based on data call response
-        result.setupResult = setLinkProperties(newState, result.newLp);
-        if (result.setupResult != DataCallState.SetupResult.SUCCESS) {
-            if (DBG) log("updateLinkProperty failed : " + result.setupResult);
-            return result;
-        }
-        // copy HTTP proxy as it is not part DataCallState.
-        result.newLp.setHttpProxy(mLinkProperties.getHttpProxy());
-
-        if (DBG && (! result.oldLp.equals(result.newLp))) {
-            log("updateLinkProperty old LP=" + result.oldLp);
-            log("updateLinkProperty new LP=" + result.newLp);
-        }
-        mLinkProperties = result.newLp;
-
-        return result;
-    }
-
-    /**
-     * The parent state for all other states.
-     */
-    private class DcDefaultState extends State {
-        @Override
-        public void enter() {
-            phone.mCM.registerForRilConnected(getHandler(), EVENT_RIL_CONNECTED, null);
-        }
-        @Override
-        public void exit() {
-            phone.mCM.unregisterForRilConnected(getHandler());
-        }
-        @Override
-        public boolean processMessage(Message msg) {
-            AsyncResult ar;
-
-            switch (msg.what) {
-                case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: {
-                    if (mAc != null) {
-                        if (VDBG) log("Disconnecting to previous connection mAc=" + mAc);
-                        mAc.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED,
-                                AsyncChannel.STATUS_FULL_CONNECTION_REFUSED_ALREADY_CONNECTED);
-                    } else {
-                        mAc = new AsyncChannel();
-                        mAc.connected(null, getHandler(), msg.replyTo);
-                        if (VDBG) log("DcDefaultState: FULL_CONNECTION reply connected");
-                        mAc.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED,
-                                AsyncChannel.STATUS_SUCCESSFUL, mId, "hi");
-                    }
-                    break;
-                }
-                case AsyncChannel.CMD_CHANNEL_DISCONNECT: {
-                    if (VDBG) log("CMD_CHANNEL_DISCONNECT");
-                    mAc.disconnect();
-                    break;
-                }
-                case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
-                    if (VDBG) log("CMD_CHANNEL_DISCONNECTED");
-                    mAc = null;
-                    break;
-                }
-                case DataConnectionAc.REQ_IS_INACTIVE: {
-                    boolean val = getCurrentState() == mInactiveState;
-                    if (VDBG) log("REQ_IS_INACTIVE  isInactive=" + val);
-                    mAc.replyToMessage(msg, DataConnectionAc.RSP_IS_INACTIVE, val ? 1 : 0);
-                    break;
-                }
-                case DataConnectionAc.REQ_GET_CID: {
-                    if (VDBG) log("REQ_GET_CID  cid=" + cid);
-                    mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_CID, cid);
-                    break;
-                }
-                case DataConnectionAc.REQ_GET_APNSETTING: {
-                    if (VDBG) log("REQ_GET_APNSETTING  apnSetting=" + mApn);
-                    mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_APNSETTING, mApn);
-                    break;
-                }
-                case DataConnectionAc.REQ_GET_LINK_PROPERTIES: {
-                    LinkProperties lp = new LinkProperties(mLinkProperties);
-                    if (VDBG) log("REQ_GET_LINK_PROPERTIES linkProperties" + lp);
-                    mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_LINK_PROPERTIES, lp);
-                    break;
-                }
-                case DataConnectionAc.REQ_SET_LINK_PROPERTIES_HTTP_PROXY: {
-                    ProxyProperties proxy = (ProxyProperties) msg.obj;
-                    if (VDBG) log("REQ_SET_LINK_PROPERTIES_HTTP_PROXY proxy=" + proxy);
-                    mLinkProperties.setHttpProxy(proxy);
-                    mAc.replyToMessage(msg, DataConnectionAc.RSP_SET_LINK_PROPERTIES_HTTP_PROXY);
-                    break;
-                }
-                case DataConnectionAc.REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE: {
-                    DataCallState newState = (DataCallState) msg.obj;
-                    UpdateLinkPropertyResult result =
-                                             updateLinkProperty(newState);
-                    if (VDBG) {
-                        log("REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE result="
-                            + result + " newState=" + newState);
-                    }
-                    mAc.replyToMessage(msg,
-                                   DataConnectionAc.RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE,
-                                   result);
-                    break;
-                }
-                case DataConnectionAc.REQ_GET_LINK_CAPABILITIES: {
-                    LinkCapabilities lc = new LinkCapabilities(mCapabilities);
-                    if (VDBG) log("REQ_GET_LINK_CAPABILITIES linkCapabilities" + lc);
-                    mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_LINK_CAPABILITIES, lc);
-                    break;
-                }
-                case DataConnectionAc.REQ_RESET:
-                    if (VDBG) log("DcDefaultState: msg.what=REQ_RESET");
-                    mAc.replyToMessage(msg, DataConnectionAc.RSP_RESET);
-                    transitionTo(mInactiveState);
-                    break;
-                case DataConnectionAc.REQ_GET_REFCOUNT: {
-                    if (VDBG) log("REQ_GET_REFCOUNT  refCount=" + mRefCount);
-                    mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_REFCOUNT, mRefCount);
-                    break;
-                }
-                case DataConnectionAc.REQ_ADD_APNCONTEXT: {
-                    ApnContext apnContext = (ApnContext) msg.obj;
-                    if (VDBG) log("REQ_ADD_APNCONTEXT apn=" + apnContext.getApnType());
-                    if (!mApnList.contains(apnContext)) {
-                        mApnList.add(apnContext);
-                    }
-                    mAc.replyToMessage(msg, DataConnectionAc.RSP_ADD_APNCONTEXT);
-                    break;
-                }
-                case DataConnectionAc.REQ_REMOVE_APNCONTEXT: {
-                    ApnContext apnContext = (ApnContext) msg.obj;
-                    if (VDBG) log("REQ_REMOVE_APNCONTEXT apn=" + apnContext.getApnType());
-                    mApnList.remove(apnContext);
-                    mAc.replyToMessage(msg, DataConnectionAc.RSP_REMOVE_APNCONTEXT);
-                    break;
-                }
-                case DataConnectionAc.REQ_GET_APNCONTEXT_LIST: {
-                    if (VDBG) log("REQ_GET_APNCONTEXT_LIST num in list=" + mApnList.size());
-                    mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_APNCONTEXT_LIST,
-                                       new ArrayList<ApnContext>(mApnList));
-                    break;
-                }
-                case DataConnectionAc.REQ_SET_RECONNECT_INTENT: {
-                    PendingIntent intent = (PendingIntent) msg.obj;
-                    if (VDBG) log("REQ_SET_RECONNECT_INTENT");
-                    mReconnectIntent = intent;
-                    mAc.replyToMessage(msg, DataConnectionAc.RSP_SET_RECONNECT_INTENT);
-                    break;
-                }
-                case DataConnectionAc.REQ_GET_RECONNECT_INTENT: {
-                    if (VDBG) log("REQ_GET_RECONNECT_INTENT");
-                    mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_RECONNECT_INTENT,
-                                       mReconnectIntent);
-                    break;
-                }
-                case EVENT_CONNECT:
-                    if (DBG) log("DcDefaultState: msg.what=EVENT_CONNECT, fail not expected");
-                    ConnectionParams cp = (ConnectionParams) msg.obj;
-                    notifyConnectCompleted(cp, FailCause.UNKNOWN);
-                    break;
-
-                case EVENT_DISCONNECT:
-                    if (DBG) {
-                        log("DcDefaultState deferring msg.what=EVENT_DISCONNECT" + mRefCount);
-                    }
-                    deferMessage(msg);
-                    break;
-
-                case EVENT_DISCONNECT_ALL:
-                    if (DBG) {
-                        log("DcDefaultState deferring msg.what=EVENT_DISCONNECT_ALL" + mRefCount);
-                    }
-                    deferMessage(msg);
-                    break;
-
-                case EVENT_RIL_CONNECTED:
-                    ar = (AsyncResult)msg.obj;
-                    if (ar.exception == null) {
-                        mRilVersion = (Integer)ar.result;
-                        if (DBG) {
-                            log("DcDefaultState: msg.what=EVENT_RIL_CONNECTED mRilVersion=" +
-                                mRilVersion);
-                        }
-                    } else {
-                        log("Unexpected exception on EVENT_RIL_CONNECTED");
-                        mRilVersion = -1;
-                    }
-                    break;
-
-                default:
-                    if (DBG) {
-                        log("DcDefaultState: shouldn't happen but ignore msg.what=0x" +
-                                Integer.toHexString(msg.what));
-                    }
-                    break;
-            }
-
-            return HANDLED;
-        }
-    }
-    private DcDefaultState mDefaultState = new DcDefaultState();
-
-    /**
-     * The state machine is inactive and expects a EVENT_CONNECT.
-     */
-    private class DcInactiveState extends State {
-        private ConnectionParams mConnectionParams = null;
-        private FailCause mFailCause = null;
-        private DisconnectParams mDisconnectParams = null;
-
-        public void setEnterNotificationParams(ConnectionParams cp, FailCause cause,
-                                               int retryOverride) {
-            if (VDBG) log("DcInactiveState: setEnterNoticationParams cp,cause");
-            mConnectionParams = cp;
-            mFailCause = cause;
-            mRetryOverride = retryOverride;
-        }
-
-        public void setEnterNotificationParams(DisconnectParams dp) {
-            if (VDBG) log("DcInactiveState: setEnterNoticationParams dp");
-            mDisconnectParams = dp;
-        }
-
-        @Override
-        public void enter() {
-            mTag += 1;
-
-            /**
-             * Now that we've transitioned to Inactive state we
-             * can send notifications. Previously we sent the
-             * notifications in the processMessage handler but
-             * that caused a race condition because the synchronous
-             * call to isInactive.
-             */
-            if ((mConnectionParams != null) && (mFailCause != null)) {
-                if (VDBG) log("DcInactiveState: enter notifyConnectCompleted");
-                notifyConnectCompleted(mConnectionParams, mFailCause);
-            }
-            if (mDisconnectParams != null) {
-                if (VDBG) log("DcInactiveState: enter notifyDisconnectCompleted");
-                notifyDisconnectCompleted(mDisconnectParams, true);
-            }
-            clearSettings();
-        }
-
-        @Override
-        public void exit() {
-            // clear notifications
-            mConnectionParams = null;
-            mFailCause = null;
-            mDisconnectParams = null;
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            boolean retVal;
-
-            switch (msg.what) {
-                case DataConnectionAc.REQ_RESET:
-                    if (DBG) {
-                        log("DcInactiveState: msg.what=RSP_RESET, ignore we're already reset");
-                    }
-                    mAc.replyToMessage(msg, DataConnectionAc.RSP_RESET);
-                    retVal = HANDLED;
-                    break;
-
-                case EVENT_CONNECT:
-                    ConnectionParams cp = (ConnectionParams) msg.obj;
-                    cp.tag = mTag;
-                    if (DBG) {
-                        log("DcInactiveState msg.what=EVENT_CONNECT." + "RefCount = "
-                                + mRefCount);
-                    }
-                    mRefCount = 1;
-                    onConnect(cp);
-                    transitionTo(mActivatingState);
-                    retVal = HANDLED;
-                    break;
-
-                case EVENT_DISCONNECT:
-                    if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT");
-                    notifyDisconnectCompleted((DisconnectParams)msg.obj, false);
-                    retVal = HANDLED;
-                    break;
-
-                case EVENT_DISCONNECT_ALL:
-                    if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT_ALL");
-                    notifyDisconnectCompleted((DisconnectParams)msg.obj, false);
-                    retVal = HANDLED;
-                    break;
-
-                default:
-                    if (VDBG) {
-                        log("DcInactiveState nothandled msg.what=0x" +
-                                Integer.toHexString(msg.what));
-                    }
-                    retVal = NOT_HANDLED;
-                    break;
-            }
-            return retVal;
-        }
-    }
-    private DcInactiveState mInactiveState = new DcInactiveState();
-
-    /**
-     * The state machine is activating a connection.
-     */
-    private class DcActivatingState extends State {
-        @Override
-        public boolean processMessage(Message msg) {
-            boolean retVal;
-            AsyncResult ar;
-            ConnectionParams cp;
-
-            switch (msg.what) {
-                case EVENT_CONNECT:
-                    if (DBG) log("DcActivatingState deferring msg.what=EVENT_CONNECT refCount = "
-                            + mRefCount);
-                    deferMessage(msg);
-                    retVal = HANDLED;
-                    break;
-
-                case EVENT_SETUP_DATA_CONNECTION_DONE:
-                    if (DBG) log("DcActivatingState msg.what=EVENT_SETUP_DATA_CONNECTION_DONE");
-
-                    ar = (AsyncResult) msg.obj;
-                    cp = (ConnectionParams) ar.userObj;
-
-                    DataCallState.SetupResult result = onSetupConnectionCompleted(ar);
-                    if (DBG) log("DcActivatingState onSetupConnectionCompleted result=" + result);
-                    switch (result) {
-                        case SUCCESS:
-                            // All is well
-                            mActiveState.setEnterNotificationParams(cp, FailCause.NONE);
-                            transitionTo(mActiveState);
-                            break;
-                        case ERR_BadCommand:
-                            // Vendor ril rejected the command and didn't connect.
-                            // Transition to inactive but send notifications after
-                            // we've entered the mInactive state.
-                            mInactiveState.setEnterNotificationParams(cp, result.mFailCause, -1);
-                            transitionTo(mInactiveState);
-                            break;
-                        case ERR_UnacceptableParameter:
-                            // The addresses given from the RIL are bad
-                            tearDownData(cp);
-                            transitionTo(mDisconnectingErrorCreatingConnection);
-                            break;
-                        case ERR_GetLastErrorFromRil:
-                            // Request failed and this is an old RIL
-                            phone.mCM.getLastDataCallFailCause(
-                                    obtainMessage(EVENT_GET_LAST_FAIL_DONE, cp));
-                            break;
-                        case ERR_RilError:
-                            // Request failed and mFailCause has the reason
-                            mInactiveState.setEnterNotificationParams(cp, result.mFailCause,
-                                                                      getSuggestedRetryTime(ar));
-                            transitionTo(mInactiveState);
-                            break;
-                        case ERR_Stale:
-                            // Request is stale, ignore.
-                            break;
-                        default:
-                            throw new RuntimeException("Unknown SetupResult, should not happen");
-                    }
-                    retVal = HANDLED;
-                    break;
-
-                case EVENT_GET_LAST_FAIL_DONE:
-                    ar = (AsyncResult) msg.obj;
-                    cp = (ConnectionParams) ar.userObj;
-                    FailCause cause = FailCause.UNKNOWN;
-
-                    if (cp.tag == mTag) {
-                        if (DBG) log("DcActivatingState msg.what=EVENT_GET_LAST_FAIL_DONE");
-                        if (ar.exception == null) {
-                            int rilFailCause = ((int[]) (ar.result))[0];
-                            cause = FailCause.fromInt(rilFailCause);
-                        }
-                        // Transition to inactive but send notifications after
-                        // we've entered the mInactive state.
-                        mInactiveState.setEnterNotificationParams(cp, cause, -1);
-                        transitionTo(mInactiveState);
-                    } else {
-                        if (DBG) {
-                            log("DcActivatingState EVENT_GET_LAST_FAIL_DONE is stale cp.tag="
-                                + cp.tag + ", mTag=" + mTag);
-                        }
-                    }
-
-                    retVal = HANDLED;
-                    break;
-
-                default:
-                    if (VDBG) {
-                        log("DcActivatingState not handled msg.what=0x" +
-                                Integer.toHexString(msg.what));
-                    }
-                    retVal = NOT_HANDLED;
-                    break;
-            }
-            return retVal;
-        }
-    }
-    private DcActivatingState mActivatingState = new DcActivatingState();
-
-    /**
-     * The state machine is connected, expecting an EVENT_DISCONNECT.
-     */
-    private class DcActiveState extends State {
-        private ConnectionParams mConnectionParams = null;
-        private FailCause mFailCause = null;
-
-        public void setEnterNotificationParams(ConnectionParams cp, FailCause cause) {
-            if (VDBG) log("DcInactiveState: setEnterNoticationParams cp,cause");
-            mConnectionParams = cp;
-            mFailCause = cause;
-        }
-
-        @Override public void enter() {
-            /**
-             * Now that we've transitioned to Active state we
-             * can send notifications. Previously we sent the
-             * notifications in the processMessage handler but
-             * that caused a race condition because the synchronous
-             * call to isActive.
-             */
-            if ((mConnectionParams != null) && (mFailCause != null)) {
-                if (VDBG) log("DcActiveState: enter notifyConnectCompleted");
-                notifyConnectCompleted(mConnectionParams, mFailCause);
-            }
-        }
-
-        @Override
-        public void exit() {
-            // clear notifications
-            mConnectionParams = null;
-            mFailCause = null;
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            boolean retVal;
-
-            switch (msg.what) {
-                case EVENT_CONNECT:
-                    mRefCount++;
-                    if (DBG) log("DcActiveState msg.what=EVENT_CONNECT RefCount=" + mRefCount);
-                    if (msg.obj != null) {
-                        notifyConnectCompleted((ConnectionParams) msg.obj, FailCause.NONE);
-                    }
-                    retVal = HANDLED;
-                    break;
-                case EVENT_DISCONNECT:
-                    mRefCount--;
-                    if (DBG) log("DcActiveState msg.what=EVENT_DISCONNECT RefCount=" + mRefCount);
-                    if (mRefCount == 0)
-                    {
-                        DisconnectParams dp = (DisconnectParams) msg.obj;
-                        dp.tag = mTag;
-                        tearDownData(dp);
-                        transitionTo(mDisconnectingState);
-                    } else {
-                        if (msg.obj != null) {
-                            notifyDisconnectCompleted((DisconnectParams) msg.obj, false);
-                        }
-                    }
-                    retVal = HANDLED;
-                    break;
-
-                case EVENT_DISCONNECT_ALL:
-                    if (DBG) {
-                        log("DcActiveState msg.what=EVENT_DISCONNECT_ALL RefCount=" + mRefCount);
-                    }
-                    mRefCount = 0;
-                    DisconnectParams dp = (DisconnectParams) msg.obj;
-                    dp.tag = mTag;
-                    tearDownData(dp);
-                    transitionTo(mDisconnectingState);
-                    retVal = HANDLED;
-                    break;
-
-                default:
-                    if (VDBG) {
-                        log("DcActiveState not handled msg.what=0x" +
-                                Integer.toHexString(msg.what));
-                    }
-                    retVal = NOT_HANDLED;
-                    break;
-            }
-            return retVal;
-        }
-    }
-    private DcActiveState mActiveState = new DcActiveState();
-
-    /**
-     * The state machine is disconnecting.
-     */
-    private class DcDisconnectingState extends State {
-        @Override
-        public boolean processMessage(Message msg) {
-            boolean retVal;
-
-            switch (msg.what) {
-                case EVENT_CONNECT:
-                    if (DBG) log("DcDisconnectingState msg.what=EVENT_CONNECT. Defer. RefCount = "
-                            + mRefCount);
-                    deferMessage(msg);
-                    retVal = HANDLED;
-                    break;
-
-                case EVENT_DEACTIVATE_DONE:
-                    if (DBG) log("DcDisconnectingState msg.what=EVENT_DEACTIVATE_DONE");
-                    AsyncResult ar = (AsyncResult) msg.obj;
-                    DisconnectParams dp = (DisconnectParams) ar.userObj;
-                    if (dp.tag == mTag) {
-                        // Transition to inactive but send notifications after
-                        // we've entered the mInactive state.
-                        mInactiveState.setEnterNotificationParams((DisconnectParams) ar.userObj);
-                        transitionTo(mInactiveState);
-                    } else {
-                        if (DBG) log("DcDisconnectState EVENT_DEACTIVATE_DONE stale dp.tag="
-                                + dp.tag + " mTag=" + mTag);
-                    }
-                    retVal = HANDLED;
-                    break;
-
-                default:
-                    if (VDBG) {
-                        log("DcDisconnectingState not handled msg.what=0x" +
-                                Integer.toHexString(msg.what));
-                    }
-                    retVal = NOT_HANDLED;
-                    break;
-            }
-            return retVal;
-        }
-    }
-    private DcDisconnectingState mDisconnectingState = new DcDisconnectingState();
-
-    /**
-     * The state machine is disconnecting after an creating a connection.
-     */
-    private class DcDisconnectionErrorCreatingConnection extends State {
-        @Override
-        public boolean processMessage(Message msg) {
-            boolean retVal;
-
-            switch (msg.what) {
-                case EVENT_DEACTIVATE_DONE:
-                    AsyncResult ar = (AsyncResult) msg.obj;
-                    ConnectionParams cp = (ConnectionParams) ar.userObj;
-                    if (cp.tag == mTag) {
-                        if (DBG) {
-                            log("DcDisconnectionErrorCreatingConnection" +
-                                " msg.what=EVENT_DEACTIVATE_DONE");
-                        }
-
-                        // Transition to inactive but send notifications after
-                        // we've entered the mInactive state.
-                        mInactiveState.setEnterNotificationParams(cp,
-                                FailCause.UNACCEPTABLE_NETWORK_PARAMETER, -1);
-                        transitionTo(mInactiveState);
-                    } else {
-                        if (DBG) {
-                            log("DcDisconnectionErrorCreatingConnection EVENT_DEACTIVATE_DONE" +
-                                    " stale dp.tag=" + cp.tag + ", mTag=" + mTag);
-                        }
-                    }
-                    retVal = HANDLED;
-                    break;
-
-                default:
-                    if (VDBG) {
-                        log("DcDisconnectionErrorCreatingConnection not handled msg.what=0x"
-                                + Integer.toHexString(msg.what));
-                    }
-                    retVal = NOT_HANDLED;
-                    break;
-            }
-            return retVal;
-        }
-    }
-    private DcDisconnectionErrorCreatingConnection mDisconnectingErrorCreatingConnection =
-                new DcDisconnectionErrorCreatingConnection();
-
-    // ******* public interface
-
-    /**
-     * Bring up a connection to the apn and return an AsyncResult in onCompletedMsg.
-     * Used for cellular networks that use Acesss Point Names (APN) such
-     * as GSM networks.
-     *
-     * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
-     *        With AsyncResult.userObj set to the original msg.obj,
-     *        AsyncResult.result = FailCause and AsyncResult.exception = Exception().
-     * @param apn is the Access Point Name to bring up a connection to
-     */
-    public void bringUp(Message onCompletedMsg, ApnSetting apn) {
-        sendMessage(obtainMessage(EVENT_CONNECT, new ConnectionParams(apn, onCompletedMsg)));
-    }
-
-    /**
-     * Tear down the connection through the apn on the network.
-     *
-     * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
-     *        With AsyncResult.userObj set to the original msg.obj.
-     */
-    public void tearDown(String reason, Message onCompletedMsg) {
-        sendMessage(obtainMessage(EVENT_DISCONNECT, new DisconnectParams(reason, onCompletedMsg)));
-    }
-
-    /**
-     * Tear down the connection through the apn on the network.  Ignores refcount and
-     * and always tears down.
-     *
-     * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
-     *        With AsyncResult.userObj set to the original msg.obj.
-     */
-    public void tearDownAll(String reason, Message onCompletedMsg) {
-        sendMessage(obtainMessage(EVENT_DISCONNECT_ALL,
-                new DisconnectParams(reason, onCompletedMsg)));
-    }
-
-    /**
-     * @return the string for msg.what as our info.
-     */
-    @Override
-    protected String getMessageInfo(Message msg) {
-        String info = null;
-        info = cmdToString(msg.what);
-        if (info == null) {
-            info = DataConnectionAc.cmdToString(msg.what);
-        }
-        return info;
-    }
-
-    /**
-     * Dump the current state.
-     *
-     * @param fd
-     * @param pw
-     * @param args
-     */
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.print("DataConnection ");
-        super.dump(fd, pw, args);
-        pw.println(" mApnList=" + mApnList);
-        pw.flush();
-        pw.println(" mDataConnectionTracker=" + mDataConnectionTracker);
-        pw.println(" mApn=" + mApn);
-        pw.println(" mTag=" + mTag);
-        pw.flush();
-        pw.println(" phone=" + phone);
-        pw.println(" mRilVersion=" + mRilVersion);
-        pw.println(" cid=" + cid);
-        pw.flush();
-        pw.println(" mLinkProperties=" + mLinkProperties);
-        pw.flush();
-        pw.println(" mCapabilities=" + mCapabilities);
-        pw.println(" createTime=" + TimeUtils.logTimeOfDay(createTime));
-        pw.println(" lastFailTime=" + TimeUtils.logTimeOfDay(lastFailTime));
-        pw.println(" lastFailCause=" + lastFailCause);
-        pw.flush();
-        pw.println(" mRetryOverride=" + mRetryOverride);
-        pw.println(" mRefCount=" + mRefCount);
-        pw.println(" userData=" + userData);
-        if (mRetryMgr != null) pw.println(" " + mRetryMgr);
-        pw.flush();
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionAc.java b/telephony/java/com/android/internal/telephony/DataConnectionAc.java
deleted file mode 100644
index a24414f..0000000
--- a/telephony/java/com/android/internal/telephony/DataConnectionAc.java
+++ /dev/null
@@ -1,591 +0,0 @@
-/*
- * Copyright (C) 2011 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.internal.telephony;
-
-import com.android.internal.telephony.DataConnection.UpdateLinkPropertyResult;
-import com.android.internal.util.AsyncChannel;
-import com.android.internal.util.Protocol;
-
-import android.app.PendingIntent;
-import android.net.LinkCapabilities;
-import android.net.LinkProperties;
-import android.net.ProxyProperties;
-import android.os.Message;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * AsyncChannel to a DataConnection
- */
-public class DataConnectionAc extends AsyncChannel {
-    private static final boolean DBG = false;
-    private String mLogTag;
-
-    public DataConnection dataConnection;
-
-    public static final int BASE = Protocol.BASE_DATA_CONNECTION_AC;
-
-    public static final int REQ_IS_INACTIVE = BASE + 0;
-    public static final int RSP_IS_INACTIVE = BASE + 1;
-
-    public static final int REQ_GET_CID = BASE + 2;
-    public static final int RSP_GET_CID = BASE + 3;
-
-    public static final int REQ_GET_APNSETTING = BASE + 4;
-    public static final int RSP_GET_APNSETTING = BASE + 5;
-
-    public static final int REQ_GET_LINK_PROPERTIES = BASE + 6;
-    public static final int RSP_GET_LINK_PROPERTIES = BASE + 7;
-
-    public static final int REQ_SET_LINK_PROPERTIES_HTTP_PROXY = BASE + 8;
-    public static final int RSP_SET_LINK_PROPERTIES_HTTP_PROXY = BASE + 9;
-
-    public static final int REQ_GET_LINK_CAPABILITIES = BASE + 10;
-    public static final int RSP_GET_LINK_CAPABILITIES = BASE + 11;
-
-    public static final int REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE = BASE + 12;
-    public static final int RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE = BASE + 13;
-
-    public static final int REQ_RESET = BASE + 14;
-    public static final int RSP_RESET = BASE + 15;
-
-    public static final int REQ_GET_REFCOUNT = BASE + 16;
-    public static final int RSP_GET_REFCOUNT = BASE + 17;
-
-    public static final int REQ_ADD_APNCONTEXT = BASE + 18;
-    public static final int RSP_ADD_APNCONTEXT = BASE + 19;
-
-    public static final int REQ_REMOVE_APNCONTEXT = BASE + 20;
-    public static final int RSP_REMOVE_APNCONTEXT = BASE + 21;
-
-    public static final int REQ_GET_APNCONTEXT_LIST = BASE + 22;
-    public static final int RSP_GET_APNCONTEXT_LIST = BASE + 23;
-
-    public static final int REQ_SET_RECONNECT_INTENT = BASE + 24;
-    public static final int RSP_SET_RECONNECT_INTENT = BASE + 25;
-
-    public static final int REQ_GET_RECONNECT_INTENT = BASE + 26;
-    public static final int RSP_GET_RECONNECT_INTENT = BASE + 27;
-
-    private static final int CMD_TO_STRING_COUNT = RSP_GET_RECONNECT_INTENT - BASE + 1;
-    private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
-    static {
-        sCmdToString[REQ_IS_INACTIVE - BASE] = "REQ_IS_INACTIVE";
-        sCmdToString[RSP_IS_INACTIVE - BASE] = "RSP_IS_INACTIVE";
-        sCmdToString[REQ_GET_CID - BASE] = "REQ_GET_CID";
-        sCmdToString[RSP_GET_CID - BASE] = "RSP_GET_CID";
-        sCmdToString[REQ_GET_APNSETTING - BASE] = "REQ_GET_APNSETTING";
-        sCmdToString[RSP_GET_APNSETTING - BASE] = "RSP_GET_APNSETTING";
-        sCmdToString[REQ_GET_LINK_PROPERTIES - BASE] = "REQ_GET_LINK_PROPERTIES";
-        sCmdToString[RSP_GET_LINK_PROPERTIES - BASE] = "RSP_GET_LINK_PROPERTIES";
-        sCmdToString[REQ_SET_LINK_PROPERTIES_HTTP_PROXY - BASE] =
-                "REQ_SET_LINK_PROPERTIES_HTTP_PROXY";
-        sCmdToString[RSP_SET_LINK_PROPERTIES_HTTP_PROXY - BASE] =
-                "RSP_SET_LINK_PROPERTIES_HTTP_PROXY";
-        sCmdToString[REQ_GET_LINK_CAPABILITIES - BASE] = "REQ_GET_LINK_CAPABILITIES";
-        sCmdToString[RSP_GET_LINK_CAPABILITIES - BASE] = "RSP_GET_LINK_CAPABILITIES";
-        sCmdToString[REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE - BASE] =
-                "REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE";
-        sCmdToString[RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE - BASE] =
-                "RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE";
-        sCmdToString[REQ_RESET - BASE] = "REQ_RESET";
-        sCmdToString[RSP_RESET - BASE] = "RSP_RESET";
-        sCmdToString[REQ_GET_REFCOUNT - BASE] = "REQ_GET_REFCOUNT";
-        sCmdToString[RSP_GET_REFCOUNT - BASE] = "RSP_GET_REFCOUNT";
-        sCmdToString[REQ_ADD_APNCONTEXT - BASE] = "REQ_ADD_APNCONTEXT";
-        sCmdToString[RSP_ADD_APNCONTEXT - BASE] = "RSP_ADD_APNCONTEXT";
-        sCmdToString[REQ_REMOVE_APNCONTEXT - BASE] = "REQ_REMOVE_APNCONTEXT";
-        sCmdToString[RSP_REMOVE_APNCONTEXT - BASE] = "RSP_REMOVE_APNCONTEXT";
-        sCmdToString[REQ_GET_APNCONTEXT_LIST - BASE] = "REQ_GET_APNCONTEXT_LIST";
-        sCmdToString[RSP_GET_APNCONTEXT_LIST - BASE] = "RSP_GET_APNCONTEXT_LIST";
-        sCmdToString[REQ_SET_RECONNECT_INTENT - BASE] = "REQ_SET_RECONNECT_INTENT";
-        sCmdToString[RSP_SET_RECONNECT_INTENT - BASE] = "RSP_SET_RECONNECT_INTENT";
-        sCmdToString[REQ_GET_RECONNECT_INTENT - BASE] = "REQ_GET_RECONNECT_INTENT";
-        sCmdToString[RSP_GET_RECONNECT_INTENT - BASE] = "RSP_GET_RECONNECT_INTENT";
-    }
-    protected static String cmdToString(int cmd) {
-        cmd -= BASE;
-        if ((cmd >= 0) && (cmd < sCmdToString.length)) {
-            return sCmdToString[cmd];
-        } else {
-            return AsyncChannel.cmdToString(cmd + BASE);
-        }
-    }
-
-    /**
-     * enum used to notify action taken or necessary to be
-     * taken after the link property is changed.
-     */
-    public enum LinkPropertyChangeAction {
-        NONE, CHANGED, RESET;
-
-        public static LinkPropertyChangeAction fromInt(int value) {
-            if (value == NONE.ordinal()) {
-                return NONE;
-            } else if (value == CHANGED.ordinal()) {
-                return CHANGED;
-            } else if (value == RESET.ordinal()) {
-                return RESET;
-            } else {
-                throw new RuntimeException("LinkPropertyChangeAction.fromInt: bad value=" + value);
-            }
-        }
-    }
-
-    public DataConnectionAc(DataConnection dc, String logTag) {
-        dataConnection = dc;
-        mLogTag = logTag;
-    }
-
-    /**
-     * Request if the state machine is in the inactive state.
-     * Response {@link #rspIsInactive}
-     */
-    public void reqIsInactive() {
-        sendMessage(REQ_IS_INACTIVE);
-        if (DBG) log("reqIsInactive");
-    }
-
-    /**
-     * Evaluate RSP_IS_INACTIVE.
-     *
-     * @return true if the state machine is in the inactive state.
-     */
-    public boolean rspIsInactive(Message response) {
-        boolean retVal = response.arg1 == 1;
-        if (DBG) log("rspIsInactive=" + retVal);
-        return retVal;
-    }
-
-    /**
-     * @return true if the state machine is in the inactive state.
-     */
-    public boolean isInactiveSync() {
-        Message response = sendMessageSynchronously(REQ_IS_INACTIVE);
-        if ((response != null) && (response.what == RSP_IS_INACTIVE)) {
-            return rspIsInactive(response);
-        } else {
-            log("rspIsInactive error response=" + response);
-            return false;
-        }
-    }
-
-    /**
-     * Request the Connection ID.
-     * Response {@link #rspCid}
-     */
-    public void reqCid() {
-        sendMessage(REQ_GET_CID);
-        if (DBG) log("reqCid");
-    }
-
-    /**
-     * Evaluate a RSP_GET_CID message and return the cid.
-     *
-     * @param response Message
-     * @return connection id or -1 if an error
-     */
-    public int rspCid(Message response) {
-        int retVal = response.arg1;
-        if (DBG) log("rspCid=" + retVal);
-        return retVal;
-    }
-
-    /**
-     * @return connection id or -1 if an error
-     */
-    public int getCidSync() {
-        Message response = sendMessageSynchronously(REQ_GET_CID);
-        if ((response != null) && (response.what == RSP_GET_CID)) {
-            return rspCid(response);
-        } else {
-            log("rspCid error response=" + response);
-            return -1;
-        }
-    }
-
-    /**
-     * Request the Reference Count.
-     * Response {@link #rspRefCount}
-     */
-    public void reqRefCount() {
-        sendMessage(REQ_GET_REFCOUNT);
-        if (DBG) log("reqRefCount");
-    }
-
-    /**
-     * Evaluate a RSP_GET_REFCOUNT message and return the refCount.
-     *
-     * @param response Message
-     * @return ref count or -1 if an error
-     */
-    public int rspRefCount(Message response) {
-        int retVal = response.arg1;
-        if (DBG) log("rspRefCount=" + retVal);
-        return retVal;
-    }
-
-    /**
-     * @return connection id or -1 if an error
-     */
-    public int getRefCountSync() {
-        Message response = sendMessageSynchronously(REQ_GET_REFCOUNT);
-        if ((response != null) && (response.what == RSP_GET_REFCOUNT)) {
-            return rspRefCount(response);
-        } else {
-            log("rspRefCount error response=" + response);
-            return -1;
-        }
-    }
-
-    /**
-     * Request the connections ApnSetting.
-     * Response {@link #rspApnSetting}
-     */
-    public void reqApnSetting() {
-        sendMessage(REQ_GET_APNSETTING);
-        if (DBG) log("reqApnSetting");
-    }
-
-    /**
-     * Evaluate a RSP_APN_SETTING message and return the ApnSetting.
-     *
-     * @param response Message
-     * @return ApnSetting, maybe null
-     */
-    public ApnSetting rspApnSetting(Message response) {
-        ApnSetting retVal = (ApnSetting) response.obj;
-        if (DBG) log("rspApnSetting=" + retVal);
-        return retVal;
-    }
-
-    /**
-     * Get the connections ApnSetting.
-     *
-     * @return ApnSetting or null if an error
-     */
-    public ApnSetting getApnSettingSync() {
-        Message response = sendMessageSynchronously(REQ_GET_APNSETTING);
-        if ((response != null) && (response.what == RSP_GET_APNSETTING)) {
-            return rspApnSetting(response);
-        } else {
-            log("getApnSetting error response=" + response);
-            return null;
-        }
-    }
-
-    /**
-     * Request the connections LinkProperties.
-     * Response {@link #rspLinkProperties}
-     */
-    public void reqLinkProperties() {
-        sendMessage(REQ_GET_LINK_PROPERTIES);
-        if (DBG) log("reqLinkProperties");
-    }
-
-    /**
-     * Evaluate RSP_GET_LINK_PROPERTIES
-     *
-     * @param response
-     * @return LinkProperties, maybe null.
-     */
-    public LinkProperties rspLinkProperties(Message response) {
-        LinkProperties retVal = (LinkProperties) response.obj;
-        if (DBG) log("rspLinkProperties=" + retVal);
-        return retVal;
-    }
-
-    /**
-     * Get the connections LinkProperties.
-     *
-     * @return LinkProperties or null if an error
-     */
-    public LinkProperties getLinkPropertiesSync() {
-        Message response = sendMessageSynchronously(REQ_GET_LINK_PROPERTIES);
-        if ((response != null) && (response.what == RSP_GET_LINK_PROPERTIES)) {
-            return rspLinkProperties(response);
-        } else {
-            log("getLinkProperties error response=" + response);
-            return null;
-        }
-    }
-
-    /**
-     * Request setting the connections LinkProperties.HttpProxy.
-     * Response RSP_SET_LINK_PROPERTIES when complete.
-     */
-    public void reqSetLinkPropertiesHttpProxy(ProxyProperties proxy) {
-        sendMessage(REQ_SET_LINK_PROPERTIES_HTTP_PROXY, proxy);
-        if (DBG) log("reqSetLinkPropertiesHttpProxy proxy=" + proxy);
-    }
-
-    /**
-     * Set the connections LinkProperties.HttpProxy
-     */
-    public void setLinkPropertiesHttpProxySync(ProxyProperties proxy) {
-        Message response =
-            sendMessageSynchronously(REQ_SET_LINK_PROPERTIES_HTTP_PROXY, proxy);
-        if ((response != null) && (response.what == RSP_SET_LINK_PROPERTIES_HTTP_PROXY)) {
-            if (DBG) log("setLinkPropertiesHttpPoxy ok");
-        } else {
-            log("setLinkPropertiesHttpPoxy error response=" + response);
-        }
-    }
-
-    /**
-     * Request update LinkProperties from DataCallState
-     * Response {@link #rspUpdateLinkPropertiesDataCallState}
-     */
-    public void reqUpdateLinkPropertiesDataCallState(DataCallState newState) {
-        sendMessage(REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE, newState);
-        if (DBG) log("reqUpdateLinkPropertiesDataCallState");
-    }
-
-    public UpdateLinkPropertyResult rspUpdateLinkPropertiesDataCallState(Message response) {
-        UpdateLinkPropertyResult retVal = (UpdateLinkPropertyResult)response.obj;
-        if (DBG) log("rspUpdateLinkPropertiesState: retVal=" + retVal);
-        return retVal;
-    }
-
-    /**
-     * Update link properties in the data connection
-     *
-     * @return the removed and added addresses.
-     */
-    public UpdateLinkPropertyResult updateLinkPropertiesDataCallStateSync(DataCallState newState) {
-        Message response =
-            sendMessageSynchronously(REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE, newState);
-        if ((response != null) &&
-            (response.what == RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE)) {
-            return rspUpdateLinkPropertiesDataCallState(response);
-        } else {
-            log("getLinkProperties error response=" + response);
-            return new UpdateLinkPropertyResult(new LinkProperties());
-        }
-    }
-
-    /**
-     * Request the connections LinkCapabilities.
-     * Response {@link #rspLinkCapabilities}
-     */
-    public void reqLinkCapabilities() {
-        sendMessage(REQ_GET_LINK_CAPABILITIES);
-        if (DBG) log("reqLinkCapabilities");
-    }
-
-    /**
-     * Evaluate RSP_GET_LINK_CAPABILITIES
-     *
-     * @param response
-     * @return LinkCapabilites, maybe null.
-     */
-    public LinkCapabilities rspLinkCapabilities(Message response) {
-        LinkCapabilities retVal = (LinkCapabilities) response.obj;
-        if (DBG) log("rspLinkCapabilities=" + retVal);
-        return retVal;
-    }
-
-    /**
-     * Get the connections LinkCapabilities.
-     *
-     * @return LinkCapabilities or null if an error
-     */
-    public LinkCapabilities getLinkCapabilitiesSync() {
-        Message response = sendMessageSynchronously(REQ_GET_LINK_CAPABILITIES);
-        if ((response != null) && (response.what == RSP_GET_LINK_CAPABILITIES)) {
-            return rspLinkCapabilities(response);
-        } else {
-            log("getLinkCapabilities error response=" + response);
-            return null;
-        }
-    }
-
-    /**
-     * Request the connections LinkCapabilities.
-     * Response RSP_RESET when complete
-     */
-    public void reqReset() {
-        sendMessage(REQ_RESET);
-        if (DBG) log("reqReset");
-    }
-
-    /**
-     * Reset the connection and wait for it to complete.
-     */
-    public void resetSync() {
-        Message response = sendMessageSynchronously(REQ_RESET);
-        if ((response != null) && (response.what == RSP_RESET)) {
-            if (DBG) log("restSync ok");
-        } else {
-            log("restSync error response=" + response);
-        }
-    }
-
-    /**
-     * Request to add ApnContext association.
-     * Response RSP_ADD_APNCONTEXT when complete.
-     */
-    public void reqAddApnContext(ApnContext apnContext) {
-        Message response = sendMessageSynchronously(REQ_ADD_APNCONTEXT, apnContext);
-        if (DBG) log("reqAddApnContext");
-    }
-
-    /**
-     * Add ApnContext association synchronoulsy.
-     *
-     * @param ApnContext to associate
-     */
-    public void addApnContextSync(ApnContext apnContext) {
-        Message response = sendMessageSynchronously(REQ_ADD_APNCONTEXT, apnContext);
-        if ((response != null) && (response.what == RSP_ADD_APNCONTEXT)) {
-            if (DBG) log("addApnContext ok");
-        } else {
-            log("addApnContext error response=" + response);
-        }
-    }
-
-    /**
-     * Request to remove ApnContext association.
-     * Response RSP_REMOVE_APNCONTEXT when complete.
-     */
-    public void reqRemomveApnContext(ApnContext apnContext) {
-        Message response = sendMessageSynchronously(REQ_REMOVE_APNCONTEXT, apnContext);
-        if (DBG) log("reqRemomveApnContext");
-    }
-
-    /**
-     * Remove ApnContext associateion.
-     *
-     * @param ApnContext to dissociate
-     */
-    public void removeApnContextSync(ApnContext apnContext) {
-        Message response = sendMessageSynchronously(REQ_REMOVE_APNCONTEXT, apnContext);
-        if ((response != null) && (response.what == RSP_REMOVE_APNCONTEXT)) {
-            if (DBG) log("removeApnContext ok");
-        } else {
-            log("removeApnContext error response=" + response);
-        }
-    }
-
-    /**
-     * Request to retrive ApnContext List associated with DC.
-     * Response RSP_GET_APNCONTEXT_LIST when complete.
-     */
-    public void reqGetApnList(ApnContext apnContext) {
-        Message response = sendMessageSynchronously(REQ_GET_APNCONTEXT_LIST);
-        if (DBG) log("reqGetApnList");
-    }
-
-    /**
-     * Retrieve Collection of ApnContext from the response message.
-     *
-     * @param Message sent from DC in response to REQ_GET_APNCONTEXT_LIST.
-     * @return Collection of ApnContext
-     */
-    public Collection<ApnContext> rspApnList(Message response) {
-        Collection<ApnContext> retVal = (Collection<ApnContext>)response.obj;
-        if (retVal == null) retVal = new ArrayList<ApnContext>();
-        return retVal;
-    }
-
-    /**
-     * Retrieve collection of ApnContext currently associated with
-     * the DataConnectionA synchronously.
-     *
-     * @return Collection of ApnContext
-     */
-    public Collection<ApnContext> getApnListSync() {
-        Message response = sendMessageSynchronously(REQ_GET_APNCONTEXT_LIST);
-        if ((response != null) && (response.what == RSP_GET_APNCONTEXT_LIST)) {
-            if (DBG) log("getApnList ok");
-            return rspApnList(response);
-        } else {
-            log("getApnList error response=" + response);
-            // return dummy list with no entry
-            return new ArrayList<ApnContext>();
-        }
-    }
-
-    /**
-     * Request to set Pending ReconnectIntent to DC.
-     * Response RSP_SET_RECONNECT_INTENT when complete.
-     */
-    public void reqSetReconnectIntent(PendingIntent intent) {
-        Message response = sendMessageSynchronously(REQ_SET_RECONNECT_INTENT, intent);
-        if (DBG) log("reqSetReconnectIntent");
-    }
-
-    /**
-     * Set pending reconnect intent to DC synchronously.
-     *
-     * @param PendingIntent to set.
-     */
-    public void setReconnectIntentSync(PendingIntent intent) {
-        Message response = sendMessageSynchronously(REQ_SET_RECONNECT_INTENT, intent);
-        if ((response != null) && (response.what == RSP_SET_RECONNECT_INTENT)) {
-            if (DBG) log("setReconnectIntent ok");
-        } else {
-            log("setReconnectIntent error response=" + response);
-        }
-    }
-
-    /**
-     * Request to get Pending ReconnectIntent to DC.
-     * Response RSP_GET_RECONNECT_INTENT when complete.
-     */
-    public void reqGetReconnectIntent() {
-        Message response = sendMessageSynchronously(REQ_GET_RECONNECT_INTENT);
-        if (DBG) log("reqGetReconnectIntent");
-    }
-
-    /**
-     * Retrieve reconnect intent from response message from DC.
-     *
-     * @param Message which contains the reconnect intent.
-     * @return PendingIntent from the response.
-     */
-    public PendingIntent rspReconnectIntent(Message response) {
-        PendingIntent retVal = (PendingIntent) response.obj;
-        return retVal;
-    }
-
-    /**
-     * Retrieve reconnect intent currently set in DC synchronously.
-     *
-     * @return PendingIntent reconnect intent current ly set in DC
-     */
-    public PendingIntent getReconnectIntentSync() {
-        Message response = sendMessageSynchronously(REQ_GET_RECONNECT_INTENT);
-        if ((response != null) && (response.what == RSP_GET_RECONNECT_INTENT)) {
-            if (DBG) log("getReconnectIntent ok");
-            return rspReconnectIntent(response);
-        } else {
-            log("getReconnectIntent error response=" + response);
-            return null;
-        }
-    }
-
-    @Override
-    public String toString() {
-        return dataConnection.getName();
-    }
-
-    private void log(String s) {
-        android.util.Log.d(mLogTag, "DataConnectionAc " + s);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
deleted file mode 100644
index 0dee7a1..0000000
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ /dev/null
@@ -1,1289 +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.internal.telephony;
-
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.database.ContentObserver;
-import android.net.LinkCapabilities;
-import android.net.LinkProperties;
-import android.net.NetworkInfo;
-import android.net.TrafficStats;
-import android.net.wifi.WifiManager;
-import android.os.AsyncResult;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.preference.PreferenceManager;
-import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
-import android.telephony.ServiceState;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.R;
-import com.android.internal.telephony.DataConnection.FailCause;
-import com.android.internal.util.AsyncChannel;
-import com.android.internal.util.Protocol;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * {@hide}
- */
-public abstract class DataConnectionTracker extends Handler {
-    protected static final boolean DBG = true;
-    protected static final boolean VDBG = false;
-
-    /**
-     * IDLE: ready to start data connection setup, default state
-     * INITING: state of issued setupDefaultPDP() but not finish yet
-     * CONNECTING: state of issued startPppd() but not finish yet
-     * SCANNING: data connection fails with one apn but other apns are available
-     *           ready to start data connection on other apns (before INITING)
-     * CONNECTED: IP connection is setup
-     * DISCONNECTING: Connection.disconnect() has been called, but PDP
-     *                context is not yet deactivated
-     * FAILED: data connection fail for all apns settings
-     *
-     * getDataConnectionState() maps State to DataState
-     *      FAILED or IDLE : DISCONNECTED
-     *      INITING or CONNECTING or SCANNING: CONNECTING
-     *      CONNECTED : CONNECTED or DISCONNECTING
-     */
-    public enum State {
-        IDLE,
-        INITING,
-        CONNECTING,
-        SCANNING,
-        CONNECTED,
-        DISCONNECTING,
-        FAILED
-    }
-
-    public enum Activity {
-        NONE,
-        DATAIN,
-        DATAOUT,
-        DATAINANDOUT,
-        DORMANT
-    }
-
-    public static String ACTION_DATA_CONNECTION_TRACKER_MESSENGER =
-        "com.android.internal.telephony";
-    public static String EXTRA_MESSENGER = "EXTRA_MESSENGER";
-
-    /***** Event Codes *****/
-    protected static final int BASE = Protocol.BASE_DATA_CONNECTION_TRACKER;
-    protected static final int EVENT_DATA_SETUP_COMPLETE = BASE + 0;
-    protected static final int EVENT_RADIO_AVAILABLE = BASE + 1;
-    protected static final int EVENT_RECORDS_LOADED = BASE + 2;
-    protected static final int EVENT_TRY_SETUP_DATA = BASE + 3;
-    protected static final int EVENT_DATA_STATE_CHANGED = BASE + 4;
-    protected static final int EVENT_POLL_PDP = BASE + 5;
-    protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = BASE + 6;
-    protected static final int EVENT_VOICE_CALL_STARTED = BASE + 7;
-    protected static final int EVENT_VOICE_CALL_ENDED = BASE + 8;
-    protected static final int EVENT_DATA_CONNECTION_DETACHED = BASE + 9;
-    protected static final int EVENT_LINK_STATE_CHANGED = BASE + 10;
-    protected static final int EVENT_ROAMING_ON = BASE + 11;
-    protected static final int EVENT_ROAMING_OFF = BASE + 12;
-    protected static final int EVENT_ENABLE_NEW_APN = BASE + 13;
-    protected static final int EVENT_RESTORE_DEFAULT_APN = BASE + 14;
-    protected static final int EVENT_DISCONNECT_DONE = BASE + 15;
-    protected static final int EVENT_DATA_CONNECTION_ATTACHED = BASE + 16;
-    protected static final int EVENT_DATA_STALL_ALARM = BASE + 17;
-    protected static final int EVENT_DO_RECOVERY = BASE + 18;
-    protected static final int EVENT_APN_CHANGED = BASE + 19;
-    protected static final int EVENT_CDMA_DATA_DETACHED = BASE + 20;
-    protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = BASE + 21;
-    protected static final int EVENT_PS_RESTRICT_ENABLED = BASE + 22;
-    protected static final int EVENT_PS_RESTRICT_DISABLED = BASE + 23;
-    public static final int EVENT_CLEAN_UP_CONNECTION = BASE + 24;
-    protected static final int EVENT_CDMA_OTA_PROVISION = BASE + 25;
-    protected static final int EVENT_RESTART_RADIO = BASE + 26;
-    protected static final int EVENT_SET_INTERNAL_DATA_ENABLE = BASE + 27;
-    protected static final int EVENT_RESET_DONE = BASE + 28;
-    public static final int CMD_SET_USER_DATA_ENABLE = BASE + 29;
-    public static final int EVENT_CLEAN_UP_ALL_CONNECTIONS = BASE + 30;
-    public static final int CMD_SET_DEPENDENCY_MET = BASE + 31;
-    public static final int CMD_SET_POLICY_DATA_ENABLE = BASE + 32;
-
-    /***** Constants *****/
-
-    protected static final int APN_INVALID_ID = -1;
-    protected static final int APN_DEFAULT_ID = 0;
-    protected static final int APN_MMS_ID = 1;
-    protected static final int APN_SUPL_ID = 2;
-    protected static final int APN_DUN_ID = 3;
-    protected static final int APN_HIPRI_ID = 4;
-    protected static final int APN_IMS_ID = 5;
-    protected static final int APN_FOTA_ID = 6;
-    protected static final int APN_CBS_ID = 7;
-    protected static final int APN_NUM_TYPES = 8;
-
-    public static final int DISABLED = 0;
-    public static final int ENABLED = 1;
-
-    public static final String APN_TYPE_KEY = "apnType";
-
-    /** Delay between APN attempts.
-        Note the property override mechanism is there just for testing purpose only. */
-    protected static final int APN_DELAY_MILLIS =
-                                SystemProperties.getInt("persist.radio.apn_delay", 5000);
-
-    protected Object mDataEnabledLock = new Object();
-
-    // responds to the setInternalDataEnabled call - used internally to turn off data
-    // for example during emergency calls
-    protected boolean mInternalDataEnabled = true;
-
-    // responds to public (user) API to enable/disable data use
-    // independent of mInternalDataEnabled and requests for APN access
-    // persisted
-    protected boolean mUserDataEnabled = true;
-
-    // TODO: move away from static state once 5587429 is fixed.
-    protected static boolean sPolicyDataEnabled = true;
-
-    private boolean[] dataEnabled = new boolean[APN_NUM_TYPES];
-
-    private int enabledCount = 0;
-
-    /* Currently requested APN type (TODO: This should probably be a parameter not a member) */
-    protected String mRequestedApnType = Phone.APN_TYPE_DEFAULT;
-
-    /** Retry configuration: A doubling of retry times from 5secs to 30minutes */
-    protected static final String DEFAULT_DATA_RETRY_CONFIG = "default_randomization=2000,"
-        + "5000,10000,20000,40000,80000:5000,160000:5000,"
-        + "320000:5000,640000:5000,1280000:5000,1800000:5000";
-
-    /** Retry configuration for secondary networks: 4 tries in 20 sec */
-    protected static final String SECONDARY_DATA_RETRY_CONFIG =
-            "max_retries=3, 5000, 5000, 5000";
-
-    /** Slow poll when attempting connection recovery. */
-    protected static final int POLL_NETSTAT_SLOW_MILLIS = 5000;
-    /** Default max failure count before attempting to network re-registration. */
-    protected static final int DEFAULT_MAX_PDP_RESET_FAIL = 3;
-
-    /**
-     * After detecting a potential connection problem, this is the max number
-     * of subsequent polls before attempting recovery.
-     */
-    protected static final int NO_RECV_POLL_LIMIT = 24;
-    // 1 sec. default polling interval when screen is on.
-    protected static final int POLL_NETSTAT_MILLIS = 1000;
-    // 10 min. default polling interval when screen is off.
-    protected static final int POLL_NETSTAT_SCREEN_OFF_MILLIS = 1000*60*10;
-    // 2 min for round trip time
-    protected static final int POLL_LONGEST_RTT = 120 * 1000;
-    // Default sent packets without ack which triggers initial recovery steps
-    protected static final int NUMBER_SENT_PACKETS_OF_HANG = 10;
-    // how long to wait before switching back to default APN
-    protected static final int RESTORE_DEFAULT_APN_DELAY = 1 * 60 * 1000;
-    // system property that can override the above value
-    protected static final String APN_RESTORE_DELAY_PROP_NAME = "android.telephony.apn-restore";
-    // represents an invalid IP address
-    protected static final String NULL_IP = "0.0.0.0";
-
-    // Default for the data stall alarm while non-aggressive stall detection
-    protected static final int DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60 * 6;
-    // Default for the data stall alarm for aggressive stall detection
-    protected static final int DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60;
-    // If attempt is less than this value we're doing first level recovery
-    protected static final int DATA_STALL_NO_RECV_POLL_LIMIT = 1;
-    // Tag for tracking stale alarms
-    protected static final String DATA_STALL_ALARM_TAG_EXTRA = "data.stall.alram.tag";
-
-    // TODO: See if we can remove INTENT_RECONNECT_ALARM
-    //       having to have different values for GSM and
-    //       CDMA. If so we can then remove the need for
-    //       getActionIntentReconnectAlarm.
-    protected static final String INTENT_RECONNECT_ALARM_EXTRA_REASON =
-        "reconnect_alarm_extra_reason";
-
-    // Used for debugging. Send the INTENT with an optional counter value with the number
-    // of times the setup is to fail before succeeding. If the counter isn't passed the
-    // setup will fail once. Example fail two times with FailCause.SIGNAL_LOST(-3)
-    // adb shell am broadcast \
-    //  -a com.android.internal.telephony.dataconnectiontracker.intent_set_fail_data_setup_counter \
-    //  --ei fail_data_setup_counter 3 --ei fail_data_setup_fail_cause -3
-    protected static final String INTENT_SET_FAIL_DATA_SETUP_COUNTER =
-        "com.android.internal.telephony.dataconnectiontracker.intent_set_fail_data_setup_counter";
-    protected static final String FAIL_DATA_SETUP_COUNTER = "fail_data_setup_counter";
-    protected int mFailDataSetupCounter = 0;
-    protected static final String FAIL_DATA_SETUP_FAIL_CAUSE = "fail_data_setup_fail_cause";
-    protected FailCause mFailDataSetupFailCause = FailCause.ERROR_UNSPECIFIED;
-
-    protected static final String DEFALUT_DATA_ON_BOOT_PROP = "net.def_data_on_boot";
-
-    // member variables
-    protected PhoneBase mPhone;
-    protected Activity mActivity = Activity.NONE;
-    protected State mState = State.IDLE;
-    protected Handler mDataConnectionTracker = null;
-
-
-    protected long mTxPkts;
-    protected long mRxPkts;
-    protected int mNetStatPollPeriod;
-    protected boolean mNetStatPollEnabled = false;
-
-    protected TxRxSum mDataStallTxRxSum = new TxRxSum(0, 0);
-    // Used to track stale data stall alarms.
-    protected int mDataStallAlarmTag = (int) SystemClock.elapsedRealtime();
-    // The current data stall alarm intent
-    protected PendingIntent mDataStallAlarmIntent = null;
-    // Number of packets sent since the last received packet
-    protected long mSentSinceLastRecv;
-    // Controls when a simple recovery attempt it to be tried
-    protected int mNoRecvPollCount = 0;
-
-    // wifi connection status will be updated by sticky intent
-    protected boolean mIsWifiConnected = false;
-
-    /** Intent sent when the reconnect alarm fires. */
-    protected PendingIntent mReconnectIntent = null;
-
-    /** CID of active data connection */
-    protected int mCidActive;
-
-    // When false we will not auto attach and manually attaching is required.
-    protected boolean mAutoAttachOnCreation = false;
-
-    // State of screen
-    // (TODO: Reconsider tying directly to screen, maybe this is
-    //        really a lower power mode")
-    protected boolean mIsScreenOn = true;
-
-    /** Allows the generation of unique Id's for DataConnection objects */
-    protected AtomicInteger mUniqueIdGenerator = new AtomicInteger(0);
-
-    /** The data connections. */
-    protected HashMap<Integer, DataConnection> mDataConnections =
-        new HashMap<Integer, DataConnection>();
-
-    /** The data connection async channels */
-    protected HashMap<Integer, DataConnectionAc> mDataConnectionAsyncChannels =
-        new HashMap<Integer, DataConnectionAc>();
-
-    /** Convert an ApnType string to Id (TODO: Use "enumeration" instead of String for ApnType) */
-    protected HashMap<String, Integer> mApnToDataConnectionId =
-                                    new HashMap<String, Integer>();
-
-    /** Phone.APN_TYPE_* ===> ApnContext */
-    protected ConcurrentHashMap<String, ApnContext> mApnContexts =
-                                    new ConcurrentHashMap<String, ApnContext>();
-
-    /* Currently active APN */
-    protected ApnSetting mActiveApn;
-
-    /** allApns holds all apns */
-    protected ArrayList<ApnSetting> mAllApns = null;
-
-    /** preferred apn */
-    protected ApnSetting mPreferredApn = null;
-
-    /** Is packet service restricted by network */
-    protected boolean mIsPsRestricted = false;
-
-    /* Once disposed dont handle any messages */
-    protected boolean mIsDisposed = false;
-
-    protected BroadcastReceiver mIntentReceiver = new BroadcastReceiver ()
-    {
-        @Override
-        public void onReceive(Context context, Intent intent)
-        {
-            String action = intent.getAction();
-            if (DBG) log("onReceive: action=" + action);
-            if (action.equals(Intent.ACTION_SCREEN_ON)) {
-                mIsScreenOn = true;
-                stopNetStatPoll();
-                startNetStatPoll();
-                restartDataStallAlarm();
-            } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
-                mIsScreenOn = false;
-                stopNetStatPoll();
-                startNetStatPoll();
-                restartDataStallAlarm();
-            } else if (action.startsWith(getActionIntentReconnectAlarm())) {
-                log("Reconnect alarm. Previous state was " + mState);
-                onActionIntentReconnectAlarm(intent);
-            } else if (action.equals(getActionIntentDataStallAlarm())) {
-                onActionIntentDataStallAlarm(intent);
-            } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
-                final android.net.NetworkInfo networkInfo = (NetworkInfo)
-                        intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
-                mIsWifiConnected = (networkInfo != null && networkInfo.isConnected());
-            } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
-                final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
-                        WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
-
-                if (!enabled) {
-                    // when WiFi got disabled, the NETWORK_STATE_CHANGED_ACTION
-                    // quit and won't report disconnected until next enabling.
-                    mIsWifiConnected = false;
-                }
-            } else if (action.equals(INTENT_SET_FAIL_DATA_SETUP_COUNTER)) {
-                mFailDataSetupCounter = intent.getIntExtra(FAIL_DATA_SETUP_COUNTER, 1);
-                mFailDataSetupFailCause = FailCause.fromInt(
-                        intent.getIntExtra(FAIL_DATA_SETUP_FAIL_CAUSE,
-                                                    FailCause.ERROR_UNSPECIFIED.getErrorCode()));
-                if (DBG) log("set mFailDataSetupCounter=" + mFailDataSetupCounter +
-                        " mFailDataSetupFailCause=" + mFailDataSetupFailCause);
-            }
-        }
-    };
-
-    private final DataRoamingSettingObserver mDataRoamingSettingObserver;
-
-    private class DataRoamingSettingObserver extends ContentObserver {
-        public DataRoamingSettingObserver(Handler handler) {
-            super(handler);
-        }
-
-        public void register(Context context) {
-            final ContentResolver resolver = context.getContentResolver();
-            resolver.registerContentObserver(
-                    Settings.Secure.getUriFor(Settings.Secure.DATA_ROAMING), false, this);
-        }
-
-        public void unregister(Context context) {
-            final ContentResolver resolver = context.getContentResolver();
-            resolver.unregisterContentObserver(this);
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            // already running on mPhone handler thread
-            handleDataOnRoamingChange();
-        }
-    }
-
-    /**
-     * Maintian the sum of transmit and receive packets.
-     *
-     * The packet counts are initizlied and reset to -1 and
-     * remain -1 until they can be updated.
-     */
-    public class TxRxSum {
-        public long txPkts;
-        public long rxPkts;
-
-        public TxRxSum() {
-            reset();
-        }
-
-        public TxRxSum(long txPkts, long rxPkts) {
-            this.txPkts = txPkts;
-            this.rxPkts = rxPkts;
-        }
-
-        public TxRxSum(TxRxSum sum) {
-            txPkts = sum.txPkts;
-            rxPkts = sum.rxPkts;
-        }
-
-        public void reset() {
-            txPkts = -1;
-            rxPkts = -1;
-        }
-
-        public String toString() {
-            return "{txSum=" + txPkts + " rxSum=" + rxPkts + "}";
-        }
-
-        public void updateTxRxSum() {
-            boolean txUpdated = false, rxUpdated = false;
-            long txSum = 0, rxSum = 0;
-            for (ApnContext apnContext : mApnContexts.values()) {
-                if (apnContext.getState() == State.CONNECTED) {
-                    DataConnectionAc dcac = apnContext.getDataConnectionAc();
-                    if (dcac == null) continue;
-
-                    LinkProperties linkProp = dcac.getLinkPropertiesSync();
-                    if (linkProp == null) continue;
-
-                    String iface = linkProp.getInterfaceName();
-
-                    if (iface != null) {
-                        long stats = TrafficStats.getTxPackets(iface);
-                        if (stats > 0) {
-                            txUpdated = true;
-                            txSum += stats;
-                        }
-                        stats = TrafficStats.getRxPackets(iface);
-                        if (stats > 0) {
-                            rxUpdated = true;
-                            rxSum += stats;
-                        }
-                    }
-                }
-            }
-            if (txUpdated) this.txPkts = txSum;
-            if (rxUpdated) this.rxPkts = rxSum;
-        }
-    }
-
-    protected boolean isDataSetupCompleteOk(AsyncResult ar) {
-        if (ar.exception != null) {
-            if (DBG) log("isDataSetupCompleteOk return false, ar.result=" + ar.result);
-            return false;
-        }
-        if (mFailDataSetupCounter <= 0) {
-            if (DBG) log("isDataSetupCompleteOk return true");
-            return true;
-        }
-        ar.result = mFailDataSetupFailCause;
-        if (DBG) {
-            log("isDataSetupCompleteOk return false" +
-                    " mFailDataSetupCounter=" + mFailDataSetupCounter +
-                    " mFailDataSetupFailCause=" + mFailDataSetupFailCause);
-        }
-        mFailDataSetupCounter -= 1;
-        return false;
-    }
-
-    protected void onActionIntentReconnectAlarm(Intent intent) {
-        String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON);
-        if (mState == State.FAILED) {
-            Message msg = obtainMessage(EVENT_CLEAN_UP_CONNECTION);
-            msg.arg1 = 0; // tearDown is false
-            msg.arg2 = 0;
-            msg.obj = reason;
-            sendMessage(msg);
-        }
-        sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
-    }
-
-    protected void onActionIntentDataStallAlarm(Intent intent) {
-        if (VDBG) log("onActionIntentDataStallAlarm: action=" + intent.getAction());
-        Message msg = obtainMessage(EVENT_DATA_STALL_ALARM, intent.getAction());
-        msg.arg1 = intent.getIntExtra(DATA_STALL_ALARM_TAG_EXTRA, 0);
-        sendMessage(msg);
-    }
-
-    /**
-     * Default constructor
-     */
-    protected DataConnectionTracker(PhoneBase phone) {
-        super();
-        if (DBG) log("DCT.constructor");
-        mPhone = phone;
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(getActionIntentReconnectAlarm());
-        filter.addAction(Intent.ACTION_SCREEN_ON);
-        filter.addAction(Intent.ACTION_SCREEN_OFF);
-        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
-        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
-        filter.addAction(INTENT_SET_FAIL_DATA_SETUP_COUNTER);
-
-        mUserDataEnabled = Settings.Secure.getInt(
-                mPhone.getContext().getContentResolver(), Settings.Secure.MOBILE_DATA, 1) == 1;
-
-        // TODO: Why is this registering the phone as the receiver of the intent
-        //       and not its own handler?
-        mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
-
-        // This preference tells us 1) initial condition for "dataEnabled",
-        // and 2) whether the RIL will setup the baseband to auto-PS attach.
-
-        dataEnabled[APN_DEFAULT_ID] = SystemProperties.getBoolean(DEFALUT_DATA_ON_BOOT_PROP,
-                                                                  true);
-        if (dataEnabled[APN_DEFAULT_ID]) {
-            enabledCount++;
-        }
-
-        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
-        mAutoAttachOnCreation = sp.getBoolean(PhoneBase.DATA_DISABLED_ON_BOOT_KEY, false);
-
-        // watch for changes to Settings.Secure.DATA_ROAMING
-        mDataRoamingSettingObserver = new DataRoamingSettingObserver(mPhone);
-        mDataRoamingSettingObserver.register(mPhone.getContext());
-    }
-
-    public void dispose() {
-        if (DBG) log("DCT.dispose");
-        for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
-            dcac.disconnect();
-        }
-        mDataConnectionAsyncChannels.clear();
-        mIsDisposed = true;
-        mPhone.getContext().unregisterReceiver(this.mIntentReceiver);
-        mDataRoamingSettingObserver.unregister(mPhone.getContext());
-    }
-
-    protected void broadcastMessenger() {
-        Intent intent = new Intent(ACTION_DATA_CONNECTION_TRACKER_MESSENGER);
-        intent.putExtra(EXTRA_MESSENGER, new Messenger(this));
-        mPhone.getContext().sendBroadcast(intent);
-    }
-
-    public Activity getActivity() {
-        return mActivity;
-    }
-
-    public boolean isApnTypeActive(String type) {
-        // TODO: support simultaneous with List instead
-        if (Phone.APN_TYPE_DUN.equals(type)) {
-            ApnSetting dunApn = fetchDunApn();
-            if (dunApn != null) {
-                return ((mActiveApn != null) && (dunApn.toString().equals(mActiveApn.toString())));
-            }
-        }
-        return mActiveApn != null && mActiveApn.canHandleType(type);
-    }
-
-    protected ApnSetting fetchDunApn() {
-        if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)) {
-            log("fetchDunApn: net.tethering.noprovisioning=true ret: null");
-            return null;
-        }
-        Context c = mPhone.getContext();
-        String apnData = Settings.Secure.getString(c.getContentResolver(),
-                Settings.Secure.TETHER_DUN_APN);
-        ApnSetting dunSetting = ApnSetting.fromString(apnData);
-        if (dunSetting != null) {
-            if (VDBG) log("fetchDunApn: secure TETHER_DUN_APN dunSetting=" + dunSetting);
-            return dunSetting;
-        }
-
-        apnData = c.getResources().getString(R.string.config_tether_apndata);
-        dunSetting = ApnSetting.fromString(apnData);
-        if (VDBG) log("fetchDunApn: config_tether_apndata dunSetting=" + dunSetting);
-        return dunSetting;
-    }
-
-    public String[] getActiveApnTypes() {
-        String[] result;
-        if (mActiveApn != null) {
-            result = mActiveApn.types;
-        } else {
-            result = new String[1];
-            result[0] = Phone.APN_TYPE_DEFAULT;
-        }
-        return result;
-    }
-
-    /** TODO: See if we can remove */
-    public String getActiveApnString(String apnType) {
-        String result = null;
-        if (mActiveApn != null) {
-            result = mActiveApn.apn;
-        }
-        return result;
-    }
-
-    /**
-     * Modify {@link Settings.Secure#DATA_ROAMING} value.
-     */
-    public void setDataOnRoamingEnabled(boolean enabled) {
-        if (getDataOnRoamingEnabled() != enabled) {
-            final ContentResolver resolver = mPhone.getContext().getContentResolver();
-            Settings.Secure.putInt(resolver, Settings.Secure.DATA_ROAMING, enabled ? 1 : 0);
-            // will trigger handleDataOnRoamingChange() through observer
-        }
-    }
-
-    /**
-     * Return current {@link Settings.Secure#DATA_ROAMING} value.
-     */
-    public boolean getDataOnRoamingEnabled() {
-        try {
-            final ContentResolver resolver = mPhone.getContext().getContentResolver();
-            return Settings.Secure.getInt(resolver, Settings.Secure.DATA_ROAMING) != 0;
-        } catch (SettingNotFoundException snfe) {
-            return false;
-        }
-    }
-
-    private void handleDataOnRoamingChange() {
-        if (mPhone.getServiceState().getRoaming()) {
-            if (getDataOnRoamingEnabled()) {
-                resetAllRetryCounts();
-            }
-            sendMessage(obtainMessage(EVENT_ROAMING_ON));
-        }
-    }
-
-    // abstract methods
-    protected abstract String getActionIntentReconnectAlarm();
-    protected abstract String getActionIntentDataStallAlarm();
-    protected abstract void startNetStatPoll();
-    protected abstract void stopNetStatPoll();
-    protected abstract void restartDataStallAlarm();
-    protected abstract void restartRadio();
-    protected abstract void log(String s);
-    protected abstract void loge(String s);
-    protected abstract boolean isDataAllowed();
-    protected abstract boolean isApnTypeAvailable(String type);
-    public    abstract State getState(String apnType);
-    protected abstract void setState(State s);
-    protected abstract void gotoIdleAndNotifyDataConnection(String reason);
-
-    protected abstract boolean onTrySetupData(String reason);
-    protected abstract void onRoamingOff();
-    protected abstract void onRoamingOn();
-    protected abstract void onRadioAvailable();
-    protected abstract void onRadioOffOrNotAvailable();
-    protected abstract void onDataSetupComplete(AsyncResult ar);
-    protected abstract void onDisconnectDone(int connId, AsyncResult ar);
-    protected abstract void onVoiceCallStarted();
-    protected abstract void onVoiceCallEnded();
-    protected abstract void onCleanUpConnection(boolean tearDown, int apnId, String reason);
-    protected abstract void onCleanUpAllConnections(String cause);
-    protected abstract boolean isDataPossible(String apnType);
-
-    protected void onDataStallAlarm(int tag) {
-        loge("onDataStallAlarm: not impleted tag=" + tag);
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-        switch (msg.what) {
-            case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
-                log("DISCONNECTED_CONNECTED: msg=" + msg);
-                DataConnectionAc dcac = (DataConnectionAc) msg.obj;
-                mDataConnectionAsyncChannels.remove(dcac.dataConnection.getDataConnectionId());
-                dcac.disconnected();
-                break;
-            }
-            case EVENT_ENABLE_NEW_APN:
-                onEnableApn(msg.arg1, msg.arg2);
-                break;
-
-            case EVENT_TRY_SETUP_DATA:
-                String reason = null;
-                if (msg.obj instanceof String) {
-                    reason = (String) msg.obj;
-                }
-                onTrySetupData(reason);
-                break;
-
-            case EVENT_DATA_STALL_ALARM:
-                onDataStallAlarm(msg.arg1);
-                break;
-
-            case EVENT_ROAMING_OFF:
-                if (getDataOnRoamingEnabled() == false) {
-                    resetAllRetryCounts();
-                }
-                onRoamingOff();
-                break;
-
-            case EVENT_ROAMING_ON:
-                onRoamingOn();
-                break;
-
-            case EVENT_RADIO_AVAILABLE:
-                onRadioAvailable();
-                break;
-
-            case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
-                onRadioOffOrNotAvailable();
-                break;
-
-            case EVENT_DATA_SETUP_COMPLETE:
-                mCidActive = msg.arg1;
-                onDataSetupComplete((AsyncResult) msg.obj);
-                break;
-
-            case EVENT_DISCONNECT_DONE:
-                log("DataConnectoinTracker.handleMessage: EVENT_DISCONNECT_DONE msg=" + msg);
-                onDisconnectDone(msg.arg1, (AsyncResult) msg.obj);
-                break;
-
-            case EVENT_VOICE_CALL_STARTED:
-                onVoiceCallStarted();
-                break;
-
-            case EVENT_VOICE_CALL_ENDED:
-                onVoiceCallEnded();
-                break;
-
-            case EVENT_CLEAN_UP_ALL_CONNECTIONS: {
-                onCleanUpAllConnections((String) msg.obj);
-                break;
-            }
-            case EVENT_CLEAN_UP_CONNECTION: {
-                boolean tearDown = (msg.arg1 == 0) ? false : true;
-                onCleanUpConnection(tearDown, msg.arg2, (String) msg.obj);
-                break;
-            }
-            case EVENT_SET_INTERNAL_DATA_ENABLE: {
-                boolean enabled = (msg.arg1 == ENABLED) ? true : false;
-                onSetInternalDataEnabled(enabled);
-                break;
-            }
-            case EVENT_RESET_DONE: {
-                if (DBG) log("EVENT_RESET_DONE");
-                onResetDone((AsyncResult) msg.obj);
-                break;
-            }
-            case CMD_SET_USER_DATA_ENABLE: {
-                final boolean enabled = (msg.arg1 == ENABLED) ? true : false;
-                if (DBG) log("CMD_SET_USER_DATA_ENABLE enabled=" + enabled);
-                onSetUserDataEnabled(enabled);
-                break;
-            }
-            case CMD_SET_DEPENDENCY_MET: {
-                boolean met = (msg.arg1 == ENABLED) ? true : false;
-                if (DBG) log("CMD_SET_DEPENDENCY_MET met=" + met);
-                Bundle bundle = msg.getData();
-                if (bundle != null) {
-                    String apnType = (String)bundle.get(APN_TYPE_KEY);
-                    if (apnType != null) {
-                        onSetDependencyMet(apnType, met);
-                    }
-                }
-                break;
-            }
-            case CMD_SET_POLICY_DATA_ENABLE: {
-                final boolean enabled = (msg.arg1 == ENABLED) ? true : false;
-                onSetPolicyDataEnabled(enabled);
-                break;
-            }
-            default:
-                Log.e("DATA", "Unidentified event msg=" + msg);
-                break;
-        }
-    }
-
-    /**
-     * Report on whether data connectivity is enabled
-     *
-     * @return {@code false} if data connectivity has been explicitly disabled,
-     *         {@code true} otherwise.
-     */
-    public boolean getAnyDataEnabled() {
-        final boolean result;
-        synchronized (mDataEnabledLock) {
-            result = (mInternalDataEnabled && mUserDataEnabled && sPolicyDataEnabled
-                    && (enabledCount != 0));
-        }
-        if (!result && DBG) log("getAnyDataEnabled " + result);
-        return result;
-    }
-
-    protected boolean isEmergency() {
-        final boolean result;
-        synchronized (mDataEnabledLock) {
-            result = mPhone.isInEcm() || mPhone.isInEmergencyCall();
-        }
-        log("isEmergency: result=" + result);
-        return result;
-    }
-
-    protected int apnTypeToId(String type) {
-        if (TextUtils.equals(type, Phone.APN_TYPE_DEFAULT)) {
-            return APN_DEFAULT_ID;
-        } else if (TextUtils.equals(type, Phone.APN_TYPE_MMS)) {
-            return APN_MMS_ID;
-        } else if (TextUtils.equals(type, Phone.APN_TYPE_SUPL)) {
-            return APN_SUPL_ID;
-        } else if (TextUtils.equals(type, Phone.APN_TYPE_DUN)) {
-            return APN_DUN_ID;
-        } else if (TextUtils.equals(type, Phone.APN_TYPE_HIPRI)) {
-            return APN_HIPRI_ID;
-        } else if (TextUtils.equals(type, Phone.APN_TYPE_IMS)) {
-            return APN_IMS_ID;
-        } else if (TextUtils.equals(type, Phone.APN_TYPE_FOTA)) {
-            return APN_FOTA_ID;
-        } else if (TextUtils.equals(type, Phone.APN_TYPE_CBS)) {
-            return APN_CBS_ID;
-        } else {
-            return APN_INVALID_ID;
-        }
-    }
-
-    protected String apnIdToType(int id) {
-        switch (id) {
-        case APN_DEFAULT_ID:
-            return Phone.APN_TYPE_DEFAULT;
-        case APN_MMS_ID:
-            return Phone.APN_TYPE_MMS;
-        case APN_SUPL_ID:
-            return Phone.APN_TYPE_SUPL;
-        case APN_DUN_ID:
-            return Phone.APN_TYPE_DUN;
-        case APN_HIPRI_ID:
-            return Phone.APN_TYPE_HIPRI;
-        case APN_IMS_ID:
-            return Phone.APN_TYPE_IMS;
-        case APN_FOTA_ID:
-            return Phone.APN_TYPE_FOTA;
-        case APN_CBS_ID:
-            return Phone.APN_TYPE_CBS;
-        default:
-            log("Unknown id (" + id + ") in apnIdToType");
-            return Phone.APN_TYPE_DEFAULT;
-        }
-    }
-
-    protected LinkProperties getLinkProperties(String apnType) {
-        int id = apnTypeToId(apnType);
-
-        if (isApnIdEnabled(id)) {
-            // TODO - remove this cdma-only hack and support multiple DCs.
-            DataConnectionAc dcac = mDataConnectionAsyncChannels.get(0);
-            return dcac.getLinkPropertiesSync();
-        } else {
-            return new LinkProperties();
-        }
-    }
-
-    protected LinkCapabilities getLinkCapabilities(String apnType) {
-        int id = apnTypeToId(apnType);
-        if (isApnIdEnabled(id)) {
-            // TODO - remove this cdma-only hack and support multiple DCs.
-            DataConnectionAc dcac = mDataConnectionAsyncChannels.get(0);
-            return dcac.getLinkCapabilitiesSync();
-        } else {
-            return new LinkCapabilities();
-        }
-    }
-
-    // tell all active apns of the current condition
-    protected void notifyDataConnection(String reason) {
-        for (int id = 0; id < APN_NUM_TYPES; id++) {
-            if (dataEnabled[id]) {
-                mPhone.notifyDataConnection(reason, apnIdToType(id));
-            }
-        }
-        notifyOffApnsOfAvailability(reason);
-    }
-
-    // a new APN has gone active and needs to send events to catch up with the
-    // current condition
-    private void notifyApnIdUpToCurrent(String reason, int apnId) {
-        switch (mState) {
-            case IDLE:
-            case INITING:
-                break;
-            case CONNECTING:
-            case SCANNING:
-                mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTING);
-                break;
-            case CONNECTED:
-            case DISCONNECTING:
-                mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTING);
-                mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTED);
-                break;
-        }
-    }
-
-    // since we normally don't send info to a disconnected APN, we need to do this specially
-    private void notifyApnIdDisconnected(String reason, int apnId) {
-        mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.DISCONNECTED);
-    }
-
-    // disabled apn's still need avail/unavail notificiations - send them out
-    protected void notifyOffApnsOfAvailability(String reason) {
-        if (DBG) log("notifyOffApnsOfAvailability - reason= " + reason);
-        for (int id = 0; id < APN_NUM_TYPES; id++) {
-            if (!isApnIdEnabled(id)) {
-                notifyApnIdDisconnected(reason, id);
-            }
-        }
-    }
-
-    public boolean isApnTypeEnabled(String apnType) {
-        if (apnType == null) {
-            return false;
-        } else {
-            return isApnIdEnabled(apnTypeToId(apnType));
-        }
-    }
-
-    protected synchronized boolean isApnIdEnabled(int id) {
-        if (id != APN_INVALID_ID) {
-            return dataEnabled[id];
-        }
-        return false;
-    }
-
-    /**
-     * Ensure that we are connected to an APN of the specified type.
-     *
-     * @param type the APN type (currently the only valid values are
-     *            {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL})
-     * @return Success is indicated by {@code Phone.APN_ALREADY_ACTIVE} or
-     *         {@code Phone.APN_REQUEST_STARTED}. In the latter case, a
-     *         broadcast will be sent by the ConnectivityManager when a
-     *         connection to the APN has been established.
-     */
-    public synchronized int enableApnType(String type) {
-        int id = apnTypeToId(type);
-        if (id == APN_INVALID_ID) {
-            return Phone.APN_REQUEST_FAILED;
-        }
-
-        if (DBG) {
-            log("enableApnType(" + type + "), isApnTypeActive = " + isApnTypeActive(type)
-                    + ", isApnIdEnabled =" + isApnIdEnabled(id) + " and state = " + mState);
-        }
-
-        if (!isApnTypeAvailable(type)) {
-            if (DBG) log("type not available");
-            return Phone.APN_TYPE_NOT_AVAILABLE;
-        }
-
-        if (isApnIdEnabled(id)) {
-            return Phone.APN_ALREADY_ACTIVE;
-        } else {
-            setEnabled(id, true);
-        }
-        return Phone.APN_REQUEST_STARTED;
-    }
-
-    /**
-     * The APN of the specified type is no longer needed. Ensure that if use of
-     * the default APN has not been explicitly disabled, we are connected to the
-     * default APN.
-     *
-     * @param type the APN type. The only valid values are currently
-     *            {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL}.
-     * @return Success is indicated by {@code Phone.APN_ALREADY_ACTIVE} or
-     *         {@code Phone.APN_REQUEST_STARTED}. In the latter case, a
-     *         broadcast will be sent by the ConnectivityManager when a
-     *         connection to the APN has been disconnected. A {@code
-     *         Phone.APN_REQUEST_FAILED} is returned if the type parameter is
-     *         invalid or if the apn wasn't enabled.
-     */
-    public synchronized int disableApnType(String type) {
-        if (DBG) log("disableApnType(" + type + ")");
-        int id = apnTypeToId(type);
-        if (id == APN_INVALID_ID) {
-            return Phone.APN_REQUEST_FAILED;
-        }
-        if (isApnIdEnabled(id)) {
-            setEnabled(id, false);
-            if (isApnTypeActive(Phone.APN_TYPE_DEFAULT)) {
-                if (dataEnabled[APN_DEFAULT_ID]) {
-                    return Phone.APN_ALREADY_ACTIVE;
-                } else {
-                    return Phone.APN_REQUEST_STARTED;
-                }
-            } else {
-                return Phone.APN_REQUEST_STARTED;
-            }
-        } else {
-            return Phone.APN_REQUEST_FAILED;
-        }
-    }
-
-    protected void setEnabled(int id, boolean enable) {
-        if (DBG) {
-            log("setEnabled(" + id + ", " + enable + ") with old state = " + dataEnabled[id]
-                    + " and enabledCount = " + enabledCount);
-        }
-        Message msg = obtainMessage(EVENT_ENABLE_NEW_APN);
-        msg.arg1 = id;
-        msg.arg2 = (enable ? ENABLED : DISABLED);
-        sendMessage(msg);
-    }
-
-    protected void onEnableApn(int apnId, int enabled) {
-        if (DBG) {
-            log("EVENT_APN_ENABLE_REQUEST apnId=" + apnId + ", apnType=" + apnIdToType(apnId) +
-                    ", enabled=" + enabled + ", dataEnabled = " + dataEnabled[apnId] +
-                    ", enabledCount = " + enabledCount + ", isApnTypeActive = " +
-                    isApnTypeActive(apnIdToType(apnId)));
-        }
-        if (enabled == ENABLED) {
-            synchronized (this) {
-                if (!dataEnabled[apnId]) {
-                    dataEnabled[apnId] = true;
-                    enabledCount++;
-                }
-            }
-            String type = apnIdToType(apnId);
-            if (!isApnTypeActive(type)) {
-                mRequestedApnType = type;
-                onEnableNewApn();
-            } else {
-                notifyApnIdUpToCurrent(Phone.REASON_APN_SWITCHED, apnId);
-            }
-        } else {
-            // disable
-            boolean didDisable = false;
-            synchronized (this) {
-                if (dataEnabled[apnId]) {
-                    dataEnabled[apnId] = false;
-                    enabledCount--;
-                    didDisable = true;
-                }
-            }
-            if (didDisable) {
-                if ((enabledCount == 0) || (apnId == APN_DUN_ID)) {
-                    mRequestedApnType = Phone.APN_TYPE_DEFAULT;
-                    onCleanUpConnection(true, apnId, Phone.REASON_DATA_DISABLED);
-                }
-
-                // send the disconnect msg manually, since the normal route wont send
-                // it (it's not enabled)
-                notifyApnIdDisconnected(Phone.REASON_DATA_DISABLED, apnId);
-                if (dataEnabled[APN_DEFAULT_ID] == true
-                        && !isApnTypeActive(Phone.APN_TYPE_DEFAULT)) {
-                    // TODO - this is an ugly way to restore the default conn - should be done
-                    // by a real contention manager and policy that disconnects the lower pri
-                    // stuff as enable requests come in and pops them back on as we disable back
-                    // down to the lower pri stuff
-                    mRequestedApnType = Phone.APN_TYPE_DEFAULT;
-                    onEnableNewApn();
-                }
-            }
-        }
-    }
-
-    /**
-     * Called when we switch APNs.
-     *
-     * mRequestedApnType is set prior to call
-     * To be overridden.
-     */
-    protected void onEnableNewApn() {
-    }
-
-    /**
-     * Called when EVENT_RESET_DONE is received so goto
-     * IDLE state and send notifications to those interested.
-     *
-     * TODO - currently unused.  Needs to be hooked into DataConnection cleanup
-     * TODO - needs to pass some notion of which connection is reset..
-     */
-    protected void onResetDone(AsyncResult ar) {
-        if (DBG) log("EVENT_RESET_DONE");
-        String reason = null;
-        if (ar.userObj instanceof String) {
-            reason = (String) ar.userObj;
-        }
-        gotoIdleAndNotifyDataConnection(reason);
-    }
-
-    /**
-     * Prevent mobile data connections from being established, or once again
-     * allow mobile data connections. If the state toggles, then either tear
-     * down or set up data, as appropriate to match the new state.
-     *
-     * @param enable indicates whether to enable ({@code true}) or disable (
-     *            {@code false}) data
-     * @return {@code true} if the operation succeeded
-     */
-    public boolean setInternalDataEnabled(boolean enable) {
-        if (DBG)
-            log("setInternalDataEnabled(" + enable + ")");
-
-        Message msg = obtainMessage(EVENT_SET_INTERNAL_DATA_ENABLE);
-        msg.arg1 = (enable ? ENABLED : DISABLED);
-        sendMessage(msg);
-        return true;
-    }
-
-    protected void onSetInternalDataEnabled(boolean enabled) {
-        synchronized (mDataEnabledLock) {
-            mInternalDataEnabled = enabled;
-            if (enabled) {
-                log("onSetInternalDataEnabled: changed to enabled, try to setup data call");
-                resetAllRetryCounts();
-                onTrySetupData(Phone.REASON_DATA_ENABLED);
-            } else {
-                log("onSetInternalDataEnabled: changed to disabled, cleanUpAllConnections");
-                cleanUpAllConnections(null);
-            }
-        }
-    }
-
-    public void cleanUpAllConnections(String cause) {
-        Message msg = obtainMessage(EVENT_CLEAN_UP_ALL_CONNECTIONS);
-        msg.obj = cause;
-        sendMessage(msg);
-    }
-
-    public abstract boolean isDisconnected();
-
-    protected void onSetUserDataEnabled(boolean enabled) {
-        synchronized (mDataEnabledLock) {
-            final boolean prevEnabled = getAnyDataEnabled();
-            if (mUserDataEnabled != enabled) {
-                mUserDataEnabled = enabled;
-                Settings.Secure.putInt(mPhone.getContext().getContentResolver(),
-                        Settings.Secure.MOBILE_DATA, enabled ? 1 : 0);
-                if (getDataOnRoamingEnabled() == false &&
-                        mPhone.getServiceState().getRoaming() == true) {
-                    if (enabled) {
-                        notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
-                    } else {
-                        notifyOffApnsOfAvailability(Phone.REASON_DATA_DISABLED);
-                    }
-                }
-                if (prevEnabled != getAnyDataEnabled()) {
-                    if (!prevEnabled) {
-                        resetAllRetryCounts();
-                        onTrySetupData(Phone.REASON_DATA_ENABLED);
-                    } else {
-                        onCleanUpAllConnections(Phone.REASON_DATA_DISABLED);
-                    }
-                }
-            }
-        }
-    }
-
-    protected void onSetDependencyMet(String apnType, boolean met) {
-    }
-
-    protected void onSetPolicyDataEnabled(boolean enabled) {
-        synchronized (mDataEnabledLock) {
-            final boolean prevEnabled = getAnyDataEnabled();
-            if (sPolicyDataEnabled != enabled) {
-                sPolicyDataEnabled = enabled;
-                if (prevEnabled != getAnyDataEnabled()) {
-                    if (!prevEnabled) {
-                        resetAllRetryCounts();
-                        onTrySetupData(Phone.REASON_DATA_ENABLED);
-                    } else {
-                        onCleanUpAllConnections(Phone.REASON_DATA_DISABLED);
-                    }
-                }
-            }
-        }
-    }
-
-    protected String getReryConfig(boolean forDefault) {
-        int nt = mPhone.getServiceState().getNetworkType();
-
-        if ((nt == TelephonyManager.NETWORK_TYPE_CDMA) ||
-            (nt == TelephonyManager.NETWORK_TYPE_1xRTT) ||
-            (nt == TelephonyManager.NETWORK_TYPE_EVDO_0) ||
-            (nt == TelephonyManager.NETWORK_TYPE_EVDO_A) ||
-            (nt == TelephonyManager.NETWORK_TYPE_EVDO_B) ||
-            (nt == TelephonyManager.NETWORK_TYPE_EHRPD)) {
-            // CDMA variant
-            return SystemProperties.get("ro.cdma.data_retry_config");
-        } else {
-            // Use GSM varient for all others.
-            if (forDefault) {
-                return SystemProperties.get("ro.gsm.data_retry_config");
-            } else {
-                return SystemProperties.get("ro.gsm.2nd_data_retry_config");
-            }
-        }
-    }
-
-    protected void resetAllRetryCounts() {
-        for (ApnContext ac : mApnContexts.values()) {
-            ac.setRetryCount(0);
-        }
-        for (DataConnection dc : mDataConnections.values()) {
-            dc.resetRetryCount();
-        }
-    }
-
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("DataConnectionTracker:");
-        pw.println(" mInternalDataEnabled=" + mInternalDataEnabled);
-        pw.println(" mUserDataEnabled=" + mUserDataEnabled);
-        pw.println(" sPolicyDataEnabed=" + sPolicyDataEnabled);
-        pw.println(" dataEnabled:");
-        for(int i=0; i < dataEnabled.length; i++) {
-            pw.printf("  dataEnabled[%d]=%b\n", i, dataEnabled[i]);
-        }
-        pw.flush();
-        pw.println(" enabledCount=" + enabledCount);
-        pw.println(" mRequestedApnType=" + mRequestedApnType);
-        pw.println(" mPhone=" + mPhone.getPhoneName());
-        pw.println(" mActivity=" + mActivity);
-        pw.println(" mState=" + mState);
-        pw.println(" mTxPkts=" + mTxPkts);
-        pw.println(" mRxPkts=" + mRxPkts);
-        pw.println(" mNetStatPollPeriod=" + mNetStatPollPeriod);
-        pw.println(" mNetStatPollEnabled=" + mNetStatPollEnabled);
-        pw.println(" mDataStallTxRxSum=" + mDataStallTxRxSum);
-        pw.println(" mDataStallAlarmTag=" + mDataStallAlarmTag);
-        pw.println(" mSentSinceLastRecv=" + mSentSinceLastRecv);
-        pw.println(" mNoRecvPollCount=" + mNoRecvPollCount);
-        pw.println(" mIsWifiConnected=" + mIsWifiConnected);
-        pw.println(" mReconnectIntent=" + mReconnectIntent);
-        pw.println(" mCidActive=" + mCidActive);
-        pw.println(" mAutoAttachOnCreation=" + mAutoAttachOnCreation);
-        pw.println(" mIsScreenOn=" + mIsScreenOn);
-        pw.println(" mUniqueIdGenerator=" + mUniqueIdGenerator);
-        pw.flush();
-        pw.println(" ***************************************");
-        Set<Entry<Integer, DataConnection> > mDcSet = mDataConnections.entrySet();
-        pw.println(" mDataConnections: count=" + mDcSet.size());
-        for (Entry<Integer, DataConnection> entry : mDcSet) {
-            pw.printf(" *** mDataConnection[%d] \n", entry.getKey());
-            entry.getValue().dump(fd, pw, args);
-        }
-        pw.println(" ***************************************");
-        pw.flush();
-        Set<Entry<String, Integer>> mApnToDcIdSet = mApnToDataConnectionId.entrySet();
-        pw.println(" mApnToDataConnectonId size=" + mApnToDcIdSet.size());
-        for (Entry<String, Integer> entry : mApnToDcIdSet) {
-            pw.printf(" mApnToDataConnectonId[%s]=%d\n", entry.getKey(), entry.getValue());
-        }
-        pw.println(" ***************************************");
-        pw.flush();
-        if (mApnContexts != null) {
-            Set<Entry<String, ApnContext>> mApnContextsSet = mApnContexts.entrySet();
-            pw.println(" mApnContexts size=" + mApnContextsSet.size());
-            for (Entry<String, ApnContext> entry : mApnContextsSet) {
-                entry.getValue().dump(fd, pw, args);
-            }
-            pw.println(" ***************************************");
-        } else {
-            pw.println(" mApnContexts=null");
-        }
-        pw.flush();
-        pw.println(" mActiveApn=" + mActiveApn);
-        if (mAllApns != null) {
-            pw.println(" mAllApns size=" + mAllApns.size());
-            for (int i=0; i < mAllApns.size(); i++) {
-                pw.printf(" mAllApns[%d]: %s\n", i, mAllApns.get(i));
-            }
-            pw.flush();
-        } else {
-            pw.println(" mAllApns=null");
-        }
-        pw.println(" mPreferredApn=" + mPreferredApn);
-        pw.println(" mIsPsRestricted=" + mIsPsRestricted);
-        pw.println(" mIsDisposed=" + mIsDisposed);
-        pw.println(" mIntentReceiver=" + mIntentReceiver);
-        pw.println(" mDataRoamingSettingObserver=" + mDataRoamingSettingObserver);
-        pw.flush();
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
new file mode 100644
index 0000000..10ac153
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2012 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.internal.telephony;
+
+import com.android.internal.util.Protocol;
+
+/**
+ * @hide
+ */
+public class DctConstants {
+    /**
+     * IDLE: ready to start data connection setup, default state
+     * INITING: state of issued setupDefaultPDP() but not finish yet
+     * CONNECTING: state of issued startPppd() but not finish yet
+     * SCANNING: data connection fails with one apn but other apns are available
+     *           ready to start data connection on other apns (before INITING)
+     * CONNECTED: IP connection is setup
+     * DISCONNECTING: Connection.disconnect() has been called, but PDP
+     *                context is not yet deactivated
+     * FAILED: data connection fail for all apns settings
+     *
+     * getDataConnectionState() maps State to DataState
+     *      FAILED or IDLE : DISCONNECTED
+     *      INITING or CONNECTING or SCANNING: CONNECTING
+     *      CONNECTED : CONNECTED or DISCONNECTING
+     */
+    public enum State {
+        IDLE,
+        INITING,
+        CONNECTING,
+        SCANNING,
+        CONNECTED,
+        DISCONNECTING,
+        FAILED
+    }
+
+    public enum Activity {
+        NONE,
+        DATAIN,
+        DATAOUT,
+        DATAINANDOUT,
+        DORMANT
+    }
+
+    /***** Event Codes *****/
+    public static final int BASE = Protocol.BASE_DATA_CONNECTION_TRACKER;
+    public static final int EVENT_DATA_SETUP_COMPLETE = BASE + 0;
+    public static final int EVENT_RADIO_AVAILABLE = BASE + 1;
+    public static final int EVENT_RECORDS_LOADED = BASE + 2;
+    public static final int EVENT_TRY_SETUP_DATA = BASE + 3;
+    public static final int EVENT_DATA_STATE_CHANGED = BASE + 4;
+    public static final int EVENT_POLL_PDP = BASE + 5;
+    public static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = BASE + 6;
+    public static final int EVENT_VOICE_CALL_STARTED = BASE + 7;
+    public static final int EVENT_VOICE_CALL_ENDED = BASE + 8;
+    public static final int EVENT_DATA_CONNECTION_DETACHED = BASE + 9;
+    public static final int EVENT_LINK_STATE_CHANGED = BASE + 10;
+    public static final int EVENT_ROAMING_ON = BASE + 11;
+    public static final int EVENT_ROAMING_OFF = BASE + 12;
+    public static final int EVENT_ENABLE_NEW_APN = BASE + 13;
+    public static final int EVENT_RESTORE_DEFAULT_APN = BASE + 14;
+    public static final int EVENT_DISCONNECT_DONE = BASE + 15;
+    public static final int EVENT_DATA_CONNECTION_ATTACHED = BASE + 16;
+    public static final int EVENT_DATA_STALL_ALARM = BASE + 17;
+    public static final int EVENT_DO_RECOVERY = BASE + 18;
+    public static final int EVENT_APN_CHANGED = BASE + 19;
+    public static final int EVENT_CDMA_DATA_DETACHED = BASE + 20;
+    public static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = BASE + 21;
+    public static final int EVENT_PS_RESTRICT_ENABLED = BASE + 22;
+    public static final int EVENT_PS_RESTRICT_DISABLED = BASE + 23;
+    public static final int EVENT_CLEAN_UP_CONNECTION = BASE + 24;
+    public static final int EVENT_CDMA_OTA_PROVISION = BASE + 25;
+    public static final int EVENT_RESTART_RADIO = BASE + 26;
+    public static final int EVENT_SET_INTERNAL_DATA_ENABLE = BASE + 27;
+    public static final int EVENT_RESET_DONE = BASE + 28;
+    public static final int EVENT_CLEAN_UP_ALL_CONNECTIONS = BASE + 29;
+    public static final int CMD_SET_USER_DATA_ENABLE = BASE + 30;
+    public static final int CMD_SET_DEPENDENCY_MET = BASE + 31;
+    public static final int CMD_SET_POLICY_DATA_ENABLE = BASE + 32;
+    public static final int EVENT_ICC_CHANGED = BASE + 33;
+
+    /***** Constants *****/
+
+    public static final int APN_INVALID_ID = -1;
+    public static final int APN_DEFAULT_ID = 0;
+    public static final int APN_MMS_ID = 1;
+    public static final int APN_SUPL_ID = 2;
+    public static final int APN_DUN_ID = 3;
+    public static final int APN_HIPRI_ID = 4;
+    public static final int APN_IMS_ID = 5;
+    public static final int APN_FOTA_ID = 6;
+    public static final int APN_CBS_ID = 7;
+    public static final int APN_NUM_TYPES = 8;
+
+    public static final int DISABLED = 0;
+    public static final int ENABLED = 1;
+
+    public static final String APN_TYPE_KEY = "apnType";
+    public static String ACTION_DATA_CONNECTION_TRACKER_MESSENGER =
+        "com.android.internal.telephony";
+    public static String EXTRA_MESSENGER = "EXTRA_MESSENGER";
+}
+
diff --git a/telephony/java/com/android/internal/telephony/DebugService.java b/telephony/java/com/android/internal/telephony/DebugService.java
deleted file mode 100644
index 29fea6e..0000000
--- a/telephony/java/com/android/internal/telephony/DebugService.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2012 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.internal.telephony;
-
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * A debug service that will dump telephony's state
- *
- * Currently this "Service" has a proxy in the phone app
- * com.android.phone.TelephonyDebugService which actually
- * invokes the dump method.
- */
-public class DebugService {
-    private static String TAG = "DebugService";
-
-    /** Constructor */
-    public DebugService() {
-        log("DebugService:");
-    }
-
-    /**
-     * Dump the state of various objects, add calls to other objects as desired.
-     */
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        log("dump: +");
-        PhoneProxy phoneProxy = null;
-        PhoneBase phoneBase = null;
-
-        try {
-            phoneProxy = (PhoneProxy) PhoneFactory.getDefaultPhone();
-        } catch (Exception e) {
-            pw.println("Telephony DebugService: Could not getDefaultPhone e=" + e);
-            return;
-        }
-        try {
-            phoneBase = (PhoneBase)phoneProxy.getActivePhone();
-        } catch (Exception e) {
-            pw.println("Telephony DebugService: Could not PhoneBase e=" + e);
-            return;
-        }
-
-        /**
-         * Surround each of the sub dump's with try/catch so even
-         * if one fails we'll be able to dump the next ones.
-         */
-        pw.println();
-        pw.println("++++++++++++++++++++++++++++++++");
-        pw.flush();
-        try {
-            phoneBase.dump(fd, pw, args);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        pw.flush();
-        pw.println("++++++++++++++++++++++++++++++++");
-        try {
-            phoneBase.mDataConnectionTracker.dump(fd, pw, args);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        pw.flush();
-        pw.println("++++++++++++++++++++++++++++++++");
-        try {
-            phoneBase.getServiceStateTracker().dump(fd, pw, args);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        pw.flush();
-        pw.println("++++++++++++++++++++++++++++++++");
-        try {
-            phoneBase.getCallTracker().dump(fd, pw, args);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        pw.flush();
-        pw.println("++++++++++++++++++++++++++++++++");
-        try {
-            ((RIL)phoneBase.mCM).dump(fd, pw, args);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        pw.flush();
-        pw.println("++++++++++++++++++++++++++++++++");
-        log("dump: -");
-    }
-
-    private static void log(String s) {
-        Log.d(TAG, "DebugService " + s);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
deleted file mode 100644
index eb78a53e..0000000
--- a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
+++ /dev/null
@@ -1,281 +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.internal.telephony;
-
-import android.net.LinkCapabilities;
-import android.net.LinkProperties;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.telephony.CellInfo;
-import android.telephony.ServiceState;
-import android.telephony.TelephonyManager;
-import android.util.Log;
-
-import com.android.internal.telephony.ITelephonyRegistry;
-
-/**
- * broadcast intents
- */
-public class DefaultPhoneNotifier implements PhoneNotifier {
-
-    static final String LOG_TAG = "GSM";
-    private static final boolean DBG = true;
-    private ITelephonyRegistry mRegistry;
-
-    /*package*/
-    DefaultPhoneNotifier() {
-        mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
-                    "telephony.registry"));
-    }
-
-    public void notifyPhoneState(Phone sender) {
-        Call ringingCall = sender.getRingingCall();
-        String incomingNumber = "";
-        if (ringingCall != null && ringingCall.getEarliestConnection() != null){
-            incomingNumber = ringingCall.getEarliestConnection().getAddress();
-        }
-        try {
-            mRegistry.notifyCallState(convertCallState(sender.getState()), incomingNumber);
-        } catch (RemoteException ex) {
-            // system process is dead
-        }
-    }
-
-    public void notifyServiceState(Phone sender) {
-        ServiceState ss = sender.getServiceState();
-        if (ss == null) {
-            ss = new ServiceState();
-            ss.setStateOutOfService();
-        }
-        try {
-            mRegistry.notifyServiceState(ss);
-        } catch (RemoteException ex) {
-            // system process is dead
-        }
-    }
-
-    public void notifySignalStrength(Phone sender) {
-        try {
-            mRegistry.notifySignalStrength(sender.getSignalStrength());
-        } catch (RemoteException ex) {
-            // system process is dead
-        }
-    }
-
-    public void notifyMessageWaitingChanged(Phone sender) {
-        try {
-            mRegistry.notifyMessageWaitingChanged(sender.getMessageWaitingIndicator());
-        } catch (RemoteException ex) {
-            // system process is dead
-        }
-    }
-
-    public void notifyCallForwardingChanged(Phone sender) {
-        try {
-            mRegistry.notifyCallForwardingChanged(sender.getCallForwardingIndicator());
-        } catch (RemoteException ex) {
-            // system process is dead
-        }
-    }
-
-    public void notifyDataActivity(Phone sender) {
-        try {
-            mRegistry.notifyDataActivity(convertDataActivityState(sender.getDataActivityState()));
-        } catch (RemoteException ex) {
-            // system process is dead
-        }
-    }
-
-    public void notifyDataConnection(Phone sender, String reason, String apnType,
-            Phone.DataState state) {
-        doNotifyDataConnection(sender, reason, apnType, state);
-    }
-
-    private void doNotifyDataConnection(Phone sender, String reason, String apnType,
-            Phone.DataState state) {
-        // TODO
-        // use apnType as the key to which connection we're talking about.
-        // pass apnType back up to fetch particular for this one.
-        TelephonyManager telephony = TelephonyManager.getDefault();
-        LinkProperties linkProperties = null;
-        LinkCapabilities linkCapabilities = null;
-        boolean roaming = false;
-
-        if (state == Phone.DataState.CONNECTED) {
-            linkProperties = sender.getLinkProperties(apnType);
-            linkCapabilities = sender.getLinkCapabilities(apnType);
-        }
-        ServiceState ss = sender.getServiceState();
-        if (ss != null) roaming = ss.getRoaming();
-
-        try {
-            mRegistry.notifyDataConnection(
-                    convertDataState(state),
-                    sender.isDataConnectivityPossible(apnType), reason,
-                    sender.getActiveApnHost(apnType),
-                    apnType,
-                    linkProperties,
-                    linkCapabilities,
-                    ((telephony!=null) ? telephony.getNetworkType() :
-                    TelephonyManager.NETWORK_TYPE_UNKNOWN),
-                    roaming);
-        } catch (RemoteException ex) {
-            // system process is dead
-        }
-    }
-
-    public void notifyDataConnectionFailed(Phone sender, String reason, String apnType) {
-        try {
-            mRegistry.notifyDataConnectionFailed(reason, apnType);
-        } catch (RemoteException ex) {
-            // system process is dead
-        }
-    }
-
-    public void notifyCellLocation(Phone sender) {
-        Bundle data = new Bundle();
-        sender.getCellLocation().fillInNotifierBundle(data);
-        try {
-            mRegistry.notifyCellLocation(data);
-        } catch (RemoteException ex) {
-            // system process is dead
-        }
-    }
-
-    public void notifyCellInfo(Phone sender, CellInfo cellInfo) {
-        try {
-            mRegistry.notifyCellInfo(cellInfo);
-        } catch (RemoteException ex) {
-
-        }
-    }
-
-    public void notifyOtaspChanged(Phone sender, int otaspMode) {
-        try {
-            mRegistry.notifyOtaspChanged(otaspMode);
-        } catch (RemoteException ex) {
-            // system process is dead
-        }
-    }
-
-    private void log(String s) {
-        Log.d(LOG_TAG, "[PhoneNotifier] " + s);
-    }
-
-    /**
-     * Convert the {@link State} enum into the TelephonyManager.CALL_STATE_* constants
-     * for the public API.
-     */
-    public static int convertCallState(Phone.State state) {
-        switch (state) {
-            case RINGING:
-                return TelephonyManager.CALL_STATE_RINGING;
-            case OFFHOOK:
-                return TelephonyManager.CALL_STATE_OFFHOOK;
-            default:
-                return TelephonyManager.CALL_STATE_IDLE;
-        }
-    }
-
-    /**
-     * Convert the TelephonyManager.CALL_STATE_* constants into the {@link State} enum
-     * for the public API.
-     */
-    public static Phone.State convertCallState(int state) {
-        switch (state) {
-            case TelephonyManager.CALL_STATE_RINGING:
-                return Phone.State.RINGING;
-            case TelephonyManager.CALL_STATE_OFFHOOK:
-                return Phone.State.OFFHOOK;
-            default:
-                return Phone.State.IDLE;
-        }
-    }
-
-    /**
-     * Convert the {@link DataState} enum into the TelephonyManager.DATA_* constants
-     * for the public API.
-     */
-    public static int convertDataState(Phone.DataState state) {
-        switch (state) {
-            case CONNECTING:
-                return TelephonyManager.DATA_CONNECTING;
-            case CONNECTED:
-                return TelephonyManager.DATA_CONNECTED;
-            case SUSPENDED:
-                return TelephonyManager.DATA_SUSPENDED;
-            default:
-                return TelephonyManager.DATA_DISCONNECTED;
-        }
-    }
-
-    /**
-     * Convert the TelephonyManager.DATA_* constants into {@link DataState} enum
-     * for the public API.
-     */
-    public static Phone.DataState convertDataState(int state) {
-        switch (state) {
-            case TelephonyManager.DATA_CONNECTING:
-                return Phone.DataState.CONNECTING;
-            case TelephonyManager.DATA_CONNECTED:
-                return Phone.DataState.CONNECTED;
-            case TelephonyManager.DATA_SUSPENDED:
-                return Phone.DataState.SUSPENDED;
-            default:
-                return Phone.DataState.DISCONNECTED;
-        }
-    }
-
-    /**
-     * Convert the {@link DataState} enum into the TelephonyManager.DATA_* constants
-     * for the public API.
-     */
-    public static int convertDataActivityState(Phone.DataActivityState state) {
-        switch (state) {
-            case DATAIN:
-                return TelephonyManager.DATA_ACTIVITY_IN;
-            case DATAOUT:
-                return TelephonyManager.DATA_ACTIVITY_OUT;
-            case DATAINANDOUT:
-                return TelephonyManager.DATA_ACTIVITY_INOUT;
-            case DORMANT:
-                return TelephonyManager.DATA_ACTIVITY_DORMANT;
-            default:
-                return TelephonyManager.DATA_ACTIVITY_NONE;
-        }
-    }
-
-    /**
-     * Convert the TelephonyManager.DATA_* constants into the {@link DataState} enum
-     * for the public API.
-     */
-    public static Phone.DataActivityState convertDataActivityState(int state) {
-        switch (state) {
-            case TelephonyManager.DATA_ACTIVITY_IN:
-                return Phone.DataActivityState.DATAIN;
-            case TelephonyManager.DATA_ACTIVITY_OUT:
-                return Phone.DataActivityState.DATAOUT;
-            case TelephonyManager.DATA_ACTIVITY_INOUT:
-                return Phone.DataActivityState.DATAINANDOUT;
-            case TelephonyManager.DATA_ACTIVITY_DORMANT:
-                return Phone.DataActivityState.DORMANT;
-            default:
-                return Phone.DataActivityState.NONE;
-        }
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/DriverCall.java b/telephony/java/com/android/internal/telephony/DriverCall.java
deleted file mode 100644
index 663c284..0000000
--- a/telephony/java/com/android/internal/telephony/DriverCall.java
+++ /dev/null
@@ -1,162 +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.internal.telephony;
-//import com.android.internal.telephony.*;
-import android.util.Log;
-import java.lang.Comparable;
-import android.telephony.PhoneNumberUtils;
-
-/**
- * {@hide}
- */
-public class DriverCall implements Comparable {
-    static final String LOG_TAG = "RILB";
-
-    public enum State {
-        ACTIVE,
-        HOLDING,
-        DIALING,    // MO call only
-        ALERTING,   // MO call only
-        INCOMING,   // MT call only
-        WAITING;    // MT call only
-        // If you add a state, make sure to look for the switch()
-        // statements that use this enum
-    }
-
-    public int index;
-    public boolean isMT;
-    public State state;     // May be null if unavail
-    public boolean isMpty;
-    public String number;
-    public int TOA;
-    public boolean isVoice;
-    public boolean isVoicePrivacy;
-    public int als;
-    public int numberPresentation;
-    public String name;
-    public int namePresentation;
-    public UUSInfo uusInfo;
-
-    /** returns null on error */
-    static DriverCall
-    fromCLCCLine(String line) {
-        DriverCall ret = new DriverCall();
-
-        //+CLCC: 1,0,2,0,0,\"+18005551212\",145
-        //     index,isMT,state,mode,isMpty(,number,TOA)?
-        ATResponseParser p = new ATResponseParser(line);
-
-        try {
-            ret.index = p.nextInt();
-            ret.isMT = p.nextBoolean();
-            ret.state = stateFromCLCC(p.nextInt());
-
-            ret.isVoice = (0 == p.nextInt());
-            ret.isMpty = p.nextBoolean();
-
-            // use ALLOWED as default presentation while parsing CLCC
-            ret.numberPresentation = Connection.PRESENTATION_ALLOWED;
-
-            if (p.hasMore()) {
-                // Some lame implementations return strings
-                // like "NOT AVAILABLE" in the CLCC line
-                ret.number = PhoneNumberUtils.extractNetworkPortionAlt(p.nextString());
-
-                if (ret.number.length() == 0) {
-                    ret.number = null;
-                }
-
-                ret.TOA = p.nextInt();
-
-                // Make sure there's a leading + on addresses with a TOA
-                // of 145
-
-                ret.number = PhoneNumberUtils.stringFromStringAndTOA(
-                                ret.number, ret.TOA);
-
-            }
-        } catch (ATParseEx ex) {
-            Log.e(LOG_TAG,"Invalid CLCC line: '" + line + "'");
-            return null;
-        }
-
-        return ret;
-    }
-
-    public
-    DriverCall() {
-    }
-
-    public String
-    toString() {
-        return "id=" + index + ","
-                + state + ","
-                + "toa=" + TOA + ","
-                + (isMpty ? "conf" : "norm") + ","
-                + (isMT ? "mt" : "mo") + ","
-                + als + ","
-                + (isVoice ? "voc" : "nonvoc") + ","
-                + (isVoicePrivacy ? "evp" : "noevp") + ","
-                /*+ "number=" + number */ + ",cli=" + numberPresentation + ","
-                /*+ "name="+ name */ + "," + namePresentation;
-    }
-
-    public static State
-    stateFromCLCC(int state) throws ATParseEx {
-        switch(state) {
-            case 0: return State.ACTIVE;
-            case 1: return State.HOLDING;
-            case 2: return State.DIALING;
-            case 3: return State.ALERTING;
-            case 4: return State.INCOMING;
-            case 5: return State.WAITING;
-            default:
-                throw new ATParseEx("illegal call state " + state);
-        }
-    }
-
-    public static int
-    presentationFromCLIP(int cli) throws ATParseEx
-    {
-        switch(cli) {
-            case 0: return Connection.PRESENTATION_ALLOWED;
-            case 1: return Connection.PRESENTATION_RESTRICTED;
-            case 2: return Connection.PRESENTATION_UNKNOWN;
-            case 3: return Connection.PRESENTATION_PAYPHONE;
-            default:
-                throw new ATParseEx("illegal presentation " + cli);
-        }
-    }
-
-    //***** Comparable Implementation
-
-    /** For sorting by index */
-    public int
-    compareTo (Object o) {
-        DriverCall dc;
-
-        dc = (DriverCall)o;
-
-        if (index < dc.index) {
-            return -1;
-        } else if (index == dc.index) {
-            return 0;
-        } else { /*index > dc.index*/
-            return 1;
-        }
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/EventLogTags.logtags b/telephony/java/com/android/internal/telephony/EventLogTags.logtags
deleted file mode 100644
index 427e5da..0000000
--- a/telephony/java/com/android/internal/telephony/EventLogTags.logtags
+++ /dev/null
@@ -1,73 +0,0 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
-
-option java_package com.android.internal.telephony;
-
-# PDP Context has a bad DNS address
-50100 pdp_bad_dns_address (dns_address|3)
-
-# For data connection on PDP context, reached the data-out-without-data-in
-# packet count that triggers a countdown to radio restart
-50101 pdp_radio_reset_countdown_triggered (out_packet_count|1|1)
-
-# Radio restart - timed out with no incoming packets.
-50102 pdp_radio_reset (out_packet_count|1|1)
-
-# PDP context reset - timed out with no incoming packets.
-50103 pdp_context_reset (out_packet_count|1|1)
-
-# Reregister to data network - timed out with no incoming packets.
-50104 pdp_reregister_network (out_packet_count|1|1)
-
-# PDP Setup failures
-50105 pdp_setup_fail (cause|1|5), (cid|1|5), (network_type|1|5)
-
-# Call drops
-50106 call_drop (cause|1|5), (cid|1|5), (network_type|1|5)
-
-# Data network registration failed after successful voice registration
-50107 data_network_registration_fail (op_numeric|1|5), (cid|1|5)
-
-# Suspicious status of data connection while radio poweroff
-50108 data_network_status_on_radio_off (dc_state|3), (enable|1|5)
-
-# PDP drop caused by network
-50109 pdp_network_drop (cid|1|5), (network_type|1|5)
-
-# CDMA data network setup failure
-50110 cdma_data_setup_failed (cause|1|5), (cid|1|5), (network_type|1|5)
-
-# CDMA data network drop
-50111 cdma_data_drop (cid|1|5), (network_type|1|5)
-
-# GSM radio access technology switched
-50112 gsm_rat_switched (cid|1|5), (network_from|1|5), (network_to|1|5)
-
-# GSM data connection state transition
-50113 gsm_data_state_change (oldState|3), (newState|3)
-
-# GSM service state transition
-50114 gsm_service_state_change (oldState|1|5), (oldGprsState|1|5), (newState|1|5), (newGprsState|1|5)
-
-# CDMA data connection state transition
-50115 cdma_data_state_change (oldState|3), (newState|3)
-
-# CDMA service state transition
-50116 cdma_service_state_change (oldState|1|5), (oldDataState|1|5), (newState|1|5), (newDataState|1|5)
-
-# Bad IP address
-50117 bad_ip_address (ip_address|3)
-
-# Data Stall Recovery mode DATA_STALL_RECOVERY_GET_DATA_CALL_LIST
-50118 data_stall_recovery_get_data_call_list (out_packet_count|1|1)
-
-# Data Stall Recovery mode DATA_STALL_RECOVERY_CLEANUP
-50119 data_stall_recovery_cleanup (out_packet_count|1|1)
-
-# Data Stall Recovery mode DATA_STALL_RECOVERY_REREGISTER
-50120 data_stall_recovery_reregister (out_packet_count|1|1)
-
-# Data Stall Recovery mode DATA_STALL_RECOVERY_RADIO_RESTART
-50121 data_stall_recovery_radio_restart (out_packet_count|1|1)
-
-# Data Stall Recovery mode DATA_STALL_RECOVERY_RADIO_RESTART_WITH_PROP
-50122 data_stall_recovery_radio_restart_with_prop (out_packet_count|1|1)
diff --git a/telephony/java/com/android/internal/telephony/GsmAlphabet.java b/telephony/java/com/android/internal/telephony/GsmAlphabet.java
index 25647ac..04b1220 100644
--- a/telephony/java/com/android/internal/telephony/GsmAlphabet.java
+++ b/telephony/java/com/android/internal/telephony/GsmAlphabet.java
@@ -24,15 +24,12 @@
 
 import java.nio.ByteBuffer;
 import java.nio.charset.Charset;
+import com.android.internal.telephony.SmsConstants;
 import com.android.internal.R;
 
 import java.util.ArrayList;
 import java.util.List;
 
-import static android.telephony.SmsMessage.ENCODING_7BIT;
-import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS;
-import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS_WITH_HEADER;
-
 /**
  * This class implements the character set mapping between
  * the GSM SMS 7-bit alphabet specified in TS 23.038 6.2.1
@@ -45,8 +42,6 @@
 
     private GsmAlphabet() { }
 
-    //***** Constants
-
     /**
      * This escapes extended characters, and when present indicates that the
      * following character should be looked up in the "extended" table.
@@ -81,6 +76,60 @@
     public static final int UDH_SEPTET_COST_CONCATENATED_MESSAGE = 6;
 
     /**
+     * For a specific text string, this object describes protocol
+     * properties of encoding it for transmission as message user
+     * data.
+     */
+    public static class TextEncodingDetails {
+        /**
+         *The number of SMS's required to encode the text.
+         */
+        public int msgCount;
+
+        /**
+         * The number of code units consumed so far, where code units
+         * are basically characters in the encoding -- for example,
+         * septets for the standard ASCII and GSM encodings, and 16
+         * bits for Unicode.
+         */
+        public int codeUnitCount;
+
+        /**
+         * How many code units are still available without spilling
+         * into an additional message.
+         */
+        public int codeUnitsRemaining;
+
+        /**
+         * The encoding code unit size (specified using
+         * android.telephony.SmsMessage ENCODING_*).
+         */
+        public int codeUnitSize;
+
+        /**
+         * The GSM national language table to use, or 0 for the default 7-bit alphabet.
+         */
+        public int languageTable;
+
+        /**
+         * The GSM national language shift table to use, or 0 for the default 7-bit extension table.
+         */
+        public int languageShiftTable;
+
+        @Override
+        public String toString() {
+            return "TextEncodingDetails " +
+                    "{ msgCount=" + msgCount +
+                    ", codeUnitCount=" + codeUnitCount +
+                    ", codeUnitsRemaining=" + codeUnitsRemaining +
+                    ", codeUnitSize=" + codeUnitSize +
+                    ", languageTable=" + languageTable +
+                    ", languageShiftTable=" + languageShiftTable +
+                    " }";
+        }
+    }
+
+    /**
      * Converts a char to a GSM 7 bit table index.
      * Returns ' ' in GSM alphabet if there's no possible match. Returns
      * GSM_EXTENDED_ESCAPE if this character is in the extended table.
@@ -752,27 +801,27 @@
      *     character counts for the most efficient 7-bit encoding,
      *     or null if there are no suitable language tables to encode the string.
      */
-    public static SmsMessageBase.TextEncodingDetails
+    public static TextEncodingDetails
     countGsmSeptets(CharSequence s, boolean use7bitOnly) {
         // fast path for common case where no national language shift tables are enabled
         if (sEnabledSingleShiftTables.length + sEnabledLockingShiftTables.length == 0) {
-            SmsMessageBase.TextEncodingDetails ted = new SmsMessageBase.TextEncodingDetails();
+            TextEncodingDetails ted = new TextEncodingDetails();
             int septets = GsmAlphabet.countGsmSeptetsUsingTables(s, use7bitOnly, 0, 0);
             if (septets == -1) {
                 return null;
             }
-            ted.codeUnitSize = ENCODING_7BIT;
+            ted.codeUnitSize = SmsConstants.ENCODING_7BIT;
             ted.codeUnitCount = septets;
-            if (septets > MAX_USER_DATA_SEPTETS) {
-                ted.msgCount = (septets + (MAX_USER_DATA_SEPTETS_WITH_HEADER - 1)) /
-                        MAX_USER_DATA_SEPTETS_WITH_HEADER;
+            if (septets > SmsConstants.MAX_USER_DATA_SEPTETS) {
+                ted.msgCount = (septets + (SmsConstants.MAX_USER_DATA_SEPTETS_WITH_HEADER - 1)) /
+                        SmsConstants.MAX_USER_DATA_SEPTETS_WITH_HEADER;
                 ted.codeUnitsRemaining = (ted.msgCount *
-                        MAX_USER_DATA_SEPTETS_WITH_HEADER) - septets;
+                        SmsConstants.MAX_USER_DATA_SEPTETS_WITH_HEADER) - septets;
             } else {
                 ted.msgCount = 1;
-                ted.codeUnitsRemaining = MAX_USER_DATA_SEPTETS - septets;
+                ted.codeUnitsRemaining = SmsConstants.MAX_USER_DATA_SEPTETS - septets;
             }
-            ted.codeUnitSize = ENCODING_7BIT;
+            ted.codeUnitSize = SmsConstants.ENCODING_7BIT;
             return ted;
         }
 
@@ -832,9 +881,9 @@
         }
 
         // find the least cost encoding (lowest message count and most code units remaining)
-        SmsMessageBase.TextEncodingDetails ted = new SmsMessageBase.TextEncodingDetails();
+        TextEncodingDetails ted = new TextEncodingDetails();
         ted.msgCount = Integer.MAX_VALUE;
-        ted.codeUnitSize = ENCODING_7BIT;
+        ted.codeUnitSize = SmsConstants.ENCODING_7BIT;
         int minUnencodableCount = Integer.MAX_VALUE;
         for (LanguagePairCount lpc : lpcList) {
             for (int shiftTable = 0; shiftTable <= maxSingleShiftCode; shiftTable++) {
@@ -852,17 +901,17 @@
                 }
                 int msgCount;
                 int septetsRemaining;
-                if (septets + udhLength > MAX_USER_DATA_SEPTETS) {
+                if (septets + udhLength > SmsConstants.MAX_USER_DATA_SEPTETS) {
                     if (udhLength == 0) {
                         udhLength = UDH_SEPTET_COST_LENGTH;
                     }
                     udhLength += UDH_SEPTET_COST_CONCATENATED_MESSAGE;
-                    int septetsPerMessage = MAX_USER_DATA_SEPTETS - udhLength;
+                    int septetsPerMessage = SmsConstants.MAX_USER_DATA_SEPTETS - udhLength;
                     msgCount = (septets + septetsPerMessage - 1) / septetsPerMessage;
                     septetsRemaining = (msgCount * septetsPerMessage) - septets;
                 } else {
                     msgCount = 1;
-                    septetsRemaining = MAX_USER_DATA_SEPTETS - udhLength - septets;
+                    septetsRemaining = SmsConstants.MAX_USER_DATA_SEPTETS - udhLength - septets;
                 }
                 // for 7-bit only mode, use language pair with the least unencodable chars
                 int unencodableCount = lpc.unencodableCounts[shiftTable];
diff --git a/telephony/java/com/android/internal/telephony/IIccPhoneBook.aidl b/telephony/java/com/android/internal/telephony/IIccPhoneBook.aidl
deleted file mode 100644
index f700dfe..0000000
--- a/telephony/java/com/android/internal/telephony/IIccPhoneBook.aidl
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
-** Copyright 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.internal.telephony;
-
-import com.android.internal.telephony.AdnRecord;
-
-
-
-/** Interface for applications to access the ICC phone book.
- *
- * <p>The following code snippet demonstrates a static method to
- * retrieve the IIccPhoneBook interface from Android:</p>
- * <pre>private static IIccPhoneBook getSimPhoneBookInterface()
-            throws DeadObjectException {
-    IServiceManager sm = ServiceManagerNative.getDefault();
-    IIccPhoneBook spb;
-    spb = IIccPhoneBook.Stub.asInterface(sm.getService("iccphonebook"));
-    return spb;
-}
- * </pre>
- */
-
-interface IIccPhoneBook {
-
-    /**
-     * Loads the AdnRecords in efid and returns them as a
-     * List of AdnRecords
-     *
-     * @param efid the EF id of a ADN-like SIM
-     * @return List of AdnRecord
-     */
-    List<AdnRecord> getAdnRecordsInEf(int efid);
-
-    /**
-     * Replace oldAdn with newAdn in ADN-like record in EF
-     *
-     * getAdnRecordsInEf must be called at least once before this function,
-     * otherwise an error will be returned
-     *
-     * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN
-     * @param oldTag adn tag to be replaced
-     * @param oldPhoneNumber adn number to be replaced
-     *        Set both oldTag and oldPhoneNubmer to "" means to replace an
-     *        empty record, aka, insert new record
-     * @param newTag adn tag to be stored
-     * @param newPhoneNumber adn number ot be stored
-     *        Set both newTag and newPhoneNubmer to "" means to replace the old
-     *        record with empty one, aka, delete old record
-     * @param pin2 required to update EF_FDN, otherwise must be null
-     * @return true for success
-     */
-    boolean updateAdnRecordsInEfBySearch(int efid,
-            String oldTag, String oldPhoneNumber,
-            String newTag, String newPhoneNumber,
-            String pin2);
-
-    /**
-     * Update an ADN-like EF record by record index
-     *
-     * This is useful for iteration the whole ADN file, such as write the whole
-     * phone book or erase/format the whole phonebook
-     *
-     * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN
-     * @param newTag adn tag to be stored
-     * @param newPhoneNumber adn number to be stored
-     *        Set both newTag and newPhoneNubmer to "" means to replace the old
-     *        record with empty one, aka, delete old record
-     * @param index is 1-based adn record index to be updated
-     * @param pin2 required to update EF_FDN, otherwise must be null
-     * @return true for success
-     */
-    boolean updateAdnRecordsInEfByIndex(int efid, String newTag,
-            String newPhoneNumber, int index,
-            String pin2);
-
-    /**
-     * Get the max munber of records in efid
-     *
-     * @param efid the EF id of a ADN-like SIM
-     * @return  int[3] array
-     *            recordSizes[0]  is the single record length
-     *            recordSizes[1]  is the total length of the EF file
-     *            recordSizes[2]  is the number of records in the EF file
-     */
-    int[] getAdnRecordsSize(int efid);
-
-}
diff --git a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
old mode 100755
new mode 100644
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
deleted file mode 100644
index 735f986..0000000
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
-** Copyright 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.internal.telephony;
-
-import android.app.PendingIntent;
-import com.android.internal.telephony.SmsRawData;
-
-/** Interface for applications to access the ICC phone book.
- *
- * <p>The following code snippet demonstrates a static method to
- * retrieve the ISms interface from Android:</p>
- * <pre>private static ISms getSmsInterface()
-            throws DeadObjectException {
-    IServiceManager sm = ServiceManagerNative.getDefault();
-    ISms ss;
-    ss = ISms.Stub.asInterface(sm.getService("isms"));
-    return ss;
-}
- * </pre>
- */
-
-interface ISms {
-    /**
-     * Retrieves all messages currently stored on ICC.
-     *
-     * @return list of SmsRawData of all sms on ICC
-     */
-     List<SmsRawData> getAllMessagesFromIccEf();
-
-    /**
-     * Update the specified message on the ICC.
-     *
-     * @param messageIndex record index of message to update
-     * @param newStatus new message status (STATUS_ON_ICC_READ,
-     *                  STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT,
-     *                  STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE)
-     * @param pdu the raw PDU to store
-     * @return success or not
-     *
-     */
-     boolean updateMessageOnIccEf(int messageIndex, int newStatus,
-            in byte[] pdu);
-
-    /**
-     * Copy a raw SMS PDU to the ICC.
-     *
-     * @param pdu the raw PDU to store
-     * @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD,
-     *               STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT)
-     * @return success or not
-     *
-     */
-    boolean copyMessageToIccEf(int status, in byte[] pdu, in byte[] smsc);
-
-    /**
-     * Send a data SMS.
-     *
-     * @param smsc the SMSC to send the message through, or NULL for the
-     *  default SMSC
-     * @param data the body of the message to send
-     * @param sentIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is sucessfully sent, or failed.
-     *  The result code will be <code>Activity.RESULT_OK<code> for success,
-     *  or one of these errors:<br>
-     *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
-     *  <code>RESULT_ERROR_RADIO_OFF</code><br>
-     *  <code>RESULT_ERROR_NULL_PDU</code><br>
-     *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
-     *  the extra "errorCode" containing a radio technology specific value,
-     *  generally only useful for troubleshooting.<br>
-     *  The per-application based SMS control checks sentIntent. If sentIntent
-     *  is NULL the caller will be checked against all unknown applicaitons,
-     *  which cause smaller number of SMS to be sent in checking period.
-     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is delivered to the recipient.  The
-     *  raw pdu of the status report is in the extended data ("pdu").
-     */
-    void sendData(in String destAddr, in String scAddr, in int destPort,
-            in byte[] data, in PendingIntent sentIntent, in PendingIntent deliveryIntent);
-
-    /**
-     * Send an SMS.
-     *
-     * @param smsc the SMSC to send the message through, or NULL for the
-     *  default SMSC
-     * @param text the body of the message to send
-     * @param sentIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is sucessfully sent, or failed.
-     *  The result code will be <code>Activity.RESULT_OK<code> for success,
-     *  or one of these errors:<br>
-     *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
-     *  <code>RESULT_ERROR_RADIO_OFF</code><br>
-     *  <code>RESULT_ERROR_NULL_PDU</code><br>
-     *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
-     *  the extra "errorCode" containing a radio technology specific value,
-     *  generally only useful for troubleshooting.<br>
-     *  The per-application based SMS control checks sentIntent. If sentIntent
-     *  is NULL the caller will be checked against all unknown applications,
-     *  which cause smaller number of SMS to be sent in checking period.
-     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is delivered to the recipient.  The
-     *  raw pdu of the status report is in the extended data ("pdu").
-     */
-    void sendText(in String destAddr, in String scAddr, in String text,
-            in PendingIntent sentIntent, in PendingIntent deliveryIntent);
-
-    /**
-     * Send a multi-part text based SMS.
-     *
-     * @param destinationAddress the address to send the message to
-     * @param scAddress is the service center address or null to use
-     *   the current default SMSC
-     * @param parts an <code>ArrayList</code> of strings that, in order,
-     *   comprise the original message
-     * @param sentIntents if not null, an <code>ArrayList</code> of
-     *   <code>PendingIntent</code>s (one for each message part) that is
-     *   broadcast when the corresponding message part has been sent.
-     *   The result code will be <code>Activity.RESULT_OK<code> for success,
-     *   or one of these errors:
-     *   <code>RESULT_ERROR_GENERIC_FAILURE</code>
-     *   <code>RESULT_ERROR_RADIO_OFF</code>
-     *   <code>RESULT_ERROR_NULL_PDU</code>.
-     * @param deliveryIntents if not null, an <code>ArrayList</code> of
-     *   <code>PendingIntent</code>s (one for each message part) that is
-     *   broadcast when the corresponding message part has been delivered
-     *   to the recipient.  The raw pdu of the status report is in the
-     *   extended data ("pdu").
-     */
-    void sendMultipartText(in String destinationAddress, in String scAddress,
-            in List<String> parts, in List<PendingIntent> sentIntents,
-            in List<PendingIntent> deliveryIntents);
-
-    /**
-     * Enable reception of cell broadcast (SMS-CB) messages with the given
-     * message identifier. Note that if two different clients enable the same
-     * message identifier, they must both disable it for the device to stop
-     * receiving those messages.
-     *
-     * @param messageIdentifier Message identifier as specified in TS 23.041
-     * @return true if successful, false otherwise
-     *
-     * @see #disableCellBroadcast(int)
-     */
-    boolean enableCellBroadcast(int messageIdentifier);
-
-    /**
-     * Disable reception of cell broadcast (SMS-CB) messages with the given
-     * message identifier. Note that if two different clients enable the same
-     * message identifier, they must both disable it for the device to stop
-     * receiving those messages.
-     *
-     * @param messageIdentifier Message identifier as specified in TS 23.041
-     * @return true if successful, false otherwise
-     *
-     * @see #enableCellBroadcast(int)
-     */
-    boolean disableCellBroadcast(int messageIdentifier);
-
-    /**
-     * Enable reception of cell broadcast (SMS-CB) messages with the given
-     * message identifier range. Note that if two different clients enable
-     * a message identifier range, they must both disable it for the device
-     * to stop receiving those messages.
-     *
-     * @param startMessageId first message identifier as specified in TS 23.041
-     * @param endMessageId last message identifier as specified in TS 23.041
-     * @return true if successful, false otherwise
-     *
-     * @see #disableCellBroadcastRange(int, int)
-     */
-    boolean enableCellBroadcastRange(int startMessageId, int endMessageId);
-
-    /**
-     * Disable reception of cell broadcast (SMS-CB) messages with the given
-     * message identifier range. Note that if two different clients enable
-     * a message identifier range, they must both disable it for the device
-     * to stop receiving those messages.
-     *
-     * @param startMessageId first message identifier as specified in TS 23.041
-     * @param endMessageId last message identifier as specified in TS 23.041
-     * @return true if successful, false otherwise
-     *
-     * @see #enableCellBroadcastRange(int, int)
-     */
-    boolean disableCellBroadcastRange(int startMessageId, int endMessageId);
-
-}
diff --git a/telephony/java/com/android/internal/telephony/IccCard.java b/telephony/java/com/android/internal/telephony/IccCard.java
deleted file mode 100644
index fcf2f92..0000000
--- a/telephony/java/com/android/internal/telephony/IccCard.java
+++ /dev/null
@@ -1,1002 +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.internal.telephony;
-
-import static android.Manifest.permission.READ_PHONE_STATE;
-import android.app.ActivityManagerNative;
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.util.Log;
-import android.view.WindowManager;
-
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.CommandsInterface.RadioState;
-import com.android.internal.telephony.gsm.SIMFileHandler;
-import com.android.internal.telephony.gsm.SIMRecords;
-import com.android.internal.telephony.cat.CatService;
-import com.android.internal.telephony.cdma.CDMALTEPhone;
-import com.android.internal.telephony.cdma.CdmaLteUiccFileHandler;
-import com.android.internal.telephony.cdma.CdmaLteUiccRecords;
-import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
-import com.android.internal.telephony.cdma.RuimFileHandler;
-import com.android.internal.telephony.cdma.RuimRecords;
-
-import android.os.SystemProperties;
-
-import com.android.internal.R;
-
-/**
- * {@hide}
- */
-public class IccCard {
-    protected String mLogTag;
-    protected boolean mDbg;
-
-    protected IccCardStatus mIccCardStatus = null;
-    protected State mState = null;
-    private final Object mStateMonitor = new Object();
-
-    protected boolean is3gpp = true;
-    protected boolean isSubscriptionFromIccCard = true;
-    protected CdmaSubscriptionSourceManager mCdmaSSM = null;
-    protected PhoneBase mPhone;
-    private IccRecords mIccRecords;
-    private IccFileHandler mIccFileHandler;
-    private CatService mCatService;
-
-    private RegistrantList mAbsentRegistrants = new RegistrantList();
-    private RegistrantList mPinLockedRegistrants = new RegistrantList();
-    private RegistrantList mNetworkLockedRegistrants = new RegistrantList();
-    protected RegistrantList mReadyRegistrants = new RegistrantList();
-    protected RegistrantList mRuimReadyRegistrants = new RegistrantList();
-
-    private boolean mDesiredPinLocked;
-    private boolean mDesiredFdnEnabled;
-    private boolean mIccPinLocked = true; // Default to locked
-    private boolean mIccFdnEnabled = false; // Default to disabled.
-                                            // Will be updated when SIM_READY.
-
-    /* Parameter is3gpp's values to be passed to constructor */
-    public final static boolean CARD_IS_3GPP = true;
-    public final static boolean CARD_IS_NOT_3GPP = false;
-
-
-    /* The extra data for broacasting intent INTENT_ICC_STATE_CHANGE */
-    static public final String INTENT_KEY_ICC_STATE = "ss";
-    /* NOT_READY means the ICC interface is not ready (eg, radio is off or powering on) */
-    static public final String INTENT_VALUE_ICC_NOT_READY = "NOT_READY";
-    /* ABSENT means ICC is missing */
-    static public final String INTENT_VALUE_ICC_ABSENT = "ABSENT";
-    /* LOCKED means ICC is locked by pin or by network */
-    static public final String INTENT_VALUE_ICC_LOCKED = "LOCKED";
-    /* READY means ICC is ready to access */
-    static public final String INTENT_VALUE_ICC_READY = "READY";
-    /* IMSI means ICC IMSI is ready in property */
-    static public final String INTENT_VALUE_ICC_IMSI = "IMSI";
-    /* LOADED means all ICC records, including IMSI, are loaded */
-    static public final String INTENT_VALUE_ICC_LOADED = "LOADED";
-    /* The extra data for broacasting intent INTENT_ICC_STATE_CHANGE */
-    static public final String INTENT_KEY_LOCKED_REASON = "reason";
-    /* PIN means ICC is locked on PIN1 */
-    static public final String INTENT_VALUE_LOCKED_ON_PIN = "PIN";
-    /* PUK means ICC is locked on PUK1 */
-    static public final String INTENT_VALUE_LOCKED_ON_PUK = "PUK";
-    /* NETWORK means ICC is locked on NETWORK PERSONALIZATION */
-    static public final String INTENT_VALUE_LOCKED_NETWORK = "NETWORK";
-    /* PERM_DISABLED means ICC is permanently disabled due to puk fails */
-    static public final String INTENT_VALUE_ABSENT_ON_PERM_DISABLED = "PERM_DISABLED";
-
-
-    protected static final int EVENT_ICC_LOCKED = 1;
-    private static final int EVENT_GET_ICC_STATUS_DONE = 2;
-    protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 3;
-    private static final int EVENT_PINPUK_DONE = 4;
-    private static final int EVENT_REPOLL_STATUS_DONE = 5;
-    protected static final int EVENT_ICC_READY = 6;
-    private static final int EVENT_QUERY_FACILITY_LOCK_DONE = 7;
-    private static final int EVENT_CHANGE_FACILITY_LOCK_DONE = 8;
-    private static final int EVENT_CHANGE_ICC_PASSWORD_DONE = 9;
-    private static final int EVENT_QUERY_FACILITY_FDN_DONE = 10;
-    private static final int EVENT_CHANGE_FACILITY_FDN_DONE = 11;
-    private static final int EVENT_ICC_STATUS_CHANGED = 12;
-    private static final int EVENT_CARD_REMOVED = 13;
-    private static final int EVENT_CARD_ADDED = 14;
-    protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 15;
-    protected static final int EVENT_RADIO_ON = 16;
-
-    /*
-      UNKNOWN is a transient state, for example, after uesr inputs ICC pin under
-      PIN_REQUIRED state, the query for ICC status returns UNKNOWN before it
-      turns to READY
-     */
-    public enum State {
-        UNKNOWN,
-        ABSENT,
-        PIN_REQUIRED,
-        PUK_REQUIRED,
-        NETWORK_LOCKED,
-        READY,
-        NOT_READY,
-        PERM_DISABLED;
-
-        public boolean isPinLocked() {
-            return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED));
-        }
-
-        public boolean iccCardExist() {
-            return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED)
-                    || (this == NETWORK_LOCKED) || (this == READY)
-                    || (this == PERM_DISABLED));
-        }
-    }
-
-    public State getState() {
-        if (mState == null) {
-            switch(mPhone.mCM.getRadioState()) {
-                /* This switch block must not return anything in
-                 * State.isLocked() or State.ABSENT.
-                 * If it does, handleSimStatus() may break
-                 */
-                case RADIO_OFF:
-                case RADIO_UNAVAILABLE:
-                    return State.UNKNOWN;
-                default:
-                    if (!is3gpp && !isSubscriptionFromIccCard) {
-                        // CDMA can get subscription from NV. In that case,
-                        // subscription is ready as soon as Radio is ON.
-                        return State.READY;
-                    }
-            }
-        } else {
-            return mState;
-        }
-
-        return State.UNKNOWN;
-    }
-
-    public IccCard(PhoneBase phone, String logTag, Boolean is3gpp, Boolean dbg) {
-        mLogTag = logTag;
-        mDbg = dbg;
-        if (mDbg) log("[IccCard] Creating card type " + (is3gpp ? "3gpp" : "3gpp2"));
-        mPhone = phone;
-        this.is3gpp = is3gpp;
-        mCdmaSSM = CdmaSubscriptionSourceManager.getInstance(mPhone.getContext(),
-                mPhone.mCM, mHandler, EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
-        if (phone.mCM.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE
-                && phone instanceof CDMALTEPhone) {
-            mIccFileHandler = new CdmaLteUiccFileHandler(this, "", mPhone.mCM);
-            mIccRecords = new CdmaLteUiccRecords(this, mPhone.mContext, mPhone.mCM);
-        } else {
-            // Correct aid will be set later (when GET_SIM_STATUS returns)
-            mIccFileHandler = is3gpp ? new SIMFileHandler(this, "", mPhone.mCM) :
-                                       new RuimFileHandler(this, "", mPhone.mCM);
-            mIccRecords = is3gpp ? new SIMRecords(this, mPhone.mContext, mPhone.mCM) :
-                                   new RuimRecords(this, mPhone.mContext, mPhone.mCM);
-        }
-        mCatService = CatService.getInstance(mPhone.mCM, mIccRecords,
-                mPhone.mContext, mIccFileHandler, this);
-        mPhone.mCM.registerForOffOrNotAvailable(mHandler, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
-        mPhone.mCM.registerForOn(mHandler, EVENT_RADIO_ON, null);
-        mPhone.mCM.registerForIccStatusChanged(mHandler, EVENT_ICC_STATUS_CHANGED, null);
-    }
-
-    public void dispose() {
-        if (mDbg) log("[IccCard] Disposing card type " + (is3gpp ? "3gpp" : "3gpp2"));
-        mPhone.mCM.unregisterForIccStatusChanged(mHandler);
-        mPhone.mCM.unregisterForOffOrNotAvailable(mHandler);
-        mPhone.mCM.unregisterForOn(mHandler);
-        mCatService.dispose();
-        mCdmaSSM.dispose(mHandler);
-        mIccRecords.dispose();
-        mIccFileHandler.dispose();
-    }
-
-    protected void finalize() {
-        if (mDbg) log("[IccCard] Finalized card type " + (is3gpp ? "3gpp" : "3gpp2"));
-    }
-
-    public IccRecords getIccRecords() {
-        return mIccRecords;
-    }
-
-    public IccFileHandler getIccFileHandler() {
-        return mIccFileHandler;
-    }
-
-    /**
-     * Notifies handler of any transition into State.ABSENT
-     */
-    public void registerForAbsent(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        mAbsentRegistrants.add(r);
-
-        if (getState() == State.ABSENT) {
-            r.notifyRegistrant();
-        }
-    }
-
-    public void unregisterForAbsent(Handler h) {
-        mAbsentRegistrants.remove(h);
-    }
-
-    /**
-     * Notifies handler of any transition into State.NETWORK_LOCKED
-     */
-    public void registerForNetworkLocked(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        mNetworkLockedRegistrants.add(r);
-
-        if (getState() == State.NETWORK_LOCKED) {
-            r.notifyRegistrant();
-        }
-    }
-
-    public void unregisterForNetworkLocked(Handler h) {
-        mNetworkLockedRegistrants.remove(h);
-    }
-
-    /**
-     * Notifies handler of any transition into State.isPinLocked()
-     */
-    public void registerForLocked(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        mPinLockedRegistrants.add(r);
-
-        if (getState().isPinLocked()) {
-            r.notifyRegistrant();
-        }
-    }
-
-    public void unregisterForLocked(Handler h) {
-        mPinLockedRegistrants.remove(h);
-    }
-
-    public void registerForReady(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        synchronized (mStateMonitor) {
-            mReadyRegistrants.add(r);
-
-            if (getState() == State.READY) {
-                r.notifyRegistrant(new AsyncResult(null, null, null));
-            }
-        }
-    }
-
-    public void unregisterForReady(Handler h) {
-        synchronized (mStateMonitor) {
-            mReadyRegistrants.remove(h);
-        }
-    }
-
-    public State getRuimState() {
-        if(mIccCardStatus != null) {
-            return getAppState(mIccCardStatus.getCdmaSubscriptionAppIndex());
-        } else {
-            return State.UNKNOWN;
-        }
-    }
-
-    public void registerForRuimReady(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        synchronized (mStateMonitor) {
-            mRuimReadyRegistrants.add(r);
-
-            if (getState() == State.READY && getRuimState() == State.READY ) {
-                r.notifyRegistrant(new AsyncResult(null, null, null));
-            }
-        }
-    }
-
-    public void unregisterForRuimReady(Handler h) {
-        synchronized (mStateMonitor) {
-            mRuimReadyRegistrants.remove(h);
-        }
-    }
-
-    /**
-     * Supply the ICC PIN to the ICC
-     *
-     * When the operation is complete, onComplete will be sent to its
-     * Handler.
-     *
-     * onComplete.obj will be an AsyncResult
-     *
-     * ((AsyncResult)onComplete.obj).exception == null on success
-     * ((AsyncResult)onComplete.obj).exception != null on fail
-     *
-     * If the supplied PIN is incorrect:
-     * ((AsyncResult)onComplete.obj).exception != null
-     * && ((AsyncResult)onComplete.obj).exception
-     *       instanceof com.android.internal.telephony.gsm.CommandException)
-     * && ((CommandException)(((AsyncResult)onComplete.obj).exception))
-     *          .getCommandError() == CommandException.Error.PASSWORD_INCORRECT
-     *
-     *
-     */
-
-    public void supplyPin (String pin, Message onComplete) {
-        mPhone.mCM.supplyIccPin(pin, mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
-    }
-
-    public void supplyPuk (String puk, String newPin, Message onComplete) {
-        mPhone.mCM.supplyIccPuk(puk, newPin,
-                mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
-    }
-
-    public void supplyPin2 (String pin2, Message onComplete) {
-        mPhone.mCM.supplyIccPin2(pin2,
-                mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
-    }
-
-    public void supplyPuk2 (String puk2, String newPin2, Message onComplete) {
-        mPhone.mCM.supplyIccPuk2(puk2, newPin2,
-                mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
-    }
-
-    public void supplyNetworkDepersonalization (String pin, Message onComplete) {
-        mPhone.mCM.supplyNetworkDepersonalization(pin,
-                mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
-    }
-
-    /**
-     * Check whether ICC pin lock is enabled
-     * This is a sync call which returns the cached pin enabled state
-     *
-     * @return true for ICC locked enabled
-     *         false for ICC locked disabled
-     */
-    public boolean getIccLockEnabled() {
-        return mIccPinLocked;
-     }
-
-    /**
-     * Check whether ICC fdn (fixed dialing number) is enabled
-     * This is a sync call which returns the cached pin enabled state
-     *
-     * @return true for ICC fdn enabled
-     *         false for ICC fdn disabled
-     */
-     public boolean getIccFdnEnabled() {
-        return mIccFdnEnabled;
-     }
-
-     /**
-      * Set the ICC pin lock enabled or disabled
-      * When the operation is complete, onComplete will be sent to its handler
-      *
-      * @param enabled "true" for locked "false" for unlocked.
-      * @param password needed to change the ICC pin state, aka. Pin1
-      * @param onComplete
-      *        onComplete.obj will be an AsyncResult
-      *        ((AsyncResult)onComplete.obj).exception == null on success
-      *        ((AsyncResult)onComplete.obj).exception != null on fail
-      */
-     public void setIccLockEnabled (boolean enabled,
-             String password, Message onComplete) {
-         int serviceClassX;
-         serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE +
-                 CommandsInterface.SERVICE_CLASS_DATA +
-                 CommandsInterface.SERVICE_CLASS_FAX;
-
-         mDesiredPinLocked = enabled;
-
-         mPhone.mCM.setFacilityLock(CommandsInterface.CB_FACILITY_BA_SIM,
-                 enabled, password, serviceClassX,
-                 mHandler.obtainMessage(EVENT_CHANGE_FACILITY_LOCK_DONE, onComplete));
-     }
-
-     /**
-      * Set the ICC fdn enabled or disabled
-      * When the operation is complete, onComplete will be sent to its handler
-      *
-      * @param enabled "true" for locked "false" for unlocked.
-      * @param password needed to change the ICC fdn enable, aka Pin2
-      * @param onComplete
-      *        onComplete.obj will be an AsyncResult
-      *        ((AsyncResult)onComplete.obj).exception == null on success
-      *        ((AsyncResult)onComplete.obj).exception != null on fail
-      */
-     public void setIccFdnEnabled (boolean enabled,
-             String password, Message onComplete) {
-         int serviceClassX;
-         serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE +
-                 CommandsInterface.SERVICE_CLASS_DATA +
-                 CommandsInterface.SERVICE_CLASS_FAX +
-                 CommandsInterface.SERVICE_CLASS_SMS;
-
-         mDesiredFdnEnabled = enabled;
-
-         mPhone.mCM.setFacilityLock(CommandsInterface.CB_FACILITY_BA_FD,
-                 enabled, password, serviceClassX,
-                 mHandler.obtainMessage(EVENT_CHANGE_FACILITY_FDN_DONE, onComplete));
-     }
-
-     /**
-      * Change the ICC password used in ICC pin lock
-      * When the operation is complete, onComplete will be sent to its handler
-      *
-      * @param oldPassword is the old password
-      * @param newPassword is the new password
-      * @param onComplete
-      *        onComplete.obj will be an AsyncResult
-      *        ((AsyncResult)onComplete.obj).exception == null on success
-      *        ((AsyncResult)onComplete.obj).exception != null on fail
-      */
-     public void changeIccLockPassword(String oldPassword, String newPassword,
-             Message onComplete) {
-         mPhone.mCM.changeIccPin(oldPassword, newPassword,
-                 mHandler.obtainMessage(EVENT_CHANGE_ICC_PASSWORD_DONE, onComplete));
-
-     }
-
-     /**
-      * Change the ICC password used in ICC fdn enable
-      * When the operation is complete, onComplete will be sent to its handler
-      *
-      * @param oldPassword is the old password
-      * @param newPassword is the new password
-      * @param onComplete
-      *        onComplete.obj will be an AsyncResult
-      *        ((AsyncResult)onComplete.obj).exception == null on success
-      *        ((AsyncResult)onComplete.obj).exception != null on fail
-      */
-     public void changeIccFdnPassword(String oldPassword, String newPassword,
-             Message onComplete) {
-         mPhone.mCM.changeIccPin2(oldPassword, newPassword,
-                 mHandler.obtainMessage(EVENT_CHANGE_ICC_PASSWORD_DONE, onComplete));
-
-     }
-
-
-    /**
-     * Returns service provider name stored in ICC card.
-     * If there is no service provider name associated or the record is not
-     * yet available, null will be returned <p>
-     *
-     * Please use this value when display Service Provider Name in idle mode <p>
-     *
-     * Usage of this provider name in the UI is a common carrier requirement.
-     *
-     * Also available via Android property "gsm.sim.operator.alpha"
-     *
-     * @return Service Provider Name stored in ICC card
-     *         null if no service provider name associated or the record is not
-     *         yet available
-     *
-     */
-    public String getServiceProviderName () {
-        return mPhone.mIccRecords.getServiceProviderName();
-    }
-
-    protected void updateStateProperty() {
-        mPhone.setSystemProperty(TelephonyProperties.PROPERTY_SIM_STATE, getState().toString());
-    }
-
-    private void getIccCardStatusDone(AsyncResult ar) {
-        if (ar.exception != null) {
-            Log.e(mLogTag,"Error getting ICC status. "
-                    + "RIL_REQUEST_GET_ICC_STATUS should "
-                    + "never return an error", ar.exception);
-            return;
-        }
-        handleIccCardStatus((IccCardStatus) ar.result);
-    }
-
-    private void handleIccCardStatus(IccCardStatus newCardStatus) {
-        boolean transitionedIntoPinLocked;
-        boolean transitionedIntoAbsent;
-        boolean transitionedIntoNetworkLocked;
-        boolean transitionedIntoPermBlocked;
-        boolean isIccCardRemoved;
-        boolean isIccCardAdded;
-
-        State oldState, newState;
-        State oldRuimState = getRuimState();
-
-        oldState = mState;
-        mIccCardStatus = newCardStatus;
-        newState = getIccCardState();
-
-        synchronized (mStateMonitor) {
-            mState = newState;
-            updateStateProperty();
-            if (oldState != State.READY && newState == State.READY) {
-                mHandler.sendMessage(mHandler.obtainMessage(EVENT_ICC_READY));
-                mReadyRegistrants.notifyRegistrants();
-            } else if (newState.isPinLocked()) {
-                mHandler.sendMessage(mHandler.obtainMessage(EVENT_ICC_LOCKED));
-            }
-            if (oldRuimState != State.READY && getRuimState() == State.READY) {
-                mRuimReadyRegistrants.notifyRegistrants();
-            }
-        }
-
-        transitionedIntoPinLocked = (
-                 (oldState != State.PIN_REQUIRED && newState == State.PIN_REQUIRED)
-              || (oldState != State.PUK_REQUIRED && newState == State.PUK_REQUIRED));
-        transitionedIntoAbsent = (oldState != State.ABSENT && newState == State.ABSENT);
-        transitionedIntoNetworkLocked = (oldState != State.NETWORK_LOCKED
-                && newState == State.NETWORK_LOCKED);
-        transitionedIntoPermBlocked = (oldState != State.PERM_DISABLED
-                && newState == State.PERM_DISABLED);
-        isIccCardRemoved = (oldState != null &&
-                        oldState.iccCardExist() && newState == State.ABSENT);
-        isIccCardAdded = (oldState == State.ABSENT &&
-                        newState != null && newState.iccCardExist());
-
-        if (transitionedIntoPinLocked) {
-            if (mDbg) log("Notify SIM pin or puk locked.");
-            mPinLockedRegistrants.notifyRegistrants();
-            broadcastIccStateChangedIntent(INTENT_VALUE_ICC_LOCKED,
-                    (newState == State.PIN_REQUIRED) ?
-                       INTENT_VALUE_LOCKED_ON_PIN : INTENT_VALUE_LOCKED_ON_PUK);
-        } else if (transitionedIntoAbsent) {
-            if (mDbg) log("Notify SIM missing.");
-            mAbsentRegistrants.notifyRegistrants();
-            broadcastIccStateChangedIntent(INTENT_VALUE_ICC_ABSENT, null);
-        } else if (transitionedIntoNetworkLocked) {
-            if (mDbg) log("Notify SIM network locked.");
-            mNetworkLockedRegistrants.notifyRegistrants();
-            broadcastIccStateChangedIntent(INTENT_VALUE_ICC_LOCKED,
-                  INTENT_VALUE_LOCKED_NETWORK);
-        } else if (transitionedIntoPermBlocked) {
-            if (mDbg) log("Notify SIM permanently disabled.");
-            broadcastIccStateChangedIntent(INTENT_VALUE_ICC_ABSENT,
-                    INTENT_VALUE_ABSENT_ON_PERM_DISABLED);
-        }
-
-        if (isIccCardRemoved) {
-            mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_REMOVED, null));
-        } else if (isIccCardAdded) {
-            mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_ADDED, null));
-        }
-
-        // Call onReady Record(s) on the IccCard becomes ready (not NV)
-        if (oldState != State.READY && newState == State.READY &&
-                (is3gpp || isSubscriptionFromIccCard)) {
-            if (!(mIccFileHandler instanceof CdmaLteUiccFileHandler)) {
-                // CdmaLteUicc File Handler deals with both USIM and CSIM.
-                // Do not lock onto one AID for now.
-                mIccFileHandler.setAid(getAid());
-            }
-            mIccRecords.onReady();
-        }
-    }
-
-    private void onIccSwap(boolean isAdded) {
-        // TODO: Here we assume the device can't handle SIM hot-swap
-        //      and has to reboot. We may want to add a property,
-        //      e.g. REBOOT_ON_SIM_SWAP, to indicate if modem support
-        //      hot-swap.
-        DialogInterface.OnClickListener listener = null;
-
-
-        // TODO: SimRecords is not reset while SIM ABSENT (only reset while
-        //       Radio_off_or_not_available). Have to reset in both both
-        //       added or removed situation.
-        listener = new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(DialogInterface dialog, int which) {
-                if (which == DialogInterface.BUTTON_POSITIVE) {
-                    if (mDbg) log("Reboot due to SIM swap");
-                    PowerManager pm = (PowerManager) mPhone.getContext()
-                    .getSystemService(Context.POWER_SERVICE);
-                    pm.reboot("SIM is added.");
-                }
-            }
-
-        };
-
-        Resources r = Resources.getSystem();
-
-        String title = (isAdded) ? r.getString(R.string.sim_added_title) :
-            r.getString(R.string.sim_removed_title);
-        String message = (isAdded) ? r.getString(R.string.sim_added_message) :
-            r.getString(R.string.sim_removed_message);
-        String buttonTxt = r.getString(R.string.sim_restart_button);
-
-        AlertDialog dialog = new AlertDialog.Builder(mPhone.getContext())
-            .setTitle(title)
-            .setMessage(message)
-            .setPositiveButton(buttonTxt, listener)
-            .create();
-        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
-        dialog.show();
-    }
-
-    /**
-     * Interperate EVENT_QUERY_FACILITY_LOCK_DONE
-     * @param ar is asyncResult of Query_Facility_Locked
-     */
-    private void onQueryFdnEnabled(AsyncResult ar) {
-        if(ar.exception != null) {
-            if(mDbg) log("Error in querying facility lock:" + ar.exception);
-            return;
-        }
-
-        int[] ints = (int[])ar.result;
-        if(ints.length != 0) {
-            mIccFdnEnabled = (0!=ints[0]);
-            if(mDbg) log("Query facility lock : "  + mIccFdnEnabled);
-        } else {
-            Log.e(mLogTag, "[IccCard] Bogus facility lock response");
-        }
-    }
-
-    /**
-     * Interperate EVENT_QUERY_FACILITY_LOCK_DONE
-     * @param ar is asyncResult of Query_Facility_Locked
-     */
-    private void onQueryFacilityLock(AsyncResult ar) {
-        if(ar.exception != null) {
-            if (mDbg) log("Error in querying facility lock:" + ar.exception);
-            return;
-        }
-
-        int[] ints = (int[])ar.result;
-        if(ints.length != 0) {
-            mIccPinLocked = (0!=ints[0]);
-            if(mDbg) log("Query facility lock : "  + mIccPinLocked);
-        } else {
-            Log.e(mLogTag, "[IccCard] Bogus facility lock response");
-        }
-    }
-
-    public void broadcastIccStateChangedIntent(String value, String reason) {
-        Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
-        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
-        intent.putExtra(Phone.PHONE_NAME_KEY, mPhone.getPhoneName());
-        intent.putExtra(INTENT_KEY_ICC_STATE, value);
-        intent.putExtra(INTENT_KEY_LOCKED_REASON, reason);
-        if(mDbg) log("Broadcasting intent ACTION_SIM_STATE_CHANGED " +  value
-                + " reason " + reason);
-        ActivityManagerNative.broadcastStickyIntent(intent, READ_PHONE_STATE);
-    }
-
-    protected Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg){
-            AsyncResult ar;
-            int serviceClassX;
-
-            serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE +
-                            CommandsInterface.SERVICE_CLASS_DATA +
-                            CommandsInterface.SERVICE_CLASS_FAX;
-
-            if (!mPhone.mIsTheCurrentActivePhone) {
-                Log.e(mLogTag, "Received message " + msg + "[" + msg.what
-                        + "] while being destroyed. Ignoring.");
-                return;
-            }
-
-            switch (msg.what) {
-                case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
-                    mState = null;
-                    updateStateProperty();
-                    broadcastIccStateChangedIntent(INTENT_VALUE_ICC_NOT_READY, null);
-                    break;
-                case EVENT_RADIO_ON:
-                    if (!is3gpp) {
-                        handleCdmaSubscriptionSource();
-                    }
-                    mPhone.mCM.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));
-                    break;
-                case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
-                    handleCdmaSubscriptionSource();
-                    break;
-                case EVENT_ICC_READY:
-                    if(isSubscriptionFromIccCard) {
-                        mPhone.mCM.queryFacilityLock (
-                                CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX,
-                                obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE));
-                        mPhone.mCM.queryFacilityLock (
-                                CommandsInterface.CB_FACILITY_BA_FD, "", serviceClassX,
-                                obtainMessage(EVENT_QUERY_FACILITY_FDN_DONE));
-                    }
-                    break;
-                case EVENT_ICC_LOCKED:
-                    mPhone.mCM.queryFacilityLock (
-                             CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX,
-                             obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE));
-                     break;
-                case EVENT_GET_ICC_STATUS_DONE:
-                    ar = (AsyncResult)msg.obj;
-
-                    getIccCardStatusDone(ar);
-                    break;
-                case EVENT_PINPUK_DONE:
-                    // a PIN/PUK/PIN2/PUK2/Network Personalization
-                    // request has completed. ar.userObj is the response Message
-                    // Repoll before returning
-                    ar = (AsyncResult)msg.obj;
-                    // TODO should abstract these exceptions
-                    AsyncResult.forMessage(((Message)ar.userObj)).exception
-                                                        = ar.exception;
-                    mPhone.mCM.getIccCardStatus(
-                        obtainMessage(EVENT_REPOLL_STATUS_DONE, ar.userObj));
-                    break;
-                case EVENT_REPOLL_STATUS_DONE:
-                    // Finished repolling status after PIN operation
-                    // ar.userObj is the response messaeg
-                    // ar.userObj.obj is already an AsyncResult with an
-                    // appropriate exception filled in if applicable
-
-                    ar = (AsyncResult)msg.obj;
-                    getIccCardStatusDone(ar);
-                    ((Message)ar.userObj).sendToTarget();
-                    break;
-                case EVENT_QUERY_FACILITY_LOCK_DONE:
-                    ar = (AsyncResult)msg.obj;
-                    onQueryFacilityLock(ar);
-                    break;
-                case EVENT_QUERY_FACILITY_FDN_DONE:
-                    ar = (AsyncResult)msg.obj;
-                    onQueryFdnEnabled(ar);
-                    break;
-                case EVENT_CHANGE_FACILITY_LOCK_DONE:
-                    ar = (AsyncResult)msg.obj;
-                    if (ar.exception == null) {
-                        mIccPinLocked = mDesiredPinLocked;
-                        if (mDbg) log( "EVENT_CHANGE_FACILITY_LOCK_DONE: " +
-                                "mIccPinLocked= " + mIccPinLocked);
-                    } else {
-                        Log.e(mLogTag, "Error change facility lock with exception "
-                            + ar.exception);
-                    }
-                    AsyncResult.forMessage(((Message)ar.userObj)).exception
-                                                        = ar.exception;
-                    ((Message)ar.userObj).sendToTarget();
-                    break;
-                case EVENT_CHANGE_FACILITY_FDN_DONE:
-                    ar = (AsyncResult)msg.obj;
-
-                    if (ar.exception == null) {
-                        mIccFdnEnabled = mDesiredFdnEnabled;
-                        if (mDbg) log("EVENT_CHANGE_FACILITY_FDN_DONE: " +
-                                "mIccFdnEnabled=" + mIccFdnEnabled);
-                    } else {
-                        Log.e(mLogTag, "Error change facility fdn with exception "
-                                + ar.exception);
-                    }
-                    AsyncResult.forMessage(((Message)ar.userObj)).exception
-                                                        = ar.exception;
-                    ((Message)ar.userObj).sendToTarget();
-                    break;
-                case EVENT_CHANGE_ICC_PASSWORD_DONE:
-                    ar = (AsyncResult)msg.obj;
-                    if(ar.exception != null) {
-                        Log.e(mLogTag, "Error in change sim password with exception"
-                            + ar.exception);
-                    }
-                    AsyncResult.forMessage(((Message)ar.userObj)).exception
-                                                        = ar.exception;
-                    ((Message)ar.userObj).sendToTarget();
-                    break;
-                case EVENT_ICC_STATUS_CHANGED:
-                    Log.d(mLogTag, "Received Event EVENT_ICC_STATUS_CHANGED");
-                    mPhone.mCM.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));
-                    break;
-                case EVENT_CARD_REMOVED:
-                    onIccSwap(false);
-                    break;
-                case EVENT_CARD_ADDED:
-                    onIccSwap(true);
-                    break;
-                default:
-                    Log.e(mLogTag, "[IccCard] Unknown Event " + msg.what);
-            }
-        }
-    };
-
-    private void handleCdmaSubscriptionSource() {
-        if(mCdmaSSM != null)  {
-            int newSubscriptionSource = mCdmaSSM.getCdmaSubscriptionSource();
-
-            Log.d(mLogTag, "Received Cdma subscription source: " + newSubscriptionSource);
-
-            boolean isNewSubFromRuim =
-                (newSubscriptionSource == CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM);
-
-            if (isNewSubFromRuim != isSubscriptionFromIccCard) {
-                isSubscriptionFromIccCard = isNewSubFromRuim;
-                // Parse the Stored IccCardStatus Message to set mState correctly.
-                handleIccCardStatus(mIccCardStatus);
-            }
-        }
-    }
-
-    public State getIccCardState() {
-        if(!is3gpp && !isSubscriptionFromIccCard) {
-            // CDMA can get subscription from NV. In that case,
-            // subscription is ready as soon as Radio is ON.
-            return State.READY;
-        }
-
-        if (mIccCardStatus == null) {
-            Log.e(mLogTag, "[IccCard] IccCardStatus is null");
-            return IccCard.State.ABSENT;
-        }
-
-        // this is common for all radio technologies
-        if (!mIccCardStatus.getCardState().isCardPresent()) {
-            return IccCard.State.ABSENT;
-        }
-
-        RadioState currentRadioState = mPhone.mCM.getRadioState();
-        // check radio technology
-        if( currentRadioState == RadioState.RADIO_OFF         ||
-            currentRadioState == RadioState.RADIO_UNAVAILABLE) {
-            return IccCard.State.NOT_READY;
-        }
-
-        if( currentRadioState == RadioState.RADIO_ON ) {
-            State csimState =
-                getAppState(mIccCardStatus.getCdmaSubscriptionAppIndex());
-            State usimState =
-                getAppState(mIccCardStatus.getGsmUmtsSubscriptionAppIndex());
-
-            if(mDbg) log("USIM=" + usimState + " CSIM=" + csimState);
-
-            if (mPhone.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE) {
-                // UICC card contains both USIM and CSIM
-                // Return consolidated status
-                return getConsolidatedState(csimState, usimState, csimState);
-            }
-
-            // check for CDMA radio technology
-            if (!is3gpp) {
-                return csimState;
-            }
-            return usimState;
-        }
-
-        return IccCard.State.ABSENT;
-    }
-
-    private State getAppState(int appIndex) {
-        IccCardApplication app;
-        if (appIndex >= 0 && appIndex < IccCardStatus.CARD_MAX_APPS) {
-            app = mIccCardStatus.getApplication(appIndex);
-        } else {
-            Log.e(mLogTag, "[IccCard] Invalid Subscription Application index:" + appIndex);
-            return IccCard.State.ABSENT;
-        }
-
-        if (app == null) {
-            Log.e(mLogTag, "[IccCard] Subscription Application in not present");
-            return IccCard.State.ABSENT;
-        }
-
-        // check if PIN required
-        if (app.pin1.isPermBlocked()) {
-            return IccCard.State.PERM_DISABLED;
-        }
-        if (app.app_state.isPinRequired()) {
-            return IccCard.State.PIN_REQUIRED;
-        }
-        if (app.app_state.isPukRequired()) {
-            return IccCard.State.PUK_REQUIRED;
-        }
-        if (app.app_state.isSubscriptionPersoEnabled()) {
-            return IccCard.State.NETWORK_LOCKED;
-        }
-        if (app.app_state.isAppReady()) {
-            return IccCard.State.READY;
-        }
-        if (app.app_state.isAppNotReady()) {
-            return IccCard.State.NOT_READY;
-        }
-        return IccCard.State.NOT_READY;
-    }
-
-    private State getConsolidatedState(State left, State right, State preferredState) {
-        // Check if either is absent.
-        if (right == IccCard.State.ABSENT) return left;
-        if (left == IccCard.State.ABSENT) return right;
-
-        // Only if both are ready, return ready
-        if ((left == IccCard.State.READY) && (right == IccCard.State.READY)) {
-            return State.READY;
-        }
-
-        // Case one is ready, but the other is not.
-        if (((right == IccCard.State.NOT_READY) && (left == IccCard.State.READY)) ||
-            ((left == IccCard.State.NOT_READY) && (right == IccCard.State.READY))) {
-            return IccCard.State.NOT_READY;
-        }
-
-        // At this point, the other state is assumed to be one of locked state
-        if (right == IccCard.State.NOT_READY) return left;
-        if (left == IccCard.State.NOT_READY) return right;
-
-        // At this point, FW currently just assumes the status will be
-        // consistent across the applications...
-        return preferredState;
-    }
-
-    public boolean isApplicationOnIcc(IccCardApplication.AppType type) {
-        if (mIccCardStatus == null) return false;
-
-        for (int i = 0 ; i < mIccCardStatus.getNumApplications(); i++) {
-            IccCardApplication app = mIccCardStatus.getApplication(i);
-            if (app != null && app.app_type == type) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * @return true if a ICC card is present
-     */
-    public boolean hasIccCard() {
-        if (mIccCardStatus == null) {
-            return false;
-        } else {
-            // Returns ICC card status for both GSM and CDMA mode
-            return mIccCardStatus.getCardState().isCardPresent();
-        }
-    }
-
-    private void log(String msg) {
-        Log.d(mLogTag, "[IccCard] " + msg);
-    }
-
-    protected int getCurrentApplicationIndex() {
-        if (is3gpp) {
-            return mIccCardStatus.getGsmUmtsSubscriptionAppIndex();
-        } else {
-            return mIccCardStatus.getCdmaSubscriptionAppIndex();
-        }
-    }
-
-    public String getAid() {
-        String aid = "";
-        if (mIccCardStatus == null) {
-            return aid;
-        }
-
-        int appIndex = getCurrentApplicationIndex();
-
-        if (appIndex >= 0 && appIndex < IccCardStatus.CARD_MAX_APPS) {
-            IccCardApplication app = mIccCardStatus.getApplication(appIndex);
-            if (app != null) {
-                aid = app.aid;
-            } else {
-                Log.e(mLogTag, "[IccCard] getAid: no current application index=" + appIndex);
-            }
-        } else {
-            Log.e(mLogTag, "[IccCard] getAid: Invalid Subscription Application index=" + appIndex);
-        }
-
-        return aid;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/IccCardApplication.java b/telephony/java/com/android/internal/telephony/IccCardApplication.java
deleted file mode 100644
index abb740e..0000000
--- a/telephony/java/com/android/internal/telephony/IccCardApplication.java
+++ /dev/null
@@ -1,226 +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.internal.telephony;
-
-import com.android.internal.telephony.IccCardStatus.PinState;
-
-
-/**
- * See also RIL_AppStatus in include/telephony/ril.h
- *
- * {@hide}
- */
-public class IccCardApplication {
-    public enum AppType{
-        APPTYPE_UNKNOWN,
-        APPTYPE_SIM,
-        APPTYPE_USIM,
-        APPTYPE_RUIM,
-        APPTYPE_CSIM,
-        APPTYPE_ISIM
-    };
-
-    public enum AppState{
-        APPSTATE_UNKNOWN,
-        APPSTATE_DETECTED,
-        APPSTATE_PIN,
-        APPSTATE_PUK,
-        APPSTATE_SUBSCRIPTION_PERSO,
-        APPSTATE_READY;
-
-        boolean isPinRequired() {
-            return this == APPSTATE_PIN;
-        }
-
-        boolean isPukRequired() {
-            return this == APPSTATE_PUK;
-        }
-
-        boolean isSubscriptionPersoEnabled() {
-            return this == APPSTATE_SUBSCRIPTION_PERSO;
-        }
-
-        boolean isAppReady() {
-            return this == APPSTATE_READY;
-        }
-
-        boolean isAppNotReady() {
-            return this == APPSTATE_UNKNOWN  ||
-                   this == APPSTATE_DETECTED;
-        }
-    };
-
-    public enum PersoSubState{
-        PERSOSUBSTATE_UNKNOWN,
-        PERSOSUBSTATE_IN_PROGRESS,
-        PERSOSUBSTATE_READY,
-        PERSOSUBSTATE_SIM_NETWORK,
-        PERSOSUBSTATE_SIM_NETWORK_SUBSET,
-        PERSOSUBSTATE_SIM_CORPORATE,
-        PERSOSUBSTATE_SIM_SERVICE_PROVIDER,
-        PERSOSUBSTATE_SIM_SIM,
-        PERSOSUBSTATE_SIM_NETWORK_PUK,
-        PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK,
-        PERSOSUBSTATE_SIM_CORPORATE_PUK,
-        PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK,
-        PERSOSUBSTATE_SIM_SIM_PUK,
-        PERSOSUBSTATE_RUIM_NETWORK1,
-        PERSOSUBSTATE_RUIM_NETWORK2,
-        PERSOSUBSTATE_RUIM_HRPD,
-        PERSOSUBSTATE_RUIM_CORPORATE,
-        PERSOSUBSTATE_RUIM_SERVICE_PROVIDER,
-        PERSOSUBSTATE_RUIM_RUIM,
-        PERSOSUBSTATE_RUIM_NETWORK1_PUK,
-        PERSOSUBSTATE_RUIM_NETWORK2_PUK,
-        PERSOSUBSTATE_RUIM_HRPD_PUK,
-        PERSOSUBSTATE_RUIM_CORPORATE_PUK,
-        PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK,
-        PERSOSUBSTATE_RUIM_RUIM_PUK;
-
-        boolean isPersoSubStateUnknown() {
-            return this == PERSOSUBSTATE_UNKNOWN;
-        }
-    };
-
-    public AppType        app_type;
-    public AppState       app_state;
-    // applicable only if app_state == RIL_APPSTATE_SUBSCRIPTION_PERSO
-    public PersoSubState  perso_substate;
-    // null terminated string, e.g., from 0xA0, 0x00 -> 0x41, 0x30, 0x30, 0x30 */
-    public String         aid;
-    // null terminated string
-    public String         app_label;
-    // applicable to USIM and CSIM
-    public int            pin1_replaced;
-    public PinState            pin1;
-    public PinState            pin2;
-
-    AppType AppTypeFromRILInt(int type) {
-        AppType newType;
-        /* RIL_AppType ril.h */
-        switch(type) {
-            case 0: newType = AppType.APPTYPE_UNKNOWN; break;
-            case 1: newType = AppType.APPTYPE_SIM;     break;
-            case 2: newType = AppType.APPTYPE_USIM;    break;
-            case 3: newType = AppType.APPTYPE_RUIM;    break;
-            case 4: newType = AppType.APPTYPE_CSIM;    break;
-            case 5: newType = AppType.APPTYPE_ISIM;    break;
-            default:
-                throw new RuntimeException(
-                            "Unrecognized RIL_AppType: " +type);
-        }
-        return newType;
-    }
-
-    AppState AppStateFromRILInt(int state) {
-        AppState newState;
-        /* RIL_AppState ril.h */
-        switch(state) {
-            case 0: newState = AppState.APPSTATE_UNKNOWN;  break;
-            case 1: newState = AppState.APPSTATE_DETECTED; break;
-            case 2: newState = AppState.APPSTATE_PIN; break;
-            case 3: newState = AppState.APPSTATE_PUK; break;
-            case 4: newState = AppState.APPSTATE_SUBSCRIPTION_PERSO; break;
-            case 5: newState = AppState.APPSTATE_READY; break;
-            default:
-                throw new RuntimeException(
-                            "Unrecognized RIL_AppState: " +state);
-        }
-        return newState;
-    }
-
-    PersoSubState PersoSubstateFromRILInt(int substate) {
-        PersoSubState newSubState;
-        /* RIL_PeroSubstate ril.h */
-        switch(substate) {
-            case 0:  newSubState = PersoSubState.PERSOSUBSTATE_UNKNOWN;  break;
-            case 1:  newSubState = PersoSubState.PERSOSUBSTATE_IN_PROGRESS; break;
-            case 2:  newSubState = PersoSubState.PERSOSUBSTATE_READY; break;
-            case 3:  newSubState = PersoSubState.PERSOSUBSTATE_SIM_NETWORK; break;
-            case 4:  newSubState = PersoSubState.PERSOSUBSTATE_SIM_NETWORK_SUBSET; break;
-            case 5:  newSubState = PersoSubState.PERSOSUBSTATE_SIM_CORPORATE; break;
-            case 6:  newSubState = PersoSubState.PERSOSUBSTATE_SIM_SERVICE_PROVIDER; break;
-            case 7:  newSubState = PersoSubState.PERSOSUBSTATE_SIM_SIM;  break;
-            case 8:  newSubState = PersoSubState.PERSOSUBSTATE_SIM_NETWORK_PUK; break;
-            case 9:  newSubState = PersoSubState.PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK; break;
-            case 10: newSubState = PersoSubState.PERSOSUBSTATE_SIM_CORPORATE_PUK; break;
-            case 11: newSubState = PersoSubState.PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK; break;
-            case 12: newSubState = PersoSubState.PERSOSUBSTATE_SIM_SIM_PUK; break;
-            case 13: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_NETWORK1; break;
-            case 14: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_NETWORK2; break;
-            case 15: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_HRPD; break;
-            case 16: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_CORPORATE; break;
-            case 17: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_SERVICE_PROVIDER; break;
-            case 18: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_RUIM; break;
-            case 19: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_NETWORK1_PUK; break;
-            case 20: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_NETWORK2_PUK; break;
-            case 21: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_HRPD_PUK ; break;
-            case 22: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_CORPORATE_PUK; break;
-            case 23: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK; break;
-            case 24: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_RUIM_PUK; break;
-            default:
-                throw new RuntimeException(
-                            "Unrecognized RIL_PersoSubstate: " +substate);
-        }
-        return newSubState;
-    }
-
-    PinState PinStateFromRILInt(int state) {
-        PinState newPinState;
-        switch(state) {
-            case 0:
-                newPinState = PinState.PINSTATE_UNKNOWN;
-                break;
-            case 1:
-                newPinState = PinState.PINSTATE_ENABLED_NOT_VERIFIED;
-                break;
-            case 2:
-                newPinState = PinState.PINSTATE_ENABLED_VERIFIED;
-                break;
-            case 3:
-                newPinState = PinState.PINSTATE_DISABLED;
-                break;
-            case 4:
-                newPinState = PinState.PINSTATE_ENABLED_BLOCKED;
-                break;
-            case 5:
-                newPinState = PinState.PINSTATE_ENABLED_PERM_BLOCKED;
-                break;
-            default:
-                throw new RuntimeException("Unrecognized RIL_PinState: " + state);
-        }
-        return newPinState;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append("{").append(app_type).append(",").append(app_state);
-        if (app_state == AppState.APPSTATE_SUBSCRIPTION_PERSO) {
-            sb.append(",").append(perso_substate);
-        }
-        if (app_type == AppType.APPTYPE_CSIM ||
-                app_type == AppType.APPTYPE_USIM ||
-                app_type == AppType.APPTYPE_ISIM) {
-            sb.append(",pin1=").append(pin1);
-            sb.append(",pin2=").append(pin2);
-        }
-        sb.append("}");
-        return sb.toString();
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/IccCardConstants.java b/telephony/java/com/android/internal/telephony/IccCardConstants.java
new file mode 100644
index 0000000..236bb2f
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/IccCardConstants.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2012 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.internal.telephony;
+
+/**
+ * {@hide}
+ */
+public class IccCardConstants {
+
+    /* The extra data for broacasting intent INTENT_ICC_STATE_CHANGE */
+    public static final String INTENT_KEY_ICC_STATE = "ss";
+    /* UNKNOWN means the ICC state is unknown */
+    public static final String INTENT_VALUE_ICC_UNKNOWN = "UNKNOWN";
+    /* NOT_READY means the ICC interface is not ready (eg, radio is off or powering on) */
+    public static final String INTENT_VALUE_ICC_NOT_READY = "NOT_READY";
+    /* ABSENT means ICC is missing */
+    public static final String INTENT_VALUE_ICC_ABSENT = "ABSENT";
+    /* LOCKED means ICC is locked by pin or by network */
+    public static final String INTENT_VALUE_ICC_LOCKED = "LOCKED";
+    /* READY means ICC is ready to access */
+    public static final String INTENT_VALUE_ICC_READY = "READY";
+    /* IMSI means ICC IMSI is ready in property */
+    public static final String INTENT_VALUE_ICC_IMSI = "IMSI";
+    /* LOADED means all ICC records, including IMSI, are loaded */
+    public static final String INTENT_VALUE_ICC_LOADED = "LOADED";
+    /* The extra data for broacasting intent INTENT_ICC_STATE_CHANGE */
+    public static final String INTENT_KEY_LOCKED_REASON = "reason";
+    /* PIN means ICC is locked on PIN1 */
+    public static final String INTENT_VALUE_LOCKED_ON_PIN = "PIN";
+    /* PUK means ICC is locked on PUK1 */
+    public static final String INTENT_VALUE_LOCKED_ON_PUK = "PUK";
+    /* NETWORK means ICC is locked on NETWORK PERSONALIZATION */
+    public static final String INTENT_VALUE_LOCKED_NETWORK = "NETWORK";
+    /* PERM_DISABLED means ICC is permanently disabled due to puk fails */
+    public static final String INTENT_VALUE_ABSENT_ON_PERM_DISABLED = "PERM_DISABLED";
+
+    /**
+     * This is combination of IccCardStatus.CardState and IccCardApplicationStatus.AppState
+     * for external apps (like PhoneApp) to use
+     *
+     * UNKNOWN is a transient state, for example, after user inputs ICC pin under
+     * PIN_REQUIRED state, the query for ICC status returns UNKNOWN before it
+     * turns to READY
+     */
+    public enum State {
+        UNKNOWN,
+        ABSENT,
+        PIN_REQUIRED,
+        PUK_REQUIRED,
+        NETWORK_LOCKED,
+        READY,
+        NOT_READY,
+        PERM_DISABLED;
+
+        public boolean isPinLocked() {
+            return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED));
+        }
+
+        public boolean iccCardExist() {
+            return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED)
+                    || (this == NETWORK_LOCKED) || (this == READY)
+                    || (this == PERM_DISABLED));
+        }
+    }
+}
diff --git a/telephony/java/com/android/internal/telephony/IccCardStatus.java b/telephony/java/com/android/internal/telephony/IccCardStatus.java
deleted file mode 100644
index a3bdd76..0000000
--- a/telephony/java/com/android/internal/telephony/IccCardStatus.java
+++ /dev/null
@@ -1,188 +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.internal.telephony;
-
-import java.util.ArrayList;
-
-/**
- * See also RIL_CardStatus in include/telephony/ril.h
- *
- * {@hide}
- */
-public class IccCardStatus {
-    public static final int CARD_MAX_APPS = 8;
-
-    public enum CardState {
-        CARDSTATE_ABSENT,
-        CARDSTATE_PRESENT,
-        CARDSTATE_ERROR;
-
-        boolean isCardPresent() {
-            return this == CARDSTATE_PRESENT;
-        }
-    }
-
-    public enum PinState {
-        PINSTATE_UNKNOWN,
-        PINSTATE_ENABLED_NOT_VERIFIED,
-        PINSTATE_ENABLED_VERIFIED,
-        PINSTATE_DISABLED,
-        PINSTATE_ENABLED_BLOCKED,
-        PINSTATE_ENABLED_PERM_BLOCKED;
-
-        boolean isPermBlocked() {
-            return this == PINSTATE_ENABLED_PERM_BLOCKED;
-        }
-
-        boolean isPinRequired() {
-            return this == PINSTATE_ENABLED_NOT_VERIFIED;
-        }
-
-        boolean isPukRequired() {
-            return this == PINSTATE_ENABLED_BLOCKED;
-        }
-    }
-
-    private CardState  mCardState;
-    private PinState   mUniversalPinState;
-    private int        mGsmUmtsSubscriptionAppIndex;
-    private int        mCdmaSubscriptionAppIndex;
-    private int        mImsSubscriptionAppIndex;
-    private int        mNumApplications;
-
-    private ArrayList<IccCardApplication> mApplications =
-            new ArrayList<IccCardApplication>(CARD_MAX_APPS);
-
-    public CardState getCardState() {
-        return mCardState;
-    }
-
-    public void setCardState(int state) {
-        switch(state) {
-        case 0:
-            mCardState = CardState.CARDSTATE_ABSENT;
-            break;
-        case 1:
-            mCardState = CardState.CARDSTATE_PRESENT;
-            break;
-        case 2:
-            mCardState = CardState.CARDSTATE_ERROR;
-            break;
-        default:
-            throw new RuntimeException("Unrecognized RIL_CardState: " + state);
-        }
-    }
-
-    public PinState getUniversalPinState() {
-        return mUniversalPinState;
-    }
-
-    public void setUniversalPinState(int state) {
-        switch(state) {
-        case 0:
-            mUniversalPinState = PinState.PINSTATE_UNKNOWN;
-            break;
-        case 1:
-            mUniversalPinState = PinState.PINSTATE_ENABLED_NOT_VERIFIED;
-            break;
-        case 2:
-            mUniversalPinState = PinState.PINSTATE_ENABLED_VERIFIED;
-            break;
-        case 3:
-            mUniversalPinState = PinState.PINSTATE_DISABLED;
-            break;
-        case 4:
-            mUniversalPinState = PinState.PINSTATE_ENABLED_BLOCKED;
-            break;
-        case 5:
-            mUniversalPinState = PinState.PINSTATE_ENABLED_PERM_BLOCKED;
-            break;
-        default:
-            throw new RuntimeException("Unrecognized RIL_PinState: " + state);
-        }
-    }
-
-    public int getGsmUmtsSubscriptionAppIndex() {
-        return mGsmUmtsSubscriptionAppIndex;
-    }
-
-    public void setGsmUmtsSubscriptionAppIndex(int gsmUmtsSubscriptionAppIndex) {
-        mGsmUmtsSubscriptionAppIndex = gsmUmtsSubscriptionAppIndex;
-    }
-
-    public int getCdmaSubscriptionAppIndex() {
-        return mCdmaSubscriptionAppIndex;
-    }
-
-    public void setCdmaSubscriptionAppIndex(int cdmaSubscriptionAppIndex) {
-        mCdmaSubscriptionAppIndex = cdmaSubscriptionAppIndex;
-    }
-
-    public int getImsSubscriptionAppIndex() {
-        return mImsSubscriptionAppIndex;
-    }
-
-    public void setImsSubscriptionAppIndex(int imsSubscriptionAppIndex) {
-        mImsSubscriptionAppIndex = imsSubscriptionAppIndex;
-    }
-
-    public int getNumApplications() {
-        return mNumApplications;
-    }
-
-    public void setNumApplications(int numApplications) {
-        mNumApplications = numApplications;
-    }
-
-    public void addApplication(IccCardApplication application) {
-        mApplications.add(application);
-    }
-
-    public IccCardApplication getApplication(int index) {
-        return mApplications.get(index);
-    }
-
-    @Override
-    public String toString() {
-        IccCardApplication app;
-
-        StringBuilder sb = new StringBuilder();
-        sb.append("IccCardState {").append(mCardState).append(",")
-        .append(mUniversalPinState)
-        .append(",num_apps=").append(mNumApplications)
-        .append(",gsm_id=").append(mGsmUmtsSubscriptionAppIndex);
-        if (mGsmUmtsSubscriptionAppIndex >=0
-                && mGsmUmtsSubscriptionAppIndex <CARD_MAX_APPS) {
-            app = getApplication(mGsmUmtsSubscriptionAppIndex);
-            sb.append(app == null ? "null" : app);
-        }
-
-        sb.append(",cmda_id=").append(mCdmaSubscriptionAppIndex);
-        if (mCdmaSubscriptionAppIndex >=0
-                && mCdmaSubscriptionAppIndex <CARD_MAX_APPS) {
-            app = getApplication(mCdmaSubscriptionAppIndex);
-            sb.append(app == null ? "null" : app);
-        }
-
-        sb.append(",ism_id=").append(mImsSubscriptionAppIndex);
-
-        sb.append("}");
-
-        return sb.toString();
-    }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/IccConstants.java b/telephony/java/com/android/internal/telephony/IccConstants.java
deleted file mode 100644
index 1ba6dfe..0000000
--- a/telephony/java/com/android/internal/telephony/IccConstants.java
+++ /dev/null
@@ -1,90 +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.internal.telephony;
-
-/**
- * {@hide}
- */
-public interface IccConstants {
-    // GSM SIM file ids from TS 51.011
-    static final int EF_ADN = 0x6F3A;
-    static final int EF_FDN = 0x6F3B;
-    static final int EF_SDN = 0x6F49;
-    static final int EF_EXT1 = 0x6F4A;
-    static final int EF_EXT2 = 0x6F4B;
-    static final int EF_EXT3 = 0x6F4C;
-    static final int EF_EXT6 = 0x6fc8;   // Ext record for EF[MBDN]
-    static final int EF_MWIS = 0x6FCA;
-    static final int EF_MBDN = 0x6fc7;
-    static final int EF_PNN = 0x6fc5;
-    static final int EF_SPN = 0x6F46;
-    static final int EF_SMS = 0x6F3C;
-    static final int EF_ICCID = 0x2fe2;
-    static final int EF_AD = 0x6FAD;
-    static final int EF_MBI = 0x6fc9;
-    static final int EF_MSISDN = 0x6f40;
-    static final int EF_SPDI = 0x6fcd;
-    static final int EF_SST = 0x6f38;
-    static final int EF_CFIS = 0x6FCB;
-    static final int EF_IMG = 0x4f20;
-
-    // USIM SIM file ids from TS 31.102
-    public static final int EF_PBR = 0x4F30;
-
-    // GSM SIM file ids from CPHS (phase 2, version 4.2) CPHS4_2.WW6
-    static final int EF_MAILBOX_CPHS = 0x6F17;
-    static final int EF_VOICE_MAIL_INDICATOR_CPHS = 0x6F11;
-    static final int EF_CFF_CPHS = 0x6F13;
-    static final int EF_SPN_CPHS = 0x6f14;
-    static final int EF_SPN_SHORT_CPHS = 0x6f18;
-    static final int EF_INFO_CPHS = 0x6f16;
-    static final int EF_CSP_CPHS = 0x6f15;
-
-    // CDMA RUIM file ids from 3GPP2 C.S0023-0
-    static final int EF_CST = 0x6f32;
-    static final int EF_RUIM_SPN =0x6F41;
-
-    // ETSI TS.102.221
-    static final int EF_PL = 0x2F05;
-    // 3GPP2 C.S0065
-    static final int EF_CSIM_LI = 0x6F3A;
-    static final int EF_CSIM_SPN =0x6F41;
-    static final int EF_CSIM_MDN = 0x6F44;
-    static final int EF_CSIM_IMSIM = 0x6F22;
-    static final int EF_CSIM_CDMAHOME = 0x6F28;
-    static final int EF_CSIM_EPRL = 0x6F5A;
-
-    //ISIM access
-    static final int EF_IMPU = 0x6f04;
-    static final int EF_IMPI = 0x6f02;
-    static final int EF_DOMAIN = 0x6f03;
-    static final int EF_IST = 0x6f07;
-    static final int EF_PCSCF = 0x6f09;
-
-    // SMS record length from TS 51.011 10.5.3
-    static public final int SMS_RECORD_LENGTH = 176;
-
-    static final String MF_SIM = "3F00";
-    static final String DF_TELECOM = "7F10";
-    static final String DF_PHONEBOOK = "5F3A";
-    static final String DF_GRAPHICS = "5F50";
-    static final String DF_GSM = "7F20";
-    static final String DF_CDMA = "7F25";
-
-    //ISIM access
-    static final String DF_ADFISIM = "7FFF";
-}
diff --git a/telephony/java/com/android/internal/telephony/IccFileHandler.java b/telephony/java/com/android/internal/telephony/IccFileHandler.java
deleted file mode 100644
index 70d8f7a..0000000
--- a/telephony/java/com/android/internal/telephony/IccFileHandler.java
+++ /dev/null
@@ -1,551 +0,0 @@
-/*
- * 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.internal.telephony;
-
-import android.os.*;
-import android.util.Log;
-import java.util.ArrayList;
-
-/**
- * {@hide}
- */
-public abstract class IccFileHandler extends Handler implements IccConstants {
-
-    //from TS 11.11 9.1 or elsewhere
-    static protected final int COMMAND_READ_BINARY = 0xb0;
-    static protected final int COMMAND_UPDATE_BINARY = 0xd6;
-    static protected final int COMMAND_READ_RECORD = 0xb2;
-    static protected final int COMMAND_UPDATE_RECORD = 0xdc;
-    static protected final int COMMAND_SEEK = 0xa2;
-    static protected final int COMMAND_GET_RESPONSE = 0xc0;
-
-    // from TS 11.11 9.2.5
-    static protected final int READ_RECORD_MODE_ABSOLUTE = 4;
-
-    //***** types of files  TS 11.11 9.3
-    static protected final int EF_TYPE_TRANSPARENT = 0;
-    static protected final int EF_TYPE_LINEAR_FIXED = 1;
-    static protected final int EF_TYPE_CYCLIC = 3;
-
-    //***** types of files  TS 11.11 9.3
-    static protected final int TYPE_RFU = 0;
-    static protected final int TYPE_MF  = 1;
-    static protected final int TYPE_DF  = 2;
-    static protected final int TYPE_EF  = 4;
-
-    // size of GET_RESPONSE for EF's
-    static protected final int GET_RESPONSE_EF_SIZE_BYTES = 15;
-    static protected final int GET_RESPONSE_EF_IMG_SIZE_BYTES = 10;
-
-    // Byte order received in response to COMMAND_GET_RESPONSE
-    // Refer TS 51.011 Section 9.2.1
-    static protected final int RESPONSE_DATA_RFU_1 = 0;
-    static protected final int RESPONSE_DATA_RFU_2 = 1;
-
-    static protected final int RESPONSE_DATA_FILE_SIZE_1 = 2;
-    static protected final int RESPONSE_DATA_FILE_SIZE_2 = 3;
-
-    static protected final int RESPONSE_DATA_FILE_ID_1 = 4;
-    static protected final int RESPONSE_DATA_FILE_ID_2 = 5;
-    static protected final int RESPONSE_DATA_FILE_TYPE = 6;
-    static protected final int RESPONSE_DATA_RFU_3 = 7;
-    static protected final int RESPONSE_DATA_ACCESS_CONDITION_1 = 8;
-    static protected final int RESPONSE_DATA_ACCESS_CONDITION_2 = 9;
-    static protected final int RESPONSE_DATA_ACCESS_CONDITION_3 = 10;
-    static protected final int RESPONSE_DATA_FILE_STATUS = 11;
-    static protected final int RESPONSE_DATA_LENGTH = 12;
-    static protected final int RESPONSE_DATA_STRUCTURE = 13;
-    static protected final int RESPONSE_DATA_RECORD_LENGTH = 14;
-
-
-    //***** Events
-
-    /** Finished retrieving size of transparent EF; start loading. */
-    static protected final int EVENT_GET_BINARY_SIZE_DONE = 4;
-    /** Finished loading contents of transparent EF; post result. */
-    static protected final int EVENT_READ_BINARY_DONE = 5;
-    /** Finished retrieving size of records for linear-fixed EF; now load. */
-    static protected final int EVENT_GET_RECORD_SIZE_DONE = 6;
-    /** Finished loading single record from a linear-fixed EF; post result. */
-    static protected final int EVENT_READ_RECORD_DONE = 7;
-    /** Finished retrieving record size; post result. */
-    static protected final int EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE = 8;
-    /** Finished retrieving image instance record; post result. */
-    static protected final int EVENT_READ_IMG_DONE = 9;
-    /** Finished retrieving icon data; post result. */
-    static protected final int EVENT_READ_ICON_DONE = 10;
-
-     // member variables
-    protected final CommandsInterface mCi;
-    protected final IccCard mParentCard;
-    protected String mAid;
-
-    static class LoadLinearFixedContext {
-
-        int efid;
-        int recordNum, recordSize, countRecords;
-        boolean loadAll;
-
-        Message onLoaded;
-
-        ArrayList<byte[]> results;
-
-        LoadLinearFixedContext(int efid, int recordNum, Message onLoaded) {
-            this.efid = efid;
-            this.recordNum = recordNum;
-            this.onLoaded = onLoaded;
-            this.loadAll = false;
-        }
-
-        LoadLinearFixedContext(int efid, Message onLoaded) {
-            this.efid = efid;
-            this.recordNum = 1;
-            this.loadAll = true;
-            this.onLoaded = onLoaded;
-        }
-    }
-
-    /**
-     * Default constructor
-     */
-    protected IccFileHandler(IccCard card, String aid, CommandsInterface ci) {
-        mParentCard = card;
-        mAid = aid;
-        mCi = ci;
-    }
-
-    public void dispose() {
-    }
-
-    //***** Public Methods
-
-    /**
-     * Load a record from a SIM Linear Fixed EF
-     *
-     * @param fileid EF id
-     * @param recordNum 1-based (not 0-based) record number
-     * @param onLoaded
-     *
-     * ((AsyncResult)(onLoaded.obj)).result is the byte[]
-     *
-     */
-    public void loadEFLinearFixed(int fileid, int recordNum, Message onLoaded) {
-        Message response
-            = obtainMessage(EVENT_GET_RECORD_SIZE_DONE,
-                        new LoadLinearFixedContext(fileid, recordNum, onLoaded));
-
-        mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid),
-                        0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, response);
-    }
-
-    /**
-     * Load a image instance record from a SIM Linear Fixed EF-IMG
-     *
-     * @param recordNum 1-based (not 0-based) record number
-     * @param onLoaded
-     *
-     * ((AsyncResult)(onLoaded.obj)).result is the byte[]
-     *
-     */
-    public void loadEFImgLinearFixed(int recordNum, Message onLoaded) {
-        Message response = obtainMessage(EVENT_READ_IMG_DONE,
-                new LoadLinearFixedContext(IccConstants.EF_IMG, recordNum,
-                        onLoaded));
-
-        // TODO(): Verify when path changes are done.
-        mCi.iccIOForApp(COMMAND_GET_RESPONSE, IccConstants.EF_IMG, "img",
-                recordNum, READ_RECORD_MODE_ABSOLUTE,
-                GET_RESPONSE_EF_IMG_SIZE_BYTES, null, null, mAid, response);
-    }
-
-    /**
-     * get record size for a linear fixed EF
-     *
-     * @param fileid EF id
-     * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the recordSize[]
-     *        int[0] is the record length int[1] is the total length of the EF
-     *        file int[3] is the number of records in the EF file So int[0] *
-     *        int[3] = int[1]
-     */
-    public void getEFLinearRecordSize(int fileid, Message onLoaded) {
-        Message response
-                = obtainMessage(EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE,
-                        new LoadLinearFixedContext(fileid, onLoaded));
-        mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid),
-                    0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, response);
-    }
-
-    /**
-     * Load all records from a SIM Linear Fixed EF
-     *
-     * @param fileid EF id
-     * @param onLoaded
-     *
-     * ((AsyncResult)(onLoaded.obj)).result is an ArrayList<byte[]>
-     *
-     */
-    public void loadEFLinearFixedAll(int fileid, Message onLoaded) {
-        Message response = obtainMessage(EVENT_GET_RECORD_SIZE_DONE,
-                        new LoadLinearFixedContext(fileid,onLoaded));
-
-        mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid),
-                        0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, response);
-    }
-
-    /**
-     * Load a SIM Transparent EF
-     *
-     * @param fileid EF id
-     * @param onLoaded
-     *
-     * ((AsyncResult)(onLoaded.obj)).result is the byte[]
-     *
-     */
-
-    public void loadEFTransparent(int fileid, Message onLoaded) {
-        Message response = obtainMessage(EVENT_GET_BINARY_SIZE_DONE,
-                        fileid, 0, onLoaded);
-
-        mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid),
-                        0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, response);
-    }
-
-    /**
-     * Load a SIM Transparent EF-IMG. Used right after loadEFImgLinearFixed to
-     * retrive STK's icon data.
-     *
-     * @param fileid EF id
-     * @param onLoaded
-     *
-     * ((AsyncResult)(onLoaded.obj)).result is the byte[]
-     *
-     */
-    public void loadEFImgTransparent(int fileid, int highOffset, int lowOffset,
-            int length, Message onLoaded) {
-        Message response = obtainMessage(EVENT_READ_ICON_DONE, fileid, 0,
-                onLoaded);
-
-        mCi.iccIOForApp(COMMAND_READ_BINARY, fileid, "img", highOffset, lowOffset,
-                length, null, null, mAid, response);
-    }
-
-    /**
-     * Update a record in a linear fixed EF
-     * @param fileid EF id
-     * @param recordNum 1-based (not 0-based) record number
-     * @param data must be exactly as long as the record in the EF
-     * @param pin2 for CHV2 operations, otherwist must be null
-     * @param onComplete onComplete.obj will be an AsyncResult
-     *                   onComplete.obj.userObj will be a IccIoResult on success
-     */
-    public void updateEFLinearFixed(int fileid, int recordNum, byte[] data,
-            String pin2, Message onComplete) {
-        mCi.iccIOForApp(COMMAND_UPDATE_RECORD, fileid, getEFPath(fileid),
-                        recordNum, READ_RECORD_MODE_ABSOLUTE, data.length,
-                        IccUtils.bytesToHexString(data), pin2, mAid, onComplete);
-    }
-
-    /**
-     * Update a transparent EF
-     * @param fileid EF id
-     * @param data must be exactly as long as the EF
-     */
-    public void updateEFTransparent(int fileid, byte[] data, Message onComplete) {
-        mCi.iccIOForApp(COMMAND_UPDATE_BINARY, fileid, getEFPath(fileid),
-                        0, 0, data.length,
-                        IccUtils.bytesToHexString(data), null, mAid, onComplete);
-    }
-
-
-    //***** Abstract Methods
-
-
-    //***** Private Methods
-
-    private void sendResult(Message response, Object result, Throwable ex) {
-        if (response == null) {
-            return;
-        }
-
-        AsyncResult.forMessage(response, result, ex);
-
-        response.sendToTarget();
-    }
-
-    //***** Overridden from Handler
-
-    public void handleMessage(Message msg) {
-        AsyncResult ar;
-        IccIoResult result;
-        Message response = null;
-        String str;
-        LoadLinearFixedContext lc;
-
-        IccException iccException;
-        byte data[];
-        int size;
-        int fileid;
-        int recordNum;
-        int recordSize[];
-
-        try {
-            switch (msg.what) {
-            case EVENT_READ_IMG_DONE:
-                ar = (AsyncResult) msg.obj;
-                lc = (LoadLinearFixedContext) ar.userObj;
-                result = (IccIoResult) ar.result;
-                response = lc.onLoaded;
-
-                iccException = result.getException();
-                if (iccException != null) {
-                    sendResult(response, result.payload, ar.exception);
-                }
-                break;
-            case EVENT_READ_ICON_DONE:
-                ar = (AsyncResult) msg.obj;
-                response = (Message) ar.userObj;
-                result = (IccIoResult) ar.result;
-
-                iccException = result.getException();
-                if (iccException != null) {
-                    sendResult(response, result.payload, ar.exception);
-                }
-                break;
-            case EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE:
-                ar = (AsyncResult)msg.obj;
-                lc = (LoadLinearFixedContext) ar.userObj;
-                result = (IccIoResult) ar.result;
-                response = lc.onLoaded;
-
-                if (ar.exception != null) {
-                    sendResult(response, null, ar.exception);
-                    break;
-                }
-
-                iccException = result.getException();
-                if (iccException != null) {
-                    sendResult(response, null, iccException);
-                    break;
-                }
-
-                data = result.payload;
-
-                if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE] ||
-                    EF_TYPE_LINEAR_FIXED != data[RESPONSE_DATA_STRUCTURE]) {
-                    throw new IccFileTypeMismatch();
-                }
-
-                recordSize = new int[3];
-                recordSize[0] = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF;
-                recordSize[1] = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
-                       + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);
-                recordSize[2] = recordSize[1] / recordSize[0];
-
-                sendResult(response, recordSize, null);
-                break;
-             case EVENT_GET_RECORD_SIZE_DONE:
-                ar = (AsyncResult)msg.obj;
-                lc = (LoadLinearFixedContext) ar.userObj;
-                result = (IccIoResult) ar.result;
-                response = lc.onLoaded;
-
-                if (ar.exception != null) {
-                    sendResult(response, null, ar.exception);
-                    break;
-                }
-
-                iccException = result.getException();
-
-                if (iccException != null) {
-                    sendResult(response, null, iccException);
-                    break;
-                }
-
-                data = result.payload;
-                fileid = lc.efid;
-                recordNum = lc.recordNum;
-
-                if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE]) {
-                    throw new IccFileTypeMismatch();
-                }
-
-                if (EF_TYPE_LINEAR_FIXED != data[RESPONSE_DATA_STRUCTURE]) {
-                    throw new IccFileTypeMismatch();
-                }
-
-                lc.recordSize = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF;
-
-                size = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
-                       + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);
-
-                lc.countRecords = size / lc.recordSize;
-
-                 if (lc.loadAll) {
-                     lc.results = new ArrayList<byte[]>(lc.countRecords);
-                 }
-
-                 mCi.iccIOForApp(COMMAND_READ_RECORD, lc.efid, getEFPath(lc.efid),
-                         lc.recordNum,
-                         READ_RECORD_MODE_ABSOLUTE,
-                         lc.recordSize, null, null, mAid,
-                         obtainMessage(EVENT_READ_RECORD_DONE, lc));
-                 break;
-            case EVENT_GET_BINARY_SIZE_DONE:
-                ar = (AsyncResult)msg.obj;
-                response = (Message) ar.userObj;
-                result = (IccIoResult) ar.result;
-
-                if (ar.exception != null) {
-                    sendResult(response, null, ar.exception);
-                    break;
-                }
-
-                iccException = result.getException();
-
-                if (iccException != null) {
-                    sendResult(response, null, iccException);
-                    break;
-                }
-
-                data = result.payload;
-
-                fileid = msg.arg1;
-
-                if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE]) {
-                    throw new IccFileTypeMismatch();
-                }
-
-                if (EF_TYPE_TRANSPARENT != data[RESPONSE_DATA_STRUCTURE]) {
-                    throw new IccFileTypeMismatch();
-                }
-
-                size = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
-                       + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);
-
-                mCi.iccIOForApp(COMMAND_READ_BINARY, fileid, getEFPath(fileid),
-                                0, 0, size, null, null, mAid,
-                                obtainMessage(EVENT_READ_BINARY_DONE,
-                                              fileid, 0, response));
-            break;
-
-            case EVENT_READ_RECORD_DONE:
-
-                ar = (AsyncResult)msg.obj;
-                lc = (LoadLinearFixedContext) ar.userObj;
-                result = (IccIoResult) ar.result;
-                response = lc.onLoaded;
-
-                if (ar.exception != null) {
-                    sendResult(response, null, ar.exception);
-                    break;
-                }
-
-                iccException = result.getException();
-
-                if (iccException != null) {
-                    sendResult(response, null, iccException);
-                    break;
-                }
-
-                if (!lc.loadAll) {
-                    sendResult(response, result.payload, null);
-                } else {
-                    lc.results.add(result.payload);
-
-                    lc.recordNum++;
-
-                    if (lc.recordNum > lc.countRecords) {
-                        sendResult(response, lc.results, null);
-                    } else {
-                        mCi.iccIOForApp(COMMAND_READ_RECORD, lc.efid, getEFPath(lc.efid),
-                                    lc.recordNum,
-                                    READ_RECORD_MODE_ABSOLUTE,
-                                    lc.recordSize, null, null, mAid,
-                                    obtainMessage(EVENT_READ_RECORD_DONE, lc));
-                    }
-                }
-
-            break;
-
-            case EVENT_READ_BINARY_DONE:
-                ar = (AsyncResult)msg.obj;
-                response = (Message) ar.userObj;
-                result = (IccIoResult) ar.result;
-
-                if (ar.exception != null) {
-                    sendResult(response, null, ar.exception);
-                    break;
-                }
-
-                iccException = result.getException();
-
-                if (iccException != null) {
-                    sendResult(response, null, iccException);
-                    break;
-                }
-
-                sendResult(response, result.payload, null);
-            break;
-
-        }} catch (Exception exc) {
-            if (response != null) {
-                sendResult(response, null, exc);
-            } else {
-                loge("uncaught exception" + exc);
-            }
-        }
-    }
-
-    /**
-     * Returns the root path of the EF file.
-     * i.e returns MasterFile + DFfile as a string.
-     * Ex: For EF_ADN on a SIM, it will return "3F007F10"
-     * This function handles only EFids that are common to
-     * RUIM, SIM, USIM and other types of Icc cards.
-     *
-     * @param efId
-     * @return root path of the file.
-     */
-    protected String getCommonIccEFPath(int efid) {
-        switch(efid) {
-        case EF_ADN:
-        case EF_FDN:
-        case EF_MSISDN:
-        case EF_SDN:
-        case EF_EXT1:
-        case EF_EXT2:
-        case EF_EXT3:
-            return MF_SIM + DF_TELECOM;
-
-        case EF_ICCID:
-        case EF_PL:
-            return MF_SIM;
-        case EF_IMG:
-            return MF_SIM + DF_TELECOM + DF_GRAPHICS;
-        }
-        return null;
-    }
-
-    protected abstract String getEFPath(int efid);
-    protected abstract void logd(String s);
-
-    protected abstract void loge(String s);
-    protected void setAid(String aid) {
-        mAid = aid;
-    }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/IccFileNotFound.java b/telephony/java/com/android/internal/telephony/IccFileNotFound.java
deleted file mode 100644
index 915cea6..0000000
--- a/telephony/java/com/android/internal/telephony/IccFileNotFound.java
+++ /dev/null
@@ -1,34 +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.internal.telephony;
-
-/**
- * {@hide}
- */
-public class IccFileNotFound extends IccException {
-    IccFileNotFound() {
-
-    }
-
-    IccFileNotFound(String s) {
-        super(s);
-    }
-
-    IccFileNotFound(int ef) {
-        super("ICC EF Not Found 0x" + Integer.toHexString(ef));
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/IccFileTypeMismatch.java b/telephony/java/com/android/internal/telephony/IccFileTypeMismatch.java
deleted file mode 100644
index 66fcfa9..0000000
--- a/telephony/java/com/android/internal/telephony/IccFileTypeMismatch.java
+++ /dev/null
@@ -1,30 +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.internal.telephony;
-
-/**
- * {@hide}
- */
-public class IccFileTypeMismatch extends IccException {
-    public IccFileTypeMismatch() {
-
-    }
-
-    public IccFileTypeMismatch(String s) {
-        super(s);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/IccIoResult.java b/telephony/java/com/android/internal/telephony/IccIoResult.java
deleted file mode 100644
index 7043da5..0000000
--- a/telephony/java/com/android/internal/telephony/IccIoResult.java
+++ /dev/null
@@ -1,70 +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.internal.telephony;
-
-/**
- * {@hide}
- */
-public class
-IccIoResult {
-    public int sw1;
-    public int sw2;
-
-    public byte[] payload;
-
-    public IccIoResult(int sw1, int sw2, byte[] payload) {
-        this.sw1 = sw1;
-        this.sw2 = sw2;
-        this.payload = payload;
-    }
-
-    public IccIoResult(int sw1, int sw2, String hexString) {
-        this(sw1, sw2, IccUtils.hexStringToBytes(hexString));
-    }
-
-    public String toString() {
-        return "IccIoResponse sw1:0x" + Integer.toHexString(sw1) + " sw2:0x"
-                + Integer.toHexString(sw2);
-    }
-
-    /**
-     * true if this operation was successful
-     * See GSM 11.11 Section 9.4
-     * (the fun stuff is absent in 51.011)
-     */
-    public boolean success() {
-        return sw1 == 0x90 || sw1 == 0x91 || sw1 == 0x9e || sw1 == 0x9f;
-    }
-
-    /**
-     * Returns exception on error or null if success
-     */
-    public IccException getException() {
-        if (success()) return null;
-
-        switch (sw1) {
-            case 0x94:
-                if (sw2 == 0x08) {
-                    return new IccFileTypeMismatch();
-                } else {
-                    return new IccFileNotFound();
-                }
-            default:
-                return new IccException("sw1:" + sw1 + " sw2:" + sw2);
-        }
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
deleted file mode 100644
index 45562ca..0000000
--- a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
+++ /dev/null
@@ -1,289 +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.internal.telephony;
-
-import android.content.pm.PackageManager;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.ServiceManager;
-
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * SimPhoneBookInterfaceManager to provide an inter-process communication to
- * access ADN-like SIM records.
- */
-public abstract class IccPhoneBookInterfaceManager extends IIccPhoneBook.Stub {
-    protected static final boolean DBG = true;
-
-    protected PhoneBase phone;
-    protected AdnRecordCache adnCache;
-    protected final Object mLock = new Object();
-    protected int recordSize[];
-    protected boolean success;
-    protected List<AdnRecord> records;
-
-    protected static final boolean ALLOW_SIM_OP_IN_UI_THREAD = false;
-
-    protected static final int EVENT_GET_SIZE_DONE = 1;
-    protected static final int EVENT_LOAD_DONE = 2;
-    protected static final int EVENT_UPDATE_DONE = 3;
-
-    protected Handler mBaseHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            AsyncResult ar;
-
-            switch (msg.what) {
-                case EVENT_GET_SIZE_DONE:
-                    ar = (AsyncResult) msg.obj;
-                    synchronized (mLock) {
-                        if (ar.exception == null) {
-                            recordSize = (int[])ar.result;
-                            // recordSize[0]  is the record length
-                            // recordSize[1]  is the total length of the EF file
-                            // recordSize[2]  is the number of records in the EF file
-                            logd("GET_RECORD_SIZE Size " + recordSize[0] +
-                                    " total " + recordSize[1] +
-                                    " #record " + recordSize[2]);
-                        }
-                        notifyPending(ar);
-                    }
-                    break;
-                case EVENT_UPDATE_DONE:
-                    ar = (AsyncResult) msg.obj;
-                    synchronized (mLock) {
-                        success = (ar.exception == null);
-                        notifyPending(ar);
-                    }
-                    break;
-                case EVENT_LOAD_DONE:
-                    ar = (AsyncResult)msg.obj;
-                    synchronized (mLock) {
-                        if (ar.exception == null) {
-                            records = (List<AdnRecord>) ar.result;
-                        } else {
-                            if(DBG) logd("Cannot load ADN records");
-                            if (records != null) {
-                                records.clear();
-                            }
-                        }
-                        notifyPending(ar);
-                    }
-                    break;
-            }
-        }
-
-        private void notifyPending(AsyncResult ar) {
-            if (ar.userObj == null) {
-                return;
-            }
-            AtomicBoolean status = (AtomicBoolean) ar.userObj;
-            status.set(true);
-            mLock.notifyAll();
-        }
-    };
-
-    public IccPhoneBookInterfaceManager(PhoneBase phone) {
-        this.phone = phone;
-    }
-
-    public void dispose() {
-    }
-
-    protected void publish() {
-        //NOTE service "simphonebook" added by IccSmsInterfaceManagerProxy
-        ServiceManager.addService("simphonebook", this);
-    }
-
-    protected abstract void logd(String msg);
-
-    protected abstract void loge(String msg);
-
-    /**
-     * Replace oldAdn with newAdn in ADN-like record in EF
-     *
-     * getAdnRecordsInEf must be called at least once before this function,
-     * otherwise an error will be returned. Currently the email field
-     * if set in the ADN record is ignored.
-     * throws SecurityException if no WRITE_CONTACTS permission
-     *
-     * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN
-     * @param oldTag adn tag to be replaced
-     * @param oldPhoneNumber adn number to be replaced
-     *        Set both oldTag and oldPhoneNubmer to "" means to replace an
-     *        empty record, aka, insert new record
-     * @param newTag adn tag to be stored
-     * @param newPhoneNumber adn number ot be stored
-     *        Set both newTag and newPhoneNubmer to "" means to replace the old
-     *        record with empty one, aka, delete old record
-     * @param pin2 required to update EF_FDN, otherwise must be null
-     * @return true for success
-     */
-    public boolean
-    updateAdnRecordsInEfBySearch (int efid,
-            String oldTag, String oldPhoneNumber,
-            String newTag, String newPhoneNumber, String pin2) {
-
-
-        if (phone.getContext().checkCallingOrSelfPermission(
-                android.Manifest.permission.WRITE_CONTACTS)
-            != PackageManager.PERMISSION_GRANTED) {
-            throw new SecurityException(
-                    "Requires android.permission.WRITE_CONTACTS permission");
-        }
-
-
-        if (DBG) logd("updateAdnRecordsInEfBySearch: efid=" + efid +
-                " ("+ oldTag + "," + oldPhoneNumber + ")"+ "==>" +
-                " ("+ newTag + "," + newPhoneNumber + ")"+ " pin2=" + pin2);
-
-        efid = updateEfForIccType(efid);
-
-        synchronized(mLock) {
-            checkThread();
-            success = false;
-            AtomicBoolean status = new AtomicBoolean(false);
-            Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, status);
-            AdnRecord oldAdn = new AdnRecord(oldTag, oldPhoneNumber);
-            AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber);
-            adnCache.updateAdnBySearch(efid, oldAdn, newAdn, pin2, response);
-            waitForResult(status);
-        }
-        return success;
-    }
-
-    /**
-     * Update an ADN-like EF record by record index
-     *
-     * This is useful for iteration the whole ADN file, such as write the whole
-     * phone book or erase/format the whole phonebook. Currently the email field
-     * if set in the ADN record is ignored.
-     * throws SecurityException if no WRITE_CONTACTS permission
-     *
-     * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN
-     * @param newTag adn tag to be stored
-     * @param newPhoneNumber adn number to be stored
-     *        Set both newTag and newPhoneNubmer to "" means to replace the old
-     *        record with empty one, aka, delete old record
-     * @param index is 1-based adn record index to be updated
-     * @param pin2 required to update EF_FDN, otherwise must be null
-     * @return true for success
-     */
-    public boolean
-    updateAdnRecordsInEfByIndex(int efid, String newTag,
-            String newPhoneNumber, int index, String pin2) {
-
-        if (phone.getContext().checkCallingOrSelfPermission(
-                android.Manifest.permission.WRITE_CONTACTS)
-                != PackageManager.PERMISSION_GRANTED) {
-            throw new SecurityException(
-                    "Requires android.permission.WRITE_CONTACTS permission");
-        }
-
-        if (DBG) logd("updateAdnRecordsInEfByIndex: efid=" + efid +
-                " Index=" + index + " ==> " +
-                "("+ newTag + "," + newPhoneNumber + ")"+ " pin2=" + pin2);
-        synchronized(mLock) {
-            checkThread();
-            success = false;
-            AtomicBoolean status = new AtomicBoolean(false);
-            Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, status);
-            AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber);
-            adnCache.updateAdnByIndex(efid, newAdn, index, pin2, response);
-            waitForResult(status);
-        }
-        return success;
-    }
-
-    /**
-     * Get the capacity of records in efid
-     *
-     * @param efid the EF id of a ADN-like ICC
-     * @return  int[3] array
-     *            recordSizes[0]  is the single record length
-     *            recordSizes[1]  is the total length of the EF file
-     *            recordSizes[2]  is the number of records in the EF file
-     */
-    public abstract int[] getAdnRecordsSize(int efid);
-
-    /**
-     * Loads the AdnRecords in efid and returns them as a
-     * List of AdnRecords
-     *
-     * throws SecurityException if no READ_CONTACTS permission
-     *
-     * @param efid the EF id of a ADN-like ICC
-     * @return List of AdnRecord
-     */
-    public List<AdnRecord> getAdnRecordsInEf(int efid) {
-
-        if (phone.getContext().checkCallingOrSelfPermission(
-                android.Manifest.permission.READ_CONTACTS)
-                != PackageManager.PERMISSION_GRANTED) {
-            throw new SecurityException(
-                    "Requires android.permission.READ_CONTACTS permission");
-        }
-
-        efid = updateEfForIccType(efid);
-        if (DBG) logd("getAdnRecordsInEF: efid=" + efid);
-
-        synchronized(mLock) {
-            checkThread();
-            AtomicBoolean status = new AtomicBoolean(false);
-            Message response = mBaseHandler.obtainMessage(EVENT_LOAD_DONE, status);
-            adnCache.requestLoadAllAdnLike(efid, adnCache.extensionEfForEf(efid), response);
-            waitForResult(status);
-        }
-        return records;
-    }
-
-    protected void checkThread() {
-        if (!ALLOW_SIM_OP_IN_UI_THREAD) {
-            // Make sure this isn't the UI thread, since it will block
-            if (mBaseHandler.getLooper().equals(Looper.myLooper())) {
-                loge("query() called on the main UI thread!");
-                throw new IllegalStateException(
-                        "You cannot call query on this provder from the main UI thread.");
-            }
-        }
-    }
-
-    protected void waitForResult(AtomicBoolean status) {
-        while (!status.get()) {
-            try {
-                mLock.wait();
-            } catch (InterruptedException e) {
-                logd("interrupted while trying to update by search");
-            }
-        }
-    }
-
-    private int updateEfForIccType(int efid) {
-        // Check if we are trying to read ADN records
-        if (efid == IccConstants.EF_ADN) {
-            if (phone.getIccCard().isApplicationOnIcc(IccCardApplication.AppType.APPTYPE_USIM)) {
-                return IccConstants.EF_PBR;
-            }
-        }
-        return efid;
-    }
-}
-
diff --git a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManagerProxy.java b/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManagerProxy.java
deleted file mode 100644
index 1c0fc52..0000000
--- a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManagerProxy.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.internal.telephony;
-
-import android.content.pm.PackageManager;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.ServiceManager;
-import android.telephony.PhoneNumberUtils;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-
-
-/**
- * SimPhoneBookInterfaceManager to provide an inter-process communication to
- * access ADN-like SIM records.
- */
-public class IccPhoneBookInterfaceManagerProxy extends IIccPhoneBook.Stub {
-    private IccPhoneBookInterfaceManager mIccPhoneBookInterfaceManager;
-
-    public IccPhoneBookInterfaceManagerProxy(IccPhoneBookInterfaceManager
-            iccPhoneBookInterfaceManager) {
-        mIccPhoneBookInterfaceManager = iccPhoneBookInterfaceManager;
-        if(ServiceManager.getService("simphonebook") == null) {
-            ServiceManager.addService("simphonebook", this);
-        }
-    }
-
-    public void setmIccPhoneBookInterfaceManager(
-            IccPhoneBookInterfaceManager iccPhoneBookInterfaceManager) {
-        this.mIccPhoneBookInterfaceManager = iccPhoneBookInterfaceManager;
-    }
-
-    public boolean
-    updateAdnRecordsInEfBySearch (int efid,
-            String oldTag, String oldPhoneNumber,
-            String newTag, String newPhoneNumber,
-            String pin2) throws android.os.RemoteException {
-        return mIccPhoneBookInterfaceManager.updateAdnRecordsInEfBySearch(
-                efid, oldTag, oldPhoneNumber, newTag, newPhoneNumber, pin2);
-    }
-
-    public boolean
-    updateAdnRecordsInEfByIndex(int efid, String newTag,
-            String newPhoneNumber, int index, String pin2) throws android.os.RemoteException {
-        return mIccPhoneBookInterfaceManager.updateAdnRecordsInEfByIndex(efid,
-                newTag, newPhoneNumber, index, pin2);
-    }
-
-    public int[] getAdnRecordsSize(int efid) throws android.os.RemoteException {
-        return mIccPhoneBookInterfaceManager.getAdnRecordsSize(efid);
-    }
-
-    public List<AdnRecord> getAdnRecordsInEf(int efid) throws android.os.RemoteException {
-        return mIccPhoneBookInterfaceManager.getAdnRecordsInEf(efid);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/IccProvider.java b/telephony/java/com/android/internal/telephony/IccProvider.java
deleted file mode 100644
index a66e19d..0000000
--- a/telephony/java/com/android/internal/telephony/IccProvider.java
+++ /dev/null
@@ -1,431 +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.internal.telephony;
-
-import android.content.ContentProvider;
-import android.content.UriMatcher;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.net.Uri;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.util.List;
-
-import com.android.internal.telephony.IccConstants;
-import com.android.internal.telephony.AdnRecord;
-import com.android.internal.telephony.IIccPhoneBook;
-
-
-/**
- * {@hide}
- */
-public class IccProvider extends ContentProvider {
-    private static final String TAG = "IccProvider";
-    private static final boolean DBG = false;
-
-
-    private static final String[] ADDRESS_BOOK_COLUMN_NAMES = new String[] {
-        "name",
-        "number",
-        "emails",
-        "_id"
-    };
-
-    private static final int ADN = 1;
-    private static final int FDN = 2;
-    private static final int SDN = 3;
-
-    private static final String STR_TAG = "tag";
-    private static final String STR_NUMBER = "number";
-    private static final String STR_EMAILS = "emails";
-    private static final String STR_PIN2 = "pin2";
-
-    private static final UriMatcher URL_MATCHER =
-                            new UriMatcher(UriMatcher.NO_MATCH);
-
-    static {
-        URL_MATCHER.addURI("icc", "adn", ADN);
-        URL_MATCHER.addURI("icc", "fdn", FDN);
-        URL_MATCHER.addURI("icc", "sdn", SDN);
-    }
-
-
-    @Override
-    public boolean onCreate() {
-        return true;
-    }
-
-    @Override
-    public Cursor query(Uri url, String[] projection, String selection,
-            String[] selectionArgs, String sort) {
-        switch (URL_MATCHER.match(url)) {
-            case ADN:
-                return loadFromEf(IccConstants.EF_ADN);
-
-            case FDN:
-                return loadFromEf(IccConstants.EF_FDN);
-
-            case SDN:
-                return loadFromEf(IccConstants.EF_SDN);
-
-            default:
-                throw new IllegalArgumentException("Unknown URL " + url);
-        }
-    }
-
-    @Override
-    public String getType(Uri url) {
-        switch (URL_MATCHER.match(url)) {
-            case ADN:
-            case FDN:
-            case SDN:
-                return "vnd.android.cursor.dir/sim-contact";
-
-            default:
-                throw new IllegalArgumentException("Unknown URL " + url);
-        }
-    }
-
-    @Override
-    public Uri insert(Uri url, ContentValues initialValues) {
-        Uri resultUri;
-        int efType;
-        String pin2 = null;
-
-        if (DBG) log("insert");
-
-        int match = URL_MATCHER.match(url);
-        switch (match) {
-            case ADN:
-                efType = IccConstants.EF_ADN;
-                break;
-
-            case FDN:
-                efType = IccConstants.EF_FDN;
-                pin2 = initialValues.getAsString("pin2");
-                break;
-
-            default:
-                throw new UnsupportedOperationException(
-                        "Cannot insert into URL: " + url);
-        }
-
-        String tag = initialValues.getAsString("tag");
-        String number = initialValues.getAsString("number");
-        // TODO(): Read email instead of sending null.
-        boolean success = addIccRecordToEf(efType, tag, number, null, pin2);
-
-        if (!success) {
-            return null;
-        }
-
-        StringBuilder buf = new StringBuilder("content://icc/");
-        switch (match) {
-            case ADN:
-                buf.append("adn/");
-                break;
-
-            case FDN:
-                buf.append("fdn/");
-                break;
-        }
-
-        // TODO: we need to find out the rowId for the newly added record
-        buf.append(0);
-
-        resultUri = Uri.parse(buf.toString());
-
-        /*
-        // notify interested parties that an insertion happened
-        getContext().getContentResolver().notifyInsert(
-                resultUri, rowID, null);
-        */
-
-        return resultUri;
-    }
-
-    private String normalizeValue(String inVal) {
-        int len = inVal.length();
-        String retVal = inVal;
-
-        if (inVal.charAt(0) == '\'' && inVal.charAt(len-1) == '\'') {
-            retVal = inVal.substring(1, len-1);
-        }
-
-        return retVal;
-    }
-
-    @Override
-    public int delete(Uri url, String where, String[] whereArgs) {
-        int efType;
-
-        if (DBG) log("delete");
-
-        int match = URL_MATCHER.match(url);
-        switch (match) {
-            case ADN:
-                efType = IccConstants.EF_ADN;
-                break;
-
-            case FDN:
-                efType = IccConstants.EF_FDN;
-                break;
-
-            default:
-                throw new UnsupportedOperationException(
-                        "Cannot insert into URL: " + url);
-        }
-
-        // parse where clause
-        String tag = null;
-        String number = null;
-        String[] emails = null;
-        String pin2 = null;
-
-        String[] tokens = where.split("AND");
-        int n = tokens.length;
-
-        while (--n >= 0) {
-            String param = tokens[n];
-            if (DBG) log("parsing '" + param + "'");
-
-            String[] pair = param.split("=");
-
-            if (pair.length != 2) {
-                Log.e(TAG, "resolve: bad whereClause parameter: " + param);
-                continue;
-            }
-
-            String key = pair[0].trim();
-            String val = pair[1].trim();
-
-            if (STR_TAG.equals(key)) {
-                tag = normalizeValue(val);
-            } else if (STR_NUMBER.equals(key)) {
-                number = normalizeValue(val);
-            } else if (STR_EMAILS.equals(key)) {
-                //TODO(): Email is null.
-                emails = null;
-            } else if (STR_PIN2.equals(key)) {
-                pin2 = normalizeValue(val);
-            }
-        }
-
-        if (TextUtils.isEmpty(number)) {
-            return 0;
-        }
-
-        if (efType == IccConstants.EF_FDN && TextUtils.isEmpty(pin2)) {
-            return 0;
-        }
-
-        boolean success = deleteIccRecordFromEf(efType, tag, number, emails, pin2);
-        if (!success) {
-            return 0;
-        }
-
-        return 1;
-    }
-
-    @Override
-    public int update(Uri url, ContentValues values, String where, String[] whereArgs) {
-        int efType;
-        String pin2 = null;
-
-        if (DBG) log("update");
-
-        int match = URL_MATCHER.match(url);
-        switch (match) {
-            case ADN:
-                efType = IccConstants.EF_ADN;
-                break;
-
-            case FDN:
-                efType = IccConstants.EF_FDN;
-                pin2 = values.getAsString("pin2");
-                break;
-
-            default:
-                throw new UnsupportedOperationException(
-                        "Cannot insert into URL: " + url);
-        }
-
-        String tag = values.getAsString("tag");
-        String number = values.getAsString("number");
-        String[] emails = null;
-        String newTag = values.getAsString("newTag");
-        String newNumber = values.getAsString("newNumber");
-        String[] newEmails = null;
-        // TODO(): Update for email.
-        boolean success = updateIccRecordInEf(efType, tag, number,
-                newTag, newNumber, pin2);
-
-        if (!success) {
-            return 0;
-        }
-
-        return 1;
-    }
-
-    private MatrixCursor loadFromEf(int efType) {
-        if (DBG) log("loadFromEf: efType=" + efType);
-
-        List<AdnRecord> adnRecords = null;
-        try {
-            IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
-                    ServiceManager.getService("simphonebook"));
-            if (iccIpb != null) {
-                adnRecords = iccIpb.getAdnRecordsInEf(efType);
-            }
-        } catch (RemoteException ex) {
-            // ignore it
-        } catch (SecurityException ex) {
-            if (DBG) log(ex.toString());
-        }
-
-        if (adnRecords != null) {
-            // Load the results
-            final int N = adnRecords.size();
-            final MatrixCursor cursor = new MatrixCursor(ADDRESS_BOOK_COLUMN_NAMES, N);
-            if (DBG) log("adnRecords.size=" + N);
-            for (int i = 0; i < N ; i++) {
-                loadRecord(adnRecords.get(i), cursor, i);
-            }
-            return cursor;
-        } else {
-            // No results to load
-            Log.w(TAG, "Cannot load ADN records");
-            return new MatrixCursor(ADDRESS_BOOK_COLUMN_NAMES);
-        }
-    }
-
-    private boolean
-    addIccRecordToEf(int efType, String name, String number, String[] emails, String pin2) {
-        if (DBG) log("addIccRecordToEf: efType=" + efType + ", name=" + name +
-                ", number=" + number + ", emails=" + emails);
-
-        boolean success = false;
-
-        // TODO: do we need to call getAdnRecordsInEf() before calling
-        // updateAdnRecordsInEfBySearch()? In any case, we will leave
-        // the UI level logic to fill that prereq if necessary. But
-        // hopefully, we can remove this requirement.
-
-        try {
-            IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
-                    ServiceManager.getService("simphonebook"));
-            if (iccIpb != null) {
-                success = iccIpb.updateAdnRecordsInEfBySearch(efType, "", "",
-                        name, number, pin2);
-            }
-        } catch (RemoteException ex) {
-            // ignore it
-        } catch (SecurityException ex) {
-            if (DBG) log(ex.toString());
-        }
-        if (DBG) log("addIccRecordToEf: " + success);
-        return success;
-    }
-
-    private boolean
-    updateIccRecordInEf(int efType, String oldName, String oldNumber,
-            String newName, String newNumber, String pin2) {
-        if (DBG) log("updateIccRecordInEf: efType=" + efType +
-                ", oldname=" + oldName + ", oldnumber=" + oldNumber +
-                ", newname=" + newName + ", newnumber=" + newNumber);
-        boolean success = false;
-
-        try {
-            IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
-                    ServiceManager.getService("simphonebook"));
-            if (iccIpb != null) {
-                success = iccIpb.updateAdnRecordsInEfBySearch(efType,
-                        oldName, oldNumber, newName, newNumber, pin2);
-            }
-        } catch (RemoteException ex) {
-            // ignore it
-        } catch (SecurityException ex) {
-            if (DBG) log(ex.toString());
-        }
-        if (DBG) log("updateIccRecordInEf: " + success);
-        return success;
-    }
-
-
-    private boolean deleteIccRecordFromEf(int efType, String name, String number, String[] emails,
-            String pin2) {
-        if (DBG) log("deleteIccRecordFromEf: efType=" + efType +
-                ", name=" + name + ", number=" + number + ", emails=" + emails + ", pin2=" + pin2);
-
-        boolean success = false;
-
-        try {
-            IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
-                    ServiceManager.getService("simphonebook"));
-            if (iccIpb != null) {
-                success = iccIpb.updateAdnRecordsInEfBySearch(efType,
-                        name, number, "", "", pin2);
-            }
-        } catch (RemoteException ex) {
-            // ignore it
-        } catch (SecurityException ex) {
-            if (DBG) log(ex.toString());
-        }
-        if (DBG) log("deleteIccRecordFromEf: " + success);
-        return success;
-    }
-
-    /**
-     * Loads an AdnRecord into a MatrixCursor. Must be called with mLock held.
-     *
-     * @param record the ADN record to load from
-     * @param cursor the cursor to receive the results
-     */
-    private void loadRecord(AdnRecord record, MatrixCursor cursor, int id) {
-        if (!record.isEmpty()) {
-            Object[] contact = new Object[4];
-            String alphaTag = record.getAlphaTag();
-            String number = record.getNumber();
-
-            if (DBG) log("loadRecord: " + alphaTag + ", " + number + ",");
-            contact[0] = alphaTag;
-            contact[1] = number;
-
-            String[] emails = record.getEmails();
-            if (emails != null) {
-                StringBuilder emailString = new StringBuilder();
-                for (String email: emails) {
-                    if (DBG) log("Adding email:" + email);
-                    emailString.append(email);
-                    emailString.append(",");
-                }
-                contact[2] = emailString.toString();
-            }
-            contact[3] = id;
-            cursor.addRow(contact);
-        }
-    }
-
-    private void log(String msg) {
-        Log.d(TAG, "[IccProvider] " + msg);
-    }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/IccRecords.java b/telephony/java/com/android/internal/telephony/IccRecords.java
deleted file mode 100644
index 41c9d5a..0000000
--- a/telephony/java/com/android/internal/telephony/IccRecords.java
+++ /dev/null
@@ -1,422 +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.internal.telephony;
-
-import android.content.Context;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Registrant;
-import android.os.RegistrantList;
-
-import com.android.internal.telephony.gsm.UsimServiceTable;
-import com.android.internal.telephony.ims.IsimRecords;
-
-/**
- * {@hide}
- */
-public abstract class IccRecords extends Handler implements IccConstants {
-
-    protected static final boolean DBG = true;
-    // ***** Instance Variables
-    protected boolean mDestroyed = false; // set to true once this object needs to be disposed of
-    protected Context mContext;
-    protected CommandsInterface mCi;
-    protected IccFileHandler mFh;
-    protected IccCard mParentCard;
-
-    protected RegistrantList recordsLoadedRegistrants = new RegistrantList();
-    protected RegistrantList mRecordsEventsRegistrants = new RegistrantList();
-    protected RegistrantList mNewSmsRegistrants = new RegistrantList();
-    protected RegistrantList mNetworkSelectionModeAutomaticRegistrants = new RegistrantList();
-
-    protected int recordsToLoad;  // number of pending load requests
-
-    protected AdnRecordCache adnCache;
-
-    // ***** Cached SIM State; cleared on channel close
-
-    protected boolean recordsRequested = false; // true if we've made requests for the sim records
-
-    public String iccid;
-    protected String msisdn = null;  // My mobile number
-    protected String msisdnTag = null;
-    protected String voiceMailNum = null;
-    protected String voiceMailTag = null;
-    protected String newVoiceMailNum = null;
-    protected String newVoiceMailTag = null;
-    protected boolean isVoiceMailFixed = false;
-    protected int countVoiceMessages = 0;
-
-    protected int mncLength = UNINITIALIZED;
-    protected int mailboxIndex = 0; // 0 is no mailbox dailing number associated
-
-    protected String spn;
-
-    // ***** Constants
-
-    // Markers for mncLength
-    protected static final int UNINITIALIZED = -1;
-    protected static final int UNKNOWN = 0;
-
-    // Bitmasks for SPN display rules.
-    protected static final int SPN_RULE_SHOW_SPN  = 0x01;
-    protected static final int SPN_RULE_SHOW_PLMN = 0x02;
-
-    // ***** Event Constants
-    protected static final int EVENT_SET_MSISDN_DONE = 30;
-    public static final int EVENT_MWI = 0;
-    public static final int EVENT_CFI = 1;
-    public static final int EVENT_SPN = 2;
-
-    public static final int EVENT_GET_ICC_RECORD_DONE = 100;
-
-    /**
-     * Generic ICC record loaded callback. Subclasses can call EF load methods on
-     * {@link IccFileHandler} passing a Message for onLoaded with the what field set to
-     * {@link #EVENT_GET_ICC_RECORD_DONE} and the obj field set to an instance
-     * of this interface. The {@link #handleMessage} method in this class will print a
-     * log message using {@link #getEfName()} and decrement {@link #recordsToLoad}.
-     *
-     * If the record load was successful, {@link #onRecordLoaded} will be called with the result.
-     * Otherwise, an error log message will be output by {@link #handleMessage} and
-     * {@link #onRecordLoaded} will not be called.
-     */
-    public interface IccRecordLoaded {
-        String getEfName();
-        void onRecordLoaded(AsyncResult ar);
-    }
-
-    // ***** Constructor
-    public IccRecords(IccCard card, Context c, CommandsInterface ci) {
-        mContext = c;
-        mCi = ci;
-        mFh = card.getIccFileHandler();
-        mParentCard = card;
-    }
-
-    /**
-     * Call when the IccRecords object is no longer going to be used.
-     */
-    public void dispose() {
-        mDestroyed = true;
-        mParentCard = null;
-        mFh = null;
-        mCi = null;
-        mContext = null;
-    }
-
-    protected abstract void onRadioOffOrNotAvailable();
-    public abstract void onReady();
-
-    //***** Public Methods
-    public AdnRecordCache getAdnCache() {
-        return adnCache;
-    }
-
-    public IccCard getIccCard() {
-        return mParentCard;
-    }
-
-    public void registerForRecordsLoaded(Handler h, int what, Object obj) {
-        if (mDestroyed) {
-            return;
-        }
-
-        Registrant r = new Registrant(h, what, obj);
-        recordsLoadedRegistrants.add(r);
-
-        if (recordsToLoad == 0 && recordsRequested == true) {
-            r.notifyRegistrant(new AsyncResult(null, null, null));
-        }
-    }
-    public void unregisterForRecordsLoaded(Handler h) {
-        recordsLoadedRegistrants.remove(h);
-    }
-
-    public void registerForRecordsEvents(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mRecordsEventsRegistrants.add(r);
-    }
-    public void unregisterForRecordsEvents(Handler h) {
-        mRecordsEventsRegistrants.remove(h);
-    }
-
-    public void registerForNewSms(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mNewSmsRegistrants.add(r);
-    }
-    public void unregisterForNewSms(Handler h) {
-        mNewSmsRegistrants.remove(h);
-    }
-
-    public void registerForNetworkSelectionModeAutomatic(
-            Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mNetworkSelectionModeAutomaticRegistrants.add(r);
-    }
-    public void unregisterForNetworkSelectionModeAutomatic(Handler h) {
-        mNetworkSelectionModeAutomaticRegistrants.remove(h);
-    }
-
-    /**
-     * Get the International Mobile Subscriber ID (IMSI) on a SIM
-     * for GSM, UMTS and like networks. Default is null if IMSI is
-     * not supported or unavailable.
-     *
-     * @return null if SIM is not yet ready or unavailable
-     */
-    public String getIMSI() {
-        return null;
-    }
-
-    public String getMsisdnNumber() {
-        return msisdn;
-    }
-
-    /**
-     * Set subscriber number to SIM record
-     *
-     * The subscriber number is stored in EF_MSISDN (TS 51.011)
-     *
-     * When the operation is complete, onComplete will be sent to its handler
-     *
-     * @param alphaTag alpha-tagging of the dailing nubmer (up to 10 characters)
-     * @param number dailing nubmer (up to 20 digits)
-     *        if the number starts with '+', then set to international TOA
-     * @param onComplete
-     *        onComplete.obj will be an AsyncResult
-     *        ((AsyncResult)onComplete.obj).exception == null on success
-     *        ((AsyncResult)onComplete.obj).exception != null on fail
-     */
-    public void setMsisdnNumber(String alphaTag, String number,
-            Message onComplete) {
-
-        msisdn = number;
-        msisdnTag = alphaTag;
-
-        if(DBG) log("Set MSISDN: " + msisdnTag +" " + msisdn);
-
-
-        AdnRecord adn = new AdnRecord(msisdnTag, msisdn);
-
-        new AdnRecordLoader(mFh).updateEF(adn, EF_MSISDN, EF_EXT1, 1, null,
-                obtainMessage(EVENT_SET_MSISDN_DONE, onComplete));
-    }
-
-    public String getMsisdnAlphaTag() {
-        return msisdnTag;
-    }
-
-    public String getVoiceMailNumber() {
-        return voiceMailNum;
-    }
-
-    /**
-     * Return Service Provider Name stored in SIM (EF_SPN=0x6F46) or in RUIM (EF_RUIM_SPN=0x6F41)
-     * @return null if SIM is not yet ready or no RUIM entry
-     */
-    public String getServiceProviderName() {
-        return spn;
-    }
-
-    /**
-     * Set voice mail number to SIM record
-     *
-     * The voice mail number can be stored either in EF_MBDN (TS 51.011) or
-     * EF_MAILBOX_CPHS (CPHS 4.2)
-     *
-     * If EF_MBDN is available, store the voice mail number to EF_MBDN
-     *
-     * If EF_MAILBOX_CPHS is enabled, store the voice mail number to EF_CHPS
-     *
-     * So the voice mail number will be stored in both EFs if both are available
-     *
-     * Return error only if both EF_MBDN and EF_MAILBOX_CPHS fail.
-     *
-     * When the operation is complete, onComplete will be sent to its handler
-     *
-     * @param alphaTag alpha-tagging of the dailing nubmer (upto 10 characters)
-     * @param voiceNumber dailing nubmer (upto 20 digits)
-     *        if the number is start with '+', then set to international TOA
-     * @param onComplete
-     *        onComplete.obj will be an AsyncResult
-     *        ((AsyncResult)onComplete.obj).exception == null on success
-     *        ((AsyncResult)onComplete.obj).exception != null on fail
-     */
-    public abstract void setVoiceMailNumber(String alphaTag, String voiceNumber,
-            Message onComplete);
-
-    public String getVoiceMailAlphaTag() {
-        return voiceMailTag;
-    }
-
-    /**
-     * Sets the SIM voice message waiting indicator records
-     * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
-     * @param countWaiting The number of messages waiting, if known. Use
-     *                     -1 to indicate that an unknown number of
-     *                      messages are waiting
-     */
-    public abstract void setVoiceMessageWaiting(int line, int countWaiting);
-
-    /** @return  true if there are messages waiting, false otherwise. */
-    public boolean getVoiceMessageWaiting() {
-        return countVoiceMessages != 0;
-    }
-
-    /**
-     * Returns number of voice messages waiting, if available
-     * If not available (eg, on an older CPHS SIM) -1 is returned if
-     * getVoiceMessageWaiting() is true
-     */
-    public int getVoiceMessageCount() {
-        return countVoiceMessages;
-    }
-
-    /**
-     * Called by STK Service when REFRESH is received.
-     * @param fileChanged indicates whether any files changed
-     * @param fileList if non-null, a list of EF files that changed
-     */
-    public abstract void onRefresh(boolean fileChanged, int[] fileList);
-
-
-    public boolean getRecordsLoaded() {
-        if (recordsToLoad == 0 && recordsRequested == true) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    //***** Overridden from Handler
-    @Override
-    public void handleMessage(Message msg) {
-        switch (msg.what) {
-            case EVENT_GET_ICC_RECORD_DONE:
-                try {
-                    AsyncResult ar = (AsyncResult) msg.obj;
-                    IccRecordLoaded recordLoaded = (IccRecordLoaded) ar.userObj;
-                    if (DBG) log(recordLoaded.getEfName() + " LOADED");
-
-                    if (ar.exception != null) {
-                        loge("Record Load Exception: " + ar.exception);
-                    } else {
-                        recordLoaded.onRecordLoaded(ar);
-                    }
-                }catch (RuntimeException exc) {
-                    // I don't want these exceptions to be fatal
-                    loge("Exception parsing SIM record: " + exc);
-                } finally {
-                    // Count up record load responses even if they are fails
-                    onRecordLoaded();
-                }
-                break;
-
-            default:
-                super.handleMessage(msg);
-        }
-    }
-
-    protected abstract void onRecordLoaded();
-
-    protected abstract void onAllRecordsLoaded();
-
-    /**
-     * Returns the SpnDisplayRule based on settings on the SIM and the
-     * specified plmn (currently-registered PLMN).  See TS 22.101 Annex A
-     * and TS 51.011 10.3.11 for details.
-     *
-     * If the SPN is not found on the SIM, the rule is always PLMN_ONLY.
-     * Generally used for GSM/UMTS and the like SIMs.
-     */
-    public abstract int getDisplayRule(String plmn);
-
-    /**
-     * Return true if "Restriction of menu options for manual PLMN selection"
-     * bit is set or EF_CSP data is unavailable, return false otherwise.
-     * Generally used for GSM/UMTS and the like SIMs.
-     */
-    public boolean isCspPlmnEnabled() {
-        return false;
-    }
-
-    /**
-     * Returns the 5 or 6 digit MCC/MNC of the operator that
-     * provided the SIM card. Returns null of SIM is not yet ready
-     * or is not valid for the type of IccCard. Generally used for
-     * GSM/UMTS and the like SIMS
-     */
-    public String getOperatorNumeric() {
-        return null;
-    }
-
-    /**
-     * Get the current Voice call forwarding flag for GSM/UMTS and the like SIMs
-     *
-     * @return true if enabled
-     */
-    public boolean getVoiceCallForwardingFlag() {
-        return false;
-    }
-
-    /**
-     * Set the voice call forwarding flag for GSM/UMTS and the like SIMs
-     *
-     * @param line to enable/disable
-     * @param enable
-     */
-    public void setVoiceCallForwardingFlag(int line, boolean enable) {
-    }
-
-    /**
-     * Indicates wether SIM is in provisioned state or not.
-     * Overridden only if SIM can be dynamically provisioned via OTA.
-     *
-     * @return true if provisioned
-     */
-    public boolean isProvisioned () {
-        return true;
-    }
-
-    /**
-     * Write string to log file
-     *
-     * @param s is the string to write
-     */
-    protected abstract void log(String s);
-
-    /**
-     * Write error string to log file.
-     *
-     * @param s is the string to write
-     */
-    protected abstract void loge(String s);
-
-    /**
-     * Return an interface to retrieve the ISIM records for IMS, if available.
-     * @return the interface to retrieve the ISIM records, or null if not supported
-     */
-    public IsimRecords getIsimRecords() {
-        return null;
-    }
-
-    public UsimServiceTable getUsimServiceTable() {
-        return null;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/IccRefreshResponse.java b/telephony/java/com/android/internal/telephony/IccRefreshResponse.java
deleted file mode 100644
index 6806703..0000000
--- a/telephony/java/com/android/internal/telephony/IccRefreshResponse.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2011 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.internal.telephony;
-
-/**
- * See also RIL_SimRefresh in include/telephony/ril.h
- *
- * {@hide}
- */
-
-public class IccRefreshResponse {
-
-    public static final int REFRESH_RESULT_FILE_UPDATE = 0; /* Single file was updated */
-    public static final int REFRESH_RESULT_INIT = 1;        /* The Icc has been initialized */
-    public static final int REFRESH_RESULT_RESET = 2;       /* The Icc was reset */
-
-    public int             refreshResult;      /* Sim Refresh result */
-    public int             efId;               /* EFID */
-    public String          aid;                /* null terminated string, e.g.,
-                                                  from 0xA0, 0x00 -> 0x41,
-                                                  0x30, 0x30, 0x30 */
-                                               /* Example: a0000000871002f310ffff89080000ff */
-
-    @Override
-    public String toString() {
-        return "{" + refreshResult + ", " + aid +", " + efId + "}";
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/IccServiceTable.java b/telephony/java/com/android/internal/telephony/IccServiceTable.java
deleted file mode 100644
index ed74a11..0000000
--- a/telephony/java/com/android/internal/telephony/IccServiceTable.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2011 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.internal.telephony;
-
-import android.util.Log;
-
-/**
- * Wrapper class for an ICC EF containing a bit field of enabled services.
- */
-public abstract class IccServiceTable {
-    protected final byte[] mServiceTable;
-
-    protected IccServiceTable(byte[] table) {
-        mServiceTable = table;
-    }
-
-    // Get the class name to use for log strings
-    protected abstract String getTag();
-
-    // Get the array of enums to use for toString
-    protected abstract Object[] getValues();
-
-    /**
-     * Returns if the specified service is available.
-     * @param service the service number as a zero-based offset (the enum ordinal)
-     * @return true if the service is available; false otherwise
-     */
-    protected boolean isAvailable(int service) {
-        int offset = service / 8;
-        if (offset >= mServiceTable.length) {
-            // Note: Enums are zero-based, but the TS service numbering is one-based
-            Log.e(getTag(), "isAvailable for service " + (service + 1) + " fails, max service is " +
-                    (mServiceTable.length * 8));
-            return false;
-        }
-        int bit = service % 8;
-        return (mServiceTable[offset] & (1 << bit)) != 0;
-    }
-
-    public String toString() {
-        Object[] values = getValues();
-        int numBytes = mServiceTable.length;
-        StringBuilder builder = new StringBuilder(getTag()).append('[')
-                .append(numBytes * 8).append("]={ ");
-
-        boolean addComma = false;
-        for (int i = 0; i < numBytes; i++) {
-            byte currentByte = mServiceTable[i];
-            for (int bit = 0; bit < 8; bit++) {
-                if ((currentByte & (1 << bit)) != 0) {
-                    if (addComma) {
-                        builder.append(", ");
-                    } else {
-                        addComma = true;
-                    }
-                    int ordinal = (i * 8) + bit;
-                    if (ordinal < values.length) {
-                        builder.append(values[ordinal]);
-                    } else {
-                        builder.append('#').append(ordinal + 1);    // service number (one-based)
-                    }
-                }
-            }
-        }
-        return builder.append(" }").toString();
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java
deleted file mode 100644
index 5fef6de..0000000
--- a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * 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.internal.telephony;
-
-import android.app.PendingIntent;
-import android.content.Context;
-import android.util.Log;
-
-import com.android.internal.util.HexDump;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static android.telephony.SmsManager.STATUS_ON_ICC_FREE;
-
-/**
- * IccSmsInterfaceManager to provide an inter-process communication to
- * access Sms in Icc.
- */
-public abstract class IccSmsInterfaceManager extends ISms.Stub {
-    protected PhoneBase mPhone;
-    protected Context mContext;
-    protected SMSDispatcher mDispatcher;
-
-    protected IccSmsInterfaceManager(PhoneBase phone){
-        mPhone = phone;
-        mContext = phone.getContext();
-    }
-
-    protected void enforceReceiveAndSend(String message) {
-        mContext.enforceCallingPermission(
-                "android.permission.RECEIVE_SMS", message);
-        mContext.enforceCallingPermission(
-                "android.permission.SEND_SMS", message);
-    }
-
-    /**
-     * Send a data based SMS to a specific application port.
-     *
-     * @param destAddr the address to send the message to
-     * @param scAddr is the service center address or null to use
-     *  the current default SMSC
-     * @param destPort the port to deliver the message to
-     * @param data the body of the message to send
-     * @param sentIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is successfully sent, or failed.
-     *  The result code will be <code>Activity.RESULT_OK<code> for success,
-     *  or one of these errors:<br>
-     *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
-     *  <code>RESULT_ERROR_RADIO_OFF</code><br>
-     *  <code>RESULT_ERROR_NULL_PDU</code><br>
-     *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
-     *  the extra "errorCode" containing a radio technology specific value,
-     *  generally only useful for troubleshooting.<br>
-     *  The per-application based SMS control checks sentIntent. If sentIntent
-     *  is NULL the caller will be checked against all unknown applications,
-     *  which cause smaller number of SMS to be sent in checking period.
-     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is delivered to the recipient.  The
-     *  raw pdu of the status report is in the extended data ("pdu").
-     */
-    public void sendData(String destAddr, String scAddr, int destPort,
-            byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
-        mPhone.getContext().enforceCallingPermission(
-                "android.permission.SEND_SMS",
-                "Sending SMS message");
-        if (Log.isLoggable("SMS", Log.VERBOSE)) {
-            log("sendData: destAddr=" + destAddr + " scAddr=" + scAddr + " destPort=" +
-                destPort + " data='"+ HexDump.toHexString(data)  + "' sentIntent=" +
-                sentIntent + " deliveryIntent=" + deliveryIntent);
-        }
-        mDispatcher.sendData(destAddr, scAddr, destPort, data, sentIntent, deliveryIntent);
-    }
-
-    /**
-     * Send a text based SMS.
-     *
-     * @param destAddr the address to send the message to
-     * @param scAddr is the service center address or null to use
-     *  the current default SMSC
-     * @param text the body of the message to send
-     * @param sentIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is successfully sent, or failed.
-     *  The result code will be <code>Activity.RESULT_OK<code> for success,
-     *  or one of these errors:<br>
-     *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
-     *  <code>RESULT_ERROR_RADIO_OFF</code><br>
-     *  <code>RESULT_ERROR_NULL_PDU</code><br>
-     *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
-     *  the extra "errorCode" containing a radio technology specific value,
-     *  generally only useful for troubleshooting.<br>
-     *  The per-application based SMS control checks sentIntent. If sentIntent
-     *  is NULL the caller will be checked against all unknown applications,
-     *  which cause smaller number of SMS to be sent in checking period.
-     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is delivered to the recipient.  The
-     *  raw pdu of the status report is in the extended data ("pdu").
-     */
-    public void sendText(String destAddr, String scAddr,
-            String text, PendingIntent sentIntent, PendingIntent deliveryIntent) {
-        mPhone.getContext().enforceCallingPermission(
-                "android.permission.SEND_SMS",
-                "Sending SMS message");
-        if (Log.isLoggable("SMS", Log.VERBOSE)) {
-            log("sendText: destAddr=" + destAddr + " scAddr=" + scAddr +
-                " text='"+ text + "' sentIntent=" +
-                sentIntent + " deliveryIntent=" + deliveryIntent);
-        }
-        mDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent);
-    }
-
-    /**
-     * Send a multi-part text based SMS.
-     *
-     * @param destAddr the address to send the message to
-     * @param scAddr is the service center address or null to use
-     *   the current default SMSC
-     * @param parts an <code>ArrayList</code> of strings that, in order,
-     *   comprise the original message
-     * @param sentIntents if not null, an <code>ArrayList</code> of
-     *   <code>PendingIntent</code>s (one for each message part) that is
-     *   broadcast when the corresponding message part has been sent.
-     *   The result code will be <code>Activity.RESULT_OK<code> for success,
-     *   or one of these errors:
-     *   <code>RESULT_ERROR_GENERIC_FAILURE</code>
-     *   <code>RESULT_ERROR_RADIO_OFF</code>
-     *   <code>RESULT_ERROR_NULL_PDU</code>.
-     *  The per-application based SMS control checks sentIntent. If sentIntent
-     *  is NULL the caller will be checked against all unknown applications,
-     *  which cause smaller number of SMS to be sent in checking period.
-     * @param deliveryIntents if not null, an <code>ArrayList</code> of
-     *   <code>PendingIntent</code>s (one for each message part) that is
-     *   broadcast when the corresponding message part has been delivered
-     *   to the recipient.  The raw pdu of the status report is in the
-     *   extended data ("pdu").
-     */
-    public void sendMultipartText(String destAddr, String scAddr, List<String> parts,
-            List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) {
-        mPhone.getContext().enforceCallingPermission(
-                "android.permission.SEND_SMS",
-                "Sending SMS message");
-        if (Log.isLoggable("SMS", Log.VERBOSE)) {
-            int i = 0;
-            for (String part : parts) {
-                log("sendMultipartText: destAddr=" + destAddr + ", srAddr=" + scAddr +
-                        ", part[" + (i++) + "]=" + part);
-            }
-        }
-        mDispatcher.sendMultipartText(destAddr, scAddr, (ArrayList<String>) parts,
-                (ArrayList<PendingIntent>) sentIntents, (ArrayList<PendingIntent>) deliveryIntents);
-    }
-
-    /**
-     * create SmsRawData lists from all sms record byte[]
-     * Use null to indicate "free" record
-     *
-     * @param messages List of message records from EF_SMS.
-     * @return SmsRawData list of all in-used records
-     */
-    protected ArrayList<SmsRawData> buildValidRawData(ArrayList<byte[]> messages) {
-        int count = messages.size();
-        ArrayList<SmsRawData> ret;
-
-        ret = new ArrayList<SmsRawData>(count);
-
-        for (int i = 0; i < count; i++) {
-            byte[] ba = messages.get(i);
-            if (ba[0] == STATUS_ON_ICC_FREE) {
-                ret.add(null);
-            } else {
-                ret.add(new SmsRawData(messages.get(i)));
-            }
-        }
-
-        return ret;
-    }
-
-    /**
-     * Generates an EF_SMS record from status and raw PDU.
-     *
-     * @param status Message status.  See TS 51.011 10.5.3.
-     * @param pdu Raw message PDU.
-     * @return byte array for the record.
-     */
-    protected byte[] makeSmsRecordData(int status, byte[] pdu) {
-        byte[] data = new byte[IccConstants.SMS_RECORD_LENGTH];
-
-        // Status bits for this record.  See TS 51.011 10.5.3
-        data[0] = (byte)(status & 7);
-
-        System.arraycopy(pdu, 0, data, 1, pdu.length);
-
-        // Pad out with 0xFF's.
-        for (int j = pdu.length+1; j < IccConstants.SMS_RECORD_LENGTH; j++) {
-            data[j] = -1;
-        }
-
-        return data;
-    }
-
-    protected abstract void log(String msg);
-
-}
diff --git a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy.java b/telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy.java
deleted file mode 100644
index 54de508..0000000
--- a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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.internal.telephony;
-
-import android.app.PendingIntent;
-import android.os.ServiceManager;
-
-import java.util.List;
-
-public class IccSmsInterfaceManagerProxy extends ISms.Stub {
-    private IccSmsInterfaceManager mIccSmsInterfaceManager;
-
-    public IccSmsInterfaceManagerProxy(IccSmsInterfaceManager
-            iccSmsInterfaceManager) {
-        this.mIccSmsInterfaceManager = iccSmsInterfaceManager;
-        if(ServiceManager.getService("isms") == null) {
-            ServiceManager.addService("isms", this);
-        }
-    }
-
-    public void setmIccSmsInterfaceManager(IccSmsInterfaceManager iccSmsInterfaceManager) {
-        this.mIccSmsInterfaceManager = iccSmsInterfaceManager;
-    }
-
-    public boolean
-    updateMessageOnIccEf(int index, int status, byte[] pdu) throws android.os.RemoteException {
-         return mIccSmsInterfaceManager.updateMessageOnIccEf(index, status, pdu);
-    }
-
-    public boolean copyMessageToIccEf(int status, byte[] pdu,
-            byte[] smsc) throws android.os.RemoteException {
-        return mIccSmsInterfaceManager.copyMessageToIccEf(status, pdu, smsc);
-    }
-
-    public List<SmsRawData> getAllMessagesFromIccEf() throws android.os.RemoteException {
-        return mIccSmsInterfaceManager.getAllMessagesFromIccEf();
-    }
-
-    public void sendData(String destAddr, String scAddr, int destPort,
-            byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
-        mIccSmsInterfaceManager.sendData(destAddr, scAddr, destPort, data,
-                sentIntent, deliveryIntent);
-    }
-
-    public void sendText(String destAddr, String scAddr,
-            String text, PendingIntent sentIntent, PendingIntent deliveryIntent) {
-        mIccSmsInterfaceManager.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent);
-    }
-
-    public void sendMultipartText(String destAddr, String scAddr,
-            List<String> parts, List<PendingIntent> sentIntents,
-            List<PendingIntent> deliveryIntents) throws android.os.RemoteException {
-        mIccSmsInterfaceManager.sendMultipartText(destAddr, scAddr,
-                parts, sentIntents, deliveryIntents);
-    }
-
-    public boolean enableCellBroadcast(int messageIdentifier) throws android.os.RemoteException {
-        return mIccSmsInterfaceManager.enableCellBroadcast(messageIdentifier);
-    }
-
-    public boolean disableCellBroadcast(int messageIdentifier) throws android.os.RemoteException {
-        return mIccSmsInterfaceManager.disableCellBroadcast(messageIdentifier);
-    }
-
-    public boolean enableCellBroadcastRange(int startMessageId, int endMessageId)
-            throws android.os.RemoteException {
-        return mIccSmsInterfaceManager.enableCellBroadcastRange(startMessageId, endMessageId);
-    }
-
-    public boolean disableCellBroadcastRange(int startMessageId, int endMessageId)
-            throws android.os.RemoteException {
-        return mIccSmsInterfaceManager.disableCellBroadcastRange(startMessageId, endMessageId);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/IccUtils.java b/telephony/java/com/android/internal/telephony/IccUtils.java
deleted file mode 100644
index a966f76..0000000
--- a/telephony/java/com/android/internal/telephony/IccUtils.java
+++ /dev/null
@@ -1,530 +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.internal.telephony;
-
-import android.content.res.Resources;
-import android.content.res.Resources.NotFoundException;
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.util.Log;
-
-import com.android.internal.telephony.GsmAlphabet;
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-
-/**
- * Various methods, useful for dealing with SIM data.
- */
-public class IccUtils {
-    static final String LOG_TAG="IccUtils";
-
-    /**
-     * Many fields in GSM SIM's are stored as nibble-swizzled BCD
-     *
-     * Assumes left-justified field that may be padded right with 0xf
-     * values.
-     *
-     * Stops on invalid BCD value, returning string so far
-     */
-    public static String
-    bcdToString(byte[] data, int offset, int length) {
-        StringBuilder ret = new StringBuilder(length*2);
-
-        for (int i = offset ; i < offset + length ; i++) {
-            byte b;
-            int v;
-
-            v = data[i] & 0xf;
-            if (v > 9)  break;
-            ret.append((char)('0' + v));
-
-            v = (data[i] >> 4) & 0xf;
-            // Some PLMNs have 'f' as high nibble, ignore it
-            if (v == 0xf) continue;
-            if (v > 9)  break;
-            ret.append((char)('0' + v));
-        }
-
-        return ret.toString();
-    }
-
-    /**
-     * Decode cdma byte into String.
-     */
-    public static String
-    cdmaBcdToString(byte[] data, int offset, int length) {
-        StringBuilder ret = new StringBuilder(length);
-
-        int count = 0;
-        for (int i = offset; count < length; i++) {
-            int v;
-            v = data[i] & 0xf;
-            if (v > 9)  v = 0;
-            ret.append((char)('0' + v));
-
-            if (++count == length) break;
-
-            v = (data[i] >> 4) & 0xf;
-            if (v > 9)  v = 0;
-            ret.append((char)('0' + v));
-            ++count;
-        }
-        return ret.toString();
-    }
-
-    /**
-     * Decodes a GSM-style BCD byte, returning an int ranging from 0-99.
-     *
-     * In GSM land, the least significant BCD digit is stored in the most
-     * significant nibble.
-     *
-     * Out-of-range digits are treated as 0 for the sake of the time stamp,
-     * because of this:
-     *
-     * TS 23.040 section 9.2.3.11
-     * "if the MS receives a non-integer value in the SCTS, it shall
-     * assume the digit is set to 0 but shall store the entire field
-     * exactly as received"
-     */
-    public static int
-    gsmBcdByteToInt(byte b) {
-        int ret = 0;
-
-        // treat out-of-range BCD values as 0
-        if ((b & 0xf0) <= 0x90) {
-            ret = (b >> 4) & 0xf;
-        }
-
-        if ((b & 0x0f) <= 0x09) {
-            ret +=  (b & 0xf) * 10;
-        }
-
-        return ret;
-    }
-
-    /**
-     * Decodes a CDMA style BCD byte like {@link gsmBcdByteToInt}, but
-     * opposite nibble format. The least significant BCD digit
-     * is in the least significant nibble and the most significant
-     * is in the most significant nibble.
-     */
-    public static int
-    cdmaBcdByteToInt(byte b) {
-        int ret = 0;
-
-        // treat out-of-range BCD values as 0
-        if ((b & 0xf0) <= 0x90) {
-            ret = ((b >> 4) & 0xf) * 10;
-        }
-
-        if ((b & 0x0f) <= 0x09) {
-            ret +=  (b & 0xf);
-        }
-
-        return ret;
-    }
-
-    /**
-     * Decodes a string field that's formatted like the EF[ADN] alpha
-     * identifier
-     *
-     * From TS 51.011 10.5.1:
-     *   Coding:
-     *       this alpha tagging shall use either
-     *      -    the SMS default 7 bit coded alphabet as defined in
-     *          TS 23.038 [12] with bit 8 set to 0. The alpha identifier
-     *          shall be left justified. Unused bytes shall be set to 'FF'; or
-     *      -    one of the UCS2 coded options as defined in annex B.
-     *
-     * Annex B from TS 11.11 V8.13.0:
-     *      1)  If the first octet in the alpha string is '80', then the
-     *          remaining octets are 16 bit UCS2 characters ...
-     *      2)  if the first octet in the alpha string is '81', then the
-     *          second octet contains a value indicating the number of
-     *          characters in the string, and the third octet contains an
-     *          8 bit number which defines bits 15 to 8 of a 16 bit
-     *          base pointer, where bit 16 is set to zero and bits 7 to 1
-     *          are also set to zero.  These sixteen bits constitute a
-     *          base pointer to a "half page" in the UCS2 code space, to be
-     *          used with some or all of the remaining octets in the string.
-     *          The fourth and subsequent octets contain codings as follows:
-     *          If bit 8 of the octet is set to zero, the remaining 7 bits
-     *          of the octet contain a GSM Default Alphabet character,
-     *          whereas if bit 8 of the octet is set to one, then the
-     *          remaining seven bits are an offset value added to the
-     *          16 bit base pointer defined earlier...
-     *      3)  If the first octet of the alpha string is set to '82', then
-     *          the second octet contains a value indicating the number of
-     *          characters in the string, and the third and fourth octets
-     *          contain a 16 bit number which defines the complete 16 bit
-     *          base pointer to a "half page" in the UCS2 code space...
-     */
-    public static String
-    adnStringFieldToString(byte[] data, int offset, int length) {
-        if (length == 0) {
-            return "";
-        }
-        if (length >= 1) {
-            if (data[offset] == (byte) 0x80) {
-                int ucslen = (length - 1) / 2;
-                String ret = null;
-
-                try {
-                    ret = new String(data, offset + 1, ucslen * 2, "utf-16be");
-                } catch (UnsupportedEncodingException ex) {
-                    Log.e(LOG_TAG, "implausible UnsupportedEncodingException",
-                          ex);
-                }
-
-                if (ret != null) {
-                    // trim off trailing FFFF characters
-
-                    ucslen = ret.length();
-                    while (ucslen > 0 && ret.charAt(ucslen - 1) == '\uFFFF')
-                        ucslen--;
-
-                    return ret.substring(0, ucslen);
-                }
-            }
-        }
-
-        boolean isucs2 = false;
-        char base = '\0';
-        int len = 0;
-
-        if (length >= 3 && data[offset] == (byte) 0x81) {
-            len = data[offset + 1] & 0xFF;
-            if (len > length - 3)
-                len = length - 3;
-
-            base = (char) ((data[offset + 2] & 0xFF) << 7);
-            offset += 3;
-            isucs2 = true;
-        } else if (length >= 4 && data[offset] == (byte) 0x82) {
-            len = data[offset + 1] & 0xFF;
-            if (len > length - 4)
-                len = length - 4;
-
-            base = (char) (((data[offset + 2] & 0xFF) << 8) |
-                            (data[offset + 3] & 0xFF));
-            offset += 4;
-            isucs2 = true;
-        }
-
-        if (isucs2) {
-            StringBuilder ret = new StringBuilder();
-
-            while (len > 0) {
-                // UCS2 subset case
-
-                if (data[offset] < 0) {
-                    ret.append((char) (base + (data[offset] & 0x7F)));
-                    offset++;
-                    len--;
-                }
-
-                // GSM character set case
-
-                int count = 0;
-                while (count < len && data[offset + count] >= 0)
-                    count++;
-
-                ret.append(GsmAlphabet.gsm8BitUnpackedToString(data,
-                           offset, count));
-
-                offset += count;
-                len -= count;
-            }
-
-            return ret.toString();
-        }
-
-        Resources resource = Resources.getSystem();
-        String defaultCharset = "";
-        try {
-            defaultCharset =
-                    resource.getString(com.android.internal.R.string.gsm_alphabet_default_charset);
-        } catch (NotFoundException e) {
-            // Ignore Exception and defaultCharset is set to a empty string.
-        }
-        return GsmAlphabet.gsm8BitUnpackedToString(data, offset, length, defaultCharset.trim());
-    }
-
-    static int
-    hexCharToInt(char c) {
-        if (c >= '0' && c <= '9') return (c - '0');
-        if (c >= 'A' && c <= 'F') return (c - 'A' + 10);
-        if (c >= 'a' && c <= 'f') return (c - 'a' + 10);
-
-        throw new RuntimeException ("invalid hex char '" + c + "'");
-    }
-
-    /**
-     * Converts a hex String to a byte array.
-     *
-     * @param s A string of hexadecimal characters, must be an even number of
-     *          chars long
-     *
-     * @return byte array representation
-     *
-     * @throws RuntimeException on invalid format
-     */
-    public static byte[]
-    hexStringToBytes(String s) {
-        byte[] ret;
-
-        if (s == null) return null;
-
-        int sz = s.length();
-
-        ret = new byte[sz/2];
-
-        for (int i=0 ; i <sz ; i+=2) {
-            ret[i/2] = (byte) ((hexCharToInt(s.charAt(i)) << 4)
-                                | hexCharToInt(s.charAt(i+1)));
-        }
-
-        return ret;
-    }
-
-
-    /**
-     * Converts a byte array into a String of hexadecimal characters.
-     *
-     * @param bytes an array of bytes
-     *
-     * @return hex string representation of bytes array
-     */
-    public static String
-    bytesToHexString(byte[] bytes) {
-        if (bytes == null) return null;
-
-        StringBuilder ret = new StringBuilder(2*bytes.length);
-
-        for (int i = 0 ; i < bytes.length ; i++) {
-            int b;
-
-            b = 0x0f & (bytes[i] >> 4);
-
-            ret.append("0123456789abcdef".charAt(b));
-
-            b = 0x0f & bytes[i];
-
-            ret.append("0123456789abcdef".charAt(b));
-        }
-
-        return ret.toString();
-    }
-
-
-    /**
-     * Convert a TS 24.008 Section 10.5.3.5a Network Name field to a string
-     * "offset" points to "octet 3", the coding scheme byte
-     * empty string returned on decode error
-     */
-    public static String
-    networkNameToString(byte[] data, int offset, int length) {
-        String ret;
-
-        if ((data[offset] & 0x80) != 0x80 || length < 1) {
-            return "";
-        }
-
-        switch ((data[offset] >>> 4) & 0x7) {
-            case 0:
-                // SMS character set
-                int countSeptets;
-                int unusedBits = data[offset] & 7;
-                countSeptets = (((length - 1) * 8) - unusedBits) / 7 ;
-                ret =  GsmAlphabet.gsm7BitPackedToString(data, offset + 1, countSeptets);
-            break;
-            case 1:
-                // UCS2
-                try {
-                    ret = new String(data,
-                            offset + 1, length - 1, "utf-16");
-                } catch (UnsupportedEncodingException ex) {
-                    ret = "";
-                    Log.e(LOG_TAG,"implausible UnsupportedEncodingException", ex);
-                }
-            break;
-
-            // unsupported encoding
-            default:
-                ret = "";
-            break;
-        }
-
-        // "Add CI"
-        // "The MS should add the letters for the Country's Initials and
-        //  a separator (e.g. a space) to the text string"
-
-        if ((data[offset] & 0x40) != 0) {
-            // FIXME(mkf) add country initials here
-
-        }
-
-        return ret;
-    }
-
-    /**
-     * Convert a TS 131.102 image instance of code scheme '11' into Bitmap
-     * @param data The raw data
-     * @param length The length of image body
-     * @return The bitmap
-     */
-    public static Bitmap parseToBnW(byte[] data, int length){
-        int valueIndex = 0;
-        int width = data[valueIndex++] & 0xFF;
-        int height = data[valueIndex++] & 0xFF;
-        int numOfPixels = width*height;
-
-        int[] pixels = new int[numOfPixels];
-
-        int pixelIndex = 0;
-        int bitIndex = 7;
-        byte currentByte = 0x00;
-        while (pixelIndex < numOfPixels) {
-            // reassign data and index for every byte (8 bits).
-            if (pixelIndex % 8 == 0) {
-                currentByte = data[valueIndex++];
-                bitIndex = 7;
-            }
-            pixels[pixelIndex++] = bitToRGB((currentByte >> bitIndex-- ) & 0x01);
-        };
-
-        if (pixelIndex != numOfPixels) {
-            Log.e(LOG_TAG, "parse end and size error");
-        }
-        return Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888);
-    }
-
-    private static int bitToRGB(int bit){
-        if(bit == 1){
-            return Color.WHITE;
-        } else {
-            return Color.BLACK;
-        }
-    }
-
-    /**
-     * a TS 131.102 image instance of code scheme '11' into color Bitmap
-     *
-     * @param data The raw data
-     * @param length the length of image body
-     * @param transparency with or without transparency
-     * @return The color bitmap
-     */
-    public static Bitmap parseToRGB(byte[] data, int length,
-            boolean transparency) {
-        int valueIndex = 0;
-        int width = data[valueIndex++] & 0xFF;
-        int height = data[valueIndex++] & 0xFF;
-        int bits = data[valueIndex++] & 0xFF;
-        int colorNumber = data[valueIndex++] & 0xFF;
-        int clutOffset = ((data[valueIndex++] & 0xFF) << 8)
-                | (data[valueIndex++] & 0xFF);
-
-        int[] colorIndexArray = getCLUT(data, clutOffset, colorNumber);
-        if (true == transparency) {
-            colorIndexArray[colorNumber - 1] = Color.TRANSPARENT;
-        }
-
-        int[] resultArray = null;
-        if (0 == (8 % bits)) {
-            resultArray = mapTo2OrderBitColor(data, valueIndex,
-                    (width * height), colorIndexArray, bits);
-        } else {
-            resultArray = mapToNon2OrderBitColor(data, valueIndex,
-                    (width * height), colorIndexArray, bits);
-        }
-
-        return Bitmap.createBitmap(resultArray, width, height,
-                Bitmap.Config.RGB_565);
-    }
-
-    private static int[] mapTo2OrderBitColor(byte[] data, int valueIndex,
-            int length, int[] colorArray, int bits) {
-        if (0 != (8 % bits)) {
-            Log.e(LOG_TAG, "not event number of color");
-            return mapToNon2OrderBitColor(data, valueIndex, length, colorArray,
-                    bits);
-        }
-
-        int mask = 0x01;
-        switch (bits) {
-        case 1:
-            mask = 0x01;
-            break;
-        case 2:
-            mask = 0x03;
-            break;
-        case 4:
-            mask = 0x0F;
-            break;
-        case 8:
-            mask = 0xFF;
-            break;
-        }
-
-        int[] resultArray = new int[length];
-        int resultIndex = 0;
-        int run = 8 / bits;
-        while (resultIndex < length) {
-            byte tempByte = data[valueIndex++];
-            for (int runIndex = 0; runIndex < run; ++runIndex) {
-                int offset = run - runIndex - 1;
-                resultArray[resultIndex++] = colorArray[(tempByte >> (offset * bits))
-                        & mask];
-            }
-        }
-        return resultArray;
-    }
-
-    private static int[] mapToNon2OrderBitColor(byte[] data, int valueIndex,
-            int length, int[] colorArray, int bits) {
-        if (0 == (8 % bits)) {
-            Log.e(LOG_TAG, "not odd number of color");
-            return mapTo2OrderBitColor(data, valueIndex, length, colorArray,
-                    bits);
-        }
-
-        int[] resultArray = new int[length];
-        // TODO fix me:
-        return resultArray;
-    }
-
-    private static int[] getCLUT(byte[] rawData, int offset, int number) {
-        if (null == rawData) {
-            return null;
-        }
-
-        int[] result = new int[number];
-        int endIndex = offset + (number * 3); // 1 color use 3 bytes
-        int valueIndex = offset;
-        int colorIndex = 0;
-        int alpha = 0xff << 24;
-        do {
-            result[colorIndex++] = alpha
-                    | ((rawData[valueIndex++] & 0xFF) << 16)
-                    | ((rawData[valueIndex++] & 0xFF) << 8)
-                    | ((rawData[valueIndex++] & 0xFF));
-        } while (valueIndex < endIndex);
-        return result;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/IccVmFixedException.java b/telephony/java/com/android/internal/telephony/IccVmFixedException.java
deleted file mode 100644
index a75496f..0000000
--- a/telephony/java/com/android/internal/telephony/IccVmFixedException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.internal.telephony;
-
-/**
- * {@hide}
- */
-public final class IccVmFixedException extends IccException {
-    IccVmFixedException()
-    {
-
-    }
-
-    public IccVmFixedException(String s)
-    {
-        super(s);
-    }
-}
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/IccVmNotSupportedException.java b/telephony/java/com/android/internal/telephony/IccVmNotSupportedException.java
deleted file mode 100644
index 3c9d126..0000000
--- a/telephony/java/com/android/internal/telephony/IccVmNotSupportedException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.internal.telephony;
-
-/**
- * {@hide}
- */
-public final class IccVmNotSupportedException extends IccException {
-    IccVmNotSupportedException()
-    {
-
-    }
-
-    public IccVmNotSupportedException(String s)
-    {
-        super(s);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/IntRangeManager.java b/telephony/java/com/android/internal/telephony/IntRangeManager.java
deleted file mode 100644
index cc7774d..0000000
--- a/telephony/java/com/android/internal/telephony/IntRangeManager.java
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- * Copyright (C) 2011 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.internal.telephony;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-/**
- * Clients can enable reception of SMS-CB messages for specific ranges of
- * message identifiers (channels). This class keeps track of the currently
- * enabled message identifiers and calls abstract methods to update the
- * radio when the range of enabled message identifiers changes.
- *
- * An update is a call to {@link #startUpdate} followed by zero or more
- * calls to {@link #addRange} followed by a call to {@link #finishUpdate}.
- * Calls to {@link #enableRange} and {@link #disableRange} will perform
- * an incremental update operation if the enabled ranges have changed.
- * A full update operation (i.e. after a radio reset) can be performed
- * by a call to {@link #updateRanges}.
- *
- * Clients are identified by String (the name associated with the User ID
- * of the caller) so that a call to remove a range can be mapped to the
- * client that enabled that range (or else rejected).
- */
-public abstract class IntRangeManager {
-
-    /**
-     * Initial capacity for IntRange clients array list. There will be
-     * few cell broadcast listeners on a typical device, so this can be small.
-     */
-    private static final int INITIAL_CLIENTS_ARRAY_SIZE = 4;
-
-    /**
-     * One or more clients forming the continuous range [startId, endId].
-     * <p>When a client is added, the IntRange may merge with one or more
-     * adjacent IntRanges to form a single combined IntRange.
-     * <p>When a client is removed, the IntRange may divide into several
-     * non-contiguous IntRanges.
-     */
-    private class IntRange {
-        int startId;
-        int endId;
-        // sorted by earliest start id
-        final ArrayList<ClientRange> clients;
-
-        /**
-         * Create a new IntRange with a single client.
-         * @param startId the first id included in the range
-         * @param endId the last id included in the range
-         * @param client the client requesting the enabled range
-         */
-        IntRange(int startId, int endId, String client) {
-            this.startId = startId;
-            this.endId = endId;
-            clients = new ArrayList<ClientRange>(INITIAL_CLIENTS_ARRAY_SIZE);
-            clients.add(new ClientRange(startId, endId, client));
-        }
-
-        /**
-         * Create a new IntRange for an existing ClientRange.
-         * @param clientRange the initial ClientRange to add
-         */
-        IntRange(ClientRange clientRange) {
-            startId = clientRange.startId;
-            endId = clientRange.endId;
-            clients = new ArrayList<ClientRange>(INITIAL_CLIENTS_ARRAY_SIZE);
-            clients.add(clientRange);
-        }
-
-        /**
-         * Create a new IntRange from an existing IntRange. This is used for
-         * removing a ClientRange, because new IntRanges may need to be created
-         * for any gaps that open up after the ClientRange is removed. A copy
-         * is made of the elements of the original IntRange preceding the element
-         * that is being removed. The following elements will be added to this
-         * IntRange or to a new IntRange when a gap is found.
-         * @param intRange the original IntRange to copy elements from
-         * @param numElements the number of elements to copy from the original
-         */
-        IntRange(IntRange intRange, int numElements) {
-            this.startId = intRange.startId;
-            this.endId = intRange.endId;
-            this.clients = new ArrayList<ClientRange>(intRange.clients.size());
-            for (int i=0; i < numElements; i++) {
-                this.clients.add(intRange.clients.get(i));
-            }
-        }
-
-        /**
-         * Insert new ClientRange in order by start id.
-         * <p>If the new ClientRange is known to be sorted before or after the
-         * existing ClientRanges, or at a particular index, it can be added
-         * to the clients array list directly, instead of via this method.
-         * <p>Note that this can be changed from linear to binary search if the
-         * number of clients grows large enough that it would make a difference.
-         * @param range the new ClientRange to insert
-         */
-        void insert(ClientRange range) {
-            int len = clients.size();
-            for (int i=0; i < len; i++) {
-                ClientRange nextRange = clients.get(i);
-                if (range.startId <= nextRange.startId) {
-                    // ignore duplicate ranges from the same client
-                    if (!range.equals(nextRange)) {
-                        clients.add(i, range);
-                    }
-                    return;
-                }
-            }
-            clients.add(range);    // append to end of list
-        }
-    }
-
-    /**
-     * The message id range for a single client.
-     */
-    private class ClientRange {
-        final int startId;
-        final int endId;
-        final String client;
-
-        ClientRange(int startId, int endId, String client) {
-            this.startId = startId;
-            this.endId = endId;
-            this.client = client;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (o != null && o instanceof ClientRange) {
-                ClientRange other = (ClientRange) o;
-                return startId == other.startId &&
-                        endId == other.endId &&
-                        client.equals(other.client);
-            } else {
-                return false;
-            }
-        }
-
-        @Override
-        public int hashCode() {
-            return (startId * 31 + endId) * 31 + client.hashCode();
-        }
-    }
-
-    /**
-     * List of integer ranges, one per client, sorted by start id.
-     */
-    private ArrayList<IntRange> mRanges = new ArrayList<IntRange>();
-
-    protected IntRangeManager() {}
-
-    /**
-     * Enable a range for the specified client and update ranges
-     * if necessary. If {@link #finishUpdate} returns failure,
-     * false is returned and the range is not added.
-     *
-     * @param startId the first id included in the range
-     * @param endId the last id included in the range
-     * @param client the client requesting the enabled range
-     * @return true if successful, false otherwise
-     */
-    public synchronized boolean enableRange(int startId, int endId, String client) {
-        int len = mRanges.size();
-
-        // empty range list: add the initial IntRange
-        if (len == 0) {
-            if (tryAddSingleRange(startId, endId, true)) {
-                mRanges.add(new IntRange(startId, endId, client));
-                return true;
-            } else {
-                return false;   // failed to update radio
-            }
-        }
-
-        for (int startIndex = 0; startIndex < len; startIndex++) {
-            IntRange range = mRanges.get(startIndex);
-            if (startId < range.startId) {
-                // test if new range completely precedes this range
-                // note that [1, 4] and [5, 6] coalesce to [1, 6]
-                if ((endId + 1) < range.startId) {
-                    // insert new int range before previous first range
-                    if (tryAddSingleRange(startId, endId, true)) {
-                        mRanges.add(startIndex, new IntRange(startId, endId, client));
-                        return true;
-                    } else {
-                        return false;   // failed to update radio
-                    }
-                } else if (endId <= range.endId) {
-                    // extend the start of this range
-                    if (tryAddSingleRange(startId, range.startId - 1, true)) {
-                        range.startId = startId;
-                        range.clients.add(0, new ClientRange(startId, endId, client));
-                        return true;
-                    } else {
-                        return false;   // failed to update radio
-                    }
-                } else {
-                    // find last range that can coalesce into the new combined range
-                    for (int endIndex = startIndex+1; endIndex < len; endIndex++) {
-                        IntRange endRange = mRanges.get(endIndex);
-                        if ((endId + 1) < endRange.startId) {
-                            // try to add entire new range
-                            if (tryAddSingleRange(startId, endId, true)) {
-                                range.startId = startId;
-                                range.endId = endId;
-                                // insert new ClientRange before existing ranges
-                                range.clients.add(0, new ClientRange(startId, endId, client));
-                                // coalesce range with following ranges up to endIndex-1
-                                // remove each range after adding its elements, so the index
-                                // of the next range to join is always startIndex+1.
-                                // i is the index if no elements were removed: we only care
-                                // about the number of loop iterations, not the value of i.
-                                int joinIndex = startIndex + 1;
-                                for (int i = joinIndex; i < endIndex; i++) {
-                                    IntRange joinRange = mRanges.get(joinIndex);
-                                    range.clients.addAll(joinRange.clients);
-                                    mRanges.remove(joinRange);
-                                }
-                                return true;
-                            } else {
-                                return false;   // failed to update radio
-                            }
-                        } else if (endId <= endRange.endId) {
-                            // add range from start id to start of last overlapping range,
-                            // values from endRange.startId to endId are already enabled
-                            if (tryAddSingleRange(startId, endRange.startId - 1, true)) {
-                                range.startId = startId;
-                                range.endId = endRange.endId;
-                                // insert new ClientRange before existing ranges
-                                range.clients.add(0, new ClientRange(startId, endId, client));
-                                // coalesce range with following ranges up to endIndex
-                                // remove each range after adding its elements, so the index
-                                // of the next range to join is always startIndex+1.
-                                // i is the index if no elements were removed: we only care
-                                // about the number of loop iterations, not the value of i.
-                                int joinIndex = startIndex + 1;
-                                for (int i = joinIndex; i <= endIndex; i++) {
-                                    IntRange joinRange = mRanges.get(joinIndex);
-                                    range.clients.addAll(joinRange.clients);
-                                    mRanges.remove(joinRange);
-                                }
-                                return true;
-                            } else {
-                                return false;   // failed to update radio
-                            }
-                        }
-                    }
-
-                    // endId extends past all existing IntRanges: combine them all together
-                    if (tryAddSingleRange(startId, endId, true)) {
-                        range.startId = startId;
-                        range.endId = endId;
-                        // insert new ClientRange before existing ranges
-                        range.clients.add(0, new ClientRange(startId, endId, client));
-                        // coalesce range with following ranges up to len-1
-                        // remove each range after adding its elements, so the index
-                        // of the next range to join is always startIndex+1.
-                        // i is the index if no elements were removed: we only care
-                        // about the number of loop iterations, not the value of i.
-                        int joinIndex = startIndex + 1;
-                        for (int i = joinIndex; i < len; i++) {
-                            IntRange joinRange = mRanges.get(joinIndex);
-                            range.clients.addAll(joinRange.clients);
-                            mRanges.remove(joinRange);
-                        }
-                        return true;
-                    } else {
-                        return false;   // failed to update radio
-                    }
-                }
-            } else if ((startId + 1) <= range.endId) {
-                if (endId <= range.endId) {
-                    // completely contained in existing range; no radio changes
-                    range.insert(new ClientRange(startId, endId, client));
-                    return true;
-                } else {
-                    // find last range that can coalesce into the new combined range
-                    int endIndex = startIndex;
-                    for (int testIndex = startIndex+1; testIndex < len; testIndex++) {
-                        IntRange testRange = mRanges.get(testIndex);
-                        if ((endId + 1) < testRange.startId) {
-                            break;
-                        } else {
-                            endIndex = testIndex;
-                        }
-                    }
-                    // no adjacent IntRanges to combine
-                    if (endIndex == startIndex) {
-                        // add range from range.endId+1 to endId,
-                        // values from startId to range.endId are already enabled
-                        if (tryAddSingleRange(range.endId + 1, endId, true)) {
-                            range.endId = endId;
-                            range.insert(new ClientRange(startId, endId, client));
-                            return true;
-                        } else {
-                            return false;   // failed to update radio
-                        }
-                    }
-                    // get last range to coalesce into start range
-                    IntRange endRange = mRanges.get(endIndex);
-                    // Values from startId to range.endId have already been enabled.
-                    // if endId > endRange.endId, then enable range from range.endId+1 to endId,
-                    // else enable range from range.endId+1 to endRange.startId-1, because
-                    // values from endRange.startId to endId have already been added.
-                    int newRangeEndId = (endId <= endRange.endId) ? endRange.startId - 1 : endId;
-                    if (tryAddSingleRange(range.endId + 1, newRangeEndId, true)) {
-                        range.endId = endId;
-                        // insert new ClientRange in place
-                        range.insert(new ClientRange(startId, endId, client));
-                        // coalesce range with following ranges up to endIndex-1
-                        // remove each range after adding its elements, so the index
-                        // of the next range to join is always startIndex+1 (joinIndex).
-                        // i is the index if no elements had been removed: we only care
-                        // about the number of loop iterations, not the value of i.
-                        int joinIndex = startIndex + 1;
-                        for (int i = joinIndex; i < endIndex; i++) {
-                            IntRange joinRange = mRanges.get(joinIndex);
-                            range.clients.addAll(joinRange.clients);
-                            mRanges.remove(joinRange);
-                        }
-                        return true;
-                    } else {
-                        return false;   // failed to update radio
-                    }
-                }
-            }
-        }
-
-        // append new range after existing IntRanges
-        if (tryAddSingleRange(startId, endId, true)) {
-            mRanges.add(new IntRange(startId, endId, client));
-            return true;
-        } else {
-            return false;   // failed to update radio
-        }
-    }
-
-    /**
-     * Disable a range for the specified client and update ranges
-     * if necessary. If {@link #finishUpdate} returns failure,
-     * false is returned and the range is not removed.
-     *
-     * @param startId the first id included in the range
-     * @param endId the last id included in the range
-     * @param client the client requesting to disable the range
-     * @return true if successful, false otherwise
-     */
-    public synchronized boolean disableRange(int startId, int endId, String client) {
-        int len = mRanges.size();
-
-        for (int i=0; i < len; i++) {
-            IntRange range = mRanges.get(i);
-            if (startId < range.startId) {
-                return false;   // not found
-            } else if (endId <= range.endId) {
-                // found the IntRange that encloses the client range, if any
-                // search for it in the clients list
-                ArrayList<ClientRange> clients = range.clients;
-
-                // handle common case of IntRange containing one ClientRange
-                int crLength = clients.size();
-                if (crLength == 1) {
-                    ClientRange cr = clients.get(0);
-                    if (cr.startId == startId && cr.endId == endId && cr.client.equals(client)) {
-                        // disable range in radio then remove the entire IntRange
-                        if (tryAddSingleRange(startId, endId, false)) {
-                            mRanges.remove(i);
-                            return true;
-                        } else {
-                            return false;   // failed to update radio
-                        }
-                    } else {
-                        return false;   // not found
-                    }
-                }
-
-                // several ClientRanges: remove one, potentially splitting into many IntRanges.
-                // Save the original start and end id for the original IntRange
-                // in case the radio update fails and we have to revert it. If the
-                // update succeeds, we remove the client range and insert the new IntRanges.
-                int largestEndId = Integer.MIN_VALUE;  // largest end identifier found
-                boolean updateStarted = false;
-
-                for (int crIndex=0; crIndex < crLength; crIndex++) {
-                    ClientRange cr = clients.get(crIndex);
-                    if (cr.startId == startId && cr.endId == endId && cr.client.equals(client)) {
-                        // found the ClientRange to remove, check if it's the last in the list
-                        if (crIndex == crLength - 1) {
-                            if (range.endId == largestEndId) {
-                                // no channels to remove from radio; return success
-                                clients.remove(crIndex);
-                                return true;
-                            } else {
-                                // disable the channels at the end and lower the end id
-                                if (tryAddSingleRange(largestEndId + 1, range.endId, false)) {
-                                    clients.remove(crIndex);
-                                    range.endId = largestEndId;
-                                    return true;
-                                } else {
-                                    return false;
-                                }
-                            }
-                        }
-
-                        // copy the IntRange so that we can remove elements and modify the
-                        // start and end id's in the copy, leaving the original unmodified
-                        // until after the radio update succeeds
-                        IntRange rangeCopy = new IntRange(range, crIndex);
-
-                        if (crIndex == 0) {
-                            // removing the first ClientRange, so we may need to increase
-                            // the start id of the IntRange.
-                            // We know there are at least two ClientRanges in the list,
-                            // so clients.get(1) should always succeed.
-                            int nextStartId = clients.get(1).startId;
-                            if (nextStartId != range.startId) {
-                                startUpdate();
-                                updateStarted = true;
-                                addRange(range.startId, nextStartId - 1, false);
-                                rangeCopy.startId = nextStartId;
-                            }
-                            // init largestEndId
-                            largestEndId = clients.get(1).endId;
-                        }
-
-                        // go through remaining ClientRanges, creating new IntRanges when
-                        // there is a gap in the sequence. After radio update succeeds,
-                        // remove the original IntRange and append newRanges to mRanges.
-                        // Otherwise, leave the original IntRange in mRanges and return false.
-                        ArrayList<IntRange> newRanges = new ArrayList<IntRange>();
-
-                        IntRange currentRange = rangeCopy;
-                        for (int nextIndex = crIndex + 1; nextIndex < crLength; nextIndex++) {
-                            ClientRange nextCr = clients.get(nextIndex);
-                            if (nextCr.startId > largestEndId + 1) {
-                                if (!updateStarted) {
-                                    startUpdate();
-                                    updateStarted = true;
-                                }
-                                addRange(largestEndId + 1, nextCr.startId - 1, false);
-                                currentRange.endId = largestEndId;
-                                newRanges.add(currentRange);
-                                currentRange = new IntRange(nextCr);
-                            } else {
-                                currentRange.clients.add(nextCr);
-                            }
-                            if (nextCr.endId > largestEndId) {
-                                largestEndId = nextCr.endId;
-                            }
-                        }
-
-                        // remove any channels between largestEndId and endId
-                        if (largestEndId < endId) {
-                            if (!updateStarted) {
-                                startUpdate();
-                                updateStarted = true;
-                            }
-                            addRange(largestEndId + 1, endId, false);
-                            currentRange.endId = largestEndId;
-                        }
-                        newRanges.add(currentRange);
-
-                        if (updateStarted && !finishUpdate()) {
-                            return false;   // failed to update radio
-                        }
-
-                        // replace the original IntRange with newRanges
-                        mRanges.remove(i);
-                        mRanges.addAll(i, newRanges);
-                        return true;
-                    } else {
-                        // not the ClientRange to remove; save highest end ID seen so far
-                        if (cr.endId > largestEndId) {
-                            largestEndId = cr.endId;
-                        }
-                    }
-                }
-            }
-        }
-
-        return false;   // not found
-    }
-
-    /**
-     * Perform a complete update operation (enable all ranges). Useful
-     * after a radio reset. Calls {@link #startUpdate}, followed by zero or
-     * more calls to {@link #addRange}, followed by {@link #finishUpdate}.
-     * @return true if successful, false otherwise
-     */
-    public boolean updateRanges() {
-        startUpdate();
-        Iterator<IntRange> iterator = mRanges.iterator();
-        if (iterator.hasNext()) {
-            IntRange range = iterator.next();
-            int start = range.startId;
-            int end = range.endId;
-            // accumulate ranges of [startId, endId]
-            while (iterator.hasNext()) {
-                IntRange nextNode = iterator.next();
-                // [startIdA, endIdA], [endIdA + 1, endIdB] -> [startIdA, endIdB]
-                if (nextNode.startId <= (end + 1)) {
-                    if (nextNode.endId > end) {
-                        end = nextNode.endId;
-                    }
-                } else {
-                    addRange(start, end, true);
-                    start = nextNode.startId;
-                    end = nextNode.endId;
-                }
-            }
-            // add final range
-            addRange(start, end, true);
-        }
-        return finishUpdate();
-    }
-
-    /**
-     * Enable or disable a single range of message identifiers.
-     * @param startId the first id included in the range
-     * @param endId the last id included in the range
-     * @param selected true to enable range, false to disable range
-     * @return true if successful, false otherwise
-     */
-    private boolean tryAddSingleRange(int startId, int endId, boolean selected) {
-        startUpdate();
-        addRange(startId, endId, selected);
-        return finishUpdate();
-    }
-
-    /**
-     * Returns whether the list of ranges is completely empty.
-     * @return true if there are no enabled ranges
-     */
-    public boolean isEmpty() {
-        return mRanges.isEmpty();
-    }
-
-    /**
-     * Called when the list of enabled ranges has changed. This will be
-     * followed by zero or more calls to {@link #addRange} followed by
-     * a call to {@link #finishUpdate}.
-     */
-    protected abstract void startUpdate();
-
-    /**
-     * Called after {@link #startUpdate} to indicate a range of enabled
-     * or disabled values.
-     *
-     * @param startId the first id included in the range
-     * @param endId the last id included in the range
-     * @param selected true to enable range, false to disable range
-     */
-    protected abstract void addRange(int startId, int endId, boolean selected);
-
-    /**
-     * Called to indicate the end of a range update started by the
-     * previous call to {@link #startUpdate}.
-     * @return true if successful, false otherwise
-     */
-    protected abstract boolean finishUpdate();
-}
diff --git a/telephony/java/com/android/internal/telephony/MccTable.java b/telephony/java/com/android/internal/telephony/MccTable.java
deleted file mode 100644
index b6711bc..0000000
--- a/telephony/java/com/android/internal/telephony/MccTable.java
+++ /dev/null
@@ -1,571 +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.internal.telephony;
-
-import android.app.ActivityManagerNative;
-import android.app.AlarmManager;
-import android.app.IActivityManager;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.net.wifi.WifiManager;
-import android.os.RemoteException;
-import android.os.SystemProperties;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Locale;
-import libcore.icu.TimeZones;
-
-/**
- * Mobile Country Code
- *
- * {@hide}
- */
-public final class MccTable
-{
-    static final String LOG_TAG = "MccTable";
-
-    static ArrayList<MccEntry> table;
-
-    static class MccEntry implements Comparable<MccEntry>
-    {
-        int mcc;
-        String iso;
-        int smallestDigitsMnc;
-        String language;
-
-        MccEntry(int mnc, String iso, int smallestDigitsMCC) {
-            this(mnc, iso, smallestDigitsMCC, null);
-        }
-
-        MccEntry(int mnc, String iso, int smallestDigitsMCC, String language) {
-            this.mcc = mnc;
-            this.iso = iso;
-            this.smallestDigitsMnc = smallestDigitsMCC;
-            this.language = language;
-        }
-
-
-        public int compareTo(MccEntry o)
-        {
-            return mcc - o.mcc;
-        }
-    }
-
-    private static MccEntry
-    entryForMcc(int mcc)
-    {
-        int index;
-
-        MccEntry m;
-
-        m = new MccEntry(mcc, null, 0);
-
-        index = Collections.binarySearch(table, m);
-
-        if (index < 0) {
-            return null;
-        } else {
-            return table.get(index);
-        }
-    }
-
-    /**
-     * Returns a default time zone ID for the given MCC.
-     * @param mcc Mobile Country Code
-     * @return default TimeZone ID, or null if not specified
-     */
-    public static String defaultTimeZoneForMcc(int mcc) {
-        MccEntry entry;
-
-        entry = entryForMcc(mcc);
-        if (entry == null || entry.iso == null) {
-            return null;
-        } else {
-            Locale locale;
-            if (entry.language == null) {
-                locale = new Locale(entry.iso);
-            } else {
-                locale = new Locale(entry.language, entry.iso);
-            }
-            String[] tz = TimeZones.forLocale(locale);
-            if (tz.length == 0) return null;
-            return tz[0];
-        }
-    }
-
-    /**
-     * Given a GSM Mobile Country Code, returns
-     * an ISO two-character country code if available.
-     * Returns "" if unavailable.
-     */
-    public static String
-    countryCodeForMcc(int mcc)
-    {
-        MccEntry entry;
-
-        entry = entryForMcc(mcc);
-
-        if (entry == null) {
-            return "";
-        } else {
-            return entry.iso;
-        }
-    }
-
-    /**
-     * Given a GSM Mobile Country Code, returns
-     * an ISO 2-3 character language code if available.
-     * Returns null if unavailable.
-     */
-    public static String defaultLanguageForMcc(int mcc) {
-        MccEntry entry;
-
-        entry = entryForMcc(mcc);
-
-        if (entry == null) {
-            return null;
-        } else {
-            return entry.language;
-        }
-    }
-
-    /**
-     * Given a GSM Mobile Country Code, returns
-     * the smallest number of digits that M if available.
-     * Returns 2 if unavailable.
-     */
-    public static int
-    smallestDigitsMccForMnc(int mcc)
-    {
-        MccEntry entry;
-
-        entry = entryForMcc(mcc);
-
-        if (entry == null) {
-            return 2;
-        } else {
-            return entry.smallestDigitsMnc;
-        }
-    }
-
-    /**
-     * Updates MCC and MNC device configuration information for application retrieving
-     * correct version of resources.  If either MCC or MNC is 0, they will be ignored (not set).
-     * @param context Context to act on.
-     * @param mccmnc truncated imsi with just the MCC and MNC - MNC assumed to be from 4th to end
-     */
-    public static void updateMccMncConfiguration(Context context, String mccmnc) {
-        if (!TextUtils.isEmpty(mccmnc)) {
-            int mcc, mnc;
-
-            try {
-                mcc = Integer.parseInt(mccmnc.substring(0,3));
-                mnc = Integer.parseInt(mccmnc.substring(3));
-            } catch (NumberFormatException e) {
-                Log.e(LOG_TAG, "Error parsing IMSI");
-                return;
-            }
-
-            Log.d(LOG_TAG, "updateMccMncConfiguration: mcc=" + mcc + ", mnc=" + mnc);
-
-            if (mcc != 0) {
-                setTimezoneFromMccIfNeeded(context, mcc);
-                setLocaleFromMccIfNeeded(context, mcc);
-                setWifiCountryCodeFromMcc(context, mcc);
-            }
-            try {
-                Configuration config = ActivityManagerNative.getDefault().getConfiguration();
-                if (mcc != 0) {
-                    config.mcc = mcc;
-                }
-                if (mnc != 0) {
-                    config.mnc = mnc;
-                }
-                ActivityManagerNative.getDefault().updateConfiguration(config);
-            } catch (RemoteException e) {
-                Log.e(LOG_TAG, "Can't update configuration", e);
-            }
-        }
-    }
-
-    /**
-     * Utility code to set the system locale if it's not set already
-     * @param context Context to act on.
-     * @param language Two character language code desired
-     * @param country Two character country code desired
-     *
-     *  {@hide}
-     */
-    public static void setSystemLocale(Context context, String language, String country) {
-        String l = SystemProperties.get("persist.sys.language");
-        String c = SystemProperties.get("persist.sys.country");
-
-        if (null == language) {
-            return; // no match possible
-        }
-        language = language.toLowerCase();
-        if (null == country) {
-            country = "";
-        }
-        country = country.toUpperCase();
-
-        if((null == l || 0 == l.length()) && (null == c || 0 == c.length())) {
-            try {
-                // try to find a good match
-                String[] locales = context.getAssets().getLocales();
-                final int N = locales.length;
-                String bestMatch = null;
-                for(int i = 0; i < N; i++) {
-                    // only match full (lang + country) locales
-                    if (locales[i]!=null && locales[i].length() >= 5 &&
-                            locales[i].substring(0,2).equals(language)) {
-                        if (locales[i].substring(3,5).equals(country)) {
-                            bestMatch = locales[i];
-                            break;
-                        } else if (null == bestMatch) {
-                            bestMatch = locales[i];
-                        }
-                    }
-                }
-                if (null != bestMatch) {
-                    IActivityManager am = ActivityManagerNative.getDefault();
-                    Configuration config = am.getConfiguration();
-                    config.locale = new Locale(bestMatch.substring(0,2),
-                                               bestMatch.substring(3,5));
-                    config.userSetLocale = true;
-                    am.updateConfiguration(config);
-                }
-            } catch (Exception e) {
-                // Intentionally left blank
-            }
-        }
-    }
-
-    /**
-     * If the timezone is not already set, set it based on the MCC of the SIM.
-     * @param context Context to act on.
-     * @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA)
-     */
-    private static void setTimezoneFromMccIfNeeded(Context context, int mcc) {
-        String timezone = SystemProperties.get(ServiceStateTracker.TIMEZONE_PROPERTY);
-        if (timezone == null || timezone.length() == 0) {
-            String zoneId = defaultTimeZoneForMcc(mcc);
-            if (zoneId != null && zoneId.length() > 0) {
-                // Set time zone based on MCC
-                AlarmManager alarm =
-                        (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
-                alarm.setTimeZone(zoneId);
-                Log.d(LOG_TAG, "timezone set to "+zoneId);
-            }
-        }
-    }
-
-    /**
-     * If the locale is not already set, set it based on the MCC of the SIM.
-     * @param context Context to act on.
-     * @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA)
-     */
-    private static void setLocaleFromMccIfNeeded(Context context, int mcc) {
-        if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) {
-            // Avoid system locale is set from MCC table if CDMALTEPhone is used.
-            // The locale will be picked up based on EFpl/EFli once CSIM records are loaded.
-            return;
-        }
-        String language = MccTable.defaultLanguageForMcc(mcc);
-        String country = MccTable.countryCodeForMcc(mcc);
-
-        Log.d(LOG_TAG, "locale set to "+language+"_"+country);
-        setSystemLocale(context, language, country);
-    }
-
-    /**
-     * If the number of allowed wifi channels has not been set, set it based on
-     * the MCC of the SIM.
-     * @param context Context to act on.
-     * @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA)
-     */
-    private static void setWifiCountryCodeFromMcc(Context context, int mcc) {
-        String country = MccTable.countryCodeForMcc(mcc);
-        if (!country.isEmpty()) {
-            Log.d(LOG_TAG, "WIFI_COUNTRY_CODE set to " + country);
-            WifiManager wM = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
-            //persist
-            wM.setCountryCode(country, true);
-        }
-    }
-
-    static {
-        table = new ArrayList<MccEntry>(240);
-
-
-        /*
-         * The table below is built from two resources:
-         *
-         * 1) ITU "Mobile Network Code (MNC) for the international
-         *   identification plan for mobile terminals and mobile users"
-         *   which is available as an annex to the ITU operational bulletin
-         *   available here: http://www.itu.int/itu-t/bulletin/annex.html
-         *
-         * 2) The ISO 3166 country codes list, available here:
-         *    http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/index.html
-         *
-         * This table has not been verified.
-         *
-         */
-
-		table.add(new MccEntry(202,"gr",2));	//Greece
-		table.add(new MccEntry(204,"nl",2,"nl"));	//Netherlands (Kingdom of the)
-		table.add(new MccEntry(206,"be",2));	//Belgium
-		table.add(new MccEntry(208,"fr",2,"fr"));	//France
-		table.add(new MccEntry(212,"mc",2));	//Monaco (Principality of)
-		table.add(new MccEntry(213,"ad",2));	//Andorra (Principality of)
-		table.add(new MccEntry(214,"es",2,"es"));	//Spain
-		table.add(new MccEntry(216,"hu",2));	//Hungary (Republic of)
-		table.add(new MccEntry(218,"ba",2));	//Bosnia and Herzegovina
-		table.add(new MccEntry(219,"hr",2));	//Croatia (Republic of)
-		table.add(new MccEntry(220,"rs",2));	//Serbia and Montenegro
-		table.add(new MccEntry(222,"it",2,"it"));	//Italy
-		table.add(new MccEntry(225,"va",2,"it"));	//Vatican City State
-		table.add(new MccEntry(226,"ro",2));	//Romania
-		table.add(new MccEntry(228,"ch",2,"de"));	//Switzerland (Confederation of)
-		table.add(new MccEntry(230,"cz",2,"cs"));	//Czech Republic
-		table.add(new MccEntry(231,"sk",2));	//Slovak Republic
-		table.add(new MccEntry(232,"at",2,"de"));	//Austria
-		table.add(new MccEntry(234,"gb",2,"en"));	//United Kingdom of Great Britain and Northern Ireland
-		table.add(new MccEntry(235,"gb",2,"en"));	//United Kingdom of Great Britain and Northern Ireland
-		table.add(new MccEntry(238,"dk",2));	//Denmark
-		table.add(new MccEntry(240,"se",2));	//Sweden
-		table.add(new MccEntry(242,"no",2));	//Norway
-		table.add(new MccEntry(244,"fi",2));	//Finland
-		table.add(new MccEntry(246,"lt",2));	//Lithuania (Republic of)
-		table.add(new MccEntry(247,"lv",2));	//Latvia (Republic of)
-		table.add(new MccEntry(248,"ee",2));	//Estonia (Republic of)
-		table.add(new MccEntry(250,"ru",2));	//Russian Federation
-		table.add(new MccEntry(255,"ua",2));	//Ukraine
-		table.add(new MccEntry(257,"by",2));	//Belarus (Republic of)
-		table.add(new MccEntry(259,"md",2));	//Moldova (Republic of)
-		table.add(new MccEntry(260,"pl",2));	//Poland (Republic of)
-		table.add(new MccEntry(262,"de",2,"de"));	//Germany (Federal Republic of)
-		table.add(new MccEntry(266,"gi",2));	//Gibraltar
-		table.add(new MccEntry(268,"pt",2));	//Portugal
-		table.add(new MccEntry(270,"lu",2));	//Luxembourg
-		table.add(new MccEntry(272,"ie",2,"en"));	//Ireland
-		table.add(new MccEntry(274,"is",2));	//Iceland
-		table.add(new MccEntry(276,"al",2));	//Albania (Republic of)
-		table.add(new MccEntry(278,"mt",2));	//Malta
-		table.add(new MccEntry(280,"cy",2));	//Cyprus (Republic of)
-		table.add(new MccEntry(282,"ge",2));	//Georgia
-		table.add(new MccEntry(283,"am",2));	//Armenia (Republic of)
-		table.add(new MccEntry(284,"bg",2));	//Bulgaria (Republic of)
-		table.add(new MccEntry(286,"tr",2));	//Turkey
-		table.add(new MccEntry(288,"fo",2));	//Faroe Islands
-                table.add(new MccEntry(289,"ge",2));    //Abkhazia (Georgia)
-		table.add(new MccEntry(290,"gl",2));	//Greenland (Denmark)
-		table.add(new MccEntry(292,"sm",2));	//San Marino (Republic of)
-		table.add(new MccEntry(293,"si",2));	//Slovenia (Republic of)
-                table.add(new MccEntry(294,"mk",2));   //The Former Yugoslav Republic of Macedonia
-		table.add(new MccEntry(295,"li",2));	//Liechtenstein (Principality of)
-                table.add(new MccEntry(297,"me",2));    //Montenegro (Republic of)
-		table.add(new MccEntry(302,"ca",3,""));	//Canada
-		table.add(new MccEntry(308,"pm",2));	//Saint Pierre and Miquelon (Collectivit territoriale de la Rpublique franaise)
-		table.add(new MccEntry(310,"us",3,"en"));	//United States of America
-		table.add(new MccEntry(311,"us",3,"en"));	//United States of America
-		table.add(new MccEntry(312,"us",3,"en"));	//United States of America
-		table.add(new MccEntry(313,"us",3,"en"));	//United States of America
-		table.add(new MccEntry(314,"us",3,"en"));	//United States of America
-		table.add(new MccEntry(315,"us",3,"en"));	//United States of America
-		table.add(new MccEntry(316,"us",3,"en"));	//United States of America
-		table.add(new MccEntry(330,"pr",2));	//Puerto Rico
-		table.add(new MccEntry(332,"vi",2));	//United States Virgin Islands
-		table.add(new MccEntry(334,"mx",3));	//Mexico
-		table.add(new MccEntry(338,"jm",3));	//Jamaica
-		table.add(new MccEntry(340,"gp",2));	//Guadeloupe (French Department of)
-		table.add(new MccEntry(342,"bb",3));	//Barbados
-		table.add(new MccEntry(344,"ag",3));	//Antigua and Barbuda
-		table.add(new MccEntry(346,"ky",3));	//Cayman Islands
-		table.add(new MccEntry(348,"vg",3));	//British Virgin Islands
-		table.add(new MccEntry(350,"bm",2));	//Bermuda
-		table.add(new MccEntry(352,"gd",2));	//Grenada
-		table.add(new MccEntry(354,"ms",2));	//Montserrat
-		table.add(new MccEntry(356,"kn",2));	//Saint Kitts and Nevis
-		table.add(new MccEntry(358,"lc",2));	//Saint Lucia
-		table.add(new MccEntry(360,"vc",2));	//Saint Vincent and the Grenadines
-		table.add(new MccEntry(362,"ai",2));	//Netherlands Antilles
-		table.add(new MccEntry(363,"aw",2));	//Aruba
-		table.add(new MccEntry(364,"bs",2));	//Bahamas (Commonwealth of the)
-		table.add(new MccEntry(365,"ai",3));	//Anguilla
-		table.add(new MccEntry(366,"dm",2));	//Dominica (Commonwealth of)
-		table.add(new MccEntry(368,"cu",2));	//Cuba
-		table.add(new MccEntry(370,"do",2));	//Dominican Republic
-		table.add(new MccEntry(372,"ht",2));	//Haiti (Republic of)
-		table.add(new MccEntry(374,"tt",2));	//Trinidad and Tobago
-		table.add(new MccEntry(376,"tc",2));	//Turks and Caicos Islands
-		table.add(new MccEntry(400,"az",2));	//Azerbaijani Republic
-		table.add(new MccEntry(401,"kz",2));	//Kazakhstan (Republic of)
-		table.add(new MccEntry(402,"bt",2));	//Bhutan (Kingdom of)
-		table.add(new MccEntry(404,"in",2));	//India (Republic of)
-		table.add(new MccEntry(405,"in",2));	//India (Republic of)
-		table.add(new MccEntry(410,"pk",2));	//Pakistan (Islamic Republic of)
-		table.add(new MccEntry(412,"af",2));	//Afghanistan
-		table.add(new MccEntry(413,"lk",2));	//Sri Lanka (Democratic Socialist Republic of)
-		table.add(new MccEntry(414,"mm",2));	//Myanmar (Union of)
-		table.add(new MccEntry(415,"lb",2));	//Lebanon
-		table.add(new MccEntry(416,"jo",2));	//Jordan (Hashemite Kingdom of)
-		table.add(new MccEntry(417,"sy",2));	//Syrian Arab Republic
-		table.add(new MccEntry(418,"iq",2));	//Iraq (Republic of)
-		table.add(new MccEntry(419,"kw",2));	//Kuwait (State of)
-		table.add(new MccEntry(420,"sa",2));	//Saudi Arabia (Kingdom of)
-		table.add(new MccEntry(421,"ye",2));	//Yemen (Republic of)
-		table.add(new MccEntry(422,"om",2));	//Oman (Sultanate of)
-                table.add(new MccEntry(423,"ps",2));    //Palestine
-		table.add(new MccEntry(424,"ae",2));	//United Arab Emirates
-		table.add(new MccEntry(425,"il",2));	//Israel (State of)
-		table.add(new MccEntry(426,"bh",2));	//Bahrain (Kingdom of)
-		table.add(new MccEntry(427,"qa",2));	//Qatar (State of)
-		table.add(new MccEntry(428,"mn",2));	//Mongolia
-		table.add(new MccEntry(429,"np",2));	//Nepal
-		table.add(new MccEntry(430,"ae",2));	//United Arab Emirates
-		table.add(new MccEntry(431,"ae",2));	//United Arab Emirates
-		table.add(new MccEntry(432,"ir",2));	//Iran (Islamic Republic of)
-		table.add(new MccEntry(434,"uz",2));	//Uzbekistan (Republic of)
-		table.add(new MccEntry(436,"tj",2));	//Tajikistan (Republic of)
-		table.add(new MccEntry(437,"kg",2));	//Kyrgyz Republic
-		table.add(new MccEntry(438,"tm",2));	//Turkmenistan
-		table.add(new MccEntry(440,"jp",2,"ja"));	//Japan
-		table.add(new MccEntry(441,"jp",2,"ja"));	//Japan
-		table.add(new MccEntry(450,"kr",2,"ko"));	//Korea (Republic of)
-		table.add(new MccEntry(452,"vn",2));	//Viet Nam (Socialist Republic of)
-		table.add(new MccEntry(454,"hk",2));	//"Hong Kong, China"
-		table.add(new MccEntry(455,"mo",2));	//"Macao, China"
-		table.add(new MccEntry(456,"kh",2));	//Cambodia (Kingdom of)
-		table.add(new MccEntry(457,"la",2));	//Lao People's Democratic Republic
-		table.add(new MccEntry(460,"cn",2,"zh"));	//China (People's Republic of)
-		table.add(new MccEntry(461,"cn",2,"zh"));	//China (People's Republic of)
-		table.add(new MccEntry(466,"tw",2));	//"Taiwan, China"
-		table.add(new MccEntry(467,"kp",2));	//Democratic People's Republic of Korea
-		table.add(new MccEntry(470,"bd",2));	//Bangladesh (People's Republic of)
-		table.add(new MccEntry(472,"mv",2));	//Maldives (Republic of)
-		table.add(new MccEntry(502,"my",2));	//Malaysia
-		table.add(new MccEntry(505,"au",2,"en"));	//Australia
-		table.add(new MccEntry(510,"id",2));	//Indonesia (Republic of)
-		table.add(new MccEntry(514,"tl",2));	//Democratic Republic of Timor-Leste
-		table.add(new MccEntry(515,"ph",2));	//Philippines (Republic of the)
-		table.add(new MccEntry(520,"th",2));	//Thailand
-		table.add(new MccEntry(525,"sg",2,"en"));	//Singapore (Republic of)
-		table.add(new MccEntry(528,"bn",2));	//Brunei Darussalam
-		table.add(new MccEntry(530,"nz",2, "en"));	//New Zealand
-		table.add(new MccEntry(534,"mp",2));	//Northern Mariana Islands (Commonwealth of the)
-		table.add(new MccEntry(535,"gu",2));	//Guam
-		table.add(new MccEntry(536,"nr",2));	//Nauru (Republic of)
-		table.add(new MccEntry(537,"pg",2));	//Papua New Guinea
-		table.add(new MccEntry(539,"to",2));	//Tonga (Kingdom of)
-		table.add(new MccEntry(540,"sb",2));	//Solomon Islands
-		table.add(new MccEntry(541,"vu",2));	//Vanuatu (Republic of)
-		table.add(new MccEntry(542,"fj",2));	//Fiji (Republic of)
-		table.add(new MccEntry(543,"wf",2));	//Wallis and Futuna (Territoire franais d'outre-mer)
-		table.add(new MccEntry(544,"as",2));	//American Samoa
-		table.add(new MccEntry(545,"ki",2));	//Kiribati (Republic of)
-		table.add(new MccEntry(546,"nc",2));	//New Caledonia (Territoire franais d'outre-mer)
-		table.add(new MccEntry(547,"pf",2));	//French Polynesia (Territoire franais d'outre-mer)
-		table.add(new MccEntry(548,"ck",2));	//Cook Islands
-		table.add(new MccEntry(549,"ws",2));	//Samoa (Independent State of)
-		table.add(new MccEntry(550,"fm",2));	//Micronesia (Federated States of)
-		table.add(new MccEntry(551,"mh",2));	//Marshall Islands (Republic of the)
-		table.add(new MccEntry(552,"pw",2));	//Palau (Republic of)
-		table.add(new MccEntry(602,"eg",2));	//Egypt (Arab Republic of)
-		table.add(new MccEntry(603,"dz",2));	//Algeria (People's Democratic Republic of)
-		table.add(new MccEntry(604,"ma",2));	//Morocco (Kingdom of)
-		table.add(new MccEntry(605,"tn",2));	//Tunisia
-		table.add(new MccEntry(606,"ly",2));	//Libya (Socialist People's Libyan Arab Jamahiriya)
-		table.add(new MccEntry(607,"gm",2));	//Gambia (Republic of the)
-		table.add(new MccEntry(608,"sn",2));	//Senegal (Republic of)
-		table.add(new MccEntry(609,"mr",2));	//Mauritania (Islamic Republic of)
-		table.add(new MccEntry(610,"ml",2));	//Mali (Republic of)
-		table.add(new MccEntry(611,"gn",2));	//Guinea (Republic of)
-		table.add(new MccEntry(612,"ci",2));	//Cte d'Ivoire (Republic of)
-		table.add(new MccEntry(613,"bf",2));	//Burkina Faso
-		table.add(new MccEntry(614,"ne",2));	//Niger (Republic of the)
-		table.add(new MccEntry(615,"tg",2));	//Togolese Republic
-		table.add(new MccEntry(616,"bj",2));	//Benin (Republic of)
-		table.add(new MccEntry(617,"mu",2));	//Mauritius (Republic of)
-		table.add(new MccEntry(618,"lr",2));	//Liberia (Republic of)
-		table.add(new MccEntry(619,"sl",2));	//Sierra Leone
-		table.add(new MccEntry(620,"gh",2));	//Ghana
-		table.add(new MccEntry(621,"ng",2));	//Nigeria (Federal Republic of)
-		table.add(new MccEntry(622,"td",2));	//Chad (Republic of)
-		table.add(new MccEntry(623,"cf",2));	//Central African Republic
-		table.add(new MccEntry(624,"cm",2));	//Cameroon (Republic of)
-		table.add(new MccEntry(625,"cv",2));	//Cape Verde (Republic of)
-		table.add(new MccEntry(626,"st",2));	//Sao Tome and Principe (Democratic Republic of)
-		table.add(new MccEntry(627,"gq",2));	//Equatorial Guinea (Republic of)
-		table.add(new MccEntry(628,"ga",2));	//Gabonese Republic
-		table.add(new MccEntry(629,"cg",2));	//Congo (Republic of the)
-		table.add(new MccEntry(630,"cg",2));	//Democratic Republic of the Congo
-		table.add(new MccEntry(631,"ao",2));	//Angola (Republic of)
-		table.add(new MccEntry(632,"gw",2));	//Guinea-Bissau (Republic of)
-		table.add(new MccEntry(633,"sc",2));	//Seychelles (Republic of)
-		table.add(new MccEntry(634,"sd",2));	//Sudan (Republic of the)
-		table.add(new MccEntry(635,"rw",2));	//Rwanda (Republic of)
-		table.add(new MccEntry(636,"et",2));	//Ethiopia (Federal Democratic Republic of)
-		table.add(new MccEntry(637,"so",2));	//Somali Democratic Republic
-		table.add(new MccEntry(638,"dj",2));	//Djibouti (Republic of)
-		table.add(new MccEntry(639,"ke",2));	//Kenya (Republic of)
-		table.add(new MccEntry(640,"tz",2));	//Tanzania (United Republic of)
-		table.add(new MccEntry(641,"ug",2));	//Uganda (Republic of)
-		table.add(new MccEntry(642,"bi",2));	//Burundi (Republic of)
-		table.add(new MccEntry(643,"mz",2));	//Mozambique (Republic of)
-		table.add(new MccEntry(645,"zm",2));	//Zambia (Republic of)
-		table.add(new MccEntry(646,"mg",2));	//Madagascar (Republic of)
-		table.add(new MccEntry(647,"re",2));	//Reunion (French Department of)
-		table.add(new MccEntry(648,"zw",2));	//Zimbabwe (Republic of)
-		table.add(new MccEntry(649,"na",2));	//Namibia (Republic of)
-		table.add(new MccEntry(650,"mw",2));	//Malawi
-		table.add(new MccEntry(651,"ls",2));	//Lesotho (Kingdom of)
-		table.add(new MccEntry(652,"bw",2));	//Botswana (Republic of)
-		table.add(new MccEntry(653,"sz",2));	//Swaziland (Kingdom of)
-		table.add(new MccEntry(654,"km",2));	//Comoros (Union of the)
-		table.add(new MccEntry(655,"za",2,"en"));	//South Africa (Republic of)
-		table.add(new MccEntry(657,"er",2));	//Eritrea
-		table.add(new MccEntry(702,"bz",2));	//Belize
-		table.add(new MccEntry(704,"gt",2));	//Guatemala (Republic of)
-		table.add(new MccEntry(706,"sv",2));	//El Salvador (Republic of)
-		table.add(new MccEntry(708,"hn",3));	//Honduras (Republic of)
-		table.add(new MccEntry(710,"ni",2));	//Nicaragua
-		table.add(new MccEntry(712,"cr",2));	//Costa Rica
-		table.add(new MccEntry(714,"pa",2));	//Panama (Republic of)
-		table.add(new MccEntry(716,"pe",2));	//Peru
-		table.add(new MccEntry(722,"ar",3));	//Argentine Republic
-		table.add(new MccEntry(724,"br",2));	//Brazil (Federative Republic of)
-		table.add(new MccEntry(730,"cl",2));	//Chile
-		table.add(new MccEntry(732,"co",3));	//Colombia (Republic of)
-		table.add(new MccEntry(734,"ve",2));	//Venezuela (Bolivarian Republic of)
-		table.add(new MccEntry(736,"bo",2));	//Bolivia (Republic of)
-		table.add(new MccEntry(738,"gy",2));	//Guyana
-		table.add(new MccEntry(740,"ec",2));	//Ecuador
-		table.add(new MccEntry(742,"gf",2));	//French Guiana (French Department of)
-		table.add(new MccEntry(744,"py",2));	//Paraguay (Republic of)
-		table.add(new MccEntry(746,"sr",2));	//Suriname (Republic of)
-		table.add(new MccEntry(748,"uy",2));	//Uruguay (Eastern Republic of)
-		table.add(new MccEntry(750,"fk",2));	//Falkland Islands (Malvinas)
-        //table.add(new MccEntry(901,"",2));	//"International Mobile, shared code"
-
-        Collections.sort(table);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/MmiCode.java b/telephony/java/com/android/internal/telephony/MmiCode.java
deleted file mode 100644
index c71ff77..0000000
--- a/telephony/java/com/android/internal/telephony/MmiCode.java
+++ /dev/null
@@ -1,62 +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.internal.telephony;
-
-/**
- * {@hide}
- */
-public interface MmiCode
-{
-	/**
-	 * {@hide}
-	 */
-    public enum State {
-        PENDING,
-        CANCELLED,
-        COMPLETE,
-        FAILED
-    }
-
-
-    /**
-     * @return Current state of MmiCode request
-     */
-    public State getState();
-
-    /**
-     * @return Localized message for UI display, valid only in COMPLETE
-     * or FAILED states. null otherwise
-     */
-
-    public CharSequence getMessage();
-
-    /**
-     * Cancels pending MMI request.
-     * State becomes CANCELLED unless already COMPLETE or FAILED
-     */
-    public void cancel();
-
-    /**
-     * @return true if the network response is a REQUEST for more user input.
-     */
-    public boolean isUssdRequest();
-
-    /**
-     * @return true if an outstanding request can be canceled.
-     */
-    public boolean isCancelable();
-}
diff --git a/telephony/java/com/android/internal/telephony/OperatorInfo.java b/telephony/java/com/android/internal/telephony/OperatorInfo.java
deleted file mode 100644
index 1999cb3..0000000
--- a/telephony/java/com/android/internal/telephony/OperatorInfo.java
+++ /dev/null
@@ -1,149 +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.internal.telephony;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * {@hide}
- */
-public class OperatorInfo implements Parcelable {
-    public enum State {
-        UNKNOWN,
-        AVAILABLE,
-        CURRENT,
-        FORBIDDEN;
-    }
-
-    private String operatorAlphaLong;
-    private String operatorAlphaShort;
-    private String operatorNumeric;
-
-    private State state = State.UNKNOWN;
-
-
-    public String
-    getOperatorAlphaLong() {
-        return operatorAlphaLong;
-    }
-
-    public String
-    getOperatorAlphaShort() {
-        return operatorAlphaShort;
-    }
-
-    public String
-    getOperatorNumeric() {
-        return operatorNumeric;
-    }
-
-    public State
-    getState() {
-        return state;
-    }
-
-    OperatorInfo(String operatorAlphaLong,
-                String operatorAlphaShort,
-                String operatorNumeric,
-                State state) {
-
-        this.operatorAlphaLong = operatorAlphaLong;
-        this.operatorAlphaShort = operatorAlphaShort;
-        this.operatorNumeric = operatorNumeric;
-
-        this.state = state;
-    }
-
-
-    public OperatorInfo(String operatorAlphaLong,
-                String operatorAlphaShort,
-                String operatorNumeric,
-                String stateString) {
-        this (operatorAlphaLong, operatorAlphaShort,
-                operatorNumeric, rilStateToState(stateString));
-    }
-
-    /**
-     * See state strings defined in ril.h RIL_REQUEST_QUERY_AVAILABLE_NETWORKS
-     */
-    private static State rilStateToState(String s) {
-        if (s.equals("unknown")) {
-            return State.UNKNOWN;
-        } else if (s.equals("available")) {
-            return State.AVAILABLE;
-        } else if (s.equals("current")) {
-            return State.CURRENT;
-        } else if (s.equals("forbidden")) {
-            return State.FORBIDDEN;
-        } else {
-            throw new RuntimeException(
-                "RIL impl error: Invalid network state '" + s + "'");
-        }
-    }
-
-
-    public String toString() {
-        return "OperatorInfo " + operatorAlphaLong
-                + "/" + operatorAlphaShort
-                + "/" + operatorNumeric
-                + "/" + state;
-    }
-
-    /**
-     * Parcelable interface implemented below.
-     * This is a simple effort to make OperatorInfo parcelable rather than
-     * trying to make the conventional containing object (AsyncResult),
-     * implement parcelable.  This functionality is needed for the
-     * NetworkQueryService to fix 1128695.
-     */
-
-    public int describeContents() {
-        return 0;
-    }
-
-    /**
-     * Implement the Parcelable interface.
-     * Method to serialize a OperatorInfo object.
-     */
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(operatorAlphaLong);
-        dest.writeString(operatorAlphaShort);
-        dest.writeString(operatorNumeric);
-        dest.writeSerializable(state);
-    }
-
-    /**
-     * Implement the Parcelable interface
-     * Method to deserialize a OperatorInfo object, or an array thereof.
-     */
-    public static final Creator<OperatorInfo> CREATOR =
-        new Creator<OperatorInfo>() {
-            public OperatorInfo createFromParcel(Parcel in) {
-                OperatorInfo opInfo = new OperatorInfo(
-                        in.readString(), /*operatorAlphaLong*/
-                        in.readString(), /*operatorAlphaShort*/
-                        in.readString(), /*operatorNumeric*/
-                        (State) in.readSerializable()); /*state*/
-                return opInfo;
-            }
-
-            public OperatorInfo[] newArray(int size) {
-                return new OperatorInfo[size];
-            }
-        };
-}
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
deleted file mode 100644
index d41ce4d..0000000
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ /dev/null
@@ -1,1786 +0,0 @@
-/*
- * 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.internal.telephony;
-
-import android.content.Context;
-import android.net.LinkCapabilities;
-import android.net.LinkProperties;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.telephony.CellLocation;
-import android.telephony.PhoneStateListener;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-
-import com.android.internal.telephony.DataConnection;
-import com.android.internal.telephony.gsm.UsimServiceTable;
-import com.android.internal.telephony.ims.IsimRecords;
-import com.android.internal.telephony.test.SimulatedRadioControl;
-
-import java.util.List;
-
-/**
- * Internal interface used to control the phone; SDK developers cannot
- * obtain this interface.
- *
- * {@hide}
- *
- */
-public interface Phone {
-
-    /** used to enable additional debug messages */
-    static final boolean DEBUG_PHONE = true;
-
-
-    /**
-     * The phone state. One of the following:<p>
-     * <ul>
-     * <li>IDLE = no phone activity</li>
-     * <li>RINGING = a phone call is ringing or call waiting.
-     *  In the latter case, another call is active as well</li>
-     * <li>OFFHOOK = The phone is off hook. At least one call
-     * exists that is dialing, active or holding and no calls are
-     * ringing or waiting.</li>
-     * </ul>
-     */
-    enum State {
-        IDLE, RINGING, OFFHOOK;
-    };
-
-    /**
-     * The state of a data connection.
-     * <ul>
-     * <li>CONNECTED = IP traffic should be available</li>
-     * <li>CONNECTING = Currently setting up data connection</li>
-     * <li>DISCONNECTED = IP not available</li>
-     * <li>SUSPENDED = connection is created but IP traffic is
-     *                 temperately not available. i.e. voice call is in place
-     *                 in 2G network</li>
-     * </ul>
-     */
-    enum DataState {
-        CONNECTED, CONNECTING, DISCONNECTED, SUSPENDED;
-    };
-
-    public enum DataActivityState {
-        /**
-         * The state of a data activity.
-         * <ul>
-         * <li>NONE = No traffic</li>
-         * <li>DATAIN = Receiving IP ppp traffic</li>
-         * <li>DATAOUT = Sending IP ppp traffic</li>
-         * <li>DATAINANDOUT = Both receiving and sending IP ppp traffic</li>
-         * <li>DORMANT = The data connection is still active,
-                                     but physical link is down</li>
-         * </ul>
-         */
-        NONE, DATAIN, DATAOUT, DATAINANDOUT, DORMANT;
-    };
-
-    enum SuppService {
-      UNKNOWN, SWITCH, SEPARATE, TRANSFER, CONFERENCE, REJECT, HANGUP;
-    };
-
-    static final String STATE_KEY = "state";
-    static final String PHONE_NAME_KEY = "phoneName";
-    static final String FAILURE_REASON_KEY = "reason";
-    static final String STATE_CHANGE_REASON_KEY = "reason";
-    static final String DATA_APN_TYPE_KEY = "apnType";
-    static final String DATA_APN_KEY = "apn";
-    static final String DATA_LINK_PROPERTIES_KEY = "linkProperties";
-    static final String DATA_LINK_CAPABILITIES_KEY = "linkCapabilities";
-
-    static final String DATA_IFACE_NAME_KEY = "iface";
-    static final String NETWORK_UNAVAILABLE_KEY = "networkUnvailable";
-    static final String DATA_NETWORK_ROAMING_KEY = "networkRoaming";
-    static final String PHONE_IN_ECM_STATE = "phoneinECMState";
-
-    /**
-     * APN types for data connections.  These are usage categories for an APN
-     * entry.  One APN entry may support multiple APN types, eg, a single APN
-     * may service regular internet traffic ("default") as well as MMS-specific
-     * connections.<br/>
-     * APN_TYPE_ALL is a special type to indicate that this APN entry can
-     * service all data connections.
-     */
-    static final String APN_TYPE_ALL = "*";
-    /** APN type for default data traffic */
-    static final String APN_TYPE_DEFAULT = "default";
-    /** APN type for MMS traffic */
-    static final String APN_TYPE_MMS = "mms";
-    /** APN type for SUPL assisted GPS */
-    static final String APN_TYPE_SUPL = "supl";
-    /** APN type for DUN traffic */
-    static final String APN_TYPE_DUN = "dun";
-    /** APN type for HiPri traffic */
-    static final String APN_TYPE_HIPRI = "hipri";
-    /** APN type for FOTA */
-    static final String APN_TYPE_FOTA = "fota";
-    /** APN type for IMS */
-    static final String APN_TYPE_IMS = "ims";
-    /** APN type for CBS */
-    static final String APN_TYPE_CBS = "cbs";
-
-    // "Features" accessible through the connectivity manager
-    static final String FEATURE_ENABLE_MMS = "enableMMS";
-    static final String FEATURE_ENABLE_SUPL = "enableSUPL";
-    static final String FEATURE_ENABLE_DUN = "enableDUN";
-    static final String FEATURE_ENABLE_HIPRI = "enableHIPRI";
-    static final String FEATURE_ENABLE_DUN_ALWAYS = "enableDUNAlways";
-    static final String FEATURE_ENABLE_FOTA = "enableFOTA";
-    static final String FEATURE_ENABLE_IMS = "enableIMS";
-    static final String FEATURE_ENABLE_CBS = "enableCBS";
-
-    /**
-     * Return codes for <code>enableApnType()</code>
-     */
-    static final int APN_ALREADY_ACTIVE     = 0;
-    static final int APN_REQUEST_STARTED    = 1;
-    static final int APN_TYPE_NOT_AVAILABLE = 2;
-    static final int APN_REQUEST_FAILED     = 3;
-    static final int APN_ALREADY_INACTIVE   = 4;
-
-
-    /**
-     * Optional reasons for disconnect and connect
-     */
-    static final String REASON_ROAMING_ON = "roamingOn";
-    static final String REASON_ROAMING_OFF = "roamingOff";
-    static final String REASON_DATA_DISABLED = "dataDisabled";
-    static final String REASON_DATA_ENABLED = "dataEnabled";
-    static final String REASON_DATA_ATTACHED = "dataAttached";
-    static final String REASON_DATA_DETACHED = "dataDetached";
-    static final String REASON_CDMA_DATA_ATTACHED = "cdmaDataAttached";
-    static final String REASON_CDMA_DATA_DETACHED = "cdmaDataDetached";
-    static final String REASON_APN_CHANGED = "apnChanged";
-    static final String REASON_APN_SWITCHED = "apnSwitched";
-    static final String REASON_APN_FAILED = "apnFailed";
-    static final String REASON_RESTORE_DEFAULT_APN = "restoreDefaultApn";
-    static final String REASON_RADIO_TURNED_OFF = "radioTurnedOff";
-    static final String REASON_PDP_RESET = "pdpReset";
-    static final String REASON_VOICE_CALL_ENDED = "2GVoiceCallEnded";
-    static final String REASON_VOICE_CALL_STARTED = "2GVoiceCallStarted";
-    static final String REASON_PS_RESTRICT_ENABLED = "psRestrictEnabled";
-    static final String REASON_PS_RESTRICT_DISABLED = "psRestrictDisabled";
-    static final String REASON_SIM_LOADED = "simLoaded";
-    static final String REASON_NW_TYPE_CHANGED = "nwTypeChanged";
-    static final String REASON_DATA_DEPENDENCY_MET = "dependencyMet";
-    static final String REASON_DATA_DEPENDENCY_UNMET = "dependencyUnmet";
-    static final String REASON_LINK_PROPERTIES_CHANGED = "linkPropertiesChanged";
-
-    // Used for band mode selection methods
-    static final int BM_UNSPECIFIED = 0; // selected by baseband automatically
-    static final int BM_EURO_BAND   = 1; // GSM-900 / DCS-1800 / WCDMA-IMT-2000
-    static final int BM_US_BAND     = 2; // GSM-850 / PCS-1900 / WCDMA-850 / WCDMA-PCS-1900
-    static final int BM_JPN_BAND    = 3; // WCDMA-800 / WCDMA-IMT-2000
-    static final int BM_AUS_BAND    = 4; // GSM-900 / DCS-1800 / WCDMA-850 / WCDMA-IMT-2000
-    static final int BM_AUS2_BAND   = 5; // GSM-900 / DCS-1800 / WCDMA-850
-    static final int BM_BOUNDARY    = 6; // upper band boundary
-
-    // Radio Type
-    static final int PHONE_TYPE_NONE = RILConstants.NO_PHONE;
-    static final int PHONE_TYPE_GSM = RILConstants.GSM_PHONE;
-    static final int PHONE_TYPE_CDMA = RILConstants.CDMA_PHONE;
-    static final int PHONE_TYPE_SIP = RILConstants.SIP_PHONE;
-
-    // Modes for LTE_ON_CDMA
-    static final int LTE_ON_CDMA_UNKNOWN = RILConstants.LTE_ON_CDMA_UNKNOWN;
-    static final int LTE_ON_CDMA_FALSE = RILConstants.LTE_ON_CDMA_FALSE;
-    static final int LTE_ON_CDMA_TRUE = RILConstants.LTE_ON_CDMA_TRUE;
-
-    // Used for preferred network type
-    // Note NT_* substitute RILConstants.NETWORK_MODE_* above the Phone
-    int NT_MODE_WCDMA_PREF   = RILConstants.NETWORK_MODE_WCDMA_PREF;
-    int NT_MODE_GSM_ONLY     = RILConstants.NETWORK_MODE_GSM_ONLY;
-    int NT_MODE_WCDMA_ONLY   = RILConstants.NETWORK_MODE_WCDMA_ONLY;
-    int NT_MODE_GSM_UMTS     = RILConstants.NETWORK_MODE_GSM_UMTS;
-
-    int NT_MODE_CDMA         = RILConstants.NETWORK_MODE_CDMA;
-
-    int NT_MODE_CDMA_NO_EVDO = RILConstants.NETWORK_MODE_CDMA_NO_EVDO;
-    int NT_MODE_EVDO_NO_CDMA = RILConstants.NETWORK_MODE_EVDO_NO_CDMA;
-    int NT_MODE_GLOBAL       = RILConstants.NETWORK_MODE_GLOBAL;
-
-    int NT_MODE_LTE_ONLY     = RILConstants.NETWORK_MODE_LTE_ONLY;
-    int PREFERRED_NT_MODE    = RILConstants.PREFERRED_NETWORK_MODE;
-
-
-    // Used for CDMA roaming mode
-    static final int CDMA_RM_HOME        = 0;  // Home Networks only, as defined in PRL
-    static final int CDMA_RM_AFFILIATED  = 1;  // Roaming an Affiliated networks, as defined in PRL
-    static final int CDMA_RM_ANY         = 2;  // Roaming on Any Network, as defined in PRL
-
-    // Used for CDMA subscription mode
-    static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0; // RUIM/SIM (default)
-    static final int CDMA_SUBSCRIPTION_NV       = 1; // NV -> non-volatile memory
-
-    static final int PREFERRED_CDMA_SUBSCRIPTION = CDMA_SUBSCRIPTION_NV;
-
-    static final int TTY_MODE_OFF = 0;
-    static final int TTY_MODE_FULL = 1;
-    static final int TTY_MODE_HCO = 2;
-    static final int TTY_MODE_VCO = 3;
-
-     /**
-     * CDMA OTA PROVISION STATUS, the same as RIL_CDMA_OTA_Status in ril.h
-     */
-
-    public static final int CDMA_OTA_PROVISION_STATUS_SPL_UNLOCKED = 0;
-    public static final int CDMA_OTA_PROVISION_STATUS_SPC_RETRIES_EXCEEDED = 1;
-    public static final int CDMA_OTA_PROVISION_STATUS_A_KEY_EXCHANGED = 2;
-    public static final int CDMA_OTA_PROVISION_STATUS_SSD_UPDATED = 3;
-    public static final int CDMA_OTA_PROVISION_STATUS_NAM_DOWNLOADED = 4;
-    public static final int CDMA_OTA_PROVISION_STATUS_MDN_DOWNLOADED = 5;
-    public static final int CDMA_OTA_PROVISION_STATUS_IMSI_DOWNLOADED = 6;
-    public static final int CDMA_OTA_PROVISION_STATUS_PRL_DOWNLOADED = 7;
-    public static final int CDMA_OTA_PROVISION_STATUS_COMMITTED = 8;
-    public static final int CDMA_OTA_PROVISION_STATUS_OTAPA_STARTED = 9;
-    public static final int CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED = 10;
-    public static final int CDMA_OTA_PROVISION_STATUS_OTAPA_ABORTED = 11;
-
-
-    /**
-     * Get the current ServiceState. Use
-     * <code>registerForServiceStateChanged</code> to be informed of
-     * updates.
-     */
-    ServiceState getServiceState();
-
-    /**
-     * Get the current CellLocation.
-     */
-    CellLocation getCellLocation();
-
-    /**
-     * Get the current for the default apn DataState. No change notification
-     * exists at this interface -- use
-     * {@link android.telephony.PhoneStateListener} instead.
-     */
-    DataState getDataConnectionState();
-
-    /**
-     * Get the current DataState. No change notification exists at this
-     * interface -- use
-     * {@link android.telephony.PhoneStateListener} instead.
-     * @param apnType specify for which apn to get connection state info.
-     */
-    DataState getDataConnectionState(String apnType);
-
-    /**
-     * Get the current DataActivityState. No change notification exists at this
-     * interface -- use
-     * {@link android.telephony.TelephonyManager} instead.
-     */
-    DataActivityState getDataActivityState();
-
-    /**
-     * Gets the context for the phone, as set at initialization time.
-     */
-    Context getContext();
-
-    /**
-     * Disables the DNS check (i.e., allows "0.0.0.0").
-     * Useful for lab testing environment.
-     * @param b true disables the check, false enables.
-     */
-    void disableDnsCheck(boolean b);
-
-    /**
-     * Returns true if the DNS check is currently disabled.
-     */
-    boolean isDnsCheckDisabled();
-
-    /**
-     * Get current coarse-grained voice call state.
-     * Use {@link #registerForPreciseCallStateChanged(Handler, int, Object)
-     * registerForPreciseCallStateChanged()} for change notification. <p>
-     * If the phone has an active call and call waiting occurs,
-     * then the phone state is RINGING not OFFHOOK
-     * <strong>Note:</strong>
-     * This registration point provides notification of finer-grained
-     * changes.<p>
-     *
-     */
-    State getState();
-
-    /**
-     * Returns a string identifier for this phone interface for parties
-     *  outside the phone app process.
-     *  @return The string name.
-     */
-    String getPhoneName();
-
-    /**
-     * Return a numerical identifier for the phone radio interface.
-     * @return PHONE_TYPE_XXX as defined above.
-     */
-    int getPhoneType();
-
-    /**
-     * Returns an array of string identifiers for the APN types serviced by the
-     * currently active.
-     *  @return The string array will always return at least one entry, Phone.APN_TYPE_DEFAULT.
-     * TODO: Revisit if we always should return at least one entry.
-     */
-    String[] getActiveApnTypes();
-
-    /**
-     * Returns string for the active APN host.
-     *  @return type as a string or null if none.
-     */
-    String getActiveApnHost(String apnType);
-
-    /**
-     * Return the LinkProperties for the named apn or null if not available
-     */
-    LinkProperties getLinkProperties(String apnType);
-
-    /**
-     * Return the LinkCapabilities
-     */
-    LinkCapabilities getLinkCapabilities(String apnType);
-
-    /**
-     * Get current signal strength. No change notification available on this
-     * interface. Use <code>PhoneStateNotifier</code> or an equivalent.
-     * An ASU is 0-31 or -1 if unknown (for GSM, dBm = -113 - 2 * asu).
-     * The following special values are defined:</p>
-     * <ul><li>0 means "-113 dBm or less".</li>
-     * <li>31 means "-51 dBm or greater".</li></ul>
-     *
-     * @return Current signal strength as SignalStrength
-     */
-    SignalStrength getSignalStrength();
-
-    /**
-     * Notifies when a previously untracked non-ringing/waiting connection has appeared.
-     * This is likely due to some other entity (eg, SIM card application) initiating a call.
-     */
-    void registerForUnknownConnection(Handler h, int what, Object obj);
-
-    /**
-     * Unregisters for unknown connection notifications.
-     */
-    void unregisterForUnknownConnection(Handler h);
-
-    /**
-     * Register for getting notifications for change in the Call State {@link Call.State}
-     * This is called PreciseCallState because the call state is more precise than the
-     * {@link Phone.State} which can be obtained using the {@link PhoneStateListener}
-     *
-     * Resulting events will have an AsyncResult in <code>Message.obj</code>.
-     * AsyncResult.userData will be set to the obj argument here.
-     * The <em>h</em> parameter is held only by a weak reference.
-     */
-    void registerForPreciseCallStateChanged(Handler h, int what, Object obj);
-
-    /**
-     * Unregisters for voice call state change notifications.
-     * Extraneous calls are tolerated silently.
-     */
-    void unregisterForPreciseCallStateChanged(Handler h);
-
-
-    /**
-     * Notifies when a new ringing or waiting connection has appeared.<p>
-     *
-     *  Messages received from this:
-     *  Message.obj will be an AsyncResult
-     *  AsyncResult.userObj = obj
-     *  AsyncResult.result = a Connection. <p>
-     *  Please check Connection.isRinging() to make sure the Connection
-     *  has not dropped since this message was posted.
-     *  If Connection.isRinging() is true, then
-     *   Connection.getCall() == Phone.getRingingCall()
-     */
-    void registerForNewRingingConnection(Handler h, int what, Object obj);
-
-    /**
-     * Unregisters for new ringing connection notification.
-     * Extraneous calls are tolerated silently
-     */
-
-    void unregisterForNewRingingConnection(Handler h);
-
-    /**
-     * Notifies when an incoming call rings.<p>
-     *
-     *  Messages received from this:
-     *  Message.obj will be an AsyncResult
-     *  AsyncResult.userObj = obj
-     *  AsyncResult.result = a Connection. <p>
-     */
-    void registerForIncomingRing(Handler h, int what, Object obj);
-
-    /**
-     * Unregisters for ring notification.
-     * Extraneous calls are tolerated silently
-     */
-
-    void unregisterForIncomingRing(Handler h);
-
-    /**
-     * Notifies when out-band ringback tone is needed.<p>
-     *
-     *  Messages received from this:
-     *  Message.obj will be an AsyncResult
-     *  AsyncResult.userObj = obj
-     *  AsyncResult.result = boolean, true to start play ringback tone
-     *                       and false to stop. <p>
-     */
-    void registerForRingbackTone(Handler h, int what, Object obj);
-
-    /**
-     * Unregisters for ringback tone notification.
-     */
-
-    void unregisterForRingbackTone(Handler h);
-
-    /**
-     * Registers the handler to reset the uplink mute state to get
-     * uplink audio.
-     */
-    void registerForResendIncallMute(Handler h, int what, Object obj);
-
-    /**
-     * Unregisters for resend incall mute notifications.
-     */
-    void unregisterForResendIncallMute(Handler h);
-
-    /**
-     * Notifies when a voice connection has disconnected, either due to local
-     * or remote hangup or error.
-     *
-     *  Messages received from this will have the following members:<p>
-     *  <ul><li>Message.obj will be an AsyncResult</li>
-     *  <li>AsyncResult.userObj = obj</li>
-     *  <li>AsyncResult.result = a Connection object that is
-     *  no longer connected.</li></ul>
-     */
-    void registerForDisconnect(Handler h, int what, Object obj);
-
-    /**
-     * Unregisters for voice disconnection notification.
-     * Extraneous calls are tolerated silently
-     */
-    void unregisterForDisconnect(Handler h);
-
-
-    /**
-     * Register for notifications of initiation of a new MMI code request.
-     * MMI codes for GSM are discussed in 3GPP TS 22.030.<p>
-     *
-     * Example: If Phone.dial is called with "*#31#", then the app will
-     * be notified here.<p>
-     *
-     * The returned <code>Message.obj</code> will contain an AsyncResult.
-     *
-     * <code>obj.result</code> will be an "MmiCode" object.
-     */
-    void registerForMmiInitiate(Handler h, int what, Object obj);
-
-    /**
-     * Unregisters for new MMI initiate notification.
-     * Extraneous calls are tolerated silently
-     */
-    void unregisterForMmiInitiate(Handler h);
-
-    /**
-     * Register for notifications that an MMI request has completed
-     * its network activity and is in its final state. This may mean a state
-     * of COMPLETE, FAILED, or CANCELLED.
-     *
-     * <code>Message.obj</code> will contain an AsyncResult.
-     * <code>obj.result</code> will be an "MmiCode" object
-     */
-    void registerForMmiComplete(Handler h, int what, Object obj);
-
-    /**
-     * Unregisters for MMI complete notification.
-     * Extraneous calls are tolerated silently
-     */
-    void unregisterForMmiComplete(Handler h);
-
-    /**
-     * Registration point for Ecm timer reset
-     * @param h handler to notify
-     * @param what user-defined message code
-     * @param obj placed in Message.obj
-     */
-    public void registerForEcmTimerReset(Handler h, int what, Object obj);
-
-    /**
-     * Unregister for notification for Ecm timer reset
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForEcmTimerReset(Handler h);
-
-    /**
-     * Returns a list of MMI codes that are pending. (They have initiated
-     * but have not yet completed).
-     * Presently there is only ever one.
-     * Use <code>registerForMmiInitiate</code>
-     * and <code>registerForMmiComplete</code> for change notification.
-     */
-    public List<? extends MmiCode> getPendingMmiCodes();
-
-    /**
-     * Sends user response to a USSD REQUEST message.  An MmiCode instance
-     * representing this response is sent to handlers registered with
-     * registerForMmiInitiate.
-     *
-     * @param ussdMessge    Message to send in the response.
-     */
-    public void sendUssdResponse(String ussdMessge);
-
-    /**
-     * Register for ServiceState changed.
-     * Message.obj will contain an AsyncResult.
-     * AsyncResult.result will be a ServiceState instance
-     */
-    void registerForServiceStateChanged(Handler h, int what, Object obj);
-
-    /**
-     * Unregisters for ServiceStateChange notification.
-     * Extraneous calls are tolerated silently
-     */
-    void unregisterForServiceStateChanged(Handler h);
-
-    /**
-     * Register for Supplementary Service notifications from the network.
-     * Message.obj will contain an AsyncResult.
-     * AsyncResult.result will be a SuppServiceNotification instance.
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForSuppServiceNotification(Handler h, int what, Object obj);
-
-    /**
-     * Unregisters for Supplementary Service notifications.
-     * Extraneous calls are tolerated silently
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    void unregisterForSuppServiceNotification(Handler h);
-
-    /**
-     * Register for notifications when a supplementary service attempt fails.
-     * Message.obj will contain an AsyncResult.
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForSuppServiceFailed(Handler h, int what, Object obj);
-
-    /**
-     * Unregister for notifications when a supplementary service attempt fails.
-     * Extraneous calls are tolerated silently
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    void unregisterForSuppServiceFailed(Handler h);
-
-    /**
-     * Register for notifications when a sInCall VoicePrivacy is enabled
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj);
-
-    /**
-     * Unegister for notifications when a sInCall VoicePrivacy is enabled
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    void unregisterForInCallVoicePrivacyOn(Handler h);
-
-    /**
-     * Register for notifications when a sInCall VoicePrivacy is disabled
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj);
-
-    /**
-     * Unegister for notifications when a sInCall VoicePrivacy is disabled
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    void unregisterForInCallVoicePrivacyOff(Handler h);
-
-    /**
-     * Register for notifications when CDMA OTA Provision status change
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForCdmaOtaStatusChange(Handler h, int what, Object obj);
-
-    /**
-     * Unegister for notifications when CDMA OTA Provision status change
-     * @param h Handler to be removed from the registrant list.
-     */
-    void unregisterForCdmaOtaStatusChange(Handler h);
-
-    /**
-     * Registration point for subscription info ready
-     * @param h handler to notify
-     * @param what what code of message when delivered
-     * @param obj placed in Message.obj
-     */
-    public void registerForSubscriptionInfoReady(Handler h, int what, Object obj);
-
-    /**
-     * Unregister for notifications for subscription info
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForSubscriptionInfoReady(Handler h);
-
-    /**
-     * Returns SIM record load state. Use
-     * <code>getSimCard().registerForReady()</code> for change notification.
-     *
-     * @return true if records from the SIM have been loaded and are
-     * available (if applicable). If not applicable to the underlying
-     * technology, returns true as well.
-     */
-    boolean getIccRecordsLoaded();
-
-    /**
-     * Returns the ICC card interface for this phone, or null
-     * if not applicable to underlying technology.
-     */
-    IccCard getIccCard();
-
-    /**
-     * Answers a ringing or waiting call. Active calls, if any, go on hold.
-     * Answering occurs asynchronously, and final notification occurs via
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}.
-     *
-     * @exception CallStateException when no call is ringing or waiting
-     */
-    void acceptCall() throws CallStateException;
-
-    /**
-     * Reject (ignore) a ringing call. In GSM, this means UDUB
-     * (User Determined User Busy). Reject occurs asynchronously,
-     * and final notification occurs via
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}.
-     *
-     * @exception CallStateException when no call is ringing or waiting
-     */
-    void rejectCall() throws CallStateException;
-
-    /**
-     * Places any active calls on hold, and makes any held calls
-     *  active. Switch occurs asynchronously and may fail.
-     * Final notification occurs via
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}.
-     *
-     * @exception CallStateException if a call is ringing, waiting, or
-     * dialing/alerting. In these cases, this operation may not be performed.
-     */
-    void switchHoldingAndActive() throws CallStateException;
-
-    /**
-     * Whether or not the phone can conference in the current phone
-     * state--that is, one call holding and one call active.
-     * @return true if the phone can conference; false otherwise.
-     */
-    boolean canConference();
-
-    /**
-     * Conferences holding and active. Conference occurs asynchronously
-     * and may fail. Final notification occurs via
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}.
-     *
-     * @exception CallStateException if canConference() would return false.
-     * In these cases, this operation may not be performed.
-     */
-    void conference() throws CallStateException;
-
-    /**
-     * Enable or disable enhanced Voice Privacy (VP). If enhanced VP is
-     * disabled, normal VP is enabled.
-     *
-     * @param enable whether true or false to enable or disable.
-     * @param onComplete a callback message when the action is completed.
-     */
-    void enableEnhancedVoicePrivacy(boolean enable, Message onComplete);
-
-    /**
-     * Get the currently set Voice Privacy (VP) mode.
-     *
-     * @param onComplete a callback message when the action is completed.
-     */
-    void getEnhancedVoicePrivacy(Message onComplete);
-
-    /**
-     * Whether or not the phone can do explicit call transfer in the current
-     * phone state--that is, one call holding and one call active.
-     * @return true if the phone can do explicit call transfer; false otherwise.
-     */
-    boolean canTransfer();
-
-    /**
-     * Connects the two calls and disconnects the subscriber from both calls
-     * Explicit Call Transfer occurs asynchronously
-     * and may fail. Final notification occurs via
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}.
-     *
-     * @exception CallStateException if canTransfer() would return false.
-     * In these cases, this operation may not be performed.
-     */
-    void explicitCallTransfer() throws CallStateException;
-
-    /**
-     * Clears all DISCONNECTED connections from Call connection lists.
-     * Calls that were in the DISCONNECTED state become idle. This occurs
-     * synchronously.
-     */
-    void clearDisconnected();
-
-
-    /**
-     * Gets the foreground call object, which represents all connections that
-     * are dialing or active (all connections
-     * that have their audio path connected).<p>
-     *
-     * The foreground call is a singleton object. It is constant for the life
-     * of this phone. It is never null.<p>
-     *
-     * The foreground call will only ever be in one of these states:
-     * IDLE, ACTIVE, DIALING, ALERTING, or DISCONNECTED.
-     *
-     * State change notification is available via
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}.
-     */
-    Call getForegroundCall();
-
-    /**
-     * Gets the background call object, which represents all connections that
-     * are holding (all connections that have been accepted or connected, but
-     * do not have their audio path connected). <p>
-     *
-     * The background call is a singleton object. It is constant for the life
-     * of this phone object . It is never null.<p>
-     *
-     * The background call will only ever be in one of these states:
-     * IDLE, HOLDING or DISCONNECTED.
-     *
-     * State change notification is available via
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}.
-     */
-    Call getBackgroundCall();
-
-    /**
-     * Gets the ringing call object, which represents an incoming
-     * connection (if present) that is pending answer/accept. (This connection
-     * may be RINGING or WAITING, and there may be only one.)<p>
-
-     * The ringing call is a singleton object. It is constant for the life
-     * of this phone. It is never null.<p>
-     *
-     * The ringing call will only ever be in one of these states:
-     * IDLE, INCOMING, WAITING or DISCONNECTED.
-     *
-     * State change notification is available via
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}.
-     */
-    Call getRingingCall();
-
-    /**
-     * Initiate a new voice connection. This happens asynchronously, so you
-     * cannot assume the audio path is connected (or a call index has been
-     * assigned) until PhoneStateChanged notification has occurred.
-     *
-     * @exception CallStateException if a new outgoing call is not currently
-     * possible because no more call slots exist or a call exists that is
-     * dialing, alerting, ringing, or waiting.  Other errors are
-     * handled asynchronously.
-     */
-    Connection dial(String dialString) throws CallStateException;
-
-    /**
-     * Initiate a new voice connection with supplementary User to User
-     * Information. This happens asynchronously, so you cannot assume the audio
-     * path is connected (or a call index has been assigned) until
-     * PhoneStateChanged notification has occurred.
-     *
-     * @exception CallStateException if a new outgoing call is not currently
-     *                possible because no more call slots exist or a call exists
-     *                that is dialing, alerting, ringing, or waiting. Other
-     *                errors are handled asynchronously.
-     */
-    Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException;
-
-    /**
-     * Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated
-     * without SEND (so <code>dial</code> is not appropriate).
-     *
-     * @param dialString the MMI command to be executed.
-     * @return true if MMI command is executed.
-     */
-    boolean handlePinMmi(String dialString);
-
-    /**
-     * Handles in-call MMI commands. While in a call, or while receiving a
-     * call, use this to execute MMI commands.
-     * see 3GPP 20.030, section 6.5.5.1 for specs on the allowed MMI commands.
-     *
-     * @param command the MMI command to be executed.
-     * @return true if the MMI command is executed.
-     * @throws CallStateException
-     */
-    boolean handleInCallMmiCommands(String command) throws CallStateException;
-
-    /**
-     * Play a DTMF tone on the active call. Ignored if there is no active call.
-     * @param c should be one of 0-9, '*' or '#'. Other values will be
-     * silently ignored.
-     */
-    void sendDtmf(char c);
-
-    /**
-     * Start to paly a DTMF tone on the active call. Ignored if there is no active call
-     * or there is a playing DTMF tone.
-     * @param c should be one of 0-9, '*' or '#'. Other values will be
-     * silently ignored.
-     */
-    void startDtmf(char c);
-
-    /**
-     * Stop the playing DTMF tone. Ignored if there is no playing DTMF
-     * tone or no active call.
-     */
-    void stopDtmf();
-
-    /**
-     * send burst DTMF tone, it can send the string as single character or multiple character
-     * ignore if there is no active call or not valid digits string.
-     * Valid digit means only includes characters ISO-LATIN characters 0-9, *, #
-     * The difference between sendDtmf and sendBurstDtmf is sendDtmf only sends one character,
-     * this api can send single character and multiple character, also, this api has response
-     * back to caller.
-     *
-     * @param dtmfString is string representing the dialing digit(s) in the active call
-     * @param on the DTMF ON length in milliseconds, or 0 for default
-     * @param off the DTMF OFF length in milliseconds, or 0 for default
-     * @param onComplete is the callback message when the action is processed by BP
-     *
-     */
-    void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete);
-
-    /**
-     * Sets the radio power on/off state (off is sometimes
-     * called "airplane mode"). Current state can be gotten via
-     * {@link #getServiceState()}.{@link
-     * android.telephony.ServiceState#getState() getState()}.
-     * <strong>Note: </strong>This request is asynchronous.
-     * getServiceState().getState() will not change immediately after this call.
-     * registerForServiceStateChanged() to find out when the
-     * request is complete.
-     *
-     * @param power true means "on", false means "off".
-     */
-    void setRadioPower(boolean power);
-
-    /**
-     * Get voice message waiting indicator status. No change notification
-     * available on this interface. Use PhoneStateNotifier or similar instead.
-     *
-     * @return true if there is a voice message waiting
-     */
-    boolean getMessageWaitingIndicator();
-
-    /**
-     * Get voice call forwarding indicator status. No change notification
-     * available on this interface. Use PhoneStateNotifier or similar instead.
-     *
-     * @return true if there is a voice call forwarding
-     */
-    boolean getCallForwardingIndicator();
-
-    /**
-     * Get the line 1 phone number (MSISDN). For CDMA phones, the MDN is returned
-     * and {@link #getMsisdn()} will return the MSISDN on CDMA/LTE phones.<p>
-     *
-     * @return phone number. May return null if not
-     * available or the SIM is not ready
-     */
-    String getLine1Number();
-
-    /**
-     * Returns the alpha tag associated with the msisdn number.
-     * If there is no alpha tag associated or the record is not yet available,
-     * returns a default localized string. <p>
-     */
-    String getLine1AlphaTag();
-
-    /**
-     * Sets the MSISDN phone number in the SIM card.
-     *
-     * @param alphaTag the alpha tag associated with the MSISDN phone number
-     *        (see getMsisdnAlphaTag)
-     * @param number the new MSISDN phone number to be set on the SIM.
-     * @param onComplete a callback message when the action is completed.
-     */
-    void setLine1Number(String alphaTag, String number, Message onComplete);
-
-    /**
-     * Get the voice mail access phone number. Typically dialed when the
-     * user holds the "1" key in the phone app. May return null if not
-     * available or the SIM is not ready.<p>
-     */
-    String getVoiceMailNumber();
-
-    /**
-     * Returns unread voicemail count. This count is shown when the  voicemail
-     * notification is expanded.<p>
-     */
-    int getVoiceMessageCount();
-
-    /**
-     * Returns the alpha tag associated with the voice mail number.
-     * If there is no alpha tag associated or the record is not yet available,
-     * returns a default localized string. <p>
-     *
-     * Please use this value instead of some other localized string when
-     * showing a name for this number in the UI. For example, call log
-     * entries should show this alpha tag. <p>
-     *
-     * Usage of this alpha tag in the UI is a common carrier requirement.
-     */
-    String getVoiceMailAlphaTag();
-
-    /**
-     * setVoiceMailNumber
-     * sets the voicemail number in the SIM card.
-     *
-     * @param alphaTag the alpha tag associated with the voice mail number
-     *        (see getVoiceMailAlphaTag)
-     * @param voiceMailNumber the new voicemail number to be set on the SIM.
-     * @param onComplete a callback message when the action is completed.
-     */
-    void setVoiceMailNumber(String alphaTag,
-                            String voiceMailNumber,
-                            Message onComplete);
-
-    /**
-     * getCallForwardingOptions
-     * gets a call forwarding option. The return value of
-     * ((AsyncResult)onComplete.obj) is an array of CallForwardInfo.
-     *
-     * @param commandInterfaceCFReason is one of the valid call forwarding
-     *        CF_REASONS, as defined in
-     *        <code>com.android.internal.telephony.CommandsInterface.</code>
-     * @param onComplete a callback message when the action is completed.
-     *        @see com.android.internal.telephony.CallForwardInfo for details.
-     */
-    void getCallForwardingOption(int commandInterfaceCFReason,
-                                  Message onComplete);
-
-    /**
-     * setCallForwardingOptions
-     * sets a call forwarding option.
-     *
-     * @param commandInterfaceCFReason is one of the valid call forwarding
-     *        CF_REASONS, as defined in
-     *        <code>com.android.internal.telephony.CommandsInterface.</code>
-     * @param commandInterfaceCFAction is one of the valid call forwarding
-     *        CF_ACTIONS, as defined in
-     *        <code>com.android.internal.telephony.CommandsInterface.</code>
-     * @param dialingNumber is the target phone number to forward calls to
-     * @param timerSeconds is used by CFNRy to indicate the timeout before
-     *        forwarding is attempted.
-     * @param onComplete a callback message when the action is completed.
-     */
-    void setCallForwardingOption(int commandInterfaceCFReason,
-                                 int commandInterfaceCFAction,
-                                 String dialingNumber,
-                                 int timerSeconds,
-                                 Message onComplete);
-
-    /**
-     * getOutgoingCallerIdDisplay
-     * gets outgoing caller id display. The return value of
-     * ((AsyncResult)onComplete.obj) is an array of int, with a length of 2.
-     *
-     * @param onComplete a callback message when the action is completed.
-     *        @see com.android.internal.telephony.CommandsInterface#getCLIR for details.
-     */
-    void getOutgoingCallerIdDisplay(Message onComplete);
-
-    /**
-     * setOutgoingCallerIdDisplay
-     * sets a call forwarding option.
-     *
-     * @param commandInterfaceCLIRMode is one of the valid call CLIR
-     *        modes, as defined in
-     *        <code>com.android.internal.telephony.CommandsInterface./code>
-     * @param onComplete a callback message when the action is completed.
-     */
-    void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode,
-                                    Message onComplete);
-
-    /**
-     * getCallWaiting
-     * gets call waiting activation state. The return value of
-     * ((AsyncResult)onComplete.obj) is an array of int, with a length of 1.
-     *
-     * @param onComplete a callback message when the action is completed.
-     *        @see com.android.internal.telephony.CommandsInterface#queryCallWaiting for details.
-     */
-    void getCallWaiting(Message onComplete);
-
-    /**
-     * setCallWaiting
-     * sets a call forwarding option.
-     *
-     * @param enable is a boolean representing the state that you are
-     *        requesting, true for enabled, false for disabled.
-     * @param onComplete a callback message when the action is completed.
-     */
-    void setCallWaiting(boolean enable, Message onComplete);
-
-    /**
-     * Scan available networks. This method is asynchronous; .
-     * On completion, <code>response.obj</code> is set to an AsyncResult with
-     * one of the following members:.<p>
-     *<ul>
-     * <li><code>response.obj.result</code> will be a <code>List</code> of
-     * <code>OperatorInfo</code> objects, or</li>
-     * <li><code>response.obj.exception</code> will be set with an exception
-     * on failure.</li>
-     * </ul>
-     */
-    void getAvailableNetworks(Message response);
-
-    /**
-     * Switches network selection mode to "automatic", re-scanning and
-     * re-selecting a network if appropriate.
-     *
-     * @param response The message to dispatch when the network selection
-     * is complete.
-     *
-     * @see #selectNetworkManually(OperatorInfo, android.os.Message )
-     */
-    void setNetworkSelectionModeAutomatic(Message response);
-
-    /**
-     * Manually selects a network. <code>response</code> is
-     * dispatched when this is complete.  <code>response.obj</code> will be
-     * an AsyncResult, and <code>response.obj.exception</code> will be non-null
-     * on failure.
-     *
-     * @see #setNetworkSelectionModeAutomatic(Message)
-     */
-    void selectNetworkManually(OperatorInfo network,
-                            Message response);
-
-    /**
-     *  Requests to set the preferred network type for searching and registering
-     * (CS/PS domain, RAT, and operation mode)
-     * @param networkType one of  NT_*_TYPE
-     * @param response is callback message
-     */
-    void setPreferredNetworkType(int networkType, Message response);
-
-    /**
-     *  Query the preferred network type setting
-     *
-     * @param response is callback message to report one of  NT_*_TYPE
-     */
-    void getPreferredNetworkType(Message response);
-
-    /**
-     * Gets the default SMSC address.
-     *
-     * @param result Callback message contains the SMSC address.
-     */
-    void getSmscAddress(Message result);
-
-    /**
-     * Sets the default SMSC address.
-     *
-     * @param address new SMSC address
-     * @param result Callback message is empty on completion
-     */
-    void setSmscAddress(String address, Message result);
-
-    /**
-     * Query neighboring cell IDs.  <code>response</code> is dispatched when
-     * this is complete.  <code>response.obj</code> will be an AsyncResult,
-     * and <code>response.obj.exception</code> will be non-null on failure.
-     * On success, <code>AsyncResult.result</code> will be a <code>String[]</code>
-     * containing the neighboring cell IDs.  Index 0 will contain the count
-     * of available cell IDs.  Cell IDs are in hexadecimal format.
-     *
-     * @param response callback message that is dispatched when the query
-     * completes.
-     */
-    void getNeighboringCids(Message response);
-
-    /**
-     * Sets an event to be fired when the telephony system processes
-     * a post-dial character on an outgoing call.<p>
-     *
-     * Messages of type <code>what</code> will be sent to <code>h</code>.
-     * The <code>obj</code> field of these Message's will be instances of
-     * <code>AsyncResult</code>. <code>Message.obj.result</code> will be
-     * a Connection object.<p>
-     *
-     * Message.arg1 will be the post dial character being processed,
-     * or 0 ('\0') if end of string.<p>
-     *
-     * If Connection.getPostDialState() == WAIT,
-     * the application must call
-     * {@link com.android.internal.telephony.Connection#proceedAfterWaitChar()
-     * Connection.proceedAfterWaitChar()} or
-     * {@link com.android.internal.telephony.Connection#cancelPostDial()
-     * Connection.cancelPostDial()}
-     * for the telephony system to continue playing the post-dial
-     * DTMF sequence.<p>
-     *
-     * If Connection.getPostDialState() == WILD,
-     * the application must call
-     * {@link com.android.internal.telephony.Connection#proceedAfterWildChar
-     * Connection.proceedAfterWildChar()}
-     * or
-     * {@link com.android.internal.telephony.Connection#cancelPostDial()
-     * Connection.cancelPostDial()}
-     * for the telephony system to continue playing the
-     * post-dial DTMF sequence.<p>
-     *
-     * Only one post dial character handler may be set. <p>
-     * Calling this method with "h" equal to null unsets this handler.<p>
-     */
-    void setOnPostDialCharacter(Handler h, int what, Object obj);
-
-
-    /**
-     * Mutes or unmutes the microphone for the active call. The microphone
-     * is automatically unmuted if a call is answered, dialed, or resumed
-     * from a holding state.
-     *
-     * @param muted true to mute the microphone,
-     * false to activate the microphone.
-     */
-
-    void setMute(boolean muted);
-
-    /**
-     * Gets current mute status. Use
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}
-     * as a change notifcation, although presently phone state changed is not
-     * fired when setMute() is called.
-     *
-     * @return true is muting, false is unmuting
-     */
-    boolean getMute();
-
-    /**
-     * Enables or disables echo suppression.
-     */
-    void setEchoSuppressionEnabled(boolean enabled);
-
-    /**
-     * Invokes RIL_REQUEST_OEM_HOOK_RAW on RIL implementation.
-     *
-     * @param data The data for the request.
-     * @param response <strong>On success</strong>,
-     * (byte[])(((AsyncResult)response.obj).result)
-     * <strong>On failure</strong>,
-     * (((AsyncResult)response.obj).result) == null and
-     * (((AsyncResult)response.obj).exception) being an instance of
-     * com.android.internal.telephony.gsm.CommandException
-     *
-     * @see #invokeOemRilRequestRaw(byte[], android.os.Message)
-     */
-    void invokeOemRilRequestRaw(byte[] data, Message response);
-
-    /**
-     * Invokes RIL_REQUEST_OEM_HOOK_Strings on RIL implementation.
-     *
-     * @param strings The strings to make available as the request data.
-     * @param response <strong>On success</strong>, "response" bytes is
-     * made available as:
-     * (String[])(((AsyncResult)response.obj).result).
-     * <strong>On failure</strong>,
-     * (((AsyncResult)response.obj).result) == null and
-     * (((AsyncResult)response.obj).exception) being an instance of
-     * com.android.internal.telephony.gsm.CommandException
-     *
-     * @see #invokeOemRilRequestStrings(java.lang.String[], android.os.Message)
-     */
-    void invokeOemRilRequestStrings(String[] strings, Message response);
-
-    /**
-     * Get the current active Data Call list
-     *
-     * @param response <strong>On success</strong>, "response" bytes is
-     * made available as:
-     * (String[])(((AsyncResult)response.obj).result).
-     * <strong>On failure</strong>,
-     * (((AsyncResult)response.obj).result) == null and
-     * (((AsyncResult)response.obj).exception) being an instance of
-     * com.android.internal.telephony.gsm.CommandException
-     */
-    void getDataCallList(Message response);
-
-    /**
-     * Update the ServiceState CellLocation for current network registration.
-     */
-    void updateServiceLocation();
-
-    /**
-     * Enable location update notifications.
-     */
-    void enableLocationUpdates();
-
-    /**
-     * Disable location update notifications.
-     */
-    void disableLocationUpdates();
-
-    /**
-     * For unit tests; don't send notifications to "Phone"
-     * mailbox registrants if true.
-     */
-    void setUnitTestMode(boolean f);
-
-    /**
-     * @return true If unit test mode is enabled
-     */
-    boolean getUnitTestMode();
-
-    /**
-     * Assign a specified band for RF configuration.
-     *
-     * @param bandMode one of BM_*_BAND
-     * @param response is callback message
-     */
-    void setBandMode(int bandMode, Message response);
-
-    /**
-     * Query the list of band mode supported by RF.
-     *
-     * @param response is callback message
-     *        ((AsyncResult)response.obj).result  is an int[] with every
-     *        element representing one avialable BM_*_BAND
-     */
-    void queryAvailableBandMode(Message response);
-
-    /**
-     * @return true if enable data connection on roaming
-     */
-    boolean getDataRoamingEnabled();
-
-    /**
-     * @param enable set true if enable data connection on roaming
-     */
-    void setDataRoamingEnabled(boolean enable);
-
-    /**
-     *  Query the CDMA roaming preference setting
-     *
-     * @param response is callback message to report one of  CDMA_RM_*
-     */
-    void queryCdmaRoamingPreference(Message response);
-
-    /**
-     *  Requests to set the CDMA roaming preference
-     * @param cdmaRoamingType one of  CDMA_RM_*
-     * @param response is callback message
-     */
-    void setCdmaRoamingPreference(int cdmaRoamingType, Message response);
-
-    /**
-     *  Requests to set the CDMA subscription mode
-     * @param cdmaSubscriptionType one of  CDMA_SUBSCRIPTION_*
-     * @param response is callback message
-     */
-    void setCdmaSubscription(int cdmaSubscriptionType, Message response);
-
-    /**
-     * If this is a simulated phone interface, returns a SimulatedRadioControl.
-     * @ return A SimulatedRadioControl if this is a simulated interface;
-     * otherwise, null.
-     */
-    SimulatedRadioControl getSimulatedRadioControl();
-
-    /**
-     * Enables the specified APN type. Only works for "special" APN types,
-     * i.e., not the default APN.
-     * @param type The desired APN type. Cannot be {@link #APN_TYPE_DEFAULT}.
-     * @return <code>APN_ALREADY_ACTIVE</code> if the current APN
-     * services the requested type.<br/>
-     * <code>APN_TYPE_NOT_AVAILABLE</code> if the carrier does not
-     * support the requested APN.<br/>
-     * <code>APN_REQUEST_STARTED</code> if the request has been initiated.<br/>
-     * <code>APN_REQUEST_FAILED</code> if the request was invalid.<br/>
-     * A <code>ACTION_ANY_DATA_CONNECTION_STATE_CHANGED</code> broadcast will
-     * indicate connection state progress.
-     */
-    int enableApnType(String type);
-
-    /**
-     * Disables the specified APN type, and switches back to the default APN,
-     * if necessary. Switching to the default APN will not happen if default
-     * data traffic has been explicitly disabled via a call to {@link #disableDataConnectivity}.
-     * <p/>Only works for "special" APN types,
-     * i.e., not the default APN.
-     * @param type The desired APN type. Cannot be {@link #APN_TYPE_DEFAULT}.
-     * @return <code>APN_ALREADY_ACTIVE</code> if the default APN
-     * is already active.<br/>
-     * <code>APN_REQUEST_STARTED</code> if the request to switch to the default
-     * APN has been initiated.<br/>
-     * <code>APN_REQUEST_FAILED</code> if the request was invalid.<br/>
-     * A <code>ACTION_ANY_DATA_CONNECTION_STATE_CHANGED</code> broadcast will
-     * indicate connection state progress.
-     */
-    int disableApnType(String type);
-
-    /**
-     * Report on whether data connectivity is allowed.
-     */
-    boolean isDataConnectivityPossible();
-
-    /**
-     * Report on whether data connectivity is allowed for an APN.
-     */
-    boolean isDataConnectivityPossible(String apnType);
-
-    /**
-     * Retrieves the unique device ID, e.g., IMEI for GSM phones and MEID for CDMA phones.
-     */
-    String getDeviceId();
-
-    /**
-     * Retrieves the software version number for the device, e.g., IMEI/SV
-     * for GSM phones.
-     */
-    String getDeviceSvn();
-
-    /**
-     * Retrieves the unique subscriber ID, e.g., IMSI for GSM phones.
-     */
-    String getSubscriberId();
-
-    /**
-     * Retrieves the serial number of the ICC, if applicable.
-     */
-    String getIccSerialNumber();
-
-    /* CDMA support methods */
-
-    /**
-     * Retrieves the MIN for CDMA phones.
-     */
-    String getCdmaMin();
-
-    /**
-     * Check if subscription data has been assigned to mMin
-     *
-     * return true if MIN info is ready; false otherwise.
-     */
-    boolean isMinInfoReady();
-
-    /**
-     *  Retrieves PRL Version for CDMA phones
-     */
-    String getCdmaPrlVersion();
-
-    /**
-     * Retrieves the ESN for CDMA phones.
-     */
-    String getEsn();
-
-    /**
-     * Retrieves MEID for CDMA phones.
-     */
-    String getMeid();
-
-    /**
-     * Retrieves the MSISDN from the UICC. For GSM/UMTS phones, this is equivalent to
-     * {@link #getLine1Number()}. For CDMA phones, {@link #getLine1Number()} returns
-     * the MDN, so this method is provided to return the MSISDN on CDMA/LTE phones.
-     */
-    String getMsisdn();
-
-    /**
-     * Retrieves IMEI for phones. Returns null if IMEI is not set.
-     */
-    String getImei();
-
-    /**
-     * Retrieves the PhoneSubInfo of the Phone
-     */
-    public PhoneSubInfo getPhoneSubInfo();
-
-    /**
-     * Retrieves the IccSmsInterfaceManager of the Phone
-     */
-    public IccSmsInterfaceManager getIccSmsInterfaceManager();
-
-    /**
-     * Retrieves the IccPhoneBookInterfaceManager of the Phone
-     */
-    public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager();
-
-    /**
-     * setTTYMode
-     * sets a TTY mode option.
-     * @param ttyMode is a one of the following:
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
-     * @param onComplete a callback message when the action is completed
-     */
-    void setTTYMode(int ttyMode, Message onComplete);
-
-    /**
-     * queryTTYMode
-     * query the status of the TTY mode
-     *
-     * @param onComplete a callback message when the action is completed.
-     */
-    void queryTTYMode(Message onComplete);
-
-    /**
-     * Activate or deactivate cell broadcast SMS.
-     *
-     * @param activate
-     *            0 = activate, 1 = deactivate
-     * @param response
-     *            Callback message is empty on completion
-     */
-    void activateCellBroadcastSms(int activate, Message response);
-
-    /**
-     * Query the current configuration of cdma cell broadcast SMS.
-     *
-     * @param response
-     *            Callback message is empty on completion
-     */
-    void getCellBroadcastSmsConfig(Message response);
-
-    /**
-     * Configure cell broadcast SMS.
-     *
-     * TODO: Change the configValuesArray to a RIL_BroadcastSMSConfig
-     *
-     * @param response
-     *            Callback message is empty on completion
-     */
-    public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response);
-
-    public void notifyDataActivity();
-
-    /**
-     * Returns the CDMA ERI icon index to display
-     */
-    public int getCdmaEriIconIndex();
-
-    /**
-     * Returns the CDMA ERI icon mode,
-     * 0 - ON
-     * 1 - FLASHING
-     */
-    public int getCdmaEriIconMode();
-
-    /**
-     * Returns the CDMA ERI text,
-     */
-    public String getCdmaEriText();
-
-    /**
-     * request to exit emergency call back mode
-     * the caller should use setOnECMModeExitResponse
-     * to receive the emergency callback mode exit response
-     */
-    void exitEmergencyCallbackMode();
-
-    /**
-     * this decides if the dial number is OTA(Over the air provision) number or not
-     * @param dialStr is string representing the dialing digit(s)
-     * @return  true means the dialStr is OTA number, and false means the dialStr is not OTA number
-     */
-    boolean isOtaSpNumber(String dialStr);
-
-    /**
-     * Returns true if OTA Service Provisioning needs to be performed.
-     */
-    boolean needsOtaServiceProvisioning();
-
-    /**
-     * Register for notifications when CDMA call waiting comes
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForCallWaiting(Handler h, int what, Object obj);
-
-    /**
-     * Unegister for notifications when CDMA Call waiting comes
-     * @param h Handler to be removed from the registrant list.
-     */
-    void unregisterForCallWaiting(Handler h);
-
-
-    /**
-     * Register for signal information notifications from the network.
-     * Message.obj will contain an AsyncResult.
-     * AsyncResult.result will be a SuppServiceNotification instance.
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-
-    void registerForSignalInfo(Handler h, int what, Object obj) ;
-    /**
-     * Unregisters for signal information notifications.
-     * Extraneous calls are tolerated silently
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    void unregisterForSignalInfo(Handler h);
-
-    /**
-     * Register for display information notifications from the network.
-     * Message.obj will contain an AsyncResult.
-     * AsyncResult.result will be a SuppServiceNotification instance.
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForDisplayInfo(Handler h, int what, Object obj);
-
-    /**
-     * Unregisters for display information notifications.
-     * Extraneous calls are tolerated silently
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    void unregisterForDisplayInfo(Handler h) ;
-
-    /**
-     * Register for CDMA number information record notification from the network.
-     * Message.obj will contain an AsyncResult.
-     * AsyncResult.result will be a CdmaInformationRecords.CdmaNumberInfoRec
-     * instance.
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForNumberInfo(Handler h, int what, Object obj);
-
-    /**
-     * Unregisters for number information record notifications.
-     * Extraneous calls are tolerated silently
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    void unregisterForNumberInfo(Handler h);
-
-    /**
-     * Register for CDMA redirected number information record notification
-     * from the network.
-     * Message.obj will contain an AsyncResult.
-     * AsyncResult.result will be a CdmaInformationRecords.CdmaRedirectingNumberInfoRec
-     * instance.
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForRedirectedNumberInfo(Handler h, int what, Object obj);
-
-    /**
-     * Unregisters for redirected number information record notification.
-     * Extraneous calls are tolerated silently
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    void unregisterForRedirectedNumberInfo(Handler h);
-
-    /**
-     * Register for CDMA line control information record notification
-     * from the network.
-     * Message.obj will contain an AsyncResult.
-     * AsyncResult.result will be a CdmaInformationRecords.CdmaLineControlInfoRec
-     * instance.
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForLineControlInfo(Handler h, int what, Object obj);
-
-    /**
-     * Unregisters for line control information notifications.
-     * Extraneous calls are tolerated silently
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    void unregisterForLineControlInfo(Handler h);
-
-    /**
-     * Register for CDMA T53 CLIR information record notifications
-     * from the network.
-     * Message.obj will contain an AsyncResult.
-     * AsyncResult.result will be a CdmaInformationRecords.CdmaT53ClirInfoRec
-     * instance.
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerFoT53ClirlInfo(Handler h, int what, Object obj);
-
-    /**
-     * Unregisters for T53 CLIR information record notification
-     * Extraneous calls are tolerated silently
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    void unregisterForT53ClirInfo(Handler h);
-
-    /**
-     * Register for CDMA T53 audio control information record notifications
-     * from the network.
-     * Message.obj will contain an AsyncResult.
-     * AsyncResult.result will be a CdmaInformationRecords.CdmaT53AudioControlInfoRec
-     * instance.
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForT53AudioControlInfo(Handler h, int what, Object obj);
-
-    /**
-     * Unregisters for T53 audio control information record notifications.
-     * Extraneous calls are tolerated silently
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    void unregisterForT53AudioControlInfo(Handler h);
-
-    /**
-     * registers for exit emergency call back mode request response
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-
-    void setOnEcbModeExitResponse(Handler h, int what, Object obj);
-
-    /**
-     * Unregisters for exit emergency call back mode request response
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    void unsetOnEcbModeExitResponse(Handler h);
-
-    /**
-     * Return if the current radio is LTE on CDMA. This
-     * is a tri-state return value as for a period of time
-     * the mode may be unknown.
-     *
-     * @return {@link #LTE_ON_CDMA_UNKNOWN}, {@link #LTE_ON_CDMA_FALSE} or {@link #LTE_ON_CDMA_TRUE}
-     */
-    public int getLteOnCdmaMode();
-
-    /**
-     * TODO: Adding a function for each property is not good.
-     * A fucntion of type getPhoneProp(propType) where propType is an
-     * enum of GSM+CDMA+LTE props would be a better approach.
-     *
-     * Get "Restriction of menu options for manual PLMN selection" bit
-     * status from EF_CSP data, this belongs to "Value Added Services Group".
-     * @return true if this bit is set or EF_CSP data is unavailable,
-     * false otherwise
-     */
-    boolean isCspPlmnEnabled();
-
-    /**
-     * Return an interface to retrieve the ISIM records for IMS, if available.
-     * @return the interface to retrieve the ISIM records, or null if not supported
-     */
-    IsimRecords getIsimRecords();
-
-    /**
-     * Request the ISIM application on the UICC to perform the AKA
-     * challenge/response algorithm for IMS authentication. The nonce string
-     * and challenge response are Base64 encoded Strings.
-     *
-     * @param nonce the nonce string to pass with the ISIM authentication request
-     * @param response a callback message with the String response in the obj field
-     */
-    void requestIsimAuthentication(String nonce, Message response);
-
-    /**
-     * Sets the SIM voice message waiting indicator records.
-     * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
-     * @param countWaiting The number of messages waiting, if known. Use
-     *                     -1 to indicate that an unknown number of
-     *                      messages are waiting
-     */
-    void setVoiceMessageWaiting(int line, int countWaiting);
-
-    /**
-     * Gets the USIM service table from the UICC, if present and available.
-     * @return an interface to the UsimServiceTable record, or null if not available
-     */
-    UsimServiceTable getUsimServiceTable();
-
-    /**
-     * Unregister from all events it registered for and dispose objects
-     * created by this object.
-     */
-    void dispose();
-
-    /**
-     * Remove references to external object stored in this object.
-     */
-    void removeReferences();
-}
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
deleted file mode 100644
index 2ac9365..0000000
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ /dev/null
@@ -1,1188 +0,0 @@
-/*
- * 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.internal.telephony;
-
-import android.app.ActivityManagerNative;
-import android.app.IActivityManager;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.SharedPreferences;
-import android.net.LinkCapabilities;
-import android.net.LinkProperties;
-import android.net.wifi.WifiManager;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RegistrantList;
-import android.os.SystemProperties;
-import android.preference.PreferenceManager;
-import android.provider.Settings;
-import android.telephony.ServiceState;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.R;
-import com.android.internal.telephony.gsm.UsimServiceTable;
-import com.android.internal.telephony.ims.IsimRecords;
-import com.android.internal.telephony.test.SimulatedRadioControl;
-import com.android.internal.telephony.gsm.SIMRecords;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.Locale;
-import java.util.concurrent.atomic.AtomicReference;
-
-
-/**
- * (<em>Not for SDK use</em>)
- * A base implementation for the com.android.internal.telephony.Phone interface.
- *
- * Note that implementations of Phone.java are expected to be used
- * from a single application thread. This should be the same thread that
- * originally called PhoneFactory to obtain the interface.
- *
- *  {@hide}
- *
- */
-
-public abstract class PhoneBase extends Handler implements Phone {
-    private static final String LOG_TAG = "PHONE";
-    private static final boolean LOCAL_DEBUG = true;
-
-    // Key used to read and write the saved network selection numeric value
-    public static final String NETWORK_SELECTION_KEY = "network_selection_key";
-    // Key used to read and write the saved network selection operator name
-    public static final String NETWORK_SELECTION_NAME_KEY = "network_selection_name_key";
-
-
-    // Key used to read/write "disable data connection on boot" pref (used for testing)
-    public static final String DATA_DISABLED_ON_BOOT_KEY = "disabled_on_boot_key";
-
-    /* Event Constants */
-    protected static final int EVENT_RADIO_AVAILABLE             = 1;
-    /** Supplementary Service Notification received. */
-    protected static final int EVENT_SSN                         = 2;
-    protected static final int EVENT_SIM_RECORDS_LOADED          = 3;
-    protected static final int EVENT_MMI_DONE                    = 4;
-    protected static final int EVENT_RADIO_ON                    = 5;
-    protected static final int EVENT_GET_BASEBAND_VERSION_DONE   = 6;
-    protected static final int EVENT_USSD                        = 7;
-    protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE  = 8;
-    protected static final int EVENT_GET_IMEI_DONE               = 9;
-    protected static final int EVENT_GET_IMEISV_DONE             = 10;
-    protected static final int EVENT_GET_SIM_STATUS_DONE         = 11;
-    protected static final int EVENT_SET_CALL_FORWARD_DONE       = 12;
-    protected static final int EVENT_GET_CALL_FORWARD_DONE       = 13;
-    protected static final int EVENT_CALL_RING                   = 14;
-    protected static final int EVENT_CALL_RING_CONTINUE          = 15;
-
-    // Used to intercept the carrier selection calls so that
-    // we can save the values.
-    protected static final int EVENT_SET_NETWORK_MANUAL_COMPLETE    = 16;
-    protected static final int EVENT_SET_NETWORK_AUTOMATIC_COMPLETE = 17;
-    protected static final int EVENT_SET_CLIR_COMPLETE              = 18;
-    protected static final int EVENT_REGISTERED_TO_NETWORK          = 19;
-    protected static final int EVENT_SET_VM_NUMBER_DONE             = 20;
-    // Events for CDMA support
-    protected static final int EVENT_GET_DEVICE_IDENTITY_DONE       = 21;
-    protected static final int EVENT_RUIM_RECORDS_LOADED            = 22;
-    protected static final int EVENT_NV_READY                       = 23;
-    protected static final int EVENT_SET_ENHANCED_VP                = 24;
-    protected static final int EVENT_EMERGENCY_CALLBACK_MODE_ENTER  = 25;
-    protected static final int EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE = 26;
-    protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 27;
-    // other
-    protected static final int EVENT_SET_NETWORK_AUTOMATIC          = 28;
-    protected static final int EVENT_NEW_ICC_SMS                    = 29;
-    protected static final int EVENT_ICC_RECORD_EVENTS              = 30;
-
-    // Key used to read/write current CLIR setting
-    public static final String CLIR_KEY = "clir_key";
-
-    // Key used to read/write "disable DNS server check" pref (used for testing)
-    public static final String DNS_SERVER_CHECK_DISABLED_KEY = "dns_server_check_disabled_key";
-
-    /* Instance Variables */
-    public CommandsInterface mCM;
-    boolean mDnsCheckDisabled;
-    public DataConnectionTracker mDataConnectionTracker;
-    boolean mDoesRilSendMultipleCallRing;
-    int mCallRingContinueToken;
-    int mCallRingDelay;
-    public boolean mIsTheCurrentActivePhone = true;
-    boolean mIsVoiceCapable = true;
-    public IccRecords mIccRecords;
-    protected AtomicReference<IccCard> mIccCard = new AtomicReference<IccCard>();
-    public SmsStorageMonitor mSmsStorageMonitor;
-    public SmsUsageMonitor mSmsUsageMonitor;
-    public SMSDispatcher mSMS;
-
-    /**
-     * Set a system property, unless we're in unit test mode
-     */
-    public void
-    setSystemProperty(String property, String value) {
-        if(getUnitTestMode()) {
-            return;
-        }
-        SystemProperties.set(property, value);
-    }
-
-
-    protected final RegistrantList mPreciseCallStateRegistrants
-            = new RegistrantList();
-
-    protected final RegistrantList mNewRingingConnectionRegistrants
-            = new RegistrantList();
-
-    protected final RegistrantList mIncomingRingRegistrants
-            = new RegistrantList();
-
-    protected final RegistrantList mDisconnectRegistrants
-            = new RegistrantList();
-
-    protected final RegistrantList mServiceStateRegistrants
-            = new RegistrantList();
-
-    protected final RegistrantList mMmiCompleteRegistrants
-            = new RegistrantList();
-
-    protected final RegistrantList mMmiRegistrants
-            = new RegistrantList();
-
-    protected final RegistrantList mUnknownConnectionRegistrants
-            = new RegistrantList();
-
-    protected final RegistrantList mSuppServiceFailedRegistrants
-            = new RegistrantList();
-
-    protected Looper mLooper; /* to insure registrants are in correct thread*/
-
-    protected final Context mContext;
-
-    /**
-     * PhoneNotifier is an abstraction for all system-wide
-     * state change notification. DefaultPhoneNotifier is
-     * used here unless running we're inside a unit test.
-     */
-    protected PhoneNotifier mNotifier;
-
-    protected SimulatedRadioControl mSimulatedRadioControl;
-
-    boolean mUnitTestMode;
-
-    /**
-     * Constructs a PhoneBase in normal (non-unit test) mode.
-     *
-     * @param context Context object from hosting application
-     * @param notifier An instance of DefaultPhoneNotifier,
-     * unless unit testing.
-     */
-    protected PhoneBase(PhoneNotifier notifier, Context context, CommandsInterface ci) {
-        this(notifier, context, ci, false);
-    }
-
-    /**
-     * Constructs a PhoneBase in normal (non-unit test) mode.
-     *
-     * @param context Context object from hosting application
-     * @param notifier An instance of DefaultPhoneNotifier,
-     * unless unit testing.
-     * @param unitTestMode when true, prevents notifications
-     * of state change events
-     */
-    protected PhoneBase(PhoneNotifier notifier, Context context, CommandsInterface ci,
-            boolean unitTestMode) {
-        this.mNotifier = notifier;
-        this.mContext = context;
-        mLooper = Looper.myLooper();
-        mCM = ci;
-
-        setPropertiesByCarrier();
-
-        setUnitTestMode(unitTestMode);
-
-        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
-        mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false);
-        mCM.setOnCallRing(this, EVENT_CALL_RING, null);
-
-        /* "Voice capable" means that this device supports circuit-switched
-        * (i.e. voice) phone calls over the telephony network, and is allowed
-        * to display the in-call UI while a cellular voice call is active.
-        * This will be false on "data only" devices which can't make voice
-        * calls and don't support any in-call UI.
-        */
-        mIsVoiceCapable = mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_voice_capable);
-
-        /**
-         *  Some RIL's don't always send RIL_UNSOL_CALL_RING so it needs
-         *  to be generated locally. Ideally all ring tones should be loops
-         * and this wouldn't be necessary. But to minimize changes to upper
-         * layers it is requested that it be generated by lower layers.
-         *
-         * By default old phones won't have the property set but do generate
-         * the RIL_UNSOL_CALL_RING so the default if there is no property is
-         * true.
-         */
-        mDoesRilSendMultipleCallRing = SystemProperties.getBoolean(
-                TelephonyProperties.PROPERTY_RIL_SENDS_MULTIPLE_CALL_RING, true);
-        Log.d(LOG_TAG, "mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
-
-        mCallRingDelay = SystemProperties.getInt(
-                TelephonyProperties.PROPERTY_CALL_RING_DELAY, 3000);
-        Log.d(LOG_TAG, "mCallRingDelay=" + mCallRingDelay);
-
-        // Initialize device storage and outgoing SMS usage monitors for SMSDispatchers.
-        mSmsStorageMonitor = new SmsStorageMonitor(this);
-        mSmsUsageMonitor = new SmsUsageMonitor(context);
-    }
-
-    public void dispose() {
-        synchronized(PhoneProxy.lockForRadioTechnologyChange) {
-            mCM.unSetOnCallRing(this);
-            // Must cleanup all connectionS and needs to use sendMessage!
-            mDataConnectionTracker.cleanUpAllConnections(null);
-            mIsTheCurrentActivePhone = false;
-            // Dispose the SMS usage and storage monitors
-            mSmsStorageMonitor.dispose();
-            mSmsUsageMonitor.dispose();
-        }
-    }
-
-    public void removeReferences() {
-        mSmsStorageMonitor = null;
-        mSmsUsageMonitor = null;
-        mSMS = null;
-        mIccRecords = null;
-        mIccCard.set(null);
-        mDataConnectionTracker = null;
-    }
-
-    /**
-     * When overridden the derived class needs to call
-     * super.handleMessage(msg) so this method has a
-     * a chance to process the message.
-     *
-     * @param msg
-     */
-    @Override
-    public void handleMessage(Message msg) {
-        AsyncResult ar;
-
-        switch(msg.what) {
-            case EVENT_CALL_RING:
-                Log.d(LOG_TAG, "Event EVENT_CALL_RING Received state=" + getState());
-                ar = (AsyncResult)msg.obj;
-                if (ar.exception == null) {
-                    Phone.State state = getState();
-                    if ((!mDoesRilSendMultipleCallRing)
-                            && ((state == Phone.State.RINGING) || (state == Phone.State.IDLE))) {
-                        mCallRingContinueToken += 1;
-                        sendIncomingCallRingNotification(mCallRingContinueToken);
-                    } else {
-                        notifyIncomingRing();
-                    }
-                }
-                break;
-
-            case EVENT_CALL_RING_CONTINUE:
-                Log.d(LOG_TAG, "Event EVENT_CALL_RING_CONTINUE Received stat=" + getState());
-                if (getState() == Phone.State.RINGING) {
-                    sendIncomingCallRingNotification(msg.arg1);
-                }
-                break;
-
-            default:
-                throw new RuntimeException("unexpected event not handled");
-        }
-    }
-
-    // Inherited documentation suffices.
-    public Context getContext() {
-        return mContext;
-    }
-
-    /**
-     * Disables the DNS check (i.e., allows "0.0.0.0").
-     * Useful for lab testing environment.
-     * @param b true disables the check, false enables.
-     */
-    public void disableDnsCheck(boolean b) {
-        mDnsCheckDisabled = b;
-        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
-        SharedPreferences.Editor editor = sp.edit();
-        editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b);
-        editor.apply();
-    }
-
-    /**
-     * Returns true if the DNS check is currently disabled.
-     */
-    public boolean isDnsCheckDisabled() {
-        return mDnsCheckDisabled;
-    }
-
-    // Inherited documentation suffices.
-    public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) {
-        checkCorrectThread(h);
-
-        mPreciseCallStateRegistrants.addUnique(h, what, obj);
-    }
-
-    // Inherited documentation suffices.
-    public void unregisterForPreciseCallStateChanged(Handler h) {
-        mPreciseCallStateRegistrants.remove(h);
-    }
-
-    /**
-     * Subclasses of Phone probably want to replace this with a
-     * version scoped to their packages
-     */
-    protected void notifyPreciseCallStateChangedP() {
-        AsyncResult ar = new AsyncResult(null, this, null);
-        mPreciseCallStateRegistrants.notifyRegistrants(ar);
-    }
-
-    // Inherited documentation suffices.
-    public void registerForUnknownConnection(Handler h, int what, Object obj) {
-        checkCorrectThread(h);
-
-        mUnknownConnectionRegistrants.addUnique(h, what, obj);
-    }
-
-    // Inherited documentation suffices.
-    public void unregisterForUnknownConnection(Handler h) {
-        mUnknownConnectionRegistrants.remove(h);
-    }
-
-    // Inherited documentation suffices.
-    public void registerForNewRingingConnection(
-            Handler h, int what, Object obj) {
-        checkCorrectThread(h);
-
-        mNewRingingConnectionRegistrants.addUnique(h, what, obj);
-    }
-
-    // Inherited documentation suffices.
-    public void unregisterForNewRingingConnection(Handler h) {
-        mNewRingingConnectionRegistrants.remove(h);
-    }
-
-    // Inherited documentation suffices.
-    public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){
-        mCM.registerForInCallVoicePrivacyOn(h,what,obj);
-    }
-
-    // Inherited documentation suffices.
-    public void unregisterForInCallVoicePrivacyOn(Handler h){
-        mCM.unregisterForInCallVoicePrivacyOn(h);
-    }
-
-    // Inherited documentation suffices.
-    public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){
-        mCM.registerForInCallVoicePrivacyOff(h,what,obj);
-    }
-
-    // Inherited documentation suffices.
-    public void unregisterForInCallVoicePrivacyOff(Handler h){
-        mCM.unregisterForInCallVoicePrivacyOff(h);
-    }
-
-    // Inherited documentation suffices.
-    public void registerForIncomingRing(
-            Handler h, int what, Object obj) {
-        checkCorrectThread(h);
-
-        mIncomingRingRegistrants.addUnique(h, what, obj);
-    }
-
-    // Inherited documentation suffices.
-    public void unregisterForIncomingRing(Handler h) {
-        mIncomingRingRegistrants.remove(h);
-    }
-
-    // Inherited documentation suffices.
-    public void registerForDisconnect(Handler h, int what, Object obj) {
-        checkCorrectThread(h);
-
-        mDisconnectRegistrants.addUnique(h, what, obj);
-    }
-
-    // Inherited documentation suffices.
-    public void unregisterForDisconnect(Handler h) {
-        mDisconnectRegistrants.remove(h);
-    }
-
-    // Inherited documentation suffices.
-    public void registerForSuppServiceFailed(Handler h, int what, Object obj) {
-        checkCorrectThread(h);
-
-        mSuppServiceFailedRegistrants.addUnique(h, what, obj);
-    }
-
-    // Inherited documentation suffices.
-    public void unregisterForSuppServiceFailed(Handler h) {
-        mSuppServiceFailedRegistrants.remove(h);
-    }
-
-    // Inherited documentation suffices.
-    public void registerForMmiInitiate(Handler h, int what, Object obj) {
-        checkCorrectThread(h);
-
-        mMmiRegistrants.addUnique(h, what, obj);
-    }
-
-    // Inherited documentation suffices.
-    public void unregisterForMmiInitiate(Handler h) {
-        mMmiRegistrants.remove(h);
-    }
-
-    // Inherited documentation suffices.
-    public void registerForMmiComplete(Handler h, int what, Object obj) {
-        checkCorrectThread(h);
-
-        mMmiCompleteRegistrants.addUnique(h, what, obj);
-    }
-
-    // Inherited documentation suffices.
-    public void unregisterForMmiComplete(Handler h) {
-        checkCorrectThread(h);
-
-        mMmiCompleteRegistrants.remove(h);
-    }
-
-    /**
-     * Method to retrieve the saved operator id from the Shared Preferences
-     */
-    private String getSavedNetworkSelection() {
-        // open the shared preferences and search with our key.
-        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
-        return sp.getString(NETWORK_SELECTION_KEY, "");
-    }
-
-    /**
-     * Method to restore the previously saved operator id, or reset to
-     * automatic selection, all depending upon the value in the shared
-     * preferences.
-     */
-    public void restoreSavedNetworkSelection(Message response) {
-        // retrieve the operator id
-        String networkSelection = getSavedNetworkSelection();
-
-        // set to auto if the id is empty, otherwise select the network.
-        if (TextUtils.isEmpty(networkSelection)) {
-            mCM.setNetworkSelectionModeAutomatic(response);
-        } else {
-            mCM.setNetworkSelectionModeManual(networkSelection, response);
-        }
-    }
-
-    // Inherited documentation suffices.
-    public void setUnitTestMode(boolean f) {
-        mUnitTestMode = f;
-    }
-
-    // Inherited documentation suffices.
-    public boolean getUnitTestMode() {
-        return mUnitTestMode;
-    }
-
-    /**
-     * To be invoked when a voice call Connection disconnects.
-     *
-     * Subclasses of Phone probably want to replace this with a
-     * version scoped to their packages
-     */
-    protected void notifyDisconnectP(Connection cn) {
-        AsyncResult ar = new AsyncResult(null, cn, null);
-        mDisconnectRegistrants.notifyRegistrants(ar);
-    }
-
-    // Inherited documentation suffices.
-    public void registerForServiceStateChanged(
-            Handler h, int what, Object obj) {
-        checkCorrectThread(h);
-
-        mServiceStateRegistrants.add(h, what, obj);
-    }
-
-    // Inherited documentation suffices.
-    public void unregisterForServiceStateChanged(Handler h) {
-        mServiceStateRegistrants.remove(h);
-    }
-
-    // Inherited documentation suffices.
-    public void registerForRingbackTone(Handler h, int what, Object obj) {
-        mCM.registerForRingbackTone(h,what,obj);
-    }
-
-    // Inherited documentation suffices.
-    public void unregisterForRingbackTone(Handler h) {
-        mCM.unregisterForRingbackTone(h);
-    }
-
-    // Inherited documentation suffices.
-    public void registerForResendIncallMute(Handler h, int what, Object obj) {
-        mCM.registerForResendIncallMute(h,what,obj);
-    }
-
-    // Inherited documentation suffices.
-    public void unregisterForResendIncallMute(Handler h) {
-        mCM.unregisterForResendIncallMute(h);
-    }
-
-    public void setEchoSuppressionEnabled(boolean enabled) {
-        // no need for regular phone
-    }
-
-    /**
-     * Subclasses of Phone probably want to replace this with a
-     * version scoped to their packages
-     */
-    protected void notifyServiceStateChangedP(ServiceState ss) {
-        AsyncResult ar = new AsyncResult(null, ss, null);
-        mServiceStateRegistrants.notifyRegistrants(ar);
-
-        mNotifier.notifyServiceState(this);
-    }
-
-    // Inherited documentation suffices.
-    public SimulatedRadioControl getSimulatedRadioControl() {
-        return mSimulatedRadioControl;
-    }
-
-    /**
-     * Verifies the current thread is the same as the thread originally
-     * used in the initialization of this instance. Throws RuntimeException
-     * if not.
-     *
-     * @exception RuntimeException if the current thread is not
-     * the thread that originally obtained this PhoneBase instance.
-     */
-    private void checkCorrectThread(Handler h) {
-        if (h.getLooper() != mLooper) {
-            throw new RuntimeException(
-                    "com.android.internal.telephony.Phone must be used from within one thread");
-        }
-    }
-
-    /**
-     * Set the properties by matching the carrier string in
-     * a string-array resource
-     */
-    private void setPropertiesByCarrier() {
-        String carrier = SystemProperties.get("ro.carrier");
-
-        if (null == carrier || 0 == carrier.length() || "unknown".equals(carrier)) {
-            return;
-        }
-
-        CharSequence[] carrierLocales = mContext.
-                getResources().getTextArray(R.array.carrier_properties);
-
-        for (int i = 0; i < carrierLocales.length; i+=3) {
-            String c = carrierLocales[i].toString();
-            if (carrier.equals(c)) {
-                String l = carrierLocales[i+1].toString();
-
-                String language = l.substring(0, 2);
-                String country = "";
-                if (l.length() >=5) {
-                    country = l.substring(3, 5);
-                }
-                MccTable.setSystemLocale(mContext, language, country);
-
-                if (!country.isEmpty()) {
-                    try {
-                        Settings.Secure.getInt(mContext.getContentResolver(),
-                                Settings.Secure.WIFI_COUNTRY_CODE);
-                    } catch (Settings.SettingNotFoundException e) {
-                        // note this is not persisting
-                        WifiManager wM = (WifiManager)
-                                mContext.getSystemService(Context.WIFI_SERVICE);
-                        wM.setCountryCode(country, false);
-                    }
-                }
-                return;
-            }
-        }
-    }
-
-    /**
-     * Get state
-     */
-    public abstract Phone.State getState();
-
-    /**
-     * Retrieves the IccFileHandler of the Phone instance
-     */
-    public IccFileHandler getIccFileHandler(){
-        IccCard iccCard = mIccCard.get();
-        if (iccCard == null) return null;
-        return iccCard.getIccFileHandler();
-    }
-
-    /*
-     * Retrieves the Handler of the Phone instance
-     */
-    public Handler getHandler() {
-        return this;
-    }
-
-    /**
-    * Retrieves the ServiceStateTracker of the phone instance.
-    */
-    public ServiceStateTracker getServiceStateTracker() {
-        return null;
-    }
-
-    /**
-    * Get call tracker
-    */
-    public CallTracker getCallTracker() {
-        return null;
-    }
-
-    @Override
-    public IccCard getIccCard() {
-        return mIccCard.get();
-    }
-
-    @Override
-    public String getIccSerialNumber() {
-        return mIccRecords.iccid;
-    }
-
-    @Override
-    public boolean getIccRecordsLoaded() {
-        return mIccRecords.getRecordsLoaded();
-    }
-
-    @Override
-    public boolean getMessageWaitingIndicator() {
-        return mIccRecords.getVoiceMessageWaiting();
-    }
-
-    @Override
-    public boolean getCallForwardingIndicator() {
-        return mIccRecords.getVoiceCallForwardingFlag();
-    }
-
-    /**
-     *  Query the status of the CDMA roaming preference
-     */
-    public void queryCdmaRoamingPreference(Message response) {
-        mCM.queryCdmaRoamingPreference(response);
-    }
-
-    /**
-     *  Set the status of the CDMA roaming preference
-     */
-    public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
-        mCM.setCdmaRoamingPreference(cdmaRoamingType, response);
-    }
-
-    /**
-     *  Set the status of the CDMA subscription mode
-     */
-    public void setCdmaSubscription(int cdmaSubscriptionType, Message response) {
-        mCM.setCdmaSubscriptionSource(cdmaSubscriptionType, response);
-    }
-
-    /**
-     *  Set the preferred Network Type: Global, CDMA only or GSM/UMTS only
-     */
-    public void setPreferredNetworkType(int networkType, Message response) {
-        mCM.setPreferredNetworkType(networkType, response);
-    }
-
-    public void getPreferredNetworkType(Message response) {
-        mCM.getPreferredNetworkType(response);
-    }
-
-    public void getSmscAddress(Message result) {
-        mCM.getSmscAddress(result);
-    }
-
-    public void setSmscAddress(String address, Message result) {
-        mCM.setSmscAddress(address, result);
-    }
-
-    public void setTTYMode(int ttyMode, Message onComplete) {
-        mCM.setTTYMode(ttyMode, onComplete);
-    }
-
-    public void queryTTYMode(Message onComplete) {
-        mCM.queryTTYMode(onComplete);
-    }
-
-    public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) {
-        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
-        logUnexpectedCdmaMethodCall("enableEnhancedVoicePrivacy");
-    }
-
-    public void getEnhancedVoicePrivacy(Message onComplete) {
-        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
-        logUnexpectedCdmaMethodCall("getEnhancedVoicePrivacy");
-    }
-
-    public void setBandMode(int bandMode, Message response) {
-        mCM.setBandMode(bandMode, response);
-    }
-
-    public void queryAvailableBandMode(Message response) {
-        mCM.queryAvailableBandMode(response);
-    }
-
-    public void invokeOemRilRequestRaw(byte[] data, Message response) {
-        mCM.invokeOemRilRequestRaw(data, response);
-    }
-
-    public void invokeOemRilRequestStrings(String[] strings, Message response) {
-        mCM.invokeOemRilRequestStrings(strings, response);
-    }
-
-    public void notifyDataActivity() {
-        mNotifier.notifyDataActivity(this);
-    }
-
-    public void notifyMessageWaitingIndicator() {
-        // Do not notify voice mail waiting if device doesn't support voice
-        if (!mIsVoiceCapable)
-            return;
-
-        // This function is added to send the notification to DefaultPhoneNotifier.
-        mNotifier.notifyMessageWaitingChanged(this);
-    }
-
-    public void notifyDataConnection(String reason, String apnType,
-            Phone.DataState state) {
-        mNotifier.notifyDataConnection(this, reason, apnType, state);
-    }
-
-    public void notifyDataConnection(String reason, String apnType) {
-        mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType));
-    }
-
-    public void notifyDataConnection(String reason) {
-        String types[] = getActiveApnTypes();
-        for (String apnType : types) {
-            mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType));
-        }
-    }
-
-    public void notifyOtaspChanged(int otaspMode) {
-        mNotifier.notifyOtaspChanged(this, otaspMode);
-    }
-
-    /**
-     * @return true if a mobile originating emergency call is active
-     */
-    public boolean isInEmergencyCall() {
-        return false;
-    }
-
-    /**
-     * @return true if we are in the emergency call back mode. This is a period where
-     * the phone should be using as little power as possible and be ready to receive an
-     * incoming call from the emergency operator.
-     */
-    public boolean isInEcm() {
-        return false;
-    }
-
-    public abstract String getPhoneName();
-
-    public abstract int getPhoneType();
-
-    /** @hide */
-    public int getVoiceMessageCount(){
-        return 0;
-    }
-
-    /**
-     * Returns the CDMA ERI icon index to display
-     */
-    public int getCdmaEriIconIndex() {
-        logUnexpectedCdmaMethodCall("getCdmaEriIconIndex");
-        return -1;
-    }
-
-    /**
-     * Returns the CDMA ERI icon mode,
-     * 0 - ON
-     * 1 - FLASHING
-     */
-    public int getCdmaEriIconMode() {
-        logUnexpectedCdmaMethodCall("getCdmaEriIconMode");
-        return -1;
-    }
-
-    /**
-     * Returns the CDMA ERI text,
-     */
-    public String getCdmaEriText() {
-        logUnexpectedCdmaMethodCall("getCdmaEriText");
-        return "GSM nw, no ERI";
-    }
-
-    public String getCdmaMin() {
-        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
-        logUnexpectedCdmaMethodCall("getCdmaMin");
-        return null;
-    }
-
-    public boolean isMinInfoReady() {
-        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
-        logUnexpectedCdmaMethodCall("isMinInfoReady");
-        return false;
-    }
-
-    public String getCdmaPrlVersion(){
-        //  This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
-        logUnexpectedCdmaMethodCall("getCdmaPrlVersion");
-        return null;
-    }
-
-    public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) {
-        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
-        logUnexpectedCdmaMethodCall("sendBurstDtmf");
-    }
-
-    public void exitEmergencyCallbackMode() {
-        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
-        logUnexpectedCdmaMethodCall("exitEmergencyCallbackMode");
-    }
-
-    public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) {
-        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
-        logUnexpectedCdmaMethodCall("registerForCdmaOtaStatusChange");
-    }
-
-    public void unregisterForCdmaOtaStatusChange(Handler h) {
-        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
-        logUnexpectedCdmaMethodCall("unregisterForCdmaOtaStatusChange");
-    }
-
-    public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
-        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
-        logUnexpectedCdmaMethodCall("registerForSubscriptionInfoReady");
-    }
-
-    public void unregisterForSubscriptionInfoReady(Handler h) {
-        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
-        logUnexpectedCdmaMethodCall("unregisterForSubscriptionInfoReady");
-    }
-
-    /**
-     * Returns true if OTA Service Provisioning needs to be performed.
-     * If not overridden return false.
-     */
-    public boolean needsOtaServiceProvisioning() {
-        return false;
-    }
-
-    /**
-     * Return true if number is an OTASP number.
-     * If not overridden return false.
-     */
-    public  boolean isOtaSpNumber(String dialStr) {
-        return false;
-    }
-
-    public void registerForCallWaiting(Handler h, int what, Object obj){
-        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
-        logUnexpectedCdmaMethodCall("registerForCallWaiting");
-    }
-
-    public void unregisterForCallWaiting(Handler h){
-        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
-        logUnexpectedCdmaMethodCall("unregisterForCallWaiting");
-    }
-
-    public void registerForEcmTimerReset(Handler h, int what, Object obj) {
-        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
-        logUnexpectedCdmaMethodCall("registerForEcmTimerReset");
-    }
-
-    public void unregisterForEcmTimerReset(Handler h) {
-        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
-        logUnexpectedCdmaMethodCall("unregisterForEcmTimerReset");
-    }
-
-    public void registerForSignalInfo(Handler h, int what, Object obj) {
-        mCM.registerForSignalInfo(h, what, obj);
-    }
-
-    public void unregisterForSignalInfo(Handler h) {
-        mCM.unregisterForSignalInfo(h);
-    }
-
-    public void registerForDisplayInfo(Handler h, int what, Object obj) {
-        mCM.registerForDisplayInfo(h, what, obj);
-    }
-
-     public void unregisterForDisplayInfo(Handler h) {
-         mCM.unregisterForDisplayInfo(h);
-     }
-
-    public void registerForNumberInfo(Handler h, int what, Object obj) {
-        mCM.registerForNumberInfo(h, what, obj);
-    }
-
-    public void unregisterForNumberInfo(Handler h) {
-        mCM.unregisterForNumberInfo(h);
-    }
-
-    public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) {
-        mCM.registerForRedirectedNumberInfo(h, what, obj);
-    }
-
-    public void unregisterForRedirectedNumberInfo(Handler h) {
-        mCM.unregisterForRedirectedNumberInfo(h);
-    }
-
-    public void registerForLineControlInfo(Handler h, int what, Object obj) {
-        mCM.registerForLineControlInfo( h, what, obj);
-    }
-
-    public void unregisterForLineControlInfo(Handler h) {
-        mCM.unregisterForLineControlInfo(h);
-    }
-
-    public void registerFoT53ClirlInfo(Handler h, int what, Object obj) {
-        mCM.registerFoT53ClirlInfo(h, what, obj);
-    }
-
-    public void unregisterForT53ClirInfo(Handler h) {
-        mCM.unregisterForT53ClirInfo(h);
-    }
-
-    public void registerForT53AudioControlInfo(Handler h, int what, Object obj) {
-        mCM.registerForT53AudioControlInfo( h, what, obj);
-    }
-
-    public void unregisterForT53AudioControlInfo(Handler h) {
-        mCM.unregisterForT53AudioControlInfo(h);
-    }
-
-     public void setOnEcbModeExitResponse(Handler h, int what, Object obj){
-         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
-         logUnexpectedCdmaMethodCall("setOnEcbModeExitResponse");
-     }
-
-     public void unsetOnEcbModeExitResponse(Handler h){
-        // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
-         logUnexpectedCdmaMethodCall("unsetOnEcbModeExitResponse");
-     }
-
-    public String[] getActiveApnTypes() {
-        return mDataConnectionTracker.getActiveApnTypes();
-    }
-
-    public String getActiveApnHost(String apnType) {
-        return mDataConnectionTracker.getActiveApnString(apnType);
-    }
-
-    public LinkProperties getLinkProperties(String apnType) {
-        return mDataConnectionTracker.getLinkProperties(apnType);
-    }
-
-    public LinkCapabilities getLinkCapabilities(String apnType) {
-        return mDataConnectionTracker.getLinkCapabilities(apnType);
-    }
-
-    public int enableApnType(String type) {
-        return mDataConnectionTracker.enableApnType(type);
-    }
-
-    public int disableApnType(String type) {
-        return mDataConnectionTracker.disableApnType(type);
-    }
-
-    public boolean isDataConnectivityPossible() {
-        return isDataConnectivityPossible(Phone.APN_TYPE_DEFAULT);
-    }
-
-    public boolean isDataConnectivityPossible(String apnType) {
-        return ((mDataConnectionTracker != null) &&
-                (mDataConnectionTracker.isDataPossible(apnType)));
-    }
-
-    /**
-     * Notify registrants of a new ringing Connection.
-     * Subclasses of Phone probably want to replace this with a
-     * version scoped to their packages
-     */
-    protected void notifyNewRingingConnectionP(Connection cn) {
-        if (!mIsVoiceCapable)
-            return;
-        AsyncResult ar = new AsyncResult(null, cn, null);
-        mNewRingingConnectionRegistrants.notifyRegistrants(ar);
-    }
-
-    /**
-     * Notify registrants of a RING event.
-     */
-    private void notifyIncomingRing() {
-        if (!mIsVoiceCapable)
-            return;
-        AsyncResult ar = new AsyncResult(null, this, null);
-        mIncomingRingRegistrants.notifyRegistrants(ar);
-    }
-
-    /**
-     * Send the incoming call Ring notification if conditions are right.
-     */
-    private void sendIncomingCallRingNotification(int token) {
-        if (mIsVoiceCapable && !mDoesRilSendMultipleCallRing &&
-                (token == mCallRingContinueToken)) {
-            Log.d(LOG_TAG, "Sending notifyIncomingRing");
-            notifyIncomingRing();
-            sendMessageDelayed(
-                    obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay);
-        } else {
-            Log.d(LOG_TAG, "Ignoring ring notification request,"
-                    + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing
-                    + " token=" + token
-                    + " mCallRingContinueToken=" + mCallRingContinueToken
-                    + " mIsVoiceCapable=" + mIsVoiceCapable);
-        }
-    }
-
-    public boolean isCspPlmnEnabled() {
-        // This function should be overridden by the class GSMPhone.
-        // Not implemented in CDMAPhone.
-        logUnexpectedGsmMethodCall("isCspPlmnEnabled");
-        return false;
-    }
-
-    public IsimRecords getIsimRecords() {
-        Log.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices");
-        return null;
-    }
-
-    public void requestIsimAuthentication(String nonce, Message result) {
-        Log.e(LOG_TAG, "requestIsimAuthentication() is only supported on LTE devices");
-    }
-
-    public String getMsisdn() {
-        logUnexpectedGsmMethodCall("getMsisdn");
-        return null;
-    }
-
-    /**
-     * Common error logger method for unexpected calls to CDMA-only methods.
-     */
-    private static void logUnexpectedCdmaMethodCall(String name)
-    {
-        Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
-                "called, CDMAPhone inactive.");
-    }
-
-    public DataState getDataConnectionState() {
-        return getDataConnectionState(APN_TYPE_DEFAULT);
-    }
-
-    /**
-     * Common error logger method for unexpected calls to GSM/WCDMA-only methods.
-     */
-    private static void logUnexpectedGsmMethodCall(String name) {
-        Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
-                "called, GSMPhone inactive.");
-    }
-
-    // Called by SimRecords which is constructed with a PhoneBase instead of a GSMPhone.
-    public void notifyCallForwardingIndicator() {
-        // This function should be overridden by the class GSMPhone. Not implemented in CDMAPhone.
-        Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
-    }
-
-    public void notifyDataConnectionFailed(String reason, String apnType) {
-        mNotifier.notifyDataConnectionFailed(this, reason, apnType);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public int getLteOnCdmaMode() {
-        return mCM.getLteOnCdmaMode();
-    }
-
-    /**
-     * Sets the SIM voice message waiting indicator records.
-     * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
-     * @param countWaiting The number of messages waiting, if known. Use
-     *                     -1 to indicate that an unknown number of
-     *                      messages are waiting
-     */
-    @Override
-    public void setVoiceMessageWaiting(int line, int countWaiting) {
-        mIccRecords.setVoiceMessageWaiting(line, countWaiting);
-    }
-
-    /**
-     * Gets the USIM service table from the UICC, if present and available.
-     * @return an interface to the UsimServiceTable record, or null if not available
-     */
-    @Override
-    public UsimServiceTable getUsimServiceTable() {
-        return mIccRecords.getUsimServiceTable();
-    }
-
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("PhoneBase:");
-        pw.println(" mCM=" + mCM);
-        pw.println(" mDnsCheckDisabled=" + mDnsCheckDisabled);
-        pw.println(" mDataConnectionTracker=" + mDataConnectionTracker);
-        pw.println(" mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
-        pw.println(" mCallRingContinueToken=" + mCallRingContinueToken);
-        pw.println(" mCallRingDelay=" + mCallRingDelay);
-        pw.println(" mIsTheCurrentActivePhone=" + mIsTheCurrentActivePhone);
-        pw.println(" mIsVoiceCapable=" + mIsVoiceCapable);
-        pw.println(" mIccRecords=" + mIccRecords);
-        pw.println(" mIccCard=" + mIccCard.get());
-        pw.println(" mSmsStorageMonitor=" + mSmsStorageMonitor);
-        pw.println(" mSmsUsageMonitor=" + mSmsUsageMonitor);
-        pw.println(" mSMS=" + mSMS);
-        pw.flush();
-        pw.println(" mLooper=" + mLooper);
-        pw.println(" mContext=" + mContext);
-        pw.println(" mNotifier=" + mNotifier);
-        pw.println(" mSimulatedRadioControl=" + mSimulatedRadioControl);
-        pw.println(" mUnitTestMode=" + mUnitTestMode);
-        pw.println(" isDnsCheckDisabled()=" + isDnsCheckDisabled());
-        pw.println(" getUnitTestMode()=" + getUnitTestMode());
-        pw.println(" getState()=" + getState());
-        pw.println(" getIccSerialNumber()=" + getIccSerialNumber());
-        pw.println(" getIccRecordsLoaded()=" + getIccRecordsLoaded());
-        pw.println(" getMessageWaitingIndicator()=" + getMessageWaitingIndicator());
-        pw.println(" getCallForwardingIndicator()=" + getCallForwardingIndicator());
-        pw.println(" isInEmergencyCall()=" + isInEmergencyCall());
-        pw.flush();
-        pw.println(" isInEcm()=" + isInEcm());
-        pw.println(" getPhoneName()=" + getPhoneName());
-        pw.println(" getPhoneType()=" + getPhoneType());
-        pw.println(" getVoiceMessageCount()=" + getVoiceMessageCount());
-        pw.println(" getActiveApnTypes()=" + getActiveApnTypes());
-        pw.println(" isDataConnectivityPossible()=" + isDataConnectivityPossible());
-        pw.println(" needsOtaServiceProvisioning=" + needsOtaServiceProvisioning());
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java
new file mode 100644
index 0000000..16ea625
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2012 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.internal.telephony;
+
+/**
+ * @hide
+ */
+public class PhoneConstants {
+
+    /**
+     * The phone state. One of the following:<p>
+     * <ul>
+     * <li>IDLE = no phone activity</li>
+     * <li>RINGING = a phone call is ringing or call waiting.
+     *  In the latter case, another call is active as well</li>
+     * <li>OFFHOOK = The phone is off hook. At least one call
+     * exists that is dialing, active or holding and no calls are
+     * ringing or waiting.</li>
+     * </ul>
+     */
+    public enum State {
+        IDLE, RINGING, OFFHOOK;
+    };
+
+   /**
+     * The state of a data connection.
+     * <ul>
+     * <li>CONNECTED = IP traffic should be available</li>
+     * <li>CONNECTING = Currently setting up data connection</li>
+     * <li>DISCONNECTED = IP not available</li>
+     * <li>SUSPENDED = connection is created but IP traffic is
+     *                 temperately not available. i.e. voice call is in place
+     *                 in 2G network</li>
+     * </ul>
+     */
+    public enum DataState {
+        CONNECTED, CONNECTING, DISCONNECTED, SUSPENDED;
+    };
+
+    public static final String STATE_KEY = "state";
+
+    // Radio Type
+    public static final int PHONE_TYPE_NONE = RILConstants.NO_PHONE;
+    public static final int PHONE_TYPE_GSM = RILConstants.GSM_PHONE;
+    public static final int PHONE_TYPE_CDMA = RILConstants.CDMA_PHONE;
+    public static final int PHONE_TYPE_SIP = RILConstants.SIP_PHONE;
+
+    // Modes for LTE_ON_CDMA
+    public static final int LTE_ON_CDMA_UNKNOWN = RILConstants.LTE_ON_CDMA_UNKNOWN;
+    public static final int LTE_ON_CDMA_FALSE = RILConstants.LTE_ON_CDMA_FALSE;
+    public static final int LTE_ON_CDMA_TRUE = RILConstants.LTE_ON_CDMA_TRUE;
+
+    // Number presentation type for caller id display (From internal/Conneciton.java)
+    public static int PRESENTATION_ALLOWED = 1;    // normal
+    public static int PRESENTATION_RESTRICTED = 2; // block by user
+    public static int PRESENTATION_UNKNOWN = 3;    // no specified or unknown by network
+    public static int PRESENTATION_PAYPHONE = 4;   // show pay phone info
+
+
+    public static final String PHONE_NAME_KEY = "phoneName";
+    public static final String FAILURE_REASON_KEY = "reason";
+    public static final String STATE_CHANGE_REASON_KEY = "reason";
+    public static final String DATA_APN_TYPE_KEY = "apnType";
+    public static final String DATA_APN_KEY = "apn";
+    public static final String DATA_LINK_PROPERTIES_KEY = "linkProperties";
+    public static final String DATA_LINK_CAPABILITIES_KEY = "linkCapabilities";
+
+    public static final String DATA_IFACE_NAME_KEY = "iface";
+    public static final String NETWORK_UNAVAILABLE_KEY = "networkUnvailable";
+    public static final String DATA_NETWORK_ROAMING_KEY = "networkRoaming";
+    public static final String PHONE_IN_ECM_STATE = "phoneinECMState";
+
+    public static final String REASON_LINK_PROPERTIES_CHANGED = "linkPropertiesChanged";
+
+    /**
+     * Return codes for <code>enableApnType()</code>
+     */
+    public static final int APN_ALREADY_ACTIVE     = 0;
+    public static final int APN_REQUEST_STARTED    = 1;
+    public static final int APN_TYPE_NOT_AVAILABLE = 2;
+    public static final int APN_REQUEST_FAILED     = 3;
+    public static final int APN_ALREADY_INACTIVE   = 4;
+
+    /**
+     * APN types for data connections.  These are usage categories for an APN
+     * entry.  One APN entry may support multiple APN types, eg, a single APN
+     * may service regular internet traffic ("default") as well as MMS-specific
+     * connections.<br/>
+     * APN_TYPE_ALL is a special type to indicate that this APN entry can
+     * service all data connections.
+     */
+    public static final String APN_TYPE_ALL = "*";
+    /** APN type for default data traffic */
+    public static final String APN_TYPE_DEFAULT = "default";
+    /** APN type for MMS traffic */
+    public static final String APN_TYPE_MMS = "mms";
+    /** APN type for SUPL assisted GPS */
+    public static final String APN_TYPE_SUPL = "supl";
+    /** APN type for DUN traffic */
+    public static final String APN_TYPE_DUN = "dun";
+    /** APN type for HiPri traffic */
+    public static final String APN_TYPE_HIPRI = "hipri";
+    /** APN type for FOTA */
+    public static final String APN_TYPE_FOTA = "fota";
+    /** APN type for IMS */
+    public static final String APN_TYPE_IMS = "ims";
+    /** APN type for CBS */
+    public static final String APN_TYPE_CBS = "cbs";
+
+}
diff --git a/telephony/java/com/android/internal/telephony/PhoneFactory.java b/telephony/java/com/android/internal/telephony/PhoneFactory.java
deleted file mode 100644
index f495d7e..0000000
--- a/telephony/java/com/android/internal/telephony/PhoneFactory.java
+++ /dev/null
@@ -1,249 +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.internal.telephony;
-
-import android.content.Context;
-import android.net.LocalServerSocket;
-import android.os.Looper;
-import android.provider.Settings;
-import android.util.Log;
-import android.os.SystemProperties;
-
-import com.android.internal.telephony.cdma.CDMAPhone;
-import com.android.internal.telephony.cdma.CDMALTEPhone;
-import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
-import com.android.internal.telephony.gsm.GSMPhone;
-import com.android.internal.telephony.sip.SipPhone;
-import com.android.internal.telephony.sip.SipPhoneFactory;
-
-/**
- * {@hide}
- */
-public class PhoneFactory {
-    static final String LOG_TAG = "PHONE";
-    static final int SOCKET_OPEN_RETRY_MILLIS = 2 * 1000;
-    static final int SOCKET_OPEN_MAX_RETRY = 3;
-
-    //***** Class Variables
-
-    static private Phone sProxyPhone = null;
-    static private CommandsInterface sCommandsInterface = null;
-
-    static private boolean sMadeDefaults = false;
-    static private PhoneNotifier sPhoneNotifier;
-    static private Looper sLooper;
-    static private Context sContext;
-
-    static final int preferredCdmaSubscription =
-                         CdmaSubscriptionSourceManager.PREFERRED_CDMA_SUBSCRIPTION;
-
-    //***** Class Methods
-
-    public static void makeDefaultPhones(Context context) {
-        makeDefaultPhone(context);
-    }
-
-    /**
-     * FIXME replace this with some other way of making these
-     * instances
-     */
-    public static void makeDefaultPhone(Context context) {
-        synchronized(Phone.class) {
-            if (!sMadeDefaults) {
-                sLooper = Looper.myLooper();
-                sContext = context;
-
-                if (sLooper == null) {
-                    throw new RuntimeException(
-                        "PhoneFactory.makeDefaultPhone must be called from Looper thread");
-                }
-
-                int retryCount = 0;
-                for(;;) {
-                    boolean hasException = false;
-                    retryCount ++;
-
-                    try {
-                        // use UNIX domain socket to
-                        // prevent subsequent initialization
-                        new LocalServerSocket("com.android.internal.telephony");
-                    } catch (java.io.IOException ex) {
-                        hasException = true;
-                    }
-
-                    if ( !hasException ) {
-                        break;
-                    } else if (retryCount > SOCKET_OPEN_MAX_RETRY) {
-                        throw new RuntimeException("PhoneFactory probably already running");
-                    } else {
-                        try {
-                            Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);
-                        } catch (InterruptedException er) {
-                        }
-                    }
-                }
-
-                sPhoneNotifier = new DefaultPhoneNotifier();
-
-                // Get preferred network mode
-                int preferredNetworkMode = RILConstants.PREFERRED_NETWORK_MODE;
-                if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) {
-                    preferredNetworkMode = Phone.NT_MODE_GLOBAL;
-                }
-                int networkMode = Settings.Secure.getInt(context.getContentResolver(),
-                        Settings.Secure.PREFERRED_NETWORK_MODE, preferredNetworkMode);
-                Log.i(LOG_TAG, "Network Mode set to " + Integer.toString(networkMode));
-
-                // Get cdmaSubscription
-                // TODO: Change when the ril will provides a way to know at runtime
-                //       the configuration, bug 4202572. And the ril issues the
-                //       RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, bug 4295439.
-                int cdmaSubscription;
-                int lteOnCdma = BaseCommands.getLteOnCdmaModeStatic();
-                switch (lteOnCdma) {
-                    case Phone.LTE_ON_CDMA_FALSE:
-                        cdmaSubscription = CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_NV;
-                        Log.i(LOG_TAG, "lteOnCdma is 0 use SUBSCRIPTION_FROM_NV");
-                        break;
-                    case Phone.LTE_ON_CDMA_TRUE:
-                        cdmaSubscription = CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM;
-                        Log.i(LOG_TAG, "lteOnCdma is 1 use SUBSCRIPTION_FROM_RUIM");
-                        break;
-                    case Phone.LTE_ON_CDMA_UNKNOWN:
-                    default:
-                        //Get cdmaSubscription mode from Settings.System
-                        cdmaSubscription = Settings.Secure.getInt(context.getContentResolver(),
-                                Settings.Secure.PREFERRED_CDMA_SUBSCRIPTION,
-                                preferredCdmaSubscription);
-                        Log.i(LOG_TAG, "lteOnCdma not set, using PREFERRED_CDMA_SUBSCRIPTION");
-                        break;
-                }
-                Log.i(LOG_TAG, "Cdma Subscription set to " + cdmaSubscription);
-
-                //reads the system properties and makes commandsinterface
-                sCommandsInterface = new RIL(context, networkMode, cdmaSubscription);
-
-                int phoneType = getPhoneType(networkMode);
-                if (phoneType == Phone.PHONE_TYPE_GSM) {
-                    Log.i(LOG_TAG, "Creating GSMPhone");
-                    sProxyPhone = new PhoneProxy(new GSMPhone(context,
-                            sCommandsInterface, sPhoneNotifier));
-                } else if (phoneType == Phone.PHONE_TYPE_CDMA) {
-                    switch (BaseCommands.getLteOnCdmaModeStatic()) {
-                        case Phone.LTE_ON_CDMA_TRUE:
-                            Log.i(LOG_TAG, "Creating CDMALTEPhone");
-                            sProxyPhone = new PhoneProxy(new CDMALTEPhone(context,
-                                sCommandsInterface, sPhoneNotifier));
-                            break;
-                        case Phone.LTE_ON_CDMA_FALSE:
-                        default:
-                            Log.i(LOG_TAG, "Creating CDMAPhone");
-                            sProxyPhone = new PhoneProxy(new CDMAPhone(context,
-                                    sCommandsInterface, sPhoneNotifier));
-                            break;
-                    }
-                }
-
-                sMadeDefaults = true;
-            }
-        }
-    }
-
-    /*
-     * This function returns the type of the phone, depending
-     * on the network mode.
-     *
-     * @param network mode
-     * @return Phone Type
-     */
-    public static int getPhoneType(int networkMode) {
-        switch(networkMode) {
-        case RILConstants.NETWORK_MODE_CDMA:
-        case RILConstants.NETWORK_MODE_CDMA_NO_EVDO:
-        case RILConstants.NETWORK_MODE_EVDO_NO_CDMA:
-            return Phone.PHONE_TYPE_CDMA;
-
-        case RILConstants.NETWORK_MODE_WCDMA_PREF:
-        case RILConstants.NETWORK_MODE_GSM_ONLY:
-        case RILConstants.NETWORK_MODE_WCDMA_ONLY:
-        case RILConstants.NETWORK_MODE_GSM_UMTS:
-            return Phone.PHONE_TYPE_GSM;
-
-        // Use CDMA Phone for the global mode including CDMA
-        case RILConstants.NETWORK_MODE_GLOBAL:
-        case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO:
-        case RILConstants.NETWORK_MODE_LTE_CMDA_EVDO_GSM_WCDMA:
-            return Phone.PHONE_TYPE_CDMA;
-
-        case RILConstants.NETWORK_MODE_LTE_ONLY:
-            if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) {
-                return Phone.PHONE_TYPE_CDMA;
-            } else {
-                return Phone.PHONE_TYPE_GSM;
-            }
-        default:
-            return Phone.PHONE_TYPE_GSM;
-        }
-    }
-
-    public static Phone getDefaultPhone() {
-        if (sLooper != Looper.myLooper()) {
-            throw new RuntimeException(
-                "PhoneFactory.getDefaultPhone must be called from Looper thread");
-        }
-
-        if (!sMadeDefaults) {
-            throw new IllegalStateException("Default phones haven't been made yet!");
-        }
-       return sProxyPhone;
-    }
-
-    public static Phone getCdmaPhone() {
-        Phone phone;
-        synchronized(PhoneProxy.lockForRadioTechnologyChange) {
-            switch (BaseCommands.getLteOnCdmaModeStatic()) {
-                case Phone.LTE_ON_CDMA_TRUE: {
-                    phone = new CDMALTEPhone(sContext, sCommandsInterface, sPhoneNotifier);
-                    break;
-                }
-                case Phone.LTE_ON_CDMA_FALSE:
-                case Phone.LTE_ON_CDMA_UNKNOWN:
-                default: {
-                    phone = new CDMAPhone(sContext, sCommandsInterface, sPhoneNotifier);
-                    break;
-                }
-            }
-        }
-        return phone;
-    }
-
-    public static Phone getGsmPhone() {
-        synchronized(PhoneProxy.lockForRadioTechnologyChange) {
-            Phone phone = new GSMPhone(sContext, sCommandsInterface, sPhoneNotifier);
-            return phone;
-        }
-    }
-
-    /**
-     * Makes a {@link SipPhone} object.
-     * @param sipUri the local SIP URI the phone runs on
-     * @return the {@code SipPhone} object or null if the SIP URI is not valid
-     */
-    public static SipPhone makeSipPhone(String sipUri) {
-        return SipPhoneFactory.makePhone(sipUri, sContext, sPhoneNotifier);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/PhoneNotifier.java b/telephony/java/com/android/internal/telephony/PhoneNotifier.java
deleted file mode 100644
index 1076870..0000000
--- a/telephony/java/com/android/internal/telephony/PhoneNotifier.java
+++ /dev/null
@@ -1,50 +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.internal.telephony;
-
-import android.telephony.CellInfo;
-
-/**
- * {@hide}
- */
-public interface PhoneNotifier {
-
-    public void notifyPhoneState(Phone sender);
-
-    public void notifyServiceState(Phone sender);
-
-    public void notifyCellLocation(Phone sender);
-
-    public void notifySignalStrength(Phone sender);
-
-    public void notifyMessageWaitingChanged(Phone sender);
-
-    public void notifyCallForwardingChanged(Phone sender);
-
-    /** TODO - reason should never be null */
-    public void notifyDataConnection(Phone sender, String reason, String apnType,
-            Phone.DataState state);
-
-    public void notifyDataConnectionFailed(Phone sender, String reason, String apnType);
-
-    public void notifyDataActivity(Phone sender);
-
-    public void notifyOtaspChanged(Phone sender, int otaspMode);
-
-    // TODO - trigger notifyCellInfo from ServiceStateTracker
-    public void notifyCellInfo(Phone sender, CellInfo cellInfo);
-}
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
deleted file mode 100644
index 1a8b3ca..0000000
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ /dev/null
@@ -1,972 +0,0 @@
-/*
- * 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.internal.telephony;
-
-
-import android.app.ActivityManagerNative;
-import android.content.Context;
-import android.content.Intent;
-import android.net.LinkCapabilities;
-import android.net.LinkProperties;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.telephony.CellLocation;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.util.Log;
-
-import com.android.internal.telephony.cdma.CDMAPhone;
-import com.android.internal.telephony.gsm.GSMPhone;
-import com.android.internal.telephony.gsm.UsimServiceTable;
-import com.android.internal.telephony.ims.IsimRecords;
-import com.android.internal.telephony.test.SimulatedRadioControl;
-import com.android.internal.telephony.CallManager;
-
-import java.util.List;
-
-public class PhoneProxy extends Handler implements Phone {
-    public final static Object lockForRadioTechnologyChange = new Object();
-
-    private Phone mActivePhone;
-    private CommandsInterface mCommandsInterface;
-    private IccSmsInterfaceManagerProxy mIccSmsInterfaceManagerProxy;
-    private IccPhoneBookInterfaceManagerProxy mIccPhoneBookInterfaceManagerProxy;
-    private PhoneSubInfoProxy mPhoneSubInfoProxy;
-
-    private boolean mResetModemOnRadioTechnologyChange = false;
-
-    private int mRilVersion;
-
-    private static final int EVENT_VOICE_RADIO_TECH_CHANGED = 1;
-    private static final int EVENT_RADIO_ON = 2;
-    private static final int EVENT_REQUEST_VOICE_RADIO_TECH_DONE = 3;
-    private static final int EVENT_RIL_CONNECTED = 4;
-
-    private static final String LOG_TAG = "PHONE";
-
-    //***** Class Methods
-    public PhoneProxy(Phone phone) {
-        mActivePhone = phone;
-        mResetModemOnRadioTechnologyChange = SystemProperties.getBoolean(
-                TelephonyProperties.PROPERTY_RESET_ON_RADIO_TECH_CHANGE, false);
-        mIccSmsInterfaceManagerProxy = new IccSmsInterfaceManagerProxy(
-                phone.getIccSmsInterfaceManager());
-        mIccPhoneBookInterfaceManagerProxy = new IccPhoneBookInterfaceManagerProxy(
-                phone.getIccPhoneBookInterfaceManager());
-        mPhoneSubInfoProxy = new PhoneSubInfoProxy(phone.getPhoneSubInfo());
-        mCommandsInterface = ((PhoneBase)mActivePhone).mCM;
-
-        mCommandsInterface.registerForRilConnected(this, EVENT_RIL_CONNECTED, null);
-        mCommandsInterface.registerForOn(this, EVENT_RADIO_ON, null);
-        mCommandsInterface.registerForVoiceRadioTechChanged(
-                             this, EVENT_VOICE_RADIO_TECH_CHANGED, null);
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-        AsyncResult ar = (AsyncResult) msg.obj;
-        switch(msg.what) {
-        case EVENT_RADIO_ON:
-            /* Proactively query voice radio technologies */
-            mCommandsInterface.getVoiceRadioTechnology(
-                    this.obtainMessage(EVENT_REQUEST_VOICE_RADIO_TECH_DONE));
-            break;
-
-        case EVENT_RIL_CONNECTED:
-            if (ar.exception == null && ar.result != null) {
-                mRilVersion = (Integer) ar.result;
-            } else {
-                logd("Unexpected exception on EVENT_RIL_CONNECTED");
-                mRilVersion = -1;
-            }
-            break;
-
-        case EVENT_VOICE_RADIO_TECH_CHANGED:
-        case EVENT_REQUEST_VOICE_RADIO_TECH_DONE:
-
-            if (ar.exception == null) {
-                if ((ar.result != null) && (((int[]) ar.result).length != 0)) {
-                    int newVoiceTech = ((int[]) ar.result)[0];
-                    updatePhoneObject(newVoiceTech);
-                } else {
-                    loge("Voice Radio Technology event " + msg.what + " has no tech!");
-                }
-            } else {
-                loge("Voice Radio Technology event " + msg.what + " exception!" + ar.exception);
-            }
-            break;
-
-        default:
-            loge("Error! This handler was not registered for this message type. Message: "
-                    + msg.what);
-            break;
-        }
-        super.handleMessage(msg);
-    }
-
-    private static void logd(String msg) {
-        Log.d(LOG_TAG, "[PhoneProxy] " + msg);
-    }
-
-    private void logw(String msg) {
-        Log.w(LOG_TAG, "[PhoneProxy] " + msg);
-    }
-
-    private void loge(String msg) {
-        Log.e(LOG_TAG, "[PhoneProxy] " + msg);
-    }
-
-    private void updatePhoneObject(int newVoiceRadioTech) {
-
-        if (mActivePhone != null) {
-            if(mRilVersion == 6 && getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE) {
-                /*
-                 * On v6 RIL, when LTE_ON_CDMA is TRUE, always create CDMALTEPhone
-                 * irrespective of the voice radio tech reported.
-                 */
-                if (mActivePhone.getPhoneType() == PHONE_TYPE_CDMA) {
-                    logd("LTE ON CDMA property is set. Use CDMA Phone" +
-                            " newVoiceRadioTech = " + newVoiceRadioTech +
-                            " Active Phone = " + mActivePhone.getPhoneName());
-                    return;
-                } else {
-                    logd("LTE ON CDMA property is set. Switch to CDMALTEPhone" +
-                            " newVoiceRadioTech = " + newVoiceRadioTech +
-                            " Active Phone = " + mActivePhone.getPhoneName());
-                    newVoiceRadioTech = ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT;
-                }
-            } else {
-                if ((ServiceState.isCdma(newVoiceRadioTech) &&
-                        mActivePhone.getPhoneType() == PHONE_TYPE_CDMA) ||
-                        (ServiceState.isGsm(newVoiceRadioTech) &&
-                                mActivePhone.getPhoneType() == PHONE_TYPE_GSM)) {
-                    // Nothing changed. Keep phone as it is.
-                    logd("Ignoring voice radio technology changed message." +
-                            " newVoiceRadioTech = " + newVoiceRadioTech +
-                            " Active Phone = " + mActivePhone.getPhoneName());
-                    return;
-                }
-            }
-        }
-
-        if (newVoiceRadioTech == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
-            // We need some voice phone object to be active always, so never
-            // delete the phone without anything to replace it with!
-            logd("Ignoring voice radio technology changed message. newVoiceRadioTech = Unknown."
-                    + " Active Phone = " + mActivePhone.getPhoneName());
-            return;
-        }
-
-        boolean oldPowerState = false; // old power state to off
-        if (mResetModemOnRadioTechnologyChange) {
-            if (mCommandsInterface.getRadioState().isOn()) {
-                oldPowerState = true;
-                logd("Setting Radio Power to Off");
-                mCommandsInterface.setRadioPower(false, null);
-            }
-        }
-
-        deleteAndCreatePhone(newVoiceRadioTech);
-
-        if (mResetModemOnRadioTechnologyChange && oldPowerState) { // restore power state
-            logd("Resetting Radio");
-            mCommandsInterface.setRadioPower(oldPowerState, null);
-        }
-
-        // Set the new interfaces in the proxy's
-        mIccSmsInterfaceManagerProxy.setmIccSmsInterfaceManager(
-                mActivePhone.getIccSmsInterfaceManager());
-        mIccPhoneBookInterfaceManagerProxy.setmIccPhoneBookInterfaceManager(mActivePhone
-                .getIccPhoneBookInterfaceManager());
-        mPhoneSubInfoProxy.setmPhoneSubInfo(this.mActivePhone.getPhoneSubInfo());
-
-        mCommandsInterface = ((PhoneBase)mActivePhone).mCM;
-
-        // Send an Intent to the PhoneApp that we had a radio technology change
-        Intent intent = new Intent(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED);
-        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
-        intent.putExtra(Phone.PHONE_NAME_KEY, mActivePhone.getPhoneName());
-        ActivityManagerNative.broadcastStickyIntent(intent, null);
-
-    }
-
-    private void deleteAndCreatePhone(int newVoiceRadioTech) {
-
-        String outgoingPhoneName = "Unknown";
-        Phone oldPhone = mActivePhone;
-
-        if (oldPhone != null) {
-            outgoingPhoneName = ((PhoneBase) oldPhone).getPhoneName();
-        }
-
-        logd("Switching Voice Phone : " + outgoingPhoneName + " >>> "
-                + (ServiceState.isGsm(newVoiceRadioTech) ? "GSM" : "CDMA"));
-
-        if (oldPhone != null) {
-            CallManager.getInstance().unregisterPhone(oldPhone);
-            logd("Disposing old phone..");
-            oldPhone.dispose();
-        }
-
-        // Give the garbage collector a hint to start the garbage collection
-        // asap NOTE this has been disabled since radio technology change could
-        // happen during e.g. a multimedia playing and could slow the system.
-        // Tests needs to be done to see the effects of the GC call here when
-        // system is busy.
-        // System.gc();
-
-        if (ServiceState.isCdma(newVoiceRadioTech)) {
-            mActivePhone = PhoneFactory.getCdmaPhone();
-        } else if (ServiceState.isGsm(newVoiceRadioTech)) {
-            mActivePhone = PhoneFactory.getGsmPhone();
-        }
-
-        if (oldPhone != null) {
-            oldPhone.removeReferences();
-        }
-
-        if(mActivePhone != null) {
-            CallManager.getInstance().registerPhone(mActivePhone);
-        }
-
-        oldPhone = null;
-    }
-
-    public ServiceState getServiceState() {
-        return mActivePhone.getServiceState();
-    }
-
-    public CellLocation getCellLocation() {
-        return mActivePhone.getCellLocation();
-    }
-
-    public DataState getDataConnectionState() {
-        return mActivePhone.getDataConnectionState(Phone.APN_TYPE_DEFAULT);
-    }
-
-    public DataState getDataConnectionState(String apnType) {
-        return mActivePhone.getDataConnectionState(apnType);
-    }
-
-    public DataActivityState getDataActivityState() {
-        return mActivePhone.getDataActivityState();
-    }
-
-    public Context getContext() {
-        return mActivePhone.getContext();
-    }
-
-    public void disableDnsCheck(boolean b) {
-        mActivePhone.disableDnsCheck(b);
-    }
-
-    public boolean isDnsCheckDisabled() {
-        return mActivePhone.isDnsCheckDisabled();
-    }
-
-    public State getState() {
-        return mActivePhone.getState();
-    }
-
-    public String getPhoneName() {
-        return mActivePhone.getPhoneName();
-    }
-
-    public int getPhoneType() {
-        return mActivePhone.getPhoneType();
-    }
-
-    public String[] getActiveApnTypes() {
-        return mActivePhone.getActiveApnTypes();
-    }
-
-    public String getActiveApnHost(String apnType) {
-        return mActivePhone.getActiveApnHost(apnType);
-    }
-
-    public LinkProperties getLinkProperties(String apnType) {
-        return mActivePhone.getLinkProperties(apnType);
-    }
-
-    public LinkCapabilities getLinkCapabilities(String apnType) {
-        return mActivePhone.getLinkCapabilities(apnType);
-    }
-
-    public SignalStrength getSignalStrength() {
-        return mActivePhone.getSignalStrength();
-    }
-
-    public void registerForUnknownConnection(Handler h, int what, Object obj) {
-        mActivePhone.registerForUnknownConnection(h, what, obj);
-    }
-
-    public void unregisterForUnknownConnection(Handler h) {
-        mActivePhone.unregisterForUnknownConnection(h);
-    }
-
-    public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) {
-        mActivePhone.registerForPreciseCallStateChanged(h, what, obj);
-    }
-
-    public void unregisterForPreciseCallStateChanged(Handler h) {
-        mActivePhone.unregisterForPreciseCallStateChanged(h);
-    }
-
-    public void registerForNewRingingConnection(Handler h, int what, Object obj) {
-        mActivePhone.registerForNewRingingConnection(h, what, obj);
-    }
-
-    public void unregisterForNewRingingConnection(Handler h) {
-        mActivePhone.unregisterForNewRingingConnection(h);
-    }
-
-    public void registerForIncomingRing(Handler h, int what, Object obj) {
-        mActivePhone.registerForIncomingRing(h, what, obj);
-    }
-
-    public void unregisterForIncomingRing(Handler h) {
-        mActivePhone.unregisterForIncomingRing(h);
-    }
-
-    public void registerForDisconnect(Handler h, int what, Object obj) {
-        mActivePhone.registerForDisconnect(h, what, obj);
-    }
-
-    public void unregisterForDisconnect(Handler h) {
-        mActivePhone.unregisterForDisconnect(h);
-    }
-
-    public void registerForMmiInitiate(Handler h, int what, Object obj) {
-        mActivePhone.registerForMmiInitiate(h, what, obj);
-    }
-
-    public void unregisterForMmiInitiate(Handler h) {
-        mActivePhone.unregisterForMmiInitiate(h);
-    }
-
-    public void registerForMmiComplete(Handler h, int what, Object obj) {
-        mActivePhone.registerForMmiComplete(h, what, obj);
-    }
-
-    public void unregisterForMmiComplete(Handler h) {
-        mActivePhone.unregisterForMmiComplete(h);
-    }
-
-    public List<? extends MmiCode> getPendingMmiCodes() {
-        return mActivePhone.getPendingMmiCodes();
-    }
-
-    public void sendUssdResponse(String ussdMessge) {
-        mActivePhone.sendUssdResponse(ussdMessge);
-    }
-
-    public void registerForServiceStateChanged(Handler h, int what, Object obj) {
-        mActivePhone.registerForServiceStateChanged(h, what, obj);
-    }
-
-    public void unregisterForServiceStateChanged(Handler h) {
-        mActivePhone.unregisterForServiceStateChanged(h);
-    }
-
-    public void registerForSuppServiceNotification(Handler h, int what, Object obj) {
-        mActivePhone.registerForSuppServiceNotification(h, what, obj);
-    }
-
-    public void unregisterForSuppServiceNotification(Handler h) {
-        mActivePhone.unregisterForSuppServiceNotification(h);
-    }
-
-    public void registerForSuppServiceFailed(Handler h, int what, Object obj) {
-        mActivePhone.registerForSuppServiceFailed(h, what, obj);
-    }
-
-    public void unregisterForSuppServiceFailed(Handler h) {
-        mActivePhone.unregisterForSuppServiceFailed(h);
-    }
-
-    public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){
-        mActivePhone.registerForInCallVoicePrivacyOn(h,what,obj);
-    }
-
-    public void unregisterForInCallVoicePrivacyOn(Handler h){
-        mActivePhone.unregisterForInCallVoicePrivacyOn(h);
-    }
-
-    public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){
-        mActivePhone.registerForInCallVoicePrivacyOff(h,what,obj);
-    }
-
-    public void unregisterForInCallVoicePrivacyOff(Handler h){
-        mActivePhone.unregisterForInCallVoicePrivacyOff(h);
-    }
-
-    public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) {
-        mActivePhone.registerForCdmaOtaStatusChange(h,what,obj);
-    }
-
-    public void unregisterForCdmaOtaStatusChange(Handler h) {
-         mActivePhone.unregisterForCdmaOtaStatusChange(h);
-    }
-
-    public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
-        mActivePhone.registerForSubscriptionInfoReady(h, what, obj);
-    }
-
-    public void unregisterForSubscriptionInfoReady(Handler h) {
-        mActivePhone.unregisterForSubscriptionInfoReady(h);
-    }
-
-    public void registerForEcmTimerReset(Handler h, int what, Object obj) {
-        mActivePhone.registerForEcmTimerReset(h,what,obj);
-    }
-
-    public void unregisterForEcmTimerReset(Handler h) {
-        mActivePhone.unregisterForEcmTimerReset(h);
-    }
-
-    public void registerForRingbackTone(Handler h, int what, Object obj) {
-        mActivePhone.registerForRingbackTone(h,what,obj);
-    }
-
-    public void unregisterForRingbackTone(Handler h) {
-        mActivePhone.unregisterForRingbackTone(h);
-    }
-
-    public void registerForResendIncallMute(Handler h, int what, Object obj) {
-        mActivePhone.registerForResendIncallMute(h,what,obj);
-    }
-
-    public void unregisterForResendIncallMute(Handler h) {
-        mActivePhone.unregisterForResendIncallMute(h);
-    }
-
-    public boolean getIccRecordsLoaded() {
-        return mActivePhone.getIccRecordsLoaded();
-    }
-
-    public IccCard getIccCard() {
-        return mActivePhone.getIccCard();
-    }
-
-    public void acceptCall() throws CallStateException {
-        mActivePhone.acceptCall();
-    }
-
-    public void rejectCall() throws CallStateException {
-        mActivePhone.rejectCall();
-    }
-
-    public void switchHoldingAndActive() throws CallStateException {
-        mActivePhone.switchHoldingAndActive();
-    }
-
-    public boolean canConference() {
-        return mActivePhone.canConference();
-    }
-
-    public void conference() throws CallStateException {
-        mActivePhone.conference();
-    }
-
-    public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) {
-        mActivePhone.enableEnhancedVoicePrivacy(enable, onComplete);
-    }
-
-    public void getEnhancedVoicePrivacy(Message onComplete) {
-        mActivePhone.getEnhancedVoicePrivacy(onComplete);
-    }
-
-    public boolean canTransfer() {
-        return mActivePhone.canTransfer();
-    }
-
-    public void explicitCallTransfer() throws CallStateException {
-        mActivePhone.explicitCallTransfer();
-    }
-
-    public void clearDisconnected() {
-        mActivePhone.clearDisconnected();
-    }
-
-    public Call getForegroundCall() {
-        return mActivePhone.getForegroundCall();
-    }
-
-    public Call getBackgroundCall() {
-        return mActivePhone.getBackgroundCall();
-    }
-
-    public Call getRingingCall() {
-        return mActivePhone.getRingingCall();
-    }
-
-    public Connection dial(String dialString) throws CallStateException {
-        return mActivePhone.dial(dialString);
-    }
-
-    public Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException {
-        return mActivePhone.dial(dialString, uusInfo);
-    }
-
-    public boolean handlePinMmi(String dialString) {
-        return mActivePhone.handlePinMmi(dialString);
-    }
-
-    public boolean handleInCallMmiCommands(String command) throws CallStateException {
-        return mActivePhone.handleInCallMmiCommands(command);
-    }
-
-    public void sendDtmf(char c) {
-        mActivePhone.sendDtmf(c);
-    }
-
-    public void startDtmf(char c) {
-        mActivePhone.startDtmf(c);
-    }
-
-    public void stopDtmf() {
-        mActivePhone.stopDtmf();
-    }
-
-    public void setRadioPower(boolean power) {
-        mActivePhone.setRadioPower(power);
-    }
-
-    public boolean getMessageWaitingIndicator() {
-        return mActivePhone.getMessageWaitingIndicator();
-    }
-
-    public boolean getCallForwardingIndicator() {
-        return mActivePhone.getCallForwardingIndicator();
-    }
-
-    public String getLine1Number() {
-        return mActivePhone.getLine1Number();
-    }
-
-    public String getCdmaMin() {
-        return mActivePhone.getCdmaMin();
-    }
-
-    public boolean isMinInfoReady() {
-        return mActivePhone.isMinInfoReady();
-    }
-
-    public String getCdmaPrlVersion() {
-        return mActivePhone.getCdmaPrlVersion();
-    }
-
-    public String getLine1AlphaTag() {
-        return mActivePhone.getLine1AlphaTag();
-    }
-
-    public void setLine1Number(String alphaTag, String number, Message onComplete) {
-        mActivePhone.setLine1Number(alphaTag, number, onComplete);
-    }
-
-    public String getVoiceMailNumber() {
-        return mActivePhone.getVoiceMailNumber();
-    }
-
-     /** @hide */
-    public int getVoiceMessageCount(){
-        return mActivePhone.getVoiceMessageCount();
-    }
-
-    public String getVoiceMailAlphaTag() {
-        return mActivePhone.getVoiceMailAlphaTag();
-    }
-
-    public void setVoiceMailNumber(String alphaTag,String voiceMailNumber,
-            Message onComplete) {
-        mActivePhone.setVoiceMailNumber(alphaTag, voiceMailNumber, onComplete);
-    }
-
-    public void getCallForwardingOption(int commandInterfaceCFReason,
-            Message onComplete) {
-        mActivePhone.getCallForwardingOption(commandInterfaceCFReason,
-                onComplete);
-    }
-
-    public void setCallForwardingOption(int commandInterfaceCFReason,
-            int commandInterfaceCFAction, String dialingNumber,
-            int timerSeconds, Message onComplete) {
-        mActivePhone.setCallForwardingOption(commandInterfaceCFReason,
-            commandInterfaceCFAction, dialingNumber, timerSeconds, onComplete);
-    }
-
-    public void getOutgoingCallerIdDisplay(Message onComplete) {
-        mActivePhone.getOutgoingCallerIdDisplay(onComplete);
-    }
-
-    public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode,
-            Message onComplete) {
-        mActivePhone.setOutgoingCallerIdDisplay(commandInterfaceCLIRMode,
-                onComplete);
-    }
-
-    public void getCallWaiting(Message onComplete) {
-        mActivePhone.getCallWaiting(onComplete);
-    }
-
-    public void setCallWaiting(boolean enable, Message onComplete) {
-        mActivePhone.setCallWaiting(enable, onComplete);
-    }
-
-    public void getAvailableNetworks(Message response) {
-        mActivePhone.getAvailableNetworks(response);
-    }
-
-    public void setNetworkSelectionModeAutomatic(Message response) {
-        mActivePhone.setNetworkSelectionModeAutomatic(response);
-    }
-
-    public void selectNetworkManually(OperatorInfo network, Message response) {
-        mActivePhone.selectNetworkManually(network, response);
-    }
-
-    public void setPreferredNetworkType(int networkType, Message response) {
-        mActivePhone.setPreferredNetworkType(networkType, response);
-    }
-
-    public void getPreferredNetworkType(Message response) {
-        mActivePhone.getPreferredNetworkType(response);
-    }
-
-    public void getNeighboringCids(Message response) {
-        mActivePhone.getNeighboringCids(response);
-    }
-
-    public void setOnPostDialCharacter(Handler h, int what, Object obj) {
-        mActivePhone.setOnPostDialCharacter(h, what, obj);
-    }
-
-    public void setMute(boolean muted) {
-        mActivePhone.setMute(muted);
-    }
-
-    public boolean getMute() {
-        return mActivePhone.getMute();
-    }
-
-    public void setEchoSuppressionEnabled(boolean enabled) {
-        mActivePhone.setEchoSuppressionEnabled(enabled);
-    }
-
-    public void invokeOemRilRequestRaw(byte[] data, Message response) {
-        mActivePhone.invokeOemRilRequestRaw(data, response);
-    }
-
-    public void invokeOemRilRequestStrings(String[] strings, Message response) {
-        mActivePhone.invokeOemRilRequestStrings(strings, response);
-    }
-
-    public void getDataCallList(Message response) {
-        mActivePhone.getDataCallList(response);
-    }
-
-    public void updateServiceLocation() {
-        mActivePhone.updateServiceLocation();
-    }
-
-    public void enableLocationUpdates() {
-        mActivePhone.enableLocationUpdates();
-    }
-
-    public void disableLocationUpdates() {
-        mActivePhone.disableLocationUpdates();
-    }
-
-    public void setUnitTestMode(boolean f) {
-        mActivePhone.setUnitTestMode(f);
-    }
-
-    public boolean getUnitTestMode() {
-        return mActivePhone.getUnitTestMode();
-    }
-
-    public void setBandMode(int bandMode, Message response) {
-        mActivePhone.setBandMode(bandMode, response);
-    }
-
-    public void queryAvailableBandMode(Message response) {
-        mActivePhone.queryAvailableBandMode(response);
-    }
-
-    public boolean getDataRoamingEnabled() {
-        return mActivePhone.getDataRoamingEnabled();
-    }
-
-    public void setDataRoamingEnabled(boolean enable) {
-        mActivePhone.setDataRoamingEnabled(enable);
-    }
-
-    public void queryCdmaRoamingPreference(Message response) {
-        mActivePhone.queryCdmaRoamingPreference(response);
-    }
-
-    public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
-        mActivePhone.setCdmaRoamingPreference(cdmaRoamingType, response);
-    }
-
-    public void setCdmaSubscription(int cdmaSubscriptionType, Message response) {
-        mActivePhone.setCdmaSubscription(cdmaSubscriptionType, response);
-    }
-
-    public SimulatedRadioControl getSimulatedRadioControl() {
-        return mActivePhone.getSimulatedRadioControl();
-    }
-
-    public int enableApnType(String type) {
-        return mActivePhone.enableApnType(type);
-    }
-
-    public int disableApnType(String type) {
-        return mActivePhone.disableApnType(type);
-    }
-
-    public boolean isDataConnectivityPossible() {
-        return mActivePhone.isDataConnectivityPossible(Phone.APN_TYPE_DEFAULT);
-    }
-
-    public boolean isDataConnectivityPossible(String apnType) {
-        return mActivePhone.isDataConnectivityPossible(apnType);
-    }
-
-    public String getDeviceId() {
-        return mActivePhone.getDeviceId();
-    }
-
-    public String getDeviceSvn() {
-        return mActivePhone.getDeviceSvn();
-    }
-
-    public String getSubscriberId() {
-        return mActivePhone.getSubscriberId();
-    }
-
-    public String getIccSerialNumber() {
-        return mActivePhone.getIccSerialNumber();
-    }
-
-    public String getEsn() {
-        return mActivePhone.getEsn();
-    }
-
-    public String getMeid() {
-        return mActivePhone.getMeid();
-    }
-
-    public String getMsisdn() {
-        return mActivePhone.getMsisdn();
-    }
-
-    public String getImei() {
-        return mActivePhone.getImei();
-    }
-
-    public PhoneSubInfo getPhoneSubInfo(){
-        return mActivePhone.getPhoneSubInfo();
-    }
-
-    public IccSmsInterfaceManager getIccSmsInterfaceManager(){
-        return mActivePhone.getIccSmsInterfaceManager();
-    }
-
-    public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(){
-        return mActivePhone.getIccPhoneBookInterfaceManager();
-    }
-
-    public void setTTYMode(int ttyMode, Message onComplete) {
-        mActivePhone.setTTYMode(ttyMode, onComplete);
-    }
-
-    public void queryTTYMode(Message onComplete) {
-        mActivePhone.queryTTYMode(onComplete);
-    }
-
-    public void activateCellBroadcastSms(int activate, Message response) {
-        mActivePhone.activateCellBroadcastSms(activate, response);
-    }
-
-    public void getCellBroadcastSmsConfig(Message response) {
-        mActivePhone.getCellBroadcastSmsConfig(response);
-    }
-
-    public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response) {
-        mActivePhone.setCellBroadcastSmsConfig(configValuesArray, response);
-    }
-
-    public void notifyDataActivity() {
-         mActivePhone.notifyDataActivity();
-    }
-
-    public void getSmscAddress(Message result) {
-        mActivePhone.getSmscAddress(result);
-    }
-
-    public void setSmscAddress(String address, Message result) {
-        mActivePhone.setSmscAddress(address, result);
-    }
-
-    public int getCdmaEriIconIndex() {
-        return mActivePhone.getCdmaEriIconIndex();
-    }
-
-    public String getCdmaEriText() {
-        return mActivePhone.getCdmaEriText();
-    }
-
-    public int getCdmaEriIconMode() {
-        return mActivePhone.getCdmaEriIconMode();
-    }
-
-    public Phone getActivePhone() {
-        return mActivePhone;
-    }
-
-    public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete){
-        mActivePhone.sendBurstDtmf(dtmfString, on, off, onComplete);
-    }
-
-    public void exitEmergencyCallbackMode(){
-        mActivePhone.exitEmergencyCallbackMode();
-    }
-
-    public boolean needsOtaServiceProvisioning(){
-        return mActivePhone.needsOtaServiceProvisioning();
-    }
-
-    public boolean isOtaSpNumber(String dialStr){
-        return mActivePhone.isOtaSpNumber(dialStr);
-    }
-
-    public void registerForCallWaiting(Handler h, int what, Object obj){
-        mActivePhone.registerForCallWaiting(h,what,obj);
-    }
-
-    public void unregisterForCallWaiting(Handler h){
-        mActivePhone.unregisterForCallWaiting(h);
-    }
-
-    public void registerForSignalInfo(Handler h, int what, Object obj) {
-        mActivePhone.registerForSignalInfo(h,what,obj);
-    }
-
-    public void unregisterForSignalInfo(Handler h) {
-        mActivePhone.unregisterForSignalInfo(h);
-    }
-
-    public void registerForDisplayInfo(Handler h, int what, Object obj) {
-        mActivePhone.registerForDisplayInfo(h,what,obj);
-    }
-
-    public void unregisterForDisplayInfo(Handler h) {
-        mActivePhone.unregisterForDisplayInfo(h);
-    }
-
-    public void registerForNumberInfo(Handler h, int what, Object obj) {
-        mActivePhone.registerForNumberInfo(h, what, obj);
-    }
-
-    public void unregisterForNumberInfo(Handler h) {
-        mActivePhone.unregisterForNumberInfo(h);
-    }
-
-    public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) {
-        mActivePhone.registerForRedirectedNumberInfo(h, what, obj);
-    }
-
-    public void unregisterForRedirectedNumberInfo(Handler h) {
-        mActivePhone.unregisterForRedirectedNumberInfo(h);
-    }
-
-    public void registerForLineControlInfo(Handler h, int what, Object obj) {
-        mActivePhone.registerForLineControlInfo( h, what, obj);
-    }
-
-    public void unregisterForLineControlInfo(Handler h) {
-        mActivePhone.unregisterForLineControlInfo(h);
-    }
-
-    public void registerFoT53ClirlInfo(Handler h, int what, Object obj) {
-        mActivePhone.registerFoT53ClirlInfo(h, what, obj);
-    }
-
-    public void unregisterForT53ClirInfo(Handler h) {
-        mActivePhone.unregisterForT53ClirInfo(h);
-    }
-
-    public void registerForT53AudioControlInfo(Handler h, int what, Object obj) {
-        mActivePhone.registerForT53AudioControlInfo( h, what, obj);
-    }
-
-    public void unregisterForT53AudioControlInfo(Handler h) {
-        mActivePhone.unregisterForT53AudioControlInfo(h);
-    }
-
-    public void setOnEcbModeExitResponse(Handler h, int what, Object obj){
-        mActivePhone.setOnEcbModeExitResponse(h,what,obj);
-    }
-
-    public void unsetOnEcbModeExitResponse(Handler h){
-        mActivePhone.unsetOnEcbModeExitResponse(h);
-    }
-
-    public boolean isCspPlmnEnabled() {
-        return mActivePhone.isCspPlmnEnabled();
-    }
-
-    public IsimRecords getIsimRecords() {
-        return mActivePhone.getIsimRecords();
-    }
-
-    public void requestIsimAuthentication(String nonce, Message response) {
-        mActivePhone.requestIsimAuthentication(nonce, response);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public int getLteOnCdmaMode() {
-        return mActivePhone.getLteOnCdmaMode();
-    }
-
-    @Override
-    public void setVoiceMessageWaiting(int line, int countWaiting) {
-        mActivePhone.setVoiceMessageWaiting(line, countWaiting);
-    }
-
-    @Override
-    public UsimServiceTable getUsimServiceTable() {
-        return mActivePhone.getUsimServiceTable();
-    }
-
-    public void dispose() {
-        mCommandsInterface.unregisterForOn(this);
-        mCommandsInterface.unregisterForVoiceRadioTechChanged(this);
-        mCommandsInterface.unregisterForRilConnected(this);
-    }
-
-    public void removeReferences() {
-        mActivePhone = null;
-        mCommandsInterface = null;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java b/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java
deleted file mode 100644
index 898e624..0000000
--- a/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java
+++ /dev/null
@@ -1,203 +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.internal.telephony;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Handler;
-import android.os.Message;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.telephony.TelephonyManager;
-import android.util.Log;
-
-/**
- *
- *                            DO NOT USE THIS CLASS:
- *
- *      Use android.telephony.TelephonyManager and PhoneStateListener instead.
- *
- *
- */
-@Deprecated
-public final class PhoneStateIntentReceiver extends BroadcastReceiver {
-    private static final String LOG_TAG = "PHONE";
-    private static final boolean DBG = false;
-
-    private static final int NOTIF_PHONE    = 1 << 0;
-    private static final int NOTIF_SERVICE  = 1 << 1;
-    private static final int NOTIF_SIGNAL   = 1 << 2;
-
-    private static final int NOTIF_MAX      = 1 << 5;
-
-    Phone.State mPhoneState = Phone.State.IDLE;
-    ServiceState mServiceState = new ServiceState();
-    SignalStrength mSignalStrength = new SignalStrength();
-
-    private Context mContext;
-    private Handler mTarget;
-    private IntentFilter mFilter;
-    private int mWants;
-    private int mPhoneStateEventWhat;
-    private int mServiceStateEventWhat;
-    private int mLocationEventWhat;
-    private int mAsuEventWhat;
-
-    public PhoneStateIntentReceiver() {
-        super();
-        mFilter = new IntentFilter();
-    }
-
-    public PhoneStateIntentReceiver(Context context, Handler target) {
-        this();
-        setContext(context);
-        setTarget(target);
-    }
-
-    public void setContext(Context c) {
-        mContext = c;
-    }
-
-    public void setTarget(Handler h) {
-        mTarget = h;
-    }
-
-    public Phone.State getPhoneState() {
-        if ((mWants & NOTIF_PHONE) == 0) {
-            throw new RuntimeException
-                ("client must call notifyPhoneCallState(int)");
-        }
-        return mPhoneState;
-    }
-
-    public ServiceState getServiceState() {
-        if ((mWants & NOTIF_SERVICE) == 0) {
-            throw new RuntimeException
-                ("client must call notifyServiceState(int)");
-        }
-        return mServiceState;
-    }
-
-    /**
-     * Returns current signal strength in as an asu 0..31
-     *
-     * Throws RuntimeException if client has not called notifySignalStrength()
-     */
-    public int getSignalStrengthLevelAsu() {
-        // TODO: use new SignalStrength instead of asu
-        if ((mWants & NOTIF_SIGNAL) == 0) {
-            throw new RuntimeException
-                ("client must call notifySignalStrength(int)");
-        }
-        return mSignalStrength.getAsuLevel();
-    }
-
-    /**
-     * Return current signal strength in "dBm", ranging from -113 - -51dBm
-     * or -1 if unknown
-     *
-     * @return signal strength in dBm, -1 if not yet updated
-     * Throws RuntimeException if client has not called notifySignalStrength()
-     */
-    public int getSignalStrengthDbm() {
-        if ((mWants & NOTIF_SIGNAL) == 0) {
-            throw new RuntimeException
-                ("client must call notifySignalStrength(int)");
-        }
-        return mSignalStrength.getDbm();
-    }
-
-    public void notifyPhoneCallState(int eventWhat) {
-        mWants |= NOTIF_PHONE;
-        mPhoneStateEventWhat = eventWhat;
-        mFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
-    }
-
-    public boolean getNotifyPhoneCallState() {
-        return ((mWants & NOTIF_PHONE) != 0);
-    }
-
-    public void notifyServiceState(int eventWhat) {
-        mWants |= NOTIF_SERVICE;
-        mServiceStateEventWhat = eventWhat;
-        mFilter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
-    }
-
-    public boolean getNotifyServiceState() {
-        return ((mWants & NOTIF_SERVICE) != 0);
-    }
-
-    public void notifySignalStrength (int eventWhat) {
-        mWants |= NOTIF_SIGNAL;
-        mAsuEventWhat = eventWhat;
-        mFilter.addAction(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED);
-    }
-
-    public boolean getNotifySignalStrength() {
-        return ((mWants & NOTIF_SIGNAL) != 0);
-    }
-
-    public void registerIntent() {
-        mContext.registerReceiver(this, mFilter);
-    }
-
-    public void unregisterIntent() {
-        mContext.unregisterReceiver(this);
-    }
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        String action = intent.getAction();
-
-        try {
-            if (TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED.equals(action)) {
-                mSignalStrength = SignalStrength.newFromBundle(intent.getExtras());
-
-                if (mTarget != null && getNotifySignalStrength()) {
-                    Message message = Message.obtain(mTarget, mAsuEventWhat);
-                    mTarget.sendMessage(message);
-                }
-            } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
-                if (DBG) Log.d(LOG_TAG, "onReceiveIntent: ACTION_PHONE_STATE_CHANGED, state="
-                               + intent.getStringExtra(Phone.STATE_KEY));
-                String phoneState = intent.getStringExtra(Phone.STATE_KEY);
-                mPhoneState = (Phone.State) Enum.valueOf(
-                        Phone.State.class, phoneState);
-
-                if (mTarget != null && getNotifyPhoneCallState()) {
-                    Message message = Message.obtain(mTarget,
-                            mPhoneStateEventWhat);
-                    mTarget.sendMessage(message);
-                }
-            } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
-                mServiceState = ServiceState.newFromBundle(intent.getExtras());
-
-                if (mTarget != null && getNotifyServiceState()) {
-                    Message message = Message.obtain(mTarget,
-                            mServiceStateEventWhat);
-                    mTarget.sendMessage(message);
-                }
-            }
-        } catch (Exception ex) {
-            Log.e(LOG_TAG, "[PhoneStateIntentRecv] caught " + ex);
-            ex.printStackTrace();
-        }
-    }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/PhoneSubInfo.java b/telephony/java/com/android/internal/telephony/PhoneSubInfo.java
deleted file mode 100755
index e8449ce..0000000
--- a/telephony/java/com/android/internal/telephony/PhoneSubInfo.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * 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.internal.telephony;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Binder;
-import android.telephony.PhoneNumberUtils;
-import android.util.Log;
-
-import com.android.internal.telephony.ims.IsimRecords;
-
-public class PhoneSubInfo extends IPhoneSubInfo.Stub {
-    static final String LOG_TAG = "PHONE";
-    private Phone mPhone;
-    private Context mContext;
-    private static final String READ_PHONE_STATE =
-        android.Manifest.permission.READ_PHONE_STATE;
-    // TODO: change getCompleteVoiceMailNumber() to require READ_PRIVILEGED_PHONE_STATE
-    private static final String CALL_PRIVILEGED =
-        android.Manifest.permission.CALL_PRIVILEGED;
-    private static final String READ_PRIVILEGED_PHONE_STATE =
-        android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
-
-    public PhoneSubInfo(Phone phone) {
-        mPhone = phone;
-        mContext = phone.getContext();
-    }
-
-    public void dispose() {
-    }
-
-    protected void finalize() {
-        try {
-            super.finalize();
-        } catch (Throwable throwable) {
-            Log.e(LOG_TAG, "Error while finalizing:", throwable);
-        }
-        Log.d(LOG_TAG, "PhoneSubInfo finalized");
-    }
-
-    /**
-     * Retrieves the unique device ID, e.g., IMEI for GSM phones and MEID for CDMA phones.
-     */
-    public String getDeviceId() {
-        mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
-        return mPhone.getDeviceId();
-    }
-
-    /**
-     * Retrieves the software version number for the device, e.g., IMEI/SV
-     * for GSM phones.
-     */
-    public String getDeviceSvn() {
-        mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
-        return mPhone.getDeviceSvn();
-    }
-
-    /**
-     * Retrieves the unique subscriber ID, e.g., IMSI for GSM phones.
-     */
-    public String getSubscriberId() {
-        mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
-        return mPhone.getSubscriberId();
-    }
-
-    /**
-     * Retrieves the serial number of the ICC, if applicable.
-     */
-    public String getIccSerialNumber() {
-        mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
-        return mPhone.getIccSerialNumber();
-    }
-
-    /**
-     * Retrieves the phone number string for line 1.
-     */
-    public String getLine1Number() {
-        mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
-        return mPhone.getLine1Number();
-    }
-
-    /**
-     * Retrieves the alpha identifier for line 1.
-     */
-    public String getLine1AlphaTag() {
-        mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
-        return (String) mPhone.getLine1AlphaTag();
-    }
-
-    /**
-     * Retrieves the MSISDN string.
-     */
-    public String getMsisdn() {
-        mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
-        return mPhone.getMsisdn();
-    }
-
-    /**
-     * Retrieves the voice mail number.
-     */
-    public String getVoiceMailNumber() {
-        mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
-        String number = PhoneNumberUtils.extractNetworkPortion(mPhone.getVoiceMailNumber());
-        Log.d(LOG_TAG, "VM: PhoneSubInfo.getVoiceMailNUmber: "); // + number);
-        return number;
-    }
-
-    /**
-     * Retrieves the complete voice mail number.
-     *
-     * @hide
-     */
-    public String getCompleteVoiceMailNumber() {
-        mContext.enforceCallingOrSelfPermission(CALL_PRIVILEGED,
-                "Requires CALL_PRIVILEGED");
-        String number = mPhone.getVoiceMailNumber();
-        Log.d(LOG_TAG, "VM: PhoneSubInfo.getCompleteVoiceMailNUmber: "); // + number);
-        return number;
-    }
-
-    /**
-     * Retrieves the alpha identifier associated with the voice mail number.
-     */
-    public String getVoiceMailAlphaTag() {
-        mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
-        return (String) mPhone.getVoiceMailAlphaTag();
-    }
-
-    /**
-     * Returns the IMS private user identity (IMPI) that was loaded from the ISIM.
-     * @return the IMPI, or null if not present or not loaded
-     */
-    public String getIsimImpi() {
-        mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE,
-                "Requires READ_PRIVILEGED_PHONE_STATE");
-        IsimRecords isim = mPhone.getIsimRecords();
-        if (isim != null) {
-            return isim.getIsimImpi();
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Returns the IMS home network domain name that was loaded from the ISIM.
-     * @return the IMS domain name, or null if not present or not loaded
-     */
-    public String getIsimDomain() {
-        mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE,
-                "Requires READ_PRIVILEGED_PHONE_STATE");
-        IsimRecords isim = mPhone.getIsimRecords();
-        if (isim != null) {
-            return isim.getIsimDomain();
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Returns the IMS public user identities (IMPU) that were loaded from the ISIM.
-     * @return an array of IMPU strings, with one IMPU per string, or null if
-     *      not present or not loaded
-     */
-    public String[] getIsimImpu() {
-        mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE,
-                "Requires READ_PRIVILEGED_PHONE_STATE");
-        IsimRecords isim = mPhone.getIsimRecords();
-        if (isim != null) {
-            return isim.getIsimImpu();
-        } else {
-            return null;
-        }
-    }
-
-    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
-                != PackageManager.PERMISSION_GRANTED) {
-            pw.println("Permission Denial: can't dump PhoneSubInfo from from pid="
-                    + Binder.getCallingPid()
-                    + ", uid=" + Binder.getCallingUid());
-            return;
-        }
-
-        pw.println("Phone Subscriber Info:");
-        pw.println("  Phone Type = " + mPhone.getPhoneName());
-        pw.println("  Device ID = " + mPhone.getDeviceId());
-    }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java b/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java
deleted file mode 100755
index bd130de..0000000
--- a/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java
+++ /dev/null
@@ -1,133 +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.internal.telephony;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-import android.content.pm.PackageManager;
-import android.os.Binder;
-import android.os.ServiceManager;
-
-
-public class PhoneSubInfoProxy extends IPhoneSubInfo.Stub {
-    private PhoneSubInfo mPhoneSubInfo;
-
-    public PhoneSubInfoProxy(PhoneSubInfo phoneSubInfo) {
-        mPhoneSubInfo = phoneSubInfo;
-        if(ServiceManager.getService("iphonesubinfo") == null) {
-            ServiceManager.addService("iphonesubinfo", this);
-        }
-    }
-
-    public void setmPhoneSubInfo(PhoneSubInfo phoneSubInfo) {
-        this.mPhoneSubInfo = phoneSubInfo;
-    }
-
-    public String getDeviceId() {
-        return mPhoneSubInfo.getDeviceId();
-    }
-
-    public String getDeviceSvn() {
-        return mPhoneSubInfo.getDeviceSvn();
-    }
-
-    /**
-     * Retrieves the unique subscriber ID, e.g., IMSI for GSM phones.
-     */
-    public String getSubscriberId() {
-        return mPhoneSubInfo.getSubscriberId();
-    }
-
-    /**
-     * Retrieves the serial number of the ICC, if applicable.
-     */
-    public String getIccSerialNumber() {
-        return mPhoneSubInfo.getIccSerialNumber();
-    }
-
-    /**
-     * Retrieves the phone number string for line 1.
-     */
-    public String getLine1Number() {
-        return mPhoneSubInfo.getLine1Number();
-    }
-
-    /**
-     * Retrieves the alpha identifier for line 1.
-     */
-    public String getLine1AlphaTag() {
-        return mPhoneSubInfo.getLine1AlphaTag();
-    }
-
-    /**
-     * Retrieves the MSISDN Number.
-     */
-    public String getMsisdn() {
-        return mPhoneSubInfo.getMsisdn();
-    }
-
-    /**
-     * Retrieves the voice mail number.
-     */
-    public String getVoiceMailNumber() {
-        return mPhoneSubInfo.getVoiceMailNumber();
-    }
-
-    /**
-     * Retrieves the complete voice mail number.
-     */
-    public String getCompleteVoiceMailNumber() {
-        return mPhoneSubInfo.getCompleteVoiceMailNumber();
-    }
-
-    /**
-     * Retrieves the alpha identifier associated with the voice mail number.
-     */
-    public String getVoiceMailAlphaTag() {
-        return mPhoneSubInfo.getVoiceMailAlphaTag();
-    }
-
-    /**
-     * Returns the IMS private user identity (IMPI) that was loaded from the ISIM.
-     * @return the IMPI, or null if not present or not loaded
-     */
-    public String getIsimImpi() {
-        return mPhoneSubInfo.getIsimImpi();
-    }
-
-    /**
-     * Returns the IMS home network domain name that was loaded from the ISIM.
-     * @return the IMS domain name, or null if not present or not loaded
-     */
-    public String getIsimDomain() {
-        return mPhoneSubInfo.getIsimDomain();
-    }
-
-    /**
-     * Returns the IMS public user identities (IMPU) that were loaded from the ISIM.
-     * @return an array of IMPU strings, with one IMPU per string, or null if
-     *      not present or not loaded
-     */
-    public String[] getIsimImpu() {
-        return mPhoneSubInfo.getIsimImpu();
-    }
-
-    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        mPhoneSubInfo.dump(fd, pw, args);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
deleted file mode 100644
index b14f6c8..0000000
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ /dev/null
@@ -1,3861 +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.internal.telephony;
-
-import static com.android.internal.telephony.RILConstants.*;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_EDGE;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_GPRS;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_UMTS;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_HSDPA;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_HSUPA;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_HSPA;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.ConnectivityManager;
-import android.net.LocalSocket;
-import android.net.LocalSocketAddress;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Parcel;
-import android.os.PowerManager;
-import android.os.SystemProperties;
-import android.os.PowerManager.WakeLock;
-import android.telephony.NeighboringCellInfo;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.SmsManager;
-import android.telephony.SmsMessage;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
-import com.android.internal.telephony.gsm.SuppServiceNotification;
-import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
-import com.android.internal.telephony.cdma.CdmaInformationRecords;
-import com.android.internal.telephony.IccRefreshResponse;
-
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * {@hide}
- */
-class RILRequest {
-    static final String LOG_TAG = "RILJ";
-
-    //***** Class Variables
-    static int sNextSerial = 0;
-    static Object sSerialMonitor = new Object();
-    private static Object sPoolSync = new Object();
-    private static RILRequest sPool = null;
-    private static int sPoolSize = 0;
-    private static final int MAX_POOL_SIZE = 4;
-
-    //***** Instance Variables
-    int mSerial;
-    int mRequest;
-    Message mResult;
-    Parcel mp;
-    RILRequest mNext;
-
-    /**
-     * Retrieves a new RILRequest instance from the pool.
-     *
-     * @param request RIL_REQUEST_*
-     * @param result sent when operation completes
-     * @return a RILRequest instance from the pool.
-     */
-    static RILRequest obtain(int request, Message result) {
-        RILRequest rr = null;
-
-        synchronized(sPoolSync) {
-            if (sPool != null) {
-                rr = sPool;
-                sPool = rr.mNext;
-                rr.mNext = null;
-                sPoolSize--;
-            }
-        }
-
-        if (rr == null) {
-            rr = new RILRequest();
-        }
-
-        synchronized(sSerialMonitor) {
-            rr.mSerial = sNextSerial++;
-        }
-        rr.mRequest = request;
-        rr.mResult = result;
-        rr.mp = Parcel.obtain();
-
-        if (result != null && result.getTarget() == null) {
-            throw new NullPointerException("Message target must not be null");
-        }
-
-        // first elements in any RIL Parcel
-        rr.mp.writeInt(request);
-        rr.mp.writeInt(rr.mSerial);
-
-        return rr;
-    }
-
-    /**
-     * Returns a RILRequest instance to the pool.
-     *
-     * Note: This should only be called once per use.
-     */
-    void release() {
-        synchronized (sPoolSync) {
-            if (sPoolSize < MAX_POOL_SIZE) {
-                this.mNext = sPool;
-                sPool = this;
-                sPoolSize++;
-                mResult = null;
-            }
-        }
-    }
-
-    private RILRequest() {
-    }
-
-    static void
-    resetSerial() {
-        synchronized(sSerialMonitor) {
-            sNextSerial = 0;
-        }
-    }
-
-    String
-    serialString() {
-        //Cheesy way to do %04d
-        StringBuilder sb = new StringBuilder(8);
-        String sn;
-
-        sn = Integer.toString(mSerial);
-
-        //sb.append("J[");
-        sb.append('[');
-        for (int i = 0, s = sn.length() ; i < 4 - s; i++) {
-            sb.append('0');
-        }
-
-        sb.append(sn);
-        sb.append(']');
-        return sb.toString();
-    }
-
-    void
-    onError(int error, Object ret) {
-        CommandException ex;
-
-        ex = CommandException.fromRilErrno(error);
-
-        if (RIL.RILJ_LOGD) Log.d(LOG_TAG, serialString() + "< "
-            + RIL.requestToString(mRequest)
-            + " error: " + ex);
-
-        if (mResult != null) {
-            AsyncResult.forMessage(mResult, ret, ex);
-            mResult.sendToTarget();
-        }
-
-        if (mp != null) {
-            mp.recycle();
-            mp = null;
-        }
-    }
-}
-
-
-/**
- * RIL implementation of the CommandsInterface.
- * FIXME public only for testing
- *
- * {@hide}
- */
-public final class RIL extends BaseCommands implements CommandsInterface {
-    static final String LOG_TAG = "RILJ";
-    static final boolean RILJ_LOGD = true;
-    static final boolean RILJ_LOGV = false; // STOP SHIP if true
-
-    /**
-     * Wake lock timeout should be longer than the longest timeout in
-     * the vendor ril.
-     */
-    private static final int DEFAULT_WAKE_LOCK_TIMEOUT = 60000;
-
-    //***** Instance Variables
-
-    LocalSocket mSocket;
-    HandlerThread mSenderThread;
-    RILSender mSender;
-    Thread mReceiverThread;
-    RILReceiver mReceiver;
-    WakeLock mWakeLock;
-    int mWakeLockTimeout;
-    // The number of requests pending to be sent out, it increases before calling
-    // EVENT_SEND and decreases while handling EVENT_SEND. It gets cleared while
-    // WAKE_LOCK_TIMEOUT occurs.
-    int mRequestMessagesPending;
-    // The number of requests sent out but waiting for response. It increases while
-    // sending request and decreases while handling response. It should match
-    // mRequestList.size() unless there are requests no replied while
-    // WAKE_LOCK_TIMEOUT occurs.
-    int mRequestMessagesWaiting;
-
-    //I'd rather this be LinkedList or something
-    ArrayList<RILRequest> mRequestsList = new ArrayList<RILRequest>();
-
-    Object     mLastNITZTimeInfo;
-
-    // When we are testing emergency calls
-    AtomicBoolean mTestingEmergencyCall = new AtomicBoolean(false);
-
-    //***** Events
-
-    static final int EVENT_SEND                 = 1;
-    static final int EVENT_WAKE_LOCK_TIMEOUT    = 2;
-
-    //***** Constants
-
-    // match with constant in ril.cpp
-    static final int RIL_MAX_COMMAND_BYTES = (8 * 1024);
-    static final int RESPONSE_SOLICITED = 0;
-    static final int RESPONSE_UNSOLICITED = 1;
-
-    static final String SOCKET_NAME_RIL = "rild";
-
-    static final int SOCKET_OPEN_RETRY_MILLIS = 4 * 1000;
-
-    // The number of the required config values for broadcast SMS stored in the C struct
-    // RIL_CDMA_BroadcastServiceInfo
-    private static final int CDMA_BSI_NO_OF_INTS_STRUCT = 3;
-
-    private static final int CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES = 31;
-
-    BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
-                sendScreenState(true);
-            } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
-                sendScreenState(false);
-            } else {
-                Log.w(LOG_TAG, "RIL received unexpected Intent: " + intent.getAction());
-            }
-        }
-    };
-
-    class RILSender extends Handler implements Runnable {
-        public RILSender(Looper looper) {
-            super(looper);
-        }
-
-        // Only allocated once
-        byte[] dataLength = new byte[4];
-
-        //***** Runnable implementation
-        public void
-        run() {
-            //setup if needed
-        }
-
-
-        //***** Handler implementation
-        @Override public void
-        handleMessage(Message msg) {
-            RILRequest rr = (RILRequest)(msg.obj);
-            RILRequest req = null;
-
-            switch (msg.what) {
-                case EVENT_SEND:
-                    /**
-                     * mRequestMessagePending++ already happened for every
-                     * EVENT_SEND, thus we must make sure
-                     * mRequestMessagePending-- happens once and only once
-                     */
-                    boolean alreadySubtracted = false;
-                    try {
-                        LocalSocket s;
-
-                        s = mSocket;
-
-                        if (s == null) {
-                            rr.onError(RADIO_NOT_AVAILABLE, null);
-                            rr.release();
-                            if (mRequestMessagesPending > 0)
-                                mRequestMessagesPending--;
-                            alreadySubtracted = true;
-                            return;
-                        }
-
-                        synchronized (mRequestsList) {
-                            mRequestsList.add(rr);
-                            mRequestMessagesWaiting++;
-                        }
-
-                        if (mRequestMessagesPending > 0)
-                            mRequestMessagesPending--;
-                        alreadySubtracted = true;
-
-                        byte[] data;
-
-                        data = rr.mp.marshall();
-                        rr.mp.recycle();
-                        rr.mp = null;
-
-                        if (data.length > RIL_MAX_COMMAND_BYTES) {
-                            throw new RuntimeException(
-                                    "Parcel larger than max bytes allowed! "
-                                                          + data.length);
-                        }
-
-                        // parcel length in big endian
-                        dataLength[0] = dataLength[1] = 0;
-                        dataLength[2] = (byte)((data.length >> 8) & 0xff);
-                        dataLength[3] = (byte)((data.length) & 0xff);
-
-                        //Log.v(LOG_TAG, "writing packet: " + data.length + " bytes");
-
-                        s.getOutputStream().write(dataLength);
-                        s.getOutputStream().write(data);
-                    } catch (IOException ex) {
-                        Log.e(LOG_TAG, "IOException", ex);
-                        req = findAndRemoveRequestFromList(rr.mSerial);
-                        // make sure this request has not already been handled,
-                        // eg, if RILReceiver cleared the list.
-                        if (req != null || !alreadySubtracted) {
-                            rr.onError(RADIO_NOT_AVAILABLE, null);
-                            rr.release();
-                        }
-                    } catch (RuntimeException exc) {
-                        Log.e(LOG_TAG, "Uncaught exception ", exc);
-                        req = findAndRemoveRequestFromList(rr.mSerial);
-                        // make sure this request has not already been handled,
-                        // eg, if RILReceiver cleared the list.
-                        if (req != null || !alreadySubtracted) {
-                            rr.onError(GENERIC_FAILURE, null);
-                            rr.release();
-                        }
-                    } finally {
-                        // Note: We are "Done" only if there are no outstanding
-                        // requests or replies. Thus this code path will only release
-                        // the wake lock on errors.
-                        releaseWakeLockIfDone();
-                    }
-
-                    if (!alreadySubtracted && mRequestMessagesPending > 0) {
-                        mRequestMessagesPending--;
-                    }
-
-                    break;
-
-                case EVENT_WAKE_LOCK_TIMEOUT:
-                    // Haven't heard back from the last request.  Assume we're
-                    // not getting a response and  release the wake lock.
-                    synchronized (mWakeLock) {
-                        if (mWakeLock.isHeld()) {
-                            // The timer of WAKE_LOCK_TIMEOUT is reset with each
-                            // new send request. So when WAKE_LOCK_TIMEOUT occurs
-                            // all requests in mRequestList already waited at
-                            // least DEFAULT_WAKE_LOCK_TIMEOUT but no response.
-                            // Reset mRequestMessagesWaiting to enable
-                            // releaseWakeLockIfDone().
-                            //
-                            // Note: Keep mRequestList so that delayed response
-                            // can still be handled when response finally comes.
-                            if (mRequestMessagesWaiting != 0) {
-                                Log.d(LOG_TAG, "NOTE: mReqWaiting is NOT 0 but"
-                                        + mRequestMessagesWaiting + " at TIMEOUT, reset!"
-                                        + " There still msg waitng for response");
-
-                                mRequestMessagesWaiting = 0;
-
-                                if (RILJ_LOGD) {
-                                    synchronized (mRequestsList) {
-                                        int count = mRequestsList.size();
-                                        Log.d(LOG_TAG, "WAKE_LOCK_TIMEOUT " +
-                                                " mRequestList=" + count);
-
-                                        for (int i = 0; i < count; i++) {
-                                            rr = mRequestsList.get(i);
-                                            Log.d(LOG_TAG, i + ": [" + rr.mSerial + "] "
-                                                    + requestToString(rr.mRequest));
-                                        }
-                                    }
-                                }
-                            }
-                            // mRequestMessagesPending shows how many
-                            // requests are waiting to be sent (and before
-                            // to be added in request list) since star the
-                            // WAKE_LOCK_TIMEOUT timer. Since WAKE_LOCK_TIMEOUT
-                            // is the expected time to get response, all requests
-                            // should already sent out (i.e.
-                            // mRequestMessagesPending is 0 )while TIMEOUT occurs.
-                            if (mRequestMessagesPending != 0) {
-                                Log.e(LOG_TAG, "ERROR: mReqPending is NOT 0 but"
-                                        + mRequestMessagesPending + " at TIMEOUT, reset!");
-                                mRequestMessagesPending = 0;
-
-                            }
-                            mWakeLock.release();
-                        }
-                    }
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Reads in a single RIL message off the wire. A RIL message consists
-     * of a 4-byte little-endian length and a subsequent series of bytes.
-     * The final message (length header omitted) is read into
-     * <code>buffer</code> and the length of the final message (less header)
-     * is returned. A return value of -1 indicates end-of-stream.
-     *
-     * @param is non-null; Stream to read from
-     * @param buffer Buffer to fill in. Must be as large as maximum
-     * message size, or an ArrayOutOfBounds exception will be thrown.
-     * @return Length of message less header, or -1 on end of stream.
-     * @throws IOException
-     */
-    private static int readRilMessage(InputStream is, byte[] buffer)
-            throws IOException {
-        int countRead;
-        int offset;
-        int remaining;
-        int messageLength;
-
-        // First, read in the length of the message
-        offset = 0;
-        remaining = 4;
-        do {
-            countRead = is.read(buffer, offset, remaining);
-
-            if (countRead < 0 ) {
-                Log.e(LOG_TAG, "Hit EOS reading message length");
-                return -1;
-            }
-
-            offset += countRead;
-            remaining -= countRead;
-        } while (remaining > 0);
-
-        messageLength = ((buffer[0] & 0xff) << 24)
-                | ((buffer[1] & 0xff) << 16)
-                | ((buffer[2] & 0xff) << 8)
-                | (buffer[3] & 0xff);
-
-        // Then, re-use the buffer and read in the message itself
-        offset = 0;
-        remaining = messageLength;
-        do {
-            countRead = is.read(buffer, offset, remaining);
-
-            if (countRead < 0 ) {
-                Log.e(LOG_TAG, "Hit EOS reading message.  messageLength=" + messageLength
-                        + " remaining=" + remaining);
-                return -1;
-            }
-
-            offset += countRead;
-            remaining -= countRead;
-        } while (remaining > 0);
-
-        return messageLength;
-    }
-
-    class RILReceiver implements Runnable {
-        byte[] buffer;
-
-        RILReceiver() {
-            buffer = new byte[RIL_MAX_COMMAND_BYTES];
-        }
-
-        public void
-        run() {
-            int retryCount = 0;
-
-            try {for (;;) {
-                LocalSocket s = null;
-                LocalSocketAddress l;
-
-                try {
-                    s = new LocalSocket();
-                    l = new LocalSocketAddress(SOCKET_NAME_RIL,
-                            LocalSocketAddress.Namespace.RESERVED);
-                    s.connect(l);
-                } catch (IOException ex){
-                    try {
-                        if (s != null) {
-                            s.close();
-                        }
-                    } catch (IOException ex2) {
-                        //ignore failure to close after failure to connect
-                    }
-
-                    // don't print an error message after the the first time
-                    // or after the 8th time
-
-                    if (retryCount == 8) {
-                        Log.e (LOG_TAG,
-                            "Couldn't find '" + SOCKET_NAME_RIL
-                            + "' socket after " + retryCount
-                            + " times, continuing to retry silently");
-                    } else if (retryCount > 0 && retryCount < 8) {
-                        Log.i (LOG_TAG,
-                            "Couldn't find '" + SOCKET_NAME_RIL
-                            + "' socket; retrying after timeout");
-                    }
-
-                    try {
-                        Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);
-                    } catch (InterruptedException er) {
-                    }
-
-                    retryCount++;
-                    continue;
-                }
-
-                retryCount = 0;
-
-                mSocket = s;
-                Log.i(LOG_TAG, "Connected to '" + SOCKET_NAME_RIL + "' socket");
-
-                int length = 0;
-                try {
-                    InputStream is = mSocket.getInputStream();
-
-                    for (;;) {
-                        Parcel p;
-
-                        length = readRilMessage(is, buffer);
-
-                        if (length < 0) {
-                            // End-of-stream reached
-                            break;
-                        }
-
-                        p = Parcel.obtain();
-                        p.unmarshall(buffer, 0, length);
-                        p.setDataPosition(0);
-
-                        //Log.v(LOG_TAG, "Read packet: " + length + " bytes");
-
-                        processResponse(p);
-                        p.recycle();
-                    }
-                } catch (java.io.IOException ex) {
-                    Log.i(LOG_TAG, "'" + SOCKET_NAME_RIL + "' socket closed",
-                          ex);
-                } catch (Throwable tr) {
-                    Log.e(LOG_TAG, "Uncaught exception read length=" + length +
-                        "Exception:" + tr.toString());
-                }
-
-                Log.i(LOG_TAG, "Disconnected from '" + SOCKET_NAME_RIL
-                      + "' socket");
-
-                setRadioState (RadioState.RADIO_UNAVAILABLE);
-
-                try {
-                    mSocket.close();
-                } catch (IOException ex) {
-                }
-
-                mSocket = null;
-                RILRequest.resetSerial();
-
-                // Clear request list on close
-                clearRequestsList(RADIO_NOT_AVAILABLE, false);
-            }} catch (Throwable tr) {
-                Log.e(LOG_TAG,"Uncaught exception", tr);
-            }
-
-            /* We're disconnected so we don't know the ril version */
-            notifyRegistrantsRilConnectionChanged(-1);
-        }
-    }
-
-
-
-    //***** Constructors
-
-    public RIL(Context context, int preferredNetworkType, int cdmaSubscription) {
-        super(context);
-        if (RILJ_LOGD) {
-            riljLog("RIL(context, preferredNetworkType=" + preferredNetworkType +
-                    " cdmaSubscription=" + cdmaSubscription + ")");
-        }
-        mCdmaSubscription  = cdmaSubscription;
-        mPreferredNetworkType = preferredNetworkType;
-        mPhoneType = RILConstants.NO_PHONE;
-
-        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
-        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
-        mWakeLock.setReferenceCounted(false);
-        mWakeLockTimeout = SystemProperties.getInt(TelephonyProperties.PROPERTY_WAKE_LOCK_TIMEOUT,
-                DEFAULT_WAKE_LOCK_TIMEOUT);
-        mRequestMessagesPending = 0;
-        mRequestMessagesWaiting = 0;
-
-        mSenderThread = new HandlerThread("RILSender");
-        mSenderThread.start();
-
-        Looper looper = mSenderThread.getLooper();
-        mSender = new RILSender(looper);
-
-        ConnectivityManager cm = (ConnectivityManager)context.getSystemService(
-                Context.CONNECTIVITY_SERVICE);
-        if (cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false) {
-            riljLog("Not starting RILReceiver: wifi-only");
-        } else {
-            riljLog("Starting RILReceiver");
-            mReceiver = new RILReceiver();
-            mReceiverThread = new Thread(mReceiver, "RILReceiver");
-            mReceiverThread.start();
-
-            IntentFilter filter = new IntentFilter();
-            filter.addAction(Intent.ACTION_SCREEN_ON);
-            filter.addAction(Intent.ACTION_SCREEN_OFF);
-            context.registerReceiver(mIntentReceiver, filter);
-        }
-    }
-
-    //***** CommandsInterface implementation
-
-    public void getVoiceRadioTechnology(Message result) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_VOICE_RADIO_TECH, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-
-    @Override public void
-    setOnNITZTime(Handler h, int what, Object obj) {
-        super.setOnNITZTime(h, what, obj);
-
-        // Send the last NITZ time if we have it
-        if (mLastNITZTimeInfo != null) {
-            mNITZTimeRegistrant
-                .notifyRegistrant(
-                    new AsyncResult (null, mLastNITZTimeInfo, null));
-            mLastNITZTimeInfo = null;
-        }
-    }
-
-    public void
-    getIccCardStatus(Message result) {
-        //Note: This RIL request has not been renamed to ICC,
-        //       but this request is also valid for SIM and RUIM
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_SIM_STATUS, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    @Override public void
-    supplyIccPin(String pin, Message result) {
-        supplyIccPinForApp(pin, null, result);
-    }
-
-    @Override public void
-    supplyIccPinForApp(String pin, String aid, Message result) {
-        //Note: This RIL request has not been renamed to ICC,
-        //       but this request is also valid for SIM and RUIM
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PIN, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        rr.mp.writeInt(2);
-        rr.mp.writeString(pin);
-        rr.mp.writeString(aid);
-
-        send(rr);
-    }
-
-    @Override public void
-    supplyIccPuk(String puk, String newPin, Message result) {
-        supplyIccPukForApp(puk, newPin, null, result);
-    }
-
-    @Override public void
-    supplyIccPukForApp(String puk, String newPin, String aid, Message result) {
-        //Note: This RIL request has not been renamed to ICC,
-        //       but this request is also valid for SIM and RUIM
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PUK, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        rr.mp.writeInt(3);
-        rr.mp.writeString(puk);
-        rr.mp.writeString(newPin);
-        rr.mp.writeString(aid);
-
-        send(rr);
-    }
-
-    @Override public void
-    supplyIccPin2(String pin, Message result) {
-        supplyIccPin2ForApp(pin, null, result);
-    }
-
-    @Override public void
-    supplyIccPin2ForApp(String pin, String aid, Message result) {
-        //Note: This RIL request has not been renamed to ICC,
-        //       but this request is also valid for SIM and RUIM
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PIN2, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        rr.mp.writeInt(2);
-        rr.mp.writeString(pin);
-        rr.mp.writeString(aid);
-
-        send(rr);
-    }
-
-    @Override public void
-    supplyIccPuk2(String puk2, String newPin2, Message result) {
-        supplyIccPuk2ForApp(puk2, newPin2, null, result);
-    }
-
-    @Override public void
-    supplyIccPuk2ForApp(String puk, String newPin2, String aid, Message result) {
-        //Note: This RIL request has not been renamed to ICC,
-        //       but this request is also valid for SIM and RUIM
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PUK2, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        rr.mp.writeInt(3);
-        rr.mp.writeString(puk);
-        rr.mp.writeString(newPin2);
-        rr.mp.writeString(aid);
-
-        send(rr);
-    }
-
-    @Override public void
-    changeIccPin(String oldPin, String newPin, Message result) {
-        changeIccPinForApp(oldPin, newPin, null, result);
-    }
-
-    @Override public void
-    changeIccPinForApp(String oldPin, String newPin, String aid, Message result) {
-        //Note: This RIL request has not been renamed to ICC,
-        //       but this request is also valid for SIM and RUIM
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_SIM_PIN, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        rr.mp.writeInt(3);
-        rr.mp.writeString(oldPin);
-        rr.mp.writeString(newPin);
-        rr.mp.writeString(aid);
-
-        send(rr);
-    }
-
-    @Override public void
-    changeIccPin2(String oldPin2, String newPin2, Message result) {
-        changeIccPin2ForApp(oldPin2, newPin2, null, result);
-    }
-
-    @Override public void
-    changeIccPin2ForApp(String oldPin2, String newPin2, String aid, Message result) {
-        //Note: This RIL request has not been renamed to ICC,
-        //       but this request is also valid for SIM and RUIM
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_SIM_PIN2, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        rr.mp.writeInt(3);
-        rr.mp.writeString(oldPin2);
-        rr.mp.writeString(newPin2);
-        rr.mp.writeString(aid);
-
-        send(rr);
-    }
-
-    public void
-    changeBarringPassword(String facility, String oldPwd, String newPwd, Message result) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_BARRING_PASSWORD, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        rr.mp.writeInt(3);
-        rr.mp.writeString(facility);
-        rr.mp.writeString(oldPwd);
-        rr.mp.writeString(newPwd);
-
-        send(rr);
-    }
-
-    public void
-    supplyNetworkDepersonalization(String netpin, Message result) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        rr.mp.writeInt(1);
-        rr.mp.writeString(netpin);
-
-        send(rr);
-    }
-
-    public void
-    getCurrentCalls (Message result) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_CURRENT_CALLS, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    @Deprecated public void
-    getPDPContextList(Message result) {
-        getDataCallList(result);
-    }
-
-    public void
-    getDataCallList(Message result) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_DATA_CALL_LIST, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void
-    dial (String address, int clirMode, Message result) {
-        dial(address, clirMode, null, result);
-    }
-
-    public void
-    dial(String address, int clirMode, UUSInfo uusInfo, Message result) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result);
-
-        rr.mp.writeString(address);
-        rr.mp.writeInt(clirMode);
-        rr.mp.writeInt(0); // UUS information is absent
-
-        if (uusInfo == null) {
-            rr.mp.writeInt(0); // UUS information is absent
-        } else {
-            rr.mp.writeInt(1); // UUS information is present
-            rr.mp.writeInt(uusInfo.getType());
-            rr.mp.writeInt(uusInfo.getDcs());
-            rr.mp.writeByteArray(uusInfo.getUserData());
-        }
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void
-    getIMSI(Message result) {
-        getIMSIForApp(null, result);
-    }
-
-    public void
-    getIMSIForApp(String aid, Message result) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMSI, result);
-
-        rr.mp.writeInt(1);
-        rr.mp.writeString(aid);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() +
-                              "> getIMSI: " + requestToString(rr.mRequest)
-                              + " aid: " + aid);
-
-        send(rr);
-    }
-
-    public void
-    getIMEI(Message result) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMEI, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void
-    getIMEISV(Message result) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMEISV, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-
-    public void
-    hangupConnection (int gsmIndex, Message result) {
-        if (RILJ_LOGD) riljLog("hangupConnection: gsmIndex=" + gsmIndex);
-
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_HANGUP, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " +
-                gsmIndex);
-
-        rr.mp.writeInt(1);
-        rr.mp.writeInt(gsmIndex);
-
-        send(rr);
-    }
-
-    public void
-    hangupWaitingOrBackground (Message result) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND,
-                                        result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void
-    hangupForegroundResumeBackground (Message result) {
-        RILRequest rr
-                = RILRequest.obtain(
-                        RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND,
-                                        result);
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void
-    switchWaitingOrHoldingAndActive (Message result) {
-        RILRequest rr
-                = RILRequest.obtain(
-                        RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE,
-                                        result);
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void
-    conference (Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_CONFERENCE, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-
-    public void setPreferredVoicePrivacy(boolean enable, Message result) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE,
-                result);
-
-        rr.mp.writeInt(1);
-        rr.mp.writeInt(enable ? 1:0);
-
-        send(rr);
-    }
-
-    public void getPreferredVoicePrivacy(Message result) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE,
-                result);
-        send(rr);
-    }
-
-    public void
-    separateConnection (int gsmIndex, Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_SEPARATE_CONNECTION, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                            + " " + gsmIndex);
-
-        rr.mp.writeInt(1);
-        rr.mp.writeInt(gsmIndex);
-
-        send(rr);
-    }
-
-    public void
-    acceptCall (Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_ANSWER, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void
-    rejectCall (Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_UDUB, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void
-    explicitCallTransfer (Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_EXPLICIT_CALL_TRANSFER, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void
-    getLastCallFailCause (Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_LAST_CALL_FAIL_CAUSE, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    /**
-     * @deprecated
-     */
-    public void
-    getLastPdpFailCause (Message result) {
-        getLastDataCallFailCause (result);
-    }
-
-    /**
-     * The preferred new alternative to getLastPdpFailCause
-     */
-    public void
-    getLastDataCallFailCause (Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void
-    setMute (boolean enableMute, Message response) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_SET_MUTE, response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                            + " " + enableMute);
-
-        rr.mp.writeInt(1);
-        rr.mp.writeInt(enableMute ? 1 : 0);
-
-        send(rr);
-    }
-
-    public void
-    getMute (Message response) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_GET_MUTE, response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void
-    getSignalStrength (Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_SIGNAL_STRENGTH, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void
-    getVoiceRegistrationState (Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_VOICE_REGISTRATION_STATE, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void
-    getDataRegistrationState (Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_DATA_REGISTRATION_STATE, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void
-    getOperator(Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_OPERATOR, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void
-    sendDtmf(char c, Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_DTMF, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        rr.mp.writeString(Character.toString(c));
-
-        send(rr);
-    }
-
-    public void
-    startDtmf(char c, Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_DTMF_START, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        rr.mp.writeString(Character.toString(c));
-
-        send(rr);
-    }
-
-    public void
-    stopDtmf(Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_DTMF_STOP, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void
-    sendBurstDtmf(String dtmfString, int on, int off, Message result) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_BURST_DTMF, result);
-
-        rr.mp.writeInt(3);
-        rr.mp.writeString(dtmfString);
-        rr.mp.writeString(Integer.toString(on));
-        rr.mp.writeString(Integer.toString(off));
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                + " : " + dtmfString);
-
-        send(rr);
-    }
-
-    public void
-    sendSMS (String smscPDU, String pdu, Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_SEND_SMS, result);
-
-        rr.mp.writeInt(2);
-        rr.mp.writeString(smscPDU);
-        rr.mp.writeString(pdu);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void
-    sendCdmaSms(byte[] pdu, Message result) {
-        int address_nbr_of_digits;
-        int subaddr_nbr_of_digits;
-        int bearerDataLength;
-        ByteArrayInputStream bais = new ByteArrayInputStream(pdu);
-        DataInputStream dis = new DataInputStream(bais);
-
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_CDMA_SEND_SMS, result);
-
-        try {
-            rr.mp.writeInt(dis.readInt()); //teleServiceId
-            rr.mp.writeByte((byte) dis.readInt()); //servicePresent
-            rr.mp.writeInt(dis.readInt()); //serviceCategory
-            rr.mp.writeInt(dis.read()); //address_digit_mode
-            rr.mp.writeInt(dis.read()); //address_nbr_mode
-            rr.mp.writeInt(dis.read()); //address_ton
-            rr.mp.writeInt(dis.read()); //address_nbr_plan
-            address_nbr_of_digits = (byte) dis.read();
-            rr.mp.writeByte((byte) address_nbr_of_digits);
-            for(int i=0; i < address_nbr_of_digits; i++){
-                rr.mp.writeByte(dis.readByte()); // address_orig_bytes[i]
-            }
-            rr.mp.writeInt(dis.read()); //subaddressType
-            rr.mp.writeByte((byte) dis.read()); //subaddr_odd
-            subaddr_nbr_of_digits = (byte) dis.read();
-            rr.mp.writeByte((byte) subaddr_nbr_of_digits);
-            for(int i=0; i < subaddr_nbr_of_digits; i++){
-                rr.mp.writeByte(dis.readByte()); //subaddr_orig_bytes[i]
-            }
-
-            bearerDataLength = dis.read();
-            rr.mp.writeInt(bearerDataLength);
-            for(int i=0; i < bearerDataLength; i++){
-                rr.mp.writeByte(dis.readByte()); //bearerData[i]
-            }
-        }catch (IOException ex){
-            if (RILJ_LOGD) riljLog("sendSmsCdma: conversion from input stream to object failed: "
-                    + ex);
-        }
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void deleteSmsOnSim(int index, Message response) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_DELETE_SMS_ON_SIM,
-                response);
-
-        rr.mp.writeInt(1);
-        rr.mp.writeInt(index);
-
-        if (false) {
-            if (RILJ_LOGD) riljLog(rr.serialString() + "> "
-                    + requestToString(rr.mRequest)
-                    + " " + index);
-        }
-
-        send(rr);
-    }
-
-    public void deleteSmsOnRuim(int index, Message response) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM,
-                response);
-
-        rr.mp.writeInt(1);
-        rr.mp.writeInt(index);
-
-        if (false) {
-            if (RILJ_LOGD) riljLog(rr.serialString() + "> "
-                    + requestToString(rr.mRequest)
-                    + " " + index);
-        }
-
-        send(rr);
-    }
-
-    public void writeSmsToSim(int status, String smsc, String pdu, Message response) {
-        status = translateStatus(status);
-
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_WRITE_SMS_TO_SIM,
-                response);
-
-        rr.mp.writeInt(status);
-        rr.mp.writeString(pdu);
-        rr.mp.writeString(smsc);
-
-        if (false) {
-            if (RILJ_LOGD) riljLog(rr.serialString() + "> "
-                    + requestToString(rr.mRequest)
-                    + " " + status);
-        }
-
-        send(rr);
-    }
-
-    public void writeSmsToRuim(int status, String pdu, Message response) {
-        status = translateStatus(status);
-
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM,
-                response);
-
-        rr.mp.writeInt(status);
-        rr.mp.writeString(pdu);
-
-        if (false) {
-            if (RILJ_LOGD) riljLog(rr.serialString() + "> "
-                    + requestToString(rr.mRequest)
-                    + " " + status);
-        }
-
-        send(rr);
-    }
-
-    /**
-     *  Translates EF_SMS status bits to a status value compatible with
-     *  SMS AT commands.  See TS 27.005 3.1.
-     */
-    private int translateStatus(int status) {
-        switch(status & 0x7) {
-            case SmsManager.STATUS_ON_ICC_READ:
-                return 1;
-            case SmsManager.STATUS_ON_ICC_UNREAD:
-                return 0;
-            case SmsManager.STATUS_ON_ICC_SENT:
-                return 3;
-            case SmsManager.STATUS_ON_ICC_UNSENT:
-                return 2;
-        }
-
-        // Default to READ.
-        return 1;
-    }
-
-    public void
-    setupDataCall(String radioTechnology, String profile, String apn,
-            String user, String password, String authType, String protocol,
-            Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_SETUP_DATA_CALL, result);
-
-        rr.mp.writeInt(7);
-
-        rr.mp.writeString(radioTechnology);
-        rr.mp.writeString(profile);
-        rr.mp.writeString(apn);
-        rr.mp.writeString(user);
-        rr.mp.writeString(password);
-        rr.mp.writeString(authType);
-        rr.mp.writeString(protocol);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> "
-                + requestToString(rr.mRequest) + " " + radioTechnology + " "
-                + profile + " " + apn + " " + user + " "
-                + password + " " + authType + " " + protocol);
-
-        send(rr);
-    }
-
-    public void
-    deactivateDataCall(int cid, int reason, Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_DEACTIVATE_DATA_CALL, result);
-
-        rr.mp.writeInt(2);
-        rr.mp.writeString(Integer.toString(cid));
-        rr.mp.writeString(Integer.toString(reason));
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " +
-                requestToString(rr.mRequest) + " " + cid + " " + reason);
-
-        send(rr);
-    }
-
-    public void
-    setRadioPower(boolean on, Message result) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_RADIO_POWER, result);
-
-        rr.mp.writeInt(1);
-        rr.mp.writeInt(on ? 1 : 0);
-
-        if (RILJ_LOGD) {
-            riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                    + (on ? " on" : " off"));
-        }
-
-        send(rr);
-    }
-
-    public void
-    setSuppServiceNotifications(boolean enable, Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, result);
-
-        rr.mp.writeInt(1);
-        rr.mp.writeInt(enable ? 1 : 0);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> "
-                + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void
-    acknowledgeLastIncomingGsmSms(boolean success, int cause, Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_SMS_ACKNOWLEDGE, result);
-
-        rr.mp.writeInt(2);
-        rr.mp.writeInt(success ? 1 : 0);
-        rr.mp.writeInt(cause);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                + " " + success + " " + cause);
-
-        send(rr);
-    }
-
-    public void
-    acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE, result);
-
-        rr.mp.writeInt(success ? 0 : 1); //RIL_CDMA_SMS_ErrorClass
-        // cause code according to X.S004-550E
-        rr.mp.writeInt(cause);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                + " " + success + " " + cause);
-
-        send(rr);
-    }
-
-    public void
-    acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu, Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU, result);
-
-        rr.mp.writeInt(2);
-        rr.mp.writeString(success ? "1" : "0");
-        rr.mp.writeString(ackPdu);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                + ' ' + success + " [" + ackPdu + ']');
-
-        send(rr);
-    }
-
-    public void
-    iccIO (int command, int fileid, String path, int p1, int p2, int p3,
-            String data, String pin2, Message result) {
-        iccIOForApp(command, fileid, path, p1, p2, p3, data, pin2, null, result);
-    }
-    public void
-    iccIOForApp (int command, int fileid, String path, int p1, int p2, int p3,
-            String data, String pin2, String aid, Message result) {
-        //Note: This RIL request has not been renamed to ICC,
-        //       but this request is also valid for SIM and RUIM
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_SIM_IO, result);
-
-        rr.mp.writeInt(command);
-        rr.mp.writeInt(fileid);
-        rr.mp.writeString(path);
-        rr.mp.writeInt(p1);
-        rr.mp.writeInt(p2);
-        rr.mp.writeInt(p3);
-        rr.mp.writeString(data);
-        rr.mp.writeString(pin2);
-        rr.mp.writeString(aid);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> iccIO: "
-                + requestToString(rr.mRequest)
-                + " 0x" + Integer.toHexString(command)
-                + " 0x" + Integer.toHexString(fileid) + " "
-                + " path: " + path + ","
-                + p1 + "," + p2 + "," + p3
-                + " aid: " + aid);
-
-        send(rr);
-    }
-
-    public void
-    getCLIR(Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_GET_CLIR, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void
-    setCLIR(int clirMode, Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_SET_CLIR, result);
-
-        // count ints
-        rr.mp.writeInt(1);
-
-        rr.mp.writeInt(clirMode);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                    + " " + clirMode);
-
-        send(rr);
-    }
-
-    public void
-    queryCallWaiting(int serviceClass, Message response) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_QUERY_CALL_WAITING, response);
-
-        rr.mp.writeInt(1);
-        rr.mp.writeInt(serviceClass);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                    + " " + serviceClass);
-
-        send(rr);
-    }
-
-    public void
-    setCallWaiting(boolean enable, int serviceClass, Message response) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_SET_CALL_WAITING, response);
-
-        rr.mp.writeInt(2);
-        rr.mp.writeInt(enable ? 1 : 0);
-        rr.mp.writeInt(serviceClass);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                + " " + enable + ", " + serviceClass);
-
-        send(rr);
-    }
-
-    public void
-    setNetworkSelectionModeAutomatic(Message response) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC,
-                                    response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void
-    setNetworkSelectionModeManual(String operatorNumeric, Message response) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL,
-                                    response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                    + " " + operatorNumeric);
-
-        rr.mp.writeString(operatorNumeric);
-
-        send(rr);
-    }
-
-    public void
-    getNetworkSelectionMode(Message response) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE,
-                                    response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void
-    getAvailableNetworks(Message response) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_QUERY_AVAILABLE_NETWORKS,
-                                    response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void
-    setCallForward(int action, int cfReason, int serviceClass,
-                String number, int timeSeconds, Message response) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_SET_CALL_FORWARD, response);
-
-        rr.mp.writeInt(action);
-        rr.mp.writeInt(cfReason);
-        rr.mp.writeInt(serviceClass);
-        rr.mp.writeInt(PhoneNumberUtils.toaFromString(number));
-        rr.mp.writeString(number);
-        rr.mp.writeInt (timeSeconds);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                    + " " + action + " " + cfReason + " " + serviceClass
-                    + timeSeconds);
-
-        send(rr);
-    }
-
-    public void
-    queryCallForwardStatus(int cfReason, int serviceClass,
-                String number, Message response) {
-        RILRequest rr
-            = RILRequest.obtain(RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, response);
-
-        rr.mp.writeInt(2); // 2 is for query action, not in used anyway
-        rr.mp.writeInt(cfReason);
-        rr.mp.writeInt(serviceClass);
-        rr.mp.writeInt(PhoneNumberUtils.toaFromString(number));
-        rr.mp.writeString(number);
-        rr.mp.writeInt (0);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                + " " + cfReason + " " + serviceClass);
-
-        send(rr);
-    }
-
-    public void
-    queryCLIP(Message response) {
-        RILRequest rr
-            = RILRequest.obtain(RIL_REQUEST_QUERY_CLIP, response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-
-    public void
-    getBasebandVersion (Message response) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_BASEBAND_VERSION, response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    @Override
-    public void
-    queryFacilityLock(String facility, String password, int serviceClass,
-                            Message response) {
-        queryFacilityLockForApp(facility, password, serviceClass, null, response);
-    }
-
-    @Override
-    public void
-    queryFacilityLockForApp(String facility, String password, int serviceClass, String appId,
-                            Message response) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_QUERY_FACILITY_LOCK, response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        // count strings
-        rr.mp.writeInt(4);
-
-        rr.mp.writeString(facility);
-        rr.mp.writeString(password);
-
-        rr.mp.writeString(Integer.toString(serviceClass));
-        rr.mp.writeString(appId);
-
-        send(rr);
-    }
-
-    @Override
-    public void
-    setFacilityLock (String facility, boolean lockState, String password,
-                        int serviceClass, Message response) {
-        setFacilityLockForApp(facility, lockState, password, serviceClass, null, response);
-    }
-
-    @Override
-    public void
-    setFacilityLockForApp(String facility, boolean lockState, String password,
-                        int serviceClass, String appId, Message response) {
-        String lockString;
-         RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_SET_FACILITY_LOCK, response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        // count strings
-        rr.mp.writeInt(5);
-
-        rr.mp.writeString(facility);
-        lockString = (lockState)?"1":"0";
-        rr.mp.writeString(lockString);
-        rr.mp.writeString(password);
-        rr.mp.writeString(Integer.toString(serviceClass));
-        rr.mp.writeString(appId);
-
-        send(rr);
-
-    }
-
-    public void
-    sendUSSD (String ussdString, Message response) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_SEND_USSD, response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                            + " " + ussdString);
-
-        rr.mp.writeString(ussdString);
-
-        send(rr);
-    }
-
-    // inherited javadoc suffices
-    public void cancelPendingUssd (Message response) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_CANCEL_USSD, response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString()
-                + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-
-    public void resetRadio(Message result) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_RESET_RADIO, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void invokeOemRilRequestRaw(byte[] data, Message response) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_OEM_HOOK_RAW, response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-               + "[" + IccUtils.bytesToHexString(data) + "]");
-
-        rr.mp.writeByteArray(data);
-
-        send(rr);
-
-    }
-
-    public void invokeOemRilRequestStrings(String[] strings, Message response) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_OEM_HOOK_STRINGS, response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        rr.mp.writeStringArray(strings);
-
-        send(rr);
-    }
-
-     /**
-     * Assign a specified band for RF configuration.
-     *
-     * @param bandMode one of BM_*_BAND
-     * @param response is callback message
-     */
-    public void setBandMode (int bandMode, Message response) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_SET_BAND_MODE, response);
-
-        rr.mp.writeInt(1);
-        rr.mp.writeInt(bandMode);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                 + " " + bandMode);
-
-        send(rr);
-     }
-
-    /**
-     * Query the list of band mode supported by RF.
-     *
-     * @param response is callback message
-     *        ((AsyncResult)response.obj).result  is an int[] with every
-     *        element representing one avialable BM_*_BAND
-     */
-    public void queryAvailableBandMode (Message response) {
-        RILRequest rr
-                = RILRequest.obtain(RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE,
-                response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void sendTerminalResponse(String contents, Message response) {
-        RILRequest rr = RILRequest.obtain(
-                RILConstants.RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE, response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        rr.mp.writeString(contents);
-        send(rr);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void sendEnvelope(String contents, Message response) {
-        RILRequest rr = RILRequest.obtain(
-                RILConstants.RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND, response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        rr.mp.writeString(contents);
-        send(rr);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void sendEnvelopeWithStatus(String contents, Message response) {
-        RILRequest rr = RILRequest.obtain(
-                RILConstants.RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                + '[' + contents + ']');
-
-        rr.mp.writeString(contents);
-        send(rr);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void handleCallSetupRequestFromSim(
-            boolean accept, Message response) {
-
-        RILRequest rr = RILRequest.obtain(
-            RILConstants.RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM,
-            response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        int[] param = new int[1];
-        param[0] = accept ? 1 : 0;
-        rr.mp.writeIntArray(param);
-        send(rr);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setCurrentPreferredNetworkType() {
-        if (RILJ_LOGD) riljLog("setCurrentPreferredNetworkType: " + mSetPreferredNetworkType);
-        setPreferredNetworkType(mSetPreferredNetworkType, null);
-    }
-    private int mSetPreferredNetworkType;
-
-    /**
-     * {@inheritDoc}
-     */
-    public void setPreferredNetworkType(int networkType , Message response) {
-        RILRequest rr = RILRequest.obtain(
-                RILConstants.RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, response);
-
-        rr.mp.writeInt(1);
-        rr.mp.writeInt(networkType);
-
-        mSetPreferredNetworkType = networkType;
-        mPreferredNetworkType = networkType;
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                + " : " + networkType);
-
-        send(rr);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void getPreferredNetworkType(Message response) {
-        RILRequest rr = RILRequest.obtain(
-                RILConstants.RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void getNeighboringCids(Message response) {
-        RILRequest rr = RILRequest.obtain(
-                RILConstants.RIL_REQUEST_GET_NEIGHBORING_CELL_IDS, response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void setLocationUpdates(boolean enable, Message response) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_LOCATION_UPDATES, response);
-        rr.mp.writeInt(1);
-        rr.mp.writeInt(enable ? 1 : 0);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> "
-                + requestToString(rr.mRequest) + ": " + enable);
-
-        send(rr);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void getSmscAddress(Message result) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_SMSC_ADDRESS, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void setSmscAddress(String address, Message result) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_SMSC_ADDRESS, result);
-
-        rr.mp.writeString(address);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                + " : " + address);
-
-        send(rr);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void reportSmsMemoryStatus(boolean available, Message result) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, result);
-        rr.mp.writeInt(1);
-        rr.mp.writeInt(available ? 1 : 0);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> "
-                + requestToString(rr.mRequest) + ": " + available);
-
-        send(rr);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void reportStkServiceIsRunning(Message result) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING, result);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void getGsmBroadcastConfig(Message response) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_GSM_GET_BROADCAST_CONFIG, response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_GSM_SET_BROADCAST_CONFIG, response);
-
-        int numOfConfig = config.length;
-        rr.mp.writeInt(numOfConfig);
-
-        for(int i = 0; i < numOfConfig; i++) {
-            rr.mp.writeInt(config[i].getFromServiceId());
-            rr.mp.writeInt(config[i].getToServiceId());
-            rr.mp.writeInt(config[i].getFromCodeScheme());
-            rr.mp.writeInt(config[i].getToCodeScheme());
-            rr.mp.writeInt(config[i].isSelected() ? 1 : 0);
-        }
-
-        if (RILJ_LOGD) {
-            riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                    + " with " + numOfConfig + " configs : ");
-            for (int i = 0; i < numOfConfig; i++) {
-                riljLog(config[i].toString());
-            }
-        }
-
-        send(rr);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void setGsmBroadcastActivation(boolean activate, Message response) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_GSM_BROADCAST_ACTIVATION, response);
-
-        rr.mp.writeInt(1);
-        rr.mp.writeInt(activate ? 0 : 1);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    //***** Private Methods
-
-    private void sendScreenState(boolean on) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_SCREEN_STATE, null);
-        rr.mp.writeInt(1);
-        rr.mp.writeInt(on ? 1 : 0);
-
-        if (RILJ_LOGD) riljLog(rr.serialString()
-                + "> " + requestToString(rr.mRequest) + ": " + on);
-
-        send(rr);
-    }
-
-    protected void
-    onRadioAvailable() {
-        // In case screen state was lost (due to process crash),
-        // this ensures that the RIL knows the correct screen state.
-
-        // TODO: Should query Power Manager and send the actual
-        // screen state.  Just send true for now.
-        sendScreenState(true);
-   }
-
-    private RadioState getRadioStateFromInt(int stateInt) {
-        RadioState state;
-
-        /* RIL_RadioState ril.h */
-        switch(stateInt) {
-            case 0: state = RadioState.RADIO_OFF; break;
-            case 1: state = RadioState.RADIO_UNAVAILABLE; break;
-            case 10: state = RadioState.RADIO_ON; break;
-
-            default:
-                throw new RuntimeException(
-                            "Unrecognized RIL_RadioState: " + stateInt);
-        }
-        return state;
-    }
-
-    private void switchToRadioState(RadioState newState) {
-        setRadioState(newState);
-    }
-
-    /**
-     * Holds a PARTIAL_WAKE_LOCK whenever
-     * a) There is outstanding RIL request sent to RIL deamon and no replied
-     * b) There is a request pending to be sent out.
-     *
-     * There is a WAKE_LOCK_TIMEOUT to release the lock, though it shouldn't
-     * happen often.
-     */
-
-    private void
-    acquireWakeLock() {
-        synchronized (mWakeLock) {
-            mWakeLock.acquire();
-            mRequestMessagesPending++;
-
-            mSender.removeMessages(EVENT_WAKE_LOCK_TIMEOUT);
-            Message msg = mSender.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT);
-            mSender.sendMessageDelayed(msg, mWakeLockTimeout);
-        }
-    }
-
-    private void
-    releaseWakeLockIfDone() {
-        synchronized (mWakeLock) {
-            if (mWakeLock.isHeld() &&
-                (mRequestMessagesPending == 0) &&
-                (mRequestMessagesWaiting == 0)) {
-                mSender.removeMessages(EVENT_WAKE_LOCK_TIMEOUT);
-                mWakeLock.release();
-            }
-        }
-    }
-
-    private void
-    send(RILRequest rr) {
-        Message msg;
-
-        if (mSocket == null) {
-            rr.onError(RADIO_NOT_AVAILABLE, null);
-            rr.release();
-            return;
-        }
-
-        msg = mSender.obtainMessage(EVENT_SEND, rr);
-
-        acquireWakeLock();
-
-        msg.sendToTarget();
-    }
-
-    private void
-    processResponse (Parcel p) {
-        int type;
-
-        type = p.readInt();
-
-        if (type == RESPONSE_UNSOLICITED) {
-            processUnsolicited (p);
-        } else if (type == RESPONSE_SOLICITED) {
-            processSolicited (p);
-        }
-
-        releaseWakeLockIfDone();
-    }
-
-    /**
-     * Release each request in mReqeustsList then clear the list
-     * @param error is the RIL_Errno sent back
-     * @param loggable true means to print all requests in mRequestslist
-     */
-    private void clearRequestsList(int error, boolean loggable) {
-        RILRequest rr;
-        synchronized (mRequestsList) {
-            int count = mRequestsList.size();
-            if (RILJ_LOGD && loggable) {
-                Log.d(LOG_TAG, "WAKE_LOCK_TIMEOUT " +
-                        " mReqPending=" + mRequestMessagesPending +
-                        " mRequestList=" + count);
-            }
-
-            for (int i = 0; i < count ; i++) {
-                rr = mRequestsList.get(i);
-                if (RILJ_LOGD && loggable) {
-                    Log.d(LOG_TAG, i + ": [" + rr.mSerial + "] " +
-                            requestToString(rr.mRequest));
-                }
-                rr.onError(error, null);
-                rr.release();
-            }
-            mRequestsList.clear();
-            mRequestMessagesWaiting = 0;
-        }
-    }
-
-    private RILRequest findAndRemoveRequestFromList(int serial) {
-        synchronized (mRequestsList) {
-            for (int i = 0, s = mRequestsList.size() ; i < s ; i++) {
-                RILRequest rr = mRequestsList.get(i);
-
-                if (rr.mSerial == serial) {
-                    mRequestsList.remove(i);
-                    if (mRequestMessagesWaiting > 0)
-                        mRequestMessagesWaiting--;
-                    return rr;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    private void
-    processSolicited (Parcel p) {
-        int serial, error;
-        boolean found = false;
-
-        serial = p.readInt();
-        error = p.readInt();
-
-        RILRequest rr;
-
-        rr = findAndRemoveRequestFromList(serial);
-
-        if (rr == null) {
-            Log.w(LOG_TAG, "Unexpected solicited response! sn: "
-                            + serial + " error: " + error);
-            return;
-        }
-
-        Object ret = null;
-
-        if (error == 0 || p.dataAvail() > 0) {
-            // either command succeeds or command fails but with data payload
-            try {switch (rr.mRequest) {
-            /*
- cat libs/telephony/ril_commands.h \
- | egrep "^ *{RIL_" \
- | sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: ret = \2(p); break;/'
-             */
-            case RIL_REQUEST_GET_SIM_STATUS: ret =  responseIccCardStatus(p); break;
-            case RIL_REQUEST_ENTER_SIM_PIN: ret =  responseInts(p); break;
-            case RIL_REQUEST_ENTER_SIM_PUK: ret =  responseInts(p); break;
-            case RIL_REQUEST_ENTER_SIM_PIN2: ret =  responseInts(p); break;
-            case RIL_REQUEST_ENTER_SIM_PUK2: ret =  responseInts(p); break;
-            case RIL_REQUEST_CHANGE_SIM_PIN: ret =  responseInts(p); break;
-            case RIL_REQUEST_CHANGE_SIM_PIN2: ret =  responseInts(p); break;
-            case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: ret =  responseInts(p); break;
-            case RIL_REQUEST_GET_CURRENT_CALLS: ret =  responseCallList(p); break;
-            case RIL_REQUEST_DIAL: ret =  responseVoid(p); break;
-            case RIL_REQUEST_GET_IMSI: ret =  responseString(p); break;
-            case RIL_REQUEST_HANGUP: ret =  responseVoid(p); break;
-            case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: ret =  responseVoid(p); break;
-            case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: {
-                if (mTestingEmergencyCall.getAndSet(false)) {
-                    if (mEmergencyCallbackModeRegistrant != null) {
-                        riljLog("testing emergency call, notify ECM Registrants");
-                        mEmergencyCallbackModeRegistrant.notifyRegistrant();
-                    }
-                }
-                ret =  responseVoid(p);
-                break;
-            }
-            case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: ret =  responseVoid(p); break;
-            case RIL_REQUEST_CONFERENCE: ret =  responseVoid(p); break;
-            case RIL_REQUEST_UDUB: ret =  responseVoid(p); break;
-            case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: ret =  responseInts(p); break;
-            case RIL_REQUEST_SIGNAL_STRENGTH: ret =  responseSignalStrength(p); break;
-            case RIL_REQUEST_VOICE_REGISTRATION_STATE: ret =  responseStrings(p); break;
-            case RIL_REQUEST_DATA_REGISTRATION_STATE: ret =  responseStrings(p); break;
-            case RIL_REQUEST_OPERATOR: ret =  responseStrings(p); break;
-            case RIL_REQUEST_RADIO_POWER: ret =  responseVoid(p); break;
-            case RIL_REQUEST_DTMF: ret =  responseVoid(p); break;
-            case RIL_REQUEST_SEND_SMS: ret =  responseSMS(p); break;
-            case RIL_REQUEST_SEND_SMS_EXPECT_MORE: ret =  responseSMS(p); break;
-            case RIL_REQUEST_SETUP_DATA_CALL: ret =  responseSetupDataCall(p); break;
-            case RIL_REQUEST_SIM_IO: ret =  responseICC_IO(p); break;
-            case RIL_REQUEST_SEND_USSD: ret =  responseVoid(p); break;
-            case RIL_REQUEST_CANCEL_USSD: ret =  responseVoid(p); break;
-            case RIL_REQUEST_GET_CLIR: ret =  responseInts(p); break;
-            case RIL_REQUEST_SET_CLIR: ret =  responseVoid(p); break;
-            case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: ret =  responseCallForward(p); break;
-            case RIL_REQUEST_SET_CALL_FORWARD: ret =  responseVoid(p); break;
-            case RIL_REQUEST_QUERY_CALL_WAITING: ret =  responseInts(p); break;
-            case RIL_REQUEST_SET_CALL_WAITING: ret =  responseVoid(p); break;
-            case RIL_REQUEST_SMS_ACKNOWLEDGE: ret =  responseVoid(p); break;
-            case RIL_REQUEST_GET_IMEI: ret =  responseString(p); break;
-            case RIL_REQUEST_GET_IMEISV: ret =  responseString(p); break;
-            case RIL_REQUEST_ANSWER: ret =  responseVoid(p); break;
-            case RIL_REQUEST_DEACTIVATE_DATA_CALL: ret =  responseVoid(p); break;
-            case RIL_REQUEST_QUERY_FACILITY_LOCK: ret =  responseInts(p); break;
-            case RIL_REQUEST_SET_FACILITY_LOCK: ret =  responseInts(p); break;
-            case RIL_REQUEST_CHANGE_BARRING_PASSWORD: ret =  responseVoid(p); break;
-            case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: ret =  responseInts(p); break;
-            case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: ret =  responseVoid(p); break;
-            case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: ret =  responseVoid(p); break;
-            case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : ret =  responseOperatorInfos(p); break;
-            case RIL_REQUEST_DTMF_START: ret =  responseVoid(p); break;
-            case RIL_REQUEST_DTMF_STOP: ret =  responseVoid(p); break;
-            case RIL_REQUEST_BASEBAND_VERSION: ret =  responseString(p); break;
-            case RIL_REQUEST_SEPARATE_CONNECTION: ret =  responseVoid(p); break;
-            case RIL_REQUEST_SET_MUTE: ret =  responseVoid(p); break;
-            case RIL_REQUEST_GET_MUTE: ret =  responseInts(p); break;
-            case RIL_REQUEST_QUERY_CLIP: ret =  responseInts(p); break;
-            case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: ret =  responseInts(p); break;
-            case RIL_REQUEST_DATA_CALL_LIST: ret =  responseDataCallList(p); break;
-            case RIL_REQUEST_RESET_RADIO: ret =  responseVoid(p); break;
-            case RIL_REQUEST_OEM_HOOK_RAW: ret =  responseRaw(p); break;
-            case RIL_REQUEST_OEM_HOOK_STRINGS: ret =  responseStrings(p); break;
-            case RIL_REQUEST_SCREEN_STATE: ret =  responseVoid(p); break;
-            case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: ret =  responseVoid(p); break;
-            case RIL_REQUEST_WRITE_SMS_TO_SIM: ret =  responseInts(p); break;
-            case RIL_REQUEST_DELETE_SMS_ON_SIM: ret =  responseVoid(p); break;
-            case RIL_REQUEST_SET_BAND_MODE: ret =  responseVoid(p); break;
-            case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: ret =  responseInts(p); break;
-            case RIL_REQUEST_STK_GET_PROFILE: ret =  responseString(p); break;
-            case RIL_REQUEST_STK_SET_PROFILE: ret =  responseVoid(p); break;
-            case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: ret =  responseString(p); break;
-            case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: ret =  responseVoid(p); break;
-            case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: ret =  responseInts(p); break;
-            case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: ret =  responseVoid(p); break;
-            case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: ret =  responseVoid(p); break;
-            case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: ret =  responseGetPreferredNetworkType(p); break;
-            case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: ret = responseCellList(p); break;
-            case RIL_REQUEST_SET_LOCATION_UPDATES: ret =  responseVoid(p); break;
-            case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: ret =  responseVoid(p); break;
-            case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: ret =  responseVoid(p); break;
-            case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: ret =  responseInts(p); break;
-            case RIL_REQUEST_SET_TTY_MODE: ret =  responseVoid(p); break;
-            case RIL_REQUEST_QUERY_TTY_MODE: ret =  responseInts(p); break;
-            case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE: ret =  responseVoid(p); break;
-            case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE: ret =  responseInts(p); break;
-            case RIL_REQUEST_CDMA_FLASH: ret =  responseVoid(p); break;
-            case RIL_REQUEST_CDMA_BURST_DTMF: ret =  responseVoid(p); break;
-            case RIL_REQUEST_CDMA_SEND_SMS: ret =  responseSMS(p); break;
-            case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: ret =  responseVoid(p); break;
-            case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG: ret =  responseGmsBroadcastConfig(p); break;
-            case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG: ret =  responseVoid(p); break;
-            case RIL_REQUEST_GSM_BROADCAST_ACTIVATION: ret =  responseVoid(p); break;
-            case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: ret =  responseCdmaBroadcastConfig(p); break;
-            case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: ret =  responseVoid(p); break;
-            case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: ret =  responseVoid(p); break;
-            case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: ret =  responseVoid(p); break;
-            case RIL_REQUEST_CDMA_SUBSCRIPTION: ret =  responseStrings(p); break;
-            case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: ret =  responseInts(p); break;
-            case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: ret =  responseVoid(p); break;
-            case RIL_REQUEST_DEVICE_IDENTITY: ret =  responseStrings(p); break;
-            case RIL_REQUEST_GET_SMSC_ADDRESS: ret = responseString(p); break;
-            case RIL_REQUEST_SET_SMSC_ADDRESS: ret = responseVoid(p); break;
-            case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
-            case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: ret = responseVoid(p); break;
-            case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: ret = responseVoid(p); break;
-            case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: ret =  responseInts(p); break;
-            case RIL_REQUEST_ISIM_AUTHENTICATION: ret =  responseString(p); break;
-            case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: ret = responseVoid(p); break;
-            case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: ret = responseICC_IO(p); break;
-            case RIL_REQUEST_VOICE_RADIO_TECH: ret = responseInts(p); break;
-            default:
-                throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
-            //break;
-            }} catch (Throwable tr) {
-                // Exceptions here usually mean invalid RIL responses
-
-                Log.w(LOG_TAG, rr.serialString() + "< "
-                        + requestToString(rr.mRequest)
-                        + " exception, possible invalid RIL response", tr);
-
-                if (rr.mResult != null) {
-                    AsyncResult.forMessage(rr.mResult, null, tr);
-                    rr.mResult.sendToTarget();
-                }
-                rr.release();
-                return;
-            }
-        }
-
-        if (error != 0) {
-            rr.onError(error, ret);
-            rr.release();
-            return;
-        }
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "< " + requestToString(rr.mRequest)
-            + " " + retToString(rr.mRequest, ret));
-
-        if (rr.mResult != null) {
-            AsyncResult.forMessage(rr.mResult, ret, null);
-            rr.mResult.sendToTarget();
-        }
-
-        rr.release();
-    }
-
-    private String
-    retToString(int req, Object ret) {
-        if (ret == null) return "";
-        switch (req) {
-            // Don't log these return values, for privacy's sake.
-            case RIL_REQUEST_GET_IMSI:
-            case RIL_REQUEST_GET_IMEI:
-            case RIL_REQUEST_GET_IMEISV:
-                if (!RILJ_LOGV) {
-                    // If not versbose logging just return and don't display IMSI and IMEI, IMEISV
-                    return "";
-                }
-        }
-
-        StringBuilder sb;
-        String s;
-        int length;
-        if (ret instanceof int[]){
-            int[] intArray = (int[]) ret;
-            length = intArray.length;
-            sb = new StringBuilder("{");
-            if (length > 0) {
-                int i = 0;
-                sb.append(intArray[i++]);
-                while ( i < length) {
-                    sb.append(", ").append(intArray[i++]);
-                }
-            }
-            sb.append("}");
-            s = sb.toString();
-        } else if (ret instanceof String[]) {
-            String[] strings = (String[]) ret;
-            length = strings.length;
-            sb = new StringBuilder("{");
-            if (length > 0) {
-                int i = 0;
-                sb.append(strings[i++]);
-                while ( i < length) {
-                    sb.append(", ").append(strings[i++]);
-                }
-            }
-            sb.append("}");
-            s = sb.toString();
-        }else if (req == RIL_REQUEST_GET_CURRENT_CALLS) {
-            ArrayList<DriverCall> calls = (ArrayList<DriverCall>) ret;
-            sb = new StringBuilder(" ");
-            for (DriverCall dc : calls) {
-                sb.append("[").append(dc).append("] ");
-            }
-            s = sb.toString();
-        } else if (req == RIL_REQUEST_GET_NEIGHBORING_CELL_IDS) {
-            ArrayList<NeighboringCellInfo> cells;
-            cells = (ArrayList<NeighboringCellInfo>) ret;
-            sb = new StringBuilder(" ");
-            for (NeighboringCellInfo cell : cells) {
-                sb.append(cell).append(" ");
-            }
-            s = sb.toString();
-        } else {
-            s = ret.toString();
-        }
-        return s;
-    }
-
-    private void
-    processUnsolicited (Parcel p) {
-        int response;
-        Object ret;
-
-        response = p.readInt();
-
-        try {switch(response) {
-/*
- cat libs/telephony/ril_unsol_commands.h \
- | egrep "^ *{RIL_" \
- | sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: \2(rr, p); break;/'
-*/
-
-            case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: ret =  responseVoid(p); break;
-            case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: ret =  responseVoid(p); break;
-            case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: ret =  responseVoid(p); break;
-            case RIL_UNSOL_RESPONSE_NEW_SMS: ret =  responseString(p); break;
-            case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: ret =  responseString(p); break;
-            case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: ret =  responseInts(p); break;
-            case RIL_UNSOL_ON_USSD: ret =  responseStrings(p); break;
-            case RIL_UNSOL_NITZ_TIME_RECEIVED: ret =  responseString(p); break;
-            case RIL_UNSOL_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break;
-            case RIL_UNSOL_DATA_CALL_LIST_CHANGED: ret = responseDataCallList(p);break;
-            case RIL_UNSOL_SUPP_SVC_NOTIFICATION: ret = responseSuppServiceNotification(p); break;
-            case RIL_UNSOL_STK_SESSION_END: ret = responseVoid(p); break;
-            case RIL_UNSOL_STK_PROACTIVE_COMMAND: ret = responseString(p); break;
-            case RIL_UNSOL_STK_EVENT_NOTIFY: ret = responseString(p); break;
-            case RIL_UNSOL_STK_CALL_SETUP: ret = responseInts(p); break;
-            case RIL_UNSOL_SIM_SMS_STORAGE_FULL: ret =  responseVoid(p); break;
-            case RIL_UNSOL_SIM_REFRESH: ret =  responseSimRefresh(p); break;
-            case RIL_UNSOL_CALL_RING: ret =  responseCallRing(p); break;
-            case RIL_UNSOL_RESTRICTED_STATE_CHANGED: ret = responseInts(p); break;
-            case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:  ret =  responseVoid(p); break;
-            case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:  ret =  responseCdmaSms(p); break;
-            case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:  ret =  responseRaw(p); break;
-            case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:  ret =  responseVoid(p); break;
-            case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
-            case RIL_UNSOL_CDMA_CALL_WAITING: ret = responseCdmaCallWaiting(p); break;
-            case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: ret = responseInts(p); break;
-            case RIL_UNSOL_CDMA_INFO_REC: ret = responseCdmaInformationRecord(p); break;
-            case RIL_UNSOL_OEM_HOOK_RAW: ret = responseRaw(p); break;
-            case RIL_UNSOL_RINGBACK_TONE: ret = responseInts(p); break;
-            case RIL_UNSOL_RESEND_INCALL_MUTE: ret = responseVoid(p); break;
-            case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: ret = responseInts(p); break;
-            case RIL_UNSOl_CDMA_PRL_CHANGED: ret = responseInts(p); break;
-            case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
-            case RIL_UNSOL_RIL_CONNECTED: ret = responseInts(p); break;
-            case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: ret =  responseInts(p); break;
-
-            default:
-                throw new RuntimeException("Unrecognized unsol response: " + response);
-            //break; (implied)
-        }} catch (Throwable tr) {
-            Log.e(LOG_TAG, "Exception processing unsol response: " + response +
-                "Exception:" + tr.toString());
-            return;
-        }
-
-        switch(response) {
-            case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
-                /* has bonus radio state int */
-                RadioState newState = getRadioStateFromInt(p.readInt());
-                if (RILJ_LOGD) unsljLogMore(response, newState.toString());
-
-                switchToRadioState(newState);
-            break;
-            case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
-                if (RILJ_LOGD) unsljLog(response);
-
-                mCallStateRegistrants
-                    .notifyRegistrants(new AsyncResult(null, null, null));
-            break;
-            case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED:
-                if (RILJ_LOGD) unsljLog(response);
-
-                mVoiceNetworkStateRegistrants
-                    .notifyRegistrants(new AsyncResult(null, null, null));
-            break;
-            case RIL_UNSOL_RESPONSE_NEW_SMS: {
-                if (RILJ_LOGD) unsljLog(response);
-
-                // FIXME this should move up a layer
-                String a[] = new String[2];
-
-                a[1] = (String)ret;
-
-                SmsMessage sms;
-
-                sms = SmsMessage.newFromCMT(a);
-                if (mGsmSmsRegistrant != null) {
-                    mGsmSmsRegistrant
-                        .notifyRegistrant(new AsyncResult(null, sms, null));
-                }
-            break;
-            }
-            case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT:
-                if (RILJ_LOGD) unsljLogRet(response, ret);
-
-                if (mSmsStatusRegistrant != null) {
-                    mSmsStatusRegistrant.notifyRegistrant(
-                            new AsyncResult(null, ret, null));
-                }
-            break;
-            case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM:
-                if (RILJ_LOGD) unsljLogRet(response, ret);
-
-                int[] smsIndex = (int[])ret;
-
-                if(smsIndex.length == 1) {
-                    if (mSmsOnSimRegistrant != null) {
-                        mSmsOnSimRegistrant.
-                                notifyRegistrant(new AsyncResult(null, smsIndex, null));
-                    }
-                } else {
-                    if (RILJ_LOGD) riljLog(" NEW_SMS_ON_SIM ERROR with wrong length "
-                            + smsIndex.length);
-                }
-            break;
-            case RIL_UNSOL_ON_USSD:
-                String[] resp = (String[])ret;
-
-                if (resp.length < 2) {
-                    resp = new String[2];
-                    resp[0] = ((String[])ret)[0];
-                    resp[1] = null;
-                }
-                if (RILJ_LOGD) unsljLogMore(response, resp[0]);
-                if (mUSSDRegistrant != null) {
-                    mUSSDRegistrant.notifyRegistrant(
-                        new AsyncResult (null, resp, null));
-                }
-            break;
-            case RIL_UNSOL_NITZ_TIME_RECEIVED:
-                if (RILJ_LOGD) unsljLogRet(response, ret);
-
-                // has bonus long containing milliseconds since boot that the NITZ
-                // time was received
-                long nitzReceiveTime = p.readLong();
-
-                Object[] result = new Object[2];
-
-                result[0] = ret;
-                result[1] = Long.valueOf(nitzReceiveTime);
-
-                boolean ignoreNitz = SystemProperties.getBoolean(
-                        TelephonyProperties.PROPERTY_IGNORE_NITZ, false);
-
-                if (ignoreNitz) {
-                    if (RILJ_LOGD) riljLog("ignoring UNSOL_NITZ_TIME_RECEIVED");
-                } else {
-                    if (mNITZTimeRegistrant != null) {
-
-                        mNITZTimeRegistrant
-                            .notifyRegistrant(new AsyncResult (null, result, null));
-                    } else {
-                        // in case NITZ time registrant isnt registered yet
-                        mLastNITZTimeInfo = result;
-                    }
-                }
-            break;
-
-            case RIL_UNSOL_SIGNAL_STRENGTH:
-                // Note this is set to "verbose" because it happens
-                // frequently
-                if (RILJ_LOGV) unsljLogvRet(response, ret);
-
-                if (mSignalStrengthRegistrant != null) {
-                    mSignalStrengthRegistrant.notifyRegistrant(
-                                        new AsyncResult (null, ret, null));
-                }
-            break;
-            case RIL_UNSOL_DATA_CALL_LIST_CHANGED:
-                if (RILJ_LOGD) unsljLogRet(response, ret);
-
-                mDataNetworkStateRegistrants.notifyRegistrants(new AsyncResult(null, ret, null));
-            break;
-
-            case RIL_UNSOL_SUPP_SVC_NOTIFICATION:
-                if (RILJ_LOGD) unsljLogRet(response, ret);
-
-                if (mSsnRegistrant != null) {
-                    mSsnRegistrant.notifyRegistrant(
-                                        new AsyncResult (null, ret, null));
-                }
-                break;
-
-            case RIL_UNSOL_STK_SESSION_END:
-                if (RILJ_LOGD) unsljLog(response);
-
-                if (mCatSessionEndRegistrant != null) {
-                    mCatSessionEndRegistrant.notifyRegistrant(
-                                        new AsyncResult (null, ret, null));
-                }
-                break;
-
-            case RIL_UNSOL_STK_PROACTIVE_COMMAND:
-                if (RILJ_LOGD) unsljLogRet(response, ret);
-
-                if (mCatProCmdRegistrant != null) {
-                    mCatProCmdRegistrant.notifyRegistrant(
-                                        new AsyncResult (null, ret, null));
-                }
-                break;
-
-            case RIL_UNSOL_STK_EVENT_NOTIFY:
-                if (RILJ_LOGD) unsljLogRet(response, ret);
-
-                if (mCatEventRegistrant != null) {
-                    mCatEventRegistrant.notifyRegistrant(
-                                        new AsyncResult (null, ret, null));
-                }
-                break;
-
-            case RIL_UNSOL_STK_CALL_SETUP:
-                if (RILJ_LOGD) unsljLogRet(response, ret);
-
-                if (mCatCallSetUpRegistrant != null) {
-                    mCatCallSetUpRegistrant.notifyRegistrant(
-                                        new AsyncResult (null, ret, null));
-                }
-                break;
-
-            case RIL_UNSOL_SIM_SMS_STORAGE_FULL:
-                if (RILJ_LOGD) unsljLog(response);
-
-                if (mIccSmsFullRegistrant != null) {
-                    mIccSmsFullRegistrant.notifyRegistrant();
-                }
-                break;
-
-            case RIL_UNSOL_SIM_REFRESH:
-                if (RILJ_LOGD) unsljLogRet(response, ret);
-
-                if (mIccRefreshRegistrants != null) {
-                    mIccRefreshRegistrants.notifyRegistrants(
-                            new AsyncResult (null, ret, null));
-                }
-                break;
-
-            case RIL_UNSOL_CALL_RING:
-                if (RILJ_LOGD) unsljLogRet(response, ret);
-
-                if (mRingRegistrant != null) {
-                    mRingRegistrant.notifyRegistrant(
-                            new AsyncResult (null, ret, null));
-                }
-                break;
-
-            case RIL_UNSOL_RESTRICTED_STATE_CHANGED:
-                if (RILJ_LOGD) unsljLogvRet(response, ret);
-                if (mRestrictedStateRegistrant != null) {
-                    mRestrictedStateRegistrant.notifyRegistrant(
-                                        new AsyncResult (null, ret, null));
-                }
-                break;
-
-            case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:
-                if (RILJ_LOGD) unsljLog(response);
-
-                if (mIccStatusChangedRegistrants != null) {
-                    mIccStatusChangedRegistrants.notifyRegistrants();
-                }
-                break;
-
-            case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:
-                if (RILJ_LOGD) unsljLog(response);
-
-                SmsMessage sms = (SmsMessage) ret;
-
-                if (mCdmaSmsRegistrant != null) {
-                    mCdmaSmsRegistrant
-                        .notifyRegistrant(new AsyncResult(null, sms, null));
-                }
-                break;
-
-            case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:
-                if (RILJ_LOGD) unsljLog(response);
-
-                if (mGsmBroadcastSmsRegistrant != null) {
-                    mGsmBroadcastSmsRegistrant
-                        .notifyRegistrant(new AsyncResult(null, ret, null));
-                }
-                break;
-
-            case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:
-                if (RILJ_LOGD) unsljLog(response);
-
-                if (mIccSmsFullRegistrant != null) {
-                    mIccSmsFullRegistrant.notifyRegistrant();
-                }
-                break;
-
-            case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE:
-                if (RILJ_LOGD) unsljLog(response);
-
-                if (mEmergencyCallbackModeRegistrant != null) {
-                    mEmergencyCallbackModeRegistrant.notifyRegistrant();
-                }
-                break;
-
-            case RIL_UNSOL_CDMA_CALL_WAITING:
-                if (RILJ_LOGD) unsljLogRet(response, ret);
-
-                if (mCallWaitingInfoRegistrants != null) {
-                    mCallWaitingInfoRegistrants.notifyRegistrants(
-                                        new AsyncResult (null, ret, null));
-                }
-                break;
-
-            case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS:
-                if (RILJ_LOGD) unsljLogRet(response, ret);
-
-                if (mOtaProvisionRegistrants != null) {
-                    mOtaProvisionRegistrants.notifyRegistrants(
-                                        new AsyncResult (null, ret, null));
-                }
-                break;
-
-            case RIL_UNSOL_CDMA_INFO_REC:
-                ArrayList<CdmaInformationRecords> listInfoRecs;
-
-                try {
-                    listInfoRecs = (ArrayList<CdmaInformationRecords>)ret;
-                } catch (ClassCastException e) {
-                    Log.e(LOG_TAG, "Unexpected exception casting to listInfoRecs", e);
-                    break;
-                }
-
-                for (CdmaInformationRecords rec : listInfoRecs) {
-                    if (RILJ_LOGD) unsljLogRet(response, rec);
-                    notifyRegistrantsCdmaInfoRec(rec);
-                }
-                break;
-
-            case RIL_UNSOL_OEM_HOOK_RAW:
-                if (RILJ_LOGD) unsljLogvRet(response, IccUtils.bytesToHexString((byte[])ret));
-                if (mUnsolOemHookRawRegistrant != null) {
-                    mUnsolOemHookRawRegistrant.notifyRegistrant(new AsyncResult(null, ret, null));
-                }
-                break;
-
-            case RIL_UNSOL_RINGBACK_TONE:
-                if (RILJ_LOGD) unsljLogvRet(response, ret);
-                if (mRingbackToneRegistrants != null) {
-                    boolean playtone = (((int[])ret)[0] == 1);
-                    mRingbackToneRegistrants.notifyRegistrants(
-                                        new AsyncResult (null, playtone, null));
-                }
-                break;
-
-            case RIL_UNSOL_RESEND_INCALL_MUTE:
-                if (RILJ_LOGD) unsljLogRet(response, ret);
-
-                if (mResendIncallMuteRegistrants != null) {
-                    mResendIncallMuteRegistrants.notifyRegistrants(
-                                        new AsyncResult (null, ret, null));
-                }
-                break;
-
-            case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED:
-                if (RILJ_LOGD) unsljLogRet(response, ret);
-
-                if (mVoiceRadioTechChangedRegistrants != null) {
-                    mVoiceRadioTechChangedRegistrants.notifyRegistrants(
-                            new AsyncResult(null, ret, null));
-                }
-                break;
-
-            case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
-                if (RILJ_LOGD) unsljLogRet(response, ret);
-
-                if (mCdmaSubscriptionChangedRegistrants != null) {
-                    mCdmaSubscriptionChangedRegistrants.notifyRegistrants(
-                                        new AsyncResult (null, ret, null));
-                }
-                break;
-
-            case RIL_UNSOl_CDMA_PRL_CHANGED:
-                if (RILJ_LOGD) unsljLogRet(response, ret);
-
-                if (mCdmaPrlChangedRegistrants != null) {
-                    mCdmaPrlChangedRegistrants.notifyRegistrants(
-                                        new AsyncResult (null, ret, null));
-                }
-                break;
-
-            case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE:
-                if (RILJ_LOGD) unsljLogRet(response, ret);
-
-                if (mExitEmergencyCallbackModeRegistrants != null) {
-                    mExitEmergencyCallbackModeRegistrants.notifyRegistrants(
-                                        new AsyncResult (null, null, null));
-                }
-                break;
-
-            case RIL_UNSOL_RIL_CONNECTED: {
-                if (RILJ_LOGD) unsljLogRet(response, ret);
-
-                // Initial conditions
-                setRadioPower(false, null);
-                setPreferredNetworkType(mPreferredNetworkType, null);
-                setCdmaSubscriptionSource(mCdmaSubscription, null);
-                notifyRegistrantsRilConnectionChanged(((int[])ret)[0]);
-                break;
-            }
-        }
-    }
-
-    /**
-     * Notifiy all registrants that the ril has connected or disconnected.
-     *
-     * @param rilVer is the version of the ril or -1 if disconnected.
-     */
-    private void notifyRegistrantsRilConnectionChanged(int rilVer) {
-        mRilVersion = rilVer;
-        if (mRilConnectedRegistrants != null) {
-            mRilConnectedRegistrants.notifyRegistrants(
-                                new AsyncResult (null, new Integer(rilVer), null));
-        }
-    }
-
-    private Object
-    responseInts(Parcel p) {
-        int numInts;
-        int response[];
-
-        numInts = p.readInt();
-
-        response = new int[numInts];
-
-        for (int i = 0 ; i < numInts ; i++) {
-            response[i] = p.readInt();
-        }
-
-        return response;
-    }
-
-
-    private Object
-    responseVoid(Parcel p) {
-        return null;
-    }
-
-    private Object
-    responseCallForward(Parcel p) {
-        int numInfos;
-        CallForwardInfo infos[];
-
-        numInfos = p.readInt();
-
-        infos = new CallForwardInfo[numInfos];
-
-        for (int i = 0 ; i < numInfos ; i++) {
-            infos[i] = new CallForwardInfo();
-
-            infos[i].status = p.readInt();
-            infos[i].reason = p.readInt();
-            infos[i].serviceClass = p.readInt();
-            infos[i].toa = p.readInt();
-            infos[i].number = p.readString();
-            infos[i].timeSeconds = p.readInt();
-        }
-
-        return infos;
-    }
-
-    private Object
-    responseSuppServiceNotification(Parcel p) {
-        SuppServiceNotification notification = new SuppServiceNotification();
-
-        notification.notificationType = p.readInt();
-        notification.code = p.readInt();
-        notification.index = p.readInt();
-        notification.type = p.readInt();
-        notification.number = p.readString();
-
-        return notification;
-    }
-
-    private Object
-    responseCdmaSms(Parcel p) {
-        SmsMessage sms;
-        sms = SmsMessage.newFromParcel(p);
-
-        return sms;
-    }
-
-    private Object
-    responseString(Parcel p) {
-        String response;
-
-        response = p.readString();
-
-        return response;
-    }
-
-    private Object
-    responseStrings(Parcel p) {
-        int num;
-        String response[];
-
-        response = p.readStringArray();
-
-        if (false) {
-            num = p.readInt();
-
-            response = new String[num];
-            for (int i = 0; i < num; i++) {
-                response[i] = p.readString();
-            }
-        }
-
-        return response;
-    }
-
-    private Object
-    responseRaw(Parcel p) {
-        int num;
-        byte response[];
-
-        response = p.createByteArray();
-
-        return response;
-    }
-
-    private Object
-    responseSMS(Parcel p) {
-        int messageRef, errorCode;
-        String ackPDU;
-
-        messageRef = p.readInt();
-        ackPDU = p.readString();
-        errorCode = p.readInt();
-
-        SmsResponse response = new SmsResponse(messageRef, ackPDU, errorCode);
-
-        return response;
-    }
-
-
-    private Object
-    responseICC_IO(Parcel p) {
-        int sw1, sw2;
-        byte data[] = null;
-        Message ret;
-
-        sw1 = p.readInt();
-        sw2 = p.readInt();
-
-        String s = p.readString();
-
-        if (RILJ_LOGV) riljLog("< iccIO: "
-                + " 0x" + Integer.toHexString(sw1)
-                + " 0x" + Integer.toHexString(sw2) + " "
-                + s);
-
-        return new IccIoResult(sw1, sw2, s);
-    }
-
-    private Object
-    responseIccCardStatus(Parcel p) {
-        IccCardApplication ca;
-
-        IccCardStatus status = new IccCardStatus();
-        status.setCardState(p.readInt());
-        status.setUniversalPinState(p.readInt());
-        status.setGsmUmtsSubscriptionAppIndex(p.readInt());
-        status.setCdmaSubscriptionAppIndex(p.readInt());
-        status.setImsSubscriptionAppIndex(p.readInt());
-        int numApplications = p.readInt();
-
-        // limit to maximum allowed applications
-        if (numApplications > IccCardStatus.CARD_MAX_APPS) {
-            numApplications = IccCardStatus.CARD_MAX_APPS;
-        }
-        status.setNumApplications(numApplications);
-
-        for (int i = 0 ; i < numApplications ; i++) {
-            ca = new IccCardApplication();
-            ca.app_type       = ca.AppTypeFromRILInt(p.readInt());
-            ca.app_state      = ca.AppStateFromRILInt(p.readInt());
-            ca.perso_substate = ca.PersoSubstateFromRILInt(p.readInt());
-            ca.aid            = p.readString();
-            ca.app_label      = p.readString();
-            ca.pin1_replaced  = p.readInt();
-            ca.pin1           = ca.PinStateFromRILInt(p.readInt());
-            ca.pin2           = ca.PinStateFromRILInt(p.readInt());
-            status.addApplication(ca);
-        }
-        return status;
-    }
-
-    private Object
-    responseSimRefresh(Parcel p) {
-        IccRefreshResponse response = new IccRefreshResponse();
-
-        response.refreshResult = p.readInt();
-        response.efId   = p.readInt();
-        response.aid = p.readString();
-        return response;
-    }
-
-    private Object
-    responseCallList(Parcel p) {
-        int num;
-        int voiceSettings;
-        ArrayList<DriverCall> response;
-        DriverCall dc;
-
-        num = p.readInt();
-        response = new ArrayList<DriverCall>(num);
-
-        if (RILJ_LOGV) {
-            riljLog("responseCallList: num=" + num +
-                    " mEmergencyCallbackModeRegistrant=" + mEmergencyCallbackModeRegistrant +
-                    " mTestingEmergencyCall=" + mTestingEmergencyCall.get());
-        }
-        for (int i = 0 ; i < num ; i++) {
-            dc = new DriverCall();
-
-            dc.state = DriverCall.stateFromCLCC(p.readInt());
-            dc.index = p.readInt();
-            dc.TOA = p.readInt();
-            dc.isMpty = (0 != p.readInt());
-            dc.isMT = (0 != p.readInt());
-            dc.als = p.readInt();
-            voiceSettings = p.readInt();
-            dc.isVoice = (0 == voiceSettings) ? false : true;
-            dc.isVoicePrivacy = (0 != p.readInt());
-            dc.number = p.readString();
-            int np = p.readInt();
-            dc.numberPresentation = DriverCall.presentationFromCLIP(np);
-            dc.name = p.readString();
-            dc.namePresentation = p.readInt();
-            int uusInfoPresent = p.readInt();
-            if (uusInfoPresent == 1) {
-                dc.uusInfo = new UUSInfo();
-                dc.uusInfo.setType(p.readInt());
-                dc.uusInfo.setDcs(p.readInt());
-                byte[] userData = p.createByteArray();
-                dc.uusInfo.setUserData(userData);
-                riljLogv(String.format("Incoming UUS : type=%d, dcs=%d, length=%d",
-                                dc.uusInfo.getType(), dc.uusInfo.getDcs(),
-                                dc.uusInfo.getUserData().length));
-                riljLogv("Incoming UUS : data (string)="
-                        + new String(dc.uusInfo.getUserData()));
-                riljLogv("Incoming UUS : data (hex): "
-                        + IccUtils.bytesToHexString(dc.uusInfo.getUserData()));
-            } else {
-                riljLogv("Incoming UUS : NOT present!");
-            }
-
-            // Make sure there's a leading + on addresses with a TOA of 145
-            dc.number = PhoneNumberUtils.stringFromStringAndTOA(dc.number, dc.TOA);
-
-            response.add(dc);
-
-            if (dc.isVoicePrivacy) {
-                mVoicePrivacyOnRegistrants.notifyRegistrants();
-                riljLog("InCall VoicePrivacy is enabled");
-            } else {
-                mVoicePrivacyOffRegistrants.notifyRegistrants();
-                riljLog("InCall VoicePrivacy is disabled");
-            }
-        }
-
-        Collections.sort(response);
-
-        if ((num == 0) && mTestingEmergencyCall.getAndSet(false)) {
-            if (mEmergencyCallbackModeRegistrant != null) {
-                riljLog("responseCallList: call ended, testing emergency call," +
-                            " notify ECM Registrants");
-                mEmergencyCallbackModeRegistrant.notifyRegistrant();
-            }
-        }
-
-        return response;
-    }
-
-    private DataCallState getDataCallState(Parcel p, int version) {
-        DataCallState dataCall = new DataCallState();
-
-        dataCall.version = version;
-        if (version < 5) {
-            dataCall.cid = p.readInt();
-            dataCall.active = p.readInt();
-            dataCall.type = p.readString();
-            String addresses = p.readString();
-            if (!TextUtils.isEmpty(addresses)) {
-                dataCall.addresses = addresses.split(" ");
-            }
-        } else {
-            dataCall.status = p.readInt();
-            dataCall.suggestedRetryTime = p.readInt();
-            dataCall.cid = p.readInt();
-            dataCall.active = p.readInt();
-            dataCall.type = p.readString();
-            dataCall.ifname = p.readString();
-            if ((dataCall.status == DataConnection.FailCause.NONE.getErrorCode()) &&
-                    TextUtils.isEmpty(dataCall.ifname)) {
-              throw new RuntimeException("getDataCallState, no ifname");
-            }
-            String addresses = p.readString();
-            if (!TextUtils.isEmpty(addresses)) {
-                dataCall.addresses = addresses.split(" ");
-            }
-            String dnses = p.readString();
-            if (!TextUtils.isEmpty(dnses)) {
-                dataCall.dnses = dnses.split(" ");
-            }
-            String gateways = p.readString();
-            if (!TextUtils.isEmpty(gateways)) {
-                dataCall.gateways = gateways.split(" ");
-            }
-        }
-        return dataCall;
-    }
-
-    private Object
-    responseDataCallList(Parcel p) {
-        ArrayList<DataCallState> response;
-
-        int ver = p.readInt();
-        int num = p.readInt();
-        riljLog("responseDataCallList ver=" + ver + " num=" + num);
-
-        response = new ArrayList<DataCallState>(num);
-        for (int i = 0; i < num; i++) {
-            response.add(getDataCallState(p, ver));
-        }
-
-        return response;
-    }
-
-    private Object
-    responseSetupDataCall(Parcel p) {
-        int ver = p.readInt();
-        int num = p.readInt();
-        if (RILJ_LOGV) riljLog("responseSetupDataCall ver=" + ver + " num=" + num);
-
-        DataCallState dataCall;
-
-        if (ver < 5) {
-            dataCall = new DataCallState();
-            dataCall.version = ver;
-            dataCall.cid = Integer.parseInt(p.readString());
-            dataCall.ifname = p.readString();
-            if (TextUtils.isEmpty(dataCall.ifname)) {
-                throw new RuntimeException(
-                        "RIL_REQUEST_SETUP_DATA_CALL response, no ifname");
-            }
-            String addresses = p.readString();
-            if (!TextUtils.isEmpty(addresses)) {
-              dataCall.addresses = addresses.split(" ");
-            }
-            if (num >= 4) {
-                String dnses = p.readString();
-                if (RILJ_LOGD) riljLog("responseSetupDataCall got dnses=" + dnses);
-                if (!TextUtils.isEmpty(dnses)) {
-                    dataCall.dnses = dnses.split(" ");
-                }
-            }
-            if (num >= 5) {
-                String gateways = p.readString();
-                if (RILJ_LOGD) riljLog("responseSetupDataCall got gateways=" + gateways);
-                if (!TextUtils.isEmpty(gateways)) {
-                    dataCall.gateways = gateways.split(" ");
-                }
-            }
-        } else {
-            if (num != 1) {
-                throw new RuntimeException(
-                        "RIL_REQUEST_SETUP_DATA_CALL response expecting 1 RIL_Data_Call_response_v5"
-                        + " got " + num);
-            }
-            dataCall = getDataCallState(p, ver);
-        }
-
-        return dataCall;
-    }
-
-    private Object
-    responseOperatorInfos(Parcel p) {
-        String strings[] = (String [])responseStrings(p);
-        ArrayList<OperatorInfo> ret;
-
-        if (strings.length % 4 != 0) {
-            throw new RuntimeException(
-                "RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: invalid response. Got "
-                + strings.length + " strings, expected multible of 4");
-        }
-
-        ret = new ArrayList<OperatorInfo>(strings.length / 4);
-
-        for (int i = 0 ; i < strings.length ; i += 4) {
-            ret.add (
-                new OperatorInfo(
-                    strings[i+0],
-                    strings[i+1],
-                    strings[i+2],
-                    strings[i+3]));
-        }
-
-        return ret;
-    }
-
-    private Object
-    responseCellList(Parcel p) {
-       int num, rssi;
-       String location;
-       ArrayList<NeighboringCellInfo> response;
-       NeighboringCellInfo cell;
-
-       num = p.readInt();
-       response = new ArrayList<NeighboringCellInfo>();
-
-       // Determine the radio access type
-       String radioString = SystemProperties.get(
-               TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE, "unknown");
-       int radioType;
-       if (radioString.equals("GPRS")) {
-           radioType = NETWORK_TYPE_GPRS;
-       } else if (radioString.equals("EDGE")) {
-           radioType = NETWORK_TYPE_EDGE;
-       } else if (radioString.equals("UMTS")) {
-           radioType = NETWORK_TYPE_UMTS;
-       } else if (radioString.equals("HSDPA")) {
-           radioType = NETWORK_TYPE_HSDPA;
-       } else if (radioString.equals("HSUPA")) {
-           radioType = NETWORK_TYPE_HSUPA;
-       } else if (radioString.equals("HSPA")) {
-           radioType = NETWORK_TYPE_HSPA;
-       } else {
-           radioType = NETWORK_TYPE_UNKNOWN;
-       }
-
-       // Interpret the location based on radio access type
-       if (radioType != NETWORK_TYPE_UNKNOWN) {
-           for (int i = 0 ; i < num ; i++) {
-               rssi = p.readInt();
-               location = p.readString();
-               cell = new NeighboringCellInfo(rssi, location, radioType);
-               response.add(cell);
-           }
-       }
-       return response;
-    }
-
-    private Object responseGetPreferredNetworkType(Parcel p) {
-       int [] response = (int[]) responseInts(p);
-
-       if (response.length >= 1) {
-           // Since this is the response for getPreferredNetworkType
-           // we'll assume that it should be the value we want the
-           // vendor ril to take if we reestablish a connection to it.
-           mPreferredNetworkType = response[0];
-       }
-       return response;
-    }
-
-    private Object responseGmsBroadcastConfig(Parcel p) {
-        int num;
-        ArrayList<SmsBroadcastConfigInfo> response;
-        SmsBroadcastConfigInfo info;
-
-        num = p.readInt();
-        response = new ArrayList<SmsBroadcastConfigInfo>(num);
-
-        for (int i = 0; i < num; i++) {
-            int fromId = p.readInt();
-            int toId = p.readInt();
-            int fromScheme = p.readInt();
-            int toScheme = p.readInt();
-            boolean selected = (p.readInt() == 1);
-
-            info = new SmsBroadcastConfigInfo(fromId, toId, fromScheme,
-                    toScheme, selected);
-            response.add(info);
-        }
-        return response;
-    }
-
-    private Object
-    responseCdmaBroadcastConfig(Parcel p) {
-        int numServiceCategories;
-        int response[];
-
-        numServiceCategories = p.readInt();
-
-        if (numServiceCategories == 0) {
-            // TODO: The logic of providing default values should
-            // not be done by this transport layer. And needs to
-            // be done by the vendor ril or application logic.
-            int numInts;
-            numInts = CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES * CDMA_BSI_NO_OF_INTS_STRUCT + 1;
-            response = new int[numInts];
-
-            // Faking a default record for all possible records.
-            response[0] = CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES;
-
-            // Loop over CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES set 'english' as
-            // default language and selection status to false for all.
-            for (int i = 1; i < numInts; i += CDMA_BSI_NO_OF_INTS_STRUCT ) {
-                response[i + 0] = i / CDMA_BSI_NO_OF_INTS_STRUCT;
-                response[i + 1] = 1;
-                response[i + 2] = 0;
-            }
-        } else {
-            int numInts;
-            numInts = (numServiceCategories * CDMA_BSI_NO_OF_INTS_STRUCT) + 1;
-            response = new int[numInts];
-
-            response[0] = numServiceCategories;
-            for (int i = 1 ; i < numInts; i++) {
-                 response[i] = p.readInt();
-             }
-        }
-
-        return response;
-    }
-
-    private Object
-    responseSignalStrength(Parcel p) {
-        int numInts = 12;
-        int response[];
-
-        /* TODO: Add SignalStrength class to match RIL_SignalStrength */
-        response = new int[numInts];
-        for (int i = 0 ; i < numInts ; i++) {
-            response[i] = p.readInt();
-        }
-
-        return response;
-    }
-
-    private ArrayList<CdmaInformationRecords>
-    responseCdmaInformationRecord(Parcel p) {
-        int numberOfInfoRecs;
-        ArrayList<CdmaInformationRecords> response;
-
-        /**
-         * Loop through all of the information records unmarshalling them
-         * and converting them to Java Objects.
-         */
-        numberOfInfoRecs = p.readInt();
-        response = new ArrayList<CdmaInformationRecords>(numberOfInfoRecs);
-
-        for (int i = 0; i < numberOfInfoRecs; i++) {
-            CdmaInformationRecords InfoRec = new CdmaInformationRecords(p);
-            response.add(InfoRec);
-        }
-
-        return response;
-    }
-
-    private Object
-    responseCdmaCallWaiting(Parcel p) {
-        CdmaCallWaitingNotification notification = new CdmaCallWaitingNotification();
-
-        notification.number = p.readString();
-        notification.numberPresentation = notification.presentationFromCLIP(p.readInt());
-        notification.name = p.readString();
-        notification.namePresentation = notification.numberPresentation;
-        notification.isPresent = p.readInt();
-        notification.signalType = p.readInt();
-        notification.alertPitch = p.readInt();
-        notification.signal = p.readInt();
-        notification.numberType = p.readInt();
-        notification.numberPlan = p.readInt();
-
-        return notification;
-    }
-
-    private Object
-    responseCallRing(Parcel p){
-        char response[] = new char[4];
-
-        response[0] = (char) p.readInt();    // isPresent
-        response[1] = (char) p.readInt();    // signalType
-        response[2] = (char) p.readInt();    // alertPitch
-        response[3] = (char) p.readInt();    // signal
-
-        return response;
-    }
-
-    private void
-    notifyRegistrantsCdmaInfoRec(CdmaInformationRecords infoRec) {
-        int response = RIL_UNSOL_CDMA_INFO_REC;
-        if (infoRec.record instanceof CdmaInformationRecords.CdmaDisplayInfoRec) {
-            if (mDisplayInfoRegistrants != null) {
-                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
-                mDisplayInfoRegistrants.notifyRegistrants(
-                        new AsyncResult (null, infoRec.record, null));
-            }
-        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaSignalInfoRec) {
-            if (mSignalInfoRegistrants != null) {
-                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
-                mSignalInfoRegistrants.notifyRegistrants(
-                        new AsyncResult (null, infoRec.record, null));
-            }
-        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaNumberInfoRec) {
-            if (mNumberInfoRegistrants != null) {
-                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
-                mNumberInfoRegistrants.notifyRegistrants(
-                        new AsyncResult (null, infoRec.record, null));
-            }
-        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaRedirectingNumberInfoRec) {
-            if (mRedirNumInfoRegistrants != null) {
-                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
-                mRedirNumInfoRegistrants.notifyRegistrants(
-                        new AsyncResult (null, infoRec.record, null));
-            }
-        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaLineControlInfoRec) {
-            if (mLineControlInfoRegistrants != null) {
-                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
-                mLineControlInfoRegistrants.notifyRegistrants(
-                        new AsyncResult (null, infoRec.record, null));
-            }
-        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53ClirInfoRec) {
-            if (mT53ClirInfoRegistrants != null) {
-                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
-                mT53ClirInfoRegistrants.notifyRegistrants(
-                        new AsyncResult (null, infoRec.record, null));
-            }
-        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53AudioControlInfoRec) {
-            if (mT53AudCntrlInfoRegistrants != null) {
-               if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
-               mT53AudCntrlInfoRegistrants.notifyRegistrants(
-                       new AsyncResult (null, infoRec.record, null));
-            }
-        }
-    }
-
-    static String
-    requestToString(int request) {
-/*
- cat libs/telephony/ril_commands.h \
- | egrep "^ *{RIL_" \
- | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
-*/
-        switch(request) {
-            case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS";
-            case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN";
-            case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK";
-            case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2";
-            case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2";
-            case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN";
-            case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2";
-            case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION";
-            case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS";
-            case RIL_REQUEST_DIAL: return "DIAL";
-            case RIL_REQUEST_GET_IMSI: return "GET_IMSI";
-            case RIL_REQUEST_HANGUP: return "HANGUP";
-            case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND";
-            case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
-            case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
-            case RIL_REQUEST_CONFERENCE: return "CONFERENCE";
-            case RIL_REQUEST_UDUB: return "UDUB";
-            case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE";
-            case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH";
-            case RIL_REQUEST_VOICE_REGISTRATION_STATE: return "VOICE_REGISTRATION_STATE";
-            case RIL_REQUEST_DATA_REGISTRATION_STATE: return "DATA_REGISTRATION_STATE";
-            case RIL_REQUEST_OPERATOR: return "OPERATOR";
-            case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER";
-            case RIL_REQUEST_DTMF: return "DTMF";
-            case RIL_REQUEST_SEND_SMS: return "SEND_SMS";
-            case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE";
-            case RIL_REQUEST_SETUP_DATA_CALL: return "SETUP_DATA_CALL";
-            case RIL_REQUEST_SIM_IO: return "SIM_IO";
-            case RIL_REQUEST_SEND_USSD: return "SEND_USSD";
-            case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD";
-            case RIL_REQUEST_GET_CLIR: return "GET_CLIR";
-            case RIL_REQUEST_SET_CLIR: return "SET_CLIR";
-            case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS";
-            case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD";
-            case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING";
-            case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING";
-            case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE";
-            case RIL_REQUEST_GET_IMEI: return "GET_IMEI";
-            case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV";
-            case RIL_REQUEST_ANSWER: return "ANSWER";
-            case RIL_REQUEST_DEACTIVATE_DATA_CALL: return "DEACTIVATE_DATA_CALL";
-            case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK";
-            case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK";
-            case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD";
-            case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE";
-            case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC";
-            case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL";
-            case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : return "QUERY_AVAILABLE_NETWORKS ";
-            case RIL_REQUEST_DTMF_START: return "DTMF_START";
-            case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP";
-            case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION";
-            case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION";
-            case RIL_REQUEST_SET_MUTE: return "SET_MUTE";
-            case RIL_REQUEST_GET_MUTE: return "GET_MUTE";
-            case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP";
-            case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: return "LAST_DATA_CALL_FAIL_CAUSE";
-            case RIL_REQUEST_DATA_CALL_LIST: return "DATA_CALL_LIST";
-            case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO";
-            case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW";
-            case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS";
-            case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE";
-            case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: return "SET_SUPP_SVC_NOTIFICATION";
-            case RIL_REQUEST_WRITE_SMS_TO_SIM: return "WRITE_SMS_TO_SIM";
-            case RIL_REQUEST_DELETE_SMS_ON_SIM: return "DELETE_SMS_ON_SIM";
-            case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE";
-            case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE";
-            case RIL_REQUEST_STK_GET_PROFILE: return "REQUEST_STK_GET_PROFILE";
-            case RIL_REQUEST_STK_SET_PROFILE: return "REQUEST_STK_SET_PROFILE";
-            case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "REQUEST_STK_SEND_ENVELOPE_COMMAND";
-            case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "REQUEST_STK_SEND_TERMINAL_RESPONSE";
-            case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
-            case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "REQUEST_EXPLICIT_CALL_TRANSFER";
-            case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "REQUEST_SET_PREFERRED_NETWORK_TYPE";
-            case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "REQUEST_GET_PREFERRED_NETWORK_TYPE";
-            case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "REQUEST_GET_NEIGHBORING_CELL_IDS";
-            case RIL_REQUEST_SET_LOCATION_UPDATES: return "REQUEST_SET_LOCATION_UPDATES";
-            case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: return "RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE";
-            case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: return "RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE";
-            case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: return "RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE";
-            case RIL_REQUEST_SET_TTY_MODE: return "RIL_REQUEST_SET_TTY_MODE";
-            case RIL_REQUEST_QUERY_TTY_MODE: return "RIL_REQUEST_QUERY_TTY_MODE";
-            case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE: return "RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE";
-            case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE: return "RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE";
-            case RIL_REQUEST_CDMA_FLASH: return "RIL_REQUEST_CDMA_FLASH";
-            case RIL_REQUEST_CDMA_BURST_DTMF: return "RIL_REQUEST_CDMA_BURST_DTMF";
-            case RIL_REQUEST_CDMA_SEND_SMS: return "RIL_REQUEST_CDMA_SEND_SMS";
-            case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: return "RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE";
-            case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG: return "RIL_REQUEST_GSM_GET_BROADCAST_CONFIG";
-            case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG: return "RIL_REQUEST_GSM_SET_BROADCAST_CONFIG";
-            case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: return "RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG";
-            case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: return "RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG";
-            case RIL_REQUEST_GSM_BROADCAST_ACTIVATION: return "RIL_REQUEST_GSM_BROADCAST_ACTIVATION";
-            case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: return "RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY";
-            case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: return "RIL_REQUEST_CDMA_BROADCAST_ACTIVATION";
-            case RIL_REQUEST_CDMA_SUBSCRIPTION: return "RIL_REQUEST_CDMA_SUBSCRIPTION";
-            case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: return "RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM";
-            case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: return "RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM";
-            case RIL_REQUEST_DEVICE_IDENTITY: return "RIL_REQUEST_DEVICE_IDENTITY";
-            case RIL_REQUEST_GET_SMSC_ADDRESS: return "RIL_REQUEST_GET_SMSC_ADDRESS";
-            case RIL_REQUEST_SET_SMSC_ADDRESS: return "RIL_REQUEST_SET_SMSC_ADDRESS";
-            case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "REQUEST_EXIT_EMERGENCY_CALLBACK_MODE";
-            case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "RIL_REQUEST_REPORT_SMS_MEMORY_STATUS";
-            case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING";
-            case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE";
-            case RIL_REQUEST_ISIM_AUTHENTICATION: return "RIL_REQUEST_ISIM_AUTHENTICATION";
-            case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
-            case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS";
-            case RIL_REQUEST_VOICE_RADIO_TECH: return "RIL_REQUEST_VOICE_RADIO_TECH";
-            default: return "<unknown request>";
-        }
-    }
-
-    static String
-    responseToString(int request)
-    {
-/*
- cat libs/telephony/ril_unsol_commands.h \
- | egrep "^ *{RIL_" \
- | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
-*/
-        switch(request) {
-            case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
-            case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
-            case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED";
-            case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS";
-            case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
-            case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
-            case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD";
-            case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST";
-            case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED";
-            case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH";
-            case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "UNSOL_DATA_CALL_LIST_CHANGED";
-            case RIL_UNSOL_SUPP_SVC_NOTIFICATION: return "UNSOL_SUPP_SVC_NOTIFICATION";
-            case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END";
-            case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND";
-            case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY";
-            case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP";
-            case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FULL";
-            case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH";
-            case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING";
-            case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED";
-            case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_RESPONSE_CDMA_NEW_SMS";
-            case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_RESPONSE_NEW_BROADCAST_SMS";
-            case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
-            case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "UNSOL_RESTRICTED_STATE_CHANGED";
-            case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE";
-            case RIL_UNSOL_CDMA_CALL_WAITING: return "UNSOL_CDMA_CALL_WAITING";
-            case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS";
-            case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC";
-            case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW";
-            case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONG";
-            case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE";
-            case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: return "CDMA_SUBSCRIPTION_SOURCE_CHANGED";
-            case RIL_UNSOl_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED";
-            case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
-            case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED";
-            case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return "UNSOL_VOICE_RADIO_TECH_CHANGED";
-            default: return "<unknown reponse>";
-        }
-    }
-
-    private void riljLog(String msg) {
-        Log.d(LOG_TAG, msg);
-    }
-
-    private void riljLogv(String msg) {
-        Log.v(LOG_TAG, msg);
-    }
-
-    private void unsljLog(int response) {
-        riljLog("[UNSL]< " + responseToString(response));
-    }
-
-    private void unsljLogMore(int response, String more) {
-        riljLog("[UNSL]< " + responseToString(response) + " " + more);
-    }
-
-    private void unsljLogRet(int response, Object ret) {
-        riljLog("[UNSL]< " + responseToString(response) + " " + retToString(response, ret));
-    }
-
-    private void unsljLogvRet(int response, Object ret) {
-        riljLogv("[UNSL]< " + responseToString(response) + " " + retToString(response, ret));
-    }
-
-
-    // ***** Methods for CDMA support
-    public void
-    getDeviceIdentity(Message response) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_DEVICE_IDENTITY, response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void
-    getCDMASubscription(Message response) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SUBSCRIPTION, response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    @Override
-    public void setPhoneType(int phoneType) { // Called by CDMAPhone and GSMPhone constructor
-        if (RILJ_LOGD) riljLog("setPhoneType=" + phoneType + " old value=" + mPhoneType);
-        mPhoneType = phoneType;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void queryCdmaRoamingPreference(Message response) {
-        RILRequest rr = RILRequest.obtain(
-                RILConstants.RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE, response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
-        RILRequest rr = RILRequest.obtain(
-                RILConstants.RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, response);
-
-        rr.mp.writeInt(1);
-        rr.mp.writeInt(cdmaRoamingType);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                + " : " + cdmaRoamingType);
-
-        send(rr);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void setCdmaSubscriptionSource(int cdmaSubscription , Message response) {
-        RILRequest rr = RILRequest.obtain(
-                RILConstants.RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, response);
-
-        rr.mp.writeInt(1);
-        rr.mp.writeInt(cdmaSubscription);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                + " : " + cdmaSubscription);
-
-        send(rr);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void getCdmaSubscriptionSource(Message response) {
-        RILRequest rr = RILRequest.obtain(
-                RILConstants.RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE, response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void queryTTYMode(Message response) {
-        RILRequest rr = RILRequest.obtain(
-                RILConstants.RIL_REQUEST_QUERY_TTY_MODE, response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void setTTYMode(int ttyMode, Message response) {
-        RILRequest rr = RILRequest.obtain(
-                RILConstants.RIL_REQUEST_SET_TTY_MODE, response);
-
-        rr.mp.writeInt(1);
-        rr.mp.writeInt(ttyMode);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                + " : " + ttyMode);
-
-        send(rr);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void
-    sendCDMAFeatureCode(String FeatureCode, Message response) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_FLASH, response);
-
-        rr.mp.writeString(FeatureCode);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                + " : " + FeatureCode);
-
-        send(rr);
-    }
-
-    public void getCdmaBroadcastConfig(Message response) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG, response);
-
-        send(rr);
-    }
-
-    // TODO: Change the configValuesArray to a RIL_BroadcastSMSConfig
-    public void setCdmaBroadcastConfig(int[] configValuesArray, Message response) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG, response);
-
-        for(int i = 0; i < configValuesArray.length; i++) {
-            rr.mp.writeInt(configValuesArray[i]);
-        }
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void setCdmaBroadcastActivation(boolean activate, Message response) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_BROADCAST_ACTIVATION, response);
-
-        rr.mp.writeInt(1);
-        rr.mp.writeInt(activate ? 0 :1);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void exitEmergencyCallbackMode(Message response) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, response);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    public void requestIsimAuthentication(String nonce, Message response) {
-        RILRequest rr = RILRequest.obtain(RIL_REQUEST_ISIM_AUTHENTICATION, response);
-
-        rr.mp.writeString(nonce);
-
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
-        send(rr);
-    }
-
-    /* (non-Javadoc)
-     * @see com.android.internal.telephony.BaseCommands#testingEmergencyCall()
-     */
-    @Override
-    public void testingEmergencyCall() {
-        if (RILJ_LOGD) riljLog("testingEmergencyCall");
-        mTestingEmergencyCall.set(true);
-    }
-
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("RIL:");
-        pw.println(" mSocket=" + mSocket);
-        pw.println(" mSenderThread=" + mSenderThread);
-        pw.println(" mSender=" + mSender);
-        pw.println(" mReceiverThread=" + mReceiverThread);
-        pw.println(" mReceiver=" + mReceiver);
-        pw.println(" mWakeLock=" + mWakeLock);
-        pw.println(" mWakeLockTimeout=" + mWakeLockTimeout);
-        synchronized (mRequestsList) {
-          pw.println(" mRequestMessagesPending=" + mRequestMessagesPending);
-          pw.println(" mRequestMessagesWaiting=" + mRequestMessagesWaiting);
-            int count = mRequestsList.size();
-            pw.println(" mRequestList count=" + count);
-            for (int i = 0; i < count; i++) {
-                RILRequest rr = mRequestsList.get(i);
-                pw.println("  [" + rr.mSerial + "] " + requestToString(rr.mRequest));
-            }
-        }
-        pw.println(" mLastNITZTimeInfo=" + mLastNITZTimeInfo);
-        pw.println(" mTestingEmergencyCall=" + mTestingEmergencyCall.get());
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/RestrictedState.java b/telephony/java/com/android/internal/telephony/RestrictedState.java
deleted file mode 100644
index ad2b88d..0000000
--- a/telephony/java/com/android/internal/telephony/RestrictedState.java
+++ /dev/null
@@ -1,122 +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.internal.telephony;
-
-import android.telephony.ServiceState;
-
-public class RestrictedState {
-
-    /**
-     * Set true to block packet data access due to restriction
-     */
-    private boolean mPsRestricted;
-    /**
-     * Set true to block all normal voice/SMS/USSD/SS/AV64 due to restriction
-     */
-    private boolean mCsNormalRestricted;
-    /**
-     * Set true to block emergency call due to restriction
-     */
-    private boolean mCsEmergencyRestricted;
-
-    public RestrictedState() {
-        setPsRestricted(false);
-        setCsNormalRestricted(false);
-        setCsEmergencyRestricted(false);
-    }
-
-    /**
-     * @param csEmergencyRestricted the csEmergencyRestricted to set
-     */
-    public void setCsEmergencyRestricted(boolean csEmergencyRestricted) {
-        mCsEmergencyRestricted = csEmergencyRestricted;
-    }
-
-    /**
-     * @return the csEmergencyRestricted
-     */
-    public boolean isCsEmergencyRestricted() {
-        return mCsEmergencyRestricted;
-    }
-
-    /**
-     * @param csNormalRestricted the csNormalRestricted to set
-     */
-    public void setCsNormalRestricted(boolean csNormalRestricted) {
-        mCsNormalRestricted = csNormalRestricted;
-    }
-
-    /**
-     * @return the csNormalRestricted
-     */
-    public boolean isCsNormalRestricted() {
-        return mCsNormalRestricted;
-    }
-
-    /**
-     * @param psRestricted the psRestricted to set
-     */
-    public void setPsRestricted(boolean psRestricted) {
-        mPsRestricted = psRestricted;
-    }
-
-    /**
-     * @return the psRestricted
-     */
-    public boolean isPsRestricted() {
-        return mPsRestricted;
-    }
-
-    public boolean isCsRestricted() {
-        return mCsNormalRestricted && mCsEmergencyRestricted;
-    }
-
-    @Override
-    public boolean equals (Object o) {
-        RestrictedState s;
-
-        try {
-            s = (RestrictedState) o;
-        } catch (ClassCastException ex) {
-            return false;
-        }
-
-        if (o == null) {
-            return false;
-        }
-
-        return mPsRestricted == s.mPsRestricted
-        && mCsNormalRestricted == s.mCsNormalRestricted
-        && mCsEmergencyRestricted == s.mCsEmergencyRestricted;
-    }
-
-    @Override
-    public String toString() {
-        String csString = "none";
-
-        if (mCsEmergencyRestricted && mCsNormalRestricted) {
-            csString = "all";
-        } else if (mCsEmergencyRestricted && !mCsNormalRestricted) {
-            csString = "emergency";
-        } else if (!mCsEmergencyRestricted && mCsNormalRestricted) {
-            csString = "normal call";
-        }
-
-        return  "Restricted State CS: " + csString + " PS:" + mPsRestricted;
-    }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/RetryManager.java b/telephony/java/com/android/internal/telephony/RetryManager.java
deleted file mode 100644
index 250d99e..0000000
--- a/telephony/java/com/android/internal/telephony/RetryManager.java
+++ /dev/null
@@ -1,410 +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.
- */
-
-package com.android.internal.telephony;
-
-import android.util.Log;
-import android.util.Pair;
-import android.text.TextUtils;
-
-import java.util.Random;
-import java.util.ArrayList;
-
-/**
- * Retry manager allows a simple way to declare a series of
- * retry timeouts. After creating a RetryManager the configure
- * method is used to define the sequence. A simple linear series
- * may be initialized using configure with three integer parameters
- * The other configure method allows a series to be declared using
- * a string.
- *<p>
- * The format of the configuration string is a series of parameters
- * separated by a comma. There are two name value pair parameters plus a series
- * of delay times. The units of of these delay times is unspecified.
- * The name value pairs which may be specified are:
- *<ul>
- *<li>max_retries=<value>
- *<li>default_randomizationTime=<value>
- *</ul>
- *<p>
- * max_retries is the number of times that incrementRetryCount
- * maybe called before isRetryNeeded will return false. if value
- * is infinite then isRetryNeeded will always return true.
- *
- * default_randomizationTime will be used as the randomizationTime
- * for delay times which have no supplied randomizationTime. If
- * default_randomizationTime is not defined it defaults to 0.
- *<p>
- * The other parameters define The series of delay times and each
- * may have an optional randomization value separated from the
- * delay time by a colon.
- *<p>
- * Examples:
- * <ul>
- * <li>3 retries with no randomization value which means its 0:
- * <ul><li><code>"1000, 2000, 3000"</code></ul>
- *
- * <li>10 retries with a 500 default randomization value for each and
- * the 4..10 retries all using 3000 as the delay:
- * <ul><li><code>"max_retries=10, default_randomization=500, 1000, 2000, 3000"</code></ul>
- *
- * <li>4 retries with a 100 as the default randomization value for the first 2 values and
- * the other two having specified values of 500:
- * <ul><li><code>"default_randomization=100, 1000, 2000, 4000:500, 5000:500"</code></ul>
- *
- * <li>Infinite number of retries with the first one at 1000, the second at 2000 all
- * others will be at 3000.
- * <ul><li><code>"max_retries=infinite,1000,2000,3000</code></ul>
- * </ul>
- *
- * {@hide}
- */
-public class RetryManager {
-    static public final String LOG_TAG = "GSM";
-    static public final boolean DBG = true;
-    static public final boolean VDBG = false;
-
-    /**
-     * Retry record with times in milli-seconds
-     */
-    private static class RetryRec {
-        RetryRec(int delayTime, int randomizationTime) {
-            mDelayTime = delayTime;
-            mRandomizationTime = randomizationTime;
-        }
-
-        int mDelayTime;
-        int mRandomizationTime;
-    }
-
-    /** The array of retry records */
-    private ArrayList<RetryRec> mRetryArray = new ArrayList<RetryRec>();
-
-    /** When true isRetryNeeded() will always return true */
-    private boolean mRetryForever;
-
-    /**
-     * The maximum number of retries to attempt before
-     * isRetryNeeded returns false
-     */
-    private int mMaxRetryCount;
-
-    /** The current number of retries */
-    private int mRetryCount;
-
-    /** Random number generator */
-    private Random rng = new Random();
-
-    private String mConfig;
-
-    /** Constructor */
-    public RetryManager() {
-        if (VDBG) log("constructor");
-    }
-
-    public String toString() {
-        String ret = "RetryManager: forever=" + mRetryForever + ", maxRetry=" + mMaxRetryCount +
-                ", retry=" + mRetryCount + ",\n    " + mConfig;
-        for (RetryRec r : mRetryArray) {
-            ret += "\n    " + r.mDelayTime + ":" + r.mRandomizationTime;
-        }
-        return ret;
-    }
-
-    /**
-     * Configure for a simple linear sequence of times plus
-     * a random value.
-     *
-     * @param maxRetryCount is the maximum number of retries
-     *        before isRetryNeeded returns false.
-     * @param retryTime is a time that will be returned by getRetryTime.
-     * @param randomizationTime a random value between 0 and
-     *        randomizationTime will be added to retryTime. this
-     *        parameter may be 0.
-     * @return true if successful
-     */
-    public boolean configure(int maxRetryCount, int retryTime, int randomizationTime) {
-        Pair<Boolean, Integer> value;
-
-        if (VDBG) log("configure: " + maxRetryCount + ", " + retryTime + "," + randomizationTime);
-
-        if (!validateNonNegativeInt("maxRetryCount", maxRetryCount)) {
-            return false;
-        }
-
-        if (!validateNonNegativeInt("retryTime", retryTime)) {
-            return false;
-        }
-
-        if (!validateNonNegativeInt("randomizationTime", randomizationTime)) {
-            return false;
-        }
-
-        mMaxRetryCount = maxRetryCount;
-        resetRetryCount();
-        mRetryArray.clear();
-        mRetryArray.add(new RetryRec(retryTime, randomizationTime));
-
-        return true;
-    }
-
-    /**
-     * Configure for using string which allow arbitrary
-     * sequences of times. See class comments for the
-     * string format.
-     *
-     * @return true if successful
-     */
-    public boolean configure(String configStr) {
-        // Strip quotes if present.
-        if ((configStr.startsWith("\"") && configStr.endsWith("\""))) {
-            configStr = configStr.substring(1, configStr.length()-1);
-        }
-        if (VDBG) log("configure: '" + configStr + "'");
-        mConfig = configStr;
-
-        if (!TextUtils.isEmpty(configStr)) {
-            int defaultRandomization = 0;
-
-            if (VDBG) log("configure: not empty");
-
-            mMaxRetryCount = 0;
-            resetRetryCount();
-            mRetryArray.clear();
-
-            String strArray[] = configStr.split(",");
-            for (int i = 0; i < strArray.length; i++) {
-                if (VDBG) log("configure: strArray[" + i + "]='" + strArray[i] + "'");
-                Pair<Boolean, Integer> value;
-                String splitStr[] = strArray[i].split("=", 2);
-                splitStr[0] = splitStr[0].trim();
-                if (VDBG) log("configure: splitStr[0]='" + splitStr[0] + "'");
-                if (splitStr.length > 1) {
-                    splitStr[1] = splitStr[1].trim();
-                    if (VDBG) log("configure: splitStr[1]='" + splitStr[1] + "'");
-                    if (TextUtils.equals(splitStr[0], "default_randomization")) {
-                        value = parseNonNegativeInt(splitStr[0], splitStr[1]);
-                        if (!value.first) return false;
-                        defaultRandomization = value.second;
-                    } else if (TextUtils.equals(splitStr[0], "max_retries")) {
-                        if (TextUtils.equals("infinite",splitStr[1])) {
-                            mRetryForever = true;
-                        } else {
-                            value = parseNonNegativeInt(splitStr[0], splitStr[1]);
-                            if (!value.first) return false;
-                            mMaxRetryCount = value.second;
-                        }
-                    } else {
-                        Log.e(LOG_TAG, "Unrecognized configuration name value pair: "
-                                        + strArray[i]);
-                        return false;
-                    }
-                } else {
-                    /**
-                     * Assume a retry time with an optional randomization value
-                     * following a ":"
-                     */
-                    splitStr = strArray[i].split(":", 2);
-                    splitStr[0] = splitStr[0].trim();
-                    RetryRec rr = new RetryRec(0, 0);
-                    value = parseNonNegativeInt("delayTime", splitStr[0]);
-                    if (!value.first) return false;
-                    rr.mDelayTime = value.second;
-
-                    // Check if optional randomization value present
-                    if (splitStr.length > 1) {
-                        splitStr[1] = splitStr[1].trim();
-                        if (VDBG) log("configure: splitStr[1]='" + splitStr[1] + "'");
-                        value = parseNonNegativeInt("randomizationTime", splitStr[1]);
-                        if (!value.first) return false;
-                        rr.mRandomizationTime = value.second;
-                    } else {
-                        rr.mRandomizationTime = defaultRandomization;
-                    }
-                    mRetryArray.add(rr);
-                }
-            }
-            if (mRetryArray.size() > mMaxRetryCount) {
-                mMaxRetryCount = mRetryArray.size();
-                if (VDBG) log("configure: setting mMaxRetryCount=" + mMaxRetryCount);
-            }
-            if (VDBG) log("configure: true");
-            return true;
-        } else {
-            if (VDBG) log("configure: false it's empty");
-            return false;
-        }
-    }
-
-    /**
-     * Report whether data reconnection should be retried
-     *
-     * @return {@code true} if the max retries has not been reached. {@code
-     *         false} otherwise.
-     */
-    public boolean isRetryNeeded() {
-        boolean retVal = mRetryForever || (mRetryCount < mMaxRetryCount);
-        if (DBG) log("isRetryNeeded: " + retVal);
-        return retVal;
-    }
-
-    /**
-     * Return the timer that should be used to trigger the data reconnection
-     */
-    public int getRetryTimer() {
-        int index;
-        if (mRetryCount < mRetryArray.size()) {
-            index = mRetryCount;
-        } else {
-            index = mRetryArray.size() - 1;
-        }
-
-        int retVal;
-        if ((index >= 0) && (index < mRetryArray.size())) {
-            retVal = mRetryArray.get(index).mDelayTime + nextRandomizationTime(index);
-        } else {
-            retVal = 0;
-        }
-
-        if (DBG) log("getRetryTimer: " + retVal);
-        return retVal;
-    }
-
-    /**
-     * @return retry count
-     */
-    public int getRetryCount() {
-        if (DBG) log("getRetryCount: " + mRetryCount);
-        return mRetryCount;
-    }
-
-    /**
-     * Increase the retry counter, does not change retry forever.
-     */
-    public void increaseRetryCount() {
-        mRetryCount++;
-        if (mRetryCount > mMaxRetryCount) {
-            mRetryCount = mMaxRetryCount;
-        }
-        if (DBG) log("increaseRetryCount: " + mRetryCount);
-    }
-
-    /**
-     * Set retry count to the specified value
-     */
-    public void setRetryCount(int count) {
-        mRetryCount = count;
-        if (mRetryCount > mMaxRetryCount) {
-            mRetryCount = mMaxRetryCount;
-        }
-
-        if (mRetryCount < 0) {
-            mRetryCount = 0;
-        }
-
-        if (DBG) log("setRetryCount: " + mRetryCount);
-    }
-
-    /**
-     * Set retry forever to the specified value
-     */
-    public void setRetryForever(boolean retryForever) {
-        mRetryForever = retryForever;
-        if (DBG) log("setRetryForever: " + mRetryForever);
-    }
-
-    /**
-     * Clear the data-retry counter
-     */
-    public void resetRetryCount() {
-        mRetryCount = 0;
-        if (DBG) log("resetRetryCount: " + mRetryCount);
-    }
-
-    /**
-     * Retry forever using last timeout time.
-     */
-    public void retryForeverUsingLastTimeout() {
-        mRetryCount = mMaxRetryCount;
-        mRetryForever = true;
-        if (DBG) log("retryForeverUsingLastTimeout: " + mRetryForever + ", " + mRetryCount);
-    }
-
-    /**
-     * @return true if retrying forever
-     */
-    public boolean isRetryForever() {
-        if (DBG) log("isRetryForever: " + mRetryForever);
-        return mRetryForever;
-    }
-
-    /**
-     * Parse an integer validating the value is not negative.
-     *
-     * @param name
-     * @param stringValue
-     * @return Pair.first == true if stringValue an integer >= 0
-     */
-    private Pair<Boolean, Integer> parseNonNegativeInt(String name, String stringValue) {
-        int value;
-        Pair<Boolean, Integer> retVal;
-        try {
-            value = Integer.parseInt(stringValue);
-            retVal = new Pair<Boolean, Integer>(validateNonNegativeInt(name, value), value);
-        } catch (NumberFormatException e) {
-            Log.e(LOG_TAG, name + " bad value: " + stringValue, e);
-            retVal = new Pair<Boolean, Integer>(false, 0);
-        }
-        if (VDBG) log("parseNonNetativeInt: " + name + ", " + stringValue + ", "
-                    + retVal.first + ", " + retVal.second);
-        return retVal;
-    }
-
-    /**
-     * Validate an integer is >= 0 and logs an error if not
-     *
-     * @param name
-     * @param value
-     * @return Pair.first
-     */
-    private boolean validateNonNegativeInt(String name, int value) {
-        boolean retVal;
-        if (value < 0) {
-            Log.e(LOG_TAG, name + " bad value: is < 0");
-            retVal = false;
-        } else {
-            retVal = true;
-        }
-        if (VDBG) log("validateNonNegative: " + name + ", " + value + ", " + retVal);
-        return retVal;
-    }
-
-    /**
-     * Return next random number for the index
-     */
-    private int nextRandomizationTime(int index) {
-        int randomTime = mRetryArray.get(index).mRandomizationTime;
-        if (randomTime == 0) {
-            return 0;
-        } else {
-            return rng.nextInt(randomTime);
-        }
-    }
-
-    private void log(String s) {
-        Log.d(LOG_TAG, "[RM] " + s);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
deleted file mode 100644
index 40c22a7..0000000
--- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java
+++ /dev/null
@@ -1,1169 +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.internal.telephony;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.PendingIntent;
-import android.app.PendingIntent.CanceledException;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.database.SQLException;
-import android.net.Uri;
-import android.os.AsyncResult;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.SystemProperties;
-import android.provider.Telephony;
-import android.provider.Telephony.Sms.Intents;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.ServiceState;
-import android.telephony.SmsCbMessage;
-import android.telephony.SmsMessage;
-import android.telephony.TelephonyManager;
-import android.text.Html;
-import android.text.Spanned;
-import android.util.Log;
-import android.view.WindowManager;
-
-import com.android.internal.R;
-import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails;
-import com.android.internal.util.HexDump;
-
-import java.io.ByteArrayOutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Random;
-
-import static android.telephony.SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE;
-import static android.telephony.SmsManager.RESULT_ERROR_GENERIC_FAILURE;
-import static android.telephony.SmsManager.RESULT_ERROR_LIMIT_EXCEEDED;
-import static android.telephony.SmsManager.RESULT_ERROR_NO_SERVICE;
-import static android.telephony.SmsManager.RESULT_ERROR_NULL_PDU;
-import static android.telephony.SmsManager.RESULT_ERROR_RADIO_OFF;
-
-public abstract class SMSDispatcher extends Handler {
-    static final String TAG = "SMS";    // accessed from inner class
-    private static final String SEND_NEXT_MSG_EXTRA = "SendNextMsg";
-
-    /** Permission required to receive SMS and SMS-CB messages. */
-    public static final String RECEIVE_SMS_PERMISSION = "android.permission.RECEIVE_SMS";
-
-    /** Permission required to receive ETWS and CMAS emergency broadcasts. */
-    public static final String RECEIVE_EMERGENCY_BROADCAST_PERMISSION =
-            "android.permission.RECEIVE_EMERGENCY_BROADCAST";
-
-    /** Permission required to send SMS to short codes without user confirmation. */
-    private static final String SEND_SMS_NO_CONFIRMATION_PERMISSION =
-            "android.permission.SEND_SMS_NO_CONFIRMATION";
-
-    /** Query projection for checking for duplicate message segments. */
-    private static final String[] PDU_PROJECTION = new String[] {
-            "pdu"
-    };
-
-    /** Query projection for combining concatenated message segments. */
-    private static final String[] PDU_SEQUENCE_PORT_PROJECTION = new String[] {
-            "pdu",
-            "sequence",
-            "destination_port"
-    };
-
-    private static final int PDU_COLUMN = 0;
-    private static final int SEQUENCE_COLUMN = 1;
-    private static final int DESTINATION_PORT_COLUMN = 2;
-
-    /** New SMS received. */
-    protected static final int EVENT_NEW_SMS = 1;
-
-    /** SMS send complete. */
-    protected static final int EVENT_SEND_SMS_COMPLETE = 2;
-
-    /** Retry sending a previously failed SMS message */
-    private static final int EVENT_SEND_RETRY = 3;
-
-    /** Confirmation required for sending a large number of messages. */
-    private static final int EVENT_SEND_LIMIT_REACHED_CONFIRMATION = 4;
-
-    /** Send the user confirmed SMS */
-    static final int EVENT_SEND_CONFIRMED_SMS = 5;  // accessed from inner class
-
-    /** Don't send SMS (user did not confirm). */
-    static final int EVENT_STOP_SENDING = 7;        // accessed from inner class
-
-    protected final Phone mPhone;
-    protected final Context mContext;
-    protected final ContentResolver mResolver;
-    protected final CommandsInterface mCm;
-    protected final SmsStorageMonitor mStorageMonitor;
-    protected final TelephonyManager mTelephonyManager;
-
-    protected final WapPushOverSms mWapPush;
-
-    protected static final Uri mRawUri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw");
-
-    /** Maximum number of times to retry sending a failed SMS. */
-    private static final int MAX_SEND_RETRIES = 3;
-    /** Delay before next send attempt on a failed SMS, in milliseconds. */
-    private static final int SEND_RETRY_DELAY = 2000;
-    /** single part SMS */
-    private static final int SINGLE_PART_SMS = 1;
-    /** Message sending queue limit */
-    private static final int MO_MSG_QUEUE_LIMIT = 5;
-
-    /**
-     * Message reference for a CONCATENATED_8_BIT_REFERENCE or
-     * CONCATENATED_16_BIT_REFERENCE message set.  Should be
-     * incremented for each set of concatenated messages.
-     * Static field shared by all dispatcher objects.
-     */
-    private static int sConcatenatedRef = new Random().nextInt(256);
-
-    /** Outgoing message counter. Shared by all dispatchers. */
-    private final SmsUsageMonitor mUsageMonitor;
-
-    /** Number of outgoing SmsTrackers waiting for user confirmation. */
-    private int mPendingTrackerCount;
-
-    /** Wake lock to ensure device stays awake while dispatching the SMS intent. */
-    private PowerManager.WakeLock mWakeLock;
-
-    /**
-     * Hold the wake lock for 5 seconds, which should be enough time for
-     * any receiver(s) to grab its own wake lock.
-     */
-    private static final int WAKE_LOCK_TIMEOUT = 5000;
-
-    /* Flags indicating whether the current device allows sms service */
-    protected boolean mSmsCapable = true;
-    protected boolean mSmsReceiveDisabled;
-    protected boolean mSmsSendDisabled;
-
-    protected int mRemainingMessages = -1;
-
-    protected static int getNextConcatenatedRef() {
-        sConcatenatedRef += 1;
-        return sConcatenatedRef;
-    }
-
-    /**
-     * Create a new SMS dispatcher.
-     * @param phone the Phone to use
-     * @param storageMonitor the SmsStorageMonitor to use
-     * @param usageMonitor the SmsUsageMonitor to use
-     */
-    protected SMSDispatcher(PhoneBase phone, SmsStorageMonitor storageMonitor,
-            SmsUsageMonitor usageMonitor) {
-        mPhone = phone;
-        mWapPush = new WapPushOverSms(phone, this);
-        mContext = phone.getContext();
-        mResolver = mContext.getContentResolver();
-        mCm = phone.mCM;
-        mStorageMonitor = storageMonitor;
-        mUsageMonitor = usageMonitor;
-        mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
-
-        createWakelock();
-
-        mSmsCapable = mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_sms_capable);
-        mSmsReceiveDisabled = !SystemProperties.getBoolean(
-                                TelephonyProperties.PROPERTY_SMS_RECEIVE, mSmsCapable);
-        mSmsSendDisabled = !SystemProperties.getBoolean(
-                                TelephonyProperties.PROPERTY_SMS_SEND, mSmsCapable);
-        Log.d(TAG, "SMSDispatcher: ctor mSmsCapable=" + mSmsCapable + " format=" + getFormat()
-                + " mSmsReceiveDisabled=" + mSmsReceiveDisabled
-                + " mSmsSendDisabled=" + mSmsSendDisabled);
-    }
-
-    /** Unregister for incoming SMS events. */
-    public abstract void dispose();
-
-    /**
-     * The format of the message PDU in the associated broadcast intent.
-     * This will be either "3gpp" for GSM/UMTS/LTE messages in 3GPP format
-     * or "3gpp2" for CDMA/LTE messages in 3GPP2 format.
-     *
-     * Note: All applications which handle incoming SMS messages by processing the
-     * SMS_RECEIVED_ACTION broadcast intent MUST pass the "format" extra from the intent
-     * into the new methods in {@link android.telephony.SmsMessage} which take an
-     * extra format parameter. This is required in order to correctly decode the PDU on
-     * devices which require support for both 3GPP and 3GPP2 formats at the same time,
-     * such as CDMA/LTE devices and GSM/CDMA world phones.
-     *
-     * @return the format of the message PDU
-     */
-    protected abstract String getFormat();
-
-    @Override
-    protected void finalize() {
-        Log.d(TAG, "SMSDispatcher finalized");
-    }
-
-
-    /* TODO: Need to figure out how to keep track of status report routing in a
-     *       persistent manner. If the phone process restarts (reboot or crash),
-     *       we will lose this list and any status reports that come in after
-     *       will be dropped.
-     */
-    /** Sent messages awaiting a delivery status report. */
-    protected final ArrayList<SmsTracker> deliveryPendingList = new ArrayList<SmsTracker>();
-
-    /**
-     * Handles events coming from the phone stack. Overridden from handler.
-     *
-     * @param msg the message to handle
-     */
-    @Override
-    public void handleMessage(Message msg) {
-        AsyncResult ar;
-
-        switch (msg.what) {
-        case EVENT_NEW_SMS:
-            // A new SMS has been received by the device
-            if (false) {
-                Log.d(TAG, "New SMS Message Received");
-            }
-
-            SmsMessage sms;
-
-            ar = (AsyncResult) msg.obj;
-
-            if (ar.exception != null) {
-                Log.e(TAG, "Exception processing incoming SMS. Exception:" + ar.exception);
-                return;
-            }
-
-            sms = (SmsMessage) ar.result;
-            try {
-                int result = dispatchMessage(sms.mWrappedSmsMessage);
-                if (result != Activity.RESULT_OK) {
-                    // RESULT_OK means that message was broadcast for app(s) to handle.
-                    // Any other result, we should ack here.
-                    boolean handled = (result == Intents.RESULT_SMS_HANDLED);
-                    notifyAndAcknowledgeLastIncomingSms(handled, result, null);
-                }
-            } catch (RuntimeException ex) {
-                Log.e(TAG, "Exception dispatching message", ex);
-                notifyAndAcknowledgeLastIncomingSms(false, Intents.RESULT_SMS_GENERIC_ERROR, null);
-            }
-
-            break;
-
-        case EVENT_SEND_SMS_COMPLETE:
-            // An outbound SMS has been successfully transferred, or failed.
-            handleSendComplete((AsyncResult) msg.obj);
-            break;
-
-        case EVENT_SEND_RETRY:
-            sendSms((SmsTracker) msg.obj);
-            break;
-
-        case EVENT_SEND_LIMIT_REACHED_CONFIRMATION:
-            handleReachSentLimit((SmsTracker)(msg.obj));
-            break;
-
-        case EVENT_SEND_CONFIRMED_SMS:
-        {
-            SmsTracker tracker = (SmsTracker) msg.obj;
-            if (tracker.isMultipart()) {
-                sendMultipartSms(tracker);
-            } else {
-                sendSms(tracker);
-            }
-            mPendingTrackerCount--;
-            break;
-        }
-
-        case EVENT_STOP_SENDING:
-        {
-            SmsTracker tracker = (SmsTracker) msg.obj;
-            if (tracker.mSentIntent != null) {
-                try {
-                    tracker.mSentIntent.send(RESULT_ERROR_LIMIT_EXCEEDED);
-                } catch (CanceledException ex) {
-                    Log.e(TAG, "failed to send RESULT_ERROR_LIMIT_EXCEEDED");
-                }
-            }
-            mPendingTrackerCount--;
-            break;
-        }
-        }
-    }
-
-    private void createWakelock() {
-        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
-        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SMSDispatcher");
-        mWakeLock.setReferenceCounted(true);
-    }
-
-    /**
-     * Grabs a wake lock and sends intent as an ordered broadcast.
-     * The resultReceiver will check for errors and ACK/NACK back
-     * to the RIL.
-     *
-     * @param intent intent to broadcast
-     * @param permission Receivers are required to have this permission
-     */
-    public void dispatch(Intent intent, String permission) {
-        // Hold a wake lock for WAKE_LOCK_TIMEOUT seconds, enough to give any
-        // receivers time to take their own wake locks.
-        mWakeLock.acquire(WAKE_LOCK_TIMEOUT);
-        mContext.sendOrderedBroadcast(intent, permission, mResultReceiver,
-                this, Activity.RESULT_OK, null, null);
-    }
-
-    /**
-     * Grabs a wake lock and sends intent as an ordered broadcast.
-     * Used for setting a custom result receiver for CDMA SCPD.
-     *
-     * @param intent intent to broadcast
-     * @param permission Receivers are required to have this permission
-     * @param resultReceiver the result receiver to use
-     */
-    public void dispatch(Intent intent, String permission, BroadcastReceiver resultReceiver) {
-        // Hold a wake lock for WAKE_LOCK_TIMEOUT seconds, enough to give any
-        // receivers time to take their own wake locks.
-        mWakeLock.acquire(WAKE_LOCK_TIMEOUT);
-        mContext.sendOrderedBroadcast(intent, permission, resultReceiver,
-                this, Activity.RESULT_OK, null, null);
-    }
-
-    /**
-     * Called when SMS send completes. Broadcasts a sentIntent on success.
-     * On failure, either sets up retries or broadcasts a sentIntent with
-     * the failure in the result code.
-     *
-     * @param ar AsyncResult passed into the message handler.  ar.result should
-     *           an SmsResponse instance if send was successful.  ar.userObj
-     *           should be an SmsTracker instance.
-     */
-    protected void handleSendComplete(AsyncResult ar) {
-        SmsTracker tracker = (SmsTracker) ar.userObj;
-        PendingIntent sentIntent = tracker.mSentIntent;
-
-        if (ar.exception == null) {
-            if (false) {
-                Log.d(TAG, "SMS send complete. Broadcasting "
-                        + "intent: " + sentIntent);
-            }
-
-            if (tracker.mDeliveryIntent != null) {
-                // Expecting a status report.  Add it to the list.
-                int messageRef = ((SmsResponse)ar.result).messageRef;
-                tracker.mMessageRef = messageRef;
-                deliveryPendingList.add(tracker);
-            }
-
-            if (sentIntent != null) {
-                try {
-                    if (mRemainingMessages > -1) {
-                        mRemainingMessages--;
-                    }
-
-                    if (mRemainingMessages == 0) {
-                        Intent sendNext = new Intent();
-                        sendNext.putExtra(SEND_NEXT_MSG_EXTRA, true);
-                        sentIntent.send(mContext, Activity.RESULT_OK, sendNext);
-                    } else {
-                        sentIntent.send(Activity.RESULT_OK);
-                    }
-                } catch (CanceledException ex) {}
-            }
-        } else {
-            if (false) {
-                Log.d(TAG, "SMS send failed");
-            }
-
-            int ss = mPhone.getServiceState().getState();
-
-            if (ss != ServiceState.STATE_IN_SERVICE) {
-                handleNotInService(ss, tracker.mSentIntent);
-            } else if ((((CommandException)(ar.exception)).getCommandError()
-                    == CommandException.Error.SMS_FAIL_RETRY) &&
-                   tracker.mRetryCount < MAX_SEND_RETRIES) {
-                // Retry after a delay if needed.
-                // TODO: According to TS 23.040, 9.2.3.6, we should resend
-                //       with the same TP-MR as the failed message, and
-                //       TP-RD set to 1.  However, we don't have a means of
-                //       knowing the MR for the failed message (EF_SMSstatus
-                //       may or may not have the MR corresponding to this
-                //       message, depending on the failure).  Also, in some
-                //       implementations this retry is handled by the baseband.
-                tracker.mRetryCount++;
-                Message retryMsg = obtainMessage(EVENT_SEND_RETRY, tracker);
-                sendMessageDelayed(retryMsg, SEND_RETRY_DELAY);
-            } else if (tracker.mSentIntent != null) {
-                int error = RESULT_ERROR_GENERIC_FAILURE;
-
-                if (((CommandException)(ar.exception)).getCommandError()
-                        == CommandException.Error.FDN_CHECK_FAILURE) {
-                    error = RESULT_ERROR_FDN_CHECK_FAILURE;
-                }
-                // Done retrying; return an error to the app.
-                try {
-                    Intent fillIn = new Intent();
-                    if (ar.result != null) {
-                        fillIn.putExtra("errorCode", ((SmsResponse)ar.result).errorCode);
-                    }
-                    if (mRemainingMessages > -1) {
-                        mRemainingMessages--;
-                    }
-
-                    if (mRemainingMessages == 0) {
-                        fillIn.putExtra(SEND_NEXT_MSG_EXTRA, true);
-                    }
-
-                    tracker.mSentIntent.send(mContext, error, fillIn);
-                } catch (CanceledException ex) {}
-            }
-        }
-    }
-
-    /**
-     * Handles outbound message when the phone is not in service.
-     *
-     * @param ss     Current service state.  Valid values are:
-     *                  OUT_OF_SERVICE
-     *                  EMERGENCY_ONLY
-     *                  POWER_OFF
-     * @param sentIntent the PendingIntent to send the error to
-     */
-    protected static void handleNotInService(int ss, PendingIntent sentIntent) {
-        if (sentIntent != null) {
-            try {
-                if (ss == ServiceState.STATE_POWER_OFF) {
-                    sentIntent.send(RESULT_ERROR_RADIO_OFF);
-                } else {
-                    sentIntent.send(RESULT_ERROR_NO_SERVICE);
-                }
-            } catch (CanceledException ex) {}
-        }
-    }
-
-    /**
-     * Dispatches an incoming SMS messages.
-     *
-     * @param sms the incoming message from the phone
-     * @return a result code from {@link Telephony.Sms.Intents}, or
-     *         {@link Activity#RESULT_OK} if the message has been broadcast
-     *         to applications
-     */
-    public abstract int dispatchMessage(SmsMessageBase sms);
-
-    /**
-     * Dispatch a normal incoming SMS. This is called from the format-specific
-     * {@link #dispatchMessage(SmsMessageBase)} if no format-specific handling is required.
-     *
-     * @param sms
-     * @return
-     */
-    protected int dispatchNormalMessage(SmsMessageBase sms) {
-        SmsHeader smsHeader = sms.getUserDataHeader();
-
-        // See if message is partial or port addressed.
-        if ((smsHeader == null) || (smsHeader.concatRef == null)) {
-            // Message is not partial (not part of concatenated sequence).
-            byte[][] pdus = new byte[1][];
-            pdus[0] = sms.getPdu();
-
-            if (smsHeader != null && smsHeader.portAddrs != null) {
-                if (smsHeader.portAddrs.destPort == SmsHeader.PORT_WAP_PUSH) {
-                    // GSM-style WAP indication
-                    return mWapPush.dispatchWapPdu(sms.getUserData());
-                } else {
-                    // The message was sent to a port, so concoct a URI for it.
-                    dispatchPortAddressedPdus(pdus, smsHeader.portAddrs.destPort);
-                }
-            } else {
-                // Normal short and non-port-addressed message, dispatch it.
-                dispatchPdus(pdus);
-            }
-            return Activity.RESULT_OK;
-        } else {
-            // Process the message part.
-            SmsHeader.ConcatRef concatRef = smsHeader.concatRef;
-            SmsHeader.PortAddrs portAddrs = smsHeader.portAddrs;
-            return processMessagePart(sms.getPdu(), sms.getOriginatingAddress(),
-                    concatRef.refNumber, concatRef.seqNumber, concatRef.msgCount,
-                    sms.getTimestampMillis(), (portAddrs != null ? portAddrs.destPort : -1), false);
-        }
-    }
-
-    /**
-     * If this is the last part send the parts out to the application, otherwise
-     * the part is stored for later processing. Handles both 3GPP concatenated messages
-     * as well as 3GPP2 format WAP push messages processed by
-     * {@link com.android.internal.telephony.cdma.CdmaSMSDispatcher#processCdmaWapPdu}.
-     *
-     * @param pdu the message PDU, or the datagram portion of a CDMA WDP datagram segment
-     * @param address the originating address
-     * @param referenceNumber distinguishes concatenated messages from the same sender
-     * @param sequenceNumber the order of this segment in the message
-     *          (starting at 0 for CDMA WDP datagrams and 1 for concatenated messages).
-     * @param messageCount the number of segments in the message
-     * @param timestamp the service center timestamp in millis
-     * @param destPort the destination port for the message, or -1 for no destination port
-     * @param isCdmaWapPush true if pdu is a CDMA WDP datagram segment and not an SM PDU
-     *
-     * @return a result code from {@link Telephony.Sms.Intents}, or
-     *         {@link Activity#RESULT_OK} if the message has been broadcast
-     *         to applications
-     */
-    protected int processMessagePart(byte[] pdu, String address, int referenceNumber,
-            int sequenceNumber, int messageCount, long timestamp, int destPort,
-            boolean isCdmaWapPush) {
-        byte[][] pdus = null;
-        Cursor cursor = null;
-        try {
-            // used by several query selection arguments
-            String refNumber = Integer.toString(referenceNumber);
-            String seqNumber = Integer.toString(sequenceNumber);
-
-            // Check for duplicate message segment
-            cursor = mResolver.query(mRawUri, PDU_PROJECTION,
-                    "address=? AND reference_number=? AND sequence=?",
-                    new String[] {address, refNumber, seqNumber}, null);
-
-            // moveToNext() returns false if no duplicates were found
-            if (cursor.moveToNext()) {
-                Log.w(TAG, "Discarding duplicate message segment from address=" + address
-                        + " refNumber=" + refNumber + " seqNumber=" + seqNumber);
-                String oldPduString = cursor.getString(PDU_COLUMN);
-                byte[] oldPdu = HexDump.hexStringToByteArray(oldPduString);
-                if (!Arrays.equals(oldPdu, pdu)) {
-                    Log.e(TAG, "Warning: dup message segment PDU of length " + pdu.length
-                            + " is different from existing PDU of length " + oldPdu.length);
-                }
-                return Intents.RESULT_SMS_HANDLED;
-            }
-            cursor.close();
-
-            // not a dup, query for all other segments of this concatenated message
-            String where = "address=? AND reference_number=?";
-            String[] whereArgs = new String[] {address, refNumber};
-            cursor = mResolver.query(mRawUri, PDU_SEQUENCE_PORT_PROJECTION, where, whereArgs, null);
-
-            int cursorCount = cursor.getCount();
-            if (cursorCount != messageCount - 1) {
-                // We don't have all the parts yet, store this one away
-                ContentValues values = new ContentValues();
-                values.put("date", timestamp);
-                values.put("pdu", HexDump.toHexString(pdu));
-                values.put("address", address);
-                values.put("reference_number", referenceNumber);
-                values.put("count", messageCount);
-                values.put("sequence", sequenceNumber);
-                if (destPort != -1) {
-                    values.put("destination_port", destPort);
-                }
-                mResolver.insert(mRawUri, values);
-                return Intents.RESULT_SMS_HANDLED;
-            }
-
-            // All the parts are in place, deal with them
-            pdus = new byte[messageCount][];
-            for (int i = 0; i < cursorCount; i++) {
-                cursor.moveToNext();
-                int cursorSequence = cursor.getInt(SEQUENCE_COLUMN);
-                // GSM sequence numbers start at 1; CDMA WDP datagram sequence numbers start at 0
-                if (!isCdmaWapPush) {
-                    cursorSequence--;
-                }
-                pdus[cursorSequence] = HexDump.hexStringToByteArray(
-                        cursor.getString(PDU_COLUMN));
-
-                // Read the destination port from the first segment (needed for CDMA WAP PDU).
-                // It's not a bad idea to prefer the port from the first segment for 3GPP as well.
-                if (cursorSequence == 0 && !cursor.isNull(DESTINATION_PORT_COLUMN)) {
-                    destPort = cursor.getInt(DESTINATION_PORT_COLUMN);
-                }
-            }
-            // This one isn't in the DB, so add it
-            // GSM sequence numbers start at 1; CDMA WDP datagram sequence numbers start at 0
-            if (isCdmaWapPush) {
-                pdus[sequenceNumber] = pdu;
-            } else {
-                pdus[sequenceNumber - 1] = pdu;
-            }
-
-            // Remove the parts from the database
-            mResolver.delete(mRawUri, where, whereArgs);
-        } catch (SQLException e) {
-            Log.e(TAG, "Can't access multipart SMS database", e);
-            return Intents.RESULT_SMS_GENERIC_ERROR;
-        } finally {
-            if (cursor != null) cursor.close();
-        }
-
-        // Special handling for CDMA WDP datagrams
-        if (isCdmaWapPush) {
-            // Build up the data stream
-            ByteArrayOutputStream output = new ByteArrayOutputStream();
-            for (int i = 0; i < messageCount; i++) {
-                // reassemble the (WSP-)pdu
-                output.write(pdus[i], 0, pdus[i].length);
-            }
-            byte[] datagram = output.toByteArray();
-
-            // Dispatch the PDU to applications
-            if (destPort == SmsHeader.PORT_WAP_PUSH) {
-                // Handle the PUSH
-                return mWapPush.dispatchWapPdu(datagram);
-            } else {
-                pdus = new byte[1][];
-                pdus[0] = datagram;
-                // The messages were sent to any other WAP port
-                dispatchPortAddressedPdus(pdus, destPort);
-                return Activity.RESULT_OK;
-            }
-        }
-
-        // Dispatch the PDUs to applications
-        if (destPort != -1) {
-            if (destPort == SmsHeader.PORT_WAP_PUSH) {
-                // Build up the data stream
-                ByteArrayOutputStream output = new ByteArrayOutputStream();
-                for (int i = 0; i < messageCount; i++) {
-                    SmsMessage msg = SmsMessage.createFromPdu(pdus[i], getFormat());
-                    byte[] data = msg.getUserData();
-                    output.write(data, 0, data.length);
-                }
-                // Handle the PUSH
-                return mWapPush.dispatchWapPdu(output.toByteArray());
-            } else {
-                // The messages were sent to a port, so concoct a URI for it
-                dispatchPortAddressedPdus(pdus, destPort);
-            }
-        } else {
-            // The messages were not sent to a port
-            dispatchPdus(pdus);
-        }
-        return Activity.RESULT_OK;
-    }
-
-    /**
-     * Dispatches standard PDUs to interested applications
-     *
-     * @param pdus The raw PDUs making up the message
-     */
-    protected void dispatchPdus(byte[][] pdus) {
-        Intent intent = new Intent(Intents.SMS_RECEIVED_ACTION);
-        intent.putExtra("pdus", pdus);
-        intent.putExtra("format", getFormat());
-        dispatch(intent, RECEIVE_SMS_PERMISSION);
-    }
-
-    /**
-     * Dispatches port addressed PDUs to interested applications
-     *
-     * @param pdus The raw PDUs making up the message
-     * @param port The destination port of the messages
-     */
-    protected void dispatchPortAddressedPdus(byte[][] pdus, int port) {
-        Uri uri = Uri.parse("sms://localhost:" + port);
-        Intent intent = new Intent(Intents.DATA_SMS_RECEIVED_ACTION, uri);
-        intent.putExtra("pdus", pdus);
-        intent.putExtra("format", getFormat());
-        dispatch(intent, RECEIVE_SMS_PERMISSION);
-    }
-
-    /**
-     * Send a data based SMS to a specific application port.
-     *
-     * @param destAddr the address to send the message to
-     * @param scAddr is the service center address or null to use
-     *  the current default SMSC
-     * @param destPort the port to deliver the message to
-     * @param data the body of the message to send
-     * @param sentIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is successfully sent, or failed.
-     *  The result code will be <code>Activity.RESULT_OK<code> for success,
-     *  or one of these errors:<br>
-     *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
-     *  <code>RESULT_ERROR_RADIO_OFF</code><br>
-     *  <code>RESULT_ERROR_NULL_PDU</code><br>
-     *  <code>RESULT_ERROR_NO_SERVICE</code><br>.
-     *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
-     *  the extra "errorCode" containing a radio technology specific value,
-     *  generally only useful for troubleshooting.<br>
-     *  The per-application based SMS control checks sentIntent. If sentIntent
-     *  is NULL the caller will be checked against all unknown applications,
-     *  which cause smaller number of SMS to be sent in checking period.
-     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is delivered to the recipient.  The
-     *  raw pdu of the status report is in the extended data ("pdu").
-     */
-    protected abstract void sendData(String destAddr, String scAddr, int destPort,
-            byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent);
-
-    /**
-     * Send a text based SMS.
-     *
-     * @param destAddr the address to send the message to
-     * @param scAddr is the service center address or null to use
-     *  the current default SMSC
-     * @param text the body of the message to send
-     * @param sentIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is successfully sent, or failed.
-     *  The result code will be <code>Activity.RESULT_OK<code> for success,
-     *  or one of these errors:<br>
-     *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
-     *  <code>RESULT_ERROR_RADIO_OFF</code><br>
-     *  <code>RESULT_ERROR_NULL_PDU</code><br>
-     *  <code>RESULT_ERROR_NO_SERVICE</code><br>.
-     *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
-     *  the extra "errorCode" containing a radio technology specific value,
-     *  generally only useful for troubleshooting.<br>
-     *  The per-application based SMS control checks sentIntent. If sentIntent
-     *  is NULL the caller will be checked against all unknown applications,
-     *  which cause smaller number of SMS to be sent in checking period.
-     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is delivered to the recipient.  The
-     *  raw pdu of the status report is in the extended data ("pdu").
-     */
-    protected abstract void sendText(String destAddr, String scAddr,
-            String text, PendingIntent sentIntent, PendingIntent deliveryIntent);
-
-    /**
-     * Calculate the number of septets needed to encode the message.
-     *
-     * @param messageBody the message to encode
-     * @param use7bitOnly ignore (but still count) illegal characters if true
-     * @return TextEncodingDetails
-     */
-    protected abstract TextEncodingDetails calculateLength(CharSequence messageBody,
-            boolean use7bitOnly);
-
-    /**
-     * Send a multi-part text based SMS.
-     *
-     * @param destAddr the address to send the message to
-     * @param scAddr is the service center address or null to use
-     *   the current default SMSC
-     * @param parts an <code>ArrayList</code> of strings that, in order,
-     *   comprise the original message
-     * @param sentIntents if not null, an <code>ArrayList</code> of
-     *   <code>PendingIntent</code>s (one for each message part) that is
-     *   broadcast when the corresponding message part has been sent.
-     *   The result code will be <code>Activity.RESULT_OK<code> for success,
-     *   or one of these errors:
-     *   <code>RESULT_ERROR_GENERIC_FAILURE</code>
-     *   <code>RESULT_ERROR_RADIO_OFF</code>
-     *   <code>RESULT_ERROR_NULL_PDU</code>
-     *   <code>RESULT_ERROR_NO_SERVICE</code>.
-     *  The per-application based SMS control checks sentIntent. If sentIntent
-     *  is NULL the caller will be checked against all unknown applications,
-     *  which cause smaller number of SMS to be sent in checking period.
-     * @param deliveryIntents if not null, an <code>ArrayList</code> of
-     *   <code>PendingIntent</code>s (one for each message part) that is
-     *   broadcast when the corresponding message part has been delivered
-     *   to the recipient.  The raw pdu of the status report is in the
-     *   extended data ("pdu").
-     */
-    protected void sendMultipartText(String destAddr, String scAddr,
-            ArrayList<String> parts, ArrayList<PendingIntent> sentIntents,
-            ArrayList<PendingIntent> deliveryIntents) {
-
-        int refNumber = getNextConcatenatedRef() & 0x00FF;
-        int msgCount = parts.size();
-        int encoding = android.telephony.SmsMessage.ENCODING_UNKNOWN;
-
-        mRemainingMessages = msgCount;
-
-        TextEncodingDetails[] encodingForParts = new TextEncodingDetails[msgCount];
-        for (int i = 0; i < msgCount; i++) {
-            TextEncodingDetails details = calculateLength(parts.get(i), false);
-            if (encoding != details.codeUnitSize
-                    && (encoding == android.telephony.SmsMessage.ENCODING_UNKNOWN
-                            || encoding == android.telephony.SmsMessage.ENCODING_7BIT)) {
-                encoding = details.codeUnitSize;
-            }
-            encodingForParts[i] = details;
-        }
-
-        for (int i = 0; i < msgCount; i++) {
-            SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
-            concatRef.refNumber = refNumber;
-            concatRef.seqNumber = i + 1;  // 1-based sequence
-            concatRef.msgCount = msgCount;
-            // TODO: We currently set this to true since our messaging app will never
-            // send more than 255 parts (it converts the message to MMS well before that).
-            // However, we should support 3rd party messaging apps that might need 16-bit
-            // references
-            // Note:  It's not sufficient to just flip this bit to true; it will have
-            // ripple effects (several calculations assume 8-bit ref).
-            concatRef.isEightBits = true;
-            SmsHeader smsHeader = new SmsHeader();
-            smsHeader.concatRef = concatRef;
-
-            // Set the national language tables for 3GPP 7-bit encoding, if enabled.
-            if (encoding == android.telephony.SmsMessage.ENCODING_7BIT) {
-                smsHeader.languageTable = encodingForParts[i].languageTable;
-                smsHeader.languageShiftTable = encodingForParts[i].languageShiftTable;
-            }
-
-            PendingIntent sentIntent = null;
-            if (sentIntents != null && sentIntents.size() > i) {
-                sentIntent = sentIntents.get(i);
-            }
-
-            PendingIntent deliveryIntent = null;
-            if (deliveryIntents != null && deliveryIntents.size() > i) {
-                deliveryIntent = deliveryIntents.get(i);
-            }
-
-            sendNewSubmitPdu(destAddr, scAddr, parts.get(i), smsHeader, encoding,
-                    sentIntent, deliveryIntent, (i == (msgCount - 1)));
-        }
-
-    }
-
-    /**
-     * Create a new SubmitPdu and send it.
-     */
-    protected abstract void sendNewSubmitPdu(String destinationAddress, String scAddress,
-            String message, SmsHeader smsHeader, int encoding,
-            PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart);
-
-    /**
-     * Send a SMS
-     *
-     * @param smsc the SMSC to send the message through, or NULL for the
-     *  default SMSC
-     * @param pdu the raw PDU to send
-     * @param sentIntent if not NULL this <code>Intent</code> is
-     *  broadcast when the message is successfully sent, or failed.
-     *  The result code will be <code>Activity.RESULT_OK<code> for success,
-     *  or one of these errors:
-     *  <code>RESULT_ERROR_GENERIC_FAILURE</code>
-     *  <code>RESULT_ERROR_RADIO_OFF</code>
-     *  <code>RESULT_ERROR_NULL_PDU</code>
-     *  <code>RESULT_ERROR_NO_SERVICE</code>.
-     *  The per-application based SMS control checks sentIntent. If sentIntent
-     *  is NULL the caller will be checked against all unknown applications,
-     *  which cause smaller number of SMS to be sent in checking period.
-     * @param deliveryIntent if not NULL this <code>Intent</code> is
-     *  broadcast when the message is delivered to the recipient.  The
-     *  raw pdu of the status report is in the extended data ("pdu").
-     * @param destAddr the destination phone number (for short code confirmation)
-     */
-    protected void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
-            PendingIntent deliveryIntent, String destAddr) {
-        if (mSmsSendDisabled) {
-            if (sentIntent != null) {
-                try {
-                    sentIntent.send(RESULT_ERROR_NO_SERVICE);
-                } catch (CanceledException ex) {}
-            }
-            Log.d(TAG, "Device does not support sending sms.");
-            return;
-        }
-
-        if (pdu == null) {
-            if (sentIntent != null) {
-                try {
-                    sentIntent.send(RESULT_ERROR_NULL_PDU);
-                } catch (CanceledException ex) {}
-            }
-            return;
-        }
-
-        HashMap<String, Object> map = new HashMap<String, Object>();
-        map.put("smsc", smsc);
-        map.put("pdu", pdu);
-
-        // Get calling app package name via UID from Binder call
-        PackageManager pm = mContext.getPackageManager();
-        String[] packageNames = pm.getPackagesForUid(Binder.getCallingUid());
-
-        if (packageNames == null || packageNames.length == 0) {
-            // Refuse to send SMS if we can't get the calling package name.
-            Log.e(TAG, "Can't get calling app package name: refusing to send SMS");
-            if (sentIntent != null) {
-                try {
-                    sentIntent.send(RESULT_ERROR_GENERIC_FAILURE);
-                } catch (CanceledException ex) {
-                    Log.e(TAG, "failed to send error result");
-                }
-            }
-            return;
-        }
-
-        String appPackage = packageNames[0];
-
-        // Strip non-digits from destination phone number before checking for short codes
-        // and before displaying the number to the user if confirmation is required.
-        SmsTracker tracker = new SmsTracker(map, sentIntent, deliveryIntent, appPackage,
-                PhoneNumberUtils.extractNetworkPortion(destAddr));
-
-        // check for excessive outgoing SMS usage by this app
-        if (!mUsageMonitor.check(appPackage, SINGLE_PART_SMS)) {
-            sendMessage(obtainMessage(EVENT_SEND_LIMIT_REACHED_CONFIRMATION, tracker));
-            return;
-        }
-
-        int ss = mPhone.getServiceState().getState();
-
-        if (ss != ServiceState.STATE_IN_SERVICE) {
-            handleNotInService(ss, tracker.mSentIntent);
-        } else {
-            sendSms(tracker);
-        }
-    }
-
-    /**
-     * Deny sending an SMS if the outgoing queue limit is reached. Used when the message
-     * must be confirmed by the user due to excessive usage or potential premium SMS detected.
-     * @param tracker the SmsTracker for the message to send
-     * @return true if the message was denied; false to continue with send confirmation
-     */
-    private boolean denyIfQueueLimitReached(SmsTracker tracker) {
-        if (mPendingTrackerCount >= MO_MSG_QUEUE_LIMIT) {
-            // Deny sending message when the queue limit is reached.
-            try {
-                tracker.mSentIntent.send(RESULT_ERROR_LIMIT_EXCEEDED);
-            } catch (CanceledException ex) {
-                Log.e(TAG, "failed to send back RESULT_ERROR_LIMIT_EXCEEDED");
-            }
-            return true;
-        }
-        mPendingTrackerCount++;
-        return false;
-    }
-
-    /**
-     * Returns the label for the specified app package name.
-     * @param appPackage the package name of the app requesting to send an SMS
-     * @return the label for the specified app, or the package name if getApplicationInfo() fails
-     */
-    private CharSequence getAppLabel(String appPackage) {
-        PackageManager pm = mContext.getPackageManager();
-        try {
-            ApplicationInfo appInfo = pm.getApplicationInfo(appPackage, 0);
-            return appInfo.loadLabel(pm);
-        } catch (PackageManager.NameNotFoundException e) {
-            Log.e(TAG, "PackageManager Name Not Found for package " + appPackage);
-            return appPackage;  // fall back to package name if we can't get app label
-        }
-    }
-
-    /**
-     * Post an alert when SMS needs confirmation due to excessive usage.
-     * @param tracker an SmsTracker for the current message.
-     */
-    protected void handleReachSentLimit(SmsTracker tracker) {
-        if (denyIfQueueLimitReached(tracker)) {
-            return;     // queue limit reached; error was returned to caller
-        }
-
-        CharSequence appLabel = getAppLabel(tracker.mAppPackage);
-        Resources r = Resources.getSystem();
-        Spanned messageText = Html.fromHtml(r.getString(R.string.sms_control_message, appLabel));
-
-        ConfirmDialogListener listener = new ConfirmDialogListener(tracker);
-
-        AlertDialog d = new AlertDialog.Builder(mContext)
-                .setTitle(R.string.sms_control_title)
-                .setIcon(R.drawable.stat_sys_warning)
-                .setMessage(messageText)
-                .setPositiveButton(r.getString(R.string.sms_control_yes), listener)
-                .setNegativeButton(r.getString(R.string.sms_control_no), listener)
-                .setOnCancelListener(listener)
-                .create();
-
-        d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
-        d.show();
-    }
-
-    /**
-     * Send the message along to the radio.
-     *
-     * @param tracker holds the SMS message to send
-     */
-    protected abstract void sendSms(SmsTracker tracker);
-
-    /**
-     * Send the multi-part SMS based on multipart Sms tracker
-     *
-     * @param tracker holds the multipart Sms tracker ready to be sent
-     */
-    private void sendMultipartSms(SmsTracker tracker) {
-        ArrayList<String> parts;
-        ArrayList<PendingIntent> sentIntents;
-        ArrayList<PendingIntent> deliveryIntents;
-
-        HashMap<String, Object> map = tracker.mData;
-
-        String destinationAddress = (String) map.get("destination");
-        String scAddress = (String) map.get("scaddress");
-
-        parts = (ArrayList<String>) map.get("parts");
-        sentIntents = (ArrayList<PendingIntent>) map.get("sentIntents");
-        deliveryIntents = (ArrayList<PendingIntent>) map.get("deliveryIntents");
-
-        // check if in service
-        int ss = mPhone.getServiceState().getState();
-        if (ss != ServiceState.STATE_IN_SERVICE) {
-            for (int i = 0, count = parts.size(); i < count; i++) {
-                PendingIntent sentIntent = null;
-                if (sentIntents != null && sentIntents.size() > i) {
-                    sentIntent = sentIntents.get(i);
-                }
-                handleNotInService(ss, sentIntent);
-            }
-            return;
-        }
-
-        sendMultipartText(destinationAddress, scAddress, parts, sentIntents, deliveryIntents);
-    }
-
-    /**
-     * Send an acknowledge message.
-     * @param success indicates that last message was successfully received.
-     * @param result result code indicating any error
-     * @param response callback message sent when operation completes.
-     */
-    protected abstract void acknowledgeLastIncomingSms(boolean success,
-            int result, Message response);
-
-    /**
-     * Notify interested apps if the framework has rejected an incoming SMS,
-     * and send an acknowledge message to the network.
-     * @param success indicates that last message was successfully received.
-     * @param result result code indicating any error
-     * @param response callback message sent when operation completes.
-     */
-    private void notifyAndAcknowledgeLastIncomingSms(boolean success,
-            int result, Message response) {
-        if (!success) {
-            // broadcast SMS_REJECTED_ACTION intent
-            Intent intent = new Intent(Intents.SMS_REJECTED_ACTION);
-            intent.putExtra("result", result);
-            mWakeLock.acquire(WAKE_LOCK_TIMEOUT);
-            mContext.sendBroadcast(intent, "android.permission.RECEIVE_SMS");
-        }
-        acknowledgeLastIncomingSms(success, result, response);
-    }
-
-    /**
-     * Keeps track of an SMS that has been sent to the RIL, until it has
-     * successfully been sent, or we're done trying.
-     *
-     */
-    protected static final class SmsTracker {
-        // fields need to be public for derived SmsDispatchers
-        public final HashMap<String, Object> mData;
-        public int mRetryCount;
-        public int mMessageRef;
-
-        public final PendingIntent mSentIntent;
-        public final PendingIntent mDeliveryIntent;
-
-        public final String mAppPackage;
-        public final String mDestAddress;
-
-        public SmsTracker(HashMap<String, Object> data, PendingIntent sentIntent,
-                PendingIntent deliveryIntent, String appPackage, String destAddr) {
-            mData = data;
-            mSentIntent = sentIntent;
-            mDeliveryIntent = deliveryIntent;
-            mRetryCount = 0;
-            mAppPackage = appPackage;
-            mDestAddress = destAddr;
-        }
-
-        /**
-         * Returns whether this tracker holds a multi-part SMS.
-         * @return true if the tracker holds a multi-part SMS; false otherwise
-         */
-        protected boolean isMultipart() {
-            HashMap map = mData;
-            return map.containsKey("parts");
-        }
-    }
-
-    /**
-     * Dialog listener for SMS confirmation dialog.
-     */
-    private final class ConfirmDialogListener
-            implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener {
-
-        private final SmsTracker mTracker;
-
-        ConfirmDialogListener(SmsTracker tracker) {
-            mTracker = tracker;
-        }
-
-        @Override
-        public void onClick(DialogInterface dialog, int which) {
-            if (which == DialogInterface.BUTTON_POSITIVE) {
-                Log.d(TAG, "CONFIRM sending SMS");
-                sendMessage(obtainMessage(EVENT_SEND_CONFIRMED_SMS, mTracker));
-            } else if (which == DialogInterface.BUTTON_NEGATIVE) {
-                Log.d(TAG, "DENY sending SMS");
-                sendMessage(obtainMessage(EVENT_STOP_SENDING, mTracker));
-            }
-        }
-
-        @Override
-        public void onCancel(DialogInterface dialog) {
-            Log.d(TAG, "dialog dismissed: don't send SMS");
-            sendMessage(obtainMessage(EVENT_STOP_SENDING, mTracker));
-        }
-    }
-
-    private final BroadcastReceiver mResultReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            // Assume the intent is one of the SMS receive intents that
-            // was sent as an ordered broadcast.  Check result and ACK.
-            int rc = getResultCode();
-            boolean success = (rc == Activity.RESULT_OK)
-                    || (rc == Intents.RESULT_SMS_HANDLED);
-
-            // For a multi-part message, this only ACKs the last part.
-            // Previous parts were ACK'd as they were received.
-            acknowledgeLastIncomingSms(success, rc, null);
-        }
-    };
-
-    protected void dispatchBroadcastMessage(SmsCbMessage message) {
-        if (message.isEmergencyMessage()) {
-            Intent intent = new Intent(Intents.SMS_EMERGENCY_CB_RECEIVED_ACTION);
-            intent.putExtra("message", message);
-            Log.d(TAG, "Dispatching emergency SMS CB");
-            dispatch(intent, RECEIVE_EMERGENCY_BROADCAST_PERMISSION);
-        } else {
-            Intent intent = new Intent(Intents.SMS_CB_RECEIVED_ACTION);
-            intent.putExtra("message", message);
-            Log.d(TAG, "Dispatching SMS CB");
-            dispatch(intent, RECEIVE_SMS_PERMISSION);
-        }
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
deleted file mode 100644
index e4cfb23..0000000
--- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
+++ /dev/null
@@ -1,538 +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.internal.telephony;
-
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.util.TimeUtils;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * {@hide}
- */
-public abstract class ServiceStateTracker extends Handler {
-
-    protected CommandsInterface cm;
-
-    public ServiceState ss;
-    protected ServiceState newSS;
-
-    public SignalStrength mSignalStrength;
-
-    // TODO - this should not be public
-    public RestrictedState mRestrictedState = new RestrictedState();
-
-    /* The otaspMode passed to PhoneStateListener#onOtaspChanged */
-    static public final int OTASP_UNINITIALIZED = 0;
-    static public final int OTASP_UNKNOWN = 1;
-    static public final int OTASP_NEEDED = 2;
-    static public final int OTASP_NOT_NEEDED = 3;
-
-    /**
-     * A unique identifier to track requests associated with a poll
-     * and ignore stale responses.  The value is a count-down of
-     * expected responses in this pollingContext.
-     */
-    protected int[] pollingContext;
-    protected boolean mDesiredPowerState;
-
-    /**
-     *  Values correspond to ServiceState.RIL_RADIO_TECHNOLOGY_ definitions.
-     */
-    protected int mRilRadioTechnology = 0;
-    protected int mNewRilRadioTechnology = 0;
-
-    /**
-     * By default, strength polling is enabled.  However, if we're
-     * getting unsolicited signal strength updates from the radio, set
-     * value to true and don't bother polling any more.
-     */
-    protected boolean dontPollSignalStrength = false;
-
-    protected RegistrantList mRoamingOnRegistrants = new RegistrantList();
-    protected RegistrantList mRoamingOffRegistrants = new RegistrantList();
-    protected RegistrantList mAttachedRegistrants = new RegistrantList();
-    protected RegistrantList mDetachedRegistrants = new RegistrantList();
-    protected RegistrantList mNetworkAttachedRegistrants = new RegistrantList();
-    protected RegistrantList mPsRestrictEnabledRegistrants = new RegistrantList();
-    protected RegistrantList mPsRestrictDisabledRegistrants = new RegistrantList();
-
-    /* Radio power off pending flag and tag counter */
-    private boolean mPendingRadioPowerOffAfterDataOff = false;
-    private int mPendingRadioPowerOffAfterDataOffTag = 0;
-
-    protected  static final boolean DBG = true;
-
-    /** Signal strength poll rate. */
-    protected static final int POLL_PERIOD_MILLIS = 20 * 1000;
-
-    /** Waiting period before recheck gprs and voice registration. */
-    public static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000;
-
-    /** GSM events */
-    protected static final int EVENT_RADIO_STATE_CHANGED               = 1;
-    protected static final int EVENT_NETWORK_STATE_CHANGED             = 2;
-    protected static final int EVENT_GET_SIGNAL_STRENGTH               = 3;
-    protected static final int EVENT_POLL_STATE_REGISTRATION           = 4;
-    protected static final int EVENT_POLL_STATE_GPRS                   = 5;
-    protected static final int EVENT_POLL_STATE_OPERATOR               = 6;
-    protected static final int EVENT_POLL_SIGNAL_STRENGTH              = 10;
-    protected static final int EVENT_NITZ_TIME                         = 11;
-    protected static final int EVENT_SIGNAL_STRENGTH_UPDATE            = 12;
-    protected static final int EVENT_RADIO_AVAILABLE                   = 13;
-    protected static final int EVENT_POLL_STATE_NETWORK_SELECTION_MODE = 14;
-    protected static final int EVENT_GET_LOC_DONE                      = 15;
-    protected static final int EVENT_SIM_RECORDS_LOADED                = 16;
-    protected static final int EVENT_SIM_READY                         = 17;
-    protected static final int EVENT_LOCATION_UPDATES_ENABLED          = 18;
-    protected static final int EVENT_GET_PREFERRED_NETWORK_TYPE        = 19;
-    protected static final int EVENT_SET_PREFERRED_NETWORK_TYPE        = 20;
-    protected static final int EVENT_RESET_PREFERRED_NETWORK_TYPE      = 21;
-    protected static final int EVENT_CHECK_REPORT_GPRS                 = 22;
-    protected static final int EVENT_RESTRICTED_STATE_CHANGED          = 23;
-
-    /** CDMA events */
-    protected static final int EVENT_POLL_STATE_REGISTRATION_CDMA      = 24;
-    protected static final int EVENT_POLL_STATE_OPERATOR_CDMA          = 25;
-    protected static final int EVENT_RUIM_READY                        = 26;
-    protected static final int EVENT_RUIM_RECORDS_LOADED               = 27;
-    protected static final int EVENT_POLL_SIGNAL_STRENGTH_CDMA         = 28;
-    protected static final int EVENT_GET_SIGNAL_STRENGTH_CDMA          = 29;
-    protected static final int EVENT_NETWORK_STATE_CHANGED_CDMA        = 30;
-    protected static final int EVENT_GET_LOC_DONE_CDMA                 = 31;
-    protected static final int EVENT_SIGNAL_STRENGTH_UPDATE_CDMA       = 32;
-    protected static final int EVENT_NV_LOADED                         = 33;
-    protected static final int EVENT_POLL_STATE_CDMA_SUBSCRIPTION      = 34;
-    protected static final int EVENT_NV_READY                          = 35;
-    protected static final int EVENT_ERI_FILE_LOADED                   = 36;
-    protected static final int EVENT_OTA_PROVISION_STATUS_CHANGE       = 37;
-    protected static final int EVENT_SET_RADIO_POWER_OFF               = 38;
-    protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED  = 39;
-    protected static final int EVENT_CDMA_PRL_VERSION_CHANGED          = 40;
-    protected static final int EVENT_RADIO_ON                          = 41;
-
-
-    protected static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
-
-    /**
-     * List of ISO codes for countries that can have an offset of
-     * GMT+0 when not in daylight savings time.  This ignores some
-     * small places such as the Canary Islands (Spain) and
-     * Danmarkshavn (Denmark).  The list must be sorted by code.
-    */
-    protected static final String[] GMT_COUNTRY_CODES = {
-        "bf", // Burkina Faso
-        "ci", // Cote d'Ivoire
-        "eh", // Western Sahara
-        "fo", // Faroe Islands, Denmark
-        "gb", // United Kingdom of Great Britain and Northern Ireland
-        "gh", // Ghana
-        "gm", // Gambia
-        "gn", // Guinea
-        "gw", // Guinea Bissau
-        "ie", // Ireland
-        "lr", // Liberia
-        "is", // Iceland
-        "ma", // Morocco
-        "ml", // Mali
-        "mr", // Mauritania
-        "pt", // Portugal
-        "sl", // Sierra Leone
-        "sn", // Senegal
-        "st", // Sao Tome and Principe
-        "tg", // Togo
-    };
-
-    /** Reason for registration denial. */
-    protected static final String REGISTRATION_DENIED_GEN  = "General";
-    protected static final String REGISTRATION_DENIED_AUTH = "Authentication Failure";
-
-    public ServiceStateTracker() {
-    }
-
-    public boolean getDesiredPowerState() {
-        return mDesiredPowerState;
-    }
-
-    /**
-     * Registration point for combined roaming on
-     * combined roaming is true when roaming is true and ONS differs SPN
-     *
-     * @param h handler to notify
-     * @param what what code of message when delivered
-     * @param obj placed in Message.obj
-     */
-    public  void registerForRoamingOn(Handler h, int what, Object obj) {
-        Registrant r = new Registrant(h, what, obj);
-        mRoamingOnRegistrants.add(r);
-
-        if (ss.getRoaming()) {
-            r.notifyRegistrant();
-        }
-    }
-
-    public  void unregisterForRoamingOn(Handler h) {
-        mRoamingOnRegistrants.remove(h);
-    }
-
-    /**
-     * Registration point for combined roaming off
-     * combined roaming is true when roaming is true and ONS differs SPN
-     *
-     * @param h handler to notify
-     * @param what what code of message when delivered
-     * @param obj placed in Message.obj
-     */
-    public  void registerForRoamingOff(Handler h, int what, Object obj) {
-        Registrant r = new Registrant(h, what, obj);
-        mRoamingOffRegistrants.add(r);
-
-        if (!ss.getRoaming()) {
-            r.notifyRegistrant();
-        }
-    }
-
-    public  void unregisterForRoamingOff(Handler h) {
-        mRoamingOffRegistrants.remove(h);
-    }
-
-    /**
-     * Re-register network by toggling preferred network type.
-     * This is a work-around to deregister and register network since there is
-     * no ril api to set COPS=2 (deregister) only.
-     *
-     * @param onComplete is dispatched when this is complete.  it will be
-     * an AsyncResult, and onComplete.obj.exception will be non-null
-     * on failure.
-     */
-    public void reRegisterNetwork(Message onComplete) {
-        cm.getPreferredNetworkType(
-                obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE, onComplete));
-    }
-
-    public void
-    setRadioPower(boolean power) {
-        mDesiredPowerState = power;
-
-        setPowerStateToDesired();
-    }
-
-    /**
-     * These two flags manage the behavior of the cell lock -- the
-     * lock should be held if either flag is true.  The intention is
-     * to allow temporary acquisition of the lock to get a single
-     * update.  Such a lock grab and release can thus be made to not
-     * interfere with more permanent lock holds -- in other words, the
-     * lock will only be released if both flags are false, and so
-     * releases by temporary users will only affect the lock state if
-     * there is no continuous user.
-     */
-    private boolean mWantContinuousLocationUpdates;
-    private boolean mWantSingleLocationUpdate;
-
-    public void enableSingleLocationUpdate() {
-        if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return;
-        mWantSingleLocationUpdate = true;
-        cm.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED));
-    }
-
-    public void enableLocationUpdates() {
-        if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return;
-        mWantContinuousLocationUpdates = true;
-        cm.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED));
-    }
-
-    protected void disableSingleLocationUpdate() {
-        mWantSingleLocationUpdate = false;
-        if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) {
-            cm.setLocationUpdates(false, null);
-        }
-    }
-
-    public void disableLocationUpdates() {
-        mWantContinuousLocationUpdates = false;
-        if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) {
-            cm.setLocationUpdates(false, null);
-        }
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-        switch (msg.what) {
-            case EVENT_SET_RADIO_POWER_OFF:
-                synchronized(this) {
-                    if (mPendingRadioPowerOffAfterDataOff &&
-                            (msg.arg1 == mPendingRadioPowerOffAfterDataOffTag)) {
-                        if (DBG) log("EVENT_SET_RADIO_OFF, turn radio off now.");
-                        hangupAndPowerOff();
-                        mPendingRadioPowerOffAfterDataOffTag += 1;
-                        mPendingRadioPowerOffAfterDataOff = false;
-                    } else {
-                        log("EVENT_SET_RADIO_OFF is stale arg1=" + msg.arg1 +
-                                "!= tag=" + mPendingRadioPowerOffAfterDataOffTag);
-                    }
-                }
-                break;
-
-            default:
-                log("Unhandled message with number: " + msg.what);
-                break;
-        }
-    }
-
-    protected abstract Phone getPhone();
-    protected abstract void handlePollStateResult(int what, AsyncResult ar);
-    protected abstract void updateSpnDisplay();
-    protected abstract void setPowerStateToDesired();
-    protected abstract void log(String s);
-    protected abstract void loge(String s);
-
-    public abstract int getCurrentDataConnectionState();
-    public abstract boolean isConcurrentVoiceAndDataAllowed();
-
-    /**
-     * Registration point for transition into DataConnection attached.
-     * @param h handler to notify
-     * @param what what code of message when delivered
-     * @param obj placed in Message.obj
-     */
-    public void registerForDataConnectionAttached(Handler h, int what, Object obj) {
-        Registrant r = new Registrant(h, what, obj);
-        mAttachedRegistrants.add(r);
-
-        if (getCurrentDataConnectionState() == ServiceState.STATE_IN_SERVICE) {
-            r.notifyRegistrant();
-        }
-    }
-    public void unregisterForDataConnectionAttached(Handler h) {
-        mAttachedRegistrants.remove(h);
-    }
-
-    /**
-     * Registration point for transition into DataConnection detached.
-     * @param h handler to notify
-     * @param what what code of message when delivered
-     * @param obj placed in Message.obj
-     */
-    public void registerForDataConnectionDetached(Handler h, int what, Object obj) {
-        Registrant r = new Registrant(h, what, obj);
-        mDetachedRegistrants.add(r);
-
-        if (getCurrentDataConnectionState() != ServiceState.STATE_IN_SERVICE) {
-            r.notifyRegistrant();
-        }
-    }
-    public void unregisterForDataConnectionDetached(Handler h) {
-        mDetachedRegistrants.remove(h);
-    }
-
-    /**
-     * Registration point for transition into network attached.
-     * @param h handler to notify
-     * @param what what code of message when delivered
-     * @param obj in Message.obj
-     */
-    public void registerForNetworkAttached(Handler h, int what, Object obj) {
-        Registrant r = new Registrant(h, what, obj);
-
-        mNetworkAttachedRegistrants.add(r);
-        if (ss.getState() == ServiceState.STATE_IN_SERVICE) {
-            r.notifyRegistrant();
-        }
-    }
-    public void unregisterForNetworkAttached(Handler h) {
-        mNetworkAttachedRegistrants.remove(h);
-    }
-
-    /**
-     * Registration point for transition into packet service restricted zone.
-     * @param h handler to notify
-     * @param what what code of message when delivered
-     * @param obj placed in Message.obj
-     */
-    public void registerForPsRestrictedEnabled(Handler h, int what, Object obj) {
-        Registrant r = new Registrant(h, what, obj);
-        mPsRestrictEnabledRegistrants.add(r);
-
-        if (mRestrictedState.isPsRestricted()) {
-            r.notifyRegistrant();
-        }
-    }
-
-    public void unregisterForPsRestrictedEnabled(Handler h) {
-        mPsRestrictEnabledRegistrants.remove(h);
-    }
-
-    /**
-     * Registration point for transition out of packet service restricted zone.
-     * @param h handler to notify
-     * @param what what code of message when delivered
-     * @param obj placed in Message.obj
-     */
-    public void registerForPsRestrictedDisabled(Handler h, int what, Object obj) {
-        Registrant r = new Registrant(h, what, obj);
-        mPsRestrictDisabledRegistrants.add(r);
-
-        if (mRestrictedState.isPsRestricted()) {
-            r.notifyRegistrant();
-        }
-    }
-
-    public void unregisterForPsRestrictedDisabled(Handler h) {
-        mPsRestrictDisabledRegistrants.remove(h);
-    }
-
-    /**
-     * Clean up existing voice and data connection then turn off radio power.
-     *
-     * Hang up the existing voice calls to decrease call drop rate.
-     */
-    public void powerOffRadioSafely(DataConnectionTracker dcTracker) {
-        synchronized (this) {
-            if (!mPendingRadioPowerOffAfterDataOff) {
-                // To minimize race conditions we call cleanUpAllConnections on
-                // both if else paths instead of before this isDisconnected test.
-                if (dcTracker.isDisconnected()) {
-                    // To minimize race conditions we do this after isDisconnected
-                    dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF);
-                    if (DBG) log("Data disconnected, turn off radio right away.");
-                    hangupAndPowerOff();
-                } else {
-                    dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF);
-                    Message msg = Message.obtain(this);
-                    msg.what = EVENT_SET_RADIO_POWER_OFF;
-                    msg.arg1 = ++mPendingRadioPowerOffAfterDataOffTag;
-                    if (sendMessageDelayed(msg, 30000)) {
-                        if (DBG) log("Wait upto 30s for data to disconnect, then turn off radio.");
-                        mPendingRadioPowerOffAfterDataOff = true;
-                    } else {
-                        log("Cannot send delayed Msg, turn off radio right away.");
-                        hangupAndPowerOff();
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * process the pending request to turn radio off after data is disconnected
-     *
-     * return true if there is pending request to process; false otherwise.
-     */
-    public boolean processPendingRadioPowerOffAfterDataOff() {
-        synchronized(this) {
-            if (mPendingRadioPowerOffAfterDataOff) {
-                if (DBG) log("Process pending request to turn radio off.");
-                mPendingRadioPowerOffAfterDataOffTag += 1;
-                hangupAndPowerOff();
-                mPendingRadioPowerOffAfterDataOff = false;
-                return true;
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Hang up all voice call and turn off radio. Implemented by derived class.
-     */
-    protected abstract void hangupAndPowerOff();
-
-    /** Cancel a pending (if any) pollState() operation */
-    protected void cancelPollState() {
-        // This will effectively cancel the rest of the poll requests.
-        pollingContext = new int[1];
-    }
-
-    /**
-     * Return true if time zone needs fixing.
-     *
-     * @param phoneBase
-     * @param operatorNumeric
-     * @param prevOperatorNumeric
-     * @param needToFixTimeZone
-     * @return true if time zone needs to be fixed
-     */
-    protected boolean shouldFixTimeZoneNow(PhoneBase phoneBase, String operatorNumeric,
-            String prevOperatorNumeric, boolean needToFixTimeZone) {
-        // Return false if the mcc isn't valid as we don't know where we are.
-        // Return true if we have an IccCard and the mcc changed or we
-        // need to fix it because when the NITZ time came in we didn't
-        // know the country code.
-
-        // If mcc is invalid then we'll return false
-        int mcc;
-        try {
-            mcc = Integer.parseInt(operatorNumeric.substring(0, 3));
-        } catch (Exception e) {
-            if (DBG) {
-                log("shouldFixTimeZoneNow: no mcc, operatorNumeric=" + operatorNumeric +
-                        " retVal=false");
-            }
-            return false;
-        }
-
-        // If prevMcc is invalid will make it different from mcc
-        // so we'll return true if the card exists.
-        int prevMcc;
-        try {
-            prevMcc = Integer.parseInt(prevOperatorNumeric.substring(0, 3));
-        } catch (Exception e) {
-            prevMcc = mcc + 1;
-        }
-
-        // Determine if the Icc card exists
-        IccCard iccCard = phoneBase.getIccCard();
-        boolean iccCardExist = (iccCard != null) && iccCard.getState().iccCardExist();
-
-        // Determine retVal
-        boolean retVal = ((iccCardExist && (mcc != prevMcc)) || needToFixTimeZone);
-        if (DBG) {
-            long ctm = System.currentTimeMillis();
-            log("shouldFixTimeZoneNow: retVal=" + retVal +
-                    " iccCard=" + iccCard +
-                    " iccCard.state=" + (iccCard == null ? "null" : iccCard.getState().toString()) +
-                    " iccCardExist=" + iccCardExist +
-                    " operatorNumeric=" + operatorNumeric + " mcc=" + mcc +
-                    " prevOperatorNumeric=" + prevOperatorNumeric + " prevMcc=" + prevMcc +
-                    " needToFixTimeZone=" + needToFixTimeZone +
-                    " ltod=" + TimeUtils.logTimeOfDay(ctm));
-        }
-        return retVal;
-    }
-
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("ServiceStateTracker:");
-        pw.println(" ss=" + ss);
-        pw.println(" newSS=" + newSS);
-        pw.println(" mSignalStrength=" + mSignalStrength);
-        pw.println(" mRestrictedState=" + mRestrictedState);
-        pw.println(" pollingContext=" + pollingContext);
-        pw.println(" mDesiredPowerState=" + mDesiredPowerState);
-        pw.println(" mRilRadioTechnology=" + mRilRadioTechnology);
-        pw.println(" mNewRilRadioTechnology=" + mNewRilRadioTechnology);
-        pw.println(" dontPollSignalStrength=" + dontPollSignalStrength);
-        pw.println(" mPendingRadioPowerOffAfterDataOff=" + mPendingRadioPowerOffAfterDataOff);
-        pw.println(" mPendingRadioPowerOffAfterDataOffTag=" + mPendingRadioPowerOffAfterDataOffTag);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/SmsAddress.java b/telephony/java/com/android/internal/telephony/SmsAddress.java
deleted file mode 100644
index b3892cb..0000000
--- a/telephony/java/com/android/internal/telephony/SmsAddress.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.internal.telephony;
-
-public abstract class SmsAddress {
-    // From TS 23.040 9.1.2.5 and TS 24.008 table 10.5.118
-    // and C.S0005-D table 2.7.1.3.2.4-2
-    public static final int TON_UNKNOWN = 0;
-    public static final int TON_INTERNATIONAL = 1;
-    public static final int TON_NATIONAL = 2;
-    public static final int TON_NETWORK = 3;
-    public static final int TON_SUBSCRIBER = 4;
-    public static final int TON_ALPHANUMERIC = 5;
-    public static final int TON_ABBREVIATED = 6;
-
-    public int ton;
-    public String address;
-    public byte[] origBytes;
-
-    /**
-     * Returns the address of the SMS message in String form or null if unavailable
-     */
-    public String getAddressString() {
-        return address;
-    }
-
-    /**
-     * Returns true if this is an alphanumeric address
-     */
-    public boolean isAlphanumeric() {
-        return ton == TON_ALPHANUMERIC;
-    }
-
-    /**
-     * Returns true if this is a network address
-     */
-    public boolean isNetworkSpecific() {
-        return ton == TON_NETWORK;
-    }
-
-    public boolean couldBeEmailGateway() {
-        // Some carriers seems to send email gateway messages in this form:
-        // from: an UNKNOWN TON, 3 or 4 digits long, beginning with a 5
-        // PID: 0x00, Data coding scheme 0x03
-        // So we just attempt to treat any message from an address length <= 4
-        // as an email gateway
-
-        return address.length() <= 4;
-    }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/SmsConstants.java b/telephony/java/com/android/internal/telephony/SmsConstants.java
new file mode 100644
index 0000000..1ccdc3b
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/SmsConstants.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.internal.telephony;
+
+/**
+ * SMS Constants and must be the same as the corresponding
+ * deprecated version in SmsMessage.
+ *
+ * @hide
+ */
+public class SmsConstants {
+    /** User data text encoding code unit size */
+    public static final int ENCODING_UNKNOWN = 0;
+    public static final int ENCODING_7BIT = 1;
+    public static final int ENCODING_8BIT = 2;
+    public static final int ENCODING_16BIT = 3;
+
+    /** The maximum number of payload septets per message */
+    public static final int MAX_USER_DATA_SEPTETS = 160;
+
+    /**
+     * The maximum number of payload septets per message if a user data header
+     * is present.  This assumes the header only contains the
+     * CONCATENATED_8_BIT_REFERENCE element.
+     */
+    public static final int MAX_USER_DATA_SEPTETS_WITH_HEADER = 153;
+
+    /**
+     * This value is not defined in global standard. Only in Korea, this is used.
+     */
+    public static final int ENCODING_KSC5601 = 4;
+
+    /** The maximum number of payload bytes per message */
+    public static final int MAX_USER_DATA_BYTES = 140;
+
+    /**
+     * The maximum number of payload bytes per message if a user data header
+     * is present.  This assumes the header only contains the
+     * CONCATENATED_8_BIT_REFERENCE element.
+     */
+    public static final int MAX_USER_DATA_BYTES_WITH_HEADER = 134;
+
+    /**
+     * SMS Class enumeration.
+     * See TS 23.038.
+     */
+    public enum MessageClass{
+        UNKNOWN, CLASS_0, CLASS_1, CLASS_2, CLASS_3;
+    }
+
+    /**
+     * Indicates a 3GPP format SMS message.
+     * @hide pending API council approval
+     */
+    public static final String FORMAT_3GPP = "3gpp";
+
+    /**
+     * Indicates a 3GPP2 format SMS message.
+     * @hide pending API council approval
+     */
+    public static final String FORMAT_3GPP2 = "3gpp2";
+}
diff --git a/telephony/java/com/android/internal/telephony/SmsHeader.java b/telephony/java/com/android/internal/telephony/SmsHeader.java
deleted file mode 100644
index c32388f..0000000
--- a/telephony/java/com/android/internal/telephony/SmsHeader.java
+++ /dev/null
@@ -1,289 +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.internal.telephony;
-
-import android.telephony.SmsMessage;
-
-import com.android.internal.util.HexDump;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-
-import java.util.ArrayList;
-
-/**
- * SMS user data header, as specified in TS 23.040 9.2.3.24.
- */
-public class SmsHeader {
-
-    // TODO(cleanup): this data structure is generally referred to as
-    // the 'user data header' or UDH, and so the class name should
-    // change to reflect this...
-
-    /** SMS user data header information element identifiers.
-     * (see TS 23.040 9.2.3.24)
-     */
-    public static final int ELT_ID_CONCATENATED_8_BIT_REFERENCE       = 0x00;
-    public static final int ELT_ID_SPECIAL_SMS_MESSAGE_INDICATION     = 0x01;
-    public static final int ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT  = 0x04;
-    public static final int ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT = 0x05;
-    public static final int ELT_ID_SMSC_CONTROL_PARAMS                = 0x06;
-    public static final int ELT_ID_UDH_SOURCE_INDICATION              = 0x07;
-    public static final int ELT_ID_CONCATENATED_16_BIT_REFERENCE      = 0x08;
-    public static final int ELT_ID_WIRELESS_CTRL_MSG_PROTOCOL         = 0x09;
-    public static final int ELT_ID_TEXT_FORMATTING                    = 0x0A;
-    public static final int ELT_ID_PREDEFINED_SOUND                   = 0x0B;
-    public static final int ELT_ID_USER_DEFINED_SOUND                 = 0x0C;
-    public static final int ELT_ID_PREDEFINED_ANIMATION               = 0x0D;
-    public static final int ELT_ID_LARGE_ANIMATION                    = 0x0E;
-    public static final int ELT_ID_SMALL_ANIMATION                    = 0x0F;
-    public static final int ELT_ID_LARGE_PICTURE                      = 0x10;
-    public static final int ELT_ID_SMALL_PICTURE                      = 0x11;
-    public static final int ELT_ID_VARIABLE_PICTURE                   = 0x12;
-    public static final int ELT_ID_USER_PROMPT_INDICATOR              = 0x13;
-    public static final int ELT_ID_EXTENDED_OBJECT                    = 0x14;
-    public static final int ELT_ID_REUSED_EXTENDED_OBJECT             = 0x15;
-    public static final int ELT_ID_COMPRESSION_CONTROL                = 0x16;
-    public static final int ELT_ID_OBJECT_DISTR_INDICATOR             = 0x17;
-    public static final int ELT_ID_STANDARD_WVG_OBJECT                = 0x18;
-    public static final int ELT_ID_CHARACTER_SIZE_WVG_OBJECT          = 0x19;
-    public static final int ELT_ID_EXTENDED_OBJECT_DATA_REQUEST_CMD   = 0x1A;
-    public static final int ELT_ID_RFC_822_EMAIL_HEADER               = 0x20;
-    public static final int ELT_ID_HYPERLINK_FORMAT_ELEMENT           = 0x21;
-    public static final int ELT_ID_REPLY_ADDRESS_ELEMENT              = 0x22;
-    public static final int ELT_ID_ENHANCED_VOICE_MAIL_INFORMATION    = 0x23;
-    public static final int ELT_ID_NATIONAL_LANGUAGE_SINGLE_SHIFT     = 0x24;
-    public static final int ELT_ID_NATIONAL_LANGUAGE_LOCKING_SHIFT    = 0x25;
-
-    public static final int PORT_WAP_PUSH = 2948;
-    public static final int PORT_WAP_WSP  = 9200;
-
-    public static class PortAddrs {
-        public int destPort;
-        public int origPort;
-        public boolean areEightBits;
-    }
-
-    public static class ConcatRef {
-        public int refNumber;
-        public int seqNumber;
-        public int msgCount;
-        public boolean isEightBits;
-    }
-
-    /**
-     * A header element that is not explicitly parsed, meaning not
-     * PortAddrs or ConcatRef.
-     */
-    public static class MiscElt {
-        public int id;
-        public byte[] data;
-    }
-
-    public PortAddrs portAddrs;
-    public ConcatRef concatRef;
-    public ArrayList<MiscElt> miscEltList = new ArrayList<MiscElt>();
-
-    /** 7 bit national language locking shift table, or 0 for GSM default 7 bit alphabet. */
-    public int languageTable;
-
-    /** 7 bit national language single shift table, or 0 for GSM default 7 bit extension table. */
-    public int languageShiftTable;
-
-    public SmsHeader() {}
-
-    /**
-     * Create structured SmsHeader object from serialized byte array representation.
-     * (see TS 23.040 9.2.3.24)
-     * @param data is user data header bytes
-     * @return SmsHeader object
-     */
-    public static SmsHeader fromByteArray(byte[] data) {
-        ByteArrayInputStream inStream = new ByteArrayInputStream(data);
-        SmsHeader smsHeader = new SmsHeader();
-        while (inStream.available() > 0) {
-            /**
-             * NOTE: as defined in the spec, ConcatRef and PortAddr
-             * fields should not reoccur, but if they do the last
-             * occurrence is to be used.  Also, for ConcatRef
-             * elements, if the count is zero, sequence is zero, or
-             * sequence is larger than count, the entire element is to
-             * be ignored.
-             */
-            int id = inStream.read();
-            int length = inStream.read();
-            ConcatRef concatRef;
-            PortAddrs portAddrs;
-            switch (id) {
-            case ELT_ID_CONCATENATED_8_BIT_REFERENCE:
-                concatRef = new ConcatRef();
-                concatRef.refNumber = inStream.read();
-                concatRef.msgCount = inStream.read();
-                concatRef.seqNumber = inStream.read();
-                concatRef.isEightBits = true;
-                if (concatRef.msgCount != 0 && concatRef.seqNumber != 0 &&
-                        concatRef.seqNumber <= concatRef.msgCount) {
-                    smsHeader.concatRef = concatRef;
-                }
-                break;
-            case ELT_ID_CONCATENATED_16_BIT_REFERENCE:
-                concatRef = new ConcatRef();
-                concatRef.refNumber = (inStream.read() << 8) | inStream.read();
-                concatRef.msgCount = inStream.read();
-                concatRef.seqNumber = inStream.read();
-                concatRef.isEightBits = false;
-                if (concatRef.msgCount != 0 && concatRef.seqNumber != 0 &&
-                        concatRef.seqNumber <= concatRef.msgCount) {
-                    smsHeader.concatRef = concatRef;
-                }
-                break;
-            case ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT:
-                portAddrs = new PortAddrs();
-                portAddrs.destPort = inStream.read();
-                portAddrs.origPort = inStream.read();
-                portAddrs.areEightBits = true;
-                smsHeader.portAddrs = portAddrs;
-                break;
-            case ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT:
-                portAddrs = new PortAddrs();
-                portAddrs.destPort = (inStream.read() << 8) | inStream.read();
-                portAddrs.origPort = (inStream.read() << 8) | inStream.read();
-                portAddrs.areEightBits = false;
-                smsHeader.portAddrs = portAddrs;
-                break;
-            case ELT_ID_NATIONAL_LANGUAGE_SINGLE_SHIFT:
-                smsHeader.languageShiftTable = inStream.read();
-                break;
-            case ELT_ID_NATIONAL_LANGUAGE_LOCKING_SHIFT:
-                smsHeader.languageTable = inStream.read();
-                break;
-            default:
-                MiscElt miscElt = new MiscElt();
-                miscElt.id = id;
-                miscElt.data = new byte[length];
-                inStream.read(miscElt.data, 0, length);
-                smsHeader.miscEltList.add(miscElt);
-            }
-        }
-        return smsHeader;
-    }
-
-    /**
-     * Create serialized byte array representation from structured SmsHeader object.
-     * (see TS 23.040 9.2.3.24)
-     * @return Byte array representing the SmsHeader
-     */
-    public static byte[] toByteArray(SmsHeader smsHeader) {
-        if ((smsHeader.portAddrs == null) &&
-            (smsHeader.concatRef == null) &&
-            (smsHeader.miscEltList.isEmpty()) &&
-            (smsHeader.languageShiftTable == 0) &&
-            (smsHeader.languageTable == 0)) {
-            return null;
-        }
-
-        ByteArrayOutputStream outStream = new ByteArrayOutputStream(SmsMessage.MAX_USER_DATA_BYTES);
-        ConcatRef concatRef = smsHeader.concatRef;
-        if (concatRef != null) {
-            if (concatRef.isEightBits) {
-                outStream.write(ELT_ID_CONCATENATED_8_BIT_REFERENCE);
-                outStream.write(3);
-                outStream.write(concatRef.refNumber);
-            } else {
-                outStream.write(ELT_ID_CONCATENATED_16_BIT_REFERENCE);
-                outStream.write(4);
-                outStream.write(concatRef.refNumber >>> 8);
-                outStream.write(concatRef.refNumber & 0x00FF);
-            }
-            outStream.write(concatRef.msgCount);
-            outStream.write(concatRef.seqNumber);
-        }
-        PortAddrs portAddrs = smsHeader.portAddrs;
-        if (portAddrs != null) {
-            if (portAddrs.areEightBits) {
-                outStream.write(ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT);
-                outStream.write(2);
-                outStream.write(portAddrs.destPort);
-                outStream.write(portAddrs.origPort);
-            } else {
-                outStream.write(ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT);
-                outStream.write(4);
-                outStream.write(portAddrs.destPort >>> 8);
-                outStream.write(portAddrs.destPort & 0x00FF);
-                outStream.write(portAddrs.origPort >>> 8);
-                outStream.write(portAddrs.origPort & 0x00FF);
-            }
-        }
-        if (smsHeader.languageShiftTable != 0) {
-            outStream.write(ELT_ID_NATIONAL_LANGUAGE_SINGLE_SHIFT);
-            outStream.write(1);
-            outStream.write(smsHeader.languageShiftTable);
-        }
-        if (smsHeader.languageTable != 0) {
-            outStream.write(ELT_ID_NATIONAL_LANGUAGE_LOCKING_SHIFT);
-            outStream.write(1);
-            outStream.write(smsHeader.languageTable);
-        }
-        for (MiscElt miscElt : smsHeader.miscEltList) {
-            outStream.write(miscElt.id);
-            outStream.write(miscElt.data.length);
-            outStream.write(miscElt.data, 0, miscElt.data.length);
-        }
-        return outStream.toByteArray();
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder builder = new StringBuilder();
-        builder.append("UserDataHeader ");
-        builder.append("{ ConcatRef ");
-        if (concatRef == null) {
-            builder.append("unset");
-        } else {
-            builder.append("{ refNumber=" + concatRef.refNumber);
-            builder.append(", msgCount=" + concatRef.msgCount);
-            builder.append(", seqNumber=" + concatRef.seqNumber);
-            builder.append(", isEightBits=" + concatRef.isEightBits);
-            builder.append(" }");
-        }
-        builder.append(", PortAddrs ");
-        if (portAddrs == null) {
-            builder.append("unset");
-        } else {
-            builder.append("{ destPort=" + portAddrs.destPort);
-            builder.append(", origPort=" + portAddrs.origPort);
-            builder.append(", areEightBits=" + portAddrs.areEightBits);
-            builder.append(" }");
-        }
-        if (languageShiftTable != 0) {
-            builder.append(", languageShiftTable=" + languageShiftTable);
-        }
-        if (languageTable != 0) {
-            builder.append(", languageTable=" + languageTable);
-        }
-        for (MiscElt miscElt : miscEltList) {
-            builder.append(", MiscElt ");
-            builder.append("{ id=" + miscElt.id);
-            builder.append(", length=" + miscElt.data.length);
-            builder.append(", data=" + HexDump.toHexString(miscElt.data));
-            builder.append(" }");
-        }
-        builder.append(" }");
-        return builder.toString();
-    }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
deleted file mode 100644
index fcd038c..0000000
--- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * 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.internal.telephony;
-
-import com.android.internal.telephony.SmsHeader;
-import java.util.Arrays;
-
-import static android.telephony.SmsMessage.MessageClass;
-import android.provider.Telephony;
-
-/**
- * Base class declaring the specific methods and members for SmsMessage.
- * {@hide}
- */
-public abstract class SmsMessageBase {
-    private static final String LOG_TAG = "SMS";
-
-    /** {@hide} The address of the SMSC. May be null */
-    protected String scAddress;
-
-    /** {@hide} The address of the sender */
-    protected SmsAddress originatingAddress;
-
-    /** {@hide} The message body as a string. May be null if the message isn't text */
-    protected String messageBody;
-
-    /** {@hide} */
-    protected String pseudoSubject;
-
-    /** {@hide} Non-null if this is an email gateway message */
-    protected String emailFrom;
-
-    /** {@hide} Non-null if this is an email gateway message */
-    protected String emailBody;
-
-    /** {@hide} */
-    protected boolean isEmail;
-
-    /** {@hide} */
-    protected long scTimeMillis;
-
-    /** {@hide} The raw PDU of the message */
-    protected byte[] mPdu;
-
-    /** {@hide} The raw bytes for the user data section of the message */
-    protected byte[] userData;
-
-    /** {@hide} */
-    protected SmsHeader userDataHeader;
-
-    // "Message Waiting Indication Group"
-    // 23.038 Section 4
-    /** {@hide} */
-    protected boolean isMwi;
-
-    /** {@hide} */
-    protected boolean mwiSense;
-
-    /** {@hide} */
-    protected boolean mwiDontStore;
-
-    /**
-     * Indicates status for messages stored on the ICC.
-     */
-    protected int statusOnIcc = -1;
-
-    /**
-     * Record index of message in the EF.
-     */
-    protected int indexOnIcc = -1;
-
-    /** TP-Message-Reference - Message Reference of sent message. @hide */
-    public int messageRef;
-
-    /**
-     * For a specific text string, this object describes protocol
-     * properties of encoding it for transmission as message user
-     * data.
-     */
-    public static class TextEncodingDetails {
-        /**
-         *The number of SMS's required to encode the text.
-         */
-        public int msgCount;
-
-        /**
-         * The number of code units consumed so far, where code units
-         * are basically characters in the encoding -- for example,
-         * septets for the standard ASCII and GSM encodings, and 16
-         * bits for Unicode.
-         */
-        public int codeUnitCount;
-
-        /**
-         * How many code units are still available without spilling
-         * into an additional message.
-         */
-        public int codeUnitsRemaining;
-
-        /**
-         * The encoding code unit size (specified using
-         * android.telephony.SmsMessage ENCODING_*).
-         */
-        public int codeUnitSize;
-
-        /**
-         * The GSM national language table to use, or 0 for the default 7-bit alphabet.
-         */
-        public int languageTable;
-
-        /**
-         * The GSM national language shift table to use, or 0 for the default 7-bit extension table.
-         */
-        public int languageShiftTable;
-
-        @Override
-        public String toString() {
-            return "TextEncodingDetails " +
-                    "{ msgCount=" + msgCount +
-                    ", codeUnitCount=" + codeUnitCount +
-                    ", codeUnitsRemaining=" + codeUnitsRemaining +
-                    ", codeUnitSize=" + codeUnitSize +
-                    ", languageTable=" + languageTable +
-                    ", languageShiftTable=" + languageShiftTable +
-                    " }";
-        }
-    }
-
-    // TODO(): This class is duplicated in SmsMessage.java. Refactor accordingly.
-    public static abstract class SubmitPduBase  {
-        public byte[] encodedScAddress; // Null if not applicable.
-        public byte[] encodedMessage;
-
-        public String toString() {
-            return "SubmitPdu: encodedScAddress = "
-                    + Arrays.toString(encodedScAddress)
-                    + ", encodedMessage = "
-                    + Arrays.toString(encodedMessage);
-        }
-    }
-
-    /**
-     * Returns the address of the SMS service center that relayed this message
-     * or null if there is none.
-     */
-    public String getServiceCenterAddress() {
-        return scAddress;
-    }
-
-    /**
-     * Returns the originating address (sender) of this SMS message in String
-     * form or null if unavailable
-     */
-    public String getOriginatingAddress() {
-        if (originatingAddress == null) {
-            return null;
-        }
-
-        return originatingAddress.getAddressString();
-    }
-
-    /**
-     * Returns the originating address, or email from address if this message
-     * was from an email gateway. Returns null if originating address
-     * unavailable.
-     */
-    public String getDisplayOriginatingAddress() {
-        if (isEmail) {
-            return emailFrom;
-        } else {
-            return getOriginatingAddress();
-        }
-    }
-
-    /**
-     * Returns the message body as a String, if it exists and is text based.
-     * @return message body is there is one, otherwise null
-     */
-    public String getMessageBody() {
-        return messageBody;
-    }
-
-    /**
-     * Returns the class of this message.
-     */
-    public abstract MessageClass getMessageClass();
-
-    /**
-     * Returns the message body, or email message body if this message was from
-     * an email gateway. Returns null if message body unavailable.
-     */
-    public String getDisplayMessageBody() {
-        if (isEmail) {
-            return emailBody;
-        } else {
-            return getMessageBody();
-        }
-    }
-
-    /**
-     * Unofficial convention of a subject line enclosed in parens empty string
-     * if not present
-     */
-    public String getPseudoSubject() {
-        return pseudoSubject == null ? "" : pseudoSubject;
-    }
-
-    /**
-     * Returns the service centre timestamp in currentTimeMillis() format
-     */
-    public long getTimestampMillis() {
-        return scTimeMillis;
-    }
-
-    /**
-     * Returns true if message is an email.
-     *
-     * @return true if this message came through an email gateway and email
-     *         sender / subject / parsed body are available
-     */
-    public boolean isEmail() {
-        return isEmail;
-    }
-
-    /**
-     * @return if isEmail() is true, body of the email sent through the gateway.
-     *         null otherwise
-     */
-    public String getEmailBody() {
-        return emailBody;
-    }
-
-    /**
-     * @return if isEmail() is true, email from address of email sent through
-     *         the gateway. null otherwise
-     */
-    public String getEmailFrom() {
-        return emailFrom;
-    }
-
-    /**
-     * Get protocol identifier.
-     */
-    public abstract int getProtocolIdentifier();
-
-    /**
-     * See TS 23.040 9.2.3.9 returns true if this is a "replace short message"
-     * SMS
-     */
-    public abstract boolean isReplace();
-
-    /**
-     * Returns true for CPHS MWI toggle message.
-     *
-     * @return true if this is a CPHS MWI toggle message See CPHS 4.2 section
-     *         B.4.2
-     */
-    public abstract boolean isCphsMwiMessage();
-
-    /**
-     * returns true if this message is a CPHS voicemail / message waiting
-     * indicator (MWI) clear message
-     */
-    public abstract boolean isMWIClearMessage();
-
-    /**
-     * returns true if this message is a CPHS voicemail / message waiting
-     * indicator (MWI) set message
-     */
-    public abstract boolean isMWISetMessage();
-
-    /**
-     * returns true if this message is a "Message Waiting Indication Group:
-     * Discard Message" notification and should not be stored.
-     */
-    public abstract boolean isMwiDontStore();
-
-    /**
-     * returns the user data section minus the user data header if one was
-     * present.
-     */
-    public byte[] getUserData() {
-        return userData;
-    }
-
-    /**
-     * Returns an object representing the user data header
-     *
-     * {@hide}
-     */
-    public SmsHeader getUserDataHeader() {
-        return userDataHeader;
-    }
-
-    /**
-     * TODO(cleanup): The term PDU is used in a seemingly non-unique
-     * manner -- for example, what is the difference between this byte
-     * array and the contents of SubmitPdu objects.  Maybe a more
-     * illustrative term would be appropriate.
-     */
-
-    /**
-     * Returns the raw PDU for the message.
-     */
-    public byte[] getPdu() {
-        return mPdu;
-    }
-
-    /**
-     * For an SMS-STATUS-REPORT message, this returns the status field from
-     * the status report.  This field indicates the status of a previously
-     * submitted SMS, if requested.  See TS 23.040, 9.2.3.15 TP-Status for a
-     * description of values.
-     *
-     * @return 0 indicates the previously sent message was received.
-     *         See TS 23.040, 9.9.2.3.15 for a description of other possible
-     *         values.
-     */
-    public abstract int getStatus();
-
-    /**
-     * Return true iff the message is a SMS-STATUS-REPORT message.
-     */
-    public abstract boolean isStatusReportMessage();
-
-    /**
-     * Returns true iff the <code>TP-Reply-Path</code> bit is set in
-     * this message.
-     */
-    public abstract boolean isReplyPathPresent();
-
-    /**
-     * Returns the status of the message on the ICC (read, unread, sent, unsent).
-     *
-     * @return the status of the message on the ICC.  These are:
-     *         SmsManager.STATUS_ON_ICC_FREE
-     *         SmsManager.STATUS_ON_ICC_READ
-     *         SmsManager.STATUS_ON_ICC_UNREAD
-     *         SmsManager.STATUS_ON_ICC_SEND
-     *         SmsManager.STATUS_ON_ICC_UNSENT
-     */
-    public int getStatusOnIcc() {
-        return statusOnIcc;
-    }
-
-    /**
-     * Returns the record index of the message on the ICC (1-based index).
-     * @return the record index of the message on the ICC, or -1 if this
-     *         SmsMessage was not created from a ICC SMS EF record.
-     */
-    public int getIndexOnIcc() {
-        return indexOnIcc;
-    }
-
-    protected void parseMessageBody() {
-        // originatingAddress could be null if this message is from a status
-        // report.
-        if (originatingAddress != null && originatingAddress.couldBeEmailGateway()) {
-            extractEmailAddressFromMessageBody();
-        }
-    }
-
-    /**
-     * Try to parse this message as an email gateway message
-     * There are two ways specified in TS 23.040 Section 3.8 :
-     *  - SMS message "may have its TP-PID set for Internet electronic mail - MT
-     * SMS format: [<from-address><space>]<message> - "Depending on the
-     * nature of the gateway, the destination/origination address is either
-     * derived from the content of the SMS TP-OA or TP-DA field, or the
-     * TP-OA/TP-DA field contains a generic gateway address and the to/from
-     * address is added at the beginning as shown above." (which is supported here)
-     * - Multiple addresses separated by commas, no spaces, Subject field delimited
-     * by '()' or '##' and '#' Section 9.2.3.24.11 (which are NOT supported here)
-     */
-    protected void extractEmailAddressFromMessageBody() {
-
-        /* Some carriers may use " /" delimiter as below
-         *
-         * 1. [x@y][ ]/[subject][ ]/[body]
-         * -or-
-         * 2. [x@y][ ]/[body]
-         */
-         String[] parts = messageBody.split("( /)|( )", 2);
-         if (parts.length < 2) return;
-         emailFrom = parts[0];
-         emailBody = parts[1];
-         isEmail = Telephony.Mms.isEmailAddress(emailFrom);
-    }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/SmsRawData.java b/telephony/java/com/android/internal/telephony/SmsRawData.java
deleted file mode 100644
index 891d942..0000000
--- a/telephony/java/com/android/internal/telephony/SmsRawData.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
-** Copyright 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.internal.telephony;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- *  A parcelable holder class of byte[] for ISms aidl implementation
- */
-public class SmsRawData implements Parcelable {
-    byte[] data;
-
-    //Static Methods
-    public static final Parcelable.Creator<SmsRawData> CREATOR
-            = new Parcelable.Creator<SmsRawData> (){
-        public SmsRawData createFromParcel(Parcel source) {
-            int size;
-            size = source.readInt();
-            byte[] data = new byte[size];
-            source.readByteArray(data);
-            return new SmsRawData(data);
-        }
-
-        public SmsRawData[] newArray(int size) {
-            return new SmsRawData[size];
-        }
-    };
-
-    // Constructor
-    public SmsRawData(byte[] data) {
-        this.data = data;
-    }
-
-    public byte[] getBytes() {
-        return data;
-    }
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(data.length);
-        dest.writeByteArray(data);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/SmsResponse.java b/telephony/java/com/android/internal/telephony/SmsResponse.java
deleted file mode 100644
index a7c2840..0000000
--- a/telephony/java/com/android/internal/telephony/SmsResponse.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.internal.telephony;
-
-/**
- * Object returned by the RIL upon successful completion of sendSMS.
- * Contains message reference and ackPdu.
- *
- */
-public class SmsResponse {
-    /** Message reference of the just-sent SMS. */
-    int messageRef;
-    /** ackPdu for the just-sent SMS. */
-    String ackPdu;
-    /**
-     * errorCode: See 3GPP 27.005, 3.2.5 for GSM/UMTS,
-     * 3GPP2 N.S0005 (IS-41C) Table 171 for CDMA, -1 if unknown or not applicable.
-     */
-    int errorCode;
-
-    public SmsResponse(int messageRef, String ackPdu, int errorCode) {
-        this.messageRef = messageRef;
-        this.ackPdu = ackPdu;
-        this.errorCode = errorCode;
-    }
-
-    public String toString() {
-        String ret = "{ messageRef = " + messageRef
-                        + ", errorCode = " + errorCode
-                        + ", ackPdu = " + ackPdu
-                        + "}";
-        return ret;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/SmsStorageMonitor.java b/telephony/java/com/android/internal/telephony/SmsStorageMonitor.java
deleted file mode 100644
index 0c06ffc..0000000
--- a/telephony/java/com/android/internal/telephony/SmsStorageMonitor.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2011 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.internal.telephony;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.PowerManager;
-import android.provider.Telephony.Sms.Intents;
-import android.util.Log;
-
-/**
- * Monitors the device and ICC storage, and sends the appropriate events.
- *
- * This code was formerly part of {@link SMSDispatcher}, and has been moved
- * into a separate class to support instantiation of multiple SMSDispatchers on
- * dual-mode devices that require support for both 3GPP and 3GPP2 format messages.
- */
-public final class SmsStorageMonitor extends Handler {
-    private static final String TAG = "SmsStorageMonitor";
-
-    /** SIM/RUIM storage is full */
-    private static final int EVENT_ICC_FULL = 1;
-
-    /** Memory status reporting is acknowledged by RIL */
-    private static final int EVENT_REPORT_MEMORY_STATUS_DONE = 2;
-
-    /** Radio is ON */
-    private static final int EVENT_RADIO_ON = 3;
-
-    /** Context from phone object passed to constructor. */
-    private final Context mContext;
-
-    /** Wake lock to ensure device stays awake while dispatching the SMS intent. */
-    private PowerManager.WakeLock mWakeLock;
-
-    private boolean mReportMemoryStatusPending;
-
-    final CommandsInterface mCm;                            // accessed from inner class
-    boolean mStorageAvailable = true;                       // accessed from inner class
-
-    /**
-     * Hold the wake lock for 5 seconds, which should be enough time for
-     * any receiver(s) to grab its own wake lock.
-     */
-    private static final int WAKE_LOCK_TIMEOUT = 5000;
-
-    /**
-     * Creates an SmsStorageMonitor and registers for events.
-     * @param phone the Phone to use
-     */
-    public SmsStorageMonitor(PhoneBase phone) {
-        mContext = phone.getContext();
-        mCm = phone.mCM;
-
-        createWakelock();
-
-        mCm.setOnIccSmsFull(this, EVENT_ICC_FULL, null);
-        mCm.registerForOn(this, EVENT_RADIO_ON, null);
-
-        // Register for device storage intents.  Use these to notify the RIL
-        // that storage for SMS is or is not available.
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_DEVICE_STORAGE_FULL);
-        filter.addAction(Intent.ACTION_DEVICE_STORAGE_NOT_FULL);
-        mContext.registerReceiver(mResultReceiver, filter);
-    }
-
-    public void dispose() {
-        mCm.unSetOnIccSmsFull(this);
-        mCm.unregisterForOn(this);
-        mContext.unregisterReceiver(mResultReceiver);
-    }
-
-    /**
-     * Handles events coming from the phone stack. Overridden from handler.
-     * @param msg the message to handle
-     */
-    @Override
-    public void handleMessage(Message msg) {
-        AsyncResult ar;
-
-        switch (msg.what) {
-            case EVENT_ICC_FULL:
-                handleIccFull();
-                break;
-
-            case EVENT_REPORT_MEMORY_STATUS_DONE:
-                ar = (AsyncResult) msg.obj;
-                if (ar.exception != null) {
-                    mReportMemoryStatusPending = true;
-                    Log.v(TAG, "Memory status report to modem pending : mStorageAvailable = "
-                            + mStorageAvailable);
-                } else {
-                    mReportMemoryStatusPending = false;
-                }
-                break;
-
-            case EVENT_RADIO_ON:
-                if (mReportMemoryStatusPending) {
-                    Log.v(TAG, "Sending pending memory status report : mStorageAvailable = "
-                            + mStorageAvailable);
-                    mCm.reportSmsMemoryStatus(mStorageAvailable,
-                            obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE));
-                }
-                break;
-        }
-    }
-
-    private void createWakelock() {
-        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
-        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SmsStorageMonitor");
-        mWakeLock.setReferenceCounted(true);
-    }
-
-    /**
-     * Called when SIM_FULL message is received from the RIL.  Notifies interested
-     * parties that SIM storage for SMS messages is full.
-     */
-    private void handleIccFull() {
-        // broadcast SIM_FULL intent
-        Intent intent = new Intent(Intents.SIM_FULL_ACTION);
-        mWakeLock.acquire(WAKE_LOCK_TIMEOUT);
-        mContext.sendBroadcast(intent, SMSDispatcher.RECEIVE_SMS_PERMISSION);
-    }
-
-    /** Returns whether or not there is storage available for an incoming SMS. */
-    public boolean isStorageAvailable() {
-        return mStorageAvailable;
-    }
-
-    private final BroadcastReceiver mResultReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_FULL)) {
-                mStorageAvailable = false;
-                mCm.reportSmsMemoryStatus(false, obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE));
-            } else if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_NOT_FULL)) {
-                mStorageAvailable = true;
-                mCm.reportSmsMemoryStatus(true, obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE));
-            }
-        }
-    };
-}
diff --git a/telephony/java/com/android/internal/telephony/SmsUsageMonitor.java b/telephony/java/com/android/internal/telephony/SmsUsageMonitor.java
deleted file mode 100644
index 4a4485d..0000000
--- a/telephony/java/com/android/internal/telephony/SmsUsageMonitor.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2011 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.internal.telephony;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.res.XmlResourceParser;
-import android.database.ContentObserver;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.Settings;
-import android.telephony.PhoneNumberUtils;
-import android.util.Log;
-
-import com.android.internal.util.XmlUtils;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlPullParserFactory;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.regex.Pattern;
-
-/**
- * Implement the per-application based SMS control, which limits the number of
- * SMS/MMS messages an app can send in the checking period.
- *
- * This code was formerly part of {@link SMSDispatcher}, and has been moved
- * into a separate class to support instantiation of multiple SMSDispatchers on
- * dual-mode devices that require support for both 3GPP and 3GPP2 format messages.
- */
-public class SmsUsageMonitor {
-    private static final String TAG = "SmsUsageMonitor";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    /** Default checking period for SMS sent without user permission. */
-    private static final int DEFAULT_SMS_CHECK_PERIOD = 1800000;    // 30 minutes
-
-    /** Default number of SMS sent in checking period without user permission. */
-    private static final int DEFAULT_SMS_MAX_COUNT = 30;
-
-    private final int mCheckPeriod;
-    private final int mMaxAllowed;
-
-    private final HashMap<String, ArrayList<Long>> mSmsStamp =
-            new HashMap<String, ArrayList<Long>>();
-
-    /**
-     * Create SMS usage monitor.
-     * @param context the context to use to load resources and get TelephonyManager service
-     */
-    public SmsUsageMonitor(Context context) {
-        ContentResolver resolver = context.getContentResolver();
-
-        mMaxAllowed = Settings.Secure.getInt(resolver,
-                Settings.Secure.SMS_OUTGOING_CHECK_MAX_COUNT,
-                DEFAULT_SMS_MAX_COUNT);
-
-        mCheckPeriod = Settings.Secure.getInt(resolver,
-                Settings.Secure.SMS_OUTGOING_CHECK_INTERVAL_MS,
-                DEFAULT_SMS_CHECK_PERIOD);
-    }
-
-    /** Clear the SMS application list for disposal. */
-    void dispose() {
-        mSmsStamp.clear();
-    }
-
-    /**
-     * Check to see if an application is allowed to send new SMS messages, and confirm with
-     * user if the send limit was reached or if a non-system app is potentially sending to a
-     * premium SMS short code or number.
-     *
-     * @param appName the package name of the app requesting to send an SMS
-     * @param smsWaiting the number of new messages desired to send
-     * @return true if application is allowed to send the requested number
-     *  of new sms messages
-     */
-    public boolean check(String appName, int smsWaiting) {
-        synchronized (mSmsStamp) {
-            removeExpiredTimestamps();
-
-            ArrayList<Long> sentList = mSmsStamp.get(appName);
-            if (sentList == null) {
-                sentList = new ArrayList<Long>();
-                mSmsStamp.put(appName, sentList);
-            }
-
-            return isUnderLimit(sentList, smsWaiting);
-        }
-    }
-
-    /**
-     * Remove keys containing only old timestamps. This can happen if an SMS app is used
-     * to send messages and then uninstalled.
-     */
-    private void removeExpiredTimestamps() {
-        long beginCheckPeriod = System.currentTimeMillis() - mCheckPeriod;
-
-        synchronized (mSmsStamp) {
-            Iterator<Map.Entry<String, ArrayList<Long>>> iter = mSmsStamp.entrySet().iterator();
-            while (iter.hasNext()) {
-                Map.Entry<String, ArrayList<Long>> entry = iter.next();
-                ArrayList<Long> oldList = entry.getValue();
-                if (oldList.isEmpty() || oldList.get(oldList.size() - 1) < beginCheckPeriod) {
-                    iter.remove();
-                }
-            }
-        }
-    }
-
-    private boolean isUnderLimit(ArrayList<Long> sent, int smsWaiting) {
-        Long ct = System.currentTimeMillis();
-        long beginCheckPeriod = ct - mCheckPeriod;
-
-        if (VDBG) log("SMS send size=" + sent.size() + " time=" + ct);
-
-        while (!sent.isEmpty() && sent.get(0) < beginCheckPeriod) {
-            sent.remove(0);
-        }
-
-        if ((sent.size() + smsWaiting) <= mMaxAllowed) {
-            for (int i = 0; i < smsWaiting; i++ ) {
-                sent.add(ct);
-            }
-            return true;
-        }
-        return false;
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/TelephonyCapabilities.java b/telephony/java/com/android/internal/telephony/TelephonyCapabilities.java
deleted file mode 100644
index bd94de2..0000000
--- a/telephony/java/com/android/internal/telephony/TelephonyCapabilities.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2010 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.internal.telephony;
-
-import android.util.Log;
-
-import com.android.internal.telephony.Phone;
-
-/**
- * Utilities that check if the phone supports specified capabilities.
- */
-public class TelephonyCapabilities {
-    private static final String LOG_TAG = "TelephonyCapabilities";
-
-    /** This class is never instantiated. */
-    private TelephonyCapabilities() {
-    }
-
-    /**
-     * Return true if the current phone supports ECM ("Emergency Callback
-     * Mode"), which is a feature where the device goes into a special
-     * state for a short period of time after making an outgoing emergency
-     * call.
-     *
-     * (On current devices, that state lasts 5 minutes.  It prevents data
-     * usage by other apps, to avoid conflicts with any possible incoming
-     * calls.  It also puts up a notification in the status bar, showing a
-     * countdown while ECM is active, and allowing the user to exit ECM.)
-     *
-     * Currently this is assumed to be true for CDMA phones, and false
-     * otherwise.
-     */
-    public static boolean supportsEcm(Phone phone) {
-        return (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA);
-    }
-
-    /**
-     * Return true if the current phone supports Over The Air Service
-     * Provisioning (OTASP)
-     *
-     * Currently this is assumed to be true for CDMA phones, and false
-     * otherwise.
-     *
-     * TODO: Watch out: this is also highly carrier-specific, since the
-     * OTASP procedure is different from one carrier to the next, *and* the
-     * different carriers may want very different onscreen UI as well.
-     * The procedure may even be different for different devices with the
-     * same carrier.
-     *
-     * So we eventually will need a much more flexible, pluggable design.
-     * This method here is just a placeholder to reduce hardcoded
-     * "if (CDMA)" checks sprinkled throughout the phone app.
-     */
-    public static boolean supportsOtasp(Phone phone) {
-        return (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA);
-    }
-
-    /**
-     * Return true if the current phone can retrieve the voice message count.
-     *
-     * Currently this is assumed to be true on CDMA phones and false otherwise.
-     */
-    public static boolean supportsVoiceMessageCount(Phone phone) {
-        return (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA);
-    }
-
-    /**
-     * Return true if this phone allows the user to select which
-     * network to use.
-     *
-     * Currently this is assumed to be true only on GSM phones.
-     *
-     * TODO: Should CDMA phones allow this as well?
-     */
-    public static boolean supportsNetworkSelection(Phone phone) {
-        return (phone.getPhoneType() == Phone.PHONE_TYPE_GSM);
-    }
-
-    /**
-     * Returns a resource ID for a label to use when displaying the
-     * "device id" of the current device.  (This is currently used as the
-     * title of the "device id" dialog.)
-     *
-     * This is specific to the device's telephony technology: the device
-     * id is called "IMEI" on GSM phones and "MEID" on CDMA phones.
-     */
-    public static int getDeviceIdLabel(Phone phone) {
-        if (phone.getPhoneType() == Phone.PHONE_TYPE_GSM) {
-            return com.android.internal.R.string.imei;
-        } else if (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) {
-            return com.android.internal.R.string.meid;
-        } else {
-            Log.w(LOG_TAG, "getDeviceIdLabel: no known label for phone "
-                  + phone.getPhoneName());
-            return 0;
-        }
-    }
-
-    /**
-     * Return true if the current phone supports the ability to explicitly
-     * manage the state of a conference call (i.e. view the participants,
-     * and hangup or separate individual callers.)
-     *
-     * The in-call screen's "Manage conference" UI is available only on
-     * devices that support this feature.
-     *
-     * Currently this is assumed to be true on GSM phones and false otherwise.
-     */
-    public static boolean supportsConferenceCallManagement(Phone phone) {
-        return ((phone.getPhoneType() == Phone.PHONE_TYPE_GSM)
-                || (phone.getPhoneType() == Phone.PHONE_TYPE_SIP));
-    }
-
-    /**
-     * Return true if the current phone supports explicit "Hold" and
-     * "Unhold" actions for an active call.  (If so, the in-call UI will
-     * provide onscreen "Hold" / "Unhold" buttons.)
-     *
-     * Currently this is assumed to be true on GSM phones and false
-     * otherwise.  (In particular, CDMA has no concept of "putting a call
-     * on hold.")
-     */
-    public static boolean supportsHoldAndUnhold(Phone phone) {
-        return ((phone.getPhoneType() == Phone.PHONE_TYPE_GSM)
-                || (phone.getPhoneType() == Phone.PHONE_TYPE_SIP));
-    }
-
-    /**
-     * Return true if the current phone supports distinct "Answer & Hold"
-     * and "Answer & End" behaviors in the call-waiting scenario.  If so,
-     * the in-call UI may provide separate buttons or menu items for these
-     * two actions.
-     *
-     * Currently this is assumed to be true on GSM phones and false
-     * otherwise.  (In particular, CDMA has no concept of explicitly
-     * managing the background call, or "putting a call on hold.")
-     *
-     * TODO: It might be better to expose this capability in a more
-     * generic form, like maybe "supportsExplicitMultipleLineManagement()"
-     * rather than focusing specifically on call-waiting behavior.
-     */
-    public static boolean supportsAnswerAndHold(Phone phone) {
-        return ((phone.getPhoneType() == Phone.PHONE_TYPE_GSM)
-                || (phone.getPhoneType() == Phone.PHONE_TYPE_SIP));
-    }
-
-    /**
-     * Return true if phones with the given phone type support ADN
-     * (Abbreviated Dialing Numbers).
-     *
-     * Currently this returns true when the phone type is GSM
-     * ({@link Phone#PHONE_TYPE_GSM}).
-     *
-     * This is using int for an argument for letting apps outside
-     * Phone process access to it, while other methods in this class is
-     * using Phone object.
-     *
-     * TODO: Theoretically phones other than GSM may have the ADN capability.
-     * Consider having better check here, or have better capability as part
-     * of public API, with which the argument should be replaced with
-     * something more appropriate.
-     */
-    public static boolean supportsAdn(int phoneType) {
-        return phoneType == Phone.PHONE_TYPE_GSM;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index 3355e8a..3cfd0bf 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -230,10 +230,49 @@
      * <p class="note">.
      * This is to pop up a notice to show user that the phone is in emergency callback mode
      * and atacalls and outgoing sms are blocked.
-     * 
+     *
      * <p class="note">This is a protected intent that can only be sent
      * by the system.
      */
     public static final String ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS
             = "android.intent.action.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS";
+
+
+    /**
+     * 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";
 }
diff --git a/telephony/java/com/android/internal/telephony/UUSInfo.java b/telephony/java/com/android/internal/telephony/UUSInfo.java
deleted file mode 100644
index 801b845..0000000
--- a/telephony/java/com/android/internal/telephony/UUSInfo.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2010 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.internal.telephony;
-
-public class UUSInfo {
-
-    /*
-     * User-to-User signaling Info activation types derived from 3GPP 23.087
-     * v8.0
-     */
-
-    public static final int UUS_TYPE1_IMPLICIT = 0;
-
-    public static final int UUS_TYPE1_REQUIRED = 1;
-
-    public static final int UUS_TYPE1_NOT_REQUIRED = 2;
-
-    public static final int UUS_TYPE2_REQUIRED = 3;
-
-    public static final int UUS_TYPE2_NOT_REQUIRED = 4;
-
-    public static final int UUS_TYPE3_REQUIRED = 5;
-
-    public static final int UUS_TYPE3_NOT_REQUIRED = 6;
-
-    /*
-     * User-to-User Signaling Information data coding schemes. Possible values
-     * for Octet 3 (Protocol Discriminator field) in the UUIE. The values have
-     * been specified in section 10.5.4.25 of 3GPP TS 24.008
-     */
-
-    public static final int UUS_DCS_USP = 0; /* User specified protocol */
-
-    public static final int UUS_DCS_OSIHLP = 1; /* OSI higher layer protocol */
-
-    public static final int UUS_DCS_X244 = 2; /* X.244 */
-
-    public static final int UUS_DCS_RMCF = 3; /*
-                                               * Reserved for system management
-                                               * convergence function
-                                               */
-
-    public static final int UUS_DCS_IA5c = 4; /* IA5 characters */
-
-    private int uusType;
-
-    private int uusDcs;
-
-    private byte[] uusData;
-
-    public UUSInfo() {
-        this.uusType = UUS_TYPE1_IMPLICIT;
-        this.uusDcs = UUS_DCS_IA5c;
-        this.uusData = null;
-    }
-
-    public UUSInfo(int uusType, int uusDcs, byte[] uusData) {
-        this.uusType = uusType;
-        this.uusDcs = uusDcs;
-        this.uusData = uusData;
-    }
-
-    public int getDcs() {
-        return uusDcs;
-    }
-
-    public void setDcs(int uusDcs) {
-        this.uusDcs = uusDcs;
-    }
-
-    public int getType() {
-        return uusType;
-    }
-
-    public void setType(int uusType) {
-        this.uusType = uusType;
-    }
-
-    public byte[] getUserData() {
-        return uusData;
-    }
-
-    public void setUserData(byte[] uusData) {
-        this.uusData = uusData;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/WapPushManagerParams.java b/telephony/java/com/android/internal/telephony/WapPushManagerParams.java
deleted file mode 100644
index 11e5ff9..0000000
--- a/telephony/java/com/android/internal/telephony/WapPushManagerParams.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2010 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.internal.telephony;
-
-/**
- * WapPushManager constant value definitions
- */
-public class WapPushManagerParams {
-    /**
-     * Application type activity
-     */
-    public static final int APP_TYPE_ACTIVITY = 0;
-
-    /**
-     * Application type service
-     */
-    public static final int APP_TYPE_SERVICE = 1;
-
-    /**
-     * Process Message return value
-     * Message is handled
-     */
-    public static final int MESSAGE_HANDLED = 0x1;
-
-    /**
-     * Process Message return value
-     * Application ID or content type was not found in the application ID table
-     */
-    public static final int APP_QUERY_FAILED = 0x2;
-
-    /**
-     * Process Message return value
-     * Receiver application signature check failed
-     */
-    public static final int SIGNATURE_NO_MATCH = 0x4;
-
-    /**
-     * Process Message return value
-     * Receiver application was not found
-     */
-    public static final int INVALID_RECEIVER_NAME = 0x8;
-
-    /**
-     * Process Message return value
-     * Unknown exception
-     */
-    public static final int EXCEPTION_CAUGHT = 0x10;
-
-    /**
-     * Process Message return value
-     * Need further processing after WapPushManager message processing
-     */
-    public static final int FURTHER_PROCESSING = 0x8000;
-
-}
-
diff --git a/telephony/java/com/android/internal/telephony/WapPushOverSms.java b/telephony/java/com/android/internal/telephony/WapPushOverSms.java
deleted file mode 100755
index e2779dc..0000000
--- a/telephony/java/com/android/internal/telephony/WapPushOverSms.java
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * 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.internal.telephony;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.provider.Telephony;
-import android.provider.Telephony.Sms.Intents;
-import android.util.Log;
-import android.os.IBinder;
-import android.os.RemoteException;
-
-/**
- * WAP push handler class.
- *
- * @hide
- */
-public class WapPushOverSms {
-    private static final String LOG_TAG = "WAP PUSH";
-
-    private final Context mContext;
-    private WspTypeDecoder pduDecoder;
-    private SMSDispatcher mSmsDispatcher;
-
-    /**
-     * Hold the wake lock for 5 seconds, which should be enough time for
-     * any receiver(s) to grab its own wake lock.
-     */
-    private final int WAKE_LOCK_TIMEOUT = 5000;
-
-    private final int BIND_RETRY_INTERVAL = 1000;
-    /**
-     * A handle to WapPushManager interface
-     */
-    private WapPushConnection mWapConn = null;
-    private class WapPushConnection implements ServiceConnection {
-        private IWapPushManager mWapPushMan;
-        private Context mOwner;
-
-        public WapPushConnection(Context ownerContext) {
-            mOwner = ownerContext;
-        }
-
-        public void onServiceConnected(ComponentName name, IBinder service) {
-            mWapPushMan = IWapPushManager.Stub.asInterface(service);
-            if (false) Log.v(LOG_TAG, "wappush manager connected to " +
-                    mOwner.hashCode());
-        }
-
-        public void onServiceDisconnected(ComponentName name) {
-            mWapPushMan = null;
-            if (false) Log.v(LOG_TAG, "wappush manager disconnected.");
-            // WapPushManager must be always attached.
-            rebindWapPushManager();
-        }
-
-        /**
-         * bind WapPushManager
-         */
-        public void bindWapPushManager() {
-            if (mWapPushMan != null) return;
-
-            final ServiceConnection wapPushConnection = this;
-
-            mOwner.bindService(new Intent(IWapPushManager.class.getName()),
-                    wapPushConnection, Context.BIND_AUTO_CREATE);
-        }
-
-        /**
-         * rebind WapPushManager
-         * This method is called when WapPushManager is disconnected unexpectedly.
-         */
-        private void rebindWapPushManager() {
-            if (mWapPushMan != null) return;
-
-            final ServiceConnection wapPushConnection = this;
-            new Thread() {
-                public void run() {
-                    while (mWapPushMan == null) {
-                        mOwner.bindService(new Intent(IWapPushManager.class.getName()),
-                                wapPushConnection, Context.BIND_AUTO_CREATE);
-                        try {
-                            Thread.sleep(BIND_RETRY_INTERVAL);
-                        } catch (InterruptedException e) {
-                            if (false) Log.v(LOG_TAG, "sleep interrupted.");
-                        }
-                    }
-                }
-            }.start();
-        }
-
-        /**
-         * Returns interface to WapPushManager
-         */
-        public IWapPushManager getWapPushManager() {
-            return mWapPushMan;
-        }
-    }
-
-    public WapPushOverSms(Phone phone, SMSDispatcher smsDispatcher) {
-        mSmsDispatcher = smsDispatcher;
-        mContext = phone.getContext();
-        mWapConn = new WapPushConnection(mContext);
-        mWapConn.bindWapPushManager();
-    }
-
-
-    /**
-     * Dispatches inbound messages that are in the WAP PDU format. See
-     * wap-230-wsp-20010705-a section 8 for details on the WAP PDU format.
-     *
-     * @param pdu The WAP PDU, made up of one or more SMS PDUs
-     * @return a result code from {@link Telephony.Sms.Intents}, or
-     *         {@link Activity#RESULT_OK} if the message has been broadcast
-     *         to applications
-     */
-    public int dispatchWapPdu(byte[] pdu) {
-
-        if (false) Log.d(LOG_TAG, "Rx: " + IccUtils.bytesToHexString(pdu));
-
-        int index = 0;
-        int transactionId = pdu[index++] & 0xFF;
-        int pduType = pdu[index++] & 0xFF;
-        int headerLength = 0;
-
-        if ((pduType != WspTypeDecoder.PDU_TYPE_PUSH) &&
-                (pduType != WspTypeDecoder.PDU_TYPE_CONFIRMED_PUSH)) {
-            if (false) Log.w(LOG_TAG, "Received non-PUSH WAP PDU. Type = " + pduType);
-            return Intents.RESULT_SMS_HANDLED;
-        }
-
-        pduDecoder = new WspTypeDecoder(pdu);
-
-        /**
-         * Parse HeaderLen(unsigned integer).
-         * From wap-230-wsp-20010705-a section 8.1.2
-         * The maximum size of a uintvar is 32 bits.
-         * So it will be encoded in no more than 5 octets.
-         */
-        if (pduDecoder.decodeUintvarInteger(index) == false) {
-            if (false) Log.w(LOG_TAG, "Received PDU. Header Length error.");
-            return Intents.RESULT_SMS_GENERIC_ERROR;
-        }
-        headerLength = (int)pduDecoder.getValue32();
-        index += pduDecoder.getDecodedDataLength();
-
-        int headerStartIndex = index;
-
-        /**
-         * Parse Content-Type.
-         * From wap-230-wsp-20010705-a section 8.4.2.24
-         *
-         * Content-type-value = Constrained-media | Content-general-form
-         * Content-general-form = Value-length Media-type
-         * Media-type = (Well-known-media | Extension-Media) *(Parameter)
-         * Value-length = Short-length | (Length-quote Length)
-         * Short-length = <Any octet 0-30>   (octet <= WAP_PDU_SHORT_LENGTH_MAX)
-         * Length-quote = <Octet 31>         (WAP_PDU_LENGTH_QUOTE)
-         * Length = Uintvar-integer
-         */
-        if (pduDecoder.decodeContentType(index) == false) {
-            if (false) Log.w(LOG_TAG, "Received PDU. Header Content-Type error.");
-            return Intents.RESULT_SMS_GENERIC_ERROR;
-        }
-
-        String mimeType = pduDecoder.getValueString();
-        long binaryContentType = pduDecoder.getValue32();
-        index += pduDecoder.getDecodedDataLength();
-
-        byte[] header = new byte[headerLength];
-        System.arraycopy(pdu, headerStartIndex, header, 0, header.length);
-
-        byte[] intentData;
-
-        if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
-            intentData = pdu;
-        } else {
-            int dataIndex = headerStartIndex + headerLength;
-            intentData = new byte[pdu.length - dataIndex];
-            System.arraycopy(pdu, dataIndex, intentData, 0, intentData.length);
-        }
-
-        /**
-         * Seek for application ID field in WSP header.
-         * If application ID is found, WapPushManager substitute the message
-         * processing. Since WapPushManager is optional module, if WapPushManager
-         * is not found, legacy message processing will be continued.
-         */
-        if (pduDecoder.seekXWapApplicationId(index, index + headerLength - 1)) {
-            index = (int) pduDecoder.getValue32();
-            pduDecoder.decodeXWapApplicationId(index);
-            String wapAppId = pduDecoder.getValueString();
-            if (wapAppId == null) {
-                wapAppId = Integer.toString((int) pduDecoder.getValue32());
-            }
-
-            String contentType = ((mimeType == null) ?
-                                  Long.toString(binaryContentType) : mimeType);
-            if (false) Log.v(LOG_TAG, "appid found: " + wapAppId + ":" + contentType);
-
-            try {
-                boolean processFurther = true;
-                IWapPushManager wapPushMan = mWapConn.getWapPushManager();
-
-                if (wapPushMan == null) {
-                    if (false) Log.w(LOG_TAG, "wap push manager not found!");
-                } else {
-                    Intent intent = new Intent();
-                    intent.putExtra("transactionId", transactionId);
-                    intent.putExtra("pduType", pduType);
-                    intent.putExtra("header", header);
-                    intent.putExtra("data", intentData);
-                    intent.putExtra("contentTypeParameters",
-                            pduDecoder.getContentParameters());
-
-                    int procRet = wapPushMan.processMessage(wapAppId, contentType, intent);
-                    if (false) Log.v(LOG_TAG, "procRet:" + procRet);
-                    if ((procRet & WapPushManagerParams.MESSAGE_HANDLED) > 0
-                        && (procRet & WapPushManagerParams.FURTHER_PROCESSING) == 0) {
-                        processFurther = false;
-                    }
-                }
-                if (!processFurther) {
-                    return Intents.RESULT_SMS_HANDLED;
-                }
-            } catch (RemoteException e) {
-                if (false) Log.w(LOG_TAG, "remote func failed...");
-            }
-        }
-        if (false) Log.v(LOG_TAG, "fall back to existing handler");
-
-        if (mimeType == null) {
-            if (false) Log.w(LOG_TAG, "Header Content-Type error.");
-            return Intents.RESULT_SMS_GENERIC_ERROR;
-        }
-
-        String permission;
-
-        if (mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_MMS)) {
-            permission = "android.permission.RECEIVE_MMS";
-        } else {
-            permission = "android.permission.RECEIVE_WAP_PUSH";
-        }
-
-        Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION);
-        intent.setType(mimeType);
-        intent.putExtra("transactionId", transactionId);
-        intent.putExtra("pduType", pduType);
-        intent.putExtra("header", header);
-        intent.putExtra("data", intentData);
-        intent.putExtra("contentTypeParameters", pduDecoder.getContentParameters());
-
-        mSmsDispatcher.dispatch(intent, permission);
-
-        return Activity.RESULT_OK;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
deleted file mode 100755
index 73260fb..0000000
--- a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
+++ /dev/null
@@ -1,731 +0,0 @@
-/*
- * 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.internal.telephony;
-
-import java.util.HashMap;
-
-/**
- * Implement the WSP data type decoder.
- *
- * @hide
- */
-public class WspTypeDecoder {
-
-    private static final int WAP_PDU_SHORT_LENGTH_MAX = 30;
-    private static final int WAP_PDU_LENGTH_QUOTE = 31;
-
-    public static final int PDU_TYPE_PUSH = 0x06;
-    public static final int PDU_TYPE_CONFIRMED_PUSH = 0x07;
-
-    private final static HashMap<Integer, String> WELL_KNOWN_MIME_TYPES =
-            new HashMap<Integer, String>();
-
-    private final static HashMap<Integer, String> WELL_KNOWN_PARAMETERS =
-            new HashMap<Integer, String>();
-
-    public static final int PARAMETER_ID_X_WAP_APPLICATION_ID = 0x2f;
-    private static final int Q_VALUE = 0x00;
-
-    static {
-        WELL_KNOWN_MIME_TYPES.put(0x00, "*/*");
-        WELL_KNOWN_MIME_TYPES.put(0x01, "text/*");
-        WELL_KNOWN_MIME_TYPES.put(0x02, "text/html");
-        WELL_KNOWN_MIME_TYPES.put(0x03, "text/plain");
-        WELL_KNOWN_MIME_TYPES.put(0x04, "text/x-hdml");
-        WELL_KNOWN_MIME_TYPES.put(0x05, "text/x-ttml");
-        WELL_KNOWN_MIME_TYPES.put(0x06, "text/x-vCalendar");
-        WELL_KNOWN_MIME_TYPES.put(0x07, "text/x-vCard");
-        WELL_KNOWN_MIME_TYPES.put(0x08, "text/vnd.wap.wml");
-        WELL_KNOWN_MIME_TYPES.put(0x09, "text/vnd.wap.wmlscript");
-        WELL_KNOWN_MIME_TYPES.put(0x0A, "text/vnd.wap.wta-event");
-        WELL_KNOWN_MIME_TYPES.put(0x0B, "multipart/*");
-        WELL_KNOWN_MIME_TYPES.put(0x0C, "multipart/mixed");
-        WELL_KNOWN_MIME_TYPES.put(0x0D, "multipart/form-data");
-        WELL_KNOWN_MIME_TYPES.put(0x0E, "multipart/byterantes");
-        WELL_KNOWN_MIME_TYPES.put(0x0F, "multipart/alternative");
-        WELL_KNOWN_MIME_TYPES.put(0x10, "application/*");
-        WELL_KNOWN_MIME_TYPES.put(0x11, "application/java-vm");
-        WELL_KNOWN_MIME_TYPES.put(0x12, "application/x-www-form-urlencoded");
-        WELL_KNOWN_MIME_TYPES.put(0x13, "application/x-hdmlc");
-        WELL_KNOWN_MIME_TYPES.put(0x14, "application/vnd.wap.wmlc");
-        WELL_KNOWN_MIME_TYPES.put(0x15, "application/vnd.wap.wmlscriptc");
-        WELL_KNOWN_MIME_TYPES.put(0x16, "application/vnd.wap.wta-eventc");
-        WELL_KNOWN_MIME_TYPES.put(0x17, "application/vnd.wap.uaprof");
-        WELL_KNOWN_MIME_TYPES.put(0x18, "application/vnd.wap.wtls-ca-certificate");
-        WELL_KNOWN_MIME_TYPES.put(0x19, "application/vnd.wap.wtls-user-certificate");
-        WELL_KNOWN_MIME_TYPES.put(0x1A, "application/x-x509-ca-cert");
-        WELL_KNOWN_MIME_TYPES.put(0x1B, "application/x-x509-user-cert");
-        WELL_KNOWN_MIME_TYPES.put(0x1C, "image/*");
-        WELL_KNOWN_MIME_TYPES.put(0x1D, "image/gif");
-        WELL_KNOWN_MIME_TYPES.put(0x1E, "image/jpeg");
-        WELL_KNOWN_MIME_TYPES.put(0x1F, "image/tiff");
-        WELL_KNOWN_MIME_TYPES.put(0x20, "image/png");
-        WELL_KNOWN_MIME_TYPES.put(0x21, "image/vnd.wap.wbmp");
-        WELL_KNOWN_MIME_TYPES.put(0x22, "application/vnd.wap.multipart.*");
-        WELL_KNOWN_MIME_TYPES.put(0x23, "application/vnd.wap.multipart.mixed");
-        WELL_KNOWN_MIME_TYPES.put(0x24, "application/vnd.wap.multipart.form-data");
-        WELL_KNOWN_MIME_TYPES.put(0x25, "application/vnd.wap.multipart.byteranges");
-        WELL_KNOWN_MIME_TYPES.put(0x26, "application/vnd.wap.multipart.alternative");
-        WELL_KNOWN_MIME_TYPES.put(0x27, "application/xml");
-        WELL_KNOWN_MIME_TYPES.put(0x28, "text/xml");
-        WELL_KNOWN_MIME_TYPES.put(0x29, "application/vnd.wap.wbxml");
-        WELL_KNOWN_MIME_TYPES.put(0x2A, "application/x-x968-cross-cert");
-        WELL_KNOWN_MIME_TYPES.put(0x2B, "application/x-x968-ca-cert");
-        WELL_KNOWN_MIME_TYPES.put(0x2C, "application/x-x968-user-cert");
-        WELL_KNOWN_MIME_TYPES.put(0x2D, "text/vnd.wap.si");
-        WELL_KNOWN_MIME_TYPES.put(0x2E, "application/vnd.wap.sic");
-        WELL_KNOWN_MIME_TYPES.put(0x2F, "text/vnd.wap.sl");
-        WELL_KNOWN_MIME_TYPES.put(0x30, "application/vnd.wap.slc");
-        WELL_KNOWN_MIME_TYPES.put(0x31, "text/vnd.wap.co");
-        WELL_KNOWN_MIME_TYPES.put(0x32, "application/vnd.wap.coc");
-        WELL_KNOWN_MIME_TYPES.put(0x33, "application/vnd.wap.multipart.related");
-        WELL_KNOWN_MIME_TYPES.put(0x34, "application/vnd.wap.sia");
-        WELL_KNOWN_MIME_TYPES.put(0x35, "text/vnd.wap.connectivity-xml");
-        WELL_KNOWN_MIME_TYPES.put(0x36, "application/vnd.wap.connectivity-wbxml");
-        WELL_KNOWN_MIME_TYPES.put(0x37, "application/pkcs7-mime");
-        WELL_KNOWN_MIME_TYPES.put(0x38, "application/vnd.wap.hashed-certificate");
-        WELL_KNOWN_MIME_TYPES.put(0x39, "application/vnd.wap.signed-certificate");
-        WELL_KNOWN_MIME_TYPES.put(0x3A, "application/vnd.wap.cert-response");
-        WELL_KNOWN_MIME_TYPES.put(0x3B, "application/xhtml+xml");
-        WELL_KNOWN_MIME_TYPES.put(0x3C, "application/wml+xml");
-        WELL_KNOWN_MIME_TYPES.put(0x3D, "text/css");
-        WELL_KNOWN_MIME_TYPES.put(0x3E, "application/vnd.wap.mms-message");
-        WELL_KNOWN_MIME_TYPES.put(0x3F, "application/vnd.wap.rollover-certificate");
-        WELL_KNOWN_MIME_TYPES.put(0x40, "application/vnd.wap.locc+wbxml");
-        WELL_KNOWN_MIME_TYPES.put(0x41, "application/vnd.wap.loc+xml");
-        WELL_KNOWN_MIME_TYPES.put(0x42, "application/vnd.syncml.dm+wbxml");
-        WELL_KNOWN_MIME_TYPES.put(0x43, "application/vnd.syncml.dm+xml");
-        WELL_KNOWN_MIME_TYPES.put(0x44, "application/vnd.syncml.notification");
-        WELL_KNOWN_MIME_TYPES.put(0x45, "application/vnd.wap.xhtml+xml");
-        WELL_KNOWN_MIME_TYPES.put(0x46, "application/vnd.wv.csp.cir");
-        WELL_KNOWN_MIME_TYPES.put(0x47, "application/vnd.oma.dd+xml");
-        WELL_KNOWN_MIME_TYPES.put(0x48, "application/vnd.oma.drm.message");
-        WELL_KNOWN_MIME_TYPES.put(0x49, "application/vnd.oma.drm.content");
-        WELL_KNOWN_MIME_TYPES.put(0x4A, "application/vnd.oma.drm.rights+xml");
-        WELL_KNOWN_MIME_TYPES.put(0x4B, "application/vnd.oma.drm.rights+wbxml");
-        WELL_KNOWN_MIME_TYPES.put(0x4C, "application/vnd.wv.csp+xml");
-        WELL_KNOWN_MIME_TYPES.put(0x4D, "application/vnd.wv.csp+wbxml");
-        WELL_KNOWN_MIME_TYPES.put(0x4E, "application/vnd.syncml.ds.notification");
-        WELL_KNOWN_MIME_TYPES.put(0x4F, "audio/*");
-        WELL_KNOWN_MIME_TYPES.put(0x50, "video/*");
-        WELL_KNOWN_MIME_TYPES.put(0x51, "application/vnd.oma.dd2+xml");
-        WELL_KNOWN_MIME_TYPES.put(0x52, "application/mikey");
-        WELL_KNOWN_MIME_TYPES.put(0x53, "application/vnd.oma.dcd");
-        WELL_KNOWN_MIME_TYPES.put(0x54, "application/vnd.oma.dcdc");
-
-        WELL_KNOWN_MIME_TYPES.put(0x0201, "application/vnd.uplanet.cacheop-wbxml");
-        WELL_KNOWN_MIME_TYPES.put(0x0202, "application/vnd.uplanet.signal");
-        WELL_KNOWN_MIME_TYPES.put(0x0203, "application/vnd.uplanet.alert-wbxml");
-        WELL_KNOWN_MIME_TYPES.put(0x0204, "application/vnd.uplanet.list-wbxml");
-        WELL_KNOWN_MIME_TYPES.put(0x0205, "application/vnd.uplanet.listcmd-wbxml");
-        WELL_KNOWN_MIME_TYPES.put(0x0206, "application/vnd.uplanet.channel-wbxml");
-        WELL_KNOWN_MIME_TYPES.put(0x0207, "application/vnd.uplanet.provisioning-status-uri");
-        WELL_KNOWN_MIME_TYPES.put(0x0208, "x-wap.multipart/vnd.uplanet.header-set");
-        WELL_KNOWN_MIME_TYPES.put(0x0209, "application/vnd.uplanet.bearer-choice-wbxml");
-        WELL_KNOWN_MIME_TYPES.put(0x020A, "application/vnd.phonecom.mmc-wbxml");
-        WELL_KNOWN_MIME_TYPES.put(0x020B, "application/vnd.nokia.syncset+wbxml");
-        WELL_KNOWN_MIME_TYPES.put(0x020C, "image/x-up-wpng");
-        WELL_KNOWN_MIME_TYPES.put(0x0300, "application/iota.mmc-wbxml");
-        WELL_KNOWN_MIME_TYPES.put(0x0301, "application/iota.mmc-xml");
-        WELL_KNOWN_MIME_TYPES.put(0x0302, "application/vnd.syncml+xml");
-        WELL_KNOWN_MIME_TYPES.put(0x0303, "application/vnd.syncml+wbxml");
-        WELL_KNOWN_MIME_TYPES.put(0x0304, "text/vnd.wap.emn+xml");
-        WELL_KNOWN_MIME_TYPES.put(0x0305, "text/calendar");
-        WELL_KNOWN_MIME_TYPES.put(0x0306, "application/vnd.omads-email+xml");
-        WELL_KNOWN_MIME_TYPES.put(0x0307, "application/vnd.omads-file+xml");
-        WELL_KNOWN_MIME_TYPES.put(0x0308, "application/vnd.omads-folder+xml");
-        WELL_KNOWN_MIME_TYPES.put(0x0309, "text/directory;profile=vCard");
-        WELL_KNOWN_MIME_TYPES.put(0x030A, "application/vnd.wap.emn+wbxml");
-        WELL_KNOWN_MIME_TYPES.put(0x030B, "application/vnd.nokia.ipdc-purchase-response");
-        WELL_KNOWN_MIME_TYPES.put(0x030C, "application/vnd.motorola.screen3+xml");
-        WELL_KNOWN_MIME_TYPES.put(0x030D, "application/vnd.motorola.screen3+gzip");
-        WELL_KNOWN_MIME_TYPES.put(0x030E, "application/vnd.cmcc.setting+wbxml");
-        WELL_KNOWN_MIME_TYPES.put(0x030F, "application/vnd.cmcc.bombing+wbxml");
-        WELL_KNOWN_MIME_TYPES.put(0x0310, "application/vnd.docomo.pf");
-        WELL_KNOWN_MIME_TYPES.put(0x0311, "application/vnd.docomo.ub");
-        WELL_KNOWN_MIME_TYPES.put(0x0312, "application/vnd.omaloc-supl-init");
-        WELL_KNOWN_MIME_TYPES.put(0x0313, "application/vnd.oma.group-usage-list+xml");
-        WELL_KNOWN_MIME_TYPES.put(0x0314, "application/oma-directory+xml");
-        WELL_KNOWN_MIME_TYPES.put(0x0315, "application/vnd.docomo.pf2");
-        WELL_KNOWN_MIME_TYPES.put(0x0316, "application/vnd.oma.drm.roap-trigger+wbxml");
-        WELL_KNOWN_MIME_TYPES.put(0x0317, "application/vnd.sbm.mid2");
-        WELL_KNOWN_MIME_TYPES.put(0x0318, "application/vnd.wmf.bootstrap");
-        WELL_KNOWN_MIME_TYPES.put(0x0319, "application/vnc.cmcc.dcd+xml");
-        WELL_KNOWN_MIME_TYPES.put(0x031A, "application/vnd.sbm.cid");
-        WELL_KNOWN_MIME_TYPES.put(0x031B, "application/vnd.oma.bcast.provisioningtrigger");
-
-        WELL_KNOWN_PARAMETERS.put(0x00, "Q");
-        WELL_KNOWN_PARAMETERS.put(0x01, "Charset");
-        WELL_KNOWN_PARAMETERS.put(0x02, "Level");
-        WELL_KNOWN_PARAMETERS.put(0x03, "Type");
-        WELL_KNOWN_PARAMETERS.put(0x07, "Differences");
-        WELL_KNOWN_PARAMETERS.put(0x08, "Padding");
-        WELL_KNOWN_PARAMETERS.put(0x09, "Type");
-        WELL_KNOWN_PARAMETERS.put(0x0E, "Max-Age");
-        WELL_KNOWN_PARAMETERS.put(0x10, "Secure");
-        WELL_KNOWN_PARAMETERS.put(0x11, "SEC");
-        WELL_KNOWN_PARAMETERS.put(0x12, "MAC");
-        WELL_KNOWN_PARAMETERS.put(0x13, "Creation-date");
-        WELL_KNOWN_PARAMETERS.put(0x14, "Modification-date");
-        WELL_KNOWN_PARAMETERS.put(0x15, "Read-date");
-        WELL_KNOWN_PARAMETERS.put(0x16, "Size");
-        WELL_KNOWN_PARAMETERS.put(0x17, "Name");
-        WELL_KNOWN_PARAMETERS.put(0x18, "Filename");
-        WELL_KNOWN_PARAMETERS.put(0x19, "Start");
-        WELL_KNOWN_PARAMETERS.put(0x1A, "Start-info");
-        WELL_KNOWN_PARAMETERS.put(0x1B, "Comment");
-        WELL_KNOWN_PARAMETERS.put(0x1C, "Domain");
-        WELL_KNOWN_PARAMETERS.put(0x1D, "Path");
-    }
-
-    public static final String CONTENT_TYPE_B_PUSH_CO = "application/vnd.wap.coc";
-    public static final String CONTENT_TYPE_B_MMS = "application/vnd.wap.mms-message";
-    public static final String CONTENT_TYPE_B_PUSH_SYNCML_NOTI = "application/vnd.syncml.notification";
-
-    byte[] wspData;
-    int    dataLength;
-    long   unsigned32bit;
-    String stringValue;
-
-    HashMap<String, String> contentParameters;
-
-    public WspTypeDecoder(byte[] pdu) {
-        wspData = pdu;
-    }
-
-    /**
-     * Decode the "Text-string" type for WSP pdu
-     *
-     * @param startIndex The starting position of the "Text-string" in this pdu
-     *
-     * @return false when error(not a Text-string) occur
-     *         return value can be retrieved by getValueString() method length of data in pdu can be
-     *         retrieved by getDecodedDataLength() method
-     */
-    public boolean decodeTextString(int startIndex) {
-        int index = startIndex;
-        while (wspData[index] != 0) {
-            index++;
-        }
-        dataLength = index - startIndex + 1;
-        if (wspData[startIndex] == 127) {
-            stringValue = new String(wspData, startIndex + 1, dataLength - 2);
-        } else {
-            stringValue = new String(wspData, startIndex, dataLength - 1);
-        }
-        return true;
-    }
-
-    /**
-     * Decode the "Token-text" type for WSP pdu
-     *
-     * @param startIndex The starting position of the "Token-text" in this pdu
-     *
-     * @return always true
-     *         return value can be retrieved by getValueString() method
-     *         length of data in pdu can be retrieved by getDecodedDataLength() method
-     */
-    public boolean decodeTokenText(int startIndex) {
-        int index = startIndex;
-        while (wspData[index] != 0) {
-            index++;
-        }
-        dataLength = index - startIndex + 1;
-        stringValue = new String(wspData, startIndex, dataLength - 1);
-
-        return true;
-    }
-
-    /**
-     * Decode the "Short-integer" type for WSP pdu
-     *
-     * @param startIndex The starting position of the "Short-integer" in this pdu
-     *
-     * @return false when error(not a Short-integer) occur
-     *         return value can be retrieved by getValue32() method
-     *         length of data in pdu can be retrieved by getDecodedDataLength() method
-     */
-    public boolean decodeShortInteger(int startIndex) {
-        if ((wspData[startIndex] & 0x80) == 0) {
-            return false;
-        }
-        unsigned32bit = wspData[startIndex] & 0x7f;
-        dataLength = 1;
-        return true;
-    }
-
-    /**
-     * Decode the "Long-integer" type for WSP pdu
-     *
-     * @param startIndex The starting position of the "Long-integer" in this pdu
-     *
-     * @return false when error(not a Long-integer) occur
-     *         return value can be retrieved by getValue32() method
-     *         length of data in pdu can be retrieved by getDecodedDataLength() method
-     */
-    public boolean decodeLongInteger(int startIndex) {
-        int lengthMultiOctet = wspData[startIndex] & 0xff;
-
-        if (lengthMultiOctet > WAP_PDU_SHORT_LENGTH_MAX) {
-            return false;
-        }
-        unsigned32bit = 0;
-        for (int i = 1; i <= lengthMultiOctet; i++) {
-            unsigned32bit = (unsigned32bit << 8) | (wspData[startIndex + i] & 0xff);
-        }
-        dataLength = 1 + lengthMultiOctet;
-        return true;
-    }
-
-    /**
-     * Decode the "Integer-Value" type for WSP pdu
-     *
-     * @param startIndex The starting position of the "Integer-Value" in this pdu
-     *
-     * @return false when error(not a Integer-Value) occur
-     *         return value can be retrieved by getValue32() method
-     *         length of data in pdu can be retrieved by getDecodedDataLength() method
-     */
-    public boolean decodeIntegerValue(int startIndex) {
-        if (decodeShortInteger(startIndex) == true) {
-            return true;
-        }
-        return decodeLongInteger(startIndex);
-    }
-
-    /**
-     * Decode the "Uintvar-integer" type for WSP pdu
-     *
-     * @param startIndex The starting position of the "Uintvar-integer" in this pdu
-     *
-     * @return false when error(not a Uintvar-integer) occur
-     *         return value can be retrieved by getValue32() method
-     *         length of data in pdu can be retrieved by getDecodedDataLength() method
-     */
-    public boolean decodeUintvarInteger(int startIndex) {
-        int index = startIndex;
-
-        unsigned32bit = 0;
-        while ((wspData[index] & 0x80) != 0) {
-            if ((index - startIndex) >= 4) {
-                return false;
-            }
-            unsigned32bit = (unsigned32bit << 7) | (wspData[index] & 0x7f);
-            index++;
-        }
-        unsigned32bit = (unsigned32bit << 7) | (wspData[index] & 0x7f);
-        dataLength = index - startIndex + 1;
-        return true;
-    }
-
-    /**
-     * Decode the "Value-length" type for WSP pdu
-     *
-     * @param startIndex The starting position of the "Value-length" in this pdu
-     *
-     * @return false when error(not a Value-length) occur
-     *         return value can be retrieved by getValue32() method
-     *         length of data in pdu can be retrieved by getDecodedDataLength() method
-     */
-    public boolean decodeValueLength(int startIndex) {
-        if ((wspData[startIndex] & 0xff) > WAP_PDU_LENGTH_QUOTE) {
-            return false;
-        }
-        if (wspData[startIndex] < WAP_PDU_LENGTH_QUOTE) {
-            unsigned32bit = wspData[startIndex];
-            dataLength = 1;
-        } else {
-            decodeUintvarInteger(startIndex + 1);
-            dataLength++;
-        }
-        return true;
-    }
-
-    /**
-     * Decode the "Extension-media" type for WSP PDU.
-     *
-     * @param startIndex The starting position of the "Extension-media" in this PDU.
-     *
-     * @return false on error, such as if there is no Extension-media at startIndex.
-     *         Side-effects: updates stringValue (available with
-     *         getValueString()), which will be null on error. The length of the
-     *         data in the PDU is available with getValue32(), 0 on error.
-     */
-    public boolean decodeExtensionMedia(int startIndex) {
-        int index = startIndex;
-        dataLength = 0;
-        stringValue = null;
-        int length = wspData.length;
-        boolean rtrn = index < length;
-
-        while (index < length && wspData[index] != 0) {
-            index++;
-        }
-
-        dataLength = index - startIndex + 1;
-        stringValue = new String(wspData, startIndex, dataLength - 1);
-
-        return rtrn;
-    }
-
-    /**
-     * Decode the "Constrained-encoding" type for WSP pdu
-     *
-     * @param startIndex The starting position of the "Constrained-encoding" in this pdu
-     *
-     * @return false when error(not a Constrained-encoding) occur
-     *         return value can be retrieved first by getValueString() and second by getValue32() method
-     *         length of data in pdu can be retrieved by getDecodedDataLength() method
-     */
-    public boolean decodeConstrainedEncoding(int startIndex) {
-        if (decodeShortInteger(startIndex) == true) {
-            stringValue = null;
-            return true;
-        }
-        return decodeExtensionMedia(startIndex);
-    }
-
-    /**
-     * Decode the "Content-type" type for WSP pdu
-     *
-     * @param startIndex The starting position of the "Content-type" in this pdu
-     *
-     * @return false when error(not a Content-type) occurs
-     *         If a content type exists in the headers (either as inline string, or as well-known
-     *         value), getValueString() will return it. If a 'well known value' is encountered that
-     *         cannot be mapped to a string mime type, getValueString() will return null, and
-     *         getValue32() will return the unknown content type value.
-     *         length of data in pdu can be retrieved by getDecodedDataLength() method
-     *         Any content type parameters will be accessible via getContentParameters()
-     */
-    public boolean decodeContentType(int startIndex) {
-        int mediaPrefixLength;
-        contentParameters = new HashMap<String, String>();
-
-        try {
-            if (decodeValueLength(startIndex) == false) {
-                boolean found = decodeConstrainedEncoding(startIndex);
-                if (found) {
-                    expandWellKnownMimeType();
-                }
-                return found;
-            }
-            int headersLength = (int) unsigned32bit;
-            mediaPrefixLength = getDecodedDataLength();
-            if (decodeIntegerValue(startIndex + mediaPrefixLength) == true) {
-                dataLength += mediaPrefixLength;
-                int readLength = dataLength;
-                stringValue = null;
-                expandWellKnownMimeType();
-                long wellKnownValue = unsigned32bit;
-                String mimeType = stringValue;
-                if (readContentParameters(startIndex + dataLength,
-                        (headersLength - (dataLength - mediaPrefixLength)), 0)) {
-                    dataLength += readLength;
-                    unsigned32bit = wellKnownValue;
-                    stringValue = mimeType;
-                    return true;
-                }
-                return false;
-            }
-            if (decodeExtensionMedia(startIndex + mediaPrefixLength) == true) {
-                dataLength += mediaPrefixLength;
-                int readLength = dataLength;
-                expandWellKnownMimeType();
-                long wellKnownValue = unsigned32bit;
-                String mimeType = stringValue;
-                if (readContentParameters(startIndex + dataLength,
-                        (headersLength - (dataLength - mediaPrefixLength)), 0)) {
-                    dataLength += readLength;
-                    unsigned32bit = wellKnownValue;
-                    stringValue = mimeType;
-                    return true;
-                }
-            }
-        } catch (ArrayIndexOutOfBoundsException e) {
-            //something doesn't add up
-            return false;
-        }
-        return false;
-    }
-
-    private boolean readContentParameters(int startIndex, int leftToRead, int accumulator) {
-
-        int totalRead = 0;
-
-        if (leftToRead > 0) {
-            byte nextByte = wspData[startIndex];
-            String value = null;
-            String param = null;
-            if ((nextByte & 0x80) == 0x00 && nextByte > 31) { // untyped
-                decodeTokenText(startIndex);
-                param = stringValue;
-                totalRead += dataLength;
-            } else { // typed
-                if (decodeIntegerValue(startIndex)) {
-                    totalRead += dataLength;
-                    int wellKnownParameterValue = (int) unsigned32bit;
-                    param = WELL_KNOWN_PARAMETERS.get(wellKnownParameterValue);
-                    if (param == null) {
-                        param = "unassigned/0x" + Long.toHexString(wellKnownParameterValue);
-                    }
-                    // special case for the "Q" parameter, value is a uintvar
-                    if (wellKnownParameterValue == Q_VALUE) {
-                        if (decodeUintvarInteger(startIndex + totalRead)) {
-                            totalRead += dataLength;
-                            value = String.valueOf(unsigned32bit);
-                            contentParameters.put(param, value);
-                            return readContentParameters(startIndex + totalRead, leftToRead
-                                                            - totalRead, accumulator + totalRead);
-                        } else {
-                            return false;
-                        }
-                    }
-                } else {
-                    return false;
-                }
-            }
-
-            if (decodeNoValue(startIndex + totalRead)) {
-                totalRead += dataLength;
-                value = null;
-            } else if (decodeIntegerValue(startIndex + totalRead)) {
-                totalRead += dataLength;
-                int intValue = (int) unsigned32bit;
-                if (intValue == 0) {
-                    value = "";
-                } else {
-                    value = String.valueOf(intValue);
-                }
-            } else {
-                decodeTokenText(startIndex + totalRead);
-                totalRead += dataLength;
-                value = stringValue;
-                if (value.startsWith("\"")) {
-                    // quoted string, so remove the quote
-                    value = value.substring(1);
-                }
-            }
-            contentParameters.put(param, value);
-            return readContentParameters(startIndex + totalRead, leftToRead - totalRead,
-                                            accumulator + totalRead);
-
-        } else {
-            dataLength = accumulator;
-            return true;
-        }
-    }
-
-    /**
-     * Check if the next byte is No-Value
-     *
-     * @param startIndex The starting position of the "Content length" in this pdu
-     *
-     * @return true if and only if the next byte is 0x00
-     */
-    private boolean decodeNoValue(int startIndex) {
-        if (wspData[startIndex] == 0) {
-            dataLength = 1;
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * Populate stringValue with the mime type corresponding to the value in unsigned32bit
-     *
-     * Sets unsigned32bit to -1 if stringValue is already populated
-     */
-    private void expandWellKnownMimeType() {
-        if (stringValue == null) {
-            int binaryContentType = (int) unsigned32bit;
-            stringValue = WELL_KNOWN_MIME_TYPES.get(binaryContentType);
-        } else {
-            unsigned32bit = -1;
-        }
-    }
-
-    /**
-     * Decode the "Content length" type for WSP pdu
-     *
-     * @param startIndex The starting position of the "Content length" in this pdu
-     *
-     * @return false when error(not a Content length) occur
-     *         return value can be retrieved by getValue32() method
-     *         length of data in pdu can be retrieved by getDecodedDataLength() method
-     */
-    public boolean decodeContentLength(int startIndex) {
-        return decodeIntegerValue(startIndex);
-    }
-
-    /**
-     * Decode the "Content location" type for WSP pdu
-     *
-     * @param startIndex The starting position of the "Content location" in this pdu
-     *
-     * @return false when error(not a Content location) occur
-     *         return value can be retrieved by getValueString() method
-     *         length of data in pdu can be retrieved by getDecodedDataLength() method
-     */
-    public boolean decodeContentLocation(int startIndex) {
-        return decodeTextString(startIndex);
-    }
-
-    /**
-     * Decode the "X-Wap-Application-Id" type for WSP pdu
-     *
-     * @param startIndex The starting position of the "X-Wap-Application-Id" in this pdu
-     *
-     * @return false when error(not a X-Wap-Application-Id) occur
-     *         return value can be retrieved first by getValueString() and second by getValue32()
-     *         method
-     *         length of data in pdu can be retrieved by getDecodedDataLength() method
-     */
-    public boolean decodeXWapApplicationId(int startIndex) {
-        if (decodeIntegerValue(startIndex) == true) {
-            stringValue = null;
-            return true;
-        }
-        return decodeTextString(startIndex);
-    }
-
-    /**
-     * Seek for the "X-Wap-Application-Id" field for WSP pdu
-     *
-     * @param startIndex The starting position of seek pointer
-     * @param endIndex Valid seek area end point
-     *
-     * @return false when error(not a X-Wap-Application-Id) occur
-     *         return value can be retrieved by getValue32()
-     */
-    public boolean seekXWapApplicationId(int startIndex, int endIndex) {
-        int index = startIndex;
-
-        try {
-            for (index = startIndex; index <= endIndex; ) {
-                /**
-                 * 8.4.1.1  Field name
-                 * Field name is integer or text.
-                 */
-                if (decodeIntegerValue(index)) {
-                    int fieldValue = (int) getValue32();
-
-                    if (fieldValue == PARAMETER_ID_X_WAP_APPLICATION_ID) {
-                        unsigned32bit = index + 1;
-                        return true;
-                    }
-                } else {
-                    if (!decodeTextString(index)) return false;
-                }
-                index += getDecodedDataLength();
-                if (index > endIndex) return false;
-
-                /**
-                 * 8.4.1.2 Field values
-                 * Value Interpretation of First Octet
-                 * 0 - 30 This octet is followed by the indicated number (0 - 30)
-                        of data octets
-                 * 31 This octet is followed by a uintvar, which indicates the number
-                 *      of data octets after it
-                 * 32 - 127 The value is a text string, terminated by a zero octet
-                        (NUL character)
-                 * 128 - 255 It is an encoded 7-bit value; this header has no more data
-                 */
-                byte val = wspData[index];
-                if (0 <= val && val <= WAP_PDU_SHORT_LENGTH_MAX) {
-                    index += wspData[index] + 1;
-                } else if (val == WAP_PDU_LENGTH_QUOTE) {
-                    if (index + 1 >= endIndex) return false;
-                    index++;
-                    if (!decodeUintvarInteger(index)) return false;
-                    index += getDecodedDataLength();
-                } else if (WAP_PDU_LENGTH_QUOTE < val && val <= 127) {
-                    if (!decodeTextString(index)) return false;
-                    index += getDecodedDataLength();
-                } else {
-                    index++;
-                }
-            }
-        } catch (ArrayIndexOutOfBoundsException e) {
-            //seek application ID failed. WSP header might be corrupted
-            return false;
-        }
-        return false;
-    }
-
-    /**
-     * Decode the "X-Wap-Content-URI" type for WSP pdu
-     *
-     * @param startIndex The starting position of the "X-Wap-Content-URI" in this pdu
-     *
-     * @return false when error(not a X-Wap-Content-URI) occur
-     *         return value can be retrieved by getValueString() method
-     *         length of data in pdu can be retrieved by getDecodedDataLength() method
-     */
-    public boolean decodeXWapContentURI(int startIndex) {
-        return decodeTextString(startIndex);
-    }
-
-    /**
-     * Decode the "X-Wap-Initiator-URI" type for WSP pdu
-     *
-     * @param startIndex The starting position of the "X-Wap-Initiator-URI" in this pdu
-     *
-     * @return false when error(not a X-Wap-Initiator-URI) occur
-     *         return value can be retrieved by getValueString() method
-     *         length of data in pdu can be retrieved by getDecodedDataLength() method
-     */
-    public boolean decodeXWapInitiatorURI(int startIndex) {
-        return decodeTextString(startIndex);
-    }
-
-    /**
-     * The data length of latest operation.
-     */
-    public int getDecodedDataLength() {
-        return dataLength;
-    }
-
-    /**
-     * The 32-bits result of latest operation.
-     */
-    public long getValue32() {
-        return unsigned32bit;
-    }
-
-    /**
-     * The String result of latest operation.
-     */
-    public String getValueString() {
-        return stringValue;
-    }
-
-    /**
-     * Any parameters encountered as part of a decodeContentType() invocation.
-     *
-     * @return a map of content parameters keyed by their names, or null if
-     *         decodeContentType() has not been called If any unassigned
-     *         well-known parameters are encountered, the key of the map will be
-     *         'unassigned/0x...', where '...' is the hex value of the
-     *         unassigned parameter.  If a parameter has No-Value the value will be null.
-     *
-     */
-    public HashMap<String, String> getContentParameters() {
-        return contentParameters;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/AppInterface.java b/telephony/java/com/android/internal/telephony/cat/AppInterface.java
deleted file mode 100644
index 299e140..0000000
--- a/telephony/java/com/android/internal/telephony/cat/AppInterface.java
+++ /dev/null
@@ -1,96 +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.internal.telephony.cat;
-
-/**
- * Interface for communication between STK App and CAT Telephony
- *
- * {@hide}
- */
-public interface AppInterface {
-
-    /*
-     * Intent's actions which are broadcasted by the Telephony once a new CAT
-     * proactive command, session end arrive.
-     */
-    public static final String CAT_CMD_ACTION =
-                                    "android.intent.action.stk.command";
-    public static final String CAT_SESSION_END_ACTION =
-                                    "android.intent.action.stk.session_end";
-
-    /*
-     * Callback function from app to telephony to pass a result code and user's
-     * input back to the ICC.
-     */
-    void onCmdResponse(CatResponseMessage resMsg);
-
-    /*
-     * Enumeration for representing "Type of Command" of proactive commands.
-     * Those are the only commands which are supported by the Telephony. Any app
-     * implementation should support those.
-     * Refer to ETSI TS 102.223 section 9.4
-     */
-    public static enum CommandType {
-        DISPLAY_TEXT(0x21),
-        GET_INKEY(0x22),
-        GET_INPUT(0x23),
-        LAUNCH_BROWSER(0x15),
-        PLAY_TONE(0x20),
-        REFRESH(0x01),
-        SELECT_ITEM(0x24),
-        SEND_SS(0x11),
-        SEND_USSD(0x12),
-        SEND_SMS(0x13),
-        SEND_DTMF(0x14),
-        SET_UP_EVENT_LIST(0x05),
-        SET_UP_IDLE_MODE_TEXT(0x28),
-        SET_UP_MENU(0x25),
-        SET_UP_CALL(0x10),
-        PROVIDE_LOCAL_INFORMATION(0x26),
-        OPEN_CHANNEL(0x40),
-        CLOSE_CHANNEL(0x41),
-        RECEIVE_DATA(0x42),
-        SEND_DATA(0x43);
-
-        private int mValue;
-
-        CommandType(int value) {
-            mValue = value;
-        }
-
-        public int value() {
-            return mValue;
-        }
-
-        /**
-         * Create a CommandType object.
-         *
-         * @param value Integer value to be converted to a CommandType object.
-         * @return CommandType object whose "Type of Command" value is {@code
-         *         value}. If no CommandType object has that value, null is
-         *         returned.
-         */
-        public static CommandType fromInt(int value) {
-            for (CommandType e : CommandType.values()) {
-                if (e.mValue == value) {
-                    return e;
-                }
-            }
-            return null;
-        }
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/BerTlv.java b/telephony/java/com/android/internal/telephony/cat/BerTlv.java
deleted file mode 100644
index 095e65b..0000000
--- a/telephony/java/com/android/internal/telephony/cat/BerTlv.java
+++ /dev/null
@@ -1,123 +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.internal.telephony.cat;
-
-import java.util.List;
-
-/**
- * Class for representing BER-TLV objects.
- *
- * @see "ETSI TS 102 223 Annex C" for more information.
- *
- * {@hide}
- */
-class BerTlv {
-    private int mTag = BER_UNKNOWN_TAG;
-    private List<ComprehensionTlv> mCompTlvs = null;
-
-    public static final int BER_UNKNOWN_TAG             = 0x00;
-    public static final int BER_PROACTIVE_COMMAND_TAG   = 0xd0;
-    public static final int BER_MENU_SELECTION_TAG      = 0xd3;
-    public static final int BER_EVENT_DOWNLOAD_TAG      = 0xd6;
-
-    private BerTlv(int tag, List<ComprehensionTlv> ctlvs) {
-        mTag = tag;
-        mCompTlvs = ctlvs;
-    }
-
-    /**
-     * Gets a list of ComprehensionTlv objects contained in this BER-TLV object.
-     *
-     * @return A list of COMPREHENSION-TLV object
-     */
-    public List<ComprehensionTlv> getComprehensionTlvs() {
-        return mCompTlvs;
-    }
-
-    /**
-     * Gets a tag id of the BER-TLV object.
-     *
-     * @return A tag integer.
-     */
-    public int getTag() {
-        return mTag;
-    }
-
-    /**
-     * Decodes a BER-TLV object from a byte array.
-     *
-     * @param data A byte array to decode from
-     * @return A BER-TLV object decoded
-     * @throws ResultException
-     */
-    public static BerTlv decode(byte[] data) throws ResultException {
-        int curIndex = 0;
-        int endIndex = data.length;
-        int tag, length = 0;
-
-        try {
-            /* tag */
-            tag = data[curIndex++] & 0xff;
-            if (tag == BER_PROACTIVE_COMMAND_TAG) {
-                /* length */
-                int temp = data[curIndex++] & 0xff;
-                if (temp < 0x80) {
-                    length = temp;
-                } else if (temp == 0x81) {
-                    temp = data[curIndex++] & 0xff;
-                    if (temp < 0x80) {
-                        throw new ResultException(
-                                ResultCode.CMD_DATA_NOT_UNDERSTOOD,
-                                "length < 0x80 length=" + Integer.toHexString(length) +
-                                " curIndex=" + curIndex + " endIndex=" + endIndex);
-
-                    }
-                    length = temp;
-                } else {
-                    throw new ResultException(
-                            ResultCode.CMD_DATA_NOT_UNDERSTOOD,
-                            "Expected first byte to be length or a length tag and < 0x81" +
-                            " byte= " + Integer.toHexString(temp) + " curIndex=" + curIndex +
-                            " endIndex=" + endIndex);
-                }
-            } else {
-                if (ComprehensionTlvTag.COMMAND_DETAILS.value() == (tag & ~0x80)) {
-                    tag = BER_UNKNOWN_TAG;
-                    curIndex = 0;
-                }
-            }
-        } catch (IndexOutOfBoundsException e) {
-            throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING,
-                    "IndexOutOfBoundsException " +
-                    " curIndex=" + curIndex + " endIndex=" + endIndex);
-        } catch (ResultException e) {
-            throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD, e.explanation());
-        }
-
-        /* COMPREHENSION-TLVs */
-        if (endIndex - curIndex < length) {
-            throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD,
-                    "Command had extra data endIndex=" + endIndex + " curIndex=" + curIndex +
-                    " length=" + length);
-        }
-
-        List<ComprehensionTlv> ctlvs = ComprehensionTlv.decodeMany(data,
-                curIndex);
-
-        return new BerTlv(tag, ctlvs);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java b/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java
deleted file mode 100644
index 48c2e2b..0000000
--- a/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * 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.internal.telephony.cat;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Class used to pass CAT messages from telephony to application. Application
- * should call getXXX() to get commands's specific values.
- *
- */
-public class CatCmdMessage implements Parcelable {
-    // members
-    CommandDetails mCmdDet;
-    private TextMessage mTextMsg;
-    private Menu mMenu;
-    private Input mInput;
-    private BrowserSettings mBrowserSettings = null;
-    private ToneSettings mToneSettings = null;
-    private CallSettings mCallSettings = null;
-
-    /*
-     * Container for Launch Browser command settings.
-     */
-    public class BrowserSettings {
-        public String url;
-        public LaunchBrowserMode mode;
-    }
-
-    /*
-     * Container for Call Setup command settings.
-     */
-    public class CallSettings {
-        public TextMessage confirmMsg;
-        public TextMessage callMsg;
-    }
-
-    CatCmdMessage(CommandParams cmdParams) {
-        mCmdDet = cmdParams.cmdDet;
-        switch(getCmdType()) {
-        case SET_UP_MENU:
-        case SELECT_ITEM:
-            mMenu = ((SelectItemParams) cmdParams).menu;
-            break;
-        case DISPLAY_TEXT:
-        case SET_UP_IDLE_MODE_TEXT:
-        case SEND_DTMF:
-        case SEND_SMS:
-        case SEND_SS:
-        case SEND_USSD:
-            mTextMsg = ((DisplayTextParams) cmdParams).textMsg;
-            break;
-        case GET_INPUT:
-        case GET_INKEY:
-            mInput = ((GetInputParams) cmdParams).input;
-            break;
-        case LAUNCH_BROWSER:
-            mTextMsg = ((LaunchBrowserParams) cmdParams).confirmMsg;
-            mBrowserSettings = new BrowserSettings();
-            mBrowserSettings.url = ((LaunchBrowserParams) cmdParams).url;
-            mBrowserSettings.mode = ((LaunchBrowserParams) cmdParams).mode;
-            break;
-        case PLAY_TONE:
-            PlayToneParams params = (PlayToneParams) cmdParams;
-            mToneSettings = params.settings;
-            mTextMsg = params.textMsg;
-            break;
-        case SET_UP_CALL:
-            mCallSettings = new CallSettings();
-            mCallSettings.confirmMsg = ((CallSetupParams) cmdParams).confirmMsg;
-            mCallSettings.callMsg = ((CallSetupParams) cmdParams).callMsg;
-            break;
-        case OPEN_CHANNEL:
-        case CLOSE_CHANNEL:
-        case RECEIVE_DATA:
-        case SEND_DATA:
-            BIPClientParams param = (BIPClientParams) cmdParams;
-            mTextMsg = param.textMsg;
-            break;
-        }
-    }
-
-    public CatCmdMessage(Parcel in) {
-        mCmdDet = in.readParcelable(null);
-        mTextMsg = in.readParcelable(null);
-        mMenu = in.readParcelable(null);
-        mInput = in.readParcelable(null);
-        switch (getCmdType()) {
-        case LAUNCH_BROWSER:
-            mBrowserSettings = new BrowserSettings();
-            mBrowserSettings.url = in.readString();
-            mBrowserSettings.mode = LaunchBrowserMode.values()[in.readInt()];
-            break;
-        case PLAY_TONE:
-            mToneSettings = in.readParcelable(null);
-            break;
-        case SET_UP_CALL:
-            mCallSettings = new CallSettings();
-            mCallSettings.confirmMsg = in.readParcelable(null);
-            mCallSettings.callMsg = in.readParcelable(null);
-            break;
-        }
-    }
-
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeParcelable(mCmdDet, 0);
-        dest.writeParcelable(mTextMsg, 0);
-        dest.writeParcelable(mMenu, 0);
-        dest.writeParcelable(mInput, 0);
-        switch(getCmdType()) {
-        case LAUNCH_BROWSER:
-            dest.writeString(mBrowserSettings.url);
-            dest.writeInt(mBrowserSettings.mode.ordinal());
-            break;
-        case PLAY_TONE:
-            dest.writeParcelable(mToneSettings, 0);
-            break;
-        case SET_UP_CALL:
-            dest.writeParcelable(mCallSettings.confirmMsg, 0);
-            dest.writeParcelable(mCallSettings.callMsg, 0);
-            break;
-        }
-    }
-
-    public static final Parcelable.Creator<CatCmdMessage> CREATOR = new Parcelable.Creator<CatCmdMessage>() {
-        public CatCmdMessage createFromParcel(Parcel in) {
-            return new CatCmdMessage(in);
-        }
-
-        public CatCmdMessage[] newArray(int size) {
-            return new CatCmdMessage[size];
-        }
-    };
-
-    public int describeContents() {
-        return 0;
-    }
-
-    /* external API to be used by application */
-    public AppInterface.CommandType getCmdType() {
-        return AppInterface.CommandType.fromInt(mCmdDet.typeOfCommand);
-    }
-
-    public Menu getMenu() {
-        return mMenu;
-    }
-
-    public Input geInput() {
-        return mInput;
-    }
-
-    public TextMessage geTextMessage() {
-        return mTextMsg;
-    }
-
-    public BrowserSettings getBrowserSettings() {
-        return mBrowserSettings;
-    }
-
-    public ToneSettings getToneSettings() {
-        return mToneSettings;
-    }
-
-    public CallSettings getCallSettings() {
-        return mCallSettings;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/CatLog.java b/telephony/java/com/android/internal/telephony/cat/CatLog.java
deleted file mode 100644
index e19ff43..0000000
--- a/telephony/java/com/android/internal/telephony/cat/CatLog.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.internal.telephony.cat;
-
-import android.util.Log;
-
-public abstract class CatLog {
-    static final boolean DEBUG = true;
-
-    public static void d(Object caller, String msg) {
-        if (!DEBUG) {
-            return;
-        }
-
-        String className = caller.getClass().getName();
-        Log.d("CAT", className.substring(className.lastIndexOf('.') + 1) + ": "
-                + msg);
-    }
-
-    public static void d(String caller, String msg) {
-        if (!DEBUG) {
-            return;
-        }
-
-        Log.d("CAT", caller + ": " + msg);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/CatResponseMessage.java b/telephony/java/com/android/internal/telephony/cat/CatResponseMessage.java
deleted file mode 100644
index cfcac36..0000000
--- a/telephony/java/com/android/internal/telephony/cat/CatResponseMessage.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.internal.telephony.cat;
-
-public class CatResponseMessage {
-        CommandDetails cmdDet = null;
-        ResultCode resCode  = ResultCode.OK;
-        int usersMenuSelection = 0;
-        String usersInput  = null;
-        boolean usersYesNoSelection = false;
-        boolean usersConfirm = false;
-
-        public CatResponseMessage(CatCmdMessage cmdMsg) {
-            this.cmdDet = cmdMsg.mCmdDet;
-        }
-
-        public void setResultCode(ResultCode resCode) {
-            this.resCode = resCode;
-        }
-
-        public void setMenuSelection(int selection) {
-            this.usersMenuSelection = selection;
-        }
-
-        public void setInput(String input) {
-            this.usersInput = input;
-        }
-
-        public void setYesNo(boolean yesNo) {
-            usersYesNoSelection = yesNo;
-        }
-
-        public void setConfirmation(boolean confirm) {
-            usersConfirm = confirm;
-        }
-
-        CommandDetails getCmdDetails() {
-            return cmdDet;
-        }
-    }
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/cat/CatService.java b/telephony/java/com/android/internal/telephony/cat/CatService.java
deleted file mode 100644
index 17574ce..0000000
--- a/telephony/java/com/android/internal/telephony/cat/CatService.java
+++ /dev/null
@@ -1,753 +0,0 @@
-/*
- * 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.internal.telephony.cat;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Message;
-import android.os.SystemProperties;
-
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccFileHandler;
-import com.android.internal.telephony.IccRecords;
-
-
-import java.io.ByteArrayOutputStream;
-import java.util.List;
-import java.util.Locale;
-
-class RilMessage {
-    int mId;
-    Object mData;
-    ResultCode mResCode;
-
-    RilMessage(int msgId, String rawData) {
-        mId = msgId;
-        mData = rawData;
-    }
-
-    RilMessage(RilMessage other) {
-        this.mId = other.mId;
-        this.mData = other.mData;
-        this.mResCode = other.mResCode;
-    }
-}
-
-/**
- * Class that implements SIM Toolkit Telephony Service. Interacts with the RIL
- * and application.
- *
- * {@hide}
- */
-public class CatService extends Handler implements AppInterface {
-
-    // Class members
-    private static IccRecords mIccRecords;
-
-    // Service members.
-    // Protects singleton instance lazy initialization.
-    private static final Object sInstanceLock = new Object();
-    private static CatService sInstance;
-    private CommandsInterface mCmdIf;
-    private Context mContext;
-    private CatCmdMessage mCurrntCmd = null;
-    private CatCmdMessage mMenuCmd = null;
-
-    private RilMessageDecoder mMsgDecoder = null;
-    private boolean mStkAppInstalled = false;
-
-    // Service constants.
-    static final int MSG_ID_SESSION_END              = 1;
-    static final int MSG_ID_PROACTIVE_COMMAND        = 2;
-    static final int MSG_ID_EVENT_NOTIFY             = 3;
-    static final int MSG_ID_CALL_SETUP               = 4;
-    static final int MSG_ID_REFRESH                  = 5;
-    static final int MSG_ID_RESPONSE                 = 6;
-    static final int MSG_ID_SIM_READY                = 7;
-
-    static final int MSG_ID_RIL_MSG_DECODED          = 10;
-
-    // Events to signal SIM presence or absent in the device.
-    private static final int MSG_ID_ICC_RECORDS_LOADED       = 20;
-
-    private static final int DEV_ID_KEYPAD      = 0x01;
-    private static final int DEV_ID_DISPLAY     = 0x02;
-    private static final int DEV_ID_EARPIECE    = 0x03;
-    private static final int DEV_ID_UICC        = 0x81;
-    private static final int DEV_ID_TERMINAL    = 0x82;
-    private static final int DEV_ID_NETWORK     = 0x83;
-
-    static final String STK_DEFAULT = "Defualt Message";
-
-    /* Intentionally private for singleton */
-    private CatService(CommandsInterface ci, IccRecords ir, Context context,
-            IccFileHandler fh, IccCard ic) {
-        if (ci == null || ir == null || context == null || fh == null
-                || ic == null) {
-            throw new NullPointerException(
-                    "Service: Input parameters must not be null");
-        }
-        mCmdIf = ci;
-        mContext = context;
-
-        // Get the RilMessagesDecoder for decoding the messages.
-        mMsgDecoder = RilMessageDecoder.getInstance(this, fh);
-
-        // Register ril events handling.
-        mCmdIf.setOnCatSessionEnd(this, MSG_ID_SESSION_END, null);
-        mCmdIf.setOnCatProactiveCmd(this, MSG_ID_PROACTIVE_COMMAND, null);
-        mCmdIf.setOnCatEvent(this, MSG_ID_EVENT_NOTIFY, null);
-        mCmdIf.setOnCatCallSetUp(this, MSG_ID_CALL_SETUP, null);
-        //mCmdIf.setOnSimRefresh(this, MSG_ID_REFRESH, null);
-
-        mIccRecords = ir;
-
-        // Register for SIM ready event.
-        ic.registerForReady(this, MSG_ID_SIM_READY, null);
-        mIccRecords.registerForRecordsLoaded(this, MSG_ID_ICC_RECORDS_LOADED, null);
-
-        // Check if STK application is availalbe
-        mStkAppInstalled = isStkAppInstalled();
-
-        CatLog.d(this, "Running CAT service. STK app installed:" + mStkAppInstalled);
-    }
-
-    public void dispose() {
-        mIccRecords.unregisterForRecordsLoaded(this);
-        mCmdIf.unSetOnCatSessionEnd(this);
-        mCmdIf.unSetOnCatProactiveCmd(this);
-        mCmdIf.unSetOnCatEvent(this);
-        mCmdIf.unSetOnCatCallSetUp(this);
-
-        this.removeCallbacksAndMessages(null);
-    }
-
-    protected void finalize() {
-        CatLog.d(this, "Service finalized");
-    }
-
-    private void handleRilMsg(RilMessage rilMsg) {
-        if (rilMsg == null) {
-            return;
-        }
-
-        // dispatch messages
-        CommandParams cmdParams = null;
-        switch (rilMsg.mId) {
-        case MSG_ID_EVENT_NOTIFY:
-            if (rilMsg.mResCode == ResultCode.OK) {
-                cmdParams = (CommandParams) rilMsg.mData;
-                if (cmdParams != null) {
-                    handleCommand(cmdParams, false);
-                }
-            }
-            break;
-        case MSG_ID_PROACTIVE_COMMAND:
-            try {
-                cmdParams = (CommandParams) rilMsg.mData;
-            } catch (ClassCastException e) {
-                // for error handling : cast exception
-                CatLog.d(this, "Fail to parse proactive command");
-                // Don't send Terminal Resp if command detail is not available
-                if (mCurrntCmd != null) {
-                    sendTerminalResponse(mCurrntCmd.mCmdDet, ResultCode.CMD_DATA_NOT_UNDERSTOOD,
-                                     false, 0x00, null);
-                }
-                break;
-            }
-            if (cmdParams != null) {
-                if (rilMsg.mResCode == ResultCode.OK) {
-                    handleCommand(cmdParams, true);
-                } else {
-                    // for proactive commands that couldn't be decoded
-                    // successfully respond with the code generated by the
-                    // message decoder.
-                    sendTerminalResponse(cmdParams.cmdDet, rilMsg.mResCode,
-                            false, 0, null);
-                }
-            }
-            break;
-        case MSG_ID_REFRESH:
-            cmdParams = (CommandParams) rilMsg.mData;
-            if (cmdParams != null) {
-                handleCommand(cmdParams, false);
-            }
-            break;
-        case MSG_ID_SESSION_END:
-            handleSessionEnd();
-            break;
-        case MSG_ID_CALL_SETUP:
-            // prior event notify command supplied all the information
-            // needed for set up call processing.
-            break;
-        }
-    }
-
-    /**
-     * Handles RIL_UNSOL_STK_EVENT_NOTIFY or RIL_UNSOL_STK_PROACTIVE_COMMAND command
-     * from RIL.
-     * Sends valid proactive command data to the application using intents.
-     * RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE will be send back if the command is
-     * from RIL_UNSOL_STK_PROACTIVE_COMMAND.
-     */
-    private void handleCommand(CommandParams cmdParams, boolean isProactiveCmd) {
-        CatLog.d(this, cmdParams.getCommandType().name());
-
-        CharSequence message;
-        CatCmdMessage cmdMsg = new CatCmdMessage(cmdParams);
-        switch (cmdParams.getCommandType()) {
-            case SET_UP_MENU:
-                if (removeMenu(cmdMsg.getMenu())) {
-                    mMenuCmd = null;
-                } else {
-                    mMenuCmd = cmdMsg;
-                }
-                sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
-                break;
-            case DISPLAY_TEXT:
-                // when application is not required to respond, send an immediate response.
-                if (!cmdMsg.geTextMessage().responseNeeded) {
-                    sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
-                }
-                break;
-            case REFRESH:
-                // ME side only handles refresh commands which meant to remove IDLE
-                // MODE TEXT.
-                cmdParams.cmdDet.typeOfCommand = CommandType.SET_UP_IDLE_MODE_TEXT.value();
-                break;
-            case SET_UP_IDLE_MODE_TEXT:
-                sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
-                break;
-            case PROVIDE_LOCAL_INFORMATION:
-                ResponseData resp;
-                switch (cmdParams.cmdDet.commandQualifier) {
-                    case CommandParamsFactory.DTTZ_SETTING:
-                        resp = new DTTZResponseData(null);
-                        sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, resp);
-                        break;
-                    case CommandParamsFactory.LANGUAGE_SETTING:
-                        resp = new LanguageResponseData(Locale.getDefault().getLanguage());
-                        sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, resp);
-                        break;
-                    default:
-                        sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
-                }
-                // No need to start STK app here.
-                return;
-            case LAUNCH_BROWSER:
-                if ((((LaunchBrowserParams) cmdParams).confirmMsg.text != null)
-                        && (((LaunchBrowserParams) cmdParams).confirmMsg.text.equals(STK_DEFAULT))) {
-                    message = mContext.getText(com.android.internal.R.string.launchBrowserDefault);
-                    ((LaunchBrowserParams) cmdParams).confirmMsg.text = message.toString();
-                }
-                break;
-            case SELECT_ITEM:
-            case GET_INPUT:
-            case GET_INKEY:
-                break;
-            case SEND_DTMF:
-            case SEND_SMS:
-            case SEND_SS:
-            case SEND_USSD:
-                if ((((DisplayTextParams)cmdParams).textMsg.text != null)
-                        && (((DisplayTextParams)cmdParams).textMsg.text.equals(STK_DEFAULT))) {
-                    message = mContext.getText(com.android.internal.R.string.sending);
-                    ((DisplayTextParams)cmdParams).textMsg.text = message.toString();
-                }
-                break;
-            case PLAY_TONE:
-                break;
-            case SET_UP_CALL:
-                if ((((CallSetupParams) cmdParams).confirmMsg.text != null)
-                        && (((CallSetupParams) cmdParams).confirmMsg.text.equals(STK_DEFAULT))) {
-                    message = mContext.getText(com.android.internal.R.string.SetupCallDefault);
-                    ((CallSetupParams) cmdParams).confirmMsg.text = message.toString();
-                }
-                break;
-            case OPEN_CHANNEL:
-            case CLOSE_CHANNEL:
-            case RECEIVE_DATA:
-            case SEND_DATA:
-                BIPClientParams cmd = (BIPClientParams) cmdParams;
-                if (cmd.bHasAlphaId && (cmd.textMsg.text == null)) {
-                    CatLog.d(this, "cmd " + cmdParams.getCommandType() + " with null alpha id");
-                    // If alpha length is zero, we just respond with OK.
-                    if (isProactiveCmd) {
-                        sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
-                    }
-                    return;
-                }
-                // Respond with permanent failure to avoid retry if STK app is not present.
-                if (!mStkAppInstalled) {
-                    CatLog.d(this, "No STK application found.");
-                    if (isProactiveCmd) {
-                        sendTerminalResponse(cmdParams.cmdDet,
-                                             ResultCode.BEYOND_TERMINAL_CAPABILITY,
-                                             false, 0, null);
-                        return;
-                    }
-                }
-                /*
-                 * CLOSE_CHANNEL, RECEIVE_DATA and SEND_DATA can be delivered by
-                 * either PROACTIVE_COMMAND or EVENT_NOTIFY.
-                 * If PROACTIVE_COMMAND is used for those commands, send terminal
-                 * response here.
-                 */
-                if (isProactiveCmd &&
-                    ((cmdParams.getCommandType() == CommandType.CLOSE_CHANNEL) ||
-                     (cmdParams.getCommandType() == CommandType.RECEIVE_DATA) ||
-                     (cmdParams.getCommandType() == CommandType.SEND_DATA))) {
-                    sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
-                }
-                break;
-            default:
-                CatLog.d(this, "Unsupported command");
-                return;
-        }
-        mCurrntCmd = cmdMsg;
-        Intent intent = new Intent(AppInterface.CAT_CMD_ACTION);
-        intent.putExtra("STK CMD", cmdMsg);
-        mContext.sendBroadcast(intent);
-    }
-
-    /**
-     * Handles RIL_UNSOL_STK_SESSION_END unsolicited command from RIL.
-     *
-     */
-    private void handleSessionEnd() {
-        CatLog.d(this, "SESSION END");
-
-        mCurrntCmd = mMenuCmd;
-        Intent intent = new Intent(AppInterface.CAT_SESSION_END_ACTION);
-        mContext.sendBroadcast(intent);
-    }
-
-    private void sendTerminalResponse(CommandDetails cmdDet,
-            ResultCode resultCode, boolean includeAdditionalInfo,
-            int additionalInfo, ResponseData resp) {
-
-        if (cmdDet == null) {
-            return;
-        }
-        ByteArrayOutputStream buf = new ByteArrayOutputStream();
-
-        Input cmdInput = null;
-        if (mCurrntCmd != null) {
-            cmdInput = mCurrntCmd.geInput();
-        }
-
-        // command details
-        int tag = ComprehensionTlvTag.COMMAND_DETAILS.value();
-        if (cmdDet.compRequired) {
-            tag |= 0x80;
-        }
-        buf.write(tag);
-        buf.write(0x03); // length
-        buf.write(cmdDet.commandNumber);
-        buf.write(cmdDet.typeOfCommand);
-        buf.write(cmdDet.commandQualifier);
-
-        // device identities
-        // According to TS102.223/TS31.111 section 6.8 Structure of
-        // TERMINAL RESPONSE, "For all SIMPLE-TLV objects with Min=N,
-        // the ME should set the CR(comprehension required) flag to
-        // comprehension not required.(CR=0)"
-        // Since DEVICE_IDENTITIES and DURATION TLVs have Min=N,
-        // the CR flag is not set.
-        tag = ComprehensionTlvTag.DEVICE_IDENTITIES.value();
-        buf.write(tag);
-        buf.write(0x02); // length
-        buf.write(DEV_ID_TERMINAL); // source device id
-        buf.write(DEV_ID_UICC); // destination device id
-
-        // result
-        tag = 0x80 | ComprehensionTlvTag.RESULT.value();
-        buf.write(tag);
-        int length = includeAdditionalInfo ? 2 : 1;
-        buf.write(length);
-        buf.write(resultCode.value());
-
-        // additional info
-        if (includeAdditionalInfo) {
-            buf.write(additionalInfo);
-        }
-
-        // Fill optional data for each corresponding command
-        if (resp != null) {
-            resp.format(buf);
-        } else {
-            encodeOptionalTags(cmdDet, resultCode, cmdInput, buf);
-        }
-
-        byte[] rawData = buf.toByteArray();
-        String hexString = IccUtils.bytesToHexString(rawData);
-        if (false) {
-            CatLog.d(this, "TERMINAL RESPONSE: " + hexString);
-        }
-
-        mCmdIf.sendTerminalResponse(hexString, null);
-    }
-
-    private void encodeOptionalTags(CommandDetails cmdDet,
-            ResultCode resultCode, Input cmdInput, ByteArrayOutputStream buf) {
-        CommandType cmdType = AppInterface.CommandType.fromInt(cmdDet.typeOfCommand);
-        if (cmdType != null) {
-            switch (cmdType) {
-                case GET_INKEY:
-                    // ETSI TS 102 384,27.22.4.2.8.4.2.
-                    // If it is a response for GET_INKEY command and the response timeout
-                    // occured, then add DURATION TLV for variable timeout case.
-                    if ((resultCode.value() == ResultCode.NO_RESPONSE_FROM_USER.value()) &&
-                        (cmdInput != null) && (cmdInput.duration != null)) {
-                        getInKeyResponse(buf, cmdInput);
-                    }
-                    break;
-                case PROVIDE_LOCAL_INFORMATION:
-                    if ((cmdDet.commandQualifier == CommandParamsFactory.LANGUAGE_SETTING) &&
-                        (resultCode.value() == ResultCode.OK.value())) {
-                        getPliResponse(buf);
-                    }
-                    break;
-                default:
-                    CatLog.d(this, "encodeOptionalTags() Unsupported Cmd details=" + cmdDet);
-                    break;
-            }
-        } else {
-            CatLog.d(this, "encodeOptionalTags() bad Cmd details=" + cmdDet);
-        }
-    }
-
-    private void getInKeyResponse(ByteArrayOutputStream buf, Input cmdInput) {
-        int tag = ComprehensionTlvTag.DURATION.value();
-
-        buf.write(tag);
-        buf.write(0x02); // length
-        buf.write(cmdInput.duration.timeUnit.SECOND.value()); // Time (Unit,Seconds)
-        buf.write(cmdInput.duration.timeInterval); // Time Duration
-    }
-
-    private void getPliResponse(ByteArrayOutputStream buf) {
-
-        // Locale Language Setting
-        String lang = SystemProperties.get("persist.sys.language");
-
-        if (lang != null) {
-            // tag
-            int tag = ComprehensionTlvTag.LANGUAGE.value();
-            buf.write(tag);
-            ResponseData.writeLength(buf, lang.length());
-            buf.write(lang.getBytes(), 0, lang.length());
-        }
-    }
-
-    private void sendMenuSelection(int menuId, boolean helpRequired) {
-
-        ByteArrayOutputStream buf = new ByteArrayOutputStream();
-
-        // tag
-        int tag = BerTlv.BER_MENU_SELECTION_TAG;
-        buf.write(tag);
-
-        // length
-        buf.write(0x00); // place holder
-
-        // device identities
-        tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value();
-        buf.write(tag);
-        buf.write(0x02); // length
-        buf.write(DEV_ID_KEYPAD); // source device id
-        buf.write(DEV_ID_UICC); // destination device id
-
-        // item identifier
-        tag = 0x80 | ComprehensionTlvTag.ITEM_ID.value();
-        buf.write(tag);
-        buf.write(0x01); // length
-        buf.write(menuId); // menu identifier chosen
-
-        // help request
-        if (helpRequired) {
-            tag = ComprehensionTlvTag.HELP_REQUEST.value();
-            buf.write(tag);
-            buf.write(0x00); // length
-        }
-
-        byte[] rawData = buf.toByteArray();
-
-        // write real length
-        int len = rawData.length - 2; // minus (tag + length)
-        rawData[1] = (byte) len;
-
-        String hexString = IccUtils.bytesToHexString(rawData);
-
-        mCmdIf.sendEnvelope(hexString, null);
-    }
-
-    private void eventDownload(int event, int sourceId, int destinationId,
-            byte[] additionalInfo, boolean oneShot) {
-
-        ByteArrayOutputStream buf = new ByteArrayOutputStream();
-
-        // tag
-        int tag = BerTlv.BER_EVENT_DOWNLOAD_TAG;
-        buf.write(tag);
-
-        // length
-        buf.write(0x00); // place holder, assume length < 128.
-
-        // event list
-        tag = 0x80 | ComprehensionTlvTag.EVENT_LIST.value();
-        buf.write(tag);
-        buf.write(0x01); // length
-        buf.write(event); // event value
-
-        // device identities
-        tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value();
-        buf.write(tag);
-        buf.write(0x02); // length
-        buf.write(sourceId); // source device id
-        buf.write(destinationId); // destination device id
-
-        // additional information
-        if (additionalInfo != null) {
-            for (byte b : additionalInfo) {
-                buf.write(b);
-            }
-        }
-
-        byte[] rawData = buf.toByteArray();
-
-        // write real length
-        int len = rawData.length - 2; // minus (tag + length)
-        rawData[1] = (byte) len;
-
-        String hexString = IccUtils.bytesToHexString(rawData);
-
-        mCmdIf.sendEnvelope(hexString, null);
-    }
-
-    /**
-     * Used for instantiating/updating the Service from the GsmPhone or CdmaPhone constructor.
-     *
-     * @param ci CommandsInterface object
-     * @param ir IccRecords object
-     * @param context phone app context
-     * @param fh Icc file handler
-     * @param ic Icc card
-     * @return The only Service object in the system
-     */
-    public static CatService getInstance(CommandsInterface ci, IccRecords ir,
-            Context context, IccFileHandler fh, IccCard ic) {
-        synchronized (sInstanceLock) {
-            if (sInstance == null) {
-                if (ci == null || ir == null || context == null || fh == null
-                        || ic == null) {
-                    return null;
-                }
-                HandlerThread thread = new HandlerThread("Cat Telephony service");
-                thread.start();
-                sInstance = new CatService(ci, ir, context, fh, ic);
-                CatLog.d(sInstance, "NEW sInstance");
-            } else if ((ir != null) && (mIccRecords != ir)) {
-                CatLog.d(sInstance, "Reinitialize the Service with SIMRecords");
-                mIccRecords = ir;
-
-                // re-Register for SIM ready event.
-                mIccRecords.registerForRecordsLoaded(sInstance, MSG_ID_ICC_RECORDS_LOADED, null);
-                CatLog.d(sInstance, "sr changed reinitialize and return current sInstance");
-            } else {
-                CatLog.d(sInstance, "Return current sInstance");
-            }
-            return sInstance;
-        }
-    }
-
-    /**
-     * Used by application to get an AppInterface object.
-     *
-     * @return The only Service object in the system
-     */
-    public static AppInterface getInstance() {
-        return getInstance(null, null, null, null, null);
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-
-        switch (msg.what) {
-        case MSG_ID_SESSION_END:
-        case MSG_ID_PROACTIVE_COMMAND:
-        case MSG_ID_EVENT_NOTIFY:
-        case MSG_ID_REFRESH:
-            CatLog.d(this, "ril message arrived");
-            String data = null;
-            if (msg.obj != null) {
-                AsyncResult ar = (AsyncResult) msg.obj;
-                if (ar != null && ar.result != null) {
-                    try {
-                        data = (String) ar.result;
-                    } catch (ClassCastException e) {
-                        break;
-                    }
-                }
-            }
-            mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, data));
-            break;
-        case MSG_ID_CALL_SETUP:
-            mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, null));
-            break;
-        case MSG_ID_ICC_RECORDS_LOADED:
-            break;
-        case MSG_ID_RIL_MSG_DECODED:
-            handleRilMsg((RilMessage) msg.obj);
-            break;
-        case MSG_ID_RESPONSE:
-            handleCmdResponse((CatResponseMessage) msg.obj);
-            break;
-        case MSG_ID_SIM_READY:
-            CatLog.d(this, "SIM ready. Reporting STK service running now...");
-            mCmdIf.reportStkServiceIsRunning(null);
-            break;
-        default:
-            throw new AssertionError("Unrecognized CAT command: " + msg.what);
-        }
-    }
-
-    public synchronized void onCmdResponse(CatResponseMessage resMsg) {
-        if (resMsg == null) {
-            return;
-        }
-        // queue a response message.
-        Message msg = this.obtainMessage(MSG_ID_RESPONSE, resMsg);
-        msg.sendToTarget();
-    }
-
-    private boolean validateResponse(CatResponseMessage resMsg) {
-        if (mCurrntCmd != null) {
-            return (resMsg.cmdDet.compareTo(mCurrntCmd.mCmdDet));
-        }
-        return false;
-    }
-
-    private boolean removeMenu(Menu menu) {
-        try {
-            if (menu.items.size() == 1 && menu.items.get(0) == null) {
-                return true;
-            }
-        } catch (NullPointerException e) {
-            CatLog.d(this, "Unable to get Menu's items size");
-            return true;
-        }
-        return false;
-    }
-
-    private void handleCmdResponse(CatResponseMessage resMsg) {
-        // Make sure the response details match the last valid command. An invalid
-        // response is a one that doesn't have a corresponding proactive command
-        // and sending it can "confuse" the baseband/ril.
-        // One reason for out of order responses can be UI glitches. For example,
-        // if the application launch an activity, and that activity is stored
-        // by the framework inside the history stack. That activity will be
-        // available for relaunch using the latest application dialog
-        // (long press on the home button). Relaunching that activity can send
-        // the same command's result again to the CatService and can cause it to
-        // get out of sync with the SIM.
-        if (!validateResponse(resMsg)) {
-            return;
-        }
-        ResponseData resp = null;
-        boolean helpRequired = false;
-        CommandDetails cmdDet = resMsg.getCmdDetails();
-
-        switch (resMsg.resCode) {
-        case HELP_INFO_REQUIRED:
-            helpRequired = true;
-            // fall through
-        case OK:
-        case PRFRMD_WITH_PARTIAL_COMPREHENSION:
-        case PRFRMD_WITH_MISSING_INFO:
-        case PRFRMD_WITH_ADDITIONAL_EFS_READ:
-        case PRFRMD_ICON_NOT_DISPLAYED:
-        case PRFRMD_MODIFIED_BY_NAA:
-        case PRFRMD_LIMITED_SERVICE:
-        case PRFRMD_WITH_MODIFICATION:
-        case PRFRMD_NAA_NOT_ACTIVE:
-        case PRFRMD_TONE_NOT_PLAYED:
-            switch (AppInterface.CommandType.fromInt(cmdDet.typeOfCommand)) {
-            case SET_UP_MENU:
-                helpRequired = resMsg.resCode == ResultCode.HELP_INFO_REQUIRED;
-                sendMenuSelection(resMsg.usersMenuSelection, helpRequired);
-                return;
-            case SELECT_ITEM:
-                resp = new SelectItemResponseData(resMsg.usersMenuSelection);
-                break;
-            case GET_INPUT:
-            case GET_INKEY:
-                Input input = mCurrntCmd.geInput();
-                if (!input.yesNo) {
-                    // when help is requested there is no need to send the text
-                    // string object.
-                    if (!helpRequired) {
-                        resp = new GetInkeyInputResponseData(resMsg.usersInput,
-                                input.ucs2, input.packed);
-                    }
-                } else {
-                    resp = new GetInkeyInputResponseData(
-                            resMsg.usersYesNoSelection);
-                }
-                break;
-            case DISPLAY_TEXT:
-            case LAUNCH_BROWSER:
-                break;
-            case SET_UP_CALL:
-                mCmdIf.handleCallSetupRequestFromSim(resMsg.usersConfirm, null);
-                // No need to send terminal response for SET UP CALL. The user's
-                // confirmation result is send back using a dedicated ril message
-                // invoked by the CommandInterface call above.
-                mCurrntCmd = null;
-                return;
-            }
-            break;
-        case NO_RESPONSE_FROM_USER:
-        case UICC_SESSION_TERM_BY_USER:
-        case BACKWARD_MOVE_BY_USER:
-        case USER_NOT_ACCEPT:
-            resp = null;
-            break;
-        default:
-            return;
-        }
-        sendTerminalResponse(cmdDet, resMsg.resCode, false, 0, resp);
-        mCurrntCmd = null;
-    }
-
-    private boolean isStkAppInstalled() {
-        Intent intent = new Intent(AppInterface.CAT_CMD_ACTION);
-        PackageManager pm = mContext.getPackageManager();
-        List<ResolveInfo> broadcastReceivers =
-                            pm.queryBroadcastReceivers(intent, PackageManager.GET_META_DATA);
-        int numReceiver = broadcastReceivers == null ? 0 : broadcastReceivers.size();
-
-        return (numReceiver > 0);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/CommandDetails.java b/telephony/java/com/android/internal/telephony/cat/CommandDetails.java
deleted file mode 100644
index 8579535..0000000
--- a/telephony/java/com/android/internal/telephony/cat/CommandDetails.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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.internal.telephony.cat;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-abstract class ValueObject {
-    abstract ComprehensionTlvTag getTag();
-}
-
-/**
- * Class for Command Detailes object of proactive commands from SIM.
- * {@hide}
- */
-class CommandDetails extends ValueObject implements Parcelable {
-    public boolean compRequired;
-    public int commandNumber;
-    public int typeOfCommand;
-    public int commandQualifier;
-
-    public ComprehensionTlvTag getTag() {
-        return ComprehensionTlvTag.COMMAND_DETAILS;
-    }
-
-    CommandDetails() {
-    }
-
-    public boolean compareTo(CommandDetails other) {
-        return (this.compRequired == other.compRequired &&
-                this.commandNumber == other.commandNumber &&
-                this.commandQualifier == other.commandQualifier &&
-                this.typeOfCommand == other.typeOfCommand);
-    }
-
-    public CommandDetails(Parcel in) {
-        compRequired = true;
-        commandNumber = in.readInt();
-        typeOfCommand = in.readInt();
-        commandQualifier = in.readInt();
-    }
-
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(commandNumber);
-        dest.writeInt(typeOfCommand);
-        dest.writeInt(commandQualifier);
-    }
-
-    public static final Parcelable.Creator<CommandDetails> CREATOR =
-                                new Parcelable.Creator<CommandDetails>() {
-        public CommandDetails createFromParcel(Parcel in) {
-            return new CommandDetails(in);
-        }
-
-        public CommandDetails[] newArray(int size) {
-            return new CommandDetails[size];
-        }
-    };
-
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public String toString() {
-        return "CmdDetails: compRequired=" + compRequired +
-                " commandNumber=" + commandNumber +
-                " typeOfCommand=" + typeOfCommand +
-                " commandQualifier=" + commandQualifier;
-    }
-}
-
-class DeviceIdentities extends ValueObject {
-    public int sourceId;
-    public int destinationId;
-
-    ComprehensionTlvTag getTag() {
-        return ComprehensionTlvTag.DEVICE_IDENTITIES;
-    }
-}
-
-// Container class to hold icon identifier value.
-class IconId extends ValueObject {
-    int recordNumber;
-    boolean selfExplanatory;
-
-    ComprehensionTlvTag getTag() {
-        return ComprehensionTlvTag.ICON_ID;
-    }
-}
-
-// Container class to hold item icon identifier list value.
-class ItemsIconId extends ValueObject {
-    int [] recordNumbers;
-    boolean selfExplanatory;
-
-    ComprehensionTlvTag getTag() {
-        return ComprehensionTlvTag.ITEM_ICON_ID_LIST;
-    }
-}
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/cat/CommandParams.java b/telephony/java/com/android/internal/telephony/cat/CommandParams.java
deleted file mode 100644
index 79f6ad2..0000000
--- a/telephony/java/com/android/internal/telephony/cat/CommandParams.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * 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.internal.telephony.cat;
-
-import android.graphics.Bitmap;
-
-/**
- * Container class for proactive command parameters.
- *
- */
-class CommandParams {
-    CommandDetails cmdDet;
-
-    CommandParams(CommandDetails cmdDet) {
-        this.cmdDet = cmdDet;
-    }
-
-    AppInterface.CommandType getCommandType() {
-        return AppInterface.CommandType.fromInt(cmdDet.typeOfCommand);
-    }
-
-    boolean setIcon(Bitmap icon) { return true; }
-
-    @Override
-    public String toString() {
-        return cmdDet.toString();
-    }
-}
-
-class DisplayTextParams extends CommandParams {
-    TextMessage textMsg;
-
-    DisplayTextParams(CommandDetails cmdDet, TextMessage textMsg) {
-        super(cmdDet);
-        this.textMsg = textMsg;
-    }
-
-    boolean setIcon(Bitmap icon) {
-        if (icon != null && textMsg != null) {
-            textMsg.icon = icon;
-            return true;
-        }
-        return false;
-    }
-}
-
-class LaunchBrowserParams extends CommandParams {
-    TextMessage confirmMsg;
-    LaunchBrowserMode mode;
-    String url;
-
-    LaunchBrowserParams(CommandDetails cmdDet, TextMessage confirmMsg,
-            String url, LaunchBrowserMode mode) {
-        super(cmdDet);
-        this.confirmMsg = confirmMsg;
-        this.mode = mode;
-        this.url = url;
-    }
-
-    boolean setIcon(Bitmap icon) {
-        if (icon != null && confirmMsg != null) {
-            confirmMsg.icon = icon;
-            return true;
-        }
-        return false;
-    }
-}
-
-class PlayToneParams extends CommandParams {
-    TextMessage textMsg;
-    ToneSettings settings;
-
-    PlayToneParams(CommandDetails cmdDet, TextMessage textMsg,
-            Tone tone, Duration duration, boolean vibrate) {
-        super(cmdDet);
-        this.textMsg = textMsg;
-        this.settings = new ToneSettings(duration, tone, vibrate);
-    }
-
-    boolean setIcon(Bitmap icon) {
-        if (icon != null && textMsg != null) {
-            textMsg.icon = icon;
-            return true;
-        }
-        return false;
-    }
-}
-
-class CallSetupParams extends CommandParams {
-    TextMessage confirmMsg;
-    TextMessage callMsg;
-
-    CallSetupParams(CommandDetails cmdDet, TextMessage confirmMsg,
-            TextMessage callMsg) {
-        super(cmdDet);
-        this.confirmMsg = confirmMsg;
-        this.callMsg = callMsg;
-    }
-
-    boolean setIcon(Bitmap icon) {
-        if (icon == null) {
-            return false;
-        }
-        if (confirmMsg != null && confirmMsg.icon == null) {
-            confirmMsg.icon = icon;
-            return true;
-        } else if (callMsg != null && callMsg.icon == null) {
-            callMsg.icon = icon;
-            return true;
-        }
-        return false;
-    }
-}
-
-class SelectItemParams extends CommandParams {
-    Menu menu = null;
-    boolean loadTitleIcon = false;
-
-    SelectItemParams(CommandDetails cmdDet, Menu menu, boolean loadTitleIcon) {
-        super(cmdDet);
-        this.menu = menu;
-        this.loadTitleIcon = loadTitleIcon;
-    }
-
-    boolean setIcon(Bitmap icon) {
-        if (icon != null && menu != null) {
-            if (loadTitleIcon && menu.titleIcon == null) {
-                menu.titleIcon = icon;
-            } else {
-                for (Item item : menu.items) {
-                    if (item.icon != null) {
-                        continue;
-                    }
-                    item.icon = icon;
-                    break;
-                }
-            }
-            return true;
-        }
-        return false;
-    }
-}
-
-class GetInputParams extends CommandParams {
-    Input input = null;
-
-    GetInputParams(CommandDetails cmdDet, Input input) {
-        super(cmdDet);
-        this.input = input;
-    }
-
-    boolean setIcon(Bitmap icon) {
-        if (icon != null && input != null) {
-            input.icon = icon;
-        }
-        return true;
-    }
-}
-
-/*
- * BIP (Bearer Independent Protocol) is the mechanism for SIM card applications
- * to access data connection through the mobile device.
- *
- * SIM utilizes proactive commands (OPEN CHANNEL, CLOSE CHANNEL, SEND DATA and
- * RECEIVE DATA to control/read/write data for BIP. Refer to ETSI TS 102 223 for
- * the details of proactive commands procedures and their structures.
- */
-class BIPClientParams extends CommandParams {
-    TextMessage textMsg;
-    boolean bHasAlphaId;
-
-    BIPClientParams(CommandDetails cmdDet, TextMessage textMsg, boolean has_alpha_id) {
-        super(cmdDet);
-        this.textMsg = textMsg;
-        this.bHasAlphaId = has_alpha_id;
-    }
-
-    boolean setIcon(Bitmap icon) {
-        if (icon != null && textMsg != null) {
-            textMsg.icon = icon;
-            return true;
-        }
-        return false;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java b/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java
deleted file mode 100644
index a554012..0000000
--- a/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java
+++ /dev/null
@@ -1,943 +0,0 @@
-/*
- * 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.internal.telephony.cat;
-
-import android.graphics.Bitmap;
-import android.os.Handler;
-import android.os.Message;
-
-import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.IccFileHandler;
-
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Factory class, used for decoding raw byte arrays, received from baseband,
- * into a CommandParams object.
- *
- */
-class CommandParamsFactory extends Handler {
-    private static CommandParamsFactory sInstance = null;
-    private IconLoader mIconLoader;
-    private CommandParams mCmdParams = null;
-    private int mIconLoadState = LOAD_NO_ICON;
-    private RilMessageDecoder mCaller = null;
-
-    // constants
-    static final int MSG_ID_LOAD_ICON_DONE = 1;
-
-    // loading icons state parameters.
-    static final int LOAD_NO_ICON           = 0;
-    static final int LOAD_SINGLE_ICON       = 1;
-    static final int LOAD_MULTI_ICONS       = 2;
-
-    // Command Qualifier values for refresh command
-    static final int REFRESH_NAA_INIT_AND_FULL_FILE_CHANGE  = 0x00;
-    static final int REFRESH_NAA_INIT_AND_FILE_CHANGE       = 0x02;
-    static final int REFRESH_NAA_INIT                       = 0x03;
-    static final int REFRESH_UICC_RESET                     = 0x04;
-
-    // Command Qualifier values for PLI command
-    static final int DTTZ_SETTING                           = 0x03;
-    static final int LANGUAGE_SETTING                       = 0x04;
-
-    static synchronized CommandParamsFactory getInstance(RilMessageDecoder caller,
-            IccFileHandler fh) {
-        if (sInstance != null) {
-            return sInstance;
-        }
-        if (fh != null) {
-            return new CommandParamsFactory(caller, fh);
-        }
-        return null;
-    }
-
-    private CommandParamsFactory(RilMessageDecoder caller, IccFileHandler fh) {
-        mCaller = caller;
-        mIconLoader = IconLoader.getInstance(this, fh);
-    }
-
-    private CommandDetails processCommandDetails(List<ComprehensionTlv> ctlvs) {
-        CommandDetails cmdDet = null;
-
-        if (ctlvs != null) {
-            // Search for the Command Details object.
-            ComprehensionTlv ctlvCmdDet = searchForTag(
-                    ComprehensionTlvTag.COMMAND_DETAILS, ctlvs);
-            if (ctlvCmdDet != null) {
-                try {
-                    cmdDet = ValueParser.retrieveCommandDetails(ctlvCmdDet);
-                } catch (ResultException e) {
-                    CatLog.d(this,
-                            "processCommandDetails: Failed to procees command details e=" + e);
-                }
-            }
-        }
-        return cmdDet;
-    }
-
-    void make(BerTlv berTlv) {
-        if (berTlv == null) {
-            return;
-        }
-        // reset global state parameters.
-        mCmdParams = null;
-        mIconLoadState = LOAD_NO_ICON;
-        // only proactive command messages are processed.
-        if (berTlv.getTag() != BerTlv.BER_PROACTIVE_COMMAND_TAG) {
-            sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD);
-            return;
-        }
-        boolean cmdPending = false;
-        List<ComprehensionTlv> ctlvs = berTlv.getComprehensionTlvs();
-        // process command dtails from the tlv list.
-        CommandDetails cmdDet = processCommandDetails(ctlvs);
-        if (cmdDet == null) {
-            sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD);
-            return;
-        }
-
-        // extract command type enumeration from the raw value stored inside
-        // the Command Details object.
-        AppInterface.CommandType cmdType = AppInterface.CommandType
-                .fromInt(cmdDet.typeOfCommand);
-        if (cmdType == null) {
-            // This PROACTIVE COMMAND is presently not handled. Hence set
-            // result code as BEYOND_TERMINAL_CAPABILITY in TR.
-            mCmdParams = new CommandParams(cmdDet);
-            sendCmdParams(ResultCode.BEYOND_TERMINAL_CAPABILITY);
-            return;
-        }
-
-        try {
-            switch (cmdType) {
-            case SET_UP_MENU:
-                cmdPending = processSelectItem(cmdDet, ctlvs);
-                break;
-            case SELECT_ITEM:
-                cmdPending = processSelectItem(cmdDet, ctlvs);
-                break;
-            case DISPLAY_TEXT:
-                cmdPending = processDisplayText(cmdDet, ctlvs);
-                break;
-             case SET_UP_IDLE_MODE_TEXT:
-                 cmdPending = processSetUpIdleModeText(cmdDet, ctlvs);
-                 break;
-             case GET_INKEY:
-                cmdPending = processGetInkey(cmdDet, ctlvs);
-                break;
-             case GET_INPUT:
-                 cmdPending = processGetInput(cmdDet, ctlvs);
-                 break;
-             case SEND_DTMF:
-             case SEND_SMS:
-             case SEND_SS:
-             case SEND_USSD:
-                 cmdPending = processEventNotify(cmdDet, ctlvs);
-                 break;
-             case SET_UP_CALL:
-                 cmdPending = processSetupCall(cmdDet, ctlvs);
-                 break;
-             case REFRESH:
-                processRefresh(cmdDet, ctlvs);
-                cmdPending = false;
-                break;
-             case LAUNCH_BROWSER:
-                 cmdPending = processLaunchBrowser(cmdDet, ctlvs);
-                 break;
-             case PLAY_TONE:
-                cmdPending = processPlayTone(cmdDet, ctlvs);
-                break;
-             case PROVIDE_LOCAL_INFORMATION:
-                cmdPending = processProvideLocalInfo(cmdDet, ctlvs);
-                break;
-             case OPEN_CHANNEL:
-             case CLOSE_CHANNEL:
-             case RECEIVE_DATA:
-             case SEND_DATA:
-                 cmdPending = processBIPClient(cmdDet, ctlvs);
-                 break;
-            default:
-                // unsupported proactive commands
-                mCmdParams = new CommandParams(cmdDet);
-                sendCmdParams(ResultCode.BEYOND_TERMINAL_CAPABILITY);
-                return;
-            }
-        } catch (ResultException e) {
-            CatLog.d(this, "make: caught ResultException e=" + e);
-            mCmdParams = new CommandParams(cmdDet);
-            sendCmdParams(e.result());
-            return;
-        }
-        if (!cmdPending) {
-            sendCmdParams(ResultCode.OK);
-        }
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-        switch (msg.what) {
-        case MSG_ID_LOAD_ICON_DONE:
-            sendCmdParams(setIcons(msg.obj));
-            break;
-        }
-    }
-
-    private ResultCode setIcons(Object data) {
-        Bitmap[] icons = null;
-        int iconIndex = 0;
-
-        if (data == null) {
-            return ResultCode.PRFRMD_ICON_NOT_DISPLAYED;
-        }
-        switch(mIconLoadState) {
-        case LOAD_SINGLE_ICON:
-            mCmdParams.setIcon((Bitmap) data);
-            break;
-        case LOAD_MULTI_ICONS:
-            icons = (Bitmap[]) data;
-            // set each item icon.
-            for (Bitmap icon : icons) {
-                mCmdParams.setIcon(icon);
-            }
-            break;
-        }
-        return ResultCode.OK;
-    }
-
-    private void sendCmdParams(ResultCode resCode) {
-        mCaller.sendMsgParamsDecoded(resCode, mCmdParams);
-    }
-
-    /**
-     * Search for a COMPREHENSION-TLV object with the given tag from a list
-     *
-     * @param tag A tag to search for
-     * @param ctlvs List of ComprehensionTlv objects used to search in
-     *
-     * @return A ComprehensionTlv object that has the tag value of {@code tag}.
-     *         If no object is found with the tag, null is returned.
-     */
-    private ComprehensionTlv searchForTag(ComprehensionTlvTag tag,
-            List<ComprehensionTlv> ctlvs) {
-        Iterator<ComprehensionTlv> iter = ctlvs.iterator();
-        return searchForNextTag(tag, iter);
-    }
-
-    /**
-     * Search for the next COMPREHENSION-TLV object with the given tag from a
-     * list iterated by {@code iter}. {@code iter} points to the object next to
-     * the found object when this method returns. Used for searching the same
-     * list for similar tags, usually item id.
-     *
-     * @param tag A tag to search for
-     * @param iter Iterator for ComprehensionTlv objects used for search
-     *
-     * @return A ComprehensionTlv object that has the tag value of {@code tag}.
-     *         If no object is found with the tag, null is returned.
-     */
-    private ComprehensionTlv searchForNextTag(ComprehensionTlvTag tag,
-            Iterator<ComprehensionTlv> iter) {
-        int tagValue = tag.value();
-        while (iter.hasNext()) {
-            ComprehensionTlv ctlv = iter.next();
-            if (ctlv.getTag() == tagValue) {
-                return ctlv;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Processes DISPLAY_TEXT proactive command from the SIM card.
-     *
-     * @param cmdDet Command Details container object.
-     * @param ctlvs List of ComprehensionTlv objects following Command Details
-     *        object and Device Identities object within the proactive command
-     * @return true if the command is processing is pending and additional
-     *         asynchronous processing is required.
-     * @throws ResultException
-     */
-    private boolean processDisplayText(CommandDetails cmdDet,
-            List<ComprehensionTlv> ctlvs)
-            throws ResultException {
-
-        CatLog.d(this, "process DisplayText");
-
-        TextMessage textMsg = new TextMessage();
-        IconId iconId = null;
-
-        ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING,
-                ctlvs);
-        if (ctlv != null) {
-            textMsg.text = ValueParser.retrieveTextString(ctlv);
-        }
-        // If the tlv object doesn't exist or the it is a null object reply
-        // with command not understood.
-        if (textMsg.text == null) {
-            throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
-        }
-
-        ctlv = searchForTag(ComprehensionTlvTag.IMMEDIATE_RESPONSE, ctlvs);
-        if (ctlv != null) {
-            textMsg.responseNeeded = false;
-        }
-        // parse icon identifier
-        ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
-        if (ctlv != null) {
-            iconId = ValueParser.retrieveIconId(ctlv);
-            textMsg.iconSelfExplanatory = iconId.selfExplanatory;
-        }
-        // parse tone duration
-        ctlv = searchForTag(ComprehensionTlvTag.DURATION, ctlvs);
-        if (ctlv != null) {
-            textMsg.duration = ValueParser.retrieveDuration(ctlv);
-        }
-
-        // Parse command qualifier parameters.
-        textMsg.isHighPriority = (cmdDet.commandQualifier & 0x01) != 0;
-        textMsg.userClear = (cmdDet.commandQualifier & 0x80) != 0;
-
-        mCmdParams = new DisplayTextParams(cmdDet, textMsg);
-
-        if (iconId != null) {
-            mIconLoadState = LOAD_SINGLE_ICON;
-            mIconLoader.loadIcon(iconId.recordNumber, this
-                    .obtainMessage(MSG_ID_LOAD_ICON_DONE));
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Processes SET_UP_IDLE_MODE_TEXT proactive command from the SIM card.
-     *
-     * @param cmdDet Command Details container object.
-     * @param ctlvs List of ComprehensionTlv objects following Command Details
-     *        object and Device Identities object within the proactive command
-     * @return true if the command is processing is pending and additional
-     *         asynchronous processing is required.
-     * @throws ResultException
-     */
-    private boolean processSetUpIdleModeText(CommandDetails cmdDet,
-            List<ComprehensionTlv> ctlvs) throws ResultException {
-
-        CatLog.d(this, "process SetUpIdleModeText");
-
-        TextMessage textMsg = new TextMessage();
-        IconId iconId = null;
-
-        ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING,
-                ctlvs);
-        if (ctlv != null) {
-            textMsg.text = ValueParser.retrieveTextString(ctlv);
-        }
-        // load icons only when text exist.
-        if (textMsg.text != null) {
-            ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
-            if (ctlv != null) {
-                iconId = ValueParser.retrieveIconId(ctlv);
-                textMsg.iconSelfExplanatory = iconId.selfExplanatory;
-            }
-        }
-
-        mCmdParams = new DisplayTextParams(cmdDet, textMsg);
-
-        if (iconId != null) {
-            mIconLoadState = LOAD_SINGLE_ICON;
-            mIconLoader.loadIcon(iconId.recordNumber, this
-                    .obtainMessage(MSG_ID_LOAD_ICON_DONE));
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Processes GET_INKEY proactive command from the SIM card.
-     *
-     * @param cmdDet Command Details container object.
-     * @param ctlvs List of ComprehensionTlv objects following Command Details
-     *        object and Device Identities object within the proactive command
-     * @return true if the command is processing is pending and additional
-     *         asynchronous processing is required.
-     * @throws ResultException
-     */
-    private boolean processGetInkey(CommandDetails cmdDet,
-            List<ComprehensionTlv> ctlvs) throws ResultException {
-
-        CatLog.d(this, "process GetInkey");
-
-        Input input = new Input();
-        IconId iconId = null;
-
-        ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING,
-                ctlvs);
-        if (ctlv != null) {
-            input.text = ValueParser.retrieveTextString(ctlv);
-        } else {
-            throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING);
-        }
-        // parse icon identifier
-        ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
-        if (ctlv != null) {
-            iconId = ValueParser.retrieveIconId(ctlv);
-        }
-
-        // parse duration
-        ctlv = searchForTag(ComprehensionTlvTag.DURATION, ctlvs);
-        if (ctlv != null) {
-            input.duration = ValueParser.retrieveDuration(ctlv);
-        }
-
-        input.minLen = 1;
-        input.maxLen = 1;
-
-        input.digitOnly = (cmdDet.commandQualifier & 0x01) == 0;
-        input.ucs2 = (cmdDet.commandQualifier & 0x02) != 0;
-        input.yesNo = (cmdDet.commandQualifier & 0x04) != 0;
-        input.helpAvailable = (cmdDet.commandQualifier & 0x80) != 0;
-        input.echo = true;
-
-        mCmdParams = new GetInputParams(cmdDet, input);
-
-        if (iconId != null) {
-            mIconLoadState = LOAD_SINGLE_ICON;
-            mIconLoader.loadIcon(iconId.recordNumber, this
-                    .obtainMessage(MSG_ID_LOAD_ICON_DONE));
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Processes GET_INPUT proactive command from the SIM card.
-     *
-     * @param cmdDet Command Details container object.
-     * @param ctlvs List of ComprehensionTlv objects following Command Details
-     *        object and Device Identities object within the proactive command
-     * @return true if the command is processing is pending and additional
-     *         asynchronous processing is required.
-     * @throws ResultException
-     */
-    private boolean processGetInput(CommandDetails cmdDet,
-            List<ComprehensionTlv> ctlvs) throws ResultException {
-
-        CatLog.d(this, "process GetInput");
-
-        Input input = new Input();
-        IconId iconId = null;
-
-        ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING,
-                ctlvs);
-        if (ctlv != null) {
-            input.text = ValueParser.retrieveTextString(ctlv);
-        } else {
-            throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING);
-        }
-
-        ctlv = searchForTag(ComprehensionTlvTag.RESPONSE_LENGTH, ctlvs);
-        if (ctlv != null) {
-            try {
-                byte[] rawValue = ctlv.getRawValue();
-                int valueIndex = ctlv.getValueIndex();
-                input.minLen = rawValue[valueIndex] & 0xff;
-                input.maxLen = rawValue[valueIndex + 1] & 0xff;
-            } catch (IndexOutOfBoundsException e) {
-                throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
-            }
-        } else {
-            throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING);
-        }
-
-        ctlv = searchForTag(ComprehensionTlvTag.DEFAULT_TEXT, ctlvs);
-        if (ctlv != null) {
-            input.defaultText = ValueParser.retrieveTextString(ctlv);
-        }
-        // parse icon identifier
-        ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
-        if (ctlv != null) {
-            iconId = ValueParser.retrieveIconId(ctlv);
-        }
-
-        input.digitOnly = (cmdDet.commandQualifier & 0x01) == 0;
-        input.ucs2 = (cmdDet.commandQualifier & 0x02) != 0;
-        input.echo = (cmdDet.commandQualifier & 0x04) == 0;
-        input.packed = (cmdDet.commandQualifier & 0x08) != 0;
-        input.helpAvailable = (cmdDet.commandQualifier & 0x80) != 0;
-
-        mCmdParams = new GetInputParams(cmdDet, input);
-
-        if (iconId != null) {
-            mIconLoadState = LOAD_SINGLE_ICON;
-            mIconLoader.loadIcon(iconId.recordNumber, this
-                    .obtainMessage(MSG_ID_LOAD_ICON_DONE));
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Processes REFRESH proactive command from the SIM card.
-     *
-     * @param cmdDet Command Details container object.
-     * @param ctlvs List of ComprehensionTlv objects following Command Details
-     *        object and Device Identities object within the proactive command
-     */
-    private boolean processRefresh(CommandDetails cmdDet,
-            List<ComprehensionTlv> ctlvs) {
-
-        CatLog.d(this, "process Refresh");
-
-        // REFRESH proactive command is rerouted by the baseband and handled by
-        // the telephony layer. IDLE TEXT should be removed for a REFRESH command
-        // with "initialization" or "reset"
-        switch (cmdDet.commandQualifier) {
-        case REFRESH_NAA_INIT_AND_FULL_FILE_CHANGE:
-        case REFRESH_NAA_INIT_AND_FILE_CHANGE:
-        case REFRESH_NAA_INIT:
-        case REFRESH_UICC_RESET:
-            mCmdParams = new DisplayTextParams(cmdDet, null);
-            break;
-        }
-        return false;
-    }
-
-    /**
-     * Processes SELECT_ITEM proactive command from the SIM card.
-     *
-     * @param cmdDet Command Details container object.
-     * @param ctlvs List of ComprehensionTlv objects following Command Details
-     *        object and Device Identities object within the proactive command
-     * @return true if the command is processing is pending and additional
-     *         asynchronous processing is required.
-     * @throws ResultException
-     */
-    private boolean processSelectItem(CommandDetails cmdDet,
-            List<ComprehensionTlv> ctlvs) throws ResultException {
-
-        CatLog.d(this, "process SelectItem");
-
-        Menu menu = new Menu();
-        IconId titleIconId = null;
-        ItemsIconId itemsIconId = null;
-        Iterator<ComprehensionTlv> iter = ctlvs.iterator();
-
-        ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID,
-                ctlvs);
-        if (ctlv != null) {
-            menu.title = ValueParser.retrieveAlphaId(ctlv);
-        }
-
-        while (true) {
-            ctlv = searchForNextTag(ComprehensionTlvTag.ITEM, iter);
-            if (ctlv != null) {
-                menu.items.add(ValueParser.retrieveItem(ctlv));
-            } else {
-                break;
-            }
-        }
-
-        // We must have at least one menu item.
-        if (menu.items.size() == 0) {
-            throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING);
-        }
-
-        ctlv = searchForTag(ComprehensionTlvTag.ITEM_ID, ctlvs);
-        if (ctlv != null) {
-            // CAT items are listed 1...n while list start at 0, need to
-            // subtract one.
-            menu.defaultItem = ValueParser.retrieveItemId(ctlv) - 1;
-        }
-
-        ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
-        if (ctlv != null) {
-            mIconLoadState = LOAD_SINGLE_ICON;
-            titleIconId = ValueParser.retrieveIconId(ctlv);
-            menu.titleIconSelfExplanatory = titleIconId.selfExplanatory;
-        }
-
-        ctlv = searchForTag(ComprehensionTlvTag.ITEM_ICON_ID_LIST, ctlvs);
-        if (ctlv != null) {
-            mIconLoadState = LOAD_MULTI_ICONS;
-            itemsIconId = ValueParser.retrieveItemsIconId(ctlv);
-            menu.itemsIconSelfExplanatory = itemsIconId.selfExplanatory;
-        }
-
-        boolean presentTypeSpecified = (cmdDet.commandQualifier & 0x01) != 0;
-        if (presentTypeSpecified) {
-            if ((cmdDet.commandQualifier & 0x02) == 0) {
-                menu.presentationType = PresentationType.DATA_VALUES;
-            } else {
-                menu.presentationType = PresentationType.NAVIGATION_OPTIONS;
-            }
-        }
-        menu.softKeyPreferred = (cmdDet.commandQualifier & 0x04) != 0;
-        menu.helpAvailable = (cmdDet.commandQualifier & 0x80) != 0;
-
-        mCmdParams = new SelectItemParams(cmdDet, menu, titleIconId != null);
-
-        // Load icons data if needed.
-        switch(mIconLoadState) {
-        case LOAD_NO_ICON:
-            return false;
-        case LOAD_SINGLE_ICON:
-            mIconLoader.loadIcon(titleIconId.recordNumber, this
-                    .obtainMessage(MSG_ID_LOAD_ICON_DONE));
-            break;
-        case LOAD_MULTI_ICONS:
-            int[] recordNumbers = itemsIconId.recordNumbers;
-            if (titleIconId != null) {
-                // Create a new array for all the icons (title and items).
-                recordNumbers = new int[itemsIconId.recordNumbers.length + 1];
-                recordNumbers[0] = titleIconId.recordNumber;
-                System.arraycopy(itemsIconId.recordNumbers, 0, recordNumbers,
-                        1, itemsIconId.recordNumbers.length);
-            }
-            mIconLoader.loadIcons(recordNumbers, this
-                    .obtainMessage(MSG_ID_LOAD_ICON_DONE));
-            break;
-        }
-        return true;
-    }
-
-    /**
-     * Processes EVENT_NOTIFY message from baseband.
-     *
-     * @param cmdDet Command Details container object.
-     * @param ctlvs List of ComprehensionTlv objects following Command Details
-     *        object and Device Identities object within the proactive command
-     * @return true if the command is processing is pending and additional
-     *         asynchronous processing is required.
-     */
-    private boolean processEventNotify(CommandDetails cmdDet,
-            List<ComprehensionTlv> ctlvs) throws ResultException {
-
-        CatLog.d(this, "process EventNotify");
-
-        TextMessage textMsg = new TextMessage();
-        IconId iconId = null;
-
-        ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID,
-                ctlvs);
-        textMsg.text = ValueParser.retrieveAlphaId(ctlv);
-
-        ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
-        if (ctlv != null) {
-            iconId = ValueParser.retrieveIconId(ctlv);
-            textMsg.iconSelfExplanatory = iconId.selfExplanatory;
-        }
-
-        textMsg.responseNeeded = false;
-        mCmdParams = new DisplayTextParams(cmdDet, textMsg);
-
-        if (iconId != null) {
-            mIconLoadState = LOAD_SINGLE_ICON;
-            mIconLoader.loadIcon(iconId.recordNumber, this
-                    .obtainMessage(MSG_ID_LOAD_ICON_DONE));
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Processes SET_UP_EVENT_LIST proactive command from the SIM card.
-     *
-     * @param cmdDet Command Details object retrieved.
-     * @param ctlvs List of ComprehensionTlv objects following Command Details
-     *        object and Device Identities object within the proactive command
-     * @return true if the command is processing is pending and additional
-     *         asynchronous processing is required.
-     */
-    private boolean processSetUpEventList(CommandDetails cmdDet,
-            List<ComprehensionTlv> ctlvs) {
-
-        CatLog.d(this, "process SetUpEventList");
-        //
-        // ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.EVENT_LIST,
-        // ctlvs);
-        // if (ctlv != null) {
-        // try {
-        // byte[] rawValue = ctlv.getRawValue();
-        // int valueIndex = ctlv.getValueIndex();
-        // int valueLen = ctlv.getLength();
-        //
-        // } catch (IndexOutOfBoundsException e) {}
-        // }
-        return true;
-    }
-
-    /**
-     * Processes LAUNCH_BROWSER proactive command from the SIM card.
-     *
-     * @param cmdDet Command Details container object.
-     * @param ctlvs List of ComprehensionTlv objects following Command Details
-     *        object and Device Identities object within the proactive command
-     * @return true if the command is processing is pending and additional
-     *         asynchronous processing is required.
-     * @throws ResultException
-     */
-    private boolean processLaunchBrowser(CommandDetails cmdDet,
-            List<ComprehensionTlv> ctlvs) throws ResultException {
-
-        CatLog.d(this, "process LaunchBrowser");
-
-        TextMessage confirmMsg = new TextMessage();
-        IconId iconId = null;
-        String url = null;
-
-        ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.URL, ctlvs);
-        if (ctlv != null) {
-            try {
-                byte[] rawValue = ctlv.getRawValue();
-                int valueIndex = ctlv.getValueIndex();
-                int valueLen = ctlv.getLength();
-                if (valueLen > 0) {
-                    url = GsmAlphabet.gsm8BitUnpackedToString(rawValue,
-                            valueIndex, valueLen);
-                } else {
-                    url = null;
-                }
-            } catch (IndexOutOfBoundsException e) {
-                throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
-            }
-        }
-
-        // parse alpha identifier.
-        ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, ctlvs);
-        confirmMsg.text = ValueParser.retrieveAlphaId(ctlv);
-
-        // parse icon identifier
-        ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
-        if (ctlv != null) {
-            iconId = ValueParser.retrieveIconId(ctlv);
-            confirmMsg.iconSelfExplanatory = iconId.selfExplanatory;
-        }
-
-        // parse command qualifier value.
-        LaunchBrowserMode mode;
-        switch (cmdDet.commandQualifier) {
-        case 0x00:
-        default:
-            mode = LaunchBrowserMode.LAUNCH_IF_NOT_ALREADY_LAUNCHED;
-            break;
-        case 0x02:
-            mode = LaunchBrowserMode.USE_EXISTING_BROWSER;
-            break;
-        case 0x03:
-            mode = LaunchBrowserMode.LAUNCH_NEW_BROWSER;
-            break;
-        }
-
-        mCmdParams = new LaunchBrowserParams(cmdDet, confirmMsg, url, mode);
-
-        if (iconId != null) {
-            mIconLoadState = LOAD_SINGLE_ICON;
-            mIconLoader.loadIcon(iconId.recordNumber, this
-                    .obtainMessage(MSG_ID_LOAD_ICON_DONE));
-            return true;
-        }
-        return false;
-    }
-
-     /**
-     * Processes PLAY_TONE proactive command from the SIM card.
-     *
-     * @param cmdDet Command Details container object.
-     * @param ctlvs List of ComprehensionTlv objects following Command Details
-     *        object and Device Identities object within the proactive command
-     * @return true if the command is processing is pending and additional
-     *         asynchronous processing is required.t
-     * @throws ResultException
-     */
-    private boolean processPlayTone(CommandDetails cmdDet,
-            List<ComprehensionTlv> ctlvs) throws ResultException {
-
-        CatLog.d(this, "process PlayTone");
-
-        Tone tone = null;
-        TextMessage textMsg = new TextMessage();
-        Duration duration = null;
-        IconId iconId = null;
-
-        ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TONE, ctlvs);
-        if (ctlv != null) {
-            // Nothing to do for null objects.
-            if (ctlv.getLength() > 0) {
-                try {
-                    byte[] rawValue = ctlv.getRawValue();
-                    int valueIndex = ctlv.getValueIndex();
-                    int toneVal = rawValue[valueIndex];
-                    tone = Tone.fromInt(toneVal);
-                } catch (IndexOutOfBoundsException e) {
-                    throw new ResultException(
-                            ResultCode.CMD_DATA_NOT_UNDERSTOOD);
-                }
-            }
-        }
-        // parse alpha identifier
-        ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, ctlvs);
-        if (ctlv != null) {
-            textMsg.text = ValueParser.retrieveAlphaId(ctlv);
-        }
-        // parse tone duration
-        ctlv = searchForTag(ComprehensionTlvTag.DURATION, ctlvs);
-        if (ctlv != null) {
-            duration = ValueParser.retrieveDuration(ctlv);
-        }
-        // parse icon identifier
-        ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
-        if (ctlv != null) {
-            iconId = ValueParser.retrieveIconId(ctlv);
-            textMsg.iconSelfExplanatory = iconId.selfExplanatory;
-        }
-
-        boolean vibrate = (cmdDet.commandQualifier & 0x01) != 0x00;
-
-        textMsg.responseNeeded = false;
-        mCmdParams = new PlayToneParams(cmdDet, textMsg, tone, duration, vibrate);
-
-        if (iconId != null) {
-            mIconLoadState = LOAD_SINGLE_ICON;
-            mIconLoader.loadIcon(iconId.recordNumber, this
-                    .obtainMessage(MSG_ID_LOAD_ICON_DONE));
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Processes SETUP_CALL proactive command from the SIM card.
-     *
-     * @param cmdDet Command Details object retrieved from the proactive command
-     *        object
-     * @param ctlvs List of ComprehensionTlv objects following Command Details
-     *        object and Device Identities object within the proactive command
-     * @return true if the command is processing is pending and additional
-     *         asynchronous processing is required.
-     */
-    private boolean processSetupCall(CommandDetails cmdDet,
-            List<ComprehensionTlv> ctlvs) throws ResultException {
-        CatLog.d(this, "process SetupCall");
-
-        Iterator<ComprehensionTlv> iter = ctlvs.iterator();
-        ComprehensionTlv ctlv = null;
-        // User confirmation phase message.
-        TextMessage confirmMsg = new TextMessage();
-        // Call set up phase message.
-        TextMessage callMsg = new TextMessage();
-        IconId confirmIconId = null;
-        IconId callIconId = null;
-
-        // get confirmation message string.
-        ctlv = searchForNextTag(ComprehensionTlvTag.ALPHA_ID, iter);
-        confirmMsg.text = ValueParser.retrieveAlphaId(ctlv);
-
-        ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
-        if (ctlv != null) {
-            confirmIconId = ValueParser.retrieveIconId(ctlv);
-            confirmMsg.iconSelfExplanatory = confirmIconId.selfExplanatory;
-        }
-
-        // get call set up message string.
-        ctlv = searchForNextTag(ComprehensionTlvTag.ALPHA_ID, iter);
-        if (ctlv != null) {
-            callMsg.text = ValueParser.retrieveAlphaId(ctlv);
-        }
-
-        ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
-        if (ctlv != null) {
-            callIconId = ValueParser.retrieveIconId(ctlv);
-            callMsg.iconSelfExplanatory = callIconId.selfExplanatory;
-        }
-
-        mCmdParams = new CallSetupParams(cmdDet, confirmMsg, callMsg);
-
-        if (confirmIconId != null || callIconId != null) {
-            mIconLoadState = LOAD_MULTI_ICONS;
-            int[] recordNumbers = new int[2];
-            recordNumbers[0] = confirmIconId != null
-                    ? confirmIconId.recordNumber : -1;
-            recordNumbers[1] = callIconId != null ? callIconId.recordNumber
-                    : -1;
-
-            mIconLoader.loadIcons(recordNumbers, this
-                    .obtainMessage(MSG_ID_LOAD_ICON_DONE));
-            return true;
-        }
-        return false;
-    }
-
-    private boolean processProvideLocalInfo(CommandDetails cmdDet, List<ComprehensionTlv> ctlvs)
-            throws ResultException {
-        CatLog.d(this, "process ProvideLocalInfo");
-        switch (cmdDet.commandQualifier) {
-            case DTTZ_SETTING:
-                CatLog.d(this, "PLI [DTTZ_SETTING]");
-                mCmdParams = new CommandParams(cmdDet);
-                break;
-            case LANGUAGE_SETTING:
-                CatLog.d(this, "PLI [LANGUAGE_SETTING]");
-                mCmdParams = new CommandParams(cmdDet);
-                break;
-            default:
-                CatLog.d(this, "PLI[" + cmdDet.commandQualifier + "] Command Not Supported");
-                mCmdParams = new CommandParams(cmdDet);
-                throw new ResultException(ResultCode.BEYOND_TERMINAL_CAPABILITY);
-        }
-        return false;
-    }
-
-    private boolean processBIPClient(CommandDetails cmdDet,
-                                     List<ComprehensionTlv> ctlvs) throws ResultException {
-        AppInterface.CommandType commandType =
-                                    AppInterface.CommandType.fromInt(cmdDet.typeOfCommand);
-        if (commandType != null) {
-            CatLog.d(this, "process "+ commandType.name());
-        }
-
-        TextMessage textMsg = new TextMessage();
-        IconId iconId = null;
-        ComprehensionTlv ctlv = null;
-        boolean has_alpha_id = false;
-
-        // parse alpha identifier
-        ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, ctlvs);
-        if (ctlv != null) {
-            textMsg.text = ValueParser.retrieveAlphaId(ctlv);
-            CatLog.d(this, "alpha TLV text=" + textMsg.text);
-            has_alpha_id = true;
-        }
-
-        // parse icon identifier
-        ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
-        if (ctlv != null) {
-            iconId = ValueParser.retrieveIconId(ctlv);
-            textMsg.iconSelfExplanatory = iconId.selfExplanatory;
-        }
-
-        textMsg.responseNeeded = false;
-        mCmdParams = new BIPClientParams(cmdDet, textMsg, has_alpha_id);
-
-        if (iconId != null) {
-            mIconLoadState = LOAD_SINGLE_ICON;
-            mIconLoader.loadIcon(iconId.recordNumber, this.obtainMessage(MSG_ID_LOAD_ICON_DONE));
-            return true;
-        }
-        return false;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java b/telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java
deleted file mode 100644
index 22cd5a4..0000000
--- a/telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2011 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.internal.telephony.cat;
-
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-
-
-/**
- * Class for representing COMPREHENSION-TLV objects.
- *
- * @see "ETSI TS 101 220 subsection 7.1.1"
- *
- * {@hide}
- */
-class ComprehensionTlv {
-    private static final String LOG_TAG = "ComprehensionTlv";
-    private int mTag;
-    private boolean mCr;
-    private int mLength;
-    private int mValueIndex;
-    private byte[] mRawValue;
-
-    /**
-     * Constructor. Private on purpose. Use
-     * {@link #decodeMany(byte[], int) decodeMany} or
-     * {@link #decode(byte[], int) decode} method.
-     *
-     * @param tag The tag for this object
-     * @param cr Comprehension Required flag
-     * @param length Length of the value
-     * @param data Byte array containing the value
-     * @param valueIndex Index in data at which the value starts
-     */
-    protected ComprehensionTlv(int tag, boolean cr, int length, byte[] data,
-            int valueIndex) {
-        mTag = tag;
-        mCr = cr;
-        mLength = length;
-        mValueIndex = valueIndex;
-        mRawValue = data;
-    }
-
-    public int getTag() {
-        return mTag;
-    }
-
-    public boolean isComprehensionRequired() {
-        return mCr;
-    }
-
-    public int getLength() {
-        return mLength;
-    }
-
-    public int getValueIndex() {
-        return mValueIndex;
-    }
-
-    public byte[] getRawValue() {
-        return mRawValue;
-    }
-
-    /**
-     * Parses a list of COMPREHENSION-TLV objects from a byte array.
-     *
-     * @param data A byte array containing data to be parsed
-     * @param startIndex Index in data at which to start parsing
-     * @return A list of COMPREHENSION-TLV objects parsed
-     * @throws ResultException
-     */
-    public static List<ComprehensionTlv> decodeMany(byte[] data, int startIndex)
-            throws ResultException {
-        ArrayList<ComprehensionTlv> items = new ArrayList<ComprehensionTlv>();
-        int endIndex = data.length;
-        while (startIndex < endIndex) {
-            ComprehensionTlv ctlv = ComprehensionTlv.decode(data, startIndex);
-            if (ctlv != null) {
-                items.add(ctlv);
-                startIndex = ctlv.mValueIndex + ctlv.mLength;
-            } else {
-                CatLog.d(LOG_TAG, "decodeMany: ctlv is null, stop decoding");
-                break;
-            }
-        }
-
-        return items;
-    }
-
-    /**
-     * Parses an COMPREHENSION-TLV object from a byte array.
-     *
-     * @param data A byte array containing data to be parsed
-     * @param startIndex Index in data at which to start parsing
-     * @return A COMPREHENSION-TLV object parsed
-     * @throws ResultException
-     */
-    public static ComprehensionTlv decode(byte[] data, int startIndex)
-            throws ResultException {
-        int curIndex = startIndex;
-        int endIndex = data.length;
-
-        try {
-            /* tag */
-            int tag;
-            boolean cr; // Comprehension required flag
-            int temp = data[curIndex++] & 0xff;
-            switch (temp) {
-            case 0:
-            case 0xff:
-            case 0x80:
-                Log.d("CAT     ", "decode: unexpected first tag byte=" + Integer.toHexString(temp) +
-                        ", startIndex=" + startIndex + " curIndex=" + curIndex +
-                        " endIndex=" + endIndex);
-                // Return null which will stop decoding, this has occurred
-                // with Ghana MTN simcard and JDI simcard.
-                return null;
-
-            case 0x7f: // tag is in three-byte format
-                tag = ((data[curIndex] & 0xff) << 8)
-                        | (data[curIndex + 1] & 0xff);
-                cr = (tag & 0x8000) != 0;
-                tag &= ~0x8000;
-                curIndex += 2;
-                break;
-
-            default: // tag is in single-byte format
-                tag = temp;
-                cr = (tag & 0x80) != 0;
-                tag &= ~0x80;
-                break;
-            }
-
-            /* length */
-            int length;
-            temp = data[curIndex++] & 0xff;
-            if (temp < 0x80) {
-                length = temp;
-            } else if (temp == 0x81) {
-                length = data[curIndex++] & 0xff;
-                if (length < 0x80) {
-                    throw new ResultException(
-                            ResultCode.CMD_DATA_NOT_UNDERSTOOD,
-                            "length < 0x80 length=" + Integer.toHexString(length) +
-                            " startIndex=" + startIndex + " curIndex=" + curIndex +
-                            " endIndex=" + endIndex);
-                }
-            } else if (temp == 0x82) {
-                length = ((data[curIndex] & 0xff) << 8)
-                        | (data[curIndex + 1] & 0xff);
-                curIndex += 2;
-                if (length < 0x100) {
-                    throw new ResultException(
-                            ResultCode.CMD_DATA_NOT_UNDERSTOOD,
-                            "two byte length < 0x100 length=" + Integer.toHexString(length) +
-                            " startIndex=" + startIndex + " curIndex=" + curIndex +
-                            " endIndex=" + endIndex);
-                }
-            } else if (temp == 0x83) {
-                length = ((data[curIndex] & 0xff) << 16)
-                        | ((data[curIndex + 1] & 0xff) << 8)
-                        | (data[curIndex + 2] & 0xff);
-                curIndex += 3;
-                if (length < 0x10000) {
-                    throw new ResultException(
-                            ResultCode.CMD_DATA_NOT_UNDERSTOOD,
-                            "three byte length < 0x10000 length=0x" + Integer.toHexString(length) +
-                            " startIndex=" + startIndex + " curIndex=" + curIndex +
-                            " endIndex=" + endIndex);
-                }
-            } else {
-                throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD,
-                        "Bad length modifer=" + temp +
-                        " startIndex=" + startIndex + " curIndex=" + curIndex +
-                        " endIndex=" + endIndex);
-
-            }
-
-            return new ComprehensionTlv(tag, cr, length, data, curIndex);
-
-        } catch (IndexOutOfBoundsException e) {
-            throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD,
-                    "IndexOutOfBoundsException" + " startIndex=" + startIndex +
-                    " curIndex=" + curIndex + " endIndex=" + endIndex);
-        }
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/ComprehensionTlvTag.java b/telephony/java/com/android/internal/telephony/cat/ComprehensionTlvTag.java
deleted file mode 100644
index 973dbc8..0000000
--- a/telephony/java/com/android/internal/telephony/cat/ComprehensionTlvTag.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2011 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.internal.telephony.cat;
-
-/**
- * Enumeration for representing the tag value of COMPREHENSION-TLV objects. If
- * you want to get the actual value, call {@link #value() value} method.
- *
- * {@hide}
- */
-public enum ComprehensionTlvTag {
-    COMMAND_DETAILS(0x01),
-    DEVICE_IDENTITIES(0x02),
-    RESULT(0x03),
-    DURATION(0x04),
-    ALPHA_ID(0x05),
-    ADDRESS(0x06),
-    USSD_STRING(0x0a),
-    SMS_TPDU(0x0b),
-    TEXT_STRING(0x0d),
-    TONE(0x0e),
-    ITEM(0x0f),
-    ITEM_ID(0x10),
-    RESPONSE_LENGTH(0x11),
-    FILE_LIST(0x12),
-    HELP_REQUEST(0x15),
-    DEFAULT_TEXT(0x17),
-    EVENT_LIST(0x19),
-    ICON_ID(0x1e),
-    ITEM_ICON_ID_LIST(0x1f),
-    IMMEDIATE_RESPONSE(0x2b),
-    LANGUAGE(0x2d),
-    URL(0x31),
-    BROWSER_TERMINATION_CAUSE(0x34),
-    TEXT_ATTRIBUTE(0x50);
-
-    private int mValue;
-
-    ComprehensionTlvTag(int value) {
-        mValue = value;
-    }
-
-    /**
-     * Returns the actual value of this COMPREHENSION-TLV object.
-     *
-     * @return Actual tag value of this object
-     */
-    public int value() {
-        return mValue;
-    }
-
-    public static ComprehensionTlvTag fromInt(int value) {
-        for (ComprehensionTlvTag e : ComprehensionTlvTag.values()) {
-            if (e.mValue == value) {
-                return e;
-            }
-        }
-        return null;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/Duration.java b/telephony/java/com/android/internal/telephony/cat/Duration.java
deleted file mode 100644
index e8cd404..0000000
--- a/telephony/java/com/android/internal/telephony/cat/Duration.java
+++ /dev/null
@@ -1,79 +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.internal.telephony.cat;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-
-/**
- * Class for representing "Duration" object for CAT.
- *
- * {@hide}
- */
-public class Duration implements Parcelable {
-    public int timeInterval;
-    public TimeUnit timeUnit;
-
-    public enum TimeUnit {
-        MINUTE(0x00),
-        SECOND(0x01),
-        TENTH_SECOND(0x02);
-
-        private int mValue;
-
-        TimeUnit(int value) {
-            mValue = value;
-        }
-
-        public int value() {
-            return mValue;
-        }
-    }
-
-    /**
-     * @param timeInterval Between 1 and 255 inclusive.
-     */
-    public Duration(int timeInterval, TimeUnit timeUnit) {
-        this.timeInterval = timeInterval;
-        this.timeUnit = timeUnit;
-    }
-
-    private Duration(Parcel in) {
-        timeInterval = in.readInt();
-        timeUnit = TimeUnit.values()[in.readInt()];
-    }
-
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(timeInterval);
-        dest.writeInt(timeUnit.ordinal());
-    }
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<Duration> CREATOR = new Parcelable.Creator<Duration>() {
-        public Duration createFromParcel(Parcel in) {
-            return new Duration(in);
-        }
-
-        public Duration[] newArray(int size) {
-            return new Duration[size];
-        }
-    };
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/FontSize.java b/telephony/java/com/android/internal/telephony/cat/FontSize.java
deleted file mode 100644
index 02c7ea0..0000000
--- a/telephony/java/com/android/internal/telephony/cat/FontSize.java
+++ /dev/null
@@ -1,50 +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.internal.telephony.cat;
-
-
-/**
- * Enumeration for representing text font size.
- *
- * {@hide}
- */
-public enum FontSize {
-    NORMAL(0x0),
-    LARGE(0x1),
-    SMALL(0x2);
-
-    private int mValue;
-
-    FontSize(int value) {
-        mValue = value;
-    }
-
-    /**
-     * Create a FontSize object.
-     * @param value Integer value to be converted to a FontSize object.
-     * @return FontSize object whose value is {@code value}. If no
-     *         FontSize object has that value, null is returned.
-     */
-    public static FontSize fromInt(int value) {
-        for (FontSize e : FontSize.values()) {
-            if (e.mValue == value) {
-                return e;
-            }
-        }
-        return null;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/IconLoader.java b/telephony/java/com/android/internal/telephony/cat/IconLoader.java
deleted file mode 100644
index 2fa1811..0000000
--- a/telephony/java/com/android/internal/telephony/cat/IconLoader.java
+++ /dev/null
@@ -1,362 +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.internal.telephony.cat;
-
-import com.android.internal.telephony.IccFileHandler;
-
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-import java.util.HashMap;
-
-/**
- * Class for loading icons from the SIM card. Has two states: single, for loading
- * one icon. Multi, for loading icons list.
- *
- */
-class IconLoader extends Handler {
-    // members
-    private int mState = STATE_SINGLE_ICON;
-    private ImageDescriptor mId = null;
-    private Bitmap mCurrentIcon = null;
-    private int mRecordNumber;
-    private IccFileHandler mSimFH = null;
-    private Message mEndMsg = null;
-    private byte[] mIconData = null;
-    // multi icons state members
-    private int[] mRecordNumbers = null;
-    private int mCurrentRecordIndex = 0;
-    private Bitmap[] mIcons = null;
-    private HashMap<Integer, Bitmap> mIconsCache = null;
-
-    private static IconLoader sLoader = null;
-
-    // Loader state values.
-    private static final int STATE_SINGLE_ICON = 1;
-    private static final int STATE_MULTI_ICONS = 2;
-
-    // Finished loading single record from a linear-fixed EF-IMG.
-    private static final int EVENT_READ_EF_IMG_RECOED_DONE  = 1;
-    // Finished loading single icon from a Transparent DF-Graphics.
-    private static final int EVENT_READ_ICON_DONE           = 2;
-    // Finished loading single colour icon lookup table.
-    private static final int EVENT_READ_CLUT_DONE           = 3;
-
-    // Color lookup table offset inside the EF.
-    private static final int CLUT_LOCATION_OFFSET = 4;
-    // CLUT entry size, {Red, Green, Black}
-    private static final int CLUT_ENTRY_SIZE = 3;
-
-
-    private IconLoader(Looper looper , IccFileHandler fh) {
-        super(looper);
-        mSimFH = fh;
-
-        mIconsCache = new HashMap<Integer, Bitmap>(50);
-    }
-
-    static IconLoader getInstance(Handler caller, IccFileHandler fh) {
-        if (sLoader != null) {
-            return sLoader;
-        }
-        if (fh != null) {
-            HandlerThread thread = new HandlerThread("Cat Icon Loader");
-            thread.start();
-            return new IconLoader(thread.getLooper(), fh);
-        }
-        return null;
-    }
-
-    void loadIcons(int[] recordNumbers, Message msg) {
-        if (recordNumbers == null || recordNumbers.length == 0 || msg == null) {
-            return;
-        }
-        mEndMsg = msg;
-        // initialize multi icons load variables.
-        mIcons = new Bitmap[recordNumbers.length];
-        mRecordNumbers = recordNumbers;
-        mCurrentRecordIndex = 0;
-        mState = STATE_MULTI_ICONS;
-        startLoadingIcon(recordNumbers[0]);
-    }
-
-    void loadIcon(int recordNumber, Message msg) {
-        if (msg == null) {
-            return;
-        }
-        mEndMsg = msg;
-        mState = STATE_SINGLE_ICON;
-        startLoadingIcon(recordNumber);
-    }
-
-    private void startLoadingIcon(int recordNumber) {
-        // Reset the load variables.
-        mId = null;
-        mIconData = null;
-        mCurrentIcon = null;
-        mRecordNumber = recordNumber;
-
-        // make sure the icon was not already loaded and saved in the local cache.
-        if (mIconsCache.containsKey(recordNumber)) {
-            mCurrentIcon = mIconsCache.get(recordNumber);
-            postIcon();
-            return;
-        }
-
-        // start the first phase ==> loading Image Descriptor.
-        readId();
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-        AsyncResult ar;
-
-        try {
-            switch (msg.what) {
-            case EVENT_READ_EF_IMG_RECOED_DONE:
-                ar = (AsyncResult) msg.obj;
-                if (handleImageDescriptor((byte[]) ar.result)) {
-                    readIconData();
-                } else {
-                    throw new Exception("Unable to parse image descriptor");
-                }
-                break;
-            case EVENT_READ_ICON_DONE:
-                ar = (AsyncResult) msg.obj;
-                byte[] rawData = ((byte[]) ar.result);
-                if (mId.codingScheme == ImageDescriptor.CODING_SCHEME_BASIC) {
-                    mCurrentIcon = parseToBnW(rawData, rawData.length);
-                    mIconsCache.put(mRecordNumber, mCurrentIcon);
-                    postIcon();
-                } else if (mId.codingScheme == ImageDescriptor.CODING_SCHEME_COLOUR) {
-                    mIconData = rawData;
-                    readClut();
-                }
-                break;
-            case EVENT_READ_CLUT_DONE:
-                ar = (AsyncResult) msg.obj;
-                byte [] clut = ((byte[]) ar.result);
-                mCurrentIcon = parseToRGB(mIconData, mIconData.length,
-                        false, clut);
-                mIconsCache.put(mRecordNumber, mCurrentIcon);
-                postIcon();
-                break;
-            }
-        } catch (Exception e) {
-            CatLog.d(this, "Icon load failed");
-            // post null icon back to the caller.
-            postIcon();
-        }
-    }
-
-    /**
-     * Handles Image descriptor parsing and required processing. This is the
-     * first step required to handle retrieving icons from the SIM.
-     *
-     * @param data byte [] containing Image Instance descriptor as defined in
-     * TS 51.011.
-     */
-    private boolean handleImageDescriptor(byte[] rawData) {
-        mId = ImageDescriptor.parse(rawData, 1);
-        if (mId == null) {
-            return false;
-        }
-        return true;
-    }
-
-    // Start reading colour lookup table from SIM card.
-    private void readClut() {
-        int length = mIconData[3] * CLUT_ENTRY_SIZE;
-        Message msg = this.obtainMessage(EVENT_READ_CLUT_DONE);
-        mSimFH.loadEFImgTransparent(mId.imageId,
-                mIconData[CLUT_LOCATION_OFFSET],
-                mIconData[CLUT_LOCATION_OFFSET + 1], length, msg);
-    }
-
-    // Start reading Image Descriptor from SIM card.
-    private void readId() {
-        if (mRecordNumber < 0) {
-            mCurrentIcon = null;
-            postIcon();
-            return;
-        }
-        Message msg = this.obtainMessage(EVENT_READ_EF_IMG_RECOED_DONE);
-        mSimFH.loadEFImgLinearFixed(mRecordNumber, msg);
-    }
-
-    // Start reading icon bytes array from SIM card.
-    private void readIconData() {
-        Message msg = this.obtainMessage(EVENT_READ_ICON_DONE);
-        mSimFH.loadEFImgTransparent(mId.imageId, 0, 0, mId.length ,msg);
-    }
-
-    // When all is done pass icon back to caller.
-    private void postIcon() {
-        if (mState == STATE_SINGLE_ICON) {
-            mEndMsg.obj = mCurrentIcon;
-            mEndMsg.sendToTarget();
-        } else if (mState == STATE_MULTI_ICONS) {
-            mIcons[mCurrentRecordIndex++] = mCurrentIcon;
-            // If not all icons were loaded, start loading the next one.
-            if (mCurrentRecordIndex < mRecordNumbers.length) {
-                startLoadingIcon(mRecordNumbers[mCurrentRecordIndex]);
-            } else {
-                mEndMsg.obj = mIcons;
-                mEndMsg.sendToTarget();
-            }
-        }
-    }
-
-    /**
-     * Convert a TS 131.102 image instance of code scheme '11' into Bitmap
-     * @param data The raw data
-     * @param length The length of image body
-     * @return The bitmap
-     */
-    public static Bitmap parseToBnW(byte[] data, int length){
-        int valueIndex = 0;
-        int width = data[valueIndex++] & 0xFF;
-        int height = data[valueIndex++] & 0xFF;
-        int numOfPixels = width*height;
-
-        int[] pixels = new int[numOfPixels];
-
-        int pixelIndex = 0;
-        int bitIndex = 7;
-        byte currentByte = 0x00;
-        while (pixelIndex < numOfPixels) {
-            // reassign data and index for every byte (8 bits).
-            if (pixelIndex % 8 == 0) {
-                currentByte = data[valueIndex++];
-                bitIndex = 7;
-            }
-            pixels[pixelIndex++] = bitToBnW((currentByte >> bitIndex-- ) & 0x01);
-        }
-
-        if (pixelIndex != numOfPixels) {
-            CatLog.d("IconLoader", "parseToBnW; size error");
-        }
-        return Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888);
-    }
-
-    /**
-     * Decode one bit to a black and white color:
-     * 0 is black
-     * 1 is white
-     * @param bit to decode
-     * @return RGB color
-     */
-    private static int bitToBnW(int bit){
-        if(bit == 1){
-            return Color.WHITE;
-        } else {
-            return Color.BLACK;
-        }
-    }
-
-    /**
-     * a TS 131.102 image instance of code scheme '11' into color Bitmap
-     *
-     * @param data The raw data
-     * @param length the length of image body
-     * @param transparency with or without transparency
-     * @param clut coulor lookup table
-     * @return The color bitmap
-     */
-    public static Bitmap parseToRGB(byte[] data, int length,
-            boolean transparency, byte[] clut) {
-        int valueIndex = 0;
-        int width = data[valueIndex++] & 0xFF;
-        int height = data[valueIndex++] & 0xFF;
-        int bitsPerImg = data[valueIndex++] & 0xFF;
-        int numOfClutEntries = data[valueIndex++] & 0xFF;
-
-        if (true == transparency) {
-            clut[numOfClutEntries - 1] = Color.TRANSPARENT;
-        }
-
-        int numOfPixels = width * height;
-        int[] pixels = new int[numOfPixels];
-
-        valueIndex = 6;
-        int pixelIndex = 0;
-        int bitsStartOffset = 8 - bitsPerImg;
-        int bitIndex = bitsStartOffset;
-        byte currentByte = data[valueIndex++];
-        int mask = getMask(bitsPerImg);
-        boolean bitsOverlaps = (8 % bitsPerImg == 0);
-        while (pixelIndex < numOfPixels) {
-            // reassign data and index for every byte (8 bits).
-            if (bitIndex < 0) {
-                currentByte = data[valueIndex++];
-                bitIndex = bitsOverlaps ? (bitsStartOffset) : (bitIndex * -1);
-            }
-            int clutEntry = ((currentByte >> bitIndex) & mask);
-            int clutIndex = clutEntry * CLUT_ENTRY_SIZE;
-            pixels[pixelIndex++] = Color.rgb(clut[clutIndex],
-                    clut[clutIndex + 1], clut[clutIndex + 2]);
-            bitIndex -= bitsPerImg;
-        }
-
-        return Bitmap.createBitmap(pixels, width, height,
-                Bitmap.Config.ARGB_8888);
-    }
-
-    /**
-     * Calculate bit mask for a given number of bits. The mask should enable to
-     * make a bitwise and to the given number of bits.
-     * @param numOfBits number of bits to calculate mask for.
-     * @return bit mask
-     */
-    private static int getMask(int numOfBits) {
-        int mask = 0x00;
-
-        switch (numOfBits) {
-        case 1:
-            mask = 0x01;
-            break;
-        case 2:
-            mask = 0x03;
-            break;
-        case 3:
-            mask = 0x07;
-            break;
-        case 4:
-            mask = 0x0F;
-            break;
-        case 5:
-            mask = 0x1F;
-            break;
-        case 6:
-            mask = 0x3F;
-            break;
-        case 7:
-            mask = 0x7F;
-            break;
-        case 8:
-            mask = 0xFF;
-            break;
-        }
-        return mask;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/ImageDescriptor.java b/telephony/java/com/android/internal/telephony/cat/ImageDescriptor.java
deleted file mode 100644
index 711d977..0000000
--- a/telephony/java/com/android/internal/telephony/cat/ImageDescriptor.java
+++ /dev/null
@@ -1,77 +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.internal.telephony.cat;
-
-/**
- * {@hide}
- */
-public class ImageDescriptor {
-    // members
-    int width;
-    int height;
-    int codingScheme;
-    int imageId;
-    int highOffset;
-    int lowOffset;
-    int length;
-
-    // constants
-    static final int CODING_SCHEME_BASIC = 0x11;
-    static final int CODING_SCHEME_COLOUR = 0x21;
-
-    // public static final int ID_LENGTH = 9;
-    // ID_LENGTH substituted by IccFileHandlerBase.GET_RESPONSE_EF_IMG_SIZE_BYTES
-
-    ImageDescriptor() {
-        width = 0;
-        height = 0;
-        codingScheme = 0;
-        imageId = 0;
-        highOffset = 0;
-        lowOffset = 0;
-        length = 0;
-    }
-
-    /**
-     * Extract descriptor information about image instance.
-     *
-     * @param rawData
-     * @param valueIndex
-     * @return ImageDescriptor
-     */
-    static ImageDescriptor parse(byte[] rawData, int valueIndex) {
-        ImageDescriptor d = new ImageDescriptor();
-        try {
-            d.width = rawData[valueIndex++] & 0xff;
-            d.height = rawData[valueIndex++] & 0xff;
-            d.codingScheme = rawData[valueIndex++] & 0xff;
-
-            // parse image id
-            d.imageId = (rawData[valueIndex++] & 0xff) << 8;
-            d.imageId |= rawData[valueIndex++] & 0xff;
-            // parse offset
-            d.highOffset = (rawData[valueIndex++] & 0xff); // high byte offset
-            d.lowOffset = rawData[valueIndex++] & 0xff; // low byte offset
-
-            d.length = ((rawData[valueIndex++] & 0xff) << 8 | (rawData[valueIndex++] & 0xff));
-        } catch (IndexOutOfBoundsException e) {
-            CatLog.d("ImageDescripter", "parse; failed parsing image descriptor");
-            d = null;
-        }
-        return d;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/Input.java b/telephony/java/com/android/internal/telephony/cat/Input.java
deleted file mode 100644
index 13a5ad4..0000000
--- a/telephony/java/com/android/internal/telephony/cat/Input.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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.internal.telephony.cat;
-
-import android.graphics.Bitmap;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Container class for CAT GET INPUT, GET IN KEY commands parameters.
- *
- */
-public class Input implements Parcelable {
-    public String text;
-    public String defaultText;
-    public Bitmap icon;
-    public int minLen;
-    public int maxLen;
-    public boolean ucs2;
-    public boolean packed;
-    public boolean digitOnly;
-    public boolean echo;
-    public boolean yesNo;
-    public boolean helpAvailable;
-    public Duration duration;
-
-    Input() {
-        text = "";
-        defaultText = null;
-        icon = null;
-        minLen = 0;
-        maxLen = 1;
-        ucs2 = false;
-        packed = false;
-        digitOnly = false;
-        echo = false;
-        yesNo = false;
-        helpAvailable = false;
-        duration = null;
-    }
-
-    private Input(Parcel in) {
-        text = in.readString();
-        defaultText = in.readString();
-        icon = in.readParcelable(null);
-        minLen = in.readInt();
-        maxLen = in.readInt();
-        ucs2 = in.readInt() == 1 ? true : false;
-        packed = in.readInt() == 1 ? true : false;
-        digitOnly = in.readInt() == 1 ? true : false;
-        echo = in.readInt() == 1 ? true : false;
-        yesNo = in.readInt() == 1 ? true : false;
-        helpAvailable = in.readInt() == 1 ? true : false;
-        duration = in.readParcelable(null);
-    }
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(text);
-        dest.writeString(defaultText);
-        dest.writeParcelable(icon, 0);
-        dest.writeInt(minLen);
-        dest.writeInt(maxLen);
-        dest.writeInt(ucs2 ? 1 : 0);
-        dest.writeInt(packed ? 1 : 0);
-        dest.writeInt(digitOnly ? 1 : 0);
-        dest.writeInt(echo ? 1 : 0);
-        dest.writeInt(yesNo ? 1 : 0);
-        dest.writeInt(helpAvailable ? 1 : 0);
-        dest.writeParcelable(duration, 0);
-    }
-
-    public static final Parcelable.Creator<Input> CREATOR = new Parcelable.Creator<Input>() {
-        public Input createFromParcel(Parcel in) {
-            return new Input(in);
-        }
-
-        public Input[] newArray(int size) {
-            return new Input[size];
-        }
-    };
-
-    boolean setIcon(Bitmap Icon) { return true; }
-}
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/cat/Item.java b/telephony/java/com/android/internal/telephony/cat/Item.java
deleted file mode 100644
index d4702bb..0000000
--- a/telephony/java/com/android/internal/telephony/cat/Item.java
+++ /dev/null
@@ -1,71 +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.internal.telephony.cat;
-
-import android.graphics.Bitmap;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Represents an Item COMPREHENSION-TLV object.
- *
- * {@hide}
- */
-public class Item implements Parcelable {
-    /** Identifier of the item. */
-    public int id;
-    /** Text string of the item. */
-    public String text;
-    /** Icon of the item */
-    public Bitmap icon;
-
-    public Item(int id, String text) {
-        this.id = id;
-        this.text = text;
-        this.icon = null;
-    }
-
-    public Item(Parcel in) {
-        id = in.readInt();
-        text = in.readString();
-        icon = in.readParcelable(null);
-    }
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(id);
-        dest.writeString(text);
-        dest.writeParcelable(icon, flags);
-    }
-
-    public static final Parcelable.Creator<Item> CREATOR = new Parcelable.Creator<Item>() {
-        public Item createFromParcel(Parcel in) {
-            return new Item(in);
-        }
-
-        public Item[] newArray(int size) {
-            return new Item[size];
-        }
-    };
-
-    public String toString() {
-        return text;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/LaunchBrowserMode.java b/telephony/java/com/android/internal/telephony/cat/LaunchBrowserMode.java
deleted file mode 100644
index af043d1..0000000
--- a/telephony/java/com/android/internal/telephony/cat/LaunchBrowserMode.java
+++ /dev/null
@@ -1,35 +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.internal.telephony.cat;
-
-
-/**
- * Browser launch mode for LAUNCH BROWSER proactive command.
- *
- * {@hide}
- */
-public enum LaunchBrowserMode {
-    /** Launch browser if not already launched. */
-    LAUNCH_IF_NOT_ALREADY_LAUNCHED,
-    /**
-     * Use the existing browser (the browser shall not use the active existing
-     * secured session).
-     */
-    USE_EXISTING_BROWSER,
-    /** Close the existing browser session and launch new browser session. */
-    LAUNCH_NEW_BROWSER;
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/Menu.java b/telephony/java/com/android/internal/telephony/cat/Menu.java
deleted file mode 100644
index 7bbae01..0000000
--- a/telephony/java/com/android/internal/telephony/cat/Menu.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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.internal.telephony.cat;
-
-import android.graphics.Bitmap;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Container class for CAT menu (SET UP MENU, SELECT ITEM) parameters.
- *
- */
-public class Menu implements Parcelable {
-    public List<Item> items;
-    public List<TextAttribute> titleAttrs;
-    public PresentationType presentationType;
-    public String title;
-    public Bitmap titleIcon;
-    public int defaultItem;
-    public boolean softKeyPreferred;
-    public boolean helpAvailable;
-    public boolean titleIconSelfExplanatory;
-    public boolean itemsIconSelfExplanatory;
-
-    public Menu() {
-        // Create an empty list.
-        items = new ArrayList<Item>();
-        title = null;
-        titleAttrs = null;
-        defaultItem = 0;
-        softKeyPreferred = false;
-        helpAvailable = false;
-        titleIconSelfExplanatory = false;
-        itemsIconSelfExplanatory = false;
-        titleIcon = null;
-        // set default style to be navigation menu.
-        presentationType = PresentationType.NAVIGATION_OPTIONS;
-    }
-
-    private Menu(Parcel in) {
-        title = in.readString();
-        titleIcon = in.readParcelable(null);
-        // rebuild items list.
-        items = new ArrayList<Item>();
-        int size = in.readInt();
-        for (int i=0; i<size; i++) {
-            Item item = in.readParcelable(null);
-            items.add(item);
-        }
-        defaultItem = in.readInt();
-        softKeyPreferred = in.readInt() == 1 ? true : false;
-        helpAvailable = in.readInt() == 1 ? true : false;
-        titleIconSelfExplanatory = in.readInt() == 1 ? true : false;
-        itemsIconSelfExplanatory = in.readInt() == 1 ? true : false;
-        presentationType = PresentationType.values()[in.readInt()];
-    }
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(title);
-        dest.writeParcelable(titleIcon, flags);
-        // write items list to the parcel.
-        int size = items.size();
-        dest.writeInt(size);
-        for (int i=0; i<size; i++) {
-            dest.writeParcelable(items.get(i), flags);
-        }
-        dest.writeInt(defaultItem);
-        dest.writeInt(softKeyPreferred ? 1 : 0);
-        dest.writeInt(helpAvailable ? 1 : 0);
-        dest.writeInt(titleIconSelfExplanatory ? 1 : 0);
-        dest.writeInt(itemsIconSelfExplanatory ? 1 : 0);
-        dest.writeInt(presentationType.ordinal());
-    }
-
-    public static final Parcelable.Creator<Menu> CREATOR = new Parcelable.Creator<Menu>() {
-        public Menu createFromParcel(Parcel in) {
-            return new Menu(in);
-        }
-
-        public Menu[] newArray(int size) {
-            return new Menu[size];
-        }
-    };
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/PresentationType.java b/telephony/java/com/android/internal/telephony/cat/PresentationType.java
deleted file mode 100644
index 7c8cd8c..0000000
--- a/telephony/java/com/android/internal/telephony/cat/PresentationType.java
+++ /dev/null
@@ -1,32 +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.internal.telephony.cat;
-
-
-/**
- * Presentation types for SELECT TYPE proactive command.
- *
- * {@hide}
- */
-public enum PresentationType {
-    /** Presentation type is not specified */
-    NOT_SPECIFIED,
-    /** Presentation as a choice of data values */
-    DATA_VALUES,
-    /** Presentation as a choice of navigation options */
-    NAVIGATION_OPTIONS;
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/ResponseData.java b/telephony/java/com/android/internal/telephony/cat/ResponseData.java
deleted file mode 100644
index 1157c1a..0000000
--- a/telephony/java/com/android/internal/telephony/cat/ResponseData.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (C) 2006-2007 Google Inc.
- *
- * 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.internal.telephony.cat;
-
-import com.android.internal.telephony.EncodeException;
-import com.android.internal.telephony.GsmAlphabet;
-import java.util.Calendar;
-import java.util.TimeZone;
-import android.os.SystemProperties;
-import android.text.TextUtils;
-
-import com.android.internal.telephony.cat.AppInterface.CommandType;
-
-import java.io.ByteArrayOutputStream;
-import java.io.UnsupportedEncodingException;
-
-abstract class ResponseData {
-    /**
-     * Format the data appropriate for TERMINAL RESPONSE and write it into
-     * the ByteArrayOutputStream object.
-     */
-    public abstract void format(ByteArrayOutputStream buf);
-
-    public static void writeLength(ByteArrayOutputStream buf, int length) {
-        // As per ETSI 102.220 Sec7.1.2, if the total length is greater
-        // than 0x7F, it should be coded in two bytes and the first byte
-        // should be 0x81.
-        if (length > 0x7F) {
-            buf.write(0x81);
-        }
-        buf.write(length);
-    }
-}
-
-class SelectItemResponseData extends ResponseData {
-    // members
-    private int id;
-
-    public SelectItemResponseData(int id) {
-        super();
-        this.id = id;
-    }
-
-    @Override
-    public void format(ByteArrayOutputStream buf) {
-        // Item identifier object
-        int tag = 0x80 | ComprehensionTlvTag.ITEM_ID.value();
-        buf.write(tag); // tag
-        buf.write(1); // length
-        buf.write(id); // identifier of item chosen
-    }
-}
-
-class GetInkeyInputResponseData extends ResponseData {
-    // members
-    private boolean mIsUcs2;
-    private boolean mIsPacked;
-    private boolean mIsYesNo;
-    private boolean mYesNoResponse;
-    public String mInData;
-
-    // GetInKey Yes/No response characters constants.
-    protected static final byte GET_INKEY_YES = 0x01;
-    protected static final byte GET_INKEY_NO = 0x00;
-
-    public GetInkeyInputResponseData(String inData, boolean ucs2, boolean packed) {
-        super();
-        this.mIsUcs2 = ucs2;
-        this.mIsPacked = packed;
-        this.mInData = inData;
-        this.mIsYesNo = false;
-    }
-
-    public GetInkeyInputResponseData(boolean yesNoResponse) {
-        super();
-        this.mIsUcs2 = false;
-        this.mIsPacked = false;
-        this.mInData = "";
-        this.mIsYesNo = true;
-        this.mYesNoResponse = yesNoResponse;
-    }
-
-    @Override
-    public void format(ByteArrayOutputStream buf) {
-        if (buf == null) {
-            return;
-        }
-
-        // Text string object
-        int tag = 0x80 | ComprehensionTlvTag.TEXT_STRING.value();
-        buf.write(tag); // tag
-
-        byte[] data;
-
-        if (mIsYesNo) {
-            data = new byte[1];
-            data[0] = mYesNoResponse ? GET_INKEY_YES : GET_INKEY_NO;
-        } else if (mInData != null && mInData.length() > 0) {
-            try {
-                if (mIsUcs2) {
-                    data = mInData.getBytes("UTF-16");
-                } else if (mIsPacked) {
-                    int size = mInData.length();
-
-                    byte[] tempData = GsmAlphabet
-                            .stringToGsm7BitPacked(mInData, 0, 0);
-                    data = new byte[size];
-                    // Since stringToGsm7BitPacked() set byte 0 in the
-                    // returned byte array to the count of septets used...
-                    // copy to a new array without byte 0.
-                    System.arraycopy(tempData, 1, data, 0, size);
-                } else {
-                    data = GsmAlphabet.stringToGsm8BitPacked(mInData);
-                }
-            } catch (UnsupportedEncodingException e) {
-                data = new byte[0];
-            } catch (EncodeException e) {
-                data = new byte[0];
-            }
-        } else {
-            data = new byte[0];
-        }
-
-        // length - one more for data coding scheme.
-        writeLength(buf, data.length + 1);
-
-        // data coding scheme
-        if (mIsUcs2) {
-            buf.write(0x08); // UCS2
-        } else if (mIsPacked) {
-            buf.write(0x00); // 7 bit packed
-        } else {
-            buf.write(0x04); // 8 bit unpacked
-        }
-
-        for (byte b : data) {
-            buf.write(b);
-        }
-    }
-}
-
-// For "PROVIDE LOCAL INFORMATION" command.
-// See TS 31.111 section 6.4.15/ETSI TS 102 223
-// TS 31.124 section 27.22.4.15 for test spec
-class LanguageResponseData extends ResponseData {
-    private String lang;
-
-    public LanguageResponseData(String lang) {
-        super();
-        this.lang = lang;
-    }
-
-    @Override
-    public void format(ByteArrayOutputStream buf) {
-        if (buf == null) {
-            return;
-        }
-
-        // Text string object
-        int tag = 0x80 | ComprehensionTlvTag.LANGUAGE.value();
-        buf.write(tag); // tag
-
-        byte[] data;
-
-        if (lang != null && lang.length() > 0) {
-            data = GsmAlphabet.stringToGsm8BitPacked(lang);
-        }
-        else {
-            data = new byte[0];
-        }
-
-        buf.write(data.length);
-
-        for (byte b : data) {
-            buf.write(b);
-        }
-    }
-}
-
-// For "PROVIDE LOCAL INFORMATION" command.
-// See TS 31.111 section 6.4.15/ETSI TS 102 223
-// TS 31.124 section 27.22.4.15 for test spec
-class DTTZResponseData extends ResponseData {
-    private Calendar calendar;
-
-    public DTTZResponseData(Calendar cal) {
-        super();
-        calendar = cal;
-    }
-
-    @Override
-    public void format(ByteArrayOutputStream buf) {
-        if (buf == null) {
-            return;
-        }
-
-        // DTTZ object
-        int tag = 0x80 | CommandType.PROVIDE_LOCAL_INFORMATION.value();
-        buf.write(tag); // tag
-
-        byte[] data = new byte[8];
-
-        data[0] = 0x07; // Write length of DTTZ data
-
-        if (calendar == null) {
-            calendar = Calendar.getInstance();
-        }
-        // Fill year byte
-        data[1] = byteToBCD(calendar.get(java.util.Calendar.YEAR) % 100);
-
-        // Fill month byte
-        data[2] = byteToBCD(calendar.get(java.util.Calendar.MONTH) + 1);
-
-        // Fill day byte
-        data[3] = byteToBCD(calendar.get(java.util.Calendar.DATE));
-
-        // Fill hour byte
-        data[4] = byteToBCD(calendar.get(java.util.Calendar.HOUR_OF_DAY));
-
-        // Fill minute byte
-        data[5] = byteToBCD(calendar.get(java.util.Calendar.MINUTE));
-
-        // Fill second byte
-        data[6] = byteToBCD(calendar.get(java.util.Calendar.SECOND));
-
-        String tz = SystemProperties.get("persist.sys.timezone", "");
-        if (TextUtils.isEmpty(tz)) {
-            data[7] = (byte) 0xFF;    // set FF in terminal response
-        } else {
-            TimeZone zone = TimeZone.getTimeZone(tz);
-            int zoneOffset = zone.getRawOffset() + zone.getDSTSavings();
-            data[7] = getTZOffSetByte(zoneOffset);
-        }
-
-        for (byte b : data) {
-            buf.write(b);
-        }
-    }
-
-    private byte byteToBCD(int value) {
-        if (value < 0 && value > 99) {
-            CatLog.d(this, "Err: byteToBCD conversion Value is " + value +
-                           " Value has to be between 0 and 99");
-            return 0;
-        }
-
-        return (byte) ((value / 10) | ((value % 10) << 4));
-    }
-
-    private byte getTZOffSetByte(long offSetVal) {
-        boolean isNegative = (offSetVal < 0);
-
-        /*
-         * The 'offSetVal' is in milliseconds. Convert it to hours and compute
-         * offset While sending T.R to UICC, offset is expressed is 'quarters of
-         * hours'
-         */
-
-         long tzOffset = offSetVal / (15 * 60 * 1000);
-         tzOffset = (isNegative ? -1 : 1) * tzOffset;
-         byte bcdVal = byteToBCD((int) tzOffset);
-         // For negative offsets, put '1' in the msb
-         return isNegative ?  (bcdVal |= 0x08) : bcdVal;
-    }
-
-}
-
diff --git a/telephony/java/com/android/internal/telephony/cat/ResultCode.java b/telephony/java/com/android/internal/telephony/cat/ResultCode.java
deleted file mode 100644
index 8544175..0000000
--- a/telephony/java/com/android/internal/telephony/cat/ResultCode.java
+++ /dev/null
@@ -1,186 +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.internal.telephony.cat;
-
-
-/**
- * Enumeration for the return code in TERMINAL RESPONSE.
- * To get the actual return code for each enum value, call {@link #code() code}
- * method.
- *
- * {@hide}
- */
-public enum ResultCode {
-
-    /*
-     * Results '0X' and '1X' indicate that the command has been performed.
-     */
-
-    /** Command performed successfully */
-    OK(0x00),
-
-    /** Command performed with partial comprehension */
-    PRFRMD_WITH_PARTIAL_COMPREHENSION(0x01),
-
-    /** Command performed, with missing information */
-    PRFRMD_WITH_MISSING_INFO(0x02),
-
-    /** REFRESH performed with additional EFs read */
-    PRFRMD_WITH_ADDITIONAL_EFS_READ(0x03),
-
-    /**
-     * Command performed successfully, but requested icon could not be
-     * displayed
-     */
-    PRFRMD_ICON_NOT_DISPLAYED(0x04),
-
-    /** Command performed, but modified by call control by NAA */
-    PRFRMD_MODIFIED_BY_NAA(0x05),
-
-    /** Command performed successfully, limited service */
-    PRFRMD_LIMITED_SERVICE(0x06),
-
-    /** Command performed with modification */
-    PRFRMD_WITH_MODIFICATION(0x07),
-
-    /** REFRESH performed but indicated NAA was not active */
-    PRFRMD_NAA_NOT_ACTIVE(0x08),
-
-    /** Command performed successfully, tone not played */
-    PRFRMD_TONE_NOT_PLAYED(0x09),
-
-    /** Proactive UICC session terminated by the user */
-    UICC_SESSION_TERM_BY_USER(0x10),
-
-    /** Backward move in the proactive UICC session requested by the user */
-    BACKWARD_MOVE_BY_USER(0x11),
-
-    /** No response from user */
-    NO_RESPONSE_FROM_USER(0x12),
-
-    /** Help information required by the user */
-    HELP_INFO_REQUIRED(0x13),
-
-    /** USSD or SS transaction terminated by the user */
-    USSD_SS_SESSION_TERM_BY_USER(0x14),
-
-
-    /*
-     * Results '2X' indicate to the UICC that it may be worth re-trying the
-     * command at a later opportunity.
-     */
-
-    /** Terminal currently unable to process command */
-    TERMINAL_CRNTLY_UNABLE_TO_PROCESS(0x20),
-
-    /** Network currently unable to process command */
-    NETWORK_CRNTLY_UNABLE_TO_PROCESS(0x21),
-
-    /** User did not accept the proactive command */
-    USER_NOT_ACCEPT(0x22),
-
-    /** User cleared down call before connection or network release */
-    USER_CLEAR_DOWN_CALL(0x23),
-
-    /** Action in contradiction with the current timer state */
-    CONTRADICTION_WITH_TIMER(0x24),
-
-    /** Interaction with call control by NAA, temporary problem */
-    NAA_CALL_CONTROL_TEMPORARY(0x25),
-
-    /** Launch browser generic error code */
-    LAUNCH_BROWSER_ERROR(0x26),
-
-    /** MMS temporary problem. */
-    MMS_TEMPORARY(0x27),
-
-
-    /*
-     * Results '3X' indicate that it is not worth the UICC re-trying with an
-     * identical command, as it will only get the same response. However, the
-     * decision to retry lies with the application.
-     */
-
-    /** Command beyond terminal's capabilities */
-    BEYOND_TERMINAL_CAPABILITY(0x30),
-
-    /** Command type not understood by terminal */
-    CMD_TYPE_NOT_UNDERSTOOD(0x31),
-
-    /** Command data not understood by terminal */
-    CMD_DATA_NOT_UNDERSTOOD(0x32),
-
-    /** Command number not known by terminal */
-    CMD_NUM_NOT_KNOWN(0x33),
-
-    /** SS Return Error */
-    SS_RETURN_ERROR(0x34),
-
-    /** SMS RP-ERROR */
-    SMS_RP_ERROR(0x35),
-
-    /** Error, required values are missing */
-    REQUIRED_VALUES_MISSING(0x36),
-
-    /** USSD Return Error */
-    USSD_RETURN_ERROR(0x37),
-
-    /** MultipleCard commands error */
-    MULTI_CARDS_CMD_ERROR(0x38),
-
-    /**
-     * Interaction with call control by USIM or MO short message control by
-     * USIM, permanent problem
-     */
-    USIM_CALL_CONTROL_PERMANENT(0x39),
-
-    /** Bearer Independent Protocol error */
-    BIP_ERROR(0x3a),
-
-    /** Access Technology unable to process command */
-    ACCESS_TECH_UNABLE_TO_PROCESS(0x3b),
-
-    /** Frames error */
-    FRAMES_ERROR(0x3c),
-
-    /** MMS Error */
-    MMS_ERROR(0x3d);
-
-
-    private int mCode;
-
-    ResultCode(int code) {
-        mCode = code;
-    }
-
-    /**
-     * Retrieves the actual result code that this object represents.
-     * @return Actual result code
-     */
-    public int value() {
-        return mCode;
-    }
-
-    public static ResultCode fromInt(int value) {
-        for (ResultCode r : ResultCode.values()) {
-            if (r.mCode == value) {
-                return r;
-            }
-        }
-        return null;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/ResultException.java b/telephony/java/com/android/internal/telephony/cat/ResultException.java
deleted file mode 100644
index 84879c2..0000000
--- a/telephony/java/com/android/internal/telephony/cat/ResultException.java
+++ /dev/null
@@ -1,97 +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.internal.telephony.cat;
-
-
-/**
- * Class for errors in the Result object.
- *
- * {@hide}
- */
-public class ResultException extends CatException {
-    private ResultCode mResult;
-    private int mAdditionalInfo;
-    private String mExplanation;
-
-    public ResultException(ResultCode result) {
-        super();
-
-        // ETSI TS 102 223, 8.12 -- For the general results '20', '21', '26',
-        // '38', '39', '3A', '3C', and '3D', it is mandatory for the terminal
-        // to provide a specific cause value as additional information.
-        switch (result) {
-            case TERMINAL_CRNTLY_UNABLE_TO_PROCESS:    // 0x20
-            case NETWORK_CRNTLY_UNABLE_TO_PROCESS:     // 0x21
-            case LAUNCH_BROWSER_ERROR:                 // 0x26
-            case MULTI_CARDS_CMD_ERROR:                // 0x38
-            case USIM_CALL_CONTROL_PERMANENT:          // 0x39
-            case BIP_ERROR:                            // 0x3a
-            case FRAMES_ERROR:                         // 0x3c
-            case MMS_ERROR:                            // 0x3d
-                throw new AssertionError(
-                        "For result code, " + result +
-                        ", additional information must be given!");
-        }
-
-        mResult = result;
-        mAdditionalInfo = -1;
-        mExplanation = "";
-    }
-
-    public ResultException(ResultCode result, String explanation) {
-        this(result);
-        mExplanation = explanation;
-    }
-
-    public ResultException(ResultCode result, int additionalInfo) {
-        this(result);
-
-        if (additionalInfo < 0) {
-            throw new AssertionError(
-                    "Additional info must be greater than zero!");
-        }
-
-        mAdditionalInfo = additionalInfo;
-    }
-
-    public ResultException(ResultCode result, int additionalInfo, String explanation) {
-        this(result, additionalInfo);
-        mExplanation = explanation;
-    }
-
-    public ResultCode result() {
-        return mResult;
-    }
-
-    public boolean hasAdditionalInfo() {
-        return mAdditionalInfo >= 0;
-    }
-
-    public int additionalInfo() {
-        return mAdditionalInfo;
-    }
-
-    public String explanation() {
-        return mExplanation;
-    }
-
-    @Override
-    public String toString() {
-        return "result=" + mResult + " additionalInfo=" + mAdditionalInfo +
-                " explantion=" + mExplanation;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/RilMessageDecoder.java b/telephony/java/com/android/internal/telephony/cat/RilMessageDecoder.java
deleted file mode 100644
index fb33a8e..0000000
--- a/telephony/java/com/android/internal/telephony/cat/RilMessageDecoder.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * 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.internal.telephony.cat;
-
-import com.android.internal.telephony.IccFileHandler;
-import com.android.internal.telephony.IccUtils;
-
-import android.os.Handler;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-import android.os.Message;
-
-/**
- * Class used for queuing raw ril messages, decoding them into CommanParams
- * objects and sending the result back to the CAT Service.
- */
-class RilMessageDecoder extends StateMachine {
-
-    // constants
-    private static final int CMD_START = 1;
-    private static final int CMD_PARAMS_READY = 2;
-
-    // members
-    private static RilMessageDecoder sInstance = null;
-    private CommandParamsFactory mCmdParamsFactory = null;
-    private RilMessage mCurrentRilMessage = null;
-    private Handler mCaller = null;
-
-    // States
-    private StateStart mStateStart = new StateStart();
-    private StateCmdParamsReady mStateCmdParamsReady = new StateCmdParamsReady();
-
-    /**
-     * Get the singleton instance, constructing if necessary.
-     *
-     * @param caller
-     * @param fh
-     * @return RilMesssageDecoder
-     */
-    public static synchronized RilMessageDecoder getInstance(Handler caller, IccFileHandler fh) {
-        if (sInstance == null) {
-            sInstance = new RilMessageDecoder(caller, fh);
-            sInstance.start();
-        }
-        return sInstance;
-    }
-
-    /**
-     * Start decoding the message parameters,
-     * when complete MSG_ID_RIL_MSG_DECODED will be returned to caller.
-     *
-     * @param rilMsg
-     */
-    public void sendStartDecodingMessageParams(RilMessage rilMsg) {
-        Message msg = obtainMessage(CMD_START);
-        msg.obj = rilMsg;
-        sendMessage(msg);
-    }
-
-    /**
-     * The command parameters have been decoded.
-     *
-     * @param resCode
-     * @param cmdParams
-     */
-    public void sendMsgParamsDecoded(ResultCode resCode, CommandParams cmdParams) {
-        Message msg = obtainMessage(RilMessageDecoder.CMD_PARAMS_READY);
-        msg.arg1 = resCode.value();
-        msg.obj = cmdParams;
-        sendMessage(msg);
-    }
-
-    private void sendCmdForExecution(RilMessage rilMsg) {
-        Message msg = mCaller.obtainMessage(CatService.MSG_ID_RIL_MSG_DECODED,
-                new RilMessage(rilMsg));
-        msg.sendToTarget();
-    }
-
-    private RilMessageDecoder(Handler caller, IccFileHandler fh) {
-        super("RilMessageDecoder");
-
-        addState(mStateStart);
-        addState(mStateCmdParamsReady);
-        setInitialState(mStateStart);
-
-        mCaller = caller;
-        mCmdParamsFactory = CommandParamsFactory.getInstance(this, fh);
-    }
-
-    private class StateStart extends State {
-        @Override
-        public boolean processMessage(Message msg) {
-            if (msg.what == CMD_START) {
-                if (decodeMessageParams((RilMessage)msg.obj)) {
-                    transitionTo(mStateCmdParamsReady);
-                }
-            } else {
-                CatLog.d(this, "StateStart unexpected expecting START=" +
-                         CMD_START + " got " + msg.what);
-            }
-            return true;
-        }
-    }
-
-    private class StateCmdParamsReady extends State {
-        @Override
-        public boolean processMessage(Message msg) {
-            if (msg.what == CMD_PARAMS_READY) {
-                mCurrentRilMessage.mResCode = ResultCode.fromInt(msg.arg1);
-                mCurrentRilMessage.mData = msg.obj;
-                sendCmdForExecution(mCurrentRilMessage);
-                transitionTo(mStateStart);
-            } else {
-                CatLog.d(this, "StateCmdParamsReady expecting CMD_PARAMS_READY="
-                         + CMD_PARAMS_READY + " got " + msg.what);
-                deferMessage(msg);
-            }
-            return true;
-        }
-    }
-
-    private boolean decodeMessageParams(RilMessage rilMsg) {
-        boolean decodingStarted;
-
-        mCurrentRilMessage = rilMsg;
-        switch(rilMsg.mId) {
-        case CatService.MSG_ID_SESSION_END:
-        case CatService.MSG_ID_CALL_SETUP:
-            mCurrentRilMessage.mResCode = ResultCode.OK;
-            sendCmdForExecution(mCurrentRilMessage);
-            decodingStarted = false;
-            break;
-        case CatService.MSG_ID_PROACTIVE_COMMAND:
-        case CatService.MSG_ID_EVENT_NOTIFY:
-        case CatService.MSG_ID_REFRESH:
-            byte[] rawData = null;
-            try {
-                rawData = IccUtils.hexStringToBytes((String) rilMsg.mData);
-            } catch (Exception e) {
-                // zombie messages are dropped
-                CatLog.d(this, "decodeMessageParams dropping zombie messages");
-                decodingStarted = false;
-                break;
-            }
-            try {
-                // Start asynch parsing of the command parameters.
-                mCmdParamsFactory.make(BerTlv.decode(rawData));
-                decodingStarted = true;
-            } catch (ResultException e) {
-                // send to Service for proper RIL communication.
-                CatLog.d(this, "decodeMessageParams: caught ResultException e=" + e);
-                mCurrentRilMessage.mResCode = e.result();
-                sendCmdForExecution(mCurrentRilMessage);
-                decodingStarted = false;
-            }
-            break;
-        default:
-            decodingStarted = false;
-            break;
-        }
-        return decodingStarted;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/TextAlignment.java b/telephony/java/com/android/internal/telephony/cat/TextAlignment.java
deleted file mode 100644
index 7fb58a5..0000000
--- a/telephony/java/com/android/internal/telephony/cat/TextAlignment.java
+++ /dev/null
@@ -1,52 +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.internal.telephony.cat;
-
-
-/**
- * Enumeration for representing text alignment.
- *
- * {@hide}
- */
-public enum TextAlignment {
-    LEFT(0x0),
-    CENTER(0x1),
-    RIGHT(0x2),
-    /** Language dependent (default) */
-    DEFAULT(0x3);
-
-    private int mValue;
-
-    TextAlignment(int value) {
-        mValue = value;
-    }
-
-    /**
-     * Create a TextAlignment object.
-     * @param value Integer value to be converted to a TextAlignment object.
-     * @return TextAlignment object whose value is {@code value}. If no
-     *         TextAlignment object has that value, null is returned.
-     */
-    public static TextAlignment fromInt(int value) {
-        for (TextAlignment e : TextAlignment.values()) {
-            if (e.mValue == value) {
-                return e;
-            }
-        }
-        return null;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/TextAttribute.java b/telephony/java/com/android/internal/telephony/cat/TextAttribute.java
deleted file mode 100644
index 0dea640..0000000
--- a/telephony/java/com/android/internal/telephony/cat/TextAttribute.java
+++ /dev/null
@@ -1,49 +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.internal.telephony.cat;
-
-
-/**
- * Class for representing text attributes for SIM Toolkit.
- *
- * {@hide}
- */
-public class TextAttribute {
-    public int start;
-    public int length;
-    public TextAlignment align;
-    public FontSize size;
-    public boolean bold;
-    public boolean italic;
-    public boolean underlined;
-    public boolean strikeThrough;
-    public TextColor color;
-
-    public TextAttribute(int start, int length, TextAlignment align,
-            FontSize size, boolean bold, boolean italic, boolean underlined,
-            boolean strikeThrough, TextColor color) {
-        this.start = start;
-        this.length = length;
-        this.align = align;
-        this.size = size;
-        this.bold = bold;
-        this.italic = italic;
-        this.underlined = underlined;
-        this.strikeThrough = strikeThrough;
-        this.color = color;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/TextColor.java b/telephony/java/com/android/internal/telephony/cat/TextColor.java
deleted file mode 100644
index 6447e74..0000000
--- a/telephony/java/com/android/internal/telephony/cat/TextColor.java
+++ /dev/null
@@ -1,63 +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.internal.telephony.cat;
-
-
-/**
- * Enumeration for representing text color.
- *
- * {@hide}
- */
-public enum TextColor {
-    BLACK(0x0),
-    DARK_GRAY(0x1),
-    DARK_RED(0x2),
-    DARK_YELLOW(0x3),
-    DARK_GREEN(0x4),
-    DARK_CYAN(0x5),
-    DARK_BLUE(0x6),
-    DARK_MAGENTA(0x7),
-    GRAY(0x8),
-    WHITE(0x9),
-    BRIGHT_RED(0xa),
-    BRIGHT_YELLOW(0xb),
-    BRIGHT_GREEN(0xc),
-    BRIGHT_CYAN(0xd),
-    BRIGHT_BLUE(0xe),
-    BRIGHT_MAGENTA(0xf);
-
-    private int mValue;
-
-    TextColor(int value) {
-        mValue = value;
-    }
-
-    /**
-     * Create a TextColor object.
-     * @param value Integer value to be converted to a TextColor object.
-     * @return TextColor object whose value is {@code value}. If no TextColor
-     *         object has that value, null is returned.
-     */
-    public static TextColor fromInt(int value) {
-        for (TextColor e : TextColor.values()) {
-            if (e.mValue == value) {
-                return e;
-            }
-        }
-        return null;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/TextMessage.java b/telephony/java/com/android/internal/telephony/cat/TextMessage.java
deleted file mode 100644
index 5ffd076..0000000
--- a/telephony/java/com/android/internal/telephony/cat/TextMessage.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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.internal.telephony.cat;
-
-import android.graphics.Bitmap;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public class TextMessage implements Parcelable {
-    public String title = "";
-    public String text = null;
-    public Bitmap icon = null;
-    public boolean iconSelfExplanatory = false;
-    public boolean isHighPriority = false;
-    public boolean responseNeeded = true;
-    public boolean userClear = false;
-    public Duration duration = null;
-
-    TextMessage() {
-    }
-
-    private TextMessage(Parcel in) {
-        title = in.readString();
-        text = in.readString();
-        icon = in.readParcelable(null);
-        iconSelfExplanatory = in.readInt() == 1 ? true : false;
-        isHighPriority = in.readInt() == 1 ? true : false;
-        responseNeeded = in.readInt() == 1 ? true : false;
-        userClear = in.readInt() == 1 ? true : false;
-        duration = in.readParcelable(null);
-    }
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(title);
-        dest.writeString(text);
-        dest.writeParcelable(icon, 0);
-        dest.writeInt(iconSelfExplanatory ? 1 : 0);
-        dest.writeInt(isHighPriority ? 1 : 0);
-        dest.writeInt(responseNeeded ? 1 : 0);
-        dest.writeInt(userClear ? 1 : 0);
-        dest.writeParcelable(duration, 0);
-    }
-
-    public static final Parcelable.Creator<TextMessage> CREATOR = new Parcelable.Creator<TextMessage>() {
-        public TextMessage createFromParcel(Parcel in) {
-            return new TextMessage(in);
-        }
-
-        public TextMessage[] newArray(int size) {
-            return new TextMessage[size];
-        }
-    };
-}
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/cat/Tone.java b/telephony/java/com/android/internal/telephony/cat/Tone.java
deleted file mode 100644
index 27b4489..0000000
--- a/telephony/java/com/android/internal/telephony/cat/Tone.java
+++ /dev/null
@@ -1,190 +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.internal.telephony.cat;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Enumeration for representing the tone values for use with PLAY TONE
- * proactive commands.
- *
- * {@hide}
- */
-public enum Tone implements Parcelable {
-    // Standard supervisory tones
-
-    /**
-     * Dial tone.
-     */
-    DIAL(0x01),
-
-    /**
-     * Called subscriber busy.
-     */
-    BUSY(0x02),
-
-    /**
-     * Congestion.
-     */
-    CONGESTION(0x03),
-
-    /**
-     * Radio path acknowledge.
-     */
-    RADIO_PATH_ACK(0x04),
-
-    /**
-     * Radio path not available / Call dropped.
-     */
-    RADIO_PATH_NOT_AVAILABLE(0x05),
-
-    /**
-     * Error/Special information.
-     */
-    ERROR_SPECIAL_INFO(0x06),
-
-    /**
-     * Call waiting tone.
-     */
-    CALL_WAITING(0x07),
-
-    /**
-     * Ringing tone.
-     */
-    RINGING(0x08),
-
-    // Terminal proprietary tones
-
-    /**
-     * General beep.
-     */
-    GENERAL_BEEP(0x10),
-
-    /**
-     * Positive acknowledgement tone.
-     */
-    POSITIVE_ACK(0x11),
-
-    /**
-     * Negative acknowledgement tone.
-     */
-    NEGATIVE_ACK(0x12),
-
-    /**
-     * Ringing tone as selected by the user for incoming speech call.
-     */
-    INCOMING_SPEECH_CALL(0x13),
-
-    /**
-     * Alert tone as selected by the user for incoming SMS.
-     */
-    INCOMING_SMS(0x14),
-
-    /**
-     * Critical alert.
-     * This tone is to be used in critical situations. The terminal shall make
-     * every effort to alert the user when this tone is indicated independent
-     * from the volume setting in the terminal.
-     */
-    CRITICAL_ALERT(0x15),
-
-    /**
-     * Vibrate only, if available.
-     */
-    VIBRATE_ONLY(0x20),
-
-    // Themed tones
-
-    /**
-     * Happy tone.
-     */
-    HAPPY(0x30),
-
-    /**
-     * Sad tone.
-     */
-    SAD(0x31),
-
-    /**
-     * Urgent action tone.
-     */
-    URGENT(0x32),
-
-    /**
-     * Question tone.
-     */
-    QUESTION(0x33),
-
-    /**
-     * Message received tone.
-     */
-    MESSAGE_RECEIVED(0x34),
-
-    // Melody tones
-    MELODY_1(0x40),
-    MELODY_2(0x41),
-    MELODY_3(0x42),
-    MELODY_4(0x43),
-    MELODY_5(0x44),
-    MELODY_6(0x45),
-    MELODY_7(0x46),
-    MELODY_8(0x47);
-
-    private int mValue;
-
-    Tone(int value) {
-        mValue = value;
-    }
-
-    /**
-     * Create a Tone object.
-     * @param value Integer value to be converted to a Tone object.
-     * @return Tone object whose value is {@code value}. If no Tone object has
-     *         that value, null is returned.
-     */
-    public static Tone fromInt(int value) {
-        for (Tone e : Tone.values()) {
-            if (e.mValue == value) {
-                return e;
-            }
-        }
-        return null;
-    }
-
-    Tone(Parcel in) {
-        mValue = in.readInt();
-    }
-
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(ordinal());
-    }
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<Tone> CREATOR = new Parcelable.Creator<Tone>() {
-        public Tone createFromParcel(Parcel in) {
-            return Tone.values()[in.readInt()];
-        }
-
-        public Tone[] newArray(int size) {
-            return new Tone[size];
-        }
-    };
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/ToneSettings.java b/telephony/java/com/android/internal/telephony/cat/ToneSettings.java
deleted file mode 100644
index 6375afb..0000000
--- a/telephony/java/com/android/internal/telephony/cat/ToneSettings.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.internal.telephony.cat;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Container class for PlayTone commands parameters.
- *
- */
-public class ToneSettings implements Parcelable {
-    public Duration duration;
-    public Tone tone;
-    public boolean vibrate;
-
-    public ToneSettings(Duration duration, Tone tone, boolean vibrate) {
-        this.duration = duration;
-        this.tone = tone;
-        this.vibrate = vibrate;
-    }
-
-    private ToneSettings(Parcel in) {
-        duration = in.readParcelable(null);
-        tone = in.readParcelable(null);
-        vibrate = in.readInt() == 1;
-    }
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeParcelable(duration, 0);
-        dest.writeParcelable(tone, 0);
-        dest.writeInt(vibrate ? 1 : 0);
-    }
-
-    public static final Parcelable.Creator<ToneSettings> CREATOR = new Parcelable.Creator<ToneSettings>() {
-        public ToneSettings createFromParcel(Parcel in) {
-            return new ToneSettings(in);
-        }
-
-        public ToneSettings[] newArray(int size) {
-            return new ToneSettings[size];
-        }
-    };
-}
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/cat/ValueParser.java b/telephony/java/com/android/internal/telephony/cat/ValueParser.java
deleted file mode 100644
index 584d96c..0000000
--- a/telephony/java/com/android/internal/telephony/cat/ValueParser.java
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * Copyright (C) 2006-2007 Google Inc.
- *
- * 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.internal.telephony.cat;
-
-import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.cat.Duration.TimeUnit;
-
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.List;
-
-abstract class ValueParser {
-
-    /**
-     * Search for a Command Details object from a list.
-     *
-     * @param ctlvs List of ComprehensionTlv objects used for search
-     * @return An CtlvCommandDetails object found from the objects. If no
-     *         Command Details object is found, ResultException is thrown.
-     * @throws ResultException
-     */
-    static CommandDetails retrieveCommandDetails(ComprehensionTlv ctlv)
-            throws ResultException {
-
-        CommandDetails cmdDet = new CommandDetails();
-        byte[] rawValue = ctlv.getRawValue();
-        int valueIndex = ctlv.getValueIndex();
-        try {
-            cmdDet.compRequired = ctlv.isComprehensionRequired();
-            cmdDet.commandNumber = rawValue[valueIndex] & 0xff;
-            cmdDet.typeOfCommand = rawValue[valueIndex + 1] & 0xff;
-            cmdDet.commandQualifier = rawValue[valueIndex + 2] & 0xff;
-            return cmdDet;
-        } catch (IndexOutOfBoundsException e) {
-            throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
-        }
-    }
-
-    /**
-     * Search for a Device Identities object from a list.
-     *
-     * @param ctlvs List of ComprehensionTlv objects used for search
-     * @return An CtlvDeviceIdentities object found from the objects. If no
-     *         Command Details object is found, ResultException is thrown.
-     * @throws ResultException
-     */
-    static DeviceIdentities retrieveDeviceIdentities(ComprehensionTlv ctlv)
-            throws ResultException {
-
-        DeviceIdentities devIds = new DeviceIdentities();
-        byte[] rawValue = ctlv.getRawValue();
-        int valueIndex = ctlv.getValueIndex();
-        try {
-            devIds.sourceId = rawValue[valueIndex] & 0xff;
-            devIds.destinationId = rawValue[valueIndex + 1] & 0xff;
-            return devIds;
-        } catch (IndexOutOfBoundsException e) {
-            throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING);
-        }
-    }
-
-    /**
-     * Retrieves Duration information from the Duration COMPREHENSION-TLV
-     * object.
-     *
-     * @param ctlv A Text Attribute COMPREHENSION-TLV object
-     * @return A Duration object
-     * @throws ResultException
-     */
-    static Duration retrieveDuration(ComprehensionTlv ctlv) throws ResultException {
-        int timeInterval = 0;
-        TimeUnit timeUnit = TimeUnit.SECOND;
-
-        byte[] rawValue = ctlv.getRawValue();
-        int valueIndex = ctlv.getValueIndex();
-
-        try {
-            timeUnit = TimeUnit.values()[(rawValue[valueIndex] & 0xff)];
-            timeInterval = rawValue[valueIndex + 1] & 0xff;
-        } catch (IndexOutOfBoundsException e) {
-            throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
-        }
-        return new Duration(timeInterval, timeUnit);
-    }
-
-    /**
-     * Retrieves Item information from the COMPREHENSION-TLV object.
-     *
-     * @param ctlv A Text Attribute COMPREHENSION-TLV object
-     * @return An Item
-     * @throws ResultException
-     */
-    static Item retrieveItem(ComprehensionTlv ctlv) throws ResultException {
-        Item item = null;
-
-        byte[] rawValue = ctlv.getRawValue();
-        int valueIndex = ctlv.getValueIndex();
-        int length = ctlv.getLength();
-
-        if (length != 0) {
-            int textLen = length - 1;
-
-            try {
-                int id = rawValue[valueIndex] & 0xff;
-                String text = IccUtils.adnStringFieldToString(rawValue,
-                        valueIndex + 1, textLen);
-                item = new Item(id, text);
-            } catch (IndexOutOfBoundsException e) {
-                throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
-            }
-        }
-
-        return item;
-    }
-
-    /**
-     * Retrieves Item id information from the COMPREHENSION-TLV object.
-     *
-     * @param ctlv A Text Attribute COMPREHENSION-TLV object
-     * @return An Item id
-     * @throws ResultException
-     */
-    static int retrieveItemId(ComprehensionTlv ctlv) throws ResultException {
-        int id = 0;
-
-        byte[] rawValue = ctlv.getRawValue();
-        int valueIndex = ctlv.getValueIndex();
-
-        try {
-            id = rawValue[valueIndex] & 0xff;
-        } catch (IndexOutOfBoundsException e) {
-            throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
-        }
-
-        return id;
-    }
-
-    /**
-     * Retrieves icon id from an Icon Identifier COMPREHENSION-TLV object
-     *
-     * @param ctlv An Icon Identifier COMPREHENSION-TLV object
-     * @return IconId instance
-     * @throws ResultException
-     */
-    static IconId retrieveIconId(ComprehensionTlv ctlv) throws ResultException {
-        IconId id = new IconId();
-
-        byte[] rawValue = ctlv.getRawValue();
-        int valueIndex = ctlv.getValueIndex();
-        try {
-            id.selfExplanatory = (rawValue[valueIndex++] & 0xff) == 0x00;
-            id.recordNumber = rawValue[valueIndex] & 0xff;
-        } catch (IndexOutOfBoundsException e) {
-            throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
-        }
-
-        return id;
-    }
-
-    /**
-     * Retrieves item icons id from an Icon Identifier List COMPREHENSION-TLV
-     * object
-     *
-     * @param ctlv An Item Icon List Identifier COMPREHENSION-TLV object
-     * @return ItemsIconId instance
-     * @throws ResultException
-     */
-    static ItemsIconId retrieveItemsIconId(ComprehensionTlv ctlv)
-            throws ResultException {
-        CatLog.d("ValueParser", "retrieveItemsIconId:");
-        ItemsIconId id = new ItemsIconId();
-
-        byte[] rawValue = ctlv.getRawValue();
-        int valueIndex = ctlv.getValueIndex();
-        int numOfItems = ctlv.getLength() - 1;
-        id.recordNumbers = new int[numOfItems];
-
-        try {
-            // get icon self-explanatory
-            id.selfExplanatory = (rawValue[valueIndex++] & 0xff) == 0x00;
-
-            for (int index = 0; index < numOfItems;) {
-                id.recordNumbers[index++] = rawValue[valueIndex++];
-            }
-        } catch (IndexOutOfBoundsException e) {
-            throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
-        }
-        return id;
-    }
-
-    /**
-     * Retrieves text attribute information from the Text Attribute
-     * COMPREHENSION-TLV object.
-     *
-     * @param ctlv A Text Attribute COMPREHENSION-TLV object
-     * @return A list of TextAttribute objects
-     * @throws ResultException
-     */
-    static List<TextAttribute> retrieveTextAttribute(ComprehensionTlv ctlv)
-            throws ResultException {
-        ArrayList<TextAttribute> lst = new ArrayList<TextAttribute>();
-
-        byte[] rawValue = ctlv.getRawValue();
-        int valueIndex = ctlv.getValueIndex();
-        int length = ctlv.getLength();
-
-        if (length != 0) {
-            // Each attribute is consisted of four bytes
-            int itemCount = length / 4;
-
-            try {
-                for (int i = 0; i < itemCount; i++, valueIndex += 4) {
-                    int start = rawValue[valueIndex] & 0xff;
-                    int textLength = rawValue[valueIndex + 1] & 0xff;
-                    int format = rawValue[valueIndex + 2] & 0xff;
-                    int colorValue = rawValue[valueIndex + 3] & 0xff;
-
-                    int alignValue = format & 0x03;
-                    TextAlignment align = TextAlignment.fromInt(alignValue);
-
-                    int sizeValue = (format >> 2) & 0x03;
-                    FontSize size = FontSize.fromInt(sizeValue);
-                    if (size == null) {
-                        // Font size value is not defined. Use default.
-                        size = FontSize.NORMAL;
-                    }
-
-                    boolean bold = (format & 0x10) != 0;
-                    boolean italic = (format & 0x20) != 0;
-                    boolean underlined = (format & 0x40) != 0;
-                    boolean strikeThrough = (format & 0x80) != 0;
-
-                    TextColor color = TextColor.fromInt(colorValue);
-
-                    TextAttribute attr = new TextAttribute(start, textLength,
-                            align, size, bold, italic, underlined,
-                            strikeThrough, color);
-                    lst.add(attr);
-                }
-
-                return lst;
-
-            } catch (IndexOutOfBoundsException e) {
-                throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
-            }
-        }
-        return null;
-    }
-
-
-    /**
-     * Retrieves alpha identifier from an Alpha Identifier COMPREHENSION-TLV
-     * object.
-     *
-     * @param ctlv An Alpha Identifier COMPREHENSION-TLV object
-     * @return String corresponding to the alpha identifier
-     * @throws ResultException
-     */
-    static String retrieveAlphaId(ComprehensionTlv ctlv) throws ResultException {
-
-        if (ctlv != null) {
-            byte[] rawValue = ctlv.getRawValue();
-            int valueIndex = ctlv.getValueIndex();
-            int length = ctlv.getLength();
-            if (length != 0) {
-                try {
-                    return IccUtils.adnStringFieldToString(rawValue, valueIndex,
-                            length);
-                } catch (IndexOutOfBoundsException e) {
-                    throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
-                }
-            } else {
-                return CatService.STK_DEFAULT;
-            }
-        } else {
-            return CatService.STK_DEFAULT;
-        }
-    }
-
-    /**
-     * Retrieves text from the Text COMPREHENSION-TLV object, and decodes it
-     * into a Java String.
-     *
-     * @param ctlv A Text COMPREHENSION-TLV object
-     * @return A Java String object decoded from the Text object
-     * @throws ResultException
-     */
-    static String retrieveTextString(ComprehensionTlv ctlv) throws ResultException {
-        byte[] rawValue = ctlv.getRawValue();
-        int valueIndex = ctlv.getValueIndex();
-        byte codingScheme = 0x00;
-        String text = null;
-        int textLen = ctlv.getLength();
-
-        // In case the text length is 0, return a null string.
-        if (textLen == 0) {
-            return text;
-        } else {
-            // one byte is coding scheme
-            textLen -= 1;
-        }
-
-        try {
-            codingScheme = (byte) (rawValue[valueIndex] & 0x0c);
-
-            if (codingScheme == 0x00) { // GSM 7-bit packed
-                text = GsmAlphabet.gsm7BitPackedToString(rawValue,
-                        valueIndex + 1, (textLen * 8) / 7);
-            } else if (codingScheme == 0x04) { // GSM 8-bit unpacked
-                text = GsmAlphabet.gsm8BitUnpackedToString(rawValue,
-                        valueIndex + 1, textLen);
-            } else if (codingScheme == 0x08) { // UCS2
-                text = new String(rawValue, valueIndex + 1, textLen, "UTF-16");
-            } else {
-                throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
-            }
-
-            return text;
-        } catch (IndexOutOfBoundsException e) {
-            throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
-        } catch (UnsupportedEncodingException e) {
-            // This should never happen.
-            throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
-        }
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/package.html b/telephony/java/com/android/internal/telephony/cat/package.html
deleted file mode 100644
index 5b6bfc6..0000000
--- a/telephony/java/com/android/internal/telephony/cat/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<HTML>
-<BODY>
-Provides classes for ICC Toolkit Service (CAT).
-</BODY>
-</HTML>
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
deleted file mode 100644
index d99a625..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2011 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.internal.telephony.cdma;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.database.SQLException;
-import android.net.Uri;
-import android.os.AsyncResult;
-import android.os.Message;
-import android.preference.PreferenceManager;
-import android.provider.Telephony;
-import android.util.Log;
-
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.OperatorInfo;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneNotifier;
-import com.android.internal.telephony.PhoneProxy;
-import com.android.internal.telephony.SMSDispatcher;
-import com.android.internal.telephony.gsm.GsmSMSDispatcher;
-import com.android.internal.telephony.gsm.SmsMessage;
-import com.android.internal.telephony.ims.IsimRecords;
-import com.android.internal.telephony.uicc.UiccController;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-public class CDMALTEPhone extends CDMAPhone {
-    static final String LOG_TAG = "CDMA";
-
-    private static final boolean DBG = true;
-
-    /** Secondary SMSDispatcher for 3GPP format messages. */
-    SMSDispatcher m3gppSMS;
-
-    /**
-     * Small container class used to hold information relevant to
-     * the carrier selection process. operatorNumeric can be ""
-     * if we are looking for automatic selection. operatorAlphaLong is the
-     * corresponding operator name.
-     */
-    private static class NetworkSelectMessage {
-        public Message message;
-        public String operatorNumeric;
-        public String operatorAlphaLong;
-    }
-
-    // Constructors
-    public CDMALTEPhone(Context context, CommandsInterface ci, PhoneNotifier notifier) {
-        super(context, ci, notifier, false);
-        m3gppSMS = new GsmSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor);
-        mIccRecords.registerForNewSms(this, EVENT_NEW_ICC_SMS, null);
-    }
-
-    @Override
-    public void handleMessage (Message msg) {
-        AsyncResult ar;
-        switch (msg.what) {
-            // handle the select network completion callbacks.
-            case EVENT_SET_NETWORK_MANUAL_COMPLETE:
-                handleSetSelectNetwork((AsyncResult) msg.obj);
-                break;
-            case EVENT_NEW_ICC_SMS:
-                ar = (AsyncResult)msg.obj;
-                m3gppSMS.dispatchMessage((SmsMessage)ar.result);
-                break;
-            default:
-                super.handleMessage(msg);
-        }
-    }
-
-    @Override
-    protected void initSstIcc() {
-        mIccCard.set(UiccController.getInstance(this).getIccCard());
-        mIccRecords = mIccCard.get().getIccRecords();
-        // CdmaLteServiceStateTracker registers with IccCard to know
-        // when the card is ready. So create mIccCard before the ServiceStateTracker
-        mSST = new CdmaLteServiceStateTracker(this);
-    }
-
-    @Override
-    public void dispose() {
-        synchronized(PhoneProxy.lockForRadioTechnologyChange) {
-            super.dispose();
-            m3gppSMS.dispose();
-            mIccRecords.unregisterForNewSms(this);
-        }
-    }
-
-    @Override
-    public void removeReferences() {
-        super.removeReferences();
-        m3gppSMS = null;
-    }
-
-    @Override
-    public DataState getDataConnectionState(String apnType) {
-        DataState ret = DataState.DISCONNECTED;
-
-        if (mSST == null) {
-            // Radio Technology Change is ongoing, dispose() and
-            // removeReferences() have already been called
-
-            ret = DataState.DISCONNECTED;
-        } else if (mDataConnectionTracker.isApnTypeEnabled(apnType) == false) {
-            ret = DataState.DISCONNECTED;
-        } else {
-            switch (mDataConnectionTracker.getState(apnType)) {
-                case FAILED:
-                case IDLE:
-                    ret = DataState.DISCONNECTED;
-                    break;
-
-                case CONNECTED:
-                case DISCONNECTING:
-                    if (mCT.state != Phone.State.IDLE && !mSST.isConcurrentVoiceAndDataAllowed()) {
-                        ret = DataState.SUSPENDED;
-                    } else {
-                        ret = DataState.CONNECTED;
-                    }
-                    break;
-
-                case INITING:
-                case CONNECTING:
-                case SCANNING:
-                    ret = DataState.CONNECTING;
-                    break;
-            }
-        }
-
-        log("getDataConnectionState apnType=" + apnType + " ret=" + ret);
-        return ret;
-    }
-
-    @Override
-    public void
-    selectNetworkManually(OperatorInfo network,
-            Message response) {
-        // wrap the response message in our own message along with
-        // the operator's id.
-        NetworkSelectMessage nsm = new NetworkSelectMessage();
-        nsm.message = response;
-        nsm.operatorNumeric = network.getOperatorNumeric();
-        nsm.operatorAlphaLong = network.getOperatorAlphaLong();
-
-        // get the message
-        Message msg = obtainMessage(EVENT_SET_NETWORK_MANUAL_COMPLETE, nsm);
-
-        mCM.setNetworkSelectionModeManual(network.getOperatorNumeric(), msg);
-    }
-
-    /**
-     * Used to track the settings upon completion of the network change.
-     */
-    private void handleSetSelectNetwork(AsyncResult ar) {
-        // look for our wrapper within the asyncresult, skip the rest if it
-        // is null.
-        if (!(ar.userObj instanceof NetworkSelectMessage)) {
-            Log.e(LOG_TAG, "unexpected result from user object.");
-            return;
-        }
-
-        NetworkSelectMessage nsm = (NetworkSelectMessage) ar.userObj;
-
-        // found the object, now we send off the message we had originally
-        // attached to the request.
-        if (nsm.message != null) {
-            if (DBG) log("sending original message to recipient");
-            AsyncResult.forMessage(nsm.message, ar.result, ar.exception);
-            nsm.message.sendToTarget();
-        }
-
-        // open the shared preferences editor, and write the value.
-        // nsm.operatorNumeric is "" if we're in automatic.selection.
-        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
-        SharedPreferences.Editor editor = sp.edit();
-        editor.putString(NETWORK_SELECTION_KEY, nsm.operatorNumeric);
-        editor.putString(NETWORK_SELECTION_NAME_KEY, nsm.operatorAlphaLong);
-
-        // commit and log the result.
-        if (! editor.commit()) {
-            Log.e(LOG_TAG, "failed to commit network selection preference");
-        }
-
-    }
-
-    @Override
-    public boolean updateCurrentCarrierInProvider() {
-        if (mIccRecords != null) {
-            try {
-                Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current");
-                ContentValues map = new ContentValues();
-                String operatorNumeric = mIccRecords.getOperatorNumeric();
-                map.put(Telephony.Carriers.NUMERIC, operatorNumeric);
-                if (DBG) log("updateCurrentCarrierInProvider from UICC: numeric=" +
-                        operatorNumeric);
-                mContext.getContentResolver().insert(uri, map);
-                return true;
-            } catch (SQLException e) {
-                Log.e(LOG_TAG, "[CDMALTEPhone] Can't store current operator ret false", e);
-            }
-        } else {
-            if (DBG) log("updateCurrentCarrierInProvider mIccRecords == null ret false");
-        }
-        return false;
-    }
-
-    // return IMSI from USIM as subscriber ID.
-    @Override
-    public String getSubscriberId() {
-        return mIccRecords.getIMSI();
-    }
-
-    @Override
-    public String getImei() {
-        return mImei;
-    }
-
-    @Override
-    public String getDeviceSvn() {
-        return mImeiSv;
-    }
-
-    @Override
-    public IsimRecords getIsimRecords() {
-        return mIccRecords.getIsimRecords();
-    }
-
-    @Override
-    public String getMsisdn() {
-        return mIccRecords.getMsisdnNumber();
-    }
-
-    @Override
-    public void getAvailableNetworks(Message response) {
-        mCM.getAvailableNetworks(response);
-    }
-
-    @Override
-    public void requestIsimAuthentication(String nonce, Message result) {
-        mCM.requestIsimAuthentication(nonce, result);
-    }
-
-    @Override
-    protected void log(String s) {
-            Log.d(LOG_TAG, "[CDMALTEPhone] " + s);
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("CDMALTEPhone extends:");
-        super.dump(fd, pw, args);
-        pw.println(" m3gppSMS=" + m3gppSMS);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
deleted file mode 100755
index 9f6ec71..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ /dev/null
@@ -1,1507 +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.internal.telephony.cdma;
-
-import android.app.ActivityManagerNative;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.database.SQLException;
-import android.net.Uri;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.os.SystemProperties;
-import android.preference.PreferenceManager;
-import android.provider.Telephony;
-import android.telephony.CellLocation;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallStateException;
-import com.android.internal.telephony.CallTracker;
-import com.android.internal.telephony.CommandException;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccException;
-import com.android.internal.telephony.IccFileHandler;
-import com.android.internal.telephony.IccPhoneBookInterfaceManager;
-import com.android.internal.telephony.IccSmsInterfaceManager;
-import com.android.internal.telephony.MccTable;
-import com.android.internal.telephony.MmiCode;
-import com.android.internal.telephony.OperatorInfo;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.PhoneNotifier;
-import com.android.internal.telephony.PhoneProxy;
-import com.android.internal.telephony.PhoneSubInfo;
-import com.android.internal.telephony.ServiceStateTracker;
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.telephony.UUSInfo;
-import com.android.internal.telephony.cat.CatService;
-import com.android.internal.telephony.uicc.UiccController;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
-
-/**
- * {@hide}
- */
-public class CDMAPhone extends PhoneBase {
-    static final String LOG_TAG = "CDMA";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false; /* STOP SHIP if true */
-
-    // Default Emergency Callback Mode exit timer
-    private static final int DEFAULT_ECM_EXIT_TIMER_VALUE = 300000;
-
-    static final String VM_COUNT_CDMA = "vm_count_key_cdma";
-    private static final String VM_NUMBER_CDMA = "vm_number_key_cdma";
-    private String mVmNumber = null;
-
-    static final int RESTART_ECM_TIMER = 0; // restart Ecm timer
-    static final int CANCEL_ECM_TIMER = 1; // cancel Ecm timer
-
-    // Instance Variables
-    CdmaCallTracker mCT;
-    CdmaServiceStateTracker mSST;
-    CdmaSubscriptionSourceManager mCdmaSSM;
-    ArrayList <CdmaMmiCode> mPendingMmis = new ArrayList<CdmaMmiCode>();
-    RuimPhoneBookInterfaceManager mRuimPhoneBookInterfaceManager;
-    RuimSmsInterfaceManager mRuimSmsInterfaceManager;
-    int mCdmaSubscriptionSource = CdmaSubscriptionSourceManager.SUBSCRIPTION_SOURCE_UNKNOWN;
-    PhoneSubInfo mSubInfo;
-    EriManager mEriManager;
-    WakeLock mWakeLock;
-
-    // mEriFileLoadedRegistrants are informed after the ERI text has been loaded
-    private final RegistrantList mEriFileLoadedRegistrants = new RegistrantList();
-
-    // mEcmTimerResetRegistrants are informed after Ecm timer is canceled or re-started
-    private final RegistrantList mEcmTimerResetRegistrants = new RegistrantList();
-
-    // mEcmExitRespRegistrant is informed after the phone has been exited
-    //the emergency callback mode
-    //keep track of if phone is in emergency callback mode
-    private boolean mIsPhoneInEcmState;
-    private Registrant mEcmExitRespRegistrant;
-    protected String mImei;
-    protected String mImeiSv;
-    private String mEsn;
-    private String mMeid;
-    // string to define how the carrier specifies its own ota sp number
-    private String mCarrierOtaSpNumSchema;
-
-    // A runnable which is used to automatically exit from Ecm after a period of time.
-    private Runnable mExitEcmRunnable = new Runnable() {
-        @Override
-        public void run() {
-            exitEmergencyCallbackMode();
-        }
-    };
-
-    Registrant mPostDialHandler;
-
-    static String PROPERTY_CDMA_HOME_OPERATOR_NUMERIC = "ro.cdma.home.operator.numeric";
-
-    // Constructors
-    public CDMAPhone(Context context, CommandsInterface ci, PhoneNotifier notifier) {
-        super(notifier, context, ci, false);
-        initSstIcc();
-        init(context, notifier);
-    }
-
-    public CDMAPhone(Context context, CommandsInterface ci, PhoneNotifier notifier,
-            boolean unitTestMode) {
-        super(notifier, context, ci, unitTestMode);
-        initSstIcc();
-        init(context, notifier);
-    }
-
-    protected void initSstIcc() {
-        mIccCard.set(UiccController.getInstance(this).getIccCard());
-        mIccRecords = mIccCard.get().getIccRecords();
-        // CdmaServiceStateTracker registers with IccCard to know
-        // when the Ruim card is ready. So create mIccCard before the ServiceStateTracker
-        mSST = new CdmaServiceStateTracker(this);
-    }
-
-    protected void init(Context context, PhoneNotifier notifier) {
-        mCM.setPhoneType(Phone.PHONE_TYPE_CDMA);
-        mCT = new CdmaCallTracker(this);
-        mCdmaSSM = CdmaSubscriptionSourceManager.getInstance(context, mCM, this,
-                EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
-        mSMS = new CdmaSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor);
-        mDataConnectionTracker = new CdmaDataConnectionTracker (this);
-        mRuimPhoneBookInterfaceManager = new RuimPhoneBookInterfaceManager(this);
-        mRuimSmsInterfaceManager = new RuimSmsInterfaceManager(this, mSMS);
-        mSubInfo = new PhoneSubInfo(this);
-        mEriManager = new EriManager(this, context, EriManager.ERI_FROM_XML);
-
-        mCM.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
-        registerForRuimRecordEvents();
-        mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
-        mCM.registerForOn(this, EVENT_RADIO_ON, null);
-        mCM.setOnSuppServiceNotification(this, EVENT_SSN, null);
-        mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null);
-        mCM.setEmergencyCallbackMode(this, EVENT_EMERGENCY_CALLBACK_MODE_ENTER, null);
-
-        PowerManager pm
-            = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,LOG_TAG);
-
-        //Change the system setting
-        SystemProperties.set(TelephonyProperties.CURRENT_ACTIVE_PHONE,
-                Integer.toString(Phone.PHONE_TYPE_CDMA));
-
-        // This is needed to handle phone process crashes
-        String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
-        mIsPhoneInEcmState = inEcm.equals("true");
-        if (mIsPhoneInEcmState) {
-            // Send a message which will invoke handleExitEmergencyCallbackMode
-            mCM.exitEmergencyCallbackMode(obtainMessage(EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE));
-        }
-
-        // get the string that specifies the carrier OTA Sp number
-        mCarrierOtaSpNumSchema = SystemProperties.get(
-                TelephonyProperties.PROPERTY_OTASP_NUM_SCHEMA,"");
-
-        // Sets operator alpha property by retrieving from build-time system property
-        String operatorAlpha = SystemProperties.get("ro.cdma.home.operator.alpha");
-        setSystemProperty(PROPERTY_ICC_OPERATOR_ALPHA, operatorAlpha);
-
-        // Sets operator numeric property by retrieving from build-time system property
-        String operatorNumeric = SystemProperties.get(PROPERTY_CDMA_HOME_OPERATOR_NUMERIC);
-        log("CDMAPhone: init set 'gsm.sim.operator.numeric' to operator='" +
-                operatorNumeric + "'");
-        setSystemProperty(PROPERTY_ICC_OPERATOR_NUMERIC, operatorNumeric);
-
-        // Sets iso country property by retrieving from build-time system property
-        setIsoCountryProperty(operatorNumeric);
-
-        // Sets current entry in the telephony carrier table
-        updateCurrentCarrierInProvider(operatorNumeric);
-
-        // Notify voicemails.
-        notifier.notifyMessageWaitingChanged(this);
-    }
-
-    @Override
-    public void dispose() {
-        synchronized(PhoneProxy.lockForRadioTechnologyChange) {
-            super.dispose();
-            log("dispose");
-
-            //Unregister from all former registered events
-            unregisterForRuimRecordEvents();
-            mCM.unregisterForAvailable(this); //EVENT_RADIO_AVAILABLE
-            mCM.unregisterForOffOrNotAvailable(this); //EVENT_RADIO_OFF_OR_NOT_AVAILABLE
-            mCM.unregisterForOn(this); //EVENT_RADIO_ON
-            mSST.unregisterForNetworkAttached(this); //EVENT_REGISTERED_TO_NETWORK
-            mCM.unSetOnSuppServiceNotification(this);
-            removeCallbacks(mExitEcmRunnable);
-
-            mPendingMmis.clear();
-
-            //Force all referenced classes to unregister their former registered events
-            mCT.dispose();
-            mDataConnectionTracker.dispose();
-            mSST.dispose();
-            mCdmaSSM.dispose(this);
-            mSMS.dispose();
-            mRuimPhoneBookInterfaceManager.dispose();
-            mRuimSmsInterfaceManager.dispose();
-            mSubInfo.dispose();
-            mEriManager.dispose();
-        }
-    }
-
-    @Override
-    public void removeReferences() {
-        log("removeReferences");
-        mRuimPhoneBookInterfaceManager = null;
-        mRuimSmsInterfaceManager = null;
-        mSubInfo = null;
-        mCT = null;
-        mSST = null;
-        mEriManager = null;
-        mExitEcmRunnable = null;
-        super.removeReferences();
-    }
-
-    @Override
-    protected void finalize() {
-        if(DBG) Log.d(LOG_TAG, "CDMAPhone finalized");
-        if (mWakeLock.isHeld()) {
-            Log.e(LOG_TAG, "UNEXPECTED; mWakeLock is held when finalizing.");
-            mWakeLock.release();
-        }
-    }
-
-    public ServiceState getServiceState() {
-        return mSST.ss;
-    }
-
-    public CallTracker getCallTracker() {
-        return mCT;
-    }
-
-    public Phone.State getState() {
-        return mCT.state;
-    }
-
-    public ServiceStateTracker getServiceStateTracker() {
-        return mSST;
-    }
-
-    public String getPhoneName() {
-        return "CDMA";
-    }
-
-    public int getPhoneType() {
-        return Phone.PHONE_TYPE_CDMA;
-    }
-
-    public boolean canTransfer() {
-        Log.e(LOG_TAG, "canTransfer: not possible in CDMA");
-        return false;
-    }
-
-    public CdmaCall getRingingCall() {
-        return mCT.ringingCall;
-    }
-
-    public void setMute(boolean muted) {
-        mCT.setMute(muted);
-    }
-
-    public boolean getMute() {
-        return mCT.getMute();
-    }
-
-    public void conference() throws CallStateException {
-        // three way calls in CDMA will be handled by feature codes
-        Log.e(LOG_TAG, "conference: not possible in CDMA");
-    }
-
-    public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) {
-        this.mCM.setPreferredVoicePrivacy(enable, onComplete);
-    }
-
-    public void getEnhancedVoicePrivacy(Message onComplete) {
-        this.mCM.getPreferredVoicePrivacy(onComplete);
-    }
-
-    public void clearDisconnected() {
-        mCT.clearDisconnected();
-    }
-
-    public DataActivityState getDataActivityState() {
-        DataActivityState ret = DataActivityState.NONE;
-
-        if (mSST.getCurrentDataConnectionState() == ServiceState.STATE_IN_SERVICE) {
-
-            switch (mDataConnectionTracker.getActivity()) {
-                case DATAIN:
-                    ret = DataActivityState.DATAIN;
-                break;
-
-                case DATAOUT:
-                    ret = DataActivityState.DATAOUT;
-                break;
-
-                case DATAINANDOUT:
-                    ret = DataActivityState.DATAINANDOUT;
-                break;
-
-                case DORMANT:
-                    ret = DataActivityState.DORMANT;
-                break;
-            }
-        }
-        return ret;
-    }
-
-    /*package*/ void
-    notifySignalStrength() {
-        mNotifier.notifySignalStrength(this);
-    }
-
-    public Connection
-    dial (String dialString) throws CallStateException {
-        // Need to make sure dialString gets parsed properly
-        String newDialString = PhoneNumberUtils.stripSeparators(dialString);
-        return mCT.dial(newDialString);
-    }
-
-    public Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException {
-        throw new CallStateException("Sending UUS information NOT supported in CDMA!");
-    }
-
-    public SignalStrength getSignalStrength() {
-        return mSST.mSignalStrength;
-    }
-
-    public boolean
-    getMessageWaitingIndicator() {
-        return (getVoiceMessageCount() > 0);
-    }
-
-    public List<? extends MmiCode>
-    getPendingMmiCodes() {
-        return mPendingMmis;
-    }
-
-    public void registerForSuppServiceNotification(
-            Handler h, int what, Object obj) {
-        Log.e(LOG_TAG, "method registerForSuppServiceNotification is NOT supported in CDMA!");
-    }
-
-    public CdmaCall getBackgroundCall() {
-        return mCT.backgroundCall;
-    }
-
-    public boolean handleInCallMmiCommands(String dialString) {
-        Log.e(LOG_TAG, "method handleInCallMmiCommands is NOT supported in CDMA!");
-        return false;
-    }
-
-    boolean isInCall() {
-        CdmaCall.State foregroundCallState = getForegroundCall().getState();
-        CdmaCall.State backgroundCallState = getBackgroundCall().getState();
-        CdmaCall.State ringingCallState = getRingingCall().getState();
-
-        return (foregroundCallState.isAlive() || backgroundCallState.isAlive() || ringingCallState
-                .isAlive());
-    }
-
-    public void
-    setNetworkSelectionModeAutomatic(Message response) {
-        Log.e(LOG_TAG, "method setNetworkSelectionModeAutomatic is NOT supported in CDMA!");
-    }
-
-    public void unregisterForSuppServiceNotification(Handler h) {
-        Log.e(LOG_TAG, "method unregisterForSuppServiceNotification is NOT supported in CDMA!");
-    }
-
-    public void
-    acceptCall() throws CallStateException {
-        mCT.acceptCall();
-    }
-
-    public void
-    rejectCall() throws CallStateException {
-        mCT.rejectCall();
-    }
-
-    public void
-    switchHoldingAndActive() throws CallStateException {
-        mCT.switchWaitingOrHoldingAndActive();
-    }
-
-    public String getLine1Number() {
-        return mSST.getMdnNumber();
-    }
-
-    public String getCdmaPrlVersion(){
-        return mSST.getPrlVersion();
-    }
-
-    public String getCdmaMin() {
-        return mSST.getCdmaMin();
-    }
-
-    public boolean isMinInfoReady() {
-        return mSST.isMinInfoReady();
-    }
-
-    public void getCallWaiting(Message onComplete) {
-        mCM.queryCallWaiting(CommandsInterface.SERVICE_CLASS_VOICE, onComplete);
-    }
-
-    public void
-    setRadioPower(boolean power) {
-        mSST.setRadioPower(power);
-    }
-
-    public String getEsn() {
-        return mEsn;
-    }
-
-    public String getMeid() {
-        return mMeid;
-    }
-
-    //returns MEID or ESN in CDMA
-    public String getDeviceId() {
-        String id = getMeid();
-        if ((id == null) || id.matches("^0*$")) {
-            Log.d(LOG_TAG, "getDeviceId(): MEID is not initialized use ESN");
-            id = getEsn();
-        }
-        return id;
-    }
-
-    public String getDeviceSvn() {
-        Log.d(LOG_TAG, "getDeviceSvn(): return 0");
-        return "0";
-    }
-
-    public String getSubscriberId() {
-        return mSST.getImsi();
-    }
-
-    public String getImei() {
-        Log.e(LOG_TAG, "IMEI is not available in CDMA");
-        return null;
-    }
-
-    public boolean canConference() {
-        Log.e(LOG_TAG, "canConference: not possible in CDMA");
-        return false;
-    }
-
-    public CellLocation getCellLocation() {
-        return mSST.cellLoc;
-    }
-
-    public CdmaCall getForegroundCall() {
-        return mCT.foregroundCall;
-    }
-
-    public void
-    selectNetworkManually(OperatorInfo network,
-            Message response) {
-        Log.e(LOG_TAG, "selectNetworkManually: not possible in CDMA");
-    }
-
-    public void setOnPostDialCharacter(Handler h, int what, Object obj) {
-        mPostDialHandler = new Registrant(h, what, obj);
-    }
-
-    public boolean handlePinMmi(String dialString) {
-        CdmaMmiCode mmi = CdmaMmiCode.newFromDialString(dialString, this);
-
-        if (mmi == null) {
-            Log.e(LOG_TAG, "Mmi is NULL!");
-            return false;
-        } else if (mmi.isPukCommand()) {
-            mPendingMmis.add(mmi);
-            mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
-            mmi.processCode();
-            return true;
-        }
-        Log.e(LOG_TAG, "Unrecognized mmi!");
-        return false;
-    }
-
-    /**
-     * Removes the given MMI from the pending list and notifies registrants that
-     * it is complete.
-     *
-     * @param mmi MMI that is done
-     */
-    void onMMIDone(CdmaMmiCode mmi) {
-        /*
-         * Only notify complete if it's on the pending list. Otherwise, it's
-         * already been handled (eg, previously canceled).
-         */
-        if (mPendingMmis.remove(mmi)) {
-            mMmiCompleteRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
-        }
-    }
-
-    public void setLine1Number(String alphaTag, String number, Message onComplete) {
-        Log.e(LOG_TAG, "setLine1Number: not possible in CDMA");
-    }
-
-    public void setCallWaiting(boolean enable, Message onComplete) {
-        Log.e(LOG_TAG, "method setCallWaiting is NOT supported in CDMA!");
-    }
-
-    public void updateServiceLocation() {
-        mSST.enableSingleLocationUpdate();
-    }
-
-    public void setDataRoamingEnabled(boolean enable) {
-        mDataConnectionTracker.setDataOnRoamingEnabled(enable);
-    }
-
-    public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) {
-        mCM.registerForCdmaOtaProvision(h, what, obj);
-    }
-
-    public void unregisterForCdmaOtaStatusChange(Handler h) {
-        mCM.unregisterForCdmaOtaProvision(h);
-    }
-
-    public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
-        mSST.registerForSubscriptionInfoReady(h, what, obj);
-    }
-
-    public void unregisterForSubscriptionInfoReady(Handler h) {
-        mSST.unregisterForSubscriptionInfoReady(h);
-    }
-
-    public void setOnEcbModeExitResponse(Handler h, int what, Object obj) {
-        mEcmExitRespRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unsetOnEcbModeExitResponse(Handler h) {
-        mEcmExitRespRegistrant.clear();
-    }
-
-    public void registerForCallWaiting(Handler h, int what, Object obj) {
-        mCT.registerForCallWaiting(h, what, obj);
-    }
-
-    public void unregisterForCallWaiting(Handler h) {
-        mCT.unregisterForCallWaiting(h);
-    }
-
-    public void
-    getNeighboringCids(Message response) {
-        /*
-         * This is currently not implemented.  At least as of June
-         * 2009, there is no neighbor cell information available for
-         * CDMA because some party is resisting making this
-         * information readily available.  Consequently, calling this
-         * function can have no useful effect.  This situation may
-         * (and hopefully will) change in the future.
-         */
-        if (response != null) {
-            CommandException ce = new CommandException(
-                    CommandException.Error.REQUEST_NOT_SUPPORTED);
-            AsyncResult.forMessage(response).exception = ce;
-            response.sendToTarget();
-        }
-    }
-
-    public DataState getDataConnectionState(String apnType) {
-        DataState ret = DataState.DISCONNECTED;
-
-        if (mSST == null) {
-             // Radio Technology Change is ongoning, dispose() and removeReferences() have
-             // already been called
-
-             ret = DataState.DISCONNECTED;
-        } else if (mSST.getCurrentDataConnectionState() != ServiceState.STATE_IN_SERVICE) {
-            // If we're out of service, open TCP sockets may still work
-            // but no data will flow
-            ret = DataState.DISCONNECTED;
-        } else if (mDataConnectionTracker.isApnTypeEnabled(apnType) == false ||
-                mDataConnectionTracker.isApnTypeActive(apnType) == false) {
-            ret = DataState.DISCONNECTED;
-        } else {
-            switch (mDataConnectionTracker.getState(apnType)) {
-                case FAILED:
-                case IDLE:
-                    ret = DataState.DISCONNECTED;
-                break;
-
-                case CONNECTED:
-                case DISCONNECTING:
-                    if ( mCT.state != Phone.State.IDLE
-                            && !mSST.isConcurrentVoiceAndDataAllowed()) {
-                        ret = DataState.SUSPENDED;
-                    } else {
-                        ret = DataState.CONNECTED;
-                    }
-                break;
-
-                case INITING:
-                case CONNECTING:
-                case SCANNING:
-                    ret = DataState.CONNECTING;
-                break;
-            }
-        }
-
-        log("getDataConnectionState apnType=" + apnType + " ret=" + ret);
-        return ret;
-    }
-
-    public void sendUssdResponse(String ussdMessge) {
-        Log.e(LOG_TAG, "sendUssdResponse: not possible in CDMA");
-    }
-
-    public void sendDtmf(char c) {
-        if (!PhoneNumberUtils.is12Key(c)) {
-            Log.e(LOG_TAG,
-                    "sendDtmf called with invalid character '" + c + "'");
-        } else {
-            if (mCT.state ==  Phone.State.OFFHOOK) {
-                mCM.sendDtmf(c, null);
-            }
-        }
-    }
-
-    public void startDtmf(char c) {
-        if (!PhoneNumberUtils.is12Key(c)) {
-            Log.e(LOG_TAG,
-                    "startDtmf called with invalid character '" + c + "'");
-        } else {
-            mCM.startDtmf(c, null);
-        }
-    }
-
-    public void stopDtmf() {
-        mCM.stopDtmf(null);
-    }
-
-    public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) {
-        boolean check = true;
-        for (int itr = 0;itr < dtmfString.length(); itr++) {
-            if (!PhoneNumberUtils.is12Key(dtmfString.charAt(itr))) {
-                Log.e(LOG_TAG,
-                        "sendDtmf called with invalid character '" + dtmfString.charAt(itr)+ "'");
-                check = false;
-                break;
-            }
-        }
-        if ((mCT.state ==  Phone.State.OFFHOOK)&&(check)) {
-            mCM.sendBurstDtmf(dtmfString, on, off, onComplete);
-        }
-     }
-
-    public void getAvailableNetworks(Message response) {
-        Log.e(LOG_TAG, "getAvailableNetworks: not possible in CDMA");
-    }
-
-    public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode, Message onComplete) {
-        Log.e(LOG_TAG, "setOutgoingCallerIdDisplay: not possible in CDMA");
-    }
-
-    public void enableLocationUpdates() {
-        mSST.enableLocationUpdates();
-    }
-
-    public void disableLocationUpdates() {
-        mSST.disableLocationUpdates();
-    }
-
-    public void getDataCallList(Message response) {
-        mCM.getDataCallList(response);
-    }
-
-    public boolean getDataRoamingEnabled() {
-        return mDataConnectionTracker.getDataOnRoamingEnabled();
-    }
-
-    public void setVoiceMailNumber(String alphaTag,
-                                   String voiceMailNumber,
-                                   Message onComplete) {
-        Message resp;
-        mVmNumber = voiceMailNumber;
-        resp = obtainMessage(EVENT_SET_VM_NUMBER_DONE, 0, 0, onComplete);
-        mIccRecords.setVoiceMailNumber(alphaTag, mVmNumber, resp);
-    }
-
-    public String getVoiceMailNumber() {
-        String number = null;
-        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
-        // TODO: The default value of voicemail number should be read from a system property
-
-        // Read platform settings for dynamic voicemail number
-        if (getContext().getResources().getBoolean(com.android.internal
-                .R.bool.config_telephony_use_own_number_for_voicemail)) {
-            number = sp.getString(VM_NUMBER_CDMA, getLine1Number());
-        } else {
-            number = sp.getString(VM_NUMBER_CDMA, "*86");
-        }
-        return number;
-    }
-
-    /* Returns Number of Voicemails
-     * @hide
-     */
-    public int getVoiceMessageCount() {
-        int voicemailCount =  mIccRecords.getVoiceMessageCount();
-        // If mRuimRecords.getVoiceMessageCount returns zero, then there is possibility
-        // that phone was power cycled and would have lost the voicemail count.
-        // So get the count from preferences.
-        if (voicemailCount == 0) {
-            SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
-            voicemailCount = sp.getInt(VM_COUNT_CDMA, 0);
-        }
-        return voicemailCount;
-    }
-
-    public String getVoiceMailAlphaTag() {
-        // TODO: Where can we get this value has to be clarified with QC.
-        String ret = "";//TODO: Remove = "", if we know where to get this value.
-
-        //ret = mSIMRecords.getVoiceMailAlphaTag();
-
-        if (ret == null || ret.length() == 0) {
-            return mContext.getText(
-                com.android.internal.R.string.defaultVoiceMailAlphaTag).toString();
-        }
-
-        return ret;
-    }
-
-    public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) {
-        Log.e(LOG_TAG, "getCallForwardingOption: not possible in CDMA");
-    }
-
-    public void setCallForwardingOption(int commandInterfaceCFAction,
-            int commandInterfaceCFReason,
-            String dialingNumber,
-            int timerSeconds,
-            Message onComplete) {
-        Log.e(LOG_TAG, "setCallForwardingOption: not possible in CDMA");
-    }
-
-    public void
-    getOutgoingCallerIdDisplay(Message onComplete) {
-        Log.e(LOG_TAG, "getOutgoingCallerIdDisplay: not possible in CDMA");
-    }
-
-    public boolean
-    getCallForwardingIndicator() {
-        Log.e(LOG_TAG, "getCallForwardingIndicator: not possible in CDMA");
-        return false;
-    }
-
-    public void explicitCallTransfer() {
-        Log.e(LOG_TAG, "explicitCallTransfer: not possible in CDMA");
-    }
-
-    public String getLine1AlphaTag() {
-        Log.e(LOG_TAG, "getLine1AlphaTag: not possible in CDMA");
-        return null;
-    }
-
-    /**
-     * Notify any interested party of a Phone state change  {@link Phone.State}
-     */
-    /*package*/ void notifyPhoneStateChanged() {
-        mNotifier.notifyPhoneState(this);
-    }
-
-    /**
-     * Notify registrants of a change in the call state. This notifies changes in {@link Call.State}
-     * Use this when changes in the precise call state are needed, else use notifyPhoneStateChanged.
-     */
-    /*package*/ void notifyPreciseCallStateChanged() {
-        /* we'd love it if this was package-scoped*/
-        super.notifyPreciseCallStateChangedP();
-    }
-
-     void notifyServiceStateChanged(ServiceState ss) {
-         super.notifyServiceStateChangedP(ss);
-     }
-
-     void notifyLocationChanged() {
-         mNotifier.notifyCellLocation(this);
-     }
-
-    /*package*/ void notifyNewRingingConnection(Connection c) {
-        /* we'd love it if this was package-scoped*/
-        super.notifyNewRingingConnectionP(c);
-    }
-
-    /*package*/ void notifyDisconnect(Connection cn) {
-        mDisconnectRegistrants.notifyResult(cn);
-    }
-
-    void notifyUnknownConnection() {
-        mUnknownConnectionRegistrants.notifyResult(this);
-    }
-
-    public boolean isInEmergencyCall() {
-        return mCT.isInEmergencyCall();
-    }
-
-    public boolean isInEcm() {
-        return mIsPhoneInEcmState;
-    }
-
-    void sendEmergencyCallbackModeChange(){
-        //Send an Intent
-        Intent intent = new Intent(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
-        intent.putExtra(PHONE_IN_ECM_STATE, mIsPhoneInEcmState);
-        ActivityManagerNative.broadcastStickyIntent(intent,null);
-        if (DBG) Log.d(LOG_TAG, "sendEmergencyCallbackModeChange");
-    }
-
-    @Override
-    public void exitEmergencyCallbackMode() {
-        if (mWakeLock.isHeld()) {
-            mWakeLock.release();
-        }
-        // Send a message which will invoke handleExitEmergencyCallbackMode
-        mCM.exitEmergencyCallbackMode(obtainMessage(EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE));
-    }
-
-    private void handleEnterEmergencyCallbackMode(Message msg) {
-        if (DBG) {
-            Log.d(LOG_TAG, "handleEnterEmergencyCallbackMode,mIsPhoneInEcmState= "
-                    + mIsPhoneInEcmState);
-        }
-        // if phone is not in Ecm mode, and it's changed to Ecm mode
-        if (mIsPhoneInEcmState == false) {
-            mIsPhoneInEcmState = true;
-            // notify change
-            sendEmergencyCallbackModeChange();
-            setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "true");
-
-            // Post this runnable so we will automatically exit
-            // if no one invokes exitEmergencyCallbackMode() directly.
-            long delayInMillis = SystemProperties.getLong(
-                    TelephonyProperties.PROPERTY_ECM_EXIT_TIMER, DEFAULT_ECM_EXIT_TIMER_VALUE);
-            postDelayed(mExitEcmRunnable, delayInMillis);
-            // We don't want to go to sleep while in Ecm
-            mWakeLock.acquire();
-        }
-    }
-
-    private void handleExitEmergencyCallbackMode(Message msg) {
-        AsyncResult ar = (AsyncResult)msg.obj;
-        if (DBG) {
-            Log.d(LOG_TAG, "handleExitEmergencyCallbackMode,ar.exception , mIsPhoneInEcmState "
-                    + ar.exception + mIsPhoneInEcmState);
-        }
-        // Remove pending exit Ecm runnable, if any
-        removeCallbacks(mExitEcmRunnable);
-
-        if (mEcmExitRespRegistrant != null) {
-            mEcmExitRespRegistrant.notifyRegistrant(ar);
-        }
-        // if exiting ecm success
-        if (ar.exception == null) {
-            if (mIsPhoneInEcmState) {
-                mIsPhoneInEcmState = false;
-                setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "false");
-            }
-            // send an Intent
-            sendEmergencyCallbackModeChange();
-            // Re-initiate data connection
-            mDataConnectionTracker.setInternalDataEnabled(true);
-        }
-    }
-
-    /**
-     * Handle to cancel or restart Ecm timer in emergency call back mode
-     * if action is CANCEL_ECM_TIMER, cancel Ecm timer and notify apps the timer is canceled;
-     * otherwise, restart Ecm timer and notify apps the timer is restarted.
-     */
-    void handleTimerInEmergencyCallbackMode(int action) {
-        switch(action) {
-        case CANCEL_ECM_TIMER:
-            removeCallbacks(mExitEcmRunnable);
-            mEcmTimerResetRegistrants.notifyResult(Boolean.TRUE);
-            break;
-        case RESTART_ECM_TIMER:
-            long delayInMillis = SystemProperties.getLong(
-                    TelephonyProperties.PROPERTY_ECM_EXIT_TIMER, DEFAULT_ECM_EXIT_TIMER_VALUE);
-            postDelayed(mExitEcmRunnable, delayInMillis);
-            mEcmTimerResetRegistrants.notifyResult(Boolean.FALSE);
-            break;
-        default:
-            Log.e(LOG_TAG, "handleTimerInEmergencyCallbackMode, unsupported action " + action);
-        }
-    }
-
-    /**
-     * Registration point for Ecm timer reset
-     * @param h handler to notify
-     * @param what User-defined message code
-     * @param obj placed in Message.obj
-     */
-    public void registerForEcmTimerReset(Handler h, int what, Object obj) {
-        mEcmTimerResetRegistrants.addUnique(h, what, obj);
-    }
-
-    public void unregisterForEcmTimerReset(Handler h) {
-        mEcmTimerResetRegistrants.remove(h);
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-        AsyncResult ar;
-        Message     onComplete;
-
-        switch(msg.what) {
-            case EVENT_RADIO_AVAILABLE: {
-                mCM.getBasebandVersion(obtainMessage(EVENT_GET_BASEBAND_VERSION_DONE));
-
-                mCM.getDeviceIdentity(obtainMessage(EVENT_GET_DEVICE_IDENTITY_DONE));
-            }
-            break;
-
-            case EVENT_GET_BASEBAND_VERSION_DONE:{
-                ar = (AsyncResult)msg.obj;
-
-                if (ar.exception != null) {
-                    break;
-                }
-
-                if (DBG) Log.d(LOG_TAG, "Baseband version: " + ar.result);
-                setSystemProperty(TelephonyProperties.PROPERTY_BASEBAND_VERSION, (String)ar.result);
-            }
-            break;
-
-            case EVENT_GET_DEVICE_IDENTITY_DONE:{
-                ar = (AsyncResult)msg.obj;
-
-                if (ar.exception != null) {
-                    break;
-                }
-                String[] respId = (String[])ar.result;
-                mImei = respId[0];
-                mImeiSv = respId[1];
-                mEsn  =  respId[2];
-                mMeid =  respId[3];
-            }
-            break;
-
-            case EVENT_EMERGENCY_CALLBACK_MODE_ENTER:{
-                handleEnterEmergencyCallbackMode(msg);
-            }
-            break;
-
-            case EVENT_ICC_RECORD_EVENTS:
-                ar = (AsyncResult)msg.obj;
-                processIccRecordEvents((Integer)ar.result);
-                break;
-
-            case  EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE:{
-                handleExitEmergencyCallbackMode(msg);
-            }
-            break;
-
-            case EVENT_RUIM_RECORDS_LOADED:{
-                Log.d(LOG_TAG, "Event EVENT_RUIM_RECORDS_LOADED Received");
-                updateCurrentCarrierInProvider();
-            }
-            break;
-
-            case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:{
-                Log.d(LOG_TAG, "Event EVENT_RADIO_OFF_OR_NOT_AVAILABLE Received");
-            }
-            break;
-
-            case EVENT_RADIO_ON:{
-                Log.d(LOG_TAG, "Event EVENT_RADIO_ON Received");
-                handleCdmaSubscriptionSource(mCdmaSSM.getCdmaSubscriptionSource());
-            }
-            break;
-
-            case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:{
-                Log.d(LOG_TAG, "EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED");
-                handleCdmaSubscriptionSource(mCdmaSSM.getCdmaSubscriptionSource());
-            }
-            break;
-
-            case EVENT_SSN:{
-                Log.d(LOG_TAG, "Event EVENT_SSN Received");
-            }
-            break;
-
-            case EVENT_REGISTERED_TO_NETWORK:{
-                Log.d(LOG_TAG, "Event EVENT_REGISTERED_TO_NETWORK Received");
-            }
-            break;
-
-            case EVENT_NV_READY:{
-                Log.d(LOG_TAG, "Event EVENT_NV_READY Received");
-                prepareEri();
-            }
-            break;
-
-            case EVENT_SET_VM_NUMBER_DONE:{
-                ar = (AsyncResult)msg.obj;
-                if (IccException.class.isInstance(ar.exception)) {
-                    storeVoiceMailNumber(mVmNumber);
-                    ar.exception = null;
-                }
-                onComplete = (Message) ar.userObj;
-                if (onComplete != null) {
-                    AsyncResult.forMessage(onComplete, ar.result, ar.exception);
-                    onComplete.sendToTarget();
-                }
-            }
-            break;
-
-            default:{
-                super.handleMessage(msg);
-            }
-        }
-    }
-
-    private void processIccRecordEvents(int eventCode) {
-        switch (eventCode) {
-            case RuimRecords.EVENT_MWI:
-                notifyMessageWaitingIndicator();
-                break;
-
-            default:
-                Log.e(LOG_TAG,"Unknown icc records event code " + eventCode);
-                break;
-        }
-    }
-
-    /**
-     * Handles the call to get the subscription source
-     *
-     * @param newSubscriptionSource holds the new CDMA subscription source value
-     */
-    private void handleCdmaSubscriptionSource(int newSubscriptionSource) {
-        if (newSubscriptionSource != mCdmaSubscriptionSource) {
-             mCdmaSubscriptionSource = newSubscriptionSource;
-             if (newSubscriptionSource == CDMA_SUBSCRIPTION_NV) {
-                 // NV is ready when subscription source is NV
-                 sendMessage(obtainMessage(EVENT_NV_READY));
-             }
-        }
-    }
-
-    /**
-     * Retrieves the PhoneSubInfo of the CDMAPhone
-     */
-    public PhoneSubInfo getPhoneSubInfo() {
-        return mSubInfo;
-    }
-
-    /**
-     * Retrieves the IccSmsInterfaceManager of the CDMAPhone
-     */
-    public IccSmsInterfaceManager getIccSmsInterfaceManager() {
-        return mRuimSmsInterfaceManager;
-    }
-
-    /**
-     * Retrieves the IccPhoneBookInterfaceManager of the CDMAPhone
-     */
-    public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager() {
-        return mRuimPhoneBookInterfaceManager;
-    }
-
-    public void registerForEriFileLoaded(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mEriFileLoadedRegistrants.add(r);
-    }
-
-    public void unregisterForEriFileLoaded(Handler h) {
-        mEriFileLoadedRegistrants.remove(h);
-    }
-
-    // override for allowing access from other classes of this package
-    /**
-     * {@inheritDoc}
-     */
-    public final void setSystemProperty(String property, String value) {
-        super.setSystemProperty(property, value);
-    }
-
-    /**
-     * Activate or deactivate cell broadcast SMS.
-     *
-     * @param activate 0 = activate, 1 = deactivate
-     * @param response Callback message is empty on completion
-     */
-    public void activateCellBroadcastSms(int activate, Message response) {
-        Log.e(LOG_TAG, "[CDMAPhone] activateCellBroadcastSms() is obsolete; use SmsManager");
-        response.sendToTarget();
-    }
-
-    /**
-     * Query the current configuration of cdma cell broadcast SMS.
-     *
-     * @param response Callback message is empty on completion
-     */
-    public void getCellBroadcastSmsConfig(Message response) {
-        Log.e(LOG_TAG, "[CDMAPhone] getCellBroadcastSmsConfig() is obsolete; use SmsManager");
-        response.sendToTarget();
-    }
-
-    /**
-     * Configure cdma cell broadcast SMS.
-     *
-     * @param response Callback message is empty on completion
-     */
-    public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response) {
-        Log.e(LOG_TAG, "[CDMAPhone] setCellBroadcastSmsConfig() is obsolete; use SmsManager");
-        response.sendToTarget();
-    }
-
-    /**
-     * Returns true if OTA Service Provisioning needs to be performed.
-     */
-    @Override
-    public boolean needsOtaServiceProvisioning() {
-        return mSST.getOtasp() != ServiceStateTracker.OTASP_NOT_NEEDED;
-    }
-
-    private static final String IS683A_FEATURE_CODE = "*228";
-    private static final int IS683A_FEATURE_CODE_NUM_DIGITS = 4;
-    private static final int IS683A_SYS_SEL_CODE_NUM_DIGITS = 2;
-    private static final int IS683A_SYS_SEL_CODE_OFFSET = 4;
-
-    private static final int IS683_CONST_800MHZ_A_BAND = 0;
-    private static final int IS683_CONST_800MHZ_B_BAND = 1;
-    private static final int IS683_CONST_1900MHZ_A_BLOCK = 2;
-    private static final int IS683_CONST_1900MHZ_B_BLOCK = 3;
-    private static final int IS683_CONST_1900MHZ_C_BLOCK = 4;
-    private static final int IS683_CONST_1900MHZ_D_BLOCK = 5;
-    private static final int IS683_CONST_1900MHZ_E_BLOCK = 6;
-    private static final int IS683_CONST_1900MHZ_F_BLOCK = 7;
-    private static final int INVALID_SYSTEM_SELECTION_CODE = -1;
-
-    private static boolean isIs683OtaSpDialStr(String dialStr) {
-        int sysSelCodeInt;
-        boolean isOtaspDialString = false;
-        int dialStrLen = dialStr.length();
-
-        if (dialStrLen == IS683A_FEATURE_CODE_NUM_DIGITS) {
-            if (dialStr.equals(IS683A_FEATURE_CODE)) {
-                isOtaspDialString = true;
-            }
-        } else {
-            sysSelCodeInt = extractSelCodeFromOtaSpNum(dialStr);
-            switch (sysSelCodeInt) {
-                case IS683_CONST_800MHZ_A_BAND:
-                case IS683_CONST_800MHZ_B_BAND:
-                case IS683_CONST_1900MHZ_A_BLOCK:
-                case IS683_CONST_1900MHZ_B_BLOCK:
-                case IS683_CONST_1900MHZ_C_BLOCK:
-                case IS683_CONST_1900MHZ_D_BLOCK:
-                case IS683_CONST_1900MHZ_E_BLOCK:
-                case IS683_CONST_1900MHZ_F_BLOCK:
-                    isOtaspDialString = true;
-                    break;
-                default:
-                    break;
-            }
-        }
-        return isOtaspDialString;
-    }
-    /**
-     * This function extracts the system selection code from the dial string.
-     */
-    private static int extractSelCodeFromOtaSpNum(String dialStr) {
-        int dialStrLen = dialStr.length();
-        int sysSelCodeInt = INVALID_SYSTEM_SELECTION_CODE;
-
-        if ((dialStr.regionMatches(0, IS683A_FEATURE_CODE,
-                                   0, IS683A_FEATURE_CODE_NUM_DIGITS)) &&
-            (dialStrLen >= (IS683A_FEATURE_CODE_NUM_DIGITS +
-                            IS683A_SYS_SEL_CODE_NUM_DIGITS))) {
-                // Since we checked the condition above, the system selection code
-                // extracted from dialStr will not cause any exception
-                sysSelCodeInt = Integer.parseInt (
-                                dialStr.substring (IS683A_FEATURE_CODE_NUM_DIGITS,
-                                IS683A_FEATURE_CODE_NUM_DIGITS + IS683A_SYS_SEL_CODE_NUM_DIGITS));
-        }
-        if (DBG) Log.d(LOG_TAG, "extractSelCodeFromOtaSpNum " + sysSelCodeInt);
-        return sysSelCodeInt;
-    }
-
-    /**
-     * This function checks if the system selection code extracted from
-     * the dial string "sysSelCodeInt' is the system selection code specified
-     * in the carrier ota sp number schema "sch".
-     */
-    private static boolean
-    checkOtaSpNumBasedOnSysSelCode (int sysSelCodeInt, String sch[]) {
-        boolean isOtaSpNum = false;
-        try {
-            // Get how many number of system selection code ranges
-            int selRc = Integer.parseInt((String)sch[1]);
-            for (int i = 0; i < selRc; i++) {
-                if (!TextUtils.isEmpty(sch[i+2]) && !TextUtils.isEmpty(sch[i+3])) {
-                    int selMin = Integer.parseInt((String)sch[i+2]);
-                    int selMax = Integer.parseInt((String)sch[i+3]);
-                    // Check if the selection code extracted from the dial string falls
-                    // within any of the range pairs specified in the schema.
-                    if ((sysSelCodeInt >= selMin) && (sysSelCodeInt <= selMax)) {
-                        isOtaSpNum = true;
-                        break;
-                    }
-                }
-            }
-        } catch (NumberFormatException ex) {
-            // If the carrier ota sp number schema is not correct, we still allow dial
-            // and only log the error:
-            Log.e(LOG_TAG, "checkOtaSpNumBasedOnSysSelCode, error", ex);
-        }
-        return isOtaSpNum;
-    }
-
-    // Define the pattern/format for carrier specified OTASP number schema.
-    // It separates by comma and/or whitespace.
-    private static Pattern pOtaSpNumSchema = Pattern.compile("[,\\s]+");
-
-    /**
-     * The following function checks if a dial string is a carrier specified
-     * OTASP number or not by checking against the OTASP number schema stored
-     * in PROPERTY_OTASP_NUM_SCHEMA.
-     *
-     * Currently, there are 2 schemas for carriers to specify the OTASP number:
-     * 1) Use system selection code:
-     *    The schema is:
-     *    SELC,the # of code pairs,min1,max1,min2,max2,...
-     *    e.g "SELC,3,10,20,30,40,60,70" indicates that there are 3 pairs of
-     *    selection codes, and they are {10,20}, {30,40} and {60,70} respectively.
-     *
-     * 2) Use feature code:
-     *    The schema is:
-     *    "FC,length of feature code,feature code".
-     *     e.g "FC,2,*2" indicates that the length of the feature code is 2,
-     *     and the code itself is "*2".
-     */
-    private boolean isCarrierOtaSpNum(String dialStr) {
-        boolean isOtaSpNum = false;
-        int sysSelCodeInt = extractSelCodeFromOtaSpNum(dialStr);
-        if (sysSelCodeInt == INVALID_SYSTEM_SELECTION_CODE) {
-            return isOtaSpNum;
-        }
-        // mCarrierOtaSpNumSchema is retrieved from PROPERTY_OTASP_NUM_SCHEMA:
-        if (!TextUtils.isEmpty(mCarrierOtaSpNumSchema)) {
-            Matcher m = pOtaSpNumSchema.matcher(mCarrierOtaSpNumSchema);
-            if (DBG) {
-                Log.d(LOG_TAG, "isCarrierOtaSpNum,schema" + mCarrierOtaSpNumSchema);
-            }
-
-            if (m.find()) {
-                String sch[] = pOtaSpNumSchema.split(mCarrierOtaSpNumSchema);
-                // If carrier uses system selection code mechanism
-                if (!TextUtils.isEmpty(sch[0]) && sch[0].equals("SELC")) {
-                    if (sysSelCodeInt!=INVALID_SYSTEM_SELECTION_CODE) {
-                        isOtaSpNum=checkOtaSpNumBasedOnSysSelCode(sysSelCodeInt,sch);
-                    } else {
-                        if (DBG) {
-                            Log.d(LOG_TAG, "isCarrierOtaSpNum,sysSelCodeInt is invalid");
-                        }
-                    }
-                } else if (!TextUtils.isEmpty(sch[0]) && sch[0].equals("FC")) {
-                    int fcLen =  Integer.parseInt((String)sch[1]);
-                    String fc = (String)sch[2];
-                    if (dialStr.regionMatches(0,fc,0,fcLen)) {
-                        isOtaSpNum = true;
-                    } else {
-                        if (DBG) Log.d(LOG_TAG, "isCarrierOtaSpNum,not otasp number");
-                    }
-                } else {
-                    if (DBG) {
-                        Log.d(LOG_TAG, "isCarrierOtaSpNum,ota schema not supported" + sch[0]);
-                    }
-                }
-            } else {
-                if (DBG) {
-                    Log.d(LOG_TAG, "isCarrierOtaSpNum,ota schema pattern not right" +
-                          mCarrierOtaSpNumSchema);
-                }
-            }
-        } else {
-            if (DBG) Log.d(LOG_TAG, "isCarrierOtaSpNum,ota schema pattern empty");
-        }
-        return isOtaSpNum;
-    }
-
-    /**
-     * isOTASPNumber: checks a given number against the IS-683A OTASP dial string and carrier
-     * OTASP dial string.
-     *
-     * @param dialStr the number to look up.
-     * @return true if the number is in IS-683A OTASP dial string or carrier OTASP dial string
-     */
-    @Override
-    public  boolean isOtaSpNumber(String dialStr){
-        boolean isOtaSpNum = false;
-        String dialableStr = PhoneNumberUtils.extractNetworkPortionAlt(dialStr);
-        if (dialableStr != null) {
-            isOtaSpNum = isIs683OtaSpDialStr(dialableStr);
-            if (isOtaSpNum == false) {
-                isOtaSpNum = isCarrierOtaSpNum(dialableStr);
-            }
-        }
-        if (DBG) Log.d(LOG_TAG, "isOtaSpNumber " + isOtaSpNum);
-        return isOtaSpNum;
-    }
-
-    @Override
-    public int getCdmaEriIconIndex() {
-        return getServiceState().getCdmaEriIconIndex();
-    }
-
-    /**
-     * Returns the CDMA ERI icon mode,
-     * 0 - ON
-     * 1 - FLASHING
-     */
-    @Override
-    public int getCdmaEriIconMode() {
-        return getServiceState().getCdmaEriIconMode();
-    }
-
-    /**
-     * Returns the CDMA ERI text,
-     */
-    @Override
-    public String getCdmaEriText() {
-        int roamInd = getServiceState().getCdmaRoamingIndicator();
-        int defRoamInd = getServiceState().getCdmaDefaultRoamingIndicator();
-        return mEriManager.getCdmaEriText(roamInd, defRoamInd);
-    }
-
-    /**
-     * Store the voicemail number in preferences
-     */
-    private void storeVoiceMailNumber(String number) {
-        // Update the preference value of voicemail number
-        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
-        SharedPreferences.Editor editor = sp.edit();
-        editor.putString(VM_NUMBER_CDMA, number);
-        editor.apply();
-    }
-
-    /**
-     * Sets PROPERTY_ICC_OPERATOR_ISO_COUNTRY property
-     *
-     */
-    private void setIsoCountryProperty(String operatorNumeric) {
-        if (TextUtils.isEmpty(operatorNumeric)) {
-            setSystemProperty(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, "");
-        } else {
-            String iso = "";
-            try {
-                iso = MccTable.countryCodeForMcc(Integer.parseInt(
-                        operatorNumeric.substring(0,3)));
-            } catch (NumberFormatException ex) {
-                Log.w(LOG_TAG, "countryCodeForMcc error" + ex);
-            } catch (StringIndexOutOfBoundsException ex) {
-                Log.w(LOG_TAG, "countryCodeForMcc error" + ex);
-            }
-
-            setSystemProperty(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, iso);
-        }
-    }
-
-    /**
-     * Sets the "current" field in the telephony provider according to the
-     * build-time operator numeric property
-     *
-     * @return true for success; false otherwise.
-     */
-    boolean updateCurrentCarrierInProvider(String operatorNumeric) {
-        if (!TextUtils.isEmpty(operatorNumeric)) {
-            try {
-                Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current");
-                ContentValues map = new ContentValues();
-                map.put(Telephony.Carriers.NUMERIC, operatorNumeric);
-                log("updateCurrentCarrierInProvider from system: numeric=" + operatorNumeric);
-                getContext().getContentResolver().insert(uri, map);
-
-                // Updates MCC MNC device configuration information
-                MccTable.updateMccMncConfiguration(mContext, operatorNumeric);
-
-                return true;
-            } catch (SQLException e) {
-                Log.e(LOG_TAG, "Can't store current operator", e);
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Sets the "current" field in the telephony provider according to the SIM's operator.
-     * Implemented in {@link CDMALTEPhone} for CDMA/LTE devices.
-     *
-     * @return true for success; false otherwise.
-     */
-    boolean updateCurrentCarrierInProvider() {
-        return true;
-    }
-
-    public void prepareEri() {
-        mEriManager.loadEriFile();
-        if(mEriManager.isEriFileLoaded()) {
-            // when the ERI file is loaded
-            log("ERI read, notify registrants");
-            mEriFileLoadedRegistrants.notifyRegistrants();
-        }
-    }
-
-    public boolean isEriFileLoaded() {
-        return mEriManager.isEriFileLoaded();
-    }
-
-    private void registerForRuimRecordEvents() {
-        mIccRecords.registerForRecordsEvents(this, EVENT_ICC_RECORD_EVENTS, null);
-        mIccRecords.registerForRecordsLoaded(this, EVENT_RUIM_RECORDS_LOADED, null);
-    }
-
-    private void unregisterForRuimRecordEvents() {
-        mIccRecords.unregisterForRecordsEvents(this);
-        mIccRecords.unregisterForRecordsLoaded(this);
-    }
-
-    protected void log(String s) {
-        if (DBG)
-            Log.d(LOG_TAG, "[CDMAPhone] " + s);
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("CDMAPhone extends:");
-        super.dump(fd, pw, args);
-        pw.println(" mVmNumber=" + mVmNumber);
-        pw.println(" mCT=" + mCT);
-        pw.println(" mSST=" + mSST);
-        pw.println(" mCdmaSSM=" + mCdmaSSM);
-        pw.println(" mPendingMmis=" + mPendingMmis);
-        pw.println(" mRuimPhoneBookInterfaceManager=" + mRuimPhoneBookInterfaceManager);
-        pw.println(" mRuimSmsInterfaceManager=" + mRuimSmsInterfaceManager);
-        pw.println(" mCdmaSubscriptionSource=" + mCdmaSubscriptionSource);
-        pw.println(" mSubInfo=" + mSubInfo);
-        pw.println(" mEriManager=" + mEriManager);
-        pw.println(" mWakeLock=" + mWakeLock);
-        pw.println(" mIsPhoneInEcmState=" + mIsPhoneInEcmState);
-        if (VDBG) pw.println(" mImei=" + mImei);
-        if (VDBG) pw.println(" mImeiSv=" + mImeiSv);
-        if (VDBG) pw.println(" mEsn=" + mEsn);
-        if (VDBG) pw.println(" mMeid=" + mMeid);
-        pw.println(" mCarrierOtaSpNumSchema=" + mCarrierOtaSpNumSchema);
-        pw.println(" getCdmaEriIconIndex()=" + getCdmaEriIconIndex());
-        pw.println(" getCdmaEriIconMode()=" + getCdmaEriIconMode());
-        pw.println(" getCdmaEriText()=" + getCdmaEriText());
-        pw.println(" isMinInfoReady()=" + isMinInfoReady());
-        pw.println(" isCspPlmnEnabled()=" + isCspPlmnEnabled());
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java b/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java
deleted file mode 100644
index ad6c23c..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java
+++ /dev/null
@@ -1,59 +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.internal.telephony.cdma;
-
-/**
- * CDMA Call fail causes covering all the possible failures that are
- * needed to be distinguished by the UI. CDMA call failure reasons
- * are derived from the possible call failure scenarios described
- * in "CDMA IS2000 - Release A (C.S0005-A v6.0)" standard.
- *
- * {@hide}
- *
- */
-public interface CallFailCause {
-    static final int NORMAL_CLEARING                = 16;
-    // Busy Tone
-    static final int USER_BUSY                      = 17;
-
-    static final int NORMAL_UNSPECIFIED             = 31;
-
-    // Congestion Tone
-    static final int NO_CIRCUIT_AVAIL               = 34;
-
-    // others
-    static final int ACM_LIMIT_EXCEEDED             = 68;
-    static final int CALL_BARRED                    = 240;
-    static final int FDN_BLOCKED                    = 241;
-
-    static final int CDMA_LOCKED_UNTIL_POWER_CYCLE  = 1000;
-    static final int CDMA_DROP                      = 1001;
-    static final int CDMA_INTERCEPT                 = 1002;
-    static final int CDMA_REORDER                   = 1003;
-    static final int CDMA_SO_REJECT                 = 1004;
-    static final int CDMA_RETRY_ORDER               = 1005;
-    static final int CDMA_ACCESS_FAILURE            = 1006;
-    static final int CDMA_PREEMPTED                 = 1007;
-
-    // For non-emergency number dialed while in emergency callback mode.
-    static final int CDMA_NOT_EMERGENCY             = 1008;
-
-    // Access Blocked by CDMA Network.
-    static final int CDMA_ACCESS_BLOCKED            = 1009;
-
-    static final int ERROR_UNSPECIFIED = 0xffff;
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java
deleted file mode 100644
index 4ad61bb..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java
+++ /dev/null
@@ -1,208 +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.internal.telephony.cdma;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallStateException;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.DriverCall;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.Call.State;
-
-/**
- * {@hide}
- */
-public final class CdmaCall extends Call {
-    /*************************** Instance Variables **************************/
-
-    /*package*/ ArrayList<Connection> connections = new ArrayList<Connection>();
-    /*package*/ State state = State.IDLE;
-    /*package*/ CdmaCallTracker owner;
-
-    /***************************** Class Methods *****************************/
-
-    static State
-    stateFromDCState (DriverCall.State dcState) {
-        switch (dcState) {
-            case ACTIVE:        return State.ACTIVE;
-            case HOLDING:       return State.HOLDING;
-            case DIALING:       return State.DIALING;
-            case ALERTING:      return State.ALERTING;
-            case INCOMING:      return State.INCOMING;
-            case WAITING:       return State.WAITING;
-            default:            throw new RuntimeException ("illegal call state:" + dcState);
-        }
-    }
-
-
-    /****************************** Constructors *****************************/
-    /*package*/
-    CdmaCall (CdmaCallTracker owner) {
-        this.owner = owner;
-    }
-
-    public void dispose() {
-    }
-
-    /************************** Overridden from Call *************************/
-    public List<Connection>
-    getConnections() {
-        // FIXME should return Collections.unmodifiableList();
-        return connections;
-    }
-
-    public State
-    getState() {
-        return state;
-    }
-
-    public Phone
-    getPhone() {
-        return owner.phone;
-    }
-
-    public boolean isMultiparty() {
-        return connections.size() > 1;
-    }
-
-    /** Please note: if this is the foreground call and a
-     *  background call exists, the background call will be resumed
-     *  because an AT+CHLD=1 will be sent
-     */
-    public void
-    hangup() throws CallStateException {
-        owner.hangup(this);
-    }
-
-    public String
-    toString() {
-        return state.toString();
-    }
-
-    //***** Called from CdmaConnection
-
-    /*package*/ void
-    attach(Connection conn, DriverCall dc) {
-        connections.add(conn);
-
-        state = stateFromDCState (dc.state);
-    }
-
-    /*package*/ void
-    attachFake(Connection conn, State state) {
-        connections.add(conn);
-
-        this.state = state;
-    }
-
-    /**
-     * Called by CdmaConnection when it has disconnected
-     */
-    void
-    connectionDisconnected(CdmaConnection conn) {
-        if (state != State.DISCONNECTED) {
-            /* If only disconnected connections remain, we are disconnected*/
-
-            boolean hasOnlyDisconnectedConnections = true;
-
-            for (int i = 0, s = connections.size()  ; i < s; i ++) {
-                if (connections.get(i).getState()
-                    != State.DISCONNECTED
-                ) {
-                    hasOnlyDisconnectedConnections = false;
-                    break;
-                }
-            }
-
-            if (hasOnlyDisconnectedConnections) {
-                state = State.DISCONNECTED;
-            }
-        }
-    }
-
-
-    /*package*/ void
-    detach(CdmaConnection conn) {
-        connections.remove(conn);
-
-        if (connections.size() == 0) {
-            state = State.IDLE;
-        }
-    }
-
-    /*package*/ boolean
-    update (CdmaConnection conn, DriverCall dc) {
-        State newState;
-        boolean changed = false;
-
-        newState = stateFromDCState(dc.state);
-
-        if (newState != state) {
-            state = newState;
-            changed = true;
-        }
-
-        return changed;
-    }
-
-    /**
-     * @return true if there's no space in this call for additional
-     * connections to be added via "conference"
-     */
-    /*package*/ boolean
-    isFull() {
-        return connections.size() == CdmaCallTracker.MAX_CONNECTIONS_PER_CALL;
-    }
-
-    //***** Called from CdmaCallTracker
-
-
-    /**
-     * Called when this Call is being hung up locally (eg, user pressed "end")
-     * Note that at this point, the hangup request has been dispatched to the radio
-     * but no response has yet been received so update() has not yet been called
-     */
-    void
-    onHangupLocal() {
-        for (int i = 0, s = connections.size(); i < s; i++) {
-            CdmaConnection cn = (CdmaConnection)connections.get(i);
-
-            cn.onHangupLocal();
-        }
-        state = State.DISCONNECTING;
-    }
-
-    /**
-     * Called when it's time to clean up disconnected Connection objects
-     */
-   void clearDisconnected() {
-        for (int i = connections.size() - 1 ; i >= 0 ; i--) {
-        CdmaConnection cn = (CdmaConnection)connections.get(i);
-
-            if (cn.getState() == State.DISCONNECTED) {
-                connections.remove(i);
-            }
-        }
-
-        if (connections.size() == 0) {
-            state = State.IDLE;
-        }
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
deleted file mode 100644
index af92b08..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
+++ /dev/null
@@ -1,1162 +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.internal.telephony.cdma;
-
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.ServiceState;
-import android.util.Log;
-import android.os.SystemProperties;
-
-import com.android.internal.telephony.CallStateException;
-import com.android.internal.telephony.CallTracker;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.DriverCall;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.TelephonyProperties;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-
-
-/**
- * {@hide}
- */
-public final class CdmaCallTracker extends CallTracker {
-    static final String LOG_TAG = "CDMA";
-
-    private static final boolean REPEAT_POLLING = false;
-
-    private static final boolean DBG_POLL = false;
-
-    //***** Constants
-
-    static final int MAX_CONNECTIONS = 1;   // only 1 connection allowed in CDMA
-    static final int MAX_CONNECTIONS_PER_CALL = 1; // only 1 connection allowed per call
-
-    //***** Instance Variables
-
-    CdmaConnection connections[] = new CdmaConnection[MAX_CONNECTIONS];
-    RegistrantList voiceCallEndedRegistrants = new RegistrantList();
-    RegistrantList voiceCallStartedRegistrants = new RegistrantList();
-    RegistrantList callWaitingRegistrants =  new RegistrantList();
-
-
-    // connections dropped during last poll
-    ArrayList<CdmaConnection> droppedDuringPoll
-        = new ArrayList<CdmaConnection>(MAX_CONNECTIONS);
-
-    CdmaCall ringingCall = new CdmaCall(this);
-    // A call that is ringing or (call) waiting
-    CdmaCall foregroundCall = new CdmaCall(this);
-    CdmaCall backgroundCall = new CdmaCall(this);
-
-    CdmaConnection pendingMO;
-    boolean hangupPendingMO;
-    boolean pendingCallInEcm=false;
-    boolean mIsInEmergencyCall = false;
-    CDMAPhone phone;
-
-    boolean desiredMute = false;    // false = mute off
-
-    int pendingCallClirMode;
-    Phone.State state = Phone.State.IDLE;
-
-    private boolean mIsEcmTimerCanceled = false;
-
-//    boolean needsPoll;
-
-
-
-    //***** Events
-
-    //***** Constructors
-    CdmaCallTracker(CDMAPhone phone) {
-        this.phone = phone;
-        cm = phone.mCM;
-        cm.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null);
-        cm.registerForOn(this, EVENT_RADIO_AVAILABLE, null);
-        cm.registerForNotAvailable(this, EVENT_RADIO_NOT_AVAILABLE, null);
-        cm.registerForCallWaitingInfo(this, EVENT_CALL_WAITING_INFO_CDMA, null);
-        foregroundCall.setGeneric(false);
-    }
-
-    public void dispose() {
-        cm.unregisterForCallStateChanged(this);
-        cm.unregisterForOn(this);
-        cm.unregisterForNotAvailable(this);
-        cm.unregisterForCallWaitingInfo(this);
-        for(CdmaConnection c : connections) {
-            try {
-                if(c != null) hangup(c);
-            } catch (CallStateException ex) {
-                Log.e(LOG_TAG, "unexpected error on hangup during dispose");
-            }
-        }
-
-        try {
-            if(pendingMO != null) hangup(pendingMO);
-        } catch (CallStateException ex) {
-            Log.e(LOG_TAG, "unexpected error on hangup during dispose");
-        }
-
-        clearDisconnected();
-
-    }
-
-    @Override
-    protected void finalize() {
-        Log.d(LOG_TAG, "CdmaCallTracker finalized");
-    }
-
-    //***** Instance Methods
-
-    //***** Public Methods
-    public void registerForVoiceCallStarted(Handler h, int what, Object obj) {
-        Registrant r = new Registrant(h, what, obj);
-        voiceCallStartedRegistrants.add(r);
-        // Notify if in call when registering
-        if (state != Phone.State.IDLE) {
-            r.notifyRegistrant(new AsyncResult(null, null, null));
-        }
-    }
-    public void unregisterForVoiceCallStarted(Handler h) {
-        voiceCallStartedRegistrants.remove(h);
-    }
-
-    public void registerForVoiceCallEnded(Handler h, int what, Object obj) {
-        Registrant r = new Registrant(h, what, obj);
-        voiceCallEndedRegistrants.add(r);
-    }
-
-    public void unregisterForVoiceCallEnded(Handler h) {
-        voiceCallEndedRegistrants.remove(h);
-    }
-
-    public void registerForCallWaiting(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        callWaitingRegistrants.add(r);
-    }
-
-    public void unregisterForCallWaiting(Handler h) {
-        callWaitingRegistrants.remove(h);
-    }
-
-    private void
-    fakeHoldForegroundBeforeDial() {
-        List<Connection> connCopy;
-
-        // We need to make a copy here, since fakeHoldBeforeDial()
-        // modifies the lists, and we don't want to reverse the order
-        connCopy = (List<Connection>) foregroundCall.connections.clone();
-
-        for (int i = 0, s = connCopy.size() ; i < s ; i++) {
-            CdmaConnection conn = (CdmaConnection)connCopy.get(i);
-
-            conn.fakeHoldBeforeDial();
-        }
-    }
-
-    /**
-     * clirMode is one of the CLIR_ constants
-     */
-    Connection
-    dial (String dialString, int clirMode) throws CallStateException {
-        // note that this triggers call state changed notif
-        clearDisconnected();
-
-        if (!canDial()) {
-            throw new CallStateException("cannot dial in current state");
-        }
-
-        String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
-        boolean isPhoneInEcmMode = inEcm.equals("true");
-        boolean isEmergencyCall =
-                PhoneNumberUtils.isLocalEmergencyNumber(dialString, phone.getContext());
-
-        // Cancel Ecm timer if a second emergency call is originating in Ecm mode
-        if (isPhoneInEcmMode && isEmergencyCall) {
-            handleEcmTimer(phone.CANCEL_ECM_TIMER);
-        }
-
-        // We are initiating a call therefore even if we previously
-        // didn't know the state (i.e. Generic was true) we now know
-        // and therefore can set Generic to false.
-        foregroundCall.setGeneric(false);
-
-        // The new call must be assigned to the foreground call.
-        // That call must be idle, so place anything that's
-        // there on hold
-        if (foregroundCall.getState() == CdmaCall.State.ACTIVE) {
-            return dialThreeWay(dialString);
-        }
-
-        pendingMO = new CdmaConnection(phone.getContext(), checkForTestEmergencyNumber(dialString),
-                this, foregroundCall);
-        hangupPendingMO = false;
-
-        if (pendingMO.address == null || pendingMO.address.length() == 0
-            || pendingMO.address.indexOf(PhoneNumberUtils.WILD) >= 0) {
-            // Phone number is invalid
-            pendingMO.cause = Connection.DisconnectCause.INVALID_NUMBER;
-
-            // handlePollCalls() will notice this call not present
-            // and will mark it as dropped.
-            pollCallsWhenSafe();
-        } else {
-            // Always unmute when initiating a new call
-            setMute(false);
-
-            // Check data call
-            disableDataCallInEmergencyCall(dialString);
-
-            // In Ecm mode, if another emergency call is dialed, Ecm mode will not exit.
-            if(!isPhoneInEcmMode || (isPhoneInEcmMode && isEmergencyCall)) {
-                cm.dial(pendingMO.address, clirMode, obtainCompleteMessage());
-            } else {
-                phone.exitEmergencyCallbackMode();
-                phone.setOnEcbModeExitResponse(this,EVENT_EXIT_ECM_RESPONSE_CDMA, null);
-                pendingCallClirMode=clirMode;
-                pendingCallInEcm=true;
-            }
-        }
-
-        updatePhoneState();
-        phone.notifyPreciseCallStateChanged();
-
-        return pendingMO;
-    }
-
-
-    Connection
-    dial (String dialString) throws CallStateException {
-        return dial(dialString, CommandsInterface.CLIR_DEFAULT);
-    }
-
-    private Connection
-    dialThreeWay (String dialString) {
-        if (!foregroundCall.isIdle()) {
-            // Check data call
-            disableDataCallInEmergencyCall(dialString);
-
-            // Attach the new connection to foregroundCall
-            pendingMO = new CdmaConnection(phone.getContext(),
-                                checkForTestEmergencyNumber(dialString), this, foregroundCall);
-            cm.sendCDMAFeatureCode(pendingMO.address,
-                obtainMessage(EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA));
-            return pendingMO;
-        }
-        return null;
-    }
-
-    void
-    acceptCall() throws CallStateException {
-        if (ringingCall.getState() == CdmaCall.State.INCOMING) {
-            Log.i("phone", "acceptCall: incoming...");
-            // Always unmute when answering a new call
-            setMute(false);
-            cm.acceptCall(obtainCompleteMessage());
-        } else if (ringingCall.getState() == CdmaCall.State.WAITING) {
-            CdmaConnection cwConn = (CdmaConnection)(ringingCall.getLatestConnection());
-
-            // Since there is no network response for supplimentary
-            // service for CDMA, we assume call waiting is answered.
-            // ringing Call state change to idle is in CdmaCall.detach
-            // triggered by updateParent.
-            cwConn.updateParent(ringingCall, foregroundCall);
-            cwConn.onConnectedInOrOut();
-            updatePhoneState();
-            switchWaitingOrHoldingAndActive();
-        } else {
-            throw new CallStateException("phone not ringing");
-        }
-    }
-
-    void
-    rejectCall () throws CallStateException {
-        // AT+CHLD=0 means "release held or UDUB"
-        // so if the phone isn't ringing, this could hang up held
-        if (ringingCall.getState().isRinging()) {
-            cm.rejectCall(obtainCompleteMessage());
-        } else {
-            throw new CallStateException("phone not ringing");
-        }
-    }
-
-    void
-    switchWaitingOrHoldingAndActive() throws CallStateException {
-        // Should we bother with this check?
-        if (ringingCall.getState() == CdmaCall.State.INCOMING) {
-            throw new CallStateException("cannot be in the incoming state");
-        } else if (foregroundCall.getConnections().size() > 1) {
-            flashAndSetGenericTrue();
-        } else {
-            // Send a flash command to CDMA network for putting the other party on hold.
-            // For CDMA networks which do not support this the user would just hear a beep
-            // from the network. For CDMA networks which do support it will put the other
-            // party on hold.
-            cm.sendCDMAFeatureCode("", obtainMessage(EVENT_SWITCH_RESULT));
-        }
-    }
-
-    void
-    conference() throws CallStateException {
-        // Should we be checking state?
-        flashAndSetGenericTrue();
-    }
-
-    void
-    explicitCallTransfer() throws CallStateException {
-        cm.explicitCallTransfer(obtainCompleteMessage(EVENT_ECT_RESULT));
-    }
-
-    void
-    clearDisconnected() {
-        internalClearDisconnected();
-
-        updatePhoneState();
-        phone.notifyPreciseCallStateChanged();
-    }
-
-    boolean
-    canConference() {
-        return foregroundCall.getState() == CdmaCall.State.ACTIVE
-                && backgroundCall.getState() == CdmaCall.State.HOLDING
-                && !backgroundCall.isFull()
-                && !foregroundCall.isFull();
-    }
-
-    boolean
-    canDial() {
-        boolean ret;
-        int serviceState = phone.getServiceState().getState();
-        String disableCall = SystemProperties.get(
-                TelephonyProperties.PROPERTY_DISABLE_CALL, "false");
-
-        ret = (serviceState != ServiceState.STATE_POWER_OFF)
-                && pendingMO == null
-                && !ringingCall.isRinging()
-                && !disableCall.equals("true")
-                && (!foregroundCall.getState().isAlive()
-                    || (foregroundCall.getState() == CdmaCall.State.ACTIVE)
-                    || !backgroundCall.getState().isAlive());
-
-        if (!ret) {
-            log(String.format("canDial is false\n" +
-                              "((serviceState=%d) != ServiceState.STATE_POWER_OFF)::=%s\n" +
-                              "&& pendingMO == null::=%s\n" +
-                              "&& !ringingCall.isRinging()::=%s\n" +
-                              "&& !disableCall.equals(\"true\")::=%s\n" +
-                              "&& (!foregroundCall.getState().isAlive()::=%s\n" +
-                              "   || foregroundCall.getState() == CdmaCall.State.ACTIVE::=%s\n" +
-                              "   ||!backgroundCall.getState().isAlive())::=%s)",
-                    serviceState,
-                    serviceState != ServiceState.STATE_POWER_OFF,
-                    pendingMO == null,
-                    !ringingCall.isRinging(),
-                    !disableCall.equals("true"),
-                    !foregroundCall.getState().isAlive(),
-                    foregroundCall.getState() == CdmaCall.State.ACTIVE,
-                    !backgroundCall.getState().isAlive()));
-        }
-        return ret;
-    }
-
-    boolean
-    canTransfer() {
-        Log.e(LOG_TAG, "canTransfer: not possible in CDMA");
-        return false;
-    }
-
-    //***** Private Instance Methods
-
-    private void
-    internalClearDisconnected() {
-        ringingCall.clearDisconnected();
-        foregroundCall.clearDisconnected();
-        backgroundCall.clearDisconnected();
-    }
-
-    /**
-     * Obtain a message to use for signalling "invoke getCurrentCalls() when
-     * this operation and all other pending operations are complete
-     */
-    private Message
-    obtainCompleteMessage() {
-        return obtainCompleteMessage(EVENT_OPERATION_COMPLETE);
-    }
-
-    /**
-     * Obtain a message to use for signalling "invoke getCurrentCalls() when
-     * this operation and all other pending operations are complete
-     */
-    private Message
-    obtainCompleteMessage(int what) {
-        pendingOperations++;
-        lastRelevantPoll = null;
-        needsPoll = true;
-
-        if (DBG_POLL) log("obtainCompleteMessage: pendingOperations=" +
-                pendingOperations + ", needsPoll=" + needsPoll);
-
-        return obtainMessage(what);
-    }
-
-    private void
-    operationComplete() {
-        pendingOperations--;
-
-        if (DBG_POLL) log("operationComplete: pendingOperations=" +
-                pendingOperations + ", needsPoll=" + needsPoll);
-
-        if (pendingOperations == 0 && needsPoll) {
-            lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
-            cm.getCurrentCalls(lastRelevantPoll);
-        } else if (pendingOperations < 0) {
-            // this should never happen
-            Log.e(LOG_TAG,"CdmaCallTracker.pendingOperations < 0");
-            pendingOperations = 0;
-        }
-    }
-
-
-
-    private void
-    updatePhoneState() {
-        Phone.State oldState = state;
-
-        if (ringingCall.isRinging()) {
-            state = Phone.State.RINGING;
-        } else if (pendingMO != null ||
-                !(foregroundCall.isIdle() && backgroundCall.isIdle())) {
-            state = Phone.State.OFFHOOK;
-        } else {
-            state = Phone.State.IDLE;
-        }
-
-        if (state == Phone.State.IDLE && oldState != state) {
-            voiceCallEndedRegistrants.notifyRegistrants(
-                new AsyncResult(null, null, null));
-        } else if (oldState == Phone.State.IDLE && oldState != state) {
-            voiceCallStartedRegistrants.notifyRegistrants (
-                    new AsyncResult(null, null, null));
-        }
-        if (Phone.DEBUG_PHONE) {
-            log("update phone state, old=" + oldState + " new="+ state);
-        }
-        if (state != oldState) {
-            phone.notifyPhoneStateChanged();
-        }
-    }
-
-    // ***** Overwritten from CallTracker
-
-    protected void
-    handlePollCalls(AsyncResult ar) {
-        List polledCalls;
-
-        if (ar.exception == null) {
-            polledCalls = (List)ar.result;
-        } else if (isCommandExceptionRadioNotAvailable(ar.exception)) {
-            // just a dummy empty ArrayList to cause the loop
-            // to hang up all the calls
-            polledCalls = new ArrayList();
-        } else {
-            // Radio probably wasn't ready--try again in a bit
-            // But don't keep polling if the channel is closed
-            pollCallsAfterDelay();
-            return;
-        }
-
-        Connection newRinging = null; //or waiting
-        boolean hasNonHangupStateChanged = false;   // Any change besides
-                                                    // a dropped connection
-        boolean needsPollDelay = false;
-        boolean unknownConnectionAppeared = false;
-
-        for (int i = 0, curDC = 0, dcSize = polledCalls.size()
-                ; i < connections.length; i++) {
-            CdmaConnection conn = connections[i];
-            DriverCall dc = null;
-
-            // polledCall list is sparse
-            if (curDC < dcSize) {
-                dc = (DriverCall) polledCalls.get(curDC);
-
-                if (dc.index == i+1) {
-                    curDC++;
-                } else {
-                    dc = null;
-                }
-            }
-
-            if (DBG_POLL) log("poll: conn[i=" + i + "]=" +
-                    conn+", dc=" + dc);
-
-            if (conn == null && dc != null) {
-                // Connection appeared in CLCC response that we don't know about
-                if (pendingMO != null && pendingMO.compareTo(dc)) {
-
-                    if (DBG_POLL) log("poll: pendingMO=" + pendingMO);
-
-                    // It's our pending mobile originating call
-                    connections[i] = pendingMO;
-                    pendingMO.index = i;
-                    pendingMO.update(dc);
-                    pendingMO = null;
-
-                    // Someone has already asked to hangup this call
-                    if (hangupPendingMO) {
-                        hangupPendingMO = false;
-                        // Re-start Ecm timer when an uncompleted emergency call ends
-                        if (mIsEcmTimerCanceled) {
-                            handleEcmTimer(phone.RESTART_ECM_TIMER);
-                        }
-
-                        try {
-                            if (Phone.DEBUG_PHONE) log(
-                                    "poll: hangupPendingMO, hangup conn " + i);
-                            hangup(connections[i]);
-                        } catch (CallStateException ex) {
-                            Log.e(LOG_TAG, "unexpected error on hangup");
-                        }
-
-                        // Do not continue processing this poll
-                        // Wait for hangup and repoll
-                        return;
-                    }
-                } else {
-                    if (Phone.DEBUG_PHONE) {
-                        log("pendingMo=" + pendingMO + ", dc=" + dc);
-                    }
-                    // find if the MT call is a new ring or unknown connection
-                    newRinging = checkMtFindNewRinging(dc,i);
-                    if (newRinging == null) {
-                        unknownConnectionAppeared = true;
-                    }
-                    checkAndEnableDataCallAfterEmergencyCallDropped();
-                }
-                hasNonHangupStateChanged = true;
-            } else if (conn != null && dc == null) {
-                // This case means the RIL has no more active call anymore and
-                // we need to clean up the foregroundCall and ringingCall.
-                // Loop through foreground call connections as
-                // it contains the known logical connections.
-                int count = foregroundCall.connections.size();
-                for (int n = 0; n < count; n++) {
-                    if (Phone.DEBUG_PHONE) log("adding fgCall cn " + n + " to droppedDuringPoll");
-                    CdmaConnection cn = (CdmaConnection)foregroundCall.connections.get(n);
-                    droppedDuringPoll.add(cn);
-                }
-                count = ringingCall.connections.size();
-                // Loop through ringing call connections as
-                // it may contain the known logical connections.
-                for (int n = 0; n < count; n++) {
-                    if (Phone.DEBUG_PHONE) log("adding rgCall cn " + n + " to droppedDuringPoll");
-                    CdmaConnection cn = (CdmaConnection)ringingCall.connections.get(n);
-                    droppedDuringPoll.add(cn);
-                }
-                foregroundCall.setGeneric(false);
-                ringingCall.setGeneric(false);
-
-                // Re-start Ecm timer when the connected emergency call ends
-                if (mIsEcmTimerCanceled) {
-                    handleEcmTimer(phone.RESTART_ECM_TIMER);
-                }
-                // If emergency call is not going through while dialing
-                checkAndEnableDataCallAfterEmergencyCallDropped();
-
-                // Dropped connections are removed from the CallTracker
-                // list but kept in the Call list
-                connections[i] = null;
-            } else if (conn != null && dc != null) { /* implicit conn.compareTo(dc) */
-                // Call collision case
-                if (conn.isIncoming != dc.isMT) {
-                    if (dc.isMT == true){
-                        // Mt call takes precedence than Mo,drops Mo
-                        droppedDuringPoll.add(conn);
-                        // find if the MT call is a new ring or unknown connection
-                        newRinging = checkMtFindNewRinging(dc,i);
-                        if (newRinging == null) {
-                            unknownConnectionAppeared = true;
-                        }
-                        checkAndEnableDataCallAfterEmergencyCallDropped();
-                    } else {
-                        // Call info stored in conn is not consistent with the call info from dc.
-                        // We should follow the rule of MT calls taking precedence over MO calls
-                        // when there is conflict, so here we drop the call info from dc and
-                        // continue to use the call info from conn, and only take a log.
-                        Log.e(LOG_TAG,"Error in RIL, Phantom call appeared " + dc);
-                    }
-                } else {
-                    boolean changed;
-                    changed = conn.update(dc);
-                    hasNonHangupStateChanged = hasNonHangupStateChanged || changed;
-                }
-            }
-
-            if (REPEAT_POLLING) {
-                if (dc != null) {
-                    // FIXME with RIL, we should not need this anymore
-                    if ((dc.state == DriverCall.State.DIALING
-                            /*&& cm.getOption(cm.OPTION_POLL_DIALING)*/)
-                        || (dc.state == DriverCall.State.ALERTING
-                            /*&& cm.getOption(cm.OPTION_POLL_ALERTING)*/)
-                        || (dc.state == DriverCall.State.INCOMING
-                            /*&& cm.getOption(cm.OPTION_POLL_INCOMING)*/)
-                        || (dc.state == DriverCall.State.WAITING
-                            /*&& cm.getOption(cm.OPTION_POLL_WAITING)*/)
-                    ) {
-                        // Sometimes there's no unsolicited notification
-                        // for state transitions
-                        needsPollDelay = true;
-                    }
-                }
-            }
-        }
-
-        // This is the first poll after an ATD.
-        // We expect the pending call to appear in the list
-        // If it does not, we land here
-        if (pendingMO != null) {
-            Log.d(LOG_TAG,"Pending MO dropped before poll fg state:"
-                            + foregroundCall.getState());
-
-            droppedDuringPoll.add(pendingMO);
-            pendingMO = null;
-            hangupPendingMO = false;
-            if( pendingCallInEcm) {
-                pendingCallInEcm = false;
-            }
-        }
-
-        if (newRinging != null) {
-            phone.notifyNewRingingConnection(newRinging);
-        }
-
-        // clear the "local hangup" and "missed/rejected call"
-        // cases from the "dropped during poll" list
-        // These cases need no "last call fail" reason
-        for (int i = droppedDuringPoll.size() - 1; i >= 0 ; i--) {
-            CdmaConnection conn = droppedDuringPoll.get(i);
-
-            if (conn.isIncoming() && conn.getConnectTime() == 0) {
-                // Missed or rejected call
-                Connection.DisconnectCause cause;
-                if (conn.cause == Connection.DisconnectCause.LOCAL) {
-                    cause = Connection.DisconnectCause.INCOMING_REJECTED;
-                } else {
-                    cause = Connection.DisconnectCause.INCOMING_MISSED;
-                }
-
-                if (Phone.DEBUG_PHONE) {
-                    log("missed/rejected call, conn.cause=" + conn.cause);
-                    log("setting cause to " + cause);
-                }
-                droppedDuringPoll.remove(i);
-                conn.onDisconnect(cause);
-            } else if (conn.cause == Connection.DisconnectCause.LOCAL) {
-                // Local hangup
-                droppedDuringPoll.remove(i);
-                conn.onDisconnect(Connection.DisconnectCause.LOCAL);
-            } else if (conn.cause == Connection.DisconnectCause.INVALID_NUMBER) {
-                droppedDuringPoll.remove(i);
-                conn.onDisconnect(Connection.DisconnectCause.INVALID_NUMBER);
-            }
-        }
-
-        // Any non-local disconnects: determine cause
-        if (droppedDuringPoll.size() > 0) {
-            cm.getLastCallFailCause(
-                obtainNoPollCompleteMessage(EVENT_GET_LAST_CALL_FAIL_CAUSE));
-        }
-
-        if (needsPollDelay) {
-            pollCallsAfterDelay();
-        }
-
-        // Cases when we can no longer keep disconnected Connection's
-        // with their previous calls
-        // 1) the phone has started to ring
-        // 2) A Call/Connection object has changed state...
-        //    we may have switched or held or answered (but not hung up)
-        if (newRinging != null || hasNonHangupStateChanged) {
-            internalClearDisconnected();
-        }
-
-        updatePhoneState();
-
-        if (unknownConnectionAppeared) {
-            phone.notifyUnknownConnection();
-        }
-
-        if (hasNonHangupStateChanged || newRinging != null) {
-            phone.notifyPreciseCallStateChanged();
-        }
-
-        //dumpState();
-    }
-
-    //***** Called from CdmaConnection
-    /*package*/ void
-    hangup (CdmaConnection conn) throws CallStateException {
-        if (conn.owner != this) {
-            throw new CallStateException ("CdmaConnection " + conn
-                                    + "does not belong to CdmaCallTracker " + this);
-        }
-
-        if (conn == pendingMO) {
-            // We're hanging up an outgoing call that doesn't have it's
-            // GSM index assigned yet
-
-            if (Phone.DEBUG_PHONE) log("hangup: set hangupPendingMO to true");
-            hangupPendingMO = true;
-        } else if ((conn.getCall() == ringingCall)
-                && (ringingCall.getState() == CdmaCall.State.WAITING)) {
-            // Handle call waiting hang up case.
-            //
-            // The ringingCall state will change to IDLE in CdmaCall.detach
-            // if the ringing call connection size is 0. We don't specifically
-            // set the ringing call state to IDLE here to avoid a race condition
-            // where a new call waiting could get a hang up from an old call
-            // waiting ringingCall.
-            //
-            // PhoneApp does the call log itself since only PhoneApp knows
-            // the hangup reason is user ignoring or timing out. So conn.onDisconnect()
-            // is not called here. Instead, conn.onLocalDisconnect() is called.
-            conn.onLocalDisconnect();
-            updatePhoneState();
-            phone.notifyPreciseCallStateChanged();
-            return;
-        } else {
-            try {
-                cm.hangupConnection (conn.getCDMAIndex(), obtainCompleteMessage());
-            } catch (CallStateException ex) {
-                // Ignore "connection not found"
-                // Call may have hung up already
-                Log.w(LOG_TAG,"CdmaCallTracker WARN: hangup() on absent connection "
-                                + conn);
-            }
-        }
-
-        conn.onHangupLocal();
-    }
-
-    /*package*/ void
-    separate (CdmaConnection conn) throws CallStateException {
-        if (conn.owner != this) {
-            throw new CallStateException ("CdmaConnection " + conn
-                                    + "does not belong to CdmaCallTracker " + this);
-        }
-        try {
-            cm.separateConnection (conn.getCDMAIndex(),
-                obtainCompleteMessage(EVENT_SEPARATE_RESULT));
-        } catch (CallStateException ex) {
-            // Ignore "connection not found"
-            // Call may have hung up already
-            Log.w(LOG_TAG,"CdmaCallTracker WARN: separate() on absent connection "
-                          + conn);
-        }
-    }
-
-    //***** Called from CDMAPhone
-
-    /*package*/ void
-    setMute(boolean mute) {
-        desiredMute = mute;
-        cm.setMute(desiredMute, null);
-    }
-
-    /*package*/ boolean
-    getMute() {
-        return desiredMute;
-    }
-
-
-    //***** Called from CdmaCall
-
-    /* package */ void
-    hangup (CdmaCall call) throws CallStateException {
-        if (call.getConnections().size() == 0) {
-            throw new CallStateException("no connections in call");
-        }
-
-        if (call == ringingCall) {
-            if (Phone.DEBUG_PHONE) log("(ringing) hangup waiting or background");
-            cm.hangupWaitingOrBackground(obtainCompleteMessage());
-        } else if (call == foregroundCall) {
-            if (call.isDialingOrAlerting()) {
-                if (Phone.DEBUG_PHONE) {
-                    log("(foregnd) hangup dialing or alerting...");
-                }
-                hangup((CdmaConnection)(call.getConnections().get(0)));
-            } else {
-                hangupForegroundResumeBackground();
-            }
-        } else if (call == backgroundCall) {
-            if (ringingCall.isRinging()) {
-                if (Phone.DEBUG_PHONE) {
-                    log("hangup all conns in background call");
-                }
-                hangupAllConnections(call);
-            } else {
-                hangupWaitingOrBackground();
-            }
-        } else {
-            throw new RuntimeException ("CdmaCall " + call +
-                    "does not belong to CdmaCallTracker " + this);
-        }
-
-        call.onHangupLocal();
-        phone.notifyPreciseCallStateChanged();
-    }
-
-    /* package */
-    void hangupWaitingOrBackground() {
-        if (Phone.DEBUG_PHONE) log("hangupWaitingOrBackground");
-        cm.hangupWaitingOrBackground(obtainCompleteMessage());
-    }
-
-    /* package */
-    void hangupForegroundResumeBackground() {
-        if (Phone.DEBUG_PHONE) log("hangupForegroundResumeBackground");
-        cm.hangupForegroundResumeBackground(obtainCompleteMessage());
-    }
-
-    void hangupConnectionByIndex(CdmaCall call, int index)
-            throws CallStateException {
-        int count = call.connections.size();
-        for (int i = 0; i < count; i++) {
-            CdmaConnection cn = (CdmaConnection)call.connections.get(i);
-            if (cn.getCDMAIndex() == index) {
-                cm.hangupConnection(index, obtainCompleteMessage());
-                return;
-            }
-        }
-
-        throw new CallStateException("no gsm index found");
-    }
-
-    void hangupAllConnections(CdmaCall call) throws CallStateException{
-        try {
-            int count = call.connections.size();
-            for (int i = 0; i < count; i++) {
-                CdmaConnection cn = (CdmaConnection)call.connections.get(i);
-                cm.hangupConnection(cn.getCDMAIndex(), obtainCompleteMessage());
-            }
-        } catch (CallStateException ex) {
-            Log.e(LOG_TAG, "hangupConnectionByIndex caught " + ex);
-        }
-    }
-
-    /* package */
-    CdmaConnection getConnectionByIndex(CdmaCall call, int index)
-            throws CallStateException {
-        int count = call.connections.size();
-        for (int i = 0; i < count; i++) {
-            CdmaConnection cn = (CdmaConnection)call.connections.get(i);
-            if (cn.getCDMAIndex() == index) {
-                return cn;
-            }
-        }
-
-        return null;
-    }
-
-    private void flashAndSetGenericTrue() throws CallStateException {
-        cm.sendCDMAFeatureCode("", obtainMessage(EVENT_SWITCH_RESULT));
-
-        // Set generic to true because in CDMA it is not known what
-        // the status of the call is after a call waiting is answered,
-        // 3 way call merged or a switch between calls.
-        foregroundCall.setGeneric(true);
-        phone.notifyPreciseCallStateChanged();
-    }
-
-    private Phone.SuppService getFailedService(int what) {
-        switch (what) {
-            case EVENT_SWITCH_RESULT:
-                return Phone.SuppService.SWITCH;
-            case EVENT_CONFERENCE_RESULT:
-                return Phone.SuppService.CONFERENCE;
-            case EVENT_SEPARATE_RESULT:
-                return Phone.SuppService.SEPARATE;
-            case EVENT_ECT_RESULT:
-                return Phone.SuppService.TRANSFER;
-        }
-        return Phone.SuppService.UNKNOWN;
-    }
-
-    private void handleRadioNotAvailable() {
-        // handlePollCalls will clear out its
-        // call list when it gets the CommandException
-        // error result from this
-        pollCallsWhenSafe();
-    }
-
-    private void notifyCallWaitingInfo(CdmaCallWaitingNotification obj) {
-        if (callWaitingRegistrants != null) {
-            callWaitingRegistrants.notifyRegistrants(new AsyncResult(null, obj, null));
-        }
-    }
-
-    private void handleCallWaitingInfo (CdmaCallWaitingNotification cw) {
-        // Check how many connections in foregroundCall.
-        // If the connection in foregroundCall is more
-        // than one, then the connection information is
-        // not reliable anymore since it means either
-        // call waiting is connected or 3 way call is
-        // dialed before, so set generic.
-        if (foregroundCall.connections.size() > 1 ) {
-            foregroundCall.setGeneric(true);
-        }
-
-        // Create a new CdmaConnection which attaches itself to ringingCall.
-        ringingCall.setGeneric(false);
-        new CdmaConnection(phone.getContext(), cw, this, ringingCall);
-        updatePhoneState();
-
-        // Finally notify application
-        notifyCallWaitingInfo(cw);
-    }
-    //****** Overridden from Handler
-
-    public void
-    handleMessage (Message msg) {
-        AsyncResult ar;
-
-        switch (msg.what) {
-            case EVENT_POLL_CALLS_RESULT:{
-                Log.d(LOG_TAG, "Event EVENT_POLL_CALLS_RESULT Received");
-                ar = (AsyncResult)msg.obj;
-
-                if(msg == lastRelevantPoll) {
-                    if(DBG_POLL) log(
-                            "handle EVENT_POLL_CALL_RESULT: set needsPoll=F");
-                    needsPoll = false;
-                    lastRelevantPoll = null;
-                    handlePollCalls((AsyncResult)msg.obj);
-                }
-            }
-            break;
-
-            case EVENT_OPERATION_COMPLETE:
-                operationComplete();
-            break;
-
-            case EVENT_SWITCH_RESULT:
-                 // In GSM call operationComplete() here which gets the
-                 // current call list. But in CDMA there is no list so
-                 // there is nothing to do.
-            break;
-
-            case EVENT_GET_LAST_CALL_FAIL_CAUSE:
-                int causeCode;
-                ar = (AsyncResult)msg.obj;
-
-                operationComplete();
-
-                if (ar.exception != null) {
-                    // An exception occurred...just treat the disconnect
-                    // cause as "normal"
-                    causeCode = CallFailCause.NORMAL_CLEARING;
-                    Log.i(LOG_TAG,
-                            "Exception during getLastCallFailCause, assuming normal disconnect");
-                } else {
-                    causeCode = ((int[])ar.result)[0];
-                }
-
-                for (int i = 0, s =  droppedDuringPoll.size()
-                        ; i < s ; i++
-                ) {
-                    CdmaConnection conn = droppedDuringPoll.get(i);
-
-                    conn.onRemoteDisconnect(causeCode);
-                }
-
-                updatePhoneState();
-
-                phone.notifyPreciseCallStateChanged();
-                droppedDuringPoll.clear();
-            break;
-
-            case EVENT_REPOLL_AFTER_DELAY:
-            case EVENT_CALL_STATE_CHANGE:
-                pollCallsWhenSafe();
-            break;
-
-            case EVENT_RADIO_AVAILABLE:
-                handleRadioAvailable();
-            break;
-
-            case EVENT_RADIO_NOT_AVAILABLE:
-                handleRadioNotAvailable();
-            break;
-
-            case EVENT_EXIT_ECM_RESPONSE_CDMA:
-               //no matter the result, we still do the same here
-               if (pendingCallInEcm) {
-                   cm.dial(pendingMO.address, pendingCallClirMode, obtainCompleteMessage());
-                   pendingCallInEcm = false;
-               }
-               phone.unsetOnEcbModeExitResponse(this);
-            break;
-
-            case EVENT_CALL_WAITING_INFO_CDMA:
-               ar = (AsyncResult)msg.obj;
-               if (ar.exception == null) {
-                   handleCallWaitingInfo((CdmaCallWaitingNotification)ar.result);
-                   Log.d(LOG_TAG, "Event EVENT_CALL_WAITING_INFO_CDMA Received");
-               }
-            break;
-
-            case EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA:
-                ar = (AsyncResult)msg.obj;
-                if (ar.exception == null) {
-                    // Assume 3 way call is connected
-                    pendingMO.onConnectedInOrOut();
-                    pendingMO = null;
-                }
-            break;
-
-            default:{
-               throw new RuntimeException("unexpected event not handled");
-            }
-        }
-    }
-
-    /**
-     * Handle Ecm timer to be canceled or re-started
-     */
-    private void handleEcmTimer(int action) {
-        phone.handleTimerInEmergencyCallbackMode(action);
-        switch(action) {
-        case CDMAPhone.CANCEL_ECM_TIMER: mIsEcmTimerCanceled = true; break;
-        case CDMAPhone.RESTART_ECM_TIMER: mIsEcmTimerCanceled = false; break;
-        default:
-            Log.e(LOG_TAG, "handleEcmTimer, unsupported action " + action);
-        }
-    }
-
-    /**
-     * Disable data call when emergency call is connected
-     */
-    private void disableDataCallInEmergencyCall(String dialString) {
-        if (PhoneNumberUtils.isLocalEmergencyNumber(dialString, phone.getContext())) {
-            if (Phone.DEBUG_PHONE) log("disableDataCallInEmergencyCall");
-            mIsInEmergencyCall = true;
-            phone.mDataConnectionTracker.setInternalDataEnabled(false);
-        }
-    }
-
-    /**
-     * Check and enable data call after an emergency call is dropped if it's
-     * not in ECM
-     */
-    private void checkAndEnableDataCallAfterEmergencyCallDropped() {
-        if (mIsInEmergencyCall) {
-            mIsInEmergencyCall = false;
-            String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
-            if (Phone.DEBUG_PHONE) {
-                log("checkAndEnableDataCallAfterEmergencyCallDropped,inEcm=" + inEcm);
-            }
-            if (inEcm.compareTo("false") == 0) {
-                // Re-initiate data connection
-                phone.mDataConnectionTracker.setInternalDataEnabled(true);
-            }
-        }
-    }
-
-    /**
-     * Check the MT call to see if it's a new ring or
-     * a unknown connection.
-     */
-    private Connection checkMtFindNewRinging(DriverCall dc, int i) {
-
-        Connection newRinging = null;
-
-        connections[i] = new CdmaConnection(phone.getContext(), dc, this, i);
-        // it's a ringing call
-        if (connections[i].getCall() == ringingCall) {
-            newRinging = connections[i];
-            if (Phone.DEBUG_PHONE) log("Notify new ring " + dc);
-        } else {
-            // Something strange happened: a call which is neither
-            // a ringing call nor the one we created. It could be the
-            // call collision result from RIL
-            Log.e(LOG_TAG,"Phantom call appeared " + dc);
-            // If it's a connected call, set the connect time so that
-            // it's non-zero.  It may not be accurate, but at least
-            // it won't appear as a Missed Call.
-            if (dc.state != DriverCall.State.ALERTING
-                && dc.state != DriverCall.State.DIALING) {
-                connections[i].connectTime = System.currentTimeMillis();
-            }
-        }
-        return newRinging;
-    }
-
-    /**
-     * Check if current call is in emergency call
-     *
-     * @return true if it is in emergency call
-     *         false if it is not in emergency call
-     */
-    boolean isInEmergencyCall() {
-        return mIsInEmergencyCall;
-    }
-
-    protected void log(String msg) {
-        Log.d(LOG_TAG, "[CdmaCallTracker] " + msg);
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("GsmCallTracker extends:");
-        super.dump(fd, pw, args);
-        pw.println("droppedDuringPoll: length=" + connections.length);
-        for(int i=0; i < connections.length; i++) {
-            pw.printf(" connections[%d]=%s\n", i, connections[i]);
-        }
-        pw.println(" voiceCallEndedRegistrants=" + voiceCallEndedRegistrants);
-        pw.println(" voiceCallStartedRegistrants=" + voiceCallStartedRegistrants);
-        pw.println(" callWaitingRegistrants=" + callWaitingRegistrants);
-        pw.println("droppedDuringPoll: size=" + droppedDuringPoll.size());
-        for(int i = 0; i < droppedDuringPoll.size(); i++) {
-            pw.printf( " droppedDuringPoll[%d]=%s\n", i, droppedDuringPoll.get(i));
-        }
-        pw.println(" ringingCall=" + ringingCall);
-        pw.println(" foregroundCall=" + foregroundCall);
-        pw.println(" backgroundCall=" + backgroundCall);
-        pw.println(" pendingMO=" + pendingMO);
-        pw.println(" hangupPendingMO=" + hangupPendingMO);
-        pw.println(" pendingCallInEcm=" + pendingCallInEcm);
-        pw.println(" mIsInEmergencyCall=" + mIsInEmergencyCall);
-        pw.println(" phone=" + phone);
-        pw.println(" desiredMute=" + desiredMute);
-        pw.println(" pendingCallClirMode=" + pendingCallClirMode);
-        pw.println(" state=" + state);
-        pw.println(" mIsEcmTimerCanceled=" + mIsEcmTimerCanceled);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java
deleted file mode 100644
index 81ff042..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java
+++ /dev/null
@@ -1,68 +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.
- */
-
-package com.android.internal.telephony.cdma;
-
-import android.util.Log;
-import com.android.internal.telephony.Connection;
-
-/**
- * Represents a Supplementary Service Notification received from the network.
- *
- * {@hide}
- */
-public class CdmaCallWaitingNotification {
-    static final String LOG_TAG = "CDMA";
-    public String number = null;
-    public int numberPresentation = 0;
-    public String name = null;
-    public int namePresentation = 0;
-    public int numberType = 0;
-    public int numberPlan = 0;
-    public int isPresent = 0;
-    public int signalType = 0;
-    public int alertPitch = 0;
-    public int signal = 0;
-
-    public String toString()
-    {
-        return super.toString() + "Call Waiting Notification  "
-            + " number: " + number
-            + " numberPresentation: " + numberPresentation
-            + " name: " + name
-            + " namePresentation: " + namePresentation
-            + " numberType: " + numberType
-            + " numberPlan: " + numberPlan
-            + " isPresent: " + isPresent
-            + " signalType: " + signalType
-            + " alertPitch: " + alertPitch
-            + " signal: " + signal ;
-    }
-
-    public static int
-    presentationFromCLIP(int cli)
-    {
-        switch(cli) {
-            case 0: return Connection.PRESENTATION_ALLOWED;
-            case 1: return Connection.PRESENTATION_RESTRICTED;
-            case 2: return Connection.PRESENTATION_UNKNOWN;
-            default:
-                // This shouldn't happen, just log an error and treat as Unknown
-                Log.d(LOG_TAG, "Unexpected presentation " + cli);
-                return Connection.PRESENTATION_UNKNOWN;
-        }
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
deleted file mode 100755
index 98ad3b1..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
+++ /dev/null
@@ -1,955 +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.internal.telephony.cdma;
-
-import com.android.internal.telephony.*;
-import android.content.Context;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.Registrant;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.util.Log;
-import android.text.TextUtils;
-
-import android.telephony.PhoneNumberUtils;
-import android.telephony.ServiceState;
-import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.telephony.RILConstants;
-
-/**
- * {@hide}
- */
-public class CdmaConnection extends Connection {
-    static final String LOG_TAG = "CDMA";
-
-    //***** Instance Variables
-
-    CdmaCallTracker owner;
-    CdmaCall parent;
-
-
-    String address;             // MAY BE NULL!!!
-    String dialString;          // outgoing calls only
-    String postDialString;      // outgoing calls only
-    boolean isIncoming;
-    boolean disconnected;
-    String cnapName;
-    int index;          // index in CdmaCallTracker.connections[], -1 if unassigned
-
-    /*
-     * These time/timespan values are based on System.currentTimeMillis(),
-     * i.e., "wall clock" time.
-     */
-    long createTime;
-    long connectTime;
-    long disconnectTime;
-
-    /*
-     * These time/timespan values are based on SystemClock.elapsedRealTime(),
-     * i.e., time since boot.  They are appropriate for comparison and
-     * calculating deltas.
-     */
-    long connectTimeReal;
-    long duration;
-    long holdingStartTime;  // The time when the Connection last transitioned
-                            // into HOLDING
-
-    int nextPostDialChar;       // index into postDialString
-
-    DisconnectCause cause = DisconnectCause.NOT_DISCONNECTED;
-    PostDialState postDialState = PostDialState.NOT_STARTED;
-    int numberPresentation = Connection.PRESENTATION_ALLOWED;
-    int cnapNamePresentation  = Connection.PRESENTATION_ALLOWED;
-
-
-    Handler h;
-
-    private PowerManager.WakeLock mPartialWakeLock;
-
-    //***** Event Constants
-    static final int EVENT_DTMF_DONE = 1;
-    static final int EVENT_PAUSE_DONE = 2;
-    static final int EVENT_NEXT_POST_DIAL = 3;
-    static final int EVENT_WAKE_LOCK_TIMEOUT = 4;
-
-    //***** Constants
-    static final int WAKE_LOCK_TIMEOUT_MILLIS = 60*1000;
-    static final int PAUSE_DELAY_MILLIS = 2 * 1000;
-
-    //***** Inner Classes
-
-    class MyHandler extends Handler {
-        MyHandler(Looper l) {super(l);}
-
-        public void
-        handleMessage(Message msg) {
-
-            switch (msg.what) {
-                case EVENT_NEXT_POST_DIAL:
-                case EVENT_DTMF_DONE:
-                case EVENT_PAUSE_DONE:
-                    processNextPostDialChar();
-                    break;
-                case EVENT_WAKE_LOCK_TIMEOUT:
-                    releaseWakeLock();
-                    break;
-            }
-        }
-    }
-
-    //***** Constructors
-
-    /** This is probably an MT call that we first saw in a CLCC response */
-    /*package*/
-    CdmaConnection (Context context, DriverCall dc, CdmaCallTracker ct, int index) {
-        createWakeLock(context);
-        acquireWakeLock();
-
-        owner = ct;
-        h = new MyHandler(owner.getLooper());
-
-        address = dc.number;
-
-        isIncoming = dc.isMT;
-        createTime = System.currentTimeMillis();
-        cnapName = dc.name;
-        cnapNamePresentation = dc.namePresentation;
-        numberPresentation = dc.numberPresentation;
-
-        this.index = index;
-
-        parent = parentFromDCState (dc.state);
-        parent.attach(this, dc);
-    }
-
-    /** This is an MO call/three way call, created when dialing */
-    /*package*/
-    CdmaConnection(Context context, String dialString, CdmaCallTracker ct, CdmaCall parent) {
-        createWakeLock(context);
-        acquireWakeLock();
-
-        owner = ct;
-        h = new MyHandler(owner.getLooper());
-
-        this.dialString = dialString;
-        Log.d(LOG_TAG, "[CDMAConn] CdmaConnection: dialString=" + dialString);
-        dialString = formatDialString(dialString);
-        Log.d(LOG_TAG, "[CDMAConn] CdmaConnection:formated dialString=" + dialString);
-
-        this.address = PhoneNumberUtils.extractNetworkPortionAlt(dialString);
-        this.postDialString = PhoneNumberUtils.extractPostDialPortion(dialString);
-
-        index = -1;
-
-        isIncoming = false;
-        cnapName = null;
-        cnapNamePresentation = Connection.PRESENTATION_ALLOWED;
-        numberPresentation = Connection.PRESENTATION_ALLOWED;
-        createTime = System.currentTimeMillis();
-
-        if (parent != null) {
-            this.parent = parent;
-
-            //for the three way call case, not change parent state
-            if (parent.state == CdmaCall.State.ACTIVE) {
-                parent.attachFake(this, CdmaCall.State.ACTIVE);
-            } else {
-                parent.attachFake(this, CdmaCall.State.DIALING);
-            }
-        }
-    }
-
-    /** This is a Call waiting call*/
-    CdmaConnection(Context context, CdmaCallWaitingNotification cw, CdmaCallTracker ct,
-            CdmaCall parent) {
-        createWakeLock(context);
-        acquireWakeLock();
-
-        owner = ct;
-        h = new MyHandler(owner.getLooper());
-        address = cw.number;
-        numberPresentation = cw.numberPresentation;
-        cnapName = cw.name;
-        cnapNamePresentation = cw.namePresentation;
-        index = -1;
-        isIncoming = true;
-        createTime = System.currentTimeMillis();
-        connectTime = 0;
-        this.parent = parent;
-        parent.attachFake(this, CdmaCall.State.WAITING);
-    }
-
-    public void dispose() {
-    }
-
-    static boolean
-    equalsHandlesNulls (Object a, Object b) {
-        return (a == null) ? (b == null) : a.equals (b);
-    }
-
-    /*package*/ boolean
-    compareTo(DriverCall c) {
-        // On mobile originated (MO) calls, the phone number may have changed
-        // due to a SIM Toolkit call control modification.
-        //
-        // We assume we know when MO calls are created (since we created them)
-        // and therefore don't need to compare the phone number anyway.
-        if (! (isIncoming || c.isMT)) return true;
-
-        // ... but we can compare phone numbers on MT calls, and we have
-        // no control over when they begin, so we might as well
-
-        String cAddress = PhoneNumberUtils.stringFromStringAndTOA(c.number, c.TOA);
-        return isIncoming == c.isMT && equalsHandlesNulls(address, cAddress);
-    }
-
-
-    public String getOrigDialString(){
-        return dialString;
-    }
-
-    public String getAddress() {
-        return address;
-    }
-
-    public String getCnapName() {
-        return cnapName;
-    }
-
-    public int getCnapNamePresentation() {
-        return cnapNamePresentation;
-    }
-
-    public CdmaCall getCall() {
-        return parent;
-    }
-
-    public long getCreateTime() {
-        return createTime;
-    }
-
-    public long getConnectTime() {
-        return connectTime;
-    }
-
-    public long getDisconnectTime() {
-        return disconnectTime;
-    }
-
-    public long getDurationMillis() {
-        if (connectTimeReal == 0) {
-            return 0;
-        } else if (duration == 0) {
-            return SystemClock.elapsedRealtime() - connectTimeReal;
-        } else {
-            return duration;
-        }
-    }
-
-    public long getHoldDurationMillis() {
-        if (getState() != CdmaCall.State.HOLDING) {
-            // If not holding, return 0
-            return 0;
-        } else {
-            return SystemClock.elapsedRealtime() - holdingStartTime;
-        }
-    }
-
-    public DisconnectCause getDisconnectCause() {
-        return cause;
-    }
-
-    public boolean isIncoming() {
-        return isIncoming;
-    }
-
-    public CdmaCall.State getState() {
-        if (disconnected) {
-            return CdmaCall.State.DISCONNECTED;
-        } else {
-            return super.getState();
-        }
-    }
-
-    public void hangup() throws CallStateException {
-        if (!disconnected) {
-            owner.hangup(this);
-        } else {
-            throw new CallStateException ("disconnected");
-        }
-    }
-
-    public void separate() throws CallStateException {
-        if (!disconnected) {
-            owner.separate(this);
-        } else {
-            throw new CallStateException ("disconnected");
-        }
-    }
-
-    public PostDialState getPostDialState() {
-        return postDialState;
-    }
-
-    public void proceedAfterWaitChar() {
-        if (postDialState != PostDialState.WAIT) {
-            Log.w(LOG_TAG, "CdmaConnection.proceedAfterWaitChar(): Expected "
-                + "getPostDialState() to be WAIT but was " + postDialState);
-            return;
-        }
-
-        setPostDialState(PostDialState.STARTED);
-
-        processNextPostDialChar();
-    }
-
-    public void proceedAfterWildChar(String str) {
-        if (postDialState != PostDialState.WILD) {
-            Log.w(LOG_TAG, "CdmaConnection.proceedAfterWaitChar(): Expected "
-                + "getPostDialState() to be WILD but was " + postDialState);
-            return;
-        }
-
-        setPostDialState(PostDialState.STARTED);
-
-        if (false) {
-            boolean playedTone = false;
-            int len = (str != null ? str.length() : 0);
-
-            for (int i=0; i<len; i++) {
-                char c = str.charAt(i);
-                Message msg = null;
-
-                if (i == len-1) {
-                    msg = h.obtainMessage(EVENT_DTMF_DONE);
-                }
-
-                if (PhoneNumberUtils.is12Key(c)) {
-                    owner.cm.sendDtmf(c, msg);
-                    playedTone = true;
-                }
-            }
-
-            if (!playedTone) {
-                processNextPostDialChar();
-            }
-        } else {
-            // make a new postDialString, with the wild char replacement string
-            // at the beginning, followed by the remaining postDialString.
-
-            StringBuilder buf = new StringBuilder(str);
-            buf.append(postDialString.substring(nextPostDialChar));
-            postDialString = buf.toString();
-            nextPostDialChar = 0;
-            if (Phone.DEBUG_PHONE) {
-                log("proceedAfterWildChar: new postDialString is " +
-                        postDialString);
-            }
-
-            processNextPostDialChar();
-        }
-    }
-
-    public void cancelPostDial() {
-        setPostDialState(PostDialState.CANCELLED);
-    }
-
-    /**
-     * Called when this Connection is being hung up locally (eg, user pressed "end")
-     * Note that at this point, the hangup request has been dispatched to the radio
-     * but no response has yet been received so update() has not yet been called
-     */
-    void
-    onHangupLocal() {
-        cause = DisconnectCause.LOCAL;
-    }
-
-    DisconnectCause
-    disconnectCauseFromCode(int causeCode) {
-        /**
-         * See 22.001 Annex F.4 for mapping of cause codes
-         * to local tones
-         */
-
-        switch (causeCode) {
-            case CallFailCause.USER_BUSY:
-                return DisconnectCause.BUSY;
-            case CallFailCause.NO_CIRCUIT_AVAIL:
-                return DisconnectCause.CONGESTION;
-            case CallFailCause.ACM_LIMIT_EXCEEDED:
-                return DisconnectCause.LIMIT_EXCEEDED;
-            case CallFailCause.CALL_BARRED:
-                return DisconnectCause.CALL_BARRED;
-            case CallFailCause.FDN_BLOCKED:
-                return DisconnectCause.FDN_BLOCKED;
-            case CallFailCause.CDMA_LOCKED_UNTIL_POWER_CYCLE:
-                return DisconnectCause.CDMA_LOCKED_UNTIL_POWER_CYCLE;
-            case CallFailCause.CDMA_DROP:
-                return DisconnectCause.CDMA_DROP;
-            case CallFailCause.CDMA_INTERCEPT:
-                return DisconnectCause.CDMA_INTERCEPT;
-            case CallFailCause.CDMA_REORDER:
-                return DisconnectCause.CDMA_REORDER;
-            case CallFailCause.CDMA_SO_REJECT:
-                return DisconnectCause.CDMA_SO_REJECT;
-            case CallFailCause.CDMA_RETRY_ORDER:
-                return DisconnectCause.CDMA_RETRY_ORDER;
-            case CallFailCause.CDMA_ACCESS_FAILURE:
-                return DisconnectCause.CDMA_ACCESS_FAILURE;
-            case CallFailCause.CDMA_PREEMPTED:
-                return DisconnectCause.CDMA_PREEMPTED;
-            case CallFailCause.CDMA_NOT_EMERGENCY:
-                return DisconnectCause.CDMA_NOT_EMERGENCY;
-            case CallFailCause.CDMA_ACCESS_BLOCKED:
-                return DisconnectCause.CDMA_ACCESS_BLOCKED;
-            case CallFailCause.ERROR_UNSPECIFIED:
-            case CallFailCause.NORMAL_CLEARING:
-            default:
-                CDMAPhone phone = owner.phone;
-                int serviceState = phone.getServiceState().getState();
-                if (serviceState == ServiceState.STATE_POWER_OFF) {
-                    return DisconnectCause.POWER_OFF;
-                } else if (serviceState == ServiceState.STATE_OUT_OF_SERVICE
-                        || serviceState == ServiceState.STATE_EMERGENCY_ONLY) {
-                    return DisconnectCause.OUT_OF_SERVICE;
-                } else if (phone.mCdmaSubscriptionSource ==
-                               CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM
-                           && phone.getIccCard().getState() != IccCard.State.READY) {
-                    return DisconnectCause.ICC_ERROR;
-                } else if (causeCode==CallFailCause.NORMAL_CLEARING) {
-                    return DisconnectCause.NORMAL;
-                } else {
-                    return DisconnectCause.ERROR_UNSPECIFIED;
-                }
-        }
-    }
-
-    /*package*/ void
-    onRemoteDisconnect(int causeCode) {
-        onDisconnect(disconnectCauseFromCode(causeCode));
-    }
-
-    /** Called when the radio indicates the connection has been disconnected */
-    /*package*/ void
-    onDisconnect(DisconnectCause cause) {
-        this.cause = cause;
-
-        if (!disconnected) {
-            doDisconnect();
-            if (false) Log.d(LOG_TAG,
-                    "[CDMAConn] onDisconnect: cause=" + cause);
-
-            owner.phone.notifyDisconnect(this);
-
-            if (parent != null) {
-                parent.connectionDisconnected(this);
-            }
-        }
-        releaseWakeLock();
-    }
-
-    /** Called when the call waiting connection has been hung up */
-    /*package*/ void
-    onLocalDisconnect() {
-        if (!disconnected) {
-            doDisconnect();
-            if (false) Log.d(LOG_TAG,
-                    "[CDMAConn] onLoalDisconnect" );
-
-            if (parent != null) {
-                parent.detach(this);
-            }
-        }
-        releaseWakeLock();
-    }
-
-    // Returns true if state has changed, false if nothing changed
-    /*package*/ boolean
-    update (DriverCall dc) {
-        CdmaCall newParent;
-        boolean changed = false;
-        boolean wasConnectingInOrOut = isConnectingInOrOut();
-        boolean wasHolding = (getState() == CdmaCall.State.HOLDING);
-
-        newParent = parentFromDCState(dc.state);
-
-        if (Phone.DEBUG_PHONE) log("parent= " +parent +", newParent= " + newParent);
-
-        if (!equalsHandlesNulls(address, dc.number)) {
-            if (Phone.DEBUG_PHONE) log("update: phone # changed!");
-            address = dc.number;
-            changed = true;
-        }
-
-        // A null cnapName should be the same as ""
-        if (TextUtils.isEmpty(dc.name)) {
-            if (!TextUtils.isEmpty(cnapName)) {
-                changed = true;
-                cnapName = "";
-            }
-        } else if (!dc.name.equals(cnapName)) {
-            changed = true;
-            cnapName = dc.name;
-        }
-
-        if (Phone.DEBUG_PHONE) log("--dssds----"+cnapName);
-        cnapNamePresentation = dc.namePresentation;
-        numberPresentation = dc.numberPresentation;
-
-        if (newParent != parent) {
-            if (parent != null) {
-                parent.detach(this);
-            }
-            newParent.attach(this, dc);
-            parent = newParent;
-            changed = true;
-        } else {
-            boolean parentStateChange;
-            parentStateChange = parent.update (this, dc);
-            changed = changed || parentStateChange;
-        }
-
-        /** Some state-transition events */
-
-        if (Phone.DEBUG_PHONE) log(
-                "Update, wasConnectingInOrOut=" + wasConnectingInOrOut +
-                ", wasHolding=" + wasHolding +
-                ", isConnectingInOrOut=" + isConnectingInOrOut() +
-                ", changed=" + changed);
-
-
-        if (wasConnectingInOrOut && !isConnectingInOrOut()) {
-            onConnectedInOrOut();
-        }
-
-        if (changed && !wasHolding && (getState() == CdmaCall.State.HOLDING)) {
-            // We've transitioned into HOLDING
-            onStartedHolding();
-        }
-
-        return changed;
-    }
-
-    /**
-     * Called when this Connection is in the foregroundCall
-     * when a dial is initiated.
-     * We know we're ACTIVE, and we know we're going to end up
-     * HOLDING in the backgroundCall
-     */
-    void
-    fakeHoldBeforeDial() {
-        if (parent != null) {
-            parent.detach(this);
-        }
-
-        parent = owner.backgroundCall;
-        parent.attachFake(this, CdmaCall.State.HOLDING);
-
-        onStartedHolding();
-    }
-
-    /*package*/ int
-    getCDMAIndex() throws CallStateException {
-        if (index >= 0) {
-            return index + 1;
-        } else {
-            throw new CallStateException ("CDMA connection index not assigned");
-        }
-    }
-
-    /**
-     * An incoming or outgoing call has connected
-     */
-    void
-    onConnectedInOrOut() {
-        connectTime = System.currentTimeMillis();
-        connectTimeReal = SystemClock.elapsedRealtime();
-        duration = 0;
-
-        // bug #678474: incoming call interpreted as missed call, even though
-        // it sounds like the user has picked up the call.
-        if (Phone.DEBUG_PHONE) {
-            log("onConnectedInOrOut: connectTime=" + connectTime);
-        }
-
-        if (!isIncoming) {
-            // outgoing calls only
-            processNextPostDialChar();
-        } else {
-            // Only release wake lock for incoming calls, for outgoing calls the wake lock
-            // will be released after any pause-dial is completed
-            releaseWakeLock();
-        }
-    }
-
-    private void
-    doDisconnect() {
-       index = -1;
-       disconnectTime = System.currentTimeMillis();
-       duration = SystemClock.elapsedRealtime() - connectTimeReal;
-       disconnected = true;
-    }
-
-    private void
-    onStartedHolding() {
-        holdingStartTime = SystemClock.elapsedRealtime();
-    }
-    /**
-     * Performs the appropriate action for a post-dial char, but does not
-     * notify application. returns false if the character is invalid and
-     * should be ignored
-     */
-    private boolean
-    processPostDialChar(char c) {
-        if (PhoneNumberUtils.is12Key(c)) {
-            owner.cm.sendDtmf(c, h.obtainMessage(EVENT_DTMF_DONE));
-        } else if (c == PhoneNumberUtils.PAUSE) {
-            setPostDialState(PostDialState.PAUSE);
-
-            // Upon occurrences of the separator, the UE shall
-            // pause again for 2 seconds before sending any
-            // further DTMF digits.
-            h.sendMessageDelayed(h.obtainMessage(EVENT_PAUSE_DONE),
-                                            PAUSE_DELAY_MILLIS);
-        } else if (c == PhoneNumberUtils.WAIT) {
-            setPostDialState(PostDialState.WAIT);
-        } else if (c == PhoneNumberUtils.WILD) {
-            setPostDialState(PostDialState.WILD);
-        } else {
-            return false;
-        }
-
-        return true;
-    }
-
-    public String getRemainingPostDialString() {
-        if (postDialState == PostDialState.CANCELLED
-                || postDialState == PostDialState.COMPLETE
-                || postDialString == null
-                || postDialString.length() <= nextPostDialChar) {
-            return "";
-        }
-
-        String subStr = postDialString.substring(nextPostDialChar);
-        if (subStr != null) {
-            int wIndex = subStr.indexOf(PhoneNumberUtils.WAIT);
-            int pIndex = subStr.indexOf(PhoneNumberUtils.PAUSE);
-
-            if (wIndex > 0 && (wIndex < pIndex || pIndex <= 0)) {
-                subStr = subStr.substring(0, wIndex);
-            } else if (pIndex > 0) {
-                subStr = subStr.substring(0, pIndex);
-            }
-        }
-        return subStr;
-    }
-
-    public void updateParent(CdmaCall oldParent, CdmaCall newParent){
-        if (newParent != oldParent) {
-            if (oldParent != null) {
-                oldParent.detach(this);
-            }
-            newParent.attachFake(this, CdmaCall.State.ACTIVE);
-            parent = newParent;
-        }
-    }
-
-    @Override
-    protected void finalize()
-    {
-        /**
-         * It is understood that This finializer is not guaranteed
-         * to be called and the release lock call is here just in
-         * case there is some path that doesn't call onDisconnect
-         * and or onConnectedInOrOut.
-         */
-        if (mPartialWakeLock.isHeld()) {
-            Log.e(LOG_TAG, "[CdmaConn] UNEXPECTED; mPartialWakeLock is held when finalizing.");
-        }
-        releaseWakeLock();
-    }
-
-    void processNextPostDialChar() {
-        char c = 0;
-        Registrant postDialHandler;
-
-        if (postDialState == PostDialState.CANCELLED) {
-            releaseWakeLock();
-            //Log.v("CDMA", "##### processNextPostDialChar: postDialState == CANCELLED, bail");
-            return;
-        }
-
-        if (postDialString == null ||
-                postDialString.length() <= nextPostDialChar) {
-            setPostDialState(PostDialState.COMPLETE);
-
-            // We were holding a wake lock until pause-dial was complete, so give it up now
-            releaseWakeLock();
-
-            // notifyMessage.arg1 is 0 on complete
-            c = 0;
-        } else {
-            boolean isValid;
-
-            setPostDialState(PostDialState.STARTED);
-
-            c = postDialString.charAt(nextPostDialChar++);
-
-            isValid = processPostDialChar(c);
-
-            if (!isValid) {
-                // Will call processNextPostDialChar
-                h.obtainMessage(EVENT_NEXT_POST_DIAL).sendToTarget();
-                // Don't notify application
-                Log.e("CDMA", "processNextPostDialChar: c=" + c + " isn't valid!");
-                return;
-            }
-        }
-
-        postDialHandler = owner.phone.mPostDialHandler;
-
-        Message notifyMessage;
-
-        if (postDialHandler != null &&
-                (notifyMessage = postDialHandler.messageForRegistrant()) != null) {
-            // The AsyncResult.result is the Connection object
-            PostDialState state = postDialState;
-            AsyncResult ar = AsyncResult.forMessage(notifyMessage);
-            ar.result = this;
-            ar.userObj = state;
-
-            // arg1 is the character that was/is being processed
-            notifyMessage.arg1 = c;
-
-            notifyMessage.sendToTarget();
-        }
-    }
-
-
-    /** "connecting" means "has never been ACTIVE" for both incoming
-     *  and outgoing calls
-     */
-    private boolean
-    isConnectingInOrOut() {
-        return parent == null || parent == owner.ringingCall
-            || parent.state == CdmaCall.State.DIALING
-            || parent.state == CdmaCall.State.ALERTING;
-    }
-
-    private CdmaCall
-    parentFromDCState (DriverCall.State state) {
-        switch (state) {
-            case ACTIVE:
-            case DIALING:
-            case ALERTING:
-                return owner.foregroundCall;
-            //break;
-
-            case HOLDING:
-                return owner.backgroundCall;
-            //break;
-
-            case INCOMING:
-            case WAITING:
-                return owner.ringingCall;
-            //break;
-
-            default:
-                throw new RuntimeException("illegal call state: " + state);
-        }
-    }
-
-    /**
-     * Set post dial state and acquire wake lock while switching to "started" or "wait"
-     * state, the wake lock will be released if state switches out of "started" or "wait"
-     * state or after WAKE_LOCK_TIMEOUT_MILLIS.
-     * @param s new PostDialState
-     */
-    private void setPostDialState(PostDialState s) {
-        if (s == PostDialState.STARTED ||
-                s == PostDialState.PAUSE) {
-            synchronized (mPartialWakeLock) {
-                if (mPartialWakeLock.isHeld()) {
-                    h.removeMessages(EVENT_WAKE_LOCK_TIMEOUT);
-                } else {
-                    acquireWakeLock();
-                }
-                Message msg = h.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT);
-                h.sendMessageDelayed(msg, WAKE_LOCK_TIMEOUT_MILLIS);
-            }
-        } else {
-            h.removeMessages(EVENT_WAKE_LOCK_TIMEOUT);
-            releaseWakeLock();
-        }
-        postDialState = s;
-    }
-
-    private void createWakeLock(Context context) {
-        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
-        mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
-    }
-
-    private void acquireWakeLock() {
-        log("acquireWakeLock");
-        mPartialWakeLock.acquire();
-    }
-
-    private void releaseWakeLock() {
-        synchronized (mPartialWakeLock) {
-            if (mPartialWakeLock.isHeld()) {
-                log("releaseWakeLock");
-                mPartialWakeLock.release();
-            }
-        }
-    }
-
-    private static boolean isPause(char c) {
-        return c == PhoneNumberUtils.PAUSE;
-    }
-
-    private static boolean isWait(char c) {
-        return c == PhoneNumberUtils.WAIT;
-    }
-
-    // This function is to find the next PAUSE character index if
-    // multiple pauses in a row. Otherwise it finds the next non PAUSE or
-    // non WAIT character index.
-    private static int
-    findNextPCharOrNonPOrNonWCharIndex(String phoneNumber, int currIndex) {
-        boolean wMatched = isWait(phoneNumber.charAt(currIndex));
-        int index = currIndex + 1;
-        int length = phoneNumber.length();
-        while (index < length) {
-            char cNext = phoneNumber.charAt(index);
-            // if there is any W inside P/W sequence,mark it
-            if (isWait(cNext)) {
-                wMatched = true;
-            }
-            // if any characters other than P/W chars after P/W sequence
-            // we break out the loop and append the correct
-            if (!isWait(cNext) && !isPause(cNext)) {
-                break;
-            }
-            index++;
-        }
-
-        // It means the PAUSE character(s) is in the middle of dial string
-        // and it needs to be handled one by one.
-        if ((index < length) && (index > (currIndex + 1))  &&
-            ((wMatched == false) && isPause(phoneNumber.charAt(currIndex)))) {
-            return (currIndex + 1);
-        }
-        return index;
-    }
-
-    // This function returns either PAUSE or WAIT character to append.
-    // It is based on the next non PAUSE/WAIT character in the phoneNumber and the
-    // index for the current PAUSE/WAIT character
-    private static char
-    findPOrWCharToAppend(String phoneNumber, int currPwIndex, int nextNonPwCharIndex) {
-        char c = phoneNumber.charAt(currPwIndex);
-        char ret;
-
-        // Append the PW char
-        ret = (isPause(c)) ? PhoneNumberUtils.PAUSE : PhoneNumberUtils.WAIT;
-
-        // If the nextNonPwCharIndex is greater than currPwIndex + 1,
-        // it means the PW sequence contains not only P characters.
-        // Since for the sequence that only contains P character,
-        // the P character is handled one by one, the nextNonPwCharIndex
-        // equals to currPwIndex + 1.
-        // In this case, skip P, append W.
-        if (nextNonPwCharIndex > (currPwIndex + 1)) {
-            ret = PhoneNumberUtils.WAIT;
-        }
-        return ret;
-    }
-
-    /**
-     * format original dial string
-     * 1) convert international dialing prefix "+" to
-     *    string specified per region
-     *
-     * 2) handle corner cases for PAUSE/WAIT dialing:
-     *
-     *    If PAUSE/WAIT sequence at the end, ignore them.
-     *
-     *    If consecutive PAUSE/WAIT sequence in the middle of the string,
-     *    and if there is any WAIT in PAUSE/WAIT sequence, treat them like WAIT.
-     */
-    public static String formatDialString(String phoneNumber) {
-        /**
-         * TODO(cleanup): This function should move to PhoneNumberUtils, and
-         * tests should be added.
-         */
-
-        if (phoneNumber == null) {
-            return null;
-        }
-        int length = phoneNumber.length();
-        StringBuilder ret = new StringBuilder();
-        char c;
-        int currIndex = 0;
-
-        while (currIndex < length) {
-            c = phoneNumber.charAt(currIndex);
-            if (isPause(c) || isWait(c)) {
-                if (currIndex < length - 1) {
-                    // if PW not at the end
-                    int nextIndex = findNextPCharOrNonPOrNonWCharIndex(phoneNumber, currIndex);
-                    // If there is non PW char following PW sequence
-                    if (nextIndex < length) {
-                        char pC = findPOrWCharToAppend(phoneNumber, currIndex, nextIndex);
-                        ret.append(pC);
-                        // If PW char sequence has more than 2 PW characters,
-                        // skip to the last PW character since the sequence already be
-                        // converted to WAIT character
-                        if (nextIndex > (currIndex + 1)) {
-                            currIndex = nextIndex - 1;
-                        }
-                    } else if (nextIndex == length) {
-                        // It means PW characters at the end, ignore
-                        currIndex = length - 1;
-                    }
-                }
-            } else {
-                ret.append(c);
-            }
-            currIndex++;
-        }
-        return PhoneNumberUtils.cdmaCheckAndProcessPlusCode(ret.toString());
-    }
-
-    private void log(String msg) {
-        Log.d(LOG_TAG, "[CDMAConn] " + msg);
-    }
-
-    @Override
-    public int getNumberPresentation() {
-        return numberPresentation;
-    }
-
-    @Override
-    public UUSInfo getUUSInfo() {
-        // UUS information not supported in CDMA
-        return null;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
deleted file mode 100644
index 4ef05ea..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
+++ /dev/null
@@ -1,126 +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.internal.telephony.cdma;
-
-import android.os.Message;
-import android.util.Log;
-
-import com.android.internal.telephony.DataConnection;
-import com.android.internal.telephony.DataConnectionTracker;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.RetryManager;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * {@hide}
- */
-public class CdmaDataConnection extends DataConnection {
-
-    private static final String LOG_TAG = "CDMA";
-
-    // ***** Constructor
-    private CdmaDataConnection(CDMAPhone phone, String name, int id, RetryManager rm,
-            DataConnectionTracker dct) {
-        super(phone, name, id, rm, dct);
-    }
-
-    /**
-     * Create the connection object
-     *
-     * @param phone the Phone
-     * @param id the connection id
-     * @param rm the RetryManager
-     * @return CdmaDataConnection that was created.
-     */
-    static CdmaDataConnection makeDataConnection(CDMAPhone phone, int id, RetryManager rm,
-            DataConnectionTracker dct) {
-        synchronized (mCountLock) {
-            mCount += 1;
-        }
-        CdmaDataConnection cdmaDc = new CdmaDataConnection(phone, "CdmaDC-" + mCount,
-                id, rm, dct);
-        cdmaDc.start();
-        if (DBG) cdmaDc.log("Made " + cdmaDc.getName());
-        return cdmaDc;
-    }
-
-    /**
-     * Begin setting up a data connection, calls setupDataCall
-     * and the ConnectionParams will be returned with the
-     * EVENT_SETUP_DATA_CONNECTION_DONE AsyncResul.userObj.
-     *
-     * @param cp is the connection parameters
-     */
-    @Override
-    protected void onConnect(ConnectionParams cp) {
-        if (DBG) log("CdmaDataConnection Connecting...");
-
-        mApn = cp.apn;
-        createTime = -1;
-        lastFailTime = -1;
-        lastFailCause = FailCause.NONE;
-        int dataProfile;
-        if ((cp.apn != null) && (cp.apn.types.length > 0) && (cp.apn.types[0] != null) &&
-                (cp.apn.types[0].equals(Phone.APN_TYPE_DUN))) {
-            if (DBG) log("CdmaDataConnection using DUN");
-            dataProfile = RILConstants.DATA_PROFILE_TETHERED;
-        } else {
-            dataProfile = RILConstants.DATA_PROFILE_DEFAULT;
-        }
-
-        // msg.obj will be returned in AsyncResult.userObj;
-        Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp);
-        msg.obj = cp;
-        phone.mCM.setupDataCall(
-                Integer.toString(getRilRadioTechnology(RILConstants.SETUP_DATA_TECH_CDMA)),
-                Integer.toString(dataProfile),
-                null, null, null,
-                Integer.toString(RILConstants.SETUP_DATA_AUTH_PAP_CHAP),
-                RILConstants.SETUP_DATA_PROTOCOL_IP, msg);
-    }
-
-    @Override
-    public String toString() {
-        return "State=" + getCurrentState().getName() + " create=" + createTime + " lastFail="
-                + lastFailTime + " lastFasilCause=" + lastFailCause;
-    }
-
-    @Override
-    protected boolean isDnsOk(String[] domainNameServers) {
-        if (NULL_IP.equals(domainNameServers[0])
-                && NULL_IP.equals(domainNameServers[1])
-                && !phone.isDnsCheckDisabled()) {
-            return false;
-        } else {
-            return true;
-        }
-    }
-
-    @Override
-    protected void log(String s) {
-        Log.d(LOG_TAG, "[" + getName() + "] " + s);
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("CdmaDataConnection extends:");
-        super.dump(fd, pw, args);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
deleted file mode 100644
index a691eae..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ /dev/null
@@ -1,1040 +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.internal.telephony.cdma;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.net.TrafficStats;
-import android.os.AsyncResult;
-import android.os.Message;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.telephony.ServiceState;
-import android.telephony.TelephonyManager;
-import android.telephony.cdma.CdmaCellLocation;
-import android.text.TextUtils;
-import android.util.EventLog;
-import android.util.Log;
-
-import com.android.internal.telephony.ApnSetting;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.DataCallState;
-import com.android.internal.telephony.DataConnection.FailCause;
-import com.android.internal.telephony.DataConnection;
-import com.android.internal.telephony.DataConnectionAc;
-import com.android.internal.telephony.DataConnectionTracker;
-import com.android.internal.telephony.EventLogTags;
-import com.android.internal.telephony.RetryManager;
-import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.Phone;
-import com.android.internal.util.AsyncChannel;
-import com.android.internal.telephony.RILConstants;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-
-/**
- * {@hide}
- */
-public final class CdmaDataConnectionTracker extends DataConnectionTracker {
-    protected final String LOG_TAG = "CDMA";
-
-    private CDMAPhone mCdmaPhone;
-    private CdmaSubscriptionSourceManager mCdmaSSM;
-
-    /** The DataConnection being setup */
-    private CdmaDataConnection mPendingDataConnection;
-
-    private boolean mPendingRestartRadio = false;
-    private static final int TIME_DELAYED_TO_RESTART_RADIO =
-            SystemProperties.getInt("ro.cdma.timetoradiorestart", 60000);
-
-    /**
-     * Pool size of CdmaDataConnection objects.
-     */
-    private static final int DATA_CONNECTION_POOL_SIZE = 1;
-
-    private static final String INTENT_RECONNECT_ALARM =
-        "com.android.internal.telephony.cdma-reconnect";
-
-    private static final String INTENT_DATA_STALL_ALARM =
-        "com.android.internal.telephony.cdma-data-stall";
-
-
-    /**
-     * Constants for the data connection activity:
-     * physical link down/up
-     */
-     private static final int DATA_CONNECTION_ACTIVE_PH_LINK_INACTIVE = 0;
-     private static final int DATA_CONNECTION_ACTIVE_PH_LINK_DOWN = 1;
-     private static final int DATA_CONNECTION_ACTIVE_PH_LINK_UP = 2;
-
-    private static final String[] mSupportedApnTypes = {
-            Phone.APN_TYPE_DEFAULT,
-            Phone.APN_TYPE_MMS,
-            Phone.APN_TYPE_DUN,
-            Phone.APN_TYPE_HIPRI };
-
-    private static final String[] mDefaultApnTypes = {
-            Phone.APN_TYPE_DEFAULT,
-            Phone.APN_TYPE_MMS,
-            Phone.APN_TYPE_HIPRI };
-
-    private String[] mDunApnTypes = {
-            Phone.APN_TYPE_DUN };
-
-    private static final int mDefaultApnId = DataConnectionTracker.APN_DEFAULT_ID;
-
-    /* Constructor */
-
-    CdmaDataConnectionTracker(CDMAPhone p) {
-        super(p);
-        mCdmaPhone = p;
-
-        p.mCM.registerForAvailable (this, EVENT_RADIO_AVAILABLE, null);
-        p.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
-        p.mIccRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null);
-        p.mCM.registerForDataNetworkStateChanged (this, EVENT_DATA_STATE_CHANGED, null);
-        p.mCT.registerForVoiceCallEnded (this, EVENT_VOICE_CALL_ENDED, null);
-        p.mCT.registerForVoiceCallStarted (this, EVENT_VOICE_CALL_STARTED, null);
-        p.mSST.registerForDataConnectionAttached(this, EVENT_TRY_SETUP_DATA, null);
-        p.mSST.registerForDataConnectionDetached(this, EVENT_CDMA_DATA_DETACHED, null);
-        p.mSST.registerForRoamingOn(this, EVENT_ROAMING_ON, null);
-        p.mSST.registerForRoamingOff(this, EVENT_ROAMING_OFF, null);
-        p.mCM.registerForCdmaOtaProvision(this, EVENT_CDMA_OTA_PROVISION, null);
-        mCdmaSSM = CdmaSubscriptionSourceManager.getInstance (p.getContext(), p.mCM, this,
-                EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
-
-        mDataConnectionTracker = this;
-
-        createAllDataConnectionList();
-        broadcastMessenger();
-
-        Context c = mCdmaPhone.getContext();
-        String[] t = c.getResources().getStringArray(
-                com.android.internal.R.array.config_cdma_dun_supported_types);
-        if (t != null && t.length > 0) {
-            ArrayList<String> temp = new ArrayList<String>();
-            for(int i=0; i< t.length; i++) {
-                if (!Phone.APN_TYPE_DUN.equalsIgnoreCase(t[i])) {
-                    temp.add(t[i]);
-                }
-            }
-            temp.add(0, Phone.APN_TYPE_DUN);
-            mDunApnTypes = temp.toArray(t);
-        }
-
-    }
-
-    @Override
-    public void dispose() {
-        cleanUpConnection(false, null, false);
-
-        super.dispose();
-
-        // Unregister from all events
-        mPhone.mCM.unregisterForAvailable(this);
-        mPhone.mCM.unregisterForOffOrNotAvailable(this);
-        mCdmaPhone.mIccRecords.unregisterForRecordsLoaded(this);
-        mPhone.mCM.unregisterForDataNetworkStateChanged(this);
-        mCdmaPhone.mCT.unregisterForVoiceCallEnded(this);
-        mCdmaPhone.mCT.unregisterForVoiceCallStarted(this);
-        mCdmaPhone.mSST.unregisterForDataConnectionAttached(this);
-        mCdmaPhone.mSST.unregisterForDataConnectionDetached(this);
-        mCdmaPhone.mSST.unregisterForRoamingOn(this);
-        mCdmaPhone.mSST.unregisterForRoamingOff(this);
-        mCdmaSSM.dispose(this);
-        mPhone.mCM.unregisterForCdmaOtaProvision(this);
-
-        destroyAllDataConnectionList();
-    }
-
-    @Override
-    protected void finalize() {
-        if(DBG) log("CdmaDataConnectionTracker finalized");
-    }
-
-    @Override
-    protected String getActionIntentReconnectAlarm() {
-        return INTENT_RECONNECT_ALARM;
-    }
-
-    @Override
-    protected String getActionIntentDataStallAlarm() {
-        return INTENT_DATA_STALL_ALARM;
-    }
-
-    @Override
-    protected void restartDataStallAlarm() {}
-
-    @Override
-    protected void setState(State s) {
-        if (DBG) log ("setState: " + s);
-        if (mState != s) {
-            EventLog.writeEvent(EventLogTags.CDMA_DATA_STATE_CHANGE,
-                    mState.toString(), s.toString());
-            mState = s;
-        }
-    }
-
-    @Override
-    public synchronized State getState(String apnType) {
-        return mState;
-    }
-
-    @Override
-    protected boolean isApnTypeAvailable(String type) {
-        for (String s : mSupportedApnTypes) {
-            if (TextUtils.equals(type, s)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    protected boolean isDataAllowed() {
-        final boolean internalDataEnabled;
-        synchronized (mDataEnabledLock) {
-            internalDataEnabled = mInternalDataEnabled;
-        }
-
-        int psState = mCdmaPhone.mSST.getCurrentDataConnectionState();
-        boolean roaming = (mPhone.getServiceState().getRoaming() && !getDataOnRoamingEnabled());
-        boolean desiredPowerState = mCdmaPhone.mSST.getDesiredPowerState();
-        boolean subscriptionFromNv = (mCdmaSSM.getCdmaSubscriptionSource()
-                                       == CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_NV);
-
-        boolean allowed =
-                    (psState == ServiceState.STATE_IN_SERVICE ||
-                            mAutoAttachOnCreation) &&
-                    (subscriptionFromNv ||
-                            mCdmaPhone.mIccRecords.getRecordsLoaded()) &&
-                    (mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed() ||
-                            mPhone.getState() == Phone.State.IDLE) &&
-                    !roaming &&
-                    internalDataEnabled &&
-                    desiredPowerState &&
-                    !mPendingRestartRadio &&
-                    ((mPhone.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE) ||
-                            !mCdmaPhone.needsOtaServiceProvisioning());
-        if (!allowed && DBG) {
-            String reason = "";
-            if (!((psState == ServiceState.STATE_IN_SERVICE) || mAutoAttachOnCreation)) {
-                reason += " - psState= " + psState;
-            }
-            if (!subscriptionFromNv &&
-                    !mCdmaPhone.mIccRecords.getRecordsLoaded()) {
-                reason += " - RUIM not loaded";
-            }
-            if (!(mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed() ||
-                    mPhone.getState() == Phone.State.IDLE)) {
-                reason += " - concurrentVoiceAndData not allowed and state= " + mPhone.getState();
-            }
-            if (roaming) reason += " - Roaming";
-            if (!internalDataEnabled) reason += " - mInternalDataEnabled= false";
-            if (!desiredPowerState) reason += " - desiredPowerState= false";
-            if (mPendingRestartRadio) reason += " - mPendingRestartRadio= true";
-            if (mCdmaPhone.needsOtaServiceProvisioning()) reason += " - needs Provisioning";
-            log("Data not allowed due to" + reason);
-        }
-        return allowed;
-    }
-
-    @Override
-    protected boolean isDataPossible(String apnType) {
-        boolean possible = isDataAllowed() && !(getAnyDataEnabled() &&
-                (mState == State.FAILED || mState == State.IDLE));
-        if (!possible && DBG && isDataAllowed()) {
-            log("Data not possible.  No coverage: dataState = " + mState);
-        }
-        return possible;
-    }
-
-    private boolean trySetupData(String reason) {
-        if (DBG) log("***trySetupData due to " + (reason == null ? "(unspecified)" : reason));
-
-        if (mPhone.getSimulatedRadioControl() != null) {
-            // Assume data is connected on the simulator
-            // FIXME  this can be improved
-            setState(State.CONNECTED);
-            notifyDataConnection(reason);
-            notifyOffApnsOfAvailability(reason);
-
-            log("(fix?) We're on the simulator; assuming data is connected");
-            return true;
-        }
-
-        int psState = mCdmaPhone.mSST.getCurrentDataConnectionState();
-        boolean roaming = mPhone.getServiceState().getRoaming();
-        boolean desiredPowerState = mCdmaPhone.mSST.getDesiredPowerState();
-
-        if ((mState == State.IDLE || mState == State.SCANNING) &&
-                isDataAllowed() && getAnyDataEnabled() && !isEmergency()) {
-            boolean retValue = setupData(reason);
-            notifyOffApnsOfAvailability(reason);
-            return retValue;
-        } else {
-            notifyOffApnsOfAvailability(reason);
-            return false;
-        }
-    }
-
-    /**
-     * Cleanup the CDMA data connection (only one is supported)
-     *
-     * @param tearDown true if the underlying DataConnection should be disconnected.
-     * @param reason for the clean up.
-     */
-    private void cleanUpConnection(boolean tearDown, String reason, boolean doAll) {
-        if (DBG) log("cleanUpConnection: reason: " + reason);
-
-        // Clear the reconnect alarm, if set.
-        if (mReconnectIntent != null) {
-            AlarmManager am =
-                (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
-            am.cancel(mReconnectIntent);
-            mReconnectIntent = null;
-        }
-
-        setState(State.DISCONNECTING);
-        notifyOffApnsOfAvailability(reason);
-
-        boolean notificationDeferred = false;
-        for (DataConnection conn : mDataConnections.values()) {
-            if(conn != null) {
-                DataConnectionAc dcac =
-                    mDataConnectionAsyncChannels.get(conn.getDataConnectionId());
-                if (tearDown) {
-                    if (doAll) {
-                        if (DBG) log("cleanUpConnection: teardown, conn.tearDownAll");
-                        conn.tearDownAll(reason, obtainMessage(EVENT_DISCONNECT_DONE,
-                                conn.getDataConnectionId(), 0, reason));
-                    } else {
-                        if (DBG) log("cleanUpConnection: teardown, conn.tearDown");
-                        conn.tearDown(reason, obtainMessage(EVENT_DISCONNECT_DONE,
-                                conn.getDataConnectionId(), 0, reason));
-                    }
-                    notificationDeferred = true;
-                } else {
-                    if (DBG) log("cleanUpConnection: !tearDown, call conn.resetSynchronously");
-                    if (dcac != null) {
-                        dcac.resetSync();
-                    }
-                    notificationDeferred = false;
-                }
-            }
-        }
-
-        stopNetStatPoll();
-
-        if (!notificationDeferred) {
-            if (DBG) log("cleanupConnection: !notificationDeferred");
-            gotoIdleAndNotifyDataConnection(reason);
-        }
-    }
-
-    private CdmaDataConnection findFreeDataConnection() {
-        for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
-            if (dcac.isInactiveSync()) {
-                log("found free GsmDataConnection");
-                return (CdmaDataConnection) dcac.dataConnection;
-            }
-        }
-        log("NO free CdmaDataConnection");
-        return null;
-    }
-
-    private boolean setupData(String reason) {
-        CdmaDataConnection conn = findFreeDataConnection();
-
-        if (conn == null) {
-            if (DBG) log("setupData: No free CdmaDataConnection found!");
-            return false;
-        }
-
-        /** TODO: We probably want the connection being setup to a parameter passed around */
-        mPendingDataConnection = conn;
-        String[] types;
-        int apnId;
-        if (mRequestedApnType.equals(Phone.APN_TYPE_DUN)) {
-            types = mDunApnTypes;
-            apnId = DataConnectionTracker.APN_DUN_ID;
-        } else {
-            types = mDefaultApnTypes;
-            apnId = mDefaultApnId;
-        }
-        mActiveApn = new ApnSetting(apnId, "", "", "", "", "", "", "", "", "",
-                                    "", 0, types, "IP", "IP", true, 0);
-        if (DBG) log("call conn.bringUp mActiveApn=" + mActiveApn);
-
-        Message msg = obtainMessage();
-        msg.what = EVENT_DATA_SETUP_COMPLETE;
-        msg.obj = reason;
-        conn.bringUp(msg, mActiveApn);
-
-        setState(State.INITING);
-        notifyDataConnection(reason);
-        return true;
-    }
-
-    private void notifyDefaultData(String reason) {
-        setState(State.CONNECTED);
-        notifyDataConnection(reason);
-        startNetStatPoll();
-        mDataConnections.get(0).resetRetryCount();
-    }
-
-    private void resetPollStats() {
-        mTxPkts = -1;
-        mRxPkts = -1;
-        mSentSinceLastRecv = 0;
-        mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
-        mNoRecvPollCount = 0;
-    }
-
-    @Override
-    protected void startNetStatPoll() {
-        if (mState == State.CONNECTED && mNetStatPollEnabled == false) {
-            log("[DataConnection] Start poll NetStat");
-            resetPollStats();
-            mNetStatPollEnabled = true;
-            mPollNetStat.run();
-        }
-    }
-
-    @Override
-    protected void stopNetStatPoll() {
-        mNetStatPollEnabled = false;
-        removeCallbacks(mPollNetStat);
-        log("[DataConnection] Stop poll NetStat");
-    }
-
-    @Override
-    protected void restartRadio() {
-        if (DBG) log("Cleanup connection and wait " +
-                (TIME_DELAYED_TO_RESTART_RADIO / 1000) + "s to restart radio");
-        cleanUpAllConnections(null);
-        sendEmptyMessageDelayed(EVENT_RESTART_RADIO, TIME_DELAYED_TO_RESTART_RADIO);
-        mPendingRestartRadio = true;
-    }
-
-    private Runnable mPollNetStat = new Runnable() {
-
-        public void run() {
-            long sent, received;
-            long preTxPkts = -1, preRxPkts = -1;
-
-            Activity newActivity;
-
-            preTxPkts = mTxPkts;
-            preRxPkts = mRxPkts;
-
-            mTxPkts = TrafficStats.getMobileTxPackets();
-            mRxPkts = TrafficStats.getMobileRxPackets();
-
-            //log("rx " + String.valueOf(rxPkts) + " tx " + String.valueOf(txPkts));
-
-            if (mNetStatPollEnabled && (preTxPkts > 0 || preRxPkts > 0)) {
-                sent = mTxPkts - preTxPkts;
-                received = mRxPkts - preRxPkts;
-
-                if ( sent > 0 && received > 0 ) {
-                    mSentSinceLastRecv = 0;
-                    newActivity = Activity.DATAINANDOUT;
-                } else if (sent > 0 && received == 0) {
-                    if (mPhone.getState()  == Phone.State.IDLE) {
-                        mSentSinceLastRecv += sent;
-                    } else {
-                        mSentSinceLastRecv = 0;
-                    }
-                    newActivity = Activity.DATAOUT;
-                } else if (sent == 0 && received > 0) {
-                    mSentSinceLastRecv = 0;
-                    newActivity = Activity.DATAIN;
-                } else if (sent == 0 && received == 0) {
-                    newActivity = (mActivity == Activity.DORMANT) ? mActivity : Activity.NONE;
-                } else {
-                    mSentSinceLastRecv = 0;
-                    newActivity = (mActivity == Activity.DORMANT) ? mActivity : Activity.NONE;
-                }
-
-                if (mActivity != newActivity && mIsScreenOn) {
-                    mActivity = newActivity;
-                    mPhone.notifyDataActivity();
-                }
-            }
-
-            if (mSentSinceLastRecv >= NUMBER_SENT_PACKETS_OF_HANG) {
-                // Packets sent without ack exceeded threshold.
-
-                if (mNoRecvPollCount == 0) {
-                    EventLog.writeEvent(
-                            EventLogTags.PDP_RADIO_RESET_COUNTDOWN_TRIGGERED,
-                            mSentSinceLastRecv);
-                }
-
-                if (mNoRecvPollCount < NO_RECV_POLL_LIMIT) {
-                    mNoRecvPollCount++;
-                    // Slow down the poll interval to let things happen
-                    mNetStatPollPeriod = POLL_NETSTAT_SLOW_MILLIS;
-                } else {
-                    if (DBG) log("Sent " + String.valueOf(mSentSinceLastRecv) +
-                                        " pkts since last received");
-                    // We've exceeded the threshold.  Restart the radio.
-                    mNetStatPollEnabled = false;
-                    stopNetStatPoll();
-                    restartRadio();
-                    EventLog.writeEvent(EventLogTags.PDP_RADIO_RESET, NO_RECV_POLL_LIMIT);
-                }
-            } else {
-                mNoRecvPollCount = 0;
-                mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
-            }
-
-            if (mNetStatPollEnabled) {
-                mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod);
-            }
-        }
-    };
-
-    /**
-     * Returns true if the last fail cause is something that
-     * seems like it deserves an error notification.
-     * Transient errors are ignored
-     */
-    private boolean
-    shouldPostNotification(FailCause cause) {
-        return (cause != FailCause.UNKNOWN);
-    }
-
-    /**
-     * Return true if data connection need to be setup after disconnected due to
-     * reason.
-     *
-     * @param reason the reason why data is disconnected
-     * @return true if try setup data connection is need for this reason
-     */
-    private boolean retryAfterDisconnected(String reason) {
-        boolean retry = true;
-
-        if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ) {
-            retry = false;
-        }
-        return retry;
-    }
-
-    private void reconnectAfterFail(FailCause lastFailCauseCode, String reason, int retryOverride) {
-        if (mState == State.FAILED) {
-            /**
-             * For now With CDMA we never try to reconnect on
-             * error and instead just continue to retry
-             * at the last time until the state is changed.
-             * TODO: Make this configurable?
-             */
-            int nextReconnectDelay = retryOverride;
-            if (nextReconnectDelay < 0) {
-                nextReconnectDelay = mDataConnections.get(0).getRetryTimer();
-                mDataConnections.get(0).increaseRetryCount();
-            }
-            startAlarmForReconnect(nextReconnectDelay, reason);
-
-            if (!shouldPostNotification(lastFailCauseCode)) {
-                log("NOT Posting Data Connection Unavailable notification "
-                                + "-- likely transient error");
-            } else {
-                notifyNoData(lastFailCauseCode);
-            }
-        }
-    }
-
-    private void startAlarmForReconnect(int delay, String reason) {
-
-        log("Data Connection activate failed. Scheduling next attempt for "
-                + (delay / 1000) + "s");
-
-        AlarmManager am =
-            (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
-        Intent intent = new Intent(INTENT_RECONNECT_ALARM);
-        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, reason);
-        mReconnectIntent = PendingIntent.getBroadcast(
-                mPhone.getContext(), 0, intent, 0);
-        am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                SystemClock.elapsedRealtime() + delay, mReconnectIntent);
-
-    }
-
-    private void notifyNoData(FailCause lastFailCauseCode) {
-        setState(State.FAILED);
-        notifyOffApnsOfAvailability(null);
-    }
-
-    protected void gotoIdleAndNotifyDataConnection(String reason) {
-        if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason);
-        setState(State.IDLE);
-        notifyDataConnection(reason);
-        mActiveApn = null;
-    }
-
-    protected void onRecordsLoaded() {
-        if (mState == State.FAILED) {
-            cleanUpAllConnections(null);
-        }
-        sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA, Phone.REASON_SIM_LOADED));
-    }
-
-    protected void onNVReady() {
-        if (mState == State.FAILED) {
-            cleanUpAllConnections(null);
-        }
-        sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
-    }
-
-    /**
-     * @override com.android.internal.telephony.DataConnectionTracker
-     */
-    @Override
-    protected void onEnableNewApn() {
-        // No mRequestedApnType check; only one connection is supported
-        cleanUpConnection(true, Phone.REASON_APN_SWITCHED, false);
-    }
-
-    /**
-     * @override com.android.internal.telephony.DataConnectionTracker
-     */
-    @Override
-    protected boolean onTrySetupData(String reason) {
-        return trySetupData(reason);
-    }
-
-    /**
-     * @override com.android.internal.telephony.DataConnectionTracker
-     */
-    @Override
-    protected void onRoamingOff() {
-        if (mUserDataEnabled == false) return;
-
-        if (getDataOnRoamingEnabled() == false) {
-            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_OFF);
-            trySetupData(Phone.REASON_ROAMING_OFF);
-        } else {
-            notifyDataConnection(Phone.REASON_ROAMING_OFF);
-        }
-    }
-
-    /**
-     * @override com.android.internal.telephony.DataConnectionTracker
-     */
-    @Override
-    protected void onRoamingOn() {
-        if (mUserDataEnabled == false) return;
-
-        if (getDataOnRoamingEnabled()) {
-            trySetupData(Phone.REASON_ROAMING_ON);
-            notifyDataConnection(Phone.REASON_ROAMING_ON);
-        } else {
-            if (DBG) log("Tear down data connection on roaming.");
-            cleanUpAllConnections(null);
-            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
-        }
-    }
-
-    /**
-     * @override com.android.internal.telephony.DataConnectionTracker
-     */
-    @Override
-    protected void onRadioAvailable() {
-        if (mPhone.getSimulatedRadioControl() != null) {
-            // Assume data is connected on the simulator
-            // FIXME  this can be improved
-            setState(State.CONNECTED);
-            notifyDataConnection(null);
-
-            log("We're on the simulator; assuming data is connected");
-        }
-
-        notifyOffApnsOfAvailability(null);
-
-        if (mState != State.IDLE) {
-            cleanUpAllConnections(null);
-        }
-    }
-
-    /**
-     * @override com.android.internal.telephony.DataConnectionTracker
-     */
-    @Override
-    protected void onRadioOffOrNotAvailable() {
-        mDataConnections.get(0).resetRetryCount();
-
-        if (mPhone.getSimulatedRadioControl() != null) {
-            // Assume data is connected on the simulator
-            // FIXME  this can be improved
-            log("We're on the simulator; assuming radio off is meaningless");
-        } else {
-            if (DBG) log("Radio is off and clean up all connection");
-            cleanUpAllConnections(null);
-        }
-    }
-
-    /**
-     * @override com.android.internal.telephony.DataConnectionTracker
-     */
-    @Override
-    protected void onDataSetupComplete(AsyncResult ar) {
-        String reason = null;
-        if (ar.userObj instanceof String) {
-            reason = (String) ar.userObj;
-        }
-
-        if (isDataSetupCompleteOk(ar)) {
-            // Everything is setup
-            notifyDefaultData(reason);
-        } else {
-            FailCause cause = (FailCause) (ar.result);
-            if(DBG) log("Data Connection setup failed " + cause);
-
-            // No try for permanent failure
-            if (cause.isPermanentFail()) {
-                notifyNoData(cause);
-                return;
-            }
-
-            int retryOverride = -1;
-            if (ar.exception instanceof DataConnection.CallSetupException) {
-                retryOverride =
-                    ((DataConnection.CallSetupException)ar.exception).getRetryOverride();
-            }
-            if (retryOverride == RILConstants.MAX_INT) {
-                if (DBG) log("No retry is suggested.");
-            } else {
-                startDelayedRetry(cause, reason, retryOverride);
-            }
-        }
-    }
-
-    /**
-     * Called when EVENT_DISCONNECT_DONE is received.
-     */
-    @Override
-    protected void onDisconnectDone(int connId, AsyncResult ar) {
-        if(DBG) log("EVENT_DISCONNECT_DONE connId=" + connId);
-        String reason = null;
-        if (ar.userObj instanceof String) {
-            reason = (String) ar.userObj;
-        }
-        setState(State.IDLE);
-
-        // Since the pending request to turn off or restart radio will be processed here,
-        // remove the pending event to restart radio from the message queue.
-        if (mPendingRestartRadio) removeMessages(EVENT_RESTART_RADIO);
-
-        // Process the pending request to turn off radio in ServiceStateTracker first.
-        // If radio is turned off in ServiceStateTracker, ignore the pending event to restart radio.
-        CdmaServiceStateTracker ssTracker = mCdmaPhone.mSST;
-        if (ssTracker.processPendingRadioPowerOffAfterDataOff()) {
-            mPendingRestartRadio = false;
-        } else {
-            onRestartRadio();
-        }
-
-        notifyDataConnection(reason);
-        mActiveApn = null;
-        if (retryAfterDisconnected(reason)) {
-          // Wait a bit before trying, so we're not tying up RIL command channel.
-          startAlarmForReconnect(APN_DELAY_MILLIS, reason);
-      }
-    }
-
-    /**
-     * @override com.android.internal.telephony.DataConnectionTracker
-     */
-    @Override
-    protected void onVoiceCallStarted() {
-        if (mState == State.CONNECTED && !mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed()) {
-            stopNetStatPoll();
-            notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
-            notifyOffApnsOfAvailability(Phone.REASON_VOICE_CALL_STARTED);
-        }
-    }
-
-    /**
-     * @override com.android.internal.telephony.DataConnectionTracker
-     */
-    @Override
-    protected void onVoiceCallEnded() {
-        if (mState == State.CONNECTED) {
-            if (!mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed()) {
-                startNetStatPoll();
-                notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
-            } else {
-                // clean slate after call end.
-                resetPollStats();
-            }
-            notifyOffApnsOfAvailability(Phone.REASON_VOICE_CALL_ENDED);
-        } else {
-            mDataConnections.get(0).resetRetryCount();
-            // in case data setup was attempted when we were on a voice call
-            trySetupData(Phone.REASON_VOICE_CALL_ENDED);
-        }
-    }
-
-    @Override
-    protected void onCleanUpConnection(boolean tearDown, int apnId, String reason) {
-        // No apnId check; only one connection is supported
-        cleanUpConnection(tearDown, reason, (apnId == APN_DUN_ID));
-    }
-
-    @Override
-    protected void onCleanUpAllConnections(String cause) {
-        // Only one CDMA connection is supported
-        cleanUpConnection(true, cause, false);
-    }
-
-    private void createAllDataConnectionList() {
-        CdmaDataConnection dataConn;
-
-        String retryConfig = SystemProperties.get("ro.cdma.data_retry_config");
-        for (int i = 0; i < DATA_CONNECTION_POOL_SIZE; i++) {
-            RetryManager rm = new RetryManager();
-            if (!rm.configure(retryConfig)) {
-                if (!rm.configure(DEFAULT_DATA_RETRY_CONFIG)) {
-                    // Should never happen, log an error and default to a simple linear sequence.
-                    log("Could not configure using DEFAULT_DATA_RETRY_CONFIG="
-                            + DEFAULT_DATA_RETRY_CONFIG);
-                    rm.configure(20, 2000, 1000);
-                }
-            }
-
-            int id = mUniqueIdGenerator.getAndIncrement();
-            dataConn = CdmaDataConnection.makeDataConnection(mCdmaPhone, id, rm, this);
-            mDataConnections.put(id, dataConn);
-            DataConnectionAc dcac = new DataConnectionAc(dataConn, LOG_TAG);
-            int status = dcac.fullyConnectSync(mPhone.getContext(), this, dataConn.getHandler());
-            if (status == AsyncChannel.STATUS_SUCCESSFUL) {
-                log("Fully connected");
-                mDataConnectionAsyncChannels.put(dcac.dataConnection.getDataConnectionId(), dcac);
-            } else {
-                log("Could not connect to dcac.dataConnection=" + dcac.dataConnection +
-                        " status=" + status);
-            }
-
-        }
-    }
-
-    private void destroyAllDataConnectionList() {
-        if(mDataConnections != null) {
-            mDataConnections.clear();
-        }
-    }
-
-    private void onCdmaDataDetached() {
-        if (mState == State.CONNECTED) {
-            startNetStatPoll();
-            notifyDataConnection(Phone.REASON_CDMA_DATA_DETACHED);
-        } else {
-            if (mState == State.FAILED) {
-                cleanUpConnection(false, Phone.REASON_CDMA_DATA_DETACHED, false);
-                mDataConnections.get(0).resetRetryCount();
-
-                CdmaCellLocation loc = (CdmaCellLocation)(mPhone.getCellLocation());
-                EventLog.writeEvent(EventLogTags.CDMA_DATA_SETUP_FAILED,
-                        loc != null ? loc.getBaseStationId() : -1,
-                        TelephonyManager.getDefault().getNetworkType());
-            }
-            trySetupData(Phone.REASON_CDMA_DATA_DETACHED);
-        }
-    }
-
-    private void onCdmaOtaProvision(AsyncResult ar) {
-        if (ar.exception != null) {
-            int [] otaPrivision = (int [])ar.result;
-            if ((otaPrivision != null) && (otaPrivision.length > 1)) {
-                switch (otaPrivision[0]) {
-                case Phone.CDMA_OTA_PROVISION_STATUS_COMMITTED:
-                case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED:
-                    mDataConnections.get(0).resetRetryCount();
-                    break;
-                default:
-                    break;
-                }
-            }
-        }
-    }
-
-    private void onRestartRadio() {
-        if (mPendingRestartRadio) {
-            log("************TURN OFF RADIO**************");
-            mPhone.mCM.setRadioPower(false, null);
-            /* Note: no need to call setRadioPower(true).  Assuming the desired
-             * radio power state is still ON (as tracked by ServiceStateTracker),
-             * ServiceStateTracker will call setRadioPower when it receives the
-             * RADIO_STATE_CHANGED notification for the power off.  And if the
-             * desired power state has changed in the interim, we don't want to
-             * override it with an unconditional power on.
-             */
-            mPendingRestartRadio = false;
-        }
-    }
-
-    private void writeEventLogCdmaDataDrop() {
-        CdmaCellLocation loc = (CdmaCellLocation)(mPhone.getCellLocation());
-        EventLog.writeEvent(EventLogTags.CDMA_DATA_DROP,
-                loc != null ? loc.getBaseStationId() : -1,
-                TelephonyManager.getDefault().getNetworkType());
-    }
-
-    protected void onDataStateChanged(AsyncResult ar) {
-        ArrayList<DataCallState> dataCallStates = (ArrayList<DataCallState>)(ar.result);
-
-        if (ar.exception != null) {
-            // This is probably "radio not available" or something
-            // of that sort. If so, the whole connection is going
-            // to come down soon anyway
-            return;
-        }
-
-        if (mState == State.CONNECTED) {
-            boolean isActiveOrDormantConnectionPresent = false;
-            int connectionState = DATA_CONNECTION_ACTIVE_PH_LINK_INACTIVE;
-
-            // Check for an active or dormant connection element in
-            // the DATA_CALL_LIST array
-            for (int index = 0; index < dataCallStates.size(); index++) {
-                connectionState = dataCallStates.get(index).active;
-                if (connectionState != DATA_CONNECTION_ACTIVE_PH_LINK_INACTIVE) {
-                    isActiveOrDormantConnectionPresent = true;
-                    break;
-                }
-            }
-
-            if (!isActiveOrDormantConnectionPresent) {
-                // No active or dormant connection
-                log("onDataStateChanged: No active connection"
-                        + "state is CONNECTED, disconnecting/cleanup");
-                writeEventLogCdmaDataDrop();
-                cleanUpConnection(true, null, false);
-                return;
-            }
-
-            switch (connectionState) {
-                case DATA_CONNECTION_ACTIVE_PH_LINK_UP:
-                    log("onDataStateChanged: active=LINK_ACTIVE && CONNECTED, ignore");
-                    mActivity = Activity.NONE;
-                    mPhone.notifyDataActivity();
-                    startNetStatPoll();
-                    break;
-
-                case DATA_CONNECTION_ACTIVE_PH_LINK_DOWN:
-                    log("onDataStateChanged active=LINK_DOWN && CONNECTED, dormant");
-                    mActivity = Activity.DORMANT;
-                    mPhone.notifyDataActivity();
-                    stopNetStatPoll();
-                    break;
-
-                default:
-                    log("onDataStateChanged: IGNORE unexpected DataCallState.active="
-                            + connectionState);
-            }
-        } else {
-            // TODO: Do we need to do anything?
-            log("onDataStateChanged: not connected, state=" + mState + " ignoring");
-        }
-    }
-
-    private void startDelayedRetry(FailCause cause, String reason, int retryOverride) {
-        notifyNoData(cause);
-        reconnectAfterFail(cause, reason, retryOverride);
-    }
-
-    @Override
-    public void handleMessage (Message msg) {
-        if (DBG) log("CdmaDCT handleMessage msg=" + msg);
-
-        if (!mPhone.mIsTheCurrentActivePhone || mIsDisposed) {
-            log("Ignore CDMA msgs since CDMA phone is inactive");
-            return;
-        }
-
-        switch (msg.what) {
-            case EVENT_RECORDS_LOADED:
-                onRecordsLoaded();
-                break;
-
-            case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
-                if(mCdmaSSM.getCdmaSubscriptionSource() ==
-                       CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_NV) {
-                    onNVReady();
-                }
-                break;
-
-            case EVENT_CDMA_DATA_DETACHED:
-                onCdmaDataDetached();
-                break;
-
-            case EVENT_DATA_STATE_CHANGED:
-                onDataStateChanged((AsyncResult) msg.obj);
-                break;
-
-            case EVENT_CDMA_OTA_PROVISION:
-                onCdmaOtaProvision((AsyncResult) msg.obj);
-                break;
-
-            case EVENT_RESTART_RADIO:
-                if (DBG) log("EVENT_RESTART_RADIO");
-                onRestartRadio();
-                break;
-
-            default:
-                // handle the message in the super class DataConnectionTracker
-                super.handleMessage(msg);
-                break;
-        }
-    }
-
-    @Override
-    public boolean isDisconnected() {
-        return ((mState == State.IDLE) || (mState == State.FAILED));
-    }
-
-    @Override
-    protected void log(String s) {
-        Log.d(LOG_TAG, "[CdmaDCT] " + s);
-    }
-
-    @Override
-    protected void loge(String s) {
-        Log.e(LOG_TAG, "[CdmaDCT] " + s);
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("CdmaDataConnectionTracker extends:");
-        super.dump(fd, pw, args);
-        pw.println(" mCdmaPhone=" + mCdmaPhone);
-        pw.println(" mCdmaSSM=" + mCdmaSSM);
-        pw.println(" mPendingDataConnection=" + mPendingDataConnection);
-        pw.println(" mPendingRestartRadio=" + mPendingRestartRadio);
-        pw.println(" mSupportedApnTypes=" + mSupportedApnTypes);
-        pw.println(" mDefaultApnTypes=" + mDefaultApnTypes);
-        pw.println(" mDunApnTypes=" + mDunApnTypes);
-        pw.println(" mDefaultApnId=" + mDefaultApnId);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java b/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java
deleted file mode 100644
index ce6530a..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java
+++ /dev/null
@@ -1,263 +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.
- */
-
-package com.android.internal.telephony.cdma;
-import static com.android.internal.telephony.RILConstants.*;
-import android.os.Parcel;
-
-public final class CdmaInformationRecords {
-    public Object record;
-
-    /**
-     * Record type identifier
-     */
-    public static final int RIL_CDMA_DISPLAY_INFO_REC = 0;
-    public static final int RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC = 1;
-    public static final int RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC = 2;
-    public static final int RIL_CDMA_CONNECTED_NUMBER_INFO_REC = 3;
-    public static final int RIL_CDMA_SIGNAL_INFO_REC = 4;
-    public static final int RIL_CDMA_REDIRECTING_NUMBER_INFO_REC = 5;
-    public static final int RIL_CDMA_LINE_CONTROL_INFO_REC = 6;
-    public static final int RIL_CDMA_EXTENDED_DISPLAY_INFO_REC = 7;
-    public static final int RIL_CDMA_T53_CLIR_INFO_REC = 8;
-    public static final int RIL_CDMA_T53_RELEASE_INFO_REC = 9;
-    public static final int RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC = 10;
-
-    public CdmaInformationRecords(Parcel p) {
-        int id = p.readInt();
-        switch (id) {
-            case RIL_CDMA_DISPLAY_INFO_REC:
-            case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC:
-                record  = new CdmaDisplayInfoRec(id, p.readString());
-                break;
-
-            case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC:
-            case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC:
-            case RIL_CDMA_CONNECTED_NUMBER_INFO_REC:
-                record = new CdmaNumberInfoRec(id, p.readString(), p.readInt(), p.readInt(),
-                        p.readInt(), p.readInt());
-                break;
-
-            case RIL_CDMA_SIGNAL_INFO_REC:
-                record = new CdmaSignalInfoRec(p.readInt(), p.readInt(), p.readInt(), p.readInt());
-                break;
-
-            case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC:
-                record = new CdmaRedirectingNumberInfoRec(p.readString(), p.readInt(), p.readInt(),
-                        p.readInt(), p.readInt(), p.readInt());
-                break;
-
-            case RIL_CDMA_LINE_CONTROL_INFO_REC:
-                record = new CdmaLineControlInfoRec(p.readInt(), p.readInt(), p.readInt(),
-                        p.readInt());
-                break;
-
-            case RIL_CDMA_T53_CLIR_INFO_REC:
-                record = new CdmaT53ClirInfoRec(p.readInt());
-                break;
-
-            case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC:
-                record = new CdmaT53AudioControlInfoRec(p.readInt(), p.readInt());
-                break;
-
-            case RIL_CDMA_T53_RELEASE_INFO_REC:
-                // TODO: WHAT to do, for now fall through and throw exception
-            default:
-                throw new RuntimeException("RIL_UNSOL_CDMA_INFO_REC: unsupported record. Got "
-                                            + CdmaInformationRecords.idToString(id) + " ");
-
-        }
-    }
-
-    public static String idToString(int id) {
-        switch(id) {
-        case RIL_CDMA_DISPLAY_INFO_REC: return "RIL_CDMA_DISPLAY_INFO_REC";
-        case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC: return "RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC";
-        case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC: return "RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC";
-        case RIL_CDMA_CONNECTED_NUMBER_INFO_REC: return "RIL_CDMA_CONNECTED_NUMBER_INFO_REC";
-        case RIL_CDMA_SIGNAL_INFO_REC: return "RIL_CDMA_SIGNAL_INFO_REC";
-        case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC: return "RIL_CDMA_REDIRECTING_NUMBER_INFO_REC";
-        case RIL_CDMA_LINE_CONTROL_INFO_REC: return "RIL_CDMA_LINE_CONTROL_INFO_REC";
-        case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC: return "RIL_CDMA_EXTENDED_DISPLAY_INFO_REC";
-        case RIL_CDMA_T53_CLIR_INFO_REC: return "RIL_CDMA_T53_CLIR_INFO_REC";
-        case RIL_CDMA_T53_RELEASE_INFO_REC: return "RIL_CDMA_T53_RELEASE_INFO_REC";
-        case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC: return "RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC";
-        default: return "<unknown record>";
-        }
-    }
-
-    /**
-     * Signal Information record from 3GPP2 C.S005 3.7.5.5
-     */
-    public static class CdmaSignalInfoRec {
-        public boolean isPresent;   /* non-zero if signal information record is present */
-        public int signalType;
-        public int alertPitch;
-        public int signal;
-
-        public CdmaSignalInfoRec() {}
-
-        public CdmaSignalInfoRec(int isPresent, int signalType, int alertPitch, int signal) {
-            this.isPresent = isPresent != 0;
-            this.signalType = signalType;
-            this.alertPitch = alertPitch;
-            this.signal = signal;
-        }
-
-        @Override
-        public String toString() {
-            return "CdmaSignalInfo: {" +
-                    " isPresent: " + isPresent +
-                    ", signalType: " + signalType +
-                    ", alertPitch: " + alertPitch +
-                    ", signal: " + signal +
-                    " }";
-        }
-    }
-
-    public static class CdmaDisplayInfoRec {
-        public int id;
-        public String alpha;
-
-        public CdmaDisplayInfoRec(int id, String alpha) {
-            this.id = id;
-            this.alpha = alpha;
-        }
-
-        @Override
-        public String toString() {
-            return "CdmaDisplayInfoRec: {" +
-                    " id: " + CdmaInformationRecords.idToString(id) +
-                    ", alpha: " + alpha +
-                    " }";
-        }
-    }
-
-    public static class CdmaNumberInfoRec {
-        public int id;
-        public String number;
-        public byte numberType;
-        public byte numberPlan;
-        public byte pi;
-        public byte si;
-
-        public CdmaNumberInfoRec(int id, String number, int numberType, int numberPlan, int pi,
-                int si) {
-            this.number = number;
-            this.numberType = (byte)numberType;
-            this.numberPlan = (byte)numberPlan;
-            this.pi = (byte)pi;
-            this.si = (byte)si;
-        }
-
-        @Override
-        public String toString() {
-            return "CdmaNumberInfoRec: {" +
-                    " id: " + CdmaInformationRecords.idToString(id) +
-                    ", number: " + number +
-                    ", numberType: " + numberType +
-                    ", numberPlan: " + numberPlan +
-                    ", pi: " + pi +
-                    ", si: " + si +
-                    " }";
-        }
-    }
-
-    public static class CdmaRedirectingNumberInfoRec {
-        public static final int REASON_UNKNOWN = 0;
-        public static final int REASON_CALL_FORWARDING_BUSY = 1;
-        public static final int REASON_CALL_FORWARDING_NO_REPLY = 2;
-        public static final int REASON_CALLED_DTE_OUT_OF_ORDER = 9;
-        public static final int REASON_CALL_FORWARDING_BY_THE_CALLED_DTE = 10;
-        public static final int REASON_CALL_FORWARDING_UNCONDITIONAL = 15;
-
-        public CdmaNumberInfoRec numberInfoRec;
-        public int redirectingReason;
-
-        public CdmaRedirectingNumberInfoRec(String number, int numberType, int numberPlan,
-                int pi, int si, int reason) {
-            numberInfoRec = new CdmaNumberInfoRec(RIL_CDMA_REDIRECTING_NUMBER_INFO_REC,
-                                                  number, numberType, numberPlan, pi, si);
-            redirectingReason = reason;
-        }
-
-        @Override
-        public String toString() {
-            return "CdmaNumberInfoRec: {" +
-                    " numberInfoRec: " + numberInfoRec +
-                    ", redirectingReason: " + redirectingReason +
-                    " }";
-        }
-    }
-
-    public static class CdmaLineControlInfoRec {
-        public byte lineCtrlPolarityIncluded;
-        public byte lineCtrlToggle;
-        public byte lineCtrlReverse;
-        public byte lineCtrlPowerDenial;
-
-        public CdmaLineControlInfoRec(int lineCtrlPolarityIncluded, int lineCtrlToggle,
-                int lineCtrlReverse, int lineCtrlPowerDenial) {
-            this.lineCtrlPolarityIncluded = (byte)lineCtrlPolarityIncluded;
-            this.lineCtrlToggle = (byte)lineCtrlToggle;
-            this.lineCtrlReverse = (byte)lineCtrlReverse;
-            this.lineCtrlPowerDenial = (byte)lineCtrlPowerDenial;
-        }
-
-        @Override
-        public String toString() {
-            return "CdmaLineControlInfoRec: {" +
-                    " lineCtrlPolarityIncluded: " + lineCtrlPolarityIncluded +
-                    " lineCtrlToggle: " + lineCtrlToggle +
-                    " lineCtrlReverse: " + lineCtrlReverse +
-                    " lineCtrlPowerDenial: " + lineCtrlPowerDenial +
-                    " }";
-        }
-    }
-
-    public static class CdmaT53ClirInfoRec {
-        public byte cause;
-
-        public CdmaT53ClirInfoRec(int cause) {
-            this.cause = (byte)cause;
-        }
-
-        @Override
-        public String toString() {
-            return "CdmaT53ClirInfoRec: {" +
-                    " cause: " + cause +
-                    " }";
-        }
-    }
-
-    public static class CdmaT53AudioControlInfoRec {
-        public byte uplink;
-        public byte downlink;
-
-        public CdmaT53AudioControlInfoRec(int uplink, int downlink) {
-            this.uplink = (byte) uplink;
-            this.downlink = (byte) downlink;
-        }
-
-        @Override
-        public String toString() {
-            return "CdmaT53AudioControlInfoRec: {" +
-                    " uplink: " + uplink +
-                    " downlink: " + downlink +
-                    " }";
-        }
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
deleted file mode 100644
index 0a40c75..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
+++ /dev/null
@@ -1,546 +0,0 @@
-/*
- * 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.internal.telephony.cdma;
-
-import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.telephony.MccTable;
-import com.android.internal.telephony.EventLogTags;
-import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.IccCard;
-
-import android.content.Intent;
-import android.telephony.SignalStrength;
-import android.telephony.ServiceState;
-import android.telephony.cdma.CdmaCellLocation;
-import android.os.AsyncResult;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.provider.Telephony.Intents;
-
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.EventLog;
-
-import com.android.internal.telephony.gsm.GsmDataConnectionTracker;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
-    CDMALTEPhone mCdmaLtePhone;
-
-    private ServiceState  mLteSS;  // The last LTE state from Voice Registration
-
-    public CdmaLteServiceStateTracker(CDMALTEPhone phone) {
-        super(phone);
-        mCdmaLtePhone = phone;
-
-        mLteSS = new ServiceState();
-        if (DBG) log("CdmaLteServiceStateTracker Constructors");
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-        AsyncResult ar;
-        int[] ints;
-        String[] strings;
-        switch (msg.what) {
-        case EVENT_POLL_STATE_GPRS:
-            if (DBG) log("handleMessage EVENT_POLL_STATE_GPRS");
-            ar = (AsyncResult)msg.obj;
-            handlePollStateResult(msg.what, ar);
-            break;
-        case EVENT_RUIM_RECORDS_LOADED:
-            CdmaLteUiccRecords sim = (CdmaLteUiccRecords)phone.mIccRecords;
-            if ((sim != null) && sim.isProvisioned()) {
-                mMdn = sim.getMdn();
-                mMin = sim.getMin();
-                parseSidNid(sim.getSid(), sim.getNid());
-                mPrlVersion = sim.getPrlVersion();;
-                mIsMinInfoReady = true;
-                updateOtaspState();
-            }
-            // SID/NID/PRL is loaded. Poll service state
-            // again to update to the roaming state with
-            // the latest variables.
-            pollState();
-            break;
-        default:
-            super.handleMessage(msg);
-        }
-    }
-
-    /**
-     * Set the cdmaSS for EVENT_POLL_STATE_REGISTRATION_CDMA
-     */
-    @Override
-    protected void setCdmaTechnology(int radioTechnology) {
-        // Called on voice registration state response.
-        // Just record new CDMA radio technology
-        newSS.setRadioTechnology(radioTechnology);
-    }
-
-    /**
-     * Handle the result of one of the pollState()-related requests
-     */
-    @Override
-    protected void handlePollStateResultMessage(int what, AsyncResult ar) {
-        if (what == EVENT_POLL_STATE_GPRS) {
-            if (DBG) log("handlePollStateResultMessage: EVENT_POLL_STATE_GPRS");
-            String states[] = (String[])ar.result;
-
-            int type = 0;
-            int regState = -1;
-            if (states.length > 0) {
-                try {
-                    regState = Integer.parseInt(states[0]);
-
-                    // states[3] (if present) is the current radio technology
-                    if (states.length >= 4 && states[3] != null) {
-                        type = Integer.parseInt(states[3]);
-                    }
-                } catch (NumberFormatException ex) {
-                    loge("handlePollStateResultMessage: error parsing GprsRegistrationState: "
-                                    + ex);
-                }
-            }
-
-            mLteSS.setRadioTechnology(type);
-            mLteSS.setState(regCodeToServiceState(regState));
-        } else {
-            super.handlePollStateResultMessage(what, ar);
-        }
-    }
-
-    @Override
-    protected void setSignalStrengthDefaultValues() {
-        // TODO Make a constructor only has boolean gsm as parameter
-        mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1,
-                -1, -1, -1, SignalStrength.INVALID_SNR, -1, false);
-    }
-
-    @Override
-    protected void pollState() {
-        pollingContext = new int[1];
-        pollingContext[0] = 0;
-
-        switch (cm.getRadioState()) {
-            case RADIO_UNAVAILABLE:
-                newSS.setStateOutOfService();
-                newCellLoc.setStateInvalid();
-                setSignalStrengthDefaultValues();
-                mGotCountryCode = false;
-
-                pollStateDone();
-                break;
-
-            case RADIO_OFF:
-                newSS.setStateOff();
-                newCellLoc.setStateInvalid();
-                setSignalStrengthDefaultValues();
-                mGotCountryCode = false;
-
-                pollStateDone();
-                break;
-
-            default:
-                // Issue all poll-related commands at once, then count
-                // down the responses which are allowed to arrive
-                // out-of-order.
-
-                pollingContext[0]++;
-                // RIL_REQUEST_OPERATOR is necessary for CDMA
-                cm.getOperator(obtainMessage(EVENT_POLL_STATE_OPERATOR_CDMA, pollingContext));
-
-                pollingContext[0]++;
-                // RIL_REQUEST_VOICE_REGISTRATION_STATE is necessary for CDMA
-                cm.getVoiceRegistrationState(obtainMessage(EVENT_POLL_STATE_REGISTRATION_CDMA,
-                        pollingContext));
-
-                int networkMode = android.provider.Settings.Secure.getInt(phone.getContext()
-                        .getContentResolver(),
-                        android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
-                        RILConstants.PREFERRED_NETWORK_MODE);
-                if (DBG) log("pollState: network mode here is = " + networkMode);
-                if ((networkMode == RILConstants.NETWORK_MODE_GLOBAL)
-                        || (networkMode == RILConstants.NETWORK_MODE_LTE_ONLY)) {
-                    pollingContext[0]++;
-                    // RIL_REQUEST_DATA_REGISTRATION_STATE
-                    cm.getDataRegistrationState(obtainMessage(EVENT_POLL_STATE_GPRS,
-                                                pollingContext));
-                }
-                break;
-        }
-    }
-
-    @Override
-    protected void pollStateDone() {
-        // determine data RadioTechnology from both LET and CDMA SS
-        if (mLteSS.getState() == ServiceState.STATE_IN_SERVICE) {
-            //in LTE service
-            mNewRilRadioTechnology = mLteSS.getRilRadioTechnology();
-            mNewDataConnectionState = mLteSS.getState();
-            newSS.setRadioTechnology(mNewRilRadioTechnology);
-            log("pollStateDone LTE/eHRPD STATE_IN_SERVICE mNewRilRadioTechnology = " +
-                    mNewRilRadioTechnology);
-        } else {
-            // LTE out of service, get CDMA Service State
-            mNewRilRadioTechnology = newSS.getRilRadioTechnology();
-            mNewDataConnectionState = radioTechnologyToDataServiceState(mNewRilRadioTechnology);
-            log("pollStateDone CDMA STATE_IN_SERVICE mNewRilRadioTechnology = " +
-                    mNewRilRadioTechnology + " mNewDataConnectionState = " +
-                    mNewDataConnectionState);
-        }
-
-        // TODO: Add proper support for LTE Only, we should be looking at
-        //       the preferred network mode, to know when newSS state should
-        //       be coming from mLteSs state. This was needed to pass a VZW
-        //       LTE Only test.
-        //
-        // If CDMA service is OOS, double check if the device is running with LTE only
-        // mode. If that is the case, derive the service state from LTE side.
-        // To set in LTE only mode, sqlite3 /data/data/com.android.providers.settings/
-        // databases/settings.db "update secure set value='11' where name='preferred_network_mode'"
-        if (newSS.getState() == ServiceState.STATE_OUT_OF_SERVICE) {
-            int networkMode = android.provider.Settings.Secure.getInt(phone.getContext()
-                                  .getContentResolver(),
-                                  android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
-                                  RILConstants.PREFERRED_NETWORK_MODE);
-            if (networkMode == RILConstants.NETWORK_MODE_LTE_ONLY) {
-                if (DBG) log("pollState: LTE Only mode");
-                newSS.setState(mLteSS.getState());
-            }
-        }
-
-        if (DBG) log("pollStateDone: oldSS=[" + ss + "] newSS=[" + newSS + "]");
-
-        boolean hasRegistered = ss.getState() != ServiceState.STATE_IN_SERVICE
-                && newSS.getState() == ServiceState.STATE_IN_SERVICE;
-
-        boolean hasDeregistered = ss.getState() == ServiceState.STATE_IN_SERVICE
-                && newSS.getState() != ServiceState.STATE_IN_SERVICE;
-
-        boolean hasCdmaDataConnectionAttached =
-            mDataConnectionState != ServiceState.STATE_IN_SERVICE
-                && mNewDataConnectionState == ServiceState.STATE_IN_SERVICE;
-
-        boolean hasCdmaDataConnectionDetached =
-            mDataConnectionState == ServiceState.STATE_IN_SERVICE
-                && mNewDataConnectionState != ServiceState.STATE_IN_SERVICE;
-
-        boolean hasCdmaDataConnectionChanged =
-            mDataConnectionState != mNewDataConnectionState;
-
-        boolean hasRadioTechnologyChanged = mRilRadioTechnology != mNewRilRadioTechnology;
-
-        boolean hasChanged = !newSS.equals(ss);
-
-        boolean hasRoamingOn = !ss.getRoaming() && newSS.getRoaming();
-
-        boolean hasRoamingOff = ss.getRoaming() && !newSS.getRoaming();
-
-        boolean hasLocationChanged = !newCellLoc.equals(cellLoc);
-
-        boolean has4gHandoff =
-                mNewDataConnectionState == ServiceState.STATE_IN_SERVICE &&
-                (((mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) &&
-                  (mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)) ||
-                 ((mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD) &&
-                  (mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE)));
-
-        boolean hasMultiApnSupport =
-                (((mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) ||
-                  (mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)) &&
-                 ((mRilRadioTechnology != ServiceState.RIL_RADIO_TECHNOLOGY_LTE) &&
-                  (mRilRadioTechnology != ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)));
-
-        boolean hasLostMultiApnSupport =
-            ((mNewRilRadioTechnology >= ServiceState.RIL_RADIO_TECHNOLOGY_IS95A) &&
-             (mNewRilRadioTechnology <= ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A));
-
-        if (DBG) {
-            log("pollStateDone:"
-                + " hasRegistered=" + hasRegistered
-                + " hasDeegistered=" + hasDeregistered
-                + " hasCdmaDataConnectionAttached=" + hasCdmaDataConnectionAttached
-                + " hasCdmaDataConnectionDetached=" + hasCdmaDataConnectionDetached
-                + " hasCdmaDataConnectionChanged=" + hasCdmaDataConnectionChanged
-                + " hasRadioTechnologyChanged = " + hasRadioTechnologyChanged
-                + " hasChanged=" + hasChanged
-                + " hasRoamingOn=" + hasRoamingOn
-                + " hasRoamingOff=" + hasRoamingOff
-                + " hasLocationChanged=" + hasLocationChanged
-                + " has4gHandoff = " + has4gHandoff
-                + " hasMultiApnSupport=" + hasMultiApnSupport
-                + " hasLostMultiApnSupport=" + hasLostMultiApnSupport);
-        }
-        // Add an event log when connection state changes
-        if (ss.getState() != newSS.getState()
-                || mDataConnectionState != mNewDataConnectionState) {
-            EventLog.writeEvent(EventLogTags.CDMA_SERVICE_STATE_CHANGE, ss.getState(),
-                    mDataConnectionState, newSS.getState(), mNewDataConnectionState);
-        }
-
-        ServiceState tss;
-        tss = ss;
-        ss = newSS;
-        newSS = tss;
-        // clean slate for next time
-        newSS.setStateOutOfService();
-        mLteSS.setStateOutOfService();
-
-        if ((hasMultiApnSupport)
-                && (phone.mDataConnectionTracker instanceof CdmaDataConnectionTracker)) {
-            if (DBG) log("GsmDataConnectionTracker Created");
-            phone.mDataConnectionTracker.dispose();
-            phone.mDataConnectionTracker = new GsmDataConnectionTracker(mCdmaLtePhone);
-        }
-
-        if ((hasLostMultiApnSupport)
-                && (phone.mDataConnectionTracker instanceof GsmDataConnectionTracker)) {
-            if (DBG)log("GsmDataConnectionTracker disposed");
-            phone.mDataConnectionTracker.dispose();
-            phone.mDataConnectionTracker = new CdmaDataConnectionTracker(phone);
-        }
-
-        CdmaCellLocation tcl = cellLoc;
-        cellLoc = newCellLoc;
-        newCellLoc = tcl;
-
-        mDataConnectionState = mNewDataConnectionState;
-        mRilRadioTechnology = mNewRilRadioTechnology;
-        mNewRilRadioTechnology = 0;
-
-        newSS.setStateOutOfService(); // clean slate for next time
-
-        if (hasRadioTechnologyChanged) {
-            phone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
-                    ServiceState.rilRadioTechnologyToString(mRilRadioTechnology));
-        }
-
-        if (hasRegistered) {
-            mNetworkAttachedRegistrants.notifyRegistrants();
-        }
-
-        if (hasChanged) {
-            if (phone.isEriFileLoaded()) {
-                String eriText;
-                // Now the CDMAPhone sees the new ServiceState so it can get the
-                // new ERI text
-                if (ss.getState() == ServiceState.STATE_IN_SERVICE) {
-                    eriText = phone.getCdmaEriText();
-                } else if (ss.getState() == ServiceState.STATE_POWER_OFF) {
-                    eriText = phone.mIccRecords.getServiceProviderName();
-                    if (TextUtils.isEmpty(eriText)) {
-                        // Sets operator alpha property by retrieving from
-                        // build-time system property
-                        eriText = SystemProperties.get("ro.cdma.home.operator.alpha");
-                    }
-                } else {
-                    // Note that ServiceState.STATE_OUT_OF_SERVICE is valid used
-                    // for mRegistrationState 0,2,3 and 4
-                    eriText = phone.getContext()
-                            .getText(com.android.internal.R.string.roamingTextSearching).toString();
-                }
-                ss.setOperatorAlphaLong(eriText);
-            }
-
-            if (phone.getIccCard().getState() == IccCard.State.READY) {
-                // SIM is found on the device. If ERI roaming is OFF, and SID/NID matches
-                // one configfured in SIM, use operator name  from CSIM record.
-                boolean showSpn =
-                    ((CdmaLteUiccRecords)phone.mIccRecords).getCsimSpnDisplayCondition();
-                int iconIndex = ss.getCdmaEriIconIndex();
-
-                if (showSpn && (iconIndex == EriInfo.ROAMING_INDICATOR_OFF) &&
-                    isInHomeSidNid(ss.getSystemId(), ss.getNetworkId())) {
-                    ss.setOperatorAlphaLong(phone.mIccRecords.getServiceProviderName());
-                }
-            }
-
-            String operatorNumeric;
-
-            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA,
-                    ss.getOperatorAlphaLong());
-
-            String prevOperatorNumeric =
-                    SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, "");
-            operatorNumeric = ss.getOperatorNumeric();
-            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric);
-
-            if (operatorNumeric == null) {
-                if (DBG) log("operatorNumeric is null");
-                phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
-                mGotCountryCode = false;
-            } else {
-                String isoCountryCode = "";
-                String mcc = operatorNumeric.substring(0, 3);
-                try {
-                    isoCountryCode = MccTable.countryCodeForMcc(Integer.parseInt(operatorNumeric
-                            .substring(0, 3)));
-                } catch (NumberFormatException ex) {
-                    loge("countryCodeForMcc error" + ex);
-                } catch (StringIndexOutOfBoundsException ex) {
-                    loge("countryCodeForMcc error" + ex);
-                }
-
-                phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY,
-                        isoCountryCode);
-                mGotCountryCode = true;
-
-                if (shouldFixTimeZoneNow(phone, operatorNumeric, prevOperatorNumeric,
-                        mNeedFixZone)) {
-                    fixTimeZone(isoCountryCode);
-                }
-            }
-
-            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
-                    ss.getRoaming() ? "true" : "false");
-
-            updateSpnDisplay();
-            phone.notifyServiceStateChanged(ss);
-        }
-
-        if (hasCdmaDataConnectionAttached || has4gHandoff) {
-            mAttachedRegistrants.notifyRegistrants();
-        }
-
-        if (hasCdmaDataConnectionDetached) {
-            mDetachedRegistrants.notifyRegistrants();
-        }
-
-        if ((hasCdmaDataConnectionChanged || hasRadioTechnologyChanged)) {
-            phone.notifyDataConnection(null);
-        }
-
-        if (hasRoamingOn) {
-            mRoamingOnRegistrants.notifyRegistrants();
-        }
-
-        if (hasRoamingOff) {
-            mRoamingOffRegistrants.notifyRegistrants();
-        }
-
-        if (hasLocationChanged) {
-            phone.notifyLocationChanged();
-        }
-    }
-
-    @Override
-    protected void onSignalStrengthResult(AsyncResult ar) {
-        SignalStrength oldSignalStrength = mSignalStrength;
-
-        if (ar.exception != null) {
-            // Most likely radio is resetting/disconnected change to default
-            // values.
-            setSignalStrengthDefaultValues();
-        } else {
-            int[] ints = (int[])ar.result;
-
-            int lteRssi = -1;
-            int lteRsrp = -1;
-            int lteRsrq = -1;
-            int lteRssnr = SignalStrength.INVALID_SNR;
-            int lteCqi = -1;
-
-            int offset = 2;
-            int cdmaDbm = (ints[offset] > 0) ? -ints[offset] : -120;
-            int cdmaEcio = (ints[offset + 1] > 0) ? -ints[offset + 1] : -160;
-            int evdoRssi = (ints[offset + 2] > 0) ? -ints[offset + 2] : -120;
-            int evdoEcio = (ints[offset + 3] > 0) ? -ints[offset + 3] : -1;
-            int evdoSnr = ((ints[offset + 4] > 0) && (ints[offset + 4] <= 8)) ? ints[offset + 4]
-                    : -1;
-
-            if (mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) {
-                lteRssi = ints[offset+5];
-                lteRsrp = ints[offset+6];
-                lteRsrq = ints[offset+7];
-                lteRssnr = ints[offset+8];
-                lteCqi = ints[offset+9];
-            }
-
-            if (mRilRadioTechnology != ServiceState.RIL_RADIO_TECHNOLOGY_LTE) {
-                mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio, evdoRssi, evdoEcio,
-                        evdoSnr, false);
-            } else {
-                mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio, evdoRssi, evdoEcio,
-                        evdoSnr, lteRssi, lteRsrp, lteRsrq, lteRssnr, lteCqi, true);
-            }
-        }
-
-        try {
-            phone.notifySignalStrength();
-        } catch (NullPointerException ex) {
-            loge("onSignalStrengthResult() Phone already destroyed: " + ex
-                    + "SignalStrength not notified");
-        }
-    }
-
-    @Override
-    public boolean isConcurrentVoiceAndDataAllowed() {
-        // Note: it needs to be confirmed which CDMA network types
-        // can support voice and data calls concurrently.
-        // For the time-being, the return value will be false.
-        return (mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE);
-    }
-
-    /**
-     * Check whether the specified SID and NID pair appears in the HOME SID/NID list
-     * read from NV or SIM.
-     *
-     * @return true if provided sid/nid pair belongs to operator's home network.
-     */
-    private boolean isInHomeSidNid(int sid, int nid) {
-        // if SID/NID is not available, assume this is home network.
-        if (isSidsAllZeros()) return true;
-
-        // length of SID/NID shold be same
-        if (mHomeSystemId.length != mHomeNetworkId.length) return true;
-
-        if (sid == 0) return true;
-
-        for (int i = 0; i < mHomeSystemId.length; i++) {
-            // Use SID only if NID is a reserved value.
-            // SID 0 and NID 0 and 65535 are reserved. (C.0005 2.6.5.2)
-            if ((mHomeSystemId[i] == sid) &&
-                ((mHomeNetworkId[i] == 0) || (mHomeNetworkId[i] == 65535) ||
-                 (nid == 0) || (nid == 65535) || (mHomeNetworkId[i] == nid))) {
-                return true;
-            }
-        }
-        // SID/NID are not in the list. So device is not in home network
-        return false;
-    }
-
-    @Override
-    protected void log(String s) {
-        Log.d(LOG_TAG, "[CdmaLteSST] " + s);
-    }
-
-    @Override
-    protected void loge(String s) {
-        Log.e(LOG_TAG, "[CdmaLteSST] " + s);
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("CdmaLteServiceStateTracker extends:");
-        super.dump(fd, pw, args);
-        pw.println(" mCdmaLtePhone=" + mCdmaLtePhone);
-        pw.println(" mLteSS=" + mLteSS);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java
deleted file mode 100644
index 93a6290..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2011 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.internal.telephony.cdma;
-
-import android.util.Log;
-
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccConstants;
-import com.android.internal.telephony.IccFileHandler;
-import android.os.Message;
-
-/**
- * {@hide}
- */
-public final class CdmaLteUiccFileHandler extends IccFileHandler {
-    static final String LOG_TAG = "CDMA";
-
-    public CdmaLteUiccFileHandler(IccCard card, String aid, CommandsInterface ci) {
-        super(card, aid, ci);
-    }
-
-    protected String getEFPath(int efid) {
-        switch(efid) {
-        case EF_CSIM_SPN:
-        case EF_CSIM_LI:
-        case EF_CSIM_MDN:
-        case EF_CSIM_IMSIM:
-        case EF_CSIM_CDMAHOME:
-        case EF_CSIM_EPRL:
-            return MF_SIM + DF_CDMA;
-        case EF_AD:
-            return MF_SIM + DF_GSM;
-        case EF_IMPI:
-        case EF_DOMAIN:
-        case EF_IMPU:
-            return MF_SIM + DF_ADFISIM;
-        }
-        return getCommonIccEFPath(efid);
-    }
-
-    @Override
-    public void loadEFTransparent(int fileid, Message onLoaded) {
-        if (fileid == EF_CSIM_EPRL) {
-            // Entire PRL could be huge. We are only interested in
-            // the first 4 bytes of the record.
-            mCi.iccIOForApp(COMMAND_READ_BINARY, fileid, getEFPath(fileid),
-                            0, 0, 4, null, null, mAid,
-                            obtainMessage(EVENT_READ_BINARY_DONE,
-                                          fileid, 0, onLoaded));
-        } else {
-            super.loadEFTransparent(fileid, onLoaded);
-        }
-    }
-
-
-    protected void logd(String msg) {
-        Log.d(LOG_TAG, "[CdmaLteUiccFileHandler] " + msg);
-    }
-
-    protected void loge(String msg) {
-        Log.e(LOG_TAG, "[CdmaLteUiccFileHandler] " + msg);
-    }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
deleted file mode 100755
index eaa2ede..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * Copyright (C) 2011 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.internal.telephony.cdma;
-
-import android.content.Context;
-import android.os.AsyncResult;
-import android.os.SystemProperties;
-import android.util.Log;
-
-import com.android.internal.telephony.AdnRecordLoader;
-import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.IccCardApplication.AppType;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccFileHandler;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.MccTable;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.SmsMessageBase;
-import com.android.internal.telephony.cdma.sms.UserData;
-import com.android.internal.telephony.gsm.SIMRecords;
-import com.android.internal.telephony.ims.IsimRecords;
-import com.android.internal.telephony.ims.IsimUiccRecords;
-
-import java.util.ArrayList;
-import java.util.Locale;
-
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_TEST_CSIM;
-
-/**
- * {@hide}
- */
-public final class CdmaLteUiccRecords extends SIMRecords {
-    // From CSIM application
-    private byte[] mEFpl = null;
-    private byte[] mEFli = null;
-    boolean mCsimSpnDisplayCondition = false;
-    private String mMdn;
-    private String mMin;
-    private String mPrlVersion;
-    private String mHomeSystemId;
-    private String mHomeNetworkId;
-
-    private final IsimUiccRecords mIsimUiccRecords = new IsimUiccRecords();
-
-    public CdmaLteUiccRecords(IccCard card, Context c, CommandsInterface ci) {
-        super(card, c, ci);
-    }
-
-    // Refer to ETSI TS 102.221
-    private class EfPlLoaded implements IccRecordLoaded {
-        public String getEfName() {
-            return "EF_PL";
-        }
-
-        public void onRecordLoaded(AsyncResult ar) {
-            mEFpl = (byte[]) ar.result;
-            if (DBG) log("EF_PL=" + IccUtils.bytesToHexString(mEFpl));
-        }
-    }
-
-    // Refer to C.S0065 5.2.26
-    private class EfCsimLiLoaded implements IccRecordLoaded {
-        public String getEfName() {
-            return "EF_CSIM_LI";
-        }
-
-        public void onRecordLoaded(AsyncResult ar) {
-            mEFli = (byte[]) ar.result;
-            // convert csim efli data to iso 639 format
-            for (int i = 0; i < mEFli.length; i+=2) {
-                switch(mEFli[i+1]) {
-                case 0x01: mEFli[i] = 'e'; mEFli[i+1] = 'n';break;
-                case 0x02: mEFli[i] = 'f'; mEFli[i+1] = 'r';break;
-                case 0x03: mEFli[i] = 'e'; mEFli[i+1] = 's';break;
-                case 0x04: mEFli[i] = 'j'; mEFli[i+1] = 'a';break;
-                case 0x05: mEFli[i] = 'k'; mEFli[i+1] = 'o';break;
-                case 0x06: mEFli[i] = 'z'; mEFli[i+1] = 'h';break;
-                case 0x07: mEFli[i] = 'h'; mEFli[i+1] = 'e';break;
-                default: mEFli[i] = ' '; mEFli[i+1] = ' ';
-                }
-            }
-
-            if (DBG) log("EF_LI=" + IccUtils.bytesToHexString(mEFli));
-        }
-    }
-
-    // Refer to C.S0065 5.2.32
-    private class EfCsimSpnLoaded implements IccRecordLoaded {
-        public String getEfName() {
-            return "EF_CSIM_SPN";
-        }
-
-        public void onRecordLoaded(AsyncResult ar) {
-            byte[] data = (byte[]) ar.result;
-            if (DBG) log("CSIM_SPN=" +
-                         IccUtils.bytesToHexString(data));
-
-            // C.S0065 for EF_SPN decoding
-            mCsimSpnDisplayCondition = ((0x01 & data[0]) != 0);
-
-            int encoding = data[1];
-            int language = data[2];
-            byte[] spnData = new byte[32];
-            System.arraycopy(data, 3, spnData, 0, (data.length < 32) ? data.length : 32);
-
-            int numBytes;
-            for (numBytes = 0; numBytes < spnData.length; numBytes++) {
-                if ((spnData[numBytes] & 0xFF) == 0xFF) break;
-            }
-
-            if (numBytes == 0) {
-                spn = "";
-                return;
-            }
-            try {
-                switch (encoding) {
-                case UserData.ENCODING_OCTET:
-                case UserData.ENCODING_LATIN:
-                    spn = new String(spnData, 0, numBytes, "ISO-8859-1");
-                    break;
-                case UserData.ENCODING_IA5:
-                case UserData.ENCODING_GSM_7BIT_ALPHABET:
-                case UserData.ENCODING_7BIT_ASCII:
-                    spn = GsmAlphabet.gsm7BitPackedToString(spnData, 0, (numBytes*8)/7);
-                    break;
-                case UserData.ENCODING_UNICODE_16:
-                    spn =  new String(spnData, 0, numBytes, "utf-16");
-                    break;
-                default:
-                    log("SPN encoding not supported");
-                }
-            } catch(Exception e) {
-                log("spn decode error: " + e);
-            }
-            if (DBG) log("spn=" + spn);
-            if (DBG) log("spnCondition=" + mCsimSpnDisplayCondition);
-            SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, spn);
-        }
-    }
-
-    private class EfCsimMdnLoaded implements IccRecordLoaded {
-        public String getEfName() {
-            return "EF_CSIM_MDN";
-        }
-
-        public void onRecordLoaded(AsyncResult ar) {
-            byte[] data = (byte[]) ar.result;
-            if (DBG) log("CSIM_MDN=" + IccUtils.bytesToHexString(data));
-            int mdnDigitsNum = 0x0F & data[0];
-            mMdn = IccUtils.cdmaBcdToString(data, 1, mdnDigitsNum);
-            if (DBG) log("CSIM MDN=" + mMdn);
-        }
-    }
-
-    private class EfCsimImsimLoaded implements IccRecordLoaded {
-        public String getEfName() {
-            return "EF_CSIM_IMSIM";
-        }
-
-        public void onRecordLoaded(AsyncResult ar) {
-            byte[] data = (byte[]) ar.result;
-            if (DBG) log("CSIM_IMSIM=" + IccUtils.bytesToHexString(data));
-            // C.S0065 section 5.2.2 for IMSI_M encoding
-            // C.S0005 section 2.3.1 for MIN encoding in IMSI_M.
-            boolean provisioned = ((data[7] & 0x80) == 0x80);
-
-            if (provisioned) {
-                int first3digits = ((0x03 & data[2]) << 8) + (0xFF & data[1]);
-                int second3digits = (((0xFF & data[5]) << 8) | (0xFF & data[4])) >> 6;
-                int digit7 = 0x0F & (data[4] >> 2);
-                if (digit7 > 0x09) digit7 = 0;
-                int last3digits = ((0x03 & data[4]) << 8) | (0xFF & data[3]);
-                first3digits = adjstMinDigits(first3digits);
-                second3digits = adjstMinDigits(second3digits);
-                last3digits = adjstMinDigits(last3digits);
-
-                StringBuilder builder = new StringBuilder();
-                builder.append(String.format(Locale.US, "%03d", first3digits));
-                builder.append(String.format(Locale.US, "%03d", second3digits));
-                builder.append(String.format(Locale.US, "%d", digit7));
-                builder.append(String.format(Locale.US, "%03d", last3digits));
-                mMin = builder.toString();
-                if (DBG) log("min present=" + mMin);
-            } else {
-                if (DBG) log("min not present");
-            }
-        }
-    }
-
-    private class EfCsimCdmaHomeLoaded implements IccRecordLoaded {
-        public String getEfName() {
-            return "EF_CSIM_CDMAHOME";
-        }
-
-        public void onRecordLoaded(AsyncResult ar) {
-            // Per C.S0065 section 5.2.8
-            ArrayList<byte[]> dataList = (ArrayList<byte[]>) ar.result;
-            if (DBG) log("CSIM_CDMAHOME data size=" + dataList.size());
-            if (dataList.isEmpty()) {
-                return;
-            }
-            StringBuilder sidBuf = new StringBuilder();
-            StringBuilder nidBuf = new StringBuilder();
-
-            for (byte[] data : dataList) {
-                if (data.length == 5) {
-                    int sid = ((data[1] & 0xFF) << 8) | (data[0] & 0xFF);
-                    int nid = ((data[3] & 0xFF) << 8) | (data[2] & 0xFF);
-                    sidBuf.append(sid).append(',');
-                    nidBuf.append(nid).append(',');
-                }
-            }
-            // remove trailing ","
-            sidBuf.setLength(sidBuf.length()-1);
-            nidBuf.setLength(nidBuf.length()-1);
-
-            mHomeSystemId = sidBuf.toString();
-            mHomeNetworkId = nidBuf.toString();
-        }
-    }
-
-    private class EfCsimEprlLoaded implements IccRecordLoaded {
-        public String getEfName() {
-            return "EF_CSIM_EPRL";
-        }
-        public void onRecordLoaded(AsyncResult ar) {
-            onGetCSimEprlDone(ar);
-        }
-    }
-
-    @Override
-    protected void onRecordLoaded() {
-        // One record loaded successfully or failed, In either case
-        // we need to update the recordsToLoad count
-        recordsToLoad -= 1;
-
-        if (recordsToLoad == 0 && recordsRequested == true) {
-            onAllRecordsLoaded();
-        } else if (recordsToLoad < 0) {
-            Log.e(LOG_TAG, "SIMRecords: recordsToLoad <0, programmer error suspected");
-            recordsToLoad = 0;
-        }
-    }
-
-    @Override
-    protected void onAllRecordsLoaded() {
-        setLocaleFromCsim();
-        super.onAllRecordsLoaded();     // broadcasts ICC state change to "LOADED"
-    }
-
-    @Override
-    protected void fetchSimRecords() {
-        recordsRequested = true;
-
-        mCi.getIMSIForApp(mParentCard.getAid(), obtainMessage(EVENT_GET_IMSI_DONE));
-        recordsToLoad++;
-
-        mFh.loadEFTransparent(EF_ICCID, obtainMessage(EVENT_GET_ICCID_DONE));
-        recordsToLoad++;
-
-        mFh.loadEFTransparent(EF_AD, obtainMessage(EVENT_GET_AD_DONE));
-        recordsToLoad++;
-
-        mFh.loadEFTransparent(EF_PL,
-                obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfPlLoaded()));
-        recordsToLoad++;
-
-        new AdnRecordLoader(mFh).loadFromEF(EF_MSISDN, EF_EXT1, 1,
-                obtainMessage(EVENT_GET_MSISDN_DONE));
-        recordsToLoad++;
-
-        mFh.loadEFTransparent(EF_SST, obtainMessage(EVENT_GET_SST_DONE));
-        recordsToLoad++;
-
-        mFh.loadEFTransparent(EF_CSIM_LI,
-                obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimLiLoaded()));
-        recordsToLoad++;
-
-        mFh.loadEFTransparent(EF_CSIM_SPN,
-                obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimSpnLoaded()));
-        recordsToLoad++;
-
-        mFh.loadEFLinearFixed(EF_CSIM_MDN, 1,
-                obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimMdnLoaded()));
-        recordsToLoad++;
-
-        mFh.loadEFTransparent(EF_CSIM_IMSIM,
-                obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimImsimLoaded()));
-        recordsToLoad++;
-
-        mFh.loadEFLinearFixedAll(EF_CSIM_CDMAHOME,
-                obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimCdmaHomeLoaded()));
-        recordsToLoad++;
-
-        mFh.loadEFTransparent(EF_CSIM_EPRL,
-                obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimEprlLoaded()));
-        recordsToLoad++;
-
-        // load ISIM records
-        recordsToLoad += mIsimUiccRecords.fetchIsimRecords(mFh, this);
-    }
-
-    private int adjstMinDigits (int digits) {
-        // Per C.S0005 section 2.3.1.
-        digits += 111;
-        digits = (digits % 10 == 0)?(digits - 10):digits;
-        digits = ((digits / 10) % 10 == 0)?(digits - 100):digits;
-        digits = ((digits / 100) % 10 == 0)?(digits - 1000):digits;
-        return digits;
-    }
-
-    private void onGetCSimEprlDone(AsyncResult ar) {
-        // C.S0065 section 5.2.57 for EFeprl encoding
-        // C.S0016 section 3.5.5 for PRL format.
-        byte[] data = (byte[]) ar.result;
-        if (DBG) log("CSIM_EPRL=" + IccUtils.bytesToHexString(data));
-
-        // Only need the first 4 bytes of record
-        if (data.length > 3) {
-            int prlId = ((data[2] & 0xFF) << 8) | (data[3] & 0xFF);
-            mPrlVersion = Integer.toString(prlId);
-        }
-        if (DBG) log("CSIM PRL version=" + mPrlVersion);
-    }
-
-    private void setLocaleFromCsim() {
-        String prefLang = null;
-        // check EFli then EFpl
-        prefLang = findBestLanguage(mEFli);
-
-        if (prefLang == null) {
-            prefLang = findBestLanguage(mEFpl);
-        }
-
-        if (prefLang != null) {
-            // check country code from SIM
-            String imsi = getIMSI();
-            String country = null;
-            if (imsi != null) {
-                country = MccTable.countryCodeForMcc(
-                                    Integer.parseInt(imsi.substring(0,3)));
-            }
-            log("Setting locale to " + prefLang + "_" + country);
-            MccTable.setSystemLocale(mContext, prefLang, country);
-        } else {
-            log ("No suitable CSIM selected locale");
-        }
-    }
-
-    private String findBestLanguage(byte[] languages) {
-        String bestMatch = null;
-        String[] locales = mContext.getAssets().getLocales();
-
-        if ((languages == null) || (locales == null)) return null;
-
-        // Each 2-bytes consists of one language
-        for (int i = 0; (i + 1) < languages.length; i += 2) {
-            try {
-                String lang = new String(languages, i, 2, "ISO-8859-1");
-                for (int j = 0; j < locales.length; j++) {
-                    if (locales[j] != null && locales[j].length() >= 2 &&
-                        locales[j].substring(0, 2).equals(lang)) {
-                        return lang;
-                    }
-                }
-                if (bestMatch != null) break;
-            } catch(java.io.UnsupportedEncodingException e) {
-                log ("Failed to parse SIM language records");
-            }
-        }
-        // no match found. return null
-        return null;
-    }
-
-    @Override
-    protected void log(String s) {
-        Log.d(LOG_TAG, "[CSIM] " + s);
-    }
-
-    @Override
-    protected void loge(String s) {
-        Log.e(LOG_TAG, "[CSIM] " + s);
-    }
-
-    public String getMdn() {
-        return mMdn;
-    }
-
-    public String getMin() {
-        return mMin;
-    }
-
-    public String getSid() {
-        return mHomeSystemId;
-    }
-
-    public String getNid() {
-        return mHomeNetworkId;
-    }
-
-    public String getPrlVersion() {
-        return mPrlVersion;
-    }
-
-    public boolean getCsimSpnDisplayCondition() {
-        return mCsimSpnDisplayCondition;
-    }
-
-    @Override
-    public IsimRecords getIsimRecords() {
-        return mIsimUiccRecords;
-    }
-
-    @Override
-    public boolean isProvisioned() {
-        // If UICC card has CSIM app, look for MDN and MIN field
-        // to determine if the SIM is provisioned.  Otherwise,
-        // consider the SIM is provisioned. (for case of ordinal
-        // USIM only UICC.)
-        // If PROPERTY_TEST_CSIM is defined, bypess provision check
-        // and consider the SIM is provisioned.
-        if (SystemProperties.getBoolean(PROPERTY_TEST_CSIM, false)) {
-            return true;
-        }
-
-        if (mParentCard == null) {
-            return false;
-        }
-
-        if (mParentCard.isApplicationOnIcc(AppType.APPTYPE_CSIM) &&
-            ((mMdn == null) || (mMin == null))) {
-            return false;
-        }
-        return true;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaMmiCode.java b/telephony/java/com/android/internal/telephony/cdma/CdmaMmiCode.java
deleted file mode 100644
index 8dd8c2e..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaMmiCode.java
+++ /dev/null
@@ -1,296 +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.internal.telephony.cdma;
-
-import android.content.Context;
-
-import com.android.internal.telephony.CommandException;
-import com.android.internal.telephony.MmiCode;
-
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
-
-/**
- * This class can handle Puk code Mmi
- *
- * {@hide}
- *
- */
-public final class CdmaMmiCode  extends Handler implements MmiCode {
-    static final String LOG_TAG = "CDMA_MMI";
-
-    // Constants
-
-    // From TS 22.030 6.5.2
-    static final String ACTION_REGISTER = "**";
-
-    // Supp Service codes from TS 22.030 Annex B
-    static final String SC_PUK          = "05";
-
-    // Event Constant
-
-    static final int EVENT_SET_COMPLETE = 1;
-
-    // Instance Variables
-
-    CDMAPhone phone;
-    Context context;
-
-    String action;              // ACTION_REGISTER
-    String sc;                  // Service Code
-    String sia, sib, sic;       // Service Info a,b,c
-    String poundString;         // Entire MMI string up to and including #
-    String dialingNumber;
-    String pwd;                 // For password registration
-
-    State state = State.PENDING;
-    CharSequence message;
-
-    // Class Variables
-
-    static Pattern sPatternSuppService = Pattern.compile(
-        "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)(.*)");
-/*       1  2                    3          4  5       6   7         8    9     10  11             12
-
-         1 = Full string up to and including #
-         2 = action
-         3 = service code
-         5 = SIA
-         7 = SIB
-         9 = SIC
-         10 = dialing number
-*/
-
-    static final int MATCH_GROUP_POUND_STRING = 1;
-    static final int MATCH_GROUP_ACTION = 2;
-    static final int MATCH_GROUP_SERVICE_CODE = 3;
-    static final int MATCH_GROUP_SIA = 5;
-    static final int MATCH_GROUP_SIB = 7;
-    static final int MATCH_GROUP_SIC = 9;
-    static final int MATCH_GROUP_PWD_CONFIRM = 11;
-    static final int MATCH_GROUP_DIALING_NUMBER = 12;
-
-
-    // Public Class methods
-
-    /**
-     * Check if provided string contains Mmi code in it and create corresponding
-     * Mmi if it does
-     */
-
-    public static CdmaMmiCode
-    newFromDialString(String dialString, CDMAPhone phone) {
-        Matcher m;
-        CdmaMmiCode ret = null;
-
-        m = sPatternSuppService.matcher(dialString);
-
-        // Is this formatted like a standard supplementary service code?
-        if (m.matches()) {
-            ret = new CdmaMmiCode(phone);
-            ret.poundString = makeEmptyNull(m.group(MATCH_GROUP_POUND_STRING));
-            ret.action = makeEmptyNull(m.group(MATCH_GROUP_ACTION));
-            ret.sc = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE));
-            ret.sia = makeEmptyNull(m.group(MATCH_GROUP_SIA));
-            ret.sib = makeEmptyNull(m.group(MATCH_GROUP_SIB));
-            ret.sic = makeEmptyNull(m.group(MATCH_GROUP_SIC));
-            ret.pwd = makeEmptyNull(m.group(MATCH_GROUP_PWD_CONFIRM));
-            ret.dialingNumber = makeEmptyNull(m.group(MATCH_GROUP_DIALING_NUMBER));
-
-        }
-
-        return ret;
-    }
-
-    // Private Class methods
-
-    /** make empty strings be null.
-     *  Regexp returns empty strings for empty groups
-     */
-    private static String
-    makeEmptyNull (String s) {
-        if (s != null && s.length() == 0) return null;
-
-        return s;
-    }
-
-    // Constructor
-
-    CdmaMmiCode (CDMAPhone phone) {
-        super(phone.getHandler().getLooper());
-        this.phone = phone;
-        this.context = phone.getContext();
-    }
-
-    // MmiCode implementation
-
-    public State
-    getState() {
-        return state;
-    }
-
-    public CharSequence
-    getMessage() {
-        return message;
-    }
-
-    // inherited javadoc suffices
-    public void
-    cancel() {
-        // Complete or failed cannot be cancelled
-        if (state == State.COMPLETE || state == State.FAILED) {
-            return;
-        }
-
-        state = State.CANCELLED;
-        phone.onMMIDone (this);
-    }
-
-    public boolean isCancelable() {
-        return false;
-    }
-
-    // Instance Methods
-
-    /**
-     * @return true if the Service Code is PIN/PIN2/PUK/PUK2-related
-     */
-    boolean isPukCommand() {
-        return sc != null && sc.equals(SC_PUK);
-     }
-
-    boolean isRegister() {
-        return action != null && action.equals(ACTION_REGISTER);
-    }
-
-    public boolean isUssdRequest() {
-        Log.w(LOG_TAG, "isUssdRequest is not implemented in CdmaMmiCode");
-        return false;
-    }
-
-    /** Process a MMI PUK code */
-    void
-    processCode () {
-        try {
-            if (isPukCommand()) {
-                // sia = old PUK
-                // sib = new PIN
-                // sic = new PIN
-                String oldPinOrPuk = sia;
-                String newPin = sib;
-                int pinLen = newPin.length();
-                if (isRegister()) {
-                    if (!newPin.equals(sic)) {
-                        // password mismatch; return error
-                        handlePasswordError(com.android.internal.R.string.mismatchPin);
-                    } else if (pinLen < 4 || pinLen > 8 ) {
-                        // invalid length
-                        handlePasswordError(com.android.internal.R.string.invalidPin);
-                    } else {
-                        phone.mCM.supplyIccPuk(oldPinOrPuk, newPin,
-                                obtainMessage(EVENT_SET_COMPLETE, this));
-                    }
-                } else {
-                    throw new RuntimeException ("Invalid or Unsupported MMI Code");
-                }
-            } else {
-                throw new RuntimeException ("Invalid or Unsupported MMI Code");
-            }
-        } catch (RuntimeException exc) {
-            state = State.FAILED;
-            message = context.getText(com.android.internal.R.string.mmiError);
-            phone.onMMIDone(this);
-        }
-    }
-
-    private void handlePasswordError(int res) {
-        state = State.FAILED;
-        StringBuilder sb = new StringBuilder(getScString());
-        sb.append("\n");
-        sb.append(context.getText(res));
-        message = sb;
-        phone.onMMIDone(this);
-    }
-
-    public void
-    handleMessage (Message msg) {
-        AsyncResult ar;
-
-        if (msg.what == EVENT_SET_COMPLETE) {
-            ar = (AsyncResult) (msg.obj);
-            onSetComplete(ar);
-        } else {
-            Log.e(LOG_TAG, "Unexpected reply");
-        }
-    }
-    // Private instance methods
-
-    private CharSequence getScString() {
-        if (sc != null) {
-            if (isPukCommand()) {
-                return context.getText(com.android.internal.R.string.PinMmi);
-            }
-        }
-
-        return "";
-    }
-
-    private void
-    onSetComplete(AsyncResult ar){
-        StringBuilder sb = new StringBuilder(getScString());
-        sb.append("\n");
-
-        if (ar.exception != null) {
-            state = State.FAILED;
-            if (ar.exception instanceof CommandException) {
-                CommandException.Error err = ((CommandException)(ar.exception)).getCommandError();
-                if (err == CommandException.Error.PASSWORD_INCORRECT) {
-                    if (isPukCommand()) {
-                        sb.append(context.getText(
-                                com.android.internal.R.string.badPuk));
-                    } else {
-                        sb.append(context.getText(
-                                com.android.internal.R.string.passwordIncorrect));
-                    }
-                } else {
-                    sb.append(context.getText(
-                            com.android.internal.R.string.mmiError));
-                }
-            } else {
-                sb.append(context.getText(
-                        com.android.internal.R.string.mmiError));
-            }
-        } else if (isRegister()) {
-            state = State.COMPLETE;
-            sb.append(context.getText(
-                    com.android.internal.R.string.serviceRegistered));
-        } else {
-            state = State.FAILED;
-            sb.append(context.getText(
-                    com.android.internal.R.string.mmiError));
-        }
-
-        message = sb;
-        phone.onMMIDone(this);
-    }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
deleted file mode 100755
index a6b32f9..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ /dev/null
@@ -1,501 +0,0 @@
-/*
- * 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.internal.telephony.cdma;
-
-
-import android.app.Activity;
-import android.app.PendingIntent;
-import android.app.PendingIntent.CanceledException;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.res.Resources;
-import android.os.Bundle;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.preference.PreferenceManager;
-import android.provider.Telephony;
-import android.provider.Telephony.Sms.Intents;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.SmsCbMessage;
-import android.telephony.SmsManager;
-import android.telephony.SmsMessage.MessageClass;
-import android.telephony.cdma.CdmaSmsCbProgramData;
-import android.telephony.cdma.CdmaSmsCbProgramResults;
-import android.util.Log;
-
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.SMSDispatcher;
-import com.android.internal.telephony.SmsHeader;
-import com.android.internal.telephony.SmsMessageBase;
-import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails;
-import com.android.internal.telephony.SmsStorageMonitor;
-import com.android.internal.telephony.SmsUsageMonitor;
-import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.telephony.WspTypeDecoder;
-import com.android.internal.telephony.cdma.sms.BearerData;
-import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
-import com.android.internal.telephony.cdma.sms.SmsEnvelope;
-import com.android.internal.telephony.cdma.sms.UserData;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-
-
-final class CdmaSMSDispatcher extends SMSDispatcher {
-    private static final String TAG = "CDMA";
-
-    private byte[] mLastDispatchedSmsFingerprint;
-    private byte[] mLastAcknowledgedSmsFingerprint;
-
-    private final boolean mCheckForDuplicatePortsInOmadmWapPush = Resources.getSystem().getBoolean(
-            com.android.internal.R.bool.config_duplicate_port_omadm_wappush);
-
-    CdmaSMSDispatcher(CDMAPhone phone, SmsStorageMonitor storageMonitor,
-            SmsUsageMonitor usageMonitor) {
-        super(phone, storageMonitor, usageMonitor);
-        mCm.setOnNewCdmaSms(this, EVENT_NEW_SMS, null);
-    }
-
-    @Override
-    public void dispose() {
-        mCm.unSetOnNewCdmaSms(this);
-    }
-
-    @Override
-    protected String getFormat() {
-        return android.telephony.SmsMessage.FORMAT_3GPP2;
-    }
-
-    private void handleCdmaStatusReport(SmsMessage sms) {
-        for (int i = 0, count = deliveryPendingList.size(); i < count; i++) {
-            SmsTracker tracker = deliveryPendingList.get(i);
-            if (tracker.mMessageRef == sms.messageRef) {
-                // Found it.  Remove from list and broadcast.
-                deliveryPendingList.remove(i);
-                PendingIntent intent = tracker.mDeliveryIntent;
-                Intent fillIn = new Intent();
-                fillIn.putExtra("pdu", sms.getPdu());
-                fillIn.putExtra("format", android.telephony.SmsMessage.FORMAT_3GPP2);
-                try {
-                    intent.send(mContext, Activity.RESULT_OK, fillIn);
-                } catch (CanceledException ex) {}
-                break;  // Only expect to see one tracker matching this message.
-            }
-        }
-    }
-
-    /**
-     * Dispatch service category program data to the CellBroadcastReceiver app, which filters
-     * the broadcast alerts to display.
-     * @param sms the SMS message containing one or more
-     * {@link android.telephony.cdma.CdmaSmsCbProgramData} objects.
-     */
-    private void handleServiceCategoryProgramData(SmsMessage sms) {
-        ArrayList<CdmaSmsCbProgramData> programDataList = sms.getSmsCbProgramData();
-        if (programDataList == null) {
-            Log.e(TAG, "handleServiceCategoryProgramData: program data list is null!");
-            return;
-        }
-
-        Intent intent = new Intent(Intents.SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED_ACTION);
-        intent.putExtra("sender", sms.getOriginatingAddress());
-        intent.putParcelableArrayListExtra("program_data", programDataList);
-        dispatch(intent, RECEIVE_SMS_PERMISSION, mScpResultsReceiver);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int dispatchMessage(SmsMessageBase smsb) {
-
-        // If sms is null, means there was a parsing error.
-        if (smsb == null) {
-            Log.e(TAG, "dispatchMessage: message is null");
-            return Intents.RESULT_SMS_GENERIC_ERROR;
-        }
-
-        String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
-        if (inEcm.equals("true")) {
-            return Activity.RESULT_OK;
-        }
-
-        if (mSmsReceiveDisabled) {
-            // Device doesn't support receiving SMS,
-            Log.d(TAG, "Received short message on device which doesn't support "
-                    + "receiving SMS. Ignored.");
-            return Intents.RESULT_SMS_HANDLED;
-        }
-
-        SmsMessage sms = (SmsMessage) smsb;
-
-        // Handle CMAS emergency broadcast messages.
-        if (SmsEnvelope.MESSAGE_TYPE_BROADCAST == sms.getMessageType()) {
-            Log.d(TAG, "Broadcast type message");
-            SmsCbMessage message = sms.parseBroadcastSms();
-            if (message != null) {
-                dispatchBroadcastMessage(message);
-            }
-            return Intents.RESULT_SMS_HANDLED;
-        }
-
-        // See if we have a network duplicate SMS.
-        mLastDispatchedSmsFingerprint = sms.getIncomingSmsFingerprint();
-        if (mLastAcknowledgedSmsFingerprint != null &&
-                Arrays.equals(mLastDispatchedSmsFingerprint, mLastAcknowledgedSmsFingerprint)) {
-            return Intents.RESULT_SMS_HANDLED;
-        }
-        // Decode BD stream and set sms variables.
-        sms.parseSms();
-        int teleService = sms.getTeleService();
-        boolean handled = false;
-
-        if ((SmsEnvelope.TELESERVICE_VMN == teleService) ||
-                (SmsEnvelope.TELESERVICE_MWI == teleService)) {
-            // handling Voicemail
-            int voicemailCount = sms.getNumOfVoicemails();
-            Log.d(TAG, "Voicemail count=" + voicemailCount);
-            // Store the voicemail count in preferences.
-            SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(
-                    mContext);
-            SharedPreferences.Editor editor = sp.edit();
-            editor.putInt(CDMAPhone.VM_COUNT_CDMA, voicemailCount);
-            editor.apply();
-            mPhone.setVoiceMessageWaiting(1, voicemailCount);
-            handled = true;
-        } else if (((SmsEnvelope.TELESERVICE_WMT == teleService) ||
-                (SmsEnvelope.TELESERVICE_WEMT == teleService)) &&
-                sms.isStatusReportMessage()) {
-            handleCdmaStatusReport(sms);
-            handled = true;
-        } else if (SmsEnvelope.TELESERVICE_SCPT == teleService) {
-            handleServiceCategoryProgramData(sms);
-            handled = true;
-        } else if ((sms.getUserData() == null)) {
-            if (false) {
-                Log.d(TAG, "Received SMS without user data");
-            }
-            handled = true;
-        }
-
-        if (handled) {
-            return Intents.RESULT_SMS_HANDLED;
-        }
-
-        if (!mStorageMonitor.isStorageAvailable() &&
-                sms.getMessageClass() != MessageClass.CLASS_0) {
-            // It's a storable message and there's no storage available.  Bail.
-            // (See C.S0015-B v2.0 for a description of "Immediate Display"
-            // messages, which we represent as CLASS_0.)
-            return Intents.RESULT_SMS_OUT_OF_MEMORY;
-        }
-
-        if (SmsEnvelope.TELESERVICE_WAP == teleService) {
-            return processCdmaWapPdu(sms.getUserData(), sms.messageRef,
-                    sms.getOriginatingAddress());
-        }
-
-        // Reject (NAK) any messages with teleservice ids that have
-        // not yet been handled and also do not correspond to the two
-        // kinds that are processed below.
-        if ((SmsEnvelope.TELESERVICE_WMT != teleService) &&
-                (SmsEnvelope.TELESERVICE_WEMT != teleService) &&
-                (SmsEnvelope.MESSAGE_TYPE_BROADCAST != sms.getMessageType())) {
-            return Intents.RESULT_SMS_UNSUPPORTED;
-        }
-
-        return dispatchNormalMessage(smsb);
-    }
-
-    /**
-     * Processes inbound messages that are in the WAP-WDP PDU format. See
-     * wap-259-wdp-20010614-a section 6.5 for details on the WAP-WDP PDU format.
-     * WDP segments are gathered until a datagram completes and gets dispatched.
-     *
-     * @param pdu The WAP-WDP PDU segment
-     * @return a result code from {@link Telephony.Sms.Intents}, or
-     *         {@link Activity#RESULT_OK} if the message has been broadcast
-     *         to applications
-     */
-    protected int processCdmaWapPdu(byte[] pdu, int referenceNumber, String address) {
-        int index = 0;
-
-        int msgType = (0xFF & pdu[index++]);
-        if (msgType != 0) {
-            Log.w(TAG, "Received a WAP SMS which is not WDP. Discard.");
-            return Intents.RESULT_SMS_HANDLED;
-        }
-        int totalSegments = (0xFF & pdu[index++]);   // >= 1
-        int segment = (0xFF & pdu[index++]);         // >= 0
-
-        if (segment >= totalSegments) {
-            Log.e(TAG, "WDP bad segment #" + segment + " expecting 0-" + (totalSegments - 1));
-            return Intents.RESULT_SMS_HANDLED;
-        }
-
-        // Only the first segment contains sourcePort and destination Port
-        int sourcePort = 0;
-        int destinationPort = 0;
-        if (segment == 0) {
-            //process WDP segment
-            sourcePort = (0xFF & pdu[index++]) << 8;
-            sourcePort |= 0xFF & pdu[index++];
-            destinationPort = (0xFF & pdu[index++]) << 8;
-            destinationPort |= 0xFF & pdu[index++];
-            // Some carriers incorrectly send duplicate port fields in omadm wap pushes.
-            // If configured, check for that here
-            if (mCheckForDuplicatePortsInOmadmWapPush) {
-                if (checkDuplicatePortOmadmWappush(pdu,index)) {
-                    index = index + 4; // skip duplicate port fields
-                }
-            }
-        }
-
-        // Lookup all other related parts
-        Log.i(TAG, "Received WAP PDU. Type = " + msgType + ", originator = " + address
-                + ", src-port = " + sourcePort + ", dst-port = " + destinationPort
-                + ", ID = " + referenceNumber + ", segment# = " + segment + '/' + totalSegments);
-
-        // pass the user data portion of the PDU to the shared handler in SMSDispatcher
-        byte[] userData = new byte[pdu.length - index];
-        System.arraycopy(pdu, index, userData, 0, pdu.length - index);
-
-        return processMessagePart(userData, address, referenceNumber, segment, totalSegments,
-                0L, destinationPort, true);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void sendData(String destAddr, String scAddr, int destPort,
-            byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
-        SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
-                scAddr, destAddr, destPort, data, (deliveryIntent != null));
-        sendSubmitPdu(pdu, sentIntent, deliveryIntent, destAddr);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void sendText(String destAddr, String scAddr, String text,
-            PendingIntent sentIntent, PendingIntent deliveryIntent) {
-        SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
-                scAddr, destAddr, text, (deliveryIntent != null), null);
-        sendSubmitPdu(pdu, sentIntent, deliveryIntent, destAddr);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected TextEncodingDetails calculateLength(CharSequence messageBody,
-            boolean use7bitOnly) {
-        return SmsMessage.calculateLength(messageBody, use7bitOnly);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void sendNewSubmitPdu(String destinationAddress, String scAddress,
-            String message, SmsHeader smsHeader, int encoding,
-            PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart) {
-        UserData uData = new UserData();
-        uData.payloadStr = message;
-        uData.userDataHeader = smsHeader;
-        if (encoding == android.telephony.SmsMessage.ENCODING_7BIT) {
-            uData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET;
-        } else { // assume UTF-16
-            uData.msgEncoding = UserData.ENCODING_UNICODE_16;
-        }
-        uData.msgEncodingSet = true;
-
-        /* By setting the statusReportRequested bit only for the
-         * last message fragment, this will result in only one
-         * callback to the sender when that last fragment delivery
-         * has been acknowledged. */
-        SmsMessage.SubmitPdu submitPdu = SmsMessage.getSubmitPdu(destinationAddress,
-                uData, (deliveryIntent != null) && lastPart);
-
-        sendSubmitPdu(submitPdu, sentIntent, deliveryIntent, destinationAddress);
-    }
-
-    protected void sendSubmitPdu(SmsMessage.SubmitPdu pdu,
-            PendingIntent sentIntent, PendingIntent deliveryIntent, String destAddr) {
-        if (SystemProperties.getBoolean(TelephonyProperties.PROPERTY_INECM_MODE, false)) {
-            if (sentIntent != null) {
-                try {
-                    sentIntent.send(SmsManager.RESULT_ERROR_NO_SERVICE);
-                } catch (CanceledException ex) {}
-            }
-            if (false) {
-                Log.d(TAG, "Block SMS in Emergency Callback mode");
-            }
-            return;
-        }
-        sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent, destAddr);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void sendSms(SmsTracker tracker) {
-        HashMap<String, Object> map = tracker.mData;
-
-        // byte smsc[] = (byte[]) map.get("smsc");  // unused for CDMA
-        byte pdu[] = (byte[]) map.get("pdu");
-
-        Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker);
-        mCm.sendCdmaSms(pdu, reply);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void acknowledgeLastIncomingSms(boolean success, int result, Message response) {
-        String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
-        if (inEcm.equals("true")) {
-            return;
-        }
-
-        int causeCode = resultToCause(result);
-        mCm.acknowledgeLastIncomingCdmaSms(success, causeCode, response);
-
-        if (causeCode == 0) {
-            mLastAcknowledgedSmsFingerprint = mLastDispatchedSmsFingerprint;
-        }
-        mLastDispatchedSmsFingerprint = null;
-    }
-
-    private static int resultToCause(int rc) {
-        switch (rc) {
-        case Activity.RESULT_OK:
-        case Intents.RESULT_SMS_HANDLED:
-            // Cause code is ignored on success.
-            return 0;
-        case Intents.RESULT_SMS_OUT_OF_MEMORY:
-            return CommandsInterface.CDMA_SMS_FAIL_CAUSE_RESOURCE_SHORTAGE;
-        case Intents.RESULT_SMS_UNSUPPORTED:
-            return CommandsInterface.CDMA_SMS_FAIL_CAUSE_INVALID_TELESERVICE_ID;
-        case Intents.RESULT_SMS_GENERIC_ERROR:
-        default:
-            return CommandsInterface.CDMA_SMS_FAIL_CAUSE_ENCODING_PROBLEM;
-        }
-    }
-
-    /**
-     * Optional check to see if the received WapPush is an OMADM notification with erroneous
-     * extra port fields.
-     * - Some carriers make this mistake.
-     * ex: MSGTYPE-TotalSegments-CurrentSegment
-     *       -SourcePortDestPort-SourcePortDestPort-OMADM PDU
-     * @param origPdu The WAP-WDP PDU segment
-     * @param index Current Index while parsing the PDU.
-     * @return True if OrigPdu is OmaDM Push Message which has duplicate ports.
-     *         False if OrigPdu is NOT OmaDM Push Message which has duplicate ports.
-     */
-    private static boolean checkDuplicatePortOmadmWappush(byte[] origPdu, int index) {
-        index += 4;
-        byte[] omaPdu = new byte[origPdu.length - index];
-        System.arraycopy(origPdu, index, omaPdu, 0, omaPdu.length);
-
-        WspTypeDecoder pduDecoder = new WspTypeDecoder(omaPdu);
-        int wspIndex = 2;
-
-        // Process header length field
-        if (pduDecoder.decodeUintvarInteger(wspIndex) == false) {
-            return false;
-        }
-
-        wspIndex += pduDecoder.getDecodedDataLength(); // advance to next field
-
-        // Process content type field
-        if (pduDecoder.decodeContentType(wspIndex) == false) {
-            return false;
-        }
-
-        String mimeType = pduDecoder.getValueString();
-        if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_SYNCML_NOTI)) {
-            return true;
-        }
-        return false;
-    }
-
-    // Receiver for Service Category Program Data results.
-    // We already ACK'd the original SCPD SMS, so this sends a new response SMS.
-    // TODO: handle retries if the RIL returns an error.
-    private final BroadcastReceiver mScpResultsReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            int rc = getResultCode();
-            boolean success = (rc == Activity.RESULT_OK) || (rc == Intents.RESULT_SMS_HANDLED);
-            if (!success) {
-                Log.e(TAG, "SCP results error: result code = " + rc);
-                return;
-            }
-            Bundle extras = getResultExtras(false);
-            if (extras == null) {
-                Log.e(TAG, "SCP results error: missing extras");
-                return;
-            }
-            String sender = extras.getString("sender");
-            if (sender == null) {
-                Log.e(TAG, "SCP results error: missing sender extra.");
-                return;
-            }
-            ArrayList<CdmaSmsCbProgramResults> results
-                    = extras.getParcelableArrayList("results");
-            if (results == null) {
-                Log.e(TAG, "SCP results error: missing results extra.");
-                return;
-            }
-
-            BearerData bData = new BearerData();
-            bData.messageType = BearerData.MESSAGE_TYPE_SUBMIT;
-            bData.messageId = SmsMessage.getNextMessageId();
-            bData.serviceCategoryProgramResults = results;
-            byte[] encodedBearerData = BearerData.encode(bData);
-
-            ByteArrayOutputStream baos = new ByteArrayOutputStream(100);
-            DataOutputStream dos = new DataOutputStream(baos);
-            try {
-                dos.writeInt(SmsEnvelope.TELESERVICE_SCPT);
-                dos.writeInt(0); //servicePresent
-                dos.writeInt(0); //serviceCategory
-                CdmaSmsAddress destAddr = CdmaSmsAddress.parse(
-                        PhoneNumberUtils.cdmaCheckAndProcessPlusCode(sender));
-                dos.write(destAddr.digitMode);
-                dos.write(destAddr.numberMode);
-                dos.write(destAddr.ton); // number_type
-                dos.write(destAddr.numberPlan);
-                dos.write(destAddr.numberOfDigits);
-                dos.write(destAddr.origBytes, 0, destAddr.origBytes.length); // digits
-                // Subaddress is not supported.
-                dos.write(0); //subaddressType
-                dos.write(0); //subaddr_odd
-                dos.write(0); //subaddr_nbr_of_digits
-                dos.write(encodedBearerData.length);
-                dos.write(encodedBearerData, 0, encodedBearerData.length);
-                // Ignore the RIL response. TODO: implement retry if SMS send fails.
-                mCm.sendCdmaSms(baos.toByteArray(), null);
-            } catch (IOException e) {
-                Log.e(TAG, "exception creating SCP results PDU", e);
-            } finally {
-                try {
-                    dos.close();
-                } catch (IOException ignored) {
-                }
-            }
-        }
-    };
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
deleted file mode 100755
index 564ce3b..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ /dev/null
@@ -1,1752 +0,0 @@
-/*
- * 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.internal.telephony.cdma;
-
-import com.android.internal.telephony.CommandException;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.DataConnectionTracker;
-import com.android.internal.telephony.EventLogTags;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.MccTable;
-import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.ServiceStateTracker;
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.telephony.CommandsInterface.RadioState;
-
-import android.app.AlarmManager;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.database.ContentObserver;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.provider.Settings;
-import android.provider.Settings.Secure;
-import android.provider.Settings.SettingNotFoundException;
-import android.provider.Telephony.Intents;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.telephony.cdma.CdmaCellLocation;
-import android.text.TextUtils;
-import android.util.EventLog;
-import android.util.Log;
-import android.util.TimeUtils;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.TimeZone;
-
-/**
- * {@hide}
- */
-public class CdmaServiceStateTracker extends ServiceStateTracker {
-    static final String LOG_TAG = "CDMA";
-
-    CDMAPhone phone;
-    CdmaCellLocation cellLoc;
-    CdmaCellLocation newCellLoc;
-
-    // Min values used to by getOtasp()
-    private static final String UNACTIVATED_MIN2_VALUE = "000000";
-    private static final String UNACTIVATED_MIN_VALUE = "1111110111";
-
-    // Current Otasp value
-    int mCurrentOtaspMode = OTASP_UNINITIALIZED;
-
-     /** if time between NITZ updates is less than mNitzUpdateSpacing the update may be ignored. */
-    private static final int NITZ_UPDATE_SPACING_DEFAULT = 1000 * 60 * 10;
-    private int mNitzUpdateSpacing = SystemProperties.getInt("ro.nitz_update_spacing",
-            NITZ_UPDATE_SPACING_DEFAULT);
-
-    /** If mNitzUpdateSpacing hasn't been exceeded but update is > mNitzUpdate do the update */
-    private static final int NITZ_UPDATE_DIFF_DEFAULT = 2000;
-    private int mNitzUpdateDiff = SystemProperties.getInt("ro.nitz_update_diff",
-            NITZ_UPDATE_DIFF_DEFAULT);
-
-    private boolean mCdmaRoaming = false;
-    private int mRoamingIndicator;
-    private boolean mIsInPrl;
-    private int mDefaultRoamingIndicator;
-
-    /**
-     * Initially assume no data connection.
-     */
-    protected int mDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
-    protected int mNewDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
-    protected int mRegistrationState = -1;
-    protected RegistrantList cdmaForSubscriptionInfoReadyRegistrants = new RegistrantList();
-
-    /**
-     * Sometimes we get the NITZ time before we know what country we
-     * are in. Keep the time zone information from the NITZ string so
-     * we can fix the time zone once know the country.
-     */
-    protected boolean mNeedFixZone = false;
-    private int mZoneOffset;
-    private boolean mZoneDst;
-    private long mZoneTime;
-    protected boolean mGotCountryCode = false;
-    String mSavedTimeZone;
-    long mSavedTime;
-    long mSavedAtTime;
-
-    /**
-     * We can't register for SIM_RECORDS_LOADED immediately because the
-     * SIMRecords object may not be instantiated yet.
-     */
-    private boolean mNeedToRegForRuimLoaded = false;
-
-    /** Wake lock used while setting time of day. */
-    private PowerManager.WakeLock mWakeLock;
-    private static final String WAKELOCK_TAG = "ServiceStateTracker";
-
-    /** Contains the name of the registered network in CDMA (either ONS or ERI text). */
-    protected String mCurPlmn = null;
-
-    protected String mMdn;
-    protected int mHomeSystemId[] = null;
-    protected int mHomeNetworkId[] = null;
-    protected String mMin;
-    protected String mPrlVersion;
-    protected boolean mIsMinInfoReady = false;
-
-    private boolean isEriTextLoaded = false;
-    protected boolean isSubscriptionFromRuim = false;
-    private CdmaSubscriptionSourceManager mCdmaSSM;
-
-    /* Used only for debugging purposes. */
-    private String mRegistrationDeniedReason;
-
-    private ContentResolver cr;
-    private String currentCarrier = null;
-
-    private ContentObserver mAutoTimeObserver = new ContentObserver(new Handler()) {
-        @Override
-        public void onChange(boolean selfChange) {
-            if (DBG) log("Auto time state changed");
-            revertToNitzTime();
-        }
-    };
-
-    private ContentObserver mAutoTimeZoneObserver = new ContentObserver(new Handler()) {
-        @Override
-        public void onChange(boolean selfChange) {
-            if (DBG) log("Auto time zone state changed");
-            revertToNitzTimeZone();
-        }
-    };
-
-    public CdmaServiceStateTracker(CDMAPhone phone) {
-        super();
-
-        this.phone = phone;
-        cr = phone.getContext().getContentResolver();
-        cm = phone.mCM;
-        ss = new ServiceState();
-        newSS = new ServiceState();
-        cellLoc = new CdmaCellLocation();
-        newCellLoc = new CdmaCellLocation();
-        mSignalStrength = new SignalStrength();
-
-        mCdmaSSM = CdmaSubscriptionSourceManager.getInstance(phone.getContext(), cm, this,
-                EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
-        isSubscriptionFromRuim = (mCdmaSSM.getCdmaSubscriptionSource() ==
-                          CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM);
-
-        PowerManager powerManager =
-                (PowerManager)phone.getContext().getSystemService(Context.POWER_SERVICE);
-        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG);
-
-        cm.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
-
-        cm.registerForVoiceNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED_CDMA, null);
-        cm.setOnNITZTime(this, EVENT_NITZ_TIME, null);
-        cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
-
-        cm.registerForCdmaPrlChanged(this, EVENT_CDMA_PRL_VERSION_CHANGED, null);
-        phone.registerForEriFileLoaded(this, EVENT_ERI_FILE_LOADED, null);
-        cm.registerForCdmaOtaProvision(this,EVENT_OTA_PROVISION_STATUS_CHANGE, null);
-
-        // System setting property AIRPLANE_MODE_ON is set in Settings.
-        int airplaneMode = Settings.System.getInt(cr, Settings.System.AIRPLANE_MODE_ON, 0);
-        mDesiredPowerState = ! (airplaneMode > 0);
-
-        cr.registerContentObserver(
-                Settings.System.getUriFor(Settings.System.AUTO_TIME), true,
-                mAutoTimeObserver);
-        cr.registerContentObserver(
-            Settings.System.getUriFor(Settings.System.AUTO_TIME_ZONE), true,
-            mAutoTimeZoneObserver);
-        setSignalStrengthDefaultValues();
-
-        mNeedToRegForRuimLoaded = true;
-    }
-
-    public void dispose() {
-        // Unregister for all events.
-        cm.unregisterForRadioStateChanged(this);
-        cm.unregisterForVoiceNetworkStateChanged(this);
-        phone.getIccCard().unregisterForReady(this);
-        cm.unregisterForCdmaOtaProvision(this);
-        phone.unregisterForEriFileLoaded(this);
-        phone.mIccRecords.unregisterForRecordsLoaded(this);
-        cm.unSetOnSignalStrengthUpdate(this);
-        cm.unSetOnNITZTime(this);
-        cr.unregisterContentObserver(mAutoTimeObserver);
-        cr.unregisterContentObserver(mAutoTimeZoneObserver);
-        mCdmaSSM.dispose(this);
-        cm.unregisterForCdmaPrlChanged(this);
-    }
-
-    @Override
-    protected void finalize() {
-        if (DBG) log("CdmaServiceStateTracker finalized");
-    }
-
-    /**
-     * Registration point for subscription info ready
-     * @param h handler to notify
-     * @param what what code of message when delivered
-     * @param obj placed in Message.obj
-     */
-    public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
-        Registrant r = new Registrant(h, what, obj);
-        cdmaForSubscriptionInfoReadyRegistrants.add(r);
-
-        if (isMinInfoReady()) {
-            r.notifyRegistrant();
-        }
-    }
-
-    public void unregisterForSubscriptionInfoReady(Handler h) {
-        cdmaForSubscriptionInfoReadyRegistrants.remove(h);
-    }
-
-    /**
-     * Save current source of cdma subscription
-     * @param source - 1 for NV, 0 for RUIM
-     */
-    private void saveCdmaSubscriptionSource(int source) {
-        log("Storing cdma subscription source: " + source);
-        Secure.putInt(phone.getContext().getContentResolver(),
-                Secure.CDMA_SUBSCRIPTION_MODE,
-                source );
-    }
-
-    private void getSubscriptionInfoAndStartPollingThreads() {
-        cm.getCDMASubscription(obtainMessage(EVENT_POLL_STATE_CDMA_SUBSCRIPTION));
-
-        // Get Registration Information
-        pollState();
-    }
-
-    @Override
-    public void handleMessage (Message msg) {
-        AsyncResult ar;
-        int[] ints;
-        String[] strings;
-
-        if (!phone.mIsTheCurrentActivePhone) {
-            loge("Received message " + msg + "[" + msg.what + "]" +
-                    " while being destroyed. Ignoring.");
-            return;
-        }
-
-        switch (msg.what) {
-        case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
-            handleCdmaSubscriptionSource(mCdmaSSM.getCdmaSubscriptionSource());
-            break;
-
-        case EVENT_RUIM_READY:
-            // TODO: Consider calling setCurrentPreferredNetworkType as we do in GsmSST.
-            // cm.setCurrentPreferredNetworkType();
-
-            // The RUIM is now ready i.e if it was locked it has been
-            // unlocked. At this stage, the radio is already powered on.
-            if (mNeedToRegForRuimLoaded) {
-                phone.mIccRecords.registerForRecordsLoaded(this,
-                        EVENT_RUIM_RECORDS_LOADED, null);
-                mNeedToRegForRuimLoaded = false;
-            }
-
-            if (phone.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE) {
-                // Subscription will be read from SIM I/O
-                if (DBG) log("Receive EVENT_RUIM_READY");
-                pollState();
-            } else {
-                if (DBG) log("Receive EVENT_RUIM_READY and Send Request getCDMASubscription.");
-                getSubscriptionInfoAndStartPollingThreads();
-            }
-            phone.prepareEri();
-            break;
-
-        case EVENT_NV_READY:
-            // For Non-RUIM phones, the subscription information is stored in
-            // Non Volatile. Here when Non-Volatile is ready, we can poll the CDMA
-            // subscription info.
-            getSubscriptionInfoAndStartPollingThreads();
-            break;
-
-        case EVENT_RADIO_STATE_CHANGED:
-            if(cm.getRadioState() == RadioState.RADIO_ON) {
-                handleCdmaSubscriptionSource(mCdmaSSM.getCdmaSubscriptionSource());
-
-                // Signal strength polling stops when radio is off.
-                queueNextSignalStrengthPoll();
-            }
-            // This will do nothing in the 'radio not available' case.
-            setPowerStateToDesired();
-            pollState();
-            break;
-
-        case EVENT_NETWORK_STATE_CHANGED_CDMA:
-            pollState();
-            break;
-
-        case EVENT_GET_SIGNAL_STRENGTH:
-            // This callback is called when signal strength is polled
-            // all by itself.
-
-            if (!(cm.getRadioState().isOn())) {
-                // Polling will continue when radio turns back on.
-                return;
-            }
-            ar = (AsyncResult) msg.obj;
-            onSignalStrengthResult(ar);
-            queueNextSignalStrengthPoll();
-
-            break;
-
-        case EVENT_GET_LOC_DONE_CDMA:
-            ar = (AsyncResult) msg.obj;
-
-            if (ar.exception == null) {
-                String states[] = (String[])ar.result;
-                int baseStationId = -1;
-                int baseStationLatitude = CdmaCellLocation.INVALID_LAT_LONG;
-                int baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG;
-                int systemId = -1;
-                int networkId = -1;
-
-                if (states.length > 9) {
-                    try {
-                        if (states[4] != null) {
-                            baseStationId = Integer.parseInt(states[4]);
-                        }
-                        if (states[5] != null) {
-                            baseStationLatitude = Integer.parseInt(states[5]);
-                        }
-                        if (states[6] != null) {
-                            baseStationLongitude = Integer.parseInt(states[6]);
-                        }
-                        // Some carriers only return lat-lngs of 0,0
-                        if (baseStationLatitude == 0 && baseStationLongitude == 0) {
-                            baseStationLatitude  = CdmaCellLocation.INVALID_LAT_LONG;
-                            baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG;
-                        }
-                        if (states[8] != null) {
-                            systemId = Integer.parseInt(states[8]);
-                        }
-                        if (states[9] != null) {
-                            networkId = Integer.parseInt(states[9]);
-                        }
-                    } catch (NumberFormatException ex) {
-                        loge("error parsing cell location data: " + ex);
-                    }
-                }
-
-                cellLoc.setCellLocationData(baseStationId, baseStationLatitude,
-                        baseStationLongitude, systemId, networkId);
-                phone.notifyLocationChanged();
-            }
-
-            // Release any temporary cell lock, which could have been
-            // acquired to allow a single-shot location update.
-            disableSingleLocationUpdate();
-            break;
-
-        case EVENT_POLL_STATE_REGISTRATION_CDMA:
-        case EVENT_POLL_STATE_OPERATOR_CDMA:
-            ar = (AsyncResult) msg.obj;
-            handlePollStateResult(msg.what, ar);
-            break;
-
-        case EVENT_POLL_STATE_CDMA_SUBSCRIPTION: // Handle RIL_CDMA_SUBSCRIPTION
-            ar = (AsyncResult) msg.obj;
-
-            if (ar.exception == null) {
-                String cdmaSubscription[] = (String[])ar.result;
-                if (cdmaSubscription != null && cdmaSubscription.length >= 5) {
-                    mMdn = cdmaSubscription[0];
-                    parseSidNid(cdmaSubscription[1], cdmaSubscription[2]);
-
-                    mMin = cdmaSubscription[3];
-                    mPrlVersion = cdmaSubscription[4];
-                    if (DBG) log("GET_CDMA_SUBSCRIPTION: MDN=" + mMdn);
-
-                    mIsMinInfoReady = true;
-
-                    updateOtaspState();
-                    phone.getIccCard().broadcastIccStateChangedIntent(IccCard.INTENT_VALUE_ICC_IMSI,
-                            null);
-                } else {
-                    if (DBG) {
-                        log("GET_CDMA_SUBSCRIPTION: error parsing cdmaSubscription params num="
-                            + cdmaSubscription.length);
-                    }
-                }
-            }
-            break;
-
-        case EVENT_POLL_SIGNAL_STRENGTH:
-            // Just poll signal strength...not part of pollState()
-
-            cm.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
-            break;
-
-        case EVENT_NITZ_TIME:
-            ar = (AsyncResult) msg.obj;
-
-            String nitzString = (String)((Object[])ar.result)[0];
-            long nitzReceiveTime = ((Long)((Object[])ar.result)[1]).longValue();
-
-            setTimeFromNITZString(nitzString, nitzReceiveTime);
-            break;
-
-        case EVENT_SIGNAL_STRENGTH_UPDATE:
-            // This is a notification from CommandsInterface.setOnSignalStrengthUpdate.
-
-            ar = (AsyncResult) msg.obj;
-
-            // The radio is telling us about signal strength changes,
-            // so we don't have to ask it.
-            dontPollSignalStrength = true;
-
-            onSignalStrengthResult(ar);
-            break;
-
-        case EVENT_RUIM_RECORDS_LOADED:
-            updateSpnDisplay();
-            break;
-
-        case EVENT_LOCATION_UPDATES_ENABLED:
-            ar = (AsyncResult) msg.obj;
-
-            if (ar.exception == null) {
-                cm.getVoiceRegistrationState(obtainMessage(EVENT_GET_LOC_DONE_CDMA, null));
-            }
-            break;
-
-        case EVENT_ERI_FILE_LOADED:
-            // Repoll the state once the ERI file has been loaded.
-            if (DBG) log("[CdmaServiceStateTracker] ERI file has been loaded, repolling.");
-            pollState();
-            break;
-
-        case EVENT_OTA_PROVISION_STATUS_CHANGE:
-            ar = (AsyncResult)msg.obj;
-            if (ar.exception == null) {
-                ints = (int[]) ar.result;
-                int otaStatus = ints[0];
-                if (otaStatus == Phone.CDMA_OTA_PROVISION_STATUS_COMMITTED
-                    || otaStatus == Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED) {
-                    if (DBG) log("EVENT_OTA_PROVISION_STATUS_CHANGE: Complete, Reload MDN");
-                    cm.getCDMASubscription( obtainMessage(EVENT_POLL_STATE_CDMA_SUBSCRIPTION));
-                }
-            }
-            break;
-
-        case EVENT_CDMA_PRL_VERSION_CHANGED:
-            ar = (AsyncResult)msg.obj;
-            if (ar.exception == null) {
-                ints = (int[]) ar.result;
-                mPrlVersion = Integer.toString(ints[0]);
-            }
-            break;
-
-        default:
-            super.handleMessage(msg);
-        break;
-        }
-    }
-
-    //***** Private Instance Methods
-
-    private void handleCdmaSubscriptionSource(int newSubscriptionSource) {
-        log("Subscription Source : " + newSubscriptionSource);
-        isSubscriptionFromRuim =
-            (newSubscriptionSource == CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM);
-        saveCdmaSubscriptionSource(newSubscriptionSource);
-        if (!isSubscriptionFromRuim) {
-            // NV is ready when subscription source is NV
-            sendMessage(obtainMessage(EVENT_NV_READY));
-        } else {
-            phone.getIccCard().registerForReady(this, EVENT_RUIM_READY, null);
-        }
-    }
-
-    @Override
-    protected void setPowerStateToDesired() {
-        // If we want it on and it's off, turn it on
-        if (mDesiredPowerState
-            && cm.getRadioState() == CommandsInterface.RadioState.RADIO_OFF) {
-            cm.setRadioPower(true, null);
-        } else if (!mDesiredPowerState && cm.getRadioState().isOn()) {
-            DataConnectionTracker dcTracker = phone.mDataConnectionTracker;
-
-            // If it's on and available and we want it off gracefully
-            powerOffRadioSafely(dcTracker);
-        } // Otherwise, we're in the desired state
-    }
-
-    @Override
-    protected void updateSpnDisplay() {
-        // mOperatorAlphaLong contains the ERI text
-        String plmn = ss.getOperatorAlphaLong();
-        if (!TextUtils.equals(plmn, mCurPlmn)) {
-            // Allow A blank plmn, "" to set showPlmn to true. Previously, we
-            // would set showPlmn to true only if plmn was not empty, i.e. was not
-            // null and not blank. But this would cause us to incorrectly display
-            // "No Service". Now showPlmn is set to true for any non null string.
-            boolean showPlmn = plmn != null;
-            if (DBG) {
-                log(String.format("updateSpnDisplay: changed sending intent" +
-                            " showPlmn='%b' plmn='%s'", showPlmn, plmn));
-            }
-            Intent intent = new Intent(Intents.SPN_STRINGS_UPDATED_ACTION);
-            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
-            intent.putExtra(Intents.EXTRA_SHOW_SPN, false);
-            intent.putExtra(Intents.EXTRA_SPN, "");
-            intent.putExtra(Intents.EXTRA_SHOW_PLMN, showPlmn);
-            intent.putExtra(Intents.EXTRA_PLMN, plmn);
-            phone.getContext().sendStickyBroadcast(intent);
-        }
-
-        mCurPlmn = plmn;
-    }
-
-    @Override
-    protected Phone getPhone() {
-        return phone;
-    }
-
-    /**
-    * Determine data network type based on radio technology.
-    */
-    protected void setCdmaTechnology(int radioTech){
-        mNewDataConnectionState = radioTechnologyToDataServiceState(radioTech);
-        newSS.setRadioTechnology(radioTech);
-        mNewRilRadioTechnology = radioTech;
-    }
-
-    /**
-    * Hanlde the PollStateResult message
-    */
-    protected void handlePollStateResultMessage(int what, AsyncResult ar){
-        int ints[];
-        String states[];
-        switch (what) {
-        case EVENT_POLL_STATE_REGISTRATION_CDMA: // Handle RIL_REQUEST_REGISTRATION_STATE.
-            states = (String[])ar.result;
-
-            int registrationState = 4;     //[0] registrationState
-            int radioTechnology = -1;      //[3] radioTechnology
-            int baseStationId = -1;        //[4] baseStationId
-            //[5] baseStationLatitude
-            int baseStationLatitude = CdmaCellLocation.INVALID_LAT_LONG;
-            //[6] baseStationLongitude
-            int baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG;
-            int cssIndicator = 0;          //[7] init with 0, because it is treated as a boolean
-            int systemId = 0;              //[8] systemId
-            int networkId = 0;             //[9] networkId
-            int roamingIndicator = -1;     //[10] Roaming indicator
-            int systemIsInPrl = 0;         //[11] Indicates if current system is in PRL
-            int defaultRoamingIndicator = 0;  //[12] Is default roaming indicator from PRL
-            int reasonForDenial = 0;       //[13] Denial reason if registrationState = 3
-
-            if (states.length >= 14) {
-                try {
-                    if (states[0] != null) {
-                        registrationState = Integer.parseInt(states[0]);
-                    }
-                    if (states[3] != null) {
-                        radioTechnology = Integer.parseInt(states[3]);
-                    }
-                    if (states[4] != null) {
-                        baseStationId = Integer.parseInt(states[4]);
-                    }
-                    if (states[5] != null) {
-                        baseStationLatitude = Integer.parseInt(states[5]);
-                    }
-                    if (states[6] != null) {
-                        baseStationLongitude = Integer.parseInt(states[6]);
-                    }
-                    // Some carriers only return lat-lngs of 0,0
-                    if (baseStationLatitude == 0 && baseStationLongitude == 0) {
-                        baseStationLatitude  = CdmaCellLocation.INVALID_LAT_LONG;
-                        baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG;
-                    }
-                    if (states[7] != null) {
-                        cssIndicator = Integer.parseInt(states[7]);
-                    }
-                    if (states[8] != null) {
-                        systemId = Integer.parseInt(states[8]);
-                    }
-                    if (states[9] != null) {
-                        networkId = Integer.parseInt(states[9]);
-                    }
-                    if (states[10] != null) {
-                        roamingIndicator = Integer.parseInt(states[10]);
-                    }
-                    if (states[11] != null) {
-                        systemIsInPrl = Integer.parseInt(states[11]);
-                    }
-                    if (states[12] != null) {
-                        defaultRoamingIndicator = Integer.parseInt(states[12]);
-                    }
-                    if (states[13] != null) {
-                        reasonForDenial = Integer.parseInt(states[13]);
-                    }
-                } catch (NumberFormatException ex) {
-                    loge("EVENT_POLL_STATE_REGISTRATION_CDMA: error parsing: " + ex);
-                }
-            } else {
-                throw new RuntimeException("Warning! Wrong number of parameters returned from "
-                                     + "RIL_REQUEST_REGISTRATION_STATE: expected 14 or more "
-                                     + "strings and got " + states.length + " strings");
-            }
-
-            mRegistrationState = registrationState;
-            // When registration state is roaming and TSB58
-            // roaming indicator is not in the carrier-specified
-            // list of ERIs for home system, mCdmaRoaming is true.
-            mCdmaRoaming =
-                    regCodeIsRoaming(registrationState) && !isRoamIndForHomeSystem(states[10]);
-            newSS.setState (regCodeToServiceState(registrationState));
-
-            setCdmaTechnology(radioTechnology);
-
-            newSS.setCssIndicator(cssIndicator);
-            newSS.setSystemAndNetworkId(systemId, networkId);
-            mRoamingIndicator = roamingIndicator;
-            mIsInPrl = (systemIsInPrl == 0) ? false : true;
-            mDefaultRoamingIndicator = defaultRoamingIndicator;
-
-
-            // Values are -1 if not available.
-            newCellLoc.setCellLocationData(baseStationId, baseStationLatitude,
-                    baseStationLongitude, systemId, networkId);
-
-            if (reasonForDenial == 0) {
-                mRegistrationDeniedReason = ServiceStateTracker.REGISTRATION_DENIED_GEN;
-            } else if (reasonForDenial == 1) {
-                mRegistrationDeniedReason = ServiceStateTracker.REGISTRATION_DENIED_AUTH;
-            } else {
-                mRegistrationDeniedReason = "";
-            }
-
-            if (mRegistrationState == 3) {
-                if (DBG) log("Registration denied, " + mRegistrationDeniedReason);
-            }
-            break;
-
-        case EVENT_POLL_STATE_OPERATOR_CDMA: // Handle RIL_REQUEST_OPERATOR
-            String opNames[] = (String[])ar.result;
-
-            if (opNames != null && opNames.length >= 3) {
-                // If the NUMERIC field isn't valid use PROPERTY_CDMA_HOME_OPERATOR_NUMERIC
-                if ((opNames[2] == null) || (opNames[2].length() < 5)
-                        || ("00000".equals(opNames[2]))) {
-                    opNames[2] = SystemProperties.get(
-                            CDMAPhone.PROPERTY_CDMA_HOME_OPERATOR_NUMERIC, "00000");
-                    if (DBG) {
-                        log("RIL_REQUEST_OPERATOR.response[2], the numeric, " +
-                                " is bad. Using SystemProperties '" +
-                                        CDMAPhone.PROPERTY_CDMA_HOME_OPERATOR_NUMERIC +
-                                "'= " + opNames[2]);
-                    }
-                }
-
-                if (!isSubscriptionFromRuim) {
-                    // In CDMA in case on NV, the ss.mOperatorAlphaLong is set later with the
-                    // ERI text, so here it is ignored what is coming from the modem.
-                    newSS.setOperatorName(null, opNames[1], opNames[2]);
-                } else {
-                    newSS.setOperatorName(opNames[0], opNames[1], opNames[2]);
-                }
-            } else {
-                if (DBG) log("EVENT_POLL_STATE_OPERATOR_CDMA: error parsing opNames");
-            }
-            break;
-        default:
-            loge("handlePollStateResultMessage: RIL response handle in wrong phone!"
-                    + " Expected CDMA RIL request and get GSM RIL request.");
-        break;
-        }
-    }
-
-    /**
-     * Handle the result of one of the pollState() - related requests
-     */
-    @Override
-    protected void handlePollStateResult(int what, AsyncResult ar) {
-        // Ignore stale requests from last poll.
-        if (ar.userObj != pollingContext) return;
-
-        if (ar.exception != null) {
-            CommandException.Error err=null;
-
-            if (ar.exception instanceof CommandException) {
-                err = ((CommandException)(ar.exception)).getCommandError();
-            }
-
-            if (err == CommandException.Error.RADIO_NOT_AVAILABLE) {
-                // Radio has crashed or turned off.
-                cancelPollState();
-                return;
-            }
-
-            if (!cm.getRadioState().isOn()) {
-                // Radio has crashed or turned off.
-                cancelPollState();
-                return;
-            }
-
-            if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) {
-                loge("handlePollStateResult: RIL returned an error where it must succeed"
-                        + ar.exception);
-            }
-        } else try {
-            handlePollStateResultMessage(what, ar);
-        } catch (RuntimeException ex) {
-            loge("handlePollStateResult: Exception while polling service state. "
-                    + "Probably malformed RIL response." + ex);
-        }
-
-        pollingContext[0]--;
-
-        if (pollingContext[0] == 0) {
-            boolean namMatch = false;
-            if (!isSidsAllZeros() && isHomeSid(newSS.getSystemId())) {
-                namMatch = true;
-            }
-
-            // Setting SS Roaming (general)
-            if (isSubscriptionFromRuim) {
-                newSS.setRoaming(isRoamingBetweenOperators(mCdmaRoaming, newSS));
-            } else {
-                newSS.setRoaming(mCdmaRoaming);
-            }
-
-            // Setting SS CdmaRoamingIndicator and CdmaDefaultRoamingIndicator
-            newSS.setCdmaDefaultRoamingIndicator(mDefaultRoamingIndicator);
-            newSS.setCdmaRoamingIndicator(mRoamingIndicator);
-            boolean isPrlLoaded = true;
-            if (TextUtils.isEmpty(mPrlVersion)) {
-                isPrlLoaded = false;
-            }
-            if (!isPrlLoaded) {
-                newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_OFF);
-            } else if (!isSidsAllZeros()) {
-                if (!namMatch && !mIsInPrl) {
-                    // Use default
-                    newSS.setCdmaRoamingIndicator(mDefaultRoamingIndicator);
-                } else if (namMatch && !mIsInPrl) {
-                    newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_FLASH);
-                } else if (!namMatch && mIsInPrl) {
-                    // Use the one from PRL/ERI
-                    newSS.setCdmaRoamingIndicator(mRoamingIndicator);
-                } else {
-                    // It means namMatch && mIsInPrl
-                    if ((mRoamingIndicator <= 2)) {
-                        newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_OFF);
-                    } else {
-                        // Use the one from PRL/ERI
-                        newSS.setCdmaRoamingIndicator(mRoamingIndicator);
-                    }
-                }
-            }
-
-            int roamingIndicator = newSS.getCdmaRoamingIndicator();
-            newSS.setCdmaEriIconIndex(phone.mEriManager.getCdmaEriIconIndex(roamingIndicator,
-                    mDefaultRoamingIndicator));
-            newSS.setCdmaEriIconMode(phone.mEriManager.getCdmaEriIconMode(roamingIndicator,
-                    mDefaultRoamingIndicator));
-
-            // NOTE: Some operator may require overriding mCdmaRoaming
-            // (set by the modem), depending on the mRoamingIndicator.
-
-            if (DBG) {
-                log("Set CDMA Roaming Indicator to: " + newSS.getCdmaRoamingIndicator()
-                    + ". mCdmaRoaming = " + mCdmaRoaming + ", isPrlLoaded = " + isPrlLoaded
-                    + ". namMatch = " + namMatch + " , mIsInPrl = " + mIsInPrl
-                    + ", mRoamingIndicator = " + mRoamingIndicator
-                    + ", mDefaultRoamingIndicator= " + mDefaultRoamingIndicator);
-            }
-            pollStateDone();
-        }
-
-    }
-
-    protected void setSignalStrengthDefaultValues() {
-        mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, false);
-    }
-
-    /**
-     * A complete "service state" from our perspective is
-     * composed of a handful of separate requests to the radio.
-     *
-     * We make all of these requests at once, but then abandon them
-     * and start over again if the radio notifies us that some
-     * event has changed
-     */
-    protected void
-    pollState() {
-        pollingContext = new int[1];
-        pollingContext[0] = 0;
-
-        switch (cm.getRadioState()) {
-        case RADIO_UNAVAILABLE:
-            newSS.setStateOutOfService();
-            newCellLoc.setStateInvalid();
-            setSignalStrengthDefaultValues();
-            mGotCountryCode = false;
-
-            pollStateDone();
-            break;
-
-        case RADIO_OFF:
-            newSS.setStateOff();
-            newCellLoc.setStateInvalid();
-            setSignalStrengthDefaultValues();
-            mGotCountryCode = false;
-
-            pollStateDone();
-            break;
-
-        default:
-            // Issue all poll-related commands at once, then count
-            // down the responses which are allowed to arrive
-            // out-of-order.
-
-            pollingContext[0]++;
-            // RIL_REQUEST_OPERATOR is necessary for CDMA
-            cm.getOperator(
-                    obtainMessage(EVENT_POLL_STATE_OPERATOR_CDMA, pollingContext));
-
-            pollingContext[0]++;
-            // RIL_REQUEST_VOICE_REGISTRATION_STATE is necessary for CDMA
-            cm.getVoiceRegistrationState(
-                    obtainMessage(EVENT_POLL_STATE_REGISTRATION_CDMA, pollingContext));
-
-            break;
-        }
-    }
-
-    protected void fixTimeZone(String isoCountryCode) {
-        TimeZone zone = null;
-        // If the offset is (0, false) and the time zone property
-        // is set, use the time zone property rather than GMT.
-        String zoneName = SystemProperties.get(TIMEZONE_PROPERTY);
-        if (DBG) {
-            log("fixTimeZone zoneName='" + zoneName +
-                "' mZoneOffset=" + mZoneOffset + " mZoneDst=" + mZoneDst +
-                " iso-cc='" + isoCountryCode +
-                "' iso-cc-idx=" + Arrays.binarySearch(GMT_COUNTRY_CODES, isoCountryCode));
-        }
-        if ((mZoneOffset == 0) && (mZoneDst == false) && (zoneName != null)
-                && (zoneName.length() > 0)
-                && (Arrays.binarySearch(GMT_COUNTRY_CODES, isoCountryCode) < 0)) {
-            // For NITZ string without time zone,
-            // need adjust time to reflect default time zone setting
-            zone = TimeZone.getDefault();
-            if (mNeedFixZone) {
-                long ctm = System.currentTimeMillis();
-                long tzOffset = zone.getOffset(ctm);
-                if (DBG) {
-                    log("fixTimeZone: tzOffset=" + tzOffset +
-                            " ltod=" + TimeUtils.logTimeOfDay(ctm));
-                }
-                if (getAutoTime()) {
-                    long adj = ctm - tzOffset;
-                    if (DBG) log("fixTimeZone: adj ltod=" + TimeUtils.logTimeOfDay(adj));
-                    setAndBroadcastNetworkSetTime(adj);
-                } else {
-                    // Adjust the saved NITZ time to account for tzOffset.
-                    mSavedTime = mSavedTime - tzOffset;
-                    if (DBG) log("fixTimeZone: adj mSavedTime=" + mSavedTime);
-                }
-            }
-            if (DBG) log("fixTimeZone: using default TimeZone");
-        } else if (isoCountryCode.equals("")) {
-            // Country code not found. This is likely a test network.
-            // Get a TimeZone based only on the NITZ parameters (best guess).
-            zone = getNitzTimeZone(mZoneOffset, mZoneDst, mZoneTime);
-            if (DBG) log("fixTimeZone: using NITZ TimeZone");
-        } else {
-            zone = TimeUtils.getTimeZone(mZoneOffset, mZoneDst, mZoneTime, isoCountryCode);
-            if (DBG) log("fixTimeZone: using getTimeZone(off, dst, time, iso)");
-        }
-
-        mNeedFixZone = false;
-
-        if (zone != null) {
-            log("fixTimeZone: zone != null zone.getID=" + zone.getID());
-            if (getAutoTimeZone()) {
-                setAndBroadcastNetworkSetTimeZone(zone.getID());
-            } else {
-                log("fixTimeZone: skip changing zone as getAutoTimeZone was false");
-            }
-            saveNitzTimeZone(zone.getID());
-        } else {
-            log("fixTimeZone: zone == null, do nothing for zone");
-        }
-    }
-
-    protected void pollStateDone() {
-        if (DBG) log("pollStateDone: oldSS=[" + ss + "] newSS=[" + newSS + "]");
-
-        boolean hasRegistered =
-            ss.getState() != ServiceState.STATE_IN_SERVICE
-            && newSS.getState() == ServiceState.STATE_IN_SERVICE;
-
-        boolean hasDeregistered =
-            ss.getState() == ServiceState.STATE_IN_SERVICE
-            && newSS.getState() != ServiceState.STATE_IN_SERVICE;
-
-        boolean hasCdmaDataConnectionAttached =
-            mDataConnectionState != ServiceState.STATE_IN_SERVICE
-            && mNewDataConnectionState == ServiceState.STATE_IN_SERVICE;
-
-        boolean hasCdmaDataConnectionDetached =
-            mDataConnectionState == ServiceState.STATE_IN_SERVICE
-            && mNewDataConnectionState != ServiceState.STATE_IN_SERVICE;
-
-        boolean hasCdmaDataConnectionChanged =
-                       mDataConnectionState != mNewDataConnectionState;
-
-        boolean hasRadioTechnologyChanged = mRilRadioTechnology != mNewRilRadioTechnology;
-
-        boolean hasChanged = !newSS.equals(ss);
-
-        boolean hasRoamingOn = !ss.getRoaming() && newSS.getRoaming();
-
-        boolean hasRoamingOff = ss.getRoaming() && !newSS.getRoaming();
-
-        boolean hasLocationChanged = !newCellLoc.equals(cellLoc);
-
-        // Add an event log when connection state changes
-        if (ss.getState() != newSS.getState() ||
-                mDataConnectionState != mNewDataConnectionState) {
-            EventLog.writeEvent(EventLogTags.CDMA_SERVICE_STATE_CHANGE,
-                    ss.getState(), mDataConnectionState,
-                    newSS.getState(), mNewDataConnectionState);
-        }
-
-        ServiceState tss;
-        tss = ss;
-        ss = newSS;
-        newSS = tss;
-        // clean slate for next time
-        newSS.setStateOutOfService();
-
-        CdmaCellLocation tcl = cellLoc;
-        cellLoc = newCellLoc;
-        newCellLoc = tcl;
-
-        mDataConnectionState = mNewDataConnectionState;
-        mRilRadioTechnology = mNewRilRadioTechnology;
-        // this new state has been applied - forget it until we get a new new state
-        mNewRilRadioTechnology = 0;
-
-        newSS.setStateOutOfService(); // clean slate for next time
-
-        if (hasRadioTechnologyChanged) {
-            phone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
-                    ServiceState.rilRadioTechnologyToString(mRilRadioTechnology));
-        }
-
-        if (hasRegistered) {
-            mNetworkAttachedRegistrants.notifyRegistrants();
-        }
-
-        if (hasChanged) {
-            if ((cm.getRadioState().isOn()) && (!isSubscriptionFromRuim)) {
-                String eriText;
-                // Now the CDMAPhone sees the new ServiceState so it can get the new ERI text
-                if (ss.getState() == ServiceState.STATE_IN_SERVICE) {
-                    eriText = phone.getCdmaEriText();
-                } else {
-                    // Note that ServiceState.STATE_OUT_OF_SERVICE is valid used for
-                    // mRegistrationState 0,2,3 and 4
-                    eriText = phone.getContext().getText(
-                            com.android.internal.R.string.roamingTextSearching).toString();
-                }
-                ss.setOperatorAlphaLong(eriText);
-            }
-
-            String operatorNumeric;
-
-            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA,
-                    ss.getOperatorAlphaLong());
-
-            String prevOperatorNumeric =
-                    SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, "");
-            operatorNumeric = ss.getOperatorNumeric();
-            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric);
-
-            if (operatorNumeric == null) {
-                if (DBG) log("operatorNumeric is null");
-                phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
-                mGotCountryCode = false;
-            } else {
-                String isoCountryCode = "";
-                String mcc = operatorNumeric.substring(0, 3);
-                try{
-                    isoCountryCode = MccTable.countryCodeForMcc(Integer.parseInt(
-                            operatorNumeric.substring(0,3)));
-                } catch ( NumberFormatException ex){
-                    loge("pollStateDone: countryCodeForMcc error" + ex);
-                } catch ( StringIndexOutOfBoundsException ex) {
-                    loge("pollStateDone: countryCodeForMcc error" + ex);
-                }
-
-                phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY,
-                        isoCountryCode);
-                mGotCountryCode = true;
-
-                if (shouldFixTimeZoneNow(phone, operatorNumeric, prevOperatorNumeric,
-                        mNeedFixZone)) {
-                    fixTimeZone(isoCountryCode);
-                }
-            }
-
-            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
-                    ss.getRoaming() ? "true" : "false");
-
-            updateSpnDisplay();
-            phone.notifyServiceStateChanged(ss);
-        }
-
-        if (hasCdmaDataConnectionAttached) {
-            mAttachedRegistrants.notifyRegistrants();
-        }
-
-        if (hasCdmaDataConnectionDetached) {
-            mDetachedRegistrants.notifyRegistrants();
-        }
-
-        if (hasCdmaDataConnectionChanged || hasRadioTechnologyChanged) {
-            phone.notifyDataConnection(null);
-        }
-
-        if (hasRoamingOn) {
-            mRoamingOnRegistrants.notifyRegistrants();
-        }
-
-        if (hasRoamingOff) {
-            mRoamingOffRegistrants.notifyRegistrants();
-        }
-
-        if (hasLocationChanged) {
-            phone.notifyLocationChanged();
-        }
-    }
-
-    /**
-     * Returns a TimeZone object based only on parameters from the NITZ string.
-     */
-    private TimeZone getNitzTimeZone(int offset, boolean dst, long when) {
-        TimeZone guess = findTimeZone(offset, dst, when);
-        if (guess == null) {
-            // Couldn't find a proper timezone.  Perhaps the DST data is wrong.
-            guess = findTimeZone(offset, !dst, when);
-        }
-        if (DBG) log("getNitzTimeZone returning " + (guess == null ? guess : guess.getID()));
-        return guess;
-    }
-
-    private TimeZone findTimeZone(int offset, boolean dst, long when) {
-        int rawOffset = offset;
-        if (dst) {
-            rawOffset -= 3600000;
-        }
-        String[] zones = TimeZone.getAvailableIDs(rawOffset);
-        TimeZone guess = null;
-        Date d = new Date(when);
-        for (String zone : zones) {
-            TimeZone tz = TimeZone.getTimeZone(zone);
-            if (tz.getOffset(when) == offset &&
-                    tz.inDaylightTime(d) == dst) {
-                guess = tz;
-                break;
-            }
-        }
-
-        return guess;
-    }
-
-    /**
-     * TODO: This code is exactly the same as in GsmServiceStateTracker
-     * and has a TODO to not poll signal strength if screen is off.
-     * This code should probably be hoisted to the base class so
-     * the fix, when added, works for both.
-     */
-    private void
-    queueNextSignalStrengthPoll() {
-        if (dontPollSignalStrength) {
-            // The radio is telling us about signal strength changes
-            // we don't have to ask it
-            return;
-        }
-
-        Message msg;
-
-        msg = obtainMessage();
-        msg.what = EVENT_POLL_SIGNAL_STRENGTH;
-
-        // TODO Don't poll signal strength if screen is off
-        sendMessageDelayed(msg, POLL_PERIOD_MILLIS);
-    }
-
-    /**
-     *  send signal-strength-changed notification if changed
-     *  Called both for solicited and unsolicited signal strength updates
-     */
-    protected void
-    onSignalStrengthResult(AsyncResult ar) {
-        SignalStrength oldSignalStrength = mSignalStrength;
-
-        if (ar.exception != null) {
-            // Most likely radio is resetting/disconnected change to default values.
-            setSignalStrengthDefaultValues();
-        } else {
-            int[] ints = (int[])ar.result;
-            int offset = 2;
-            int cdmaDbm = (ints[offset] > 0) ? -ints[offset] : -120;
-            int cdmaEcio = (ints[offset+1] > 0) ? -ints[offset+1] : -160;
-            int evdoRssi = (ints[offset+2] > 0) ? -ints[offset+2] : -120;
-            int evdoEcio = (ints[offset+3] > 0) ? -ints[offset+3] : -1;
-            int evdoSnr  = ((ints[offset+4] > 0) && (ints[offset+4] <= 8)) ? ints[offset+4] : -1;
-
-            //log(String.format("onSignalStrengthResult cdmaDbm=%d cdmaEcio=%d evdoRssi=%d evdoEcio=%d evdoSnr=%d",
-            //        cdmaDbm, cdmaEcio, evdoRssi, evdoEcio, evdoSnr));
-            mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio,
-                    evdoRssi, evdoEcio, evdoSnr, false);
-        }
-
-        try {
-            phone.notifySignalStrength();
-        } catch (NullPointerException ex) {
-            loge("onSignalStrengthResult() Phone already destroyed: " + ex
-                    + "SignalStrength not notified");
-        }
-    }
-
-
-    protected int radioTechnologyToDataServiceState(int code) {
-        int retVal = ServiceState.STATE_OUT_OF_SERVICE;
-        switch(code) {
-        case 0:
-        case 1:
-        case 2:
-        case 3:
-        case 4:
-        case 5:
-            break;
-        case 6: // RADIO_TECHNOLOGY_1xRTT
-        case 7: // RADIO_TECHNOLOGY_EVDO_0
-        case 8: // RADIO_TECHNOLOGY_EVDO_A
-        case 12: // RADIO_TECHNOLOGY_EVDO_B
-        case 13: // RADIO_TECHNOLOGY_EHRPD
-            retVal = ServiceState.STATE_IN_SERVICE;
-            break;
-        default:
-            loge("radioTechnologyToDataServiceState: Wrong radioTechnology code.");
-        break;
-        }
-        return(retVal);
-    }
-
-    /** code is registration state 0-5 from TS 27.007 7.2 */
-    protected int
-    regCodeToServiceState(int code) {
-        switch (code) {
-        case 0: // Not searching and not registered
-            return ServiceState.STATE_OUT_OF_SERVICE;
-        case 1:
-            return ServiceState.STATE_IN_SERVICE;
-        case 2: // 2 is "searching", fall through
-        case 3: // 3 is "registration denied", fall through
-        case 4: // 4 is "unknown", not valid in current baseband
-            return ServiceState.STATE_OUT_OF_SERVICE;
-        case 5:// 5 is "Registered, roaming"
-            return ServiceState.STATE_IN_SERVICE;
-
-        default:
-            loge("regCodeToServiceState: unexpected service state " + code);
-        return ServiceState.STATE_OUT_OF_SERVICE;
-        }
-    }
-
-    public int getCurrentDataConnectionState() {
-        return mDataConnectionState;
-    }
-
-    /**
-     * code is registration state 0-5 from TS 27.007 7.2
-     * returns true if registered roam, false otherwise
-     */
-    private boolean
-    regCodeIsRoaming (int code) {
-        // 5 is  "in service -- roam"
-        return 5 == code;
-    }
-
-    /**
-     * Determine whether a roaming indicator is in the carrier-specified list of ERIs for
-     * home system
-     *
-     * @param roamInd roaming indicator in String
-     * @return true if the roamInd is in the carrier-specified list of ERIs for home network
-     */
-    private boolean isRoamIndForHomeSystem(String roamInd) {
-        // retrieve the carrier-specified list of ERIs for home system
-        String homeRoamIndicators = SystemProperties.get("ro.cdma.homesystem");
-
-        if (!TextUtils.isEmpty(homeRoamIndicators)) {
-            // searches through the comma-separated list for a match,
-            // return true if one is found.
-            for (String homeRoamInd : homeRoamIndicators.split(",")) {
-                if (homeRoamInd.equals(roamInd)) {
-                    return true;
-                }
-            }
-            // no matches found against the list!
-            return false;
-        }
-
-        // no system property found for the roaming indicators for home system
-        return false;
-    }
-
-    /**
-     * Set roaming state when cdmaRoaming is true and ons is different from spn
-     * @param cdmaRoaming TS 27.007 7.2 CREG registered roaming
-     * @param s ServiceState hold current ons
-     * @return true for roaming state set
-     */
-    private
-    boolean isRoamingBetweenOperators(boolean cdmaRoaming, ServiceState s) {
-        String spn = SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, "empty");
-
-        // NOTE: in case of RUIM we should completely ignore the ERI data file and
-        // mOperatorAlphaLong is set from RIL_REQUEST_OPERATOR response 0 (alpha ONS)
-        String onsl = s.getOperatorAlphaLong();
-        String onss = s.getOperatorAlphaShort();
-
-        boolean equalsOnsl = onsl != null && spn.equals(onsl);
-        boolean equalsOnss = onss != null && spn.equals(onss);
-
-        return cdmaRoaming && !(equalsOnsl || equalsOnss);
-    }
-
-
-    /**
-     * nitzReceiveTime is time_t that the NITZ time was posted
-     */
-
-    private
-    void setTimeFromNITZString (String nitz, long nitzReceiveTime)
-    {
-        // "yy/mm/dd,hh:mm:ss(+/-)tz"
-        // tz is in number of quarter-hours
-
-        long start = SystemClock.elapsedRealtime();
-        if (DBG) {
-            log("NITZ: " + nitz + "," + nitzReceiveTime +
-                        " start=" + start + " delay=" + (start - nitzReceiveTime));
-        }
-
-        try {
-            /* NITZ time (hour:min:sec) will be in UTC but it supplies the timezone
-             * offset as well (which we won't worry about until later) */
-            Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
-
-            c.clear();
-            c.set(Calendar.DST_OFFSET, 0);
-
-            String[] nitzSubs = nitz.split("[/:,+-]");
-
-            int year = 2000 + Integer.parseInt(nitzSubs[0]);
-            c.set(Calendar.YEAR, year);
-
-            // month is 0 based!
-            int month = Integer.parseInt(nitzSubs[1]) - 1;
-            c.set(Calendar.MONTH, month);
-
-            int date = Integer.parseInt(nitzSubs[2]);
-            c.set(Calendar.DATE, date);
-
-            int hour = Integer.parseInt(nitzSubs[3]);
-            c.set(Calendar.HOUR, hour);
-
-            int minute = Integer.parseInt(nitzSubs[4]);
-            c.set(Calendar.MINUTE, minute);
-
-            int second = Integer.parseInt(nitzSubs[5]);
-            c.set(Calendar.SECOND, second);
-
-            boolean sign = (nitz.indexOf('-') == -1);
-
-            int tzOffset = Integer.parseInt(nitzSubs[6]);
-
-            int dst = (nitzSubs.length >= 8 ) ? Integer.parseInt(nitzSubs[7])
-                                              : 0;
-
-            // The zone offset received from NITZ is for current local time,
-            // so DST correction is already applied.  Don't add it again.
-            //
-            // tzOffset += dst * 4;
-            //
-            // We could unapply it if we wanted the raw offset.
-
-            tzOffset = (sign ? 1 : -1) * tzOffset * 15 * 60 * 1000;
-
-            TimeZone    zone = null;
-
-            // As a special extension, the Android emulator appends the name of
-            // the host computer's timezone to the nitz string. this is zoneinfo
-            // timezone name of the form Area!Location or Area!Location!SubLocation
-            // so we need to convert the ! into /
-            if (nitzSubs.length >= 9) {
-                String  tzname = nitzSubs[8].replace('!','/');
-                zone = TimeZone.getTimeZone( tzname );
-            }
-
-            String iso = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY);
-
-            if (zone == null) {
-                if (mGotCountryCode) {
-                    if (iso != null && iso.length() > 0) {
-                        zone = TimeUtils.getTimeZone(tzOffset, dst != 0,
-                                c.getTimeInMillis(),
-                                iso);
-                    } else {
-                        // We don't have a valid iso country code.  This is
-                        // most likely because we're on a test network that's
-                        // using a bogus MCC (eg, "001"), so get a TimeZone
-                        // based only on the NITZ parameters.
-                        zone = getNitzTimeZone(tzOffset, (dst != 0), c.getTimeInMillis());
-                    }
-                }
-            }
-
-            if ((zone == null) || (mZoneOffset != tzOffset) || (mZoneDst != (dst != 0))){
-                // We got the time before the country or the zone has changed
-                // so we don't know how to identify the DST rules yet.  Save
-                // the information and hope to fix it up later.
-
-                mNeedFixZone = true;
-                mZoneOffset  = tzOffset;
-                mZoneDst     = dst != 0;
-                mZoneTime    = c.getTimeInMillis();
-            }
-            if (DBG) {
-                log("NITZ: tzOffset=" + tzOffset + " dst=" + dst + " zone=" +
-                        (zone!=null ? zone.getID() : "NULL") +
-                        " iso=" + iso + " mGotCountryCode=" + mGotCountryCode +
-                        " mNeedFixZone=" + mNeedFixZone);
-            }
-
-            if (zone != null) {
-                if (getAutoTimeZone()) {
-                    setAndBroadcastNetworkSetTimeZone(zone.getID());
-                }
-                saveNitzTimeZone(zone.getID());
-            }
-
-            String ignore = SystemProperties.get("gsm.ignore-nitz");
-            if (ignore != null && ignore.equals("yes")) {
-                if (DBG) log("NITZ: Not setting clock because gsm.ignore-nitz is set");
-                return;
-            }
-
-            try {
-                mWakeLock.acquire();
-
-                /**
-                 * Correct the NITZ time by how long its taken to get here.
-                 */
-                long millisSinceNitzReceived
-                        = SystemClock.elapsedRealtime() - nitzReceiveTime;
-
-                if (millisSinceNitzReceived < 0) {
-                    // Sanity check: something is wrong
-                    if (DBG) {
-                        log("NITZ: not setting time, clock has rolled "
-                                        + "backwards since NITZ time was received, "
-                                        + nitz);
-                    }
-                    return;
-                }
-
-                if (millisSinceNitzReceived > Integer.MAX_VALUE) {
-                    // If the time is this far off, something is wrong > 24 days!
-                    if (DBG) {
-                        log("NITZ: not setting time, processing has taken "
-                                    + (millisSinceNitzReceived / (1000 * 60 * 60 * 24))
-                                    + " days");
-                    }
-                    return;
-                }
-
-                // Note: with range checks above, cast to int is safe
-                c.add(Calendar.MILLISECOND, (int)millisSinceNitzReceived);
-
-                if (getAutoTime()) {
-                    /**
-                     * Update system time automatically
-                     */
-                    long gained = c.getTimeInMillis() - System.currentTimeMillis();
-                    long timeSinceLastUpdate = SystemClock.elapsedRealtime() - mSavedAtTime;
-                    int nitzUpdateSpacing = Settings.Secure.getInt(cr,
-                            Settings.Secure.NITZ_UPDATE_SPACING, mNitzUpdateSpacing);
-                    int nitzUpdateDiff = Settings.Secure.getInt(cr,
-                            Settings.Secure.NITZ_UPDATE_DIFF, mNitzUpdateDiff);
-
-                    if ((mSavedAtTime == 0) || (timeSinceLastUpdate > nitzUpdateSpacing)
-                            || (Math.abs(gained) > nitzUpdateDiff)) {
-                        if (DBG) {
-                            log("NITZ: Auto updating time of day to " + c.getTime()
-                                + " NITZ receive delay=" + millisSinceNitzReceived
-                                + "ms gained=" + gained + "ms from " + nitz);
-                        }
-
-                        setAndBroadcastNetworkSetTime(c.getTimeInMillis());
-                    } else {
-                        if (DBG) {
-                            log("NITZ: ignore, a previous update was "
-                                + timeSinceLastUpdate + "ms ago and gained=" + gained + "ms");
-                        }
-                        return;
-                    }
-                }
-
-                /**
-                 * Update properties and save the time we did the update
-                 */
-                if (DBG) log("NITZ: update nitz time property");
-                SystemProperties.set("gsm.nitz.time", String.valueOf(c.getTimeInMillis()));
-                mSavedTime = c.getTimeInMillis();
-                mSavedAtTime = SystemClock.elapsedRealtime();
-            } finally {
-                long end = SystemClock.elapsedRealtime();
-                if (DBG) log("NITZ: end=" + end + " dur=" + (end - start));
-                mWakeLock.release();
-            }
-        } catch (RuntimeException ex) {
-            loge("NITZ: Parsing NITZ time " + nitz + " ex=" + ex);
-        }
-    }
-
-    private boolean getAutoTime() {
-        try {
-            return Settings.System.getInt(cr, Settings.System.AUTO_TIME) > 0;
-        } catch (SettingNotFoundException snfe) {
-            return true;
-        }
-    }
-
-    private boolean getAutoTimeZone() {
-        try {
-            return Settings.System.getInt(cr, Settings.System.AUTO_TIME_ZONE) > 0;
-        } catch (SettingNotFoundException snfe) {
-            return true;
-        }
-    }
-
-    private void saveNitzTimeZone(String zoneId) {
-        mSavedTimeZone = zoneId;
-    }
-
-    /**
-     * Set the timezone and send out a sticky broadcast so the system can
-     * determine if the timezone was set by the carrier.
-     *
-     * @param zoneId timezone set by carrier
-     */
-    private void setAndBroadcastNetworkSetTimeZone(String zoneId) {
-        if (DBG) log("setAndBroadcastNetworkSetTimeZone: setTimeZone=" + zoneId);
-        AlarmManager alarm =
-            (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE);
-        alarm.setTimeZone(zoneId);
-        Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE);
-        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
-        intent.putExtra("time-zone", zoneId);
-        phone.getContext().sendStickyBroadcast(intent);
-    }
-
-    /**
-     * Set the time and Send out a sticky broadcast so the system can determine
-     * if the time was set by the carrier.
-     *
-     * @param time time set by network
-     */
-    private void setAndBroadcastNetworkSetTime(long time) {
-        if (DBG) log("setAndBroadcastNetworkSetTime: time=" + time + "ms");
-        SystemClock.setCurrentTimeMillis(time);
-        Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIME);
-        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
-        intent.putExtra("time", time);
-        phone.getContext().sendStickyBroadcast(intent);
-    }
-
-    private void revertToNitzTime() {
-        if (Settings.System.getInt(cr, Settings.System.AUTO_TIME, 0) == 0) {
-            return;
-        }
-        if (DBG) {
-            log("revertToNitzTime: mSavedTime=" + mSavedTime + " mSavedAtTime=" + mSavedAtTime);
-        }
-        if (mSavedTime != 0 && mSavedAtTime != 0) {
-            setAndBroadcastNetworkSetTime(mSavedTime
-                    + (SystemClock.elapsedRealtime() - mSavedAtTime));
-        }
-    }
-
-    private void revertToNitzTimeZone() {
-        if (Settings.System.getInt(phone.getContext().getContentResolver(),
-                Settings.System.AUTO_TIME_ZONE, 0) == 0) {
-            return;
-        }
-        if (DBG) log("revertToNitzTimeZone: tz='" + mSavedTimeZone);
-        if (mSavedTimeZone != null) {
-            setAndBroadcastNetworkSetTimeZone(mSavedTimeZone);
-        }
-    }
-
-    protected boolean isSidsAllZeros() {
-        if (mHomeSystemId != null) {
-            for (int i=0; i < mHomeSystemId.length; i++) {
-                if (mHomeSystemId[i] != 0) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Check whether a specified system ID that matches one of the home system IDs.
-     */
-    private boolean isHomeSid(int sid) {
-        if (mHomeSystemId != null) {
-            for (int i=0; i < mHomeSystemId.length; i++) {
-                if (sid == mHomeSystemId[i]) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * @return true if phone is camping on a technology
-     * that could support voice and data simultaneously.
-     */
-    public boolean isConcurrentVoiceAndDataAllowed() {
-        // Note: it needs to be confirmed which CDMA network types
-        // can support voice and data calls concurrently.
-        // For the time-being, the return value will be false.
-        return false;
-    }
-
-    public String getMdnNumber() {
-        return mMdn;
-    }
-
-    public String getCdmaMin() {
-         return mMin;
-    }
-
-    /** Returns null if NV is not yet ready */
-    public String getPrlVersion() {
-        return mPrlVersion;
-    }
-
-    /**
-     * Returns IMSI as MCC + MNC + MIN
-     */
-    String getImsi() {
-        // TODO: When RUIM is enabled, IMSI will come from RUIM not build-time props.
-        String operatorNumeric = SystemProperties.get(
-                TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "");
-
-        if (!TextUtils.isEmpty(operatorNumeric) && getCdmaMin() != null) {
-            return (operatorNumeric + getCdmaMin());
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Check if subscription data has been assigned to mMin
-     *
-     * return true if MIN info is ready; false otherwise.
-     */
-    public boolean isMinInfoReady() {
-        return mIsMinInfoReady;
-    }
-
-    /**
-     * Returns OTASP_UNKNOWN, OTASP_NEEDED or OTASP_NOT_NEEDED
-     */
-    int getOtasp() {
-        int provisioningState;
-        if (mMin == null || (mMin.length() < 6)) {
-            if (DBG) log("getOtasp: bad mMin='" + mMin + "'");
-            provisioningState = OTASP_UNKNOWN;
-        } else {
-            if ((mMin.equals(UNACTIVATED_MIN_VALUE)
-                    || mMin.substring(0,6).equals(UNACTIVATED_MIN2_VALUE))
-                    || SystemProperties.getBoolean("test_cdma_setup", false)) {
-                provisioningState = OTASP_NEEDED;
-            } else {
-                provisioningState = OTASP_NOT_NEEDED;
-            }
-        }
-        if (DBG) log("getOtasp: state=" + provisioningState);
-        return provisioningState;
-    }
-
-    @Override
-    protected void hangupAndPowerOff() {
-        // hang up all active voice calls
-        phone.mCT.ringingCall.hangupIfAlive();
-        phone.mCT.backgroundCall.hangupIfAlive();
-        phone.mCT.foregroundCall.hangupIfAlive();
-        cm.setRadioPower(false, null);
-    }
-
-    protected void parseSidNid (String sidStr, String nidStr) {
-        if (sidStr != null) {
-            String[] sid = sidStr.split(",");
-            mHomeSystemId = new int[sid.length];
-            for (int i = 0; i < sid.length; i++) {
-                try {
-                    mHomeSystemId[i] = Integer.parseInt(sid[i]);
-                } catch (NumberFormatException ex) {
-                    loge("error parsing system id: " + ex);
-                }
-            }
-        }
-        if (DBG) log("CDMA_SUBSCRIPTION: SID=" + sidStr);
-
-        if (nidStr != null) {
-            String[] nid = nidStr.split(",");
-            mHomeNetworkId = new int[nid.length];
-            for (int i = 0; i < nid.length; i++) {
-                try {
-                    mHomeNetworkId[i] = Integer.parseInt(nid[i]);
-                } catch (NumberFormatException ex) {
-                    loge("CDMA_SUBSCRIPTION: error parsing network id: " + ex);
-                }
-            }
-        }
-        if (DBG) log("CDMA_SUBSCRIPTION: NID=" + nidStr);
-    }
-
-    protected void updateOtaspState() {
-        int otaspMode = getOtasp();
-        int oldOtaspMode = mCurrentOtaspMode;
-        mCurrentOtaspMode = otaspMode;
-
-        // Notify apps subscription info is ready
-        if (cdmaForSubscriptionInfoReadyRegistrants != null) {
-            if (DBG) log("CDMA_SUBSCRIPTION: call notifyRegistrants()");
-            cdmaForSubscriptionInfoReadyRegistrants.notifyRegistrants();
-        }
-        if (oldOtaspMode != mCurrentOtaspMode) {
-            if (DBG) {
-                log("CDMA_SUBSCRIPTION: call notifyOtaspChanged old otaspMode=" +
-                    oldOtaspMode + " new otaspMode=" + mCurrentOtaspMode);
-            }
-            phone.notifyOtaspChanged(mCurrentOtaspMode);
-        }
-    }
-
-    @Override
-    protected void log(String s) {
-        Log.d(LOG_TAG, "[CdmaSST] " + s);
-    }
-
-    @Override
-    protected void loge(String s) {
-        Log.e(LOG_TAG, "[CdmaSST] " + s);
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("CdmaServiceStateTracker extends:");
-        super.dump(fd, pw, args);
-        pw.println(" phone=" + phone);
-        pw.println(" cellLoc=" + cellLoc);
-        pw.println(" newCellLoc=" + newCellLoc);
-        pw.println(" mCurrentOtaspMode=" + mCurrentOtaspMode);
-        pw.println(" mCdmaRoaming=" + mCdmaRoaming);
-        pw.println(" mRoamingIndicator=" + mRoamingIndicator);
-        pw.println(" mIsInPrl=" + mIsInPrl);
-        pw.println(" mDefaultRoamingIndicator=" + mDefaultRoamingIndicator);
-        pw.println(" mDataConnectionState=" + mDataConnectionState);
-        pw.println(" mNewDataConnectionState=" + mNewDataConnectionState);
-        pw.println(" mRegistrationState=" + mRegistrationState);
-        pw.println(" mNeedFixZone=" + mNeedFixZone);
-        pw.println(" mZoneOffset=" + mZoneOffset);
-        pw.println(" mZoneDst=" + mZoneDst);
-        pw.println(" mZoneTime=" + mZoneTime);
-        pw.println(" mGotCountryCode=" + mGotCountryCode);
-        pw.println(" mSavedTimeZone=" + mSavedTimeZone);
-        pw.println(" mSavedTime=" + mSavedTime);
-        pw.println(" mSavedAtTime=" + mSavedAtTime);
-        pw.println(" mNeedToRegForRuimLoaded=" + mNeedToRegForRuimLoaded);
-        pw.println(" mWakeLock=" + mWakeLock);
-        pw.println(" mCurPlmn=" + mCurPlmn);
-        pw.println(" mMdn=" + mMdn);
-        pw.println(" mHomeSystemId=" + mHomeSystemId);
-        pw.println(" mHomeNetworkId=" + mHomeNetworkId);
-        pw.println(" mMin=" + mMin);
-        pw.println(" mPrlVersion=" + mPrlVersion);
-        pw.println(" mIsMinInfoReady=" + mIsMinInfoReady);
-        pw.println(" isEriTextLoaded=" + isEriTextLoaded);
-        pw.println(" isSubscriptionFromRuim=" + isSubscriptionFromRuim);
-        pw.println(" mCdmaSSM=" + mCdmaSSM);
-        pw.println(" mRegistrationDeniedReason=" + mRegistrationDeniedReason);
-        pw.println(" currentCarrier=" + currentCarrier);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSubscriptionSourceManager.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSubscriptionSourceManager.java
deleted file mode 100644
index 80af9d4..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSubscriptionSourceManager.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (c) 2011 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.internal.telephony.cdma;
-
-import java.util.concurrent.atomic.AtomicInteger;
-
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.RILConstants;
-
-import android.content.Context;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.provider.Settings;
-import android.util.Log;
-
-/**
- * Class that handles the CDMA subscription source changed events from RIL
- */
-public class CdmaSubscriptionSourceManager extends Handler {
-    static final String LOG_TAG = "CDMA";
-    private static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 1;
-    private static final int EVENT_GET_CDMA_SUBSCRIPTION_SOURCE     = 2;
-    private static final int EVENT_RADIO_ON                         = 3;
-
-    public static final int SUBSCRIPTION_SOURCE_UNKNOWN = -1;
-    public static final int SUBSCRIPTION_FROM_RUIM      = 0; /* CDMA subscription from RUIM */
-    public static final int SUBSCRIPTION_FROM_NV        = 1; /* CDMA subscription from NV */
-    public static final int PREFERRED_CDMA_SUBSCRIPTION = SUBSCRIPTION_FROM_NV;
-
-    private static CdmaSubscriptionSourceManager sInstance;
-    private static final Object sReferenceCountMonitor = new Object();
-    private static int sReferenceCount = 0;
-
-    // ***** Instance Variables
-    private CommandsInterface mCM;
-    private Context mContext;
-    private RegistrantList mCdmaSubscriptionSourceChangedRegistrants = new RegistrantList();
-
-    // Type of CDMA subscription source
-    private AtomicInteger mCdmaSubscriptionSource = new AtomicInteger(SUBSCRIPTION_FROM_NV);
-
-    // Constructor
-    private CdmaSubscriptionSourceManager(Context context, CommandsInterface ci) {
-        mContext = context;
-        mCM = ci;
-        mCM.registerForCdmaSubscriptionChanged(this, EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
-        mCM.registerForOn(this, EVENT_RADIO_ON, null);
-        int subscriptionSource = getDefaultCdmaSubscriptionSource();
-        mCdmaSubscriptionSource.set(subscriptionSource);
-    }
-
-    /**
-     * This function creates a single instance of this class
-     *
-     * @return object of type CdmaSubscriptionSourceManager
-     */
-    public static CdmaSubscriptionSourceManager getInstance(Context context,
-            CommandsInterface ci, Handler h, int what, Object obj) {
-        synchronized (sReferenceCountMonitor) {
-            if (null == sInstance) {
-                sInstance = new CdmaSubscriptionSourceManager(context, ci);
-            }
-            sInstance.sReferenceCount++;
-        }
-        sInstance.registerForCdmaSubscriptionSourceChanged(h, what, obj);
-        return sInstance;
-    }
-
-    /**
-     * Unregisters for the registered event with RIL
-     */
-    public void dispose(Handler h) {
-        mCdmaSubscriptionSourceChangedRegistrants.remove(h);
-        synchronized (sReferenceCountMonitor) {
-            sReferenceCount--;
-            if (sReferenceCount <= 0) {
-                mCM.unregisterForCdmaSubscriptionChanged(this);
-                mCM.unregisterForOn(this);
-                sInstance = null;
-            }
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see android.os.Handler#handleMessage(android.os.Message)
-     */
-    @Override
-    public void handleMessage(Message msg) {
-        AsyncResult ar;
-        switch (msg.what) {
-            case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
-            case EVENT_GET_CDMA_SUBSCRIPTION_SOURCE:
-            {
-                log("CDMA_SUBSCRIPTION_SOURCE event = " + msg.what);
-                ar = (AsyncResult) msg.obj;
-                handleGetCdmaSubscriptionSource(ar);
-            }
-            break;
-            case EVENT_RADIO_ON: {
-                mCM.getCdmaSubscriptionSource(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_SOURCE));
-            }
-            break;
-            default:
-                super.handleMessage(msg);
-        }
-    }
-
-    /**
-     * Returns the current CDMA subscription source value
-     * @return CDMA subscription source value
-     */
-    public int getCdmaSubscriptionSource() {
-        return mCdmaSubscriptionSource.get();
-    }
-
-    /**
-     * Gets the default CDMA subscription source
-     *
-     * @return Default CDMA subscription source from Settings DB if present.
-     */
-    private int getDefaultCdmaSubscriptionSource() {
-        // Get the default value from the Settings
-        int subscriptionSource = Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.CDMA_SUBSCRIPTION_MODE, PREFERRED_CDMA_SUBSCRIPTION);
-        return subscriptionSource;
-    }
-
-    /**
-     * Clients automatically register for CDMA subscription source changed event
-     * when they get an instance of this object.
-     */
-    private void registerForCdmaSubscriptionSourceChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mCdmaSubscriptionSourceChangedRegistrants.add(r);
-    }
-
-    /**
-     * Handles the call to get the subscription source
-     *
-     * @param ar AsyncResult object that contains the result of get CDMA
-     *            subscription source call
-     */
-    private void handleGetCdmaSubscriptionSource(AsyncResult ar) {
-        if ((ar.exception == null) && (ar.result != null)) {
-            int newSubscriptionSource = ((int[]) ar.result)[0];
-
-            if (newSubscriptionSource != mCdmaSubscriptionSource.get()) {
-                log("Subscription Source Changed : " + mCdmaSubscriptionSource + " >> "
-                        + newSubscriptionSource);
-                mCdmaSubscriptionSource.set(newSubscriptionSource);
-
-                // Notify registrants of the new CDMA subscription source
-                mCdmaSubscriptionSourceChangedRegistrants.notifyRegistrants(new AsyncResult(null,
-                        null, null));
-            }
-        } else {
-            // GET_CDMA_SUBSCRIPTION is returning Failure. Probably
-            // because modem created GSM Phone. If modem created
-            // GSMPhone, then PhoneProxy will trigger a change in
-            // Phone objects and this object will be destroyed.
-            logw("Unable to get CDMA Subscription Source, Exception: " + ar.exception
-                    + ", result: " + ar.result);
-        }
-    }
-
-    private void log(String s) {
-        Log.d(LOG_TAG, "[CdmaSSM] " + s);
-    }
-
-    private void loge(String s) {
-        Log.e(LOG_TAG, "[CdmaSSM] " + s);
-    }
-
-    private void logw(String s) {
-        Log.w(LOG_TAG, "[CdmaSSM] " + s);
-    }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/EriInfo.java b/telephony/java/com/android/internal/telephony/cdma/EriInfo.java
deleted file mode 100644
index 3e5d37e..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/EriInfo.java
+++ /dev/null
@@ -1,45 +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.
- */
-
-package com.android.internal.telephony.cdma;
-
-public final class EriInfo {
-
-    public static final int ROAMING_INDICATOR_ON    = 0;
-    public static final int ROAMING_INDICATOR_OFF   = 1;
-    public static final int ROAMING_INDICATOR_FLASH = 2;
-
-    public static final int ROAMING_ICON_MODE_NORMAL    = 0;
-    public static final int ROAMING_ICON_MODE_FLASH     = 1;
-
-    public int mRoamingIndicator;
-    public int mIconIndex;
-    public int mIconMode;
-    public String mEriText;
-    public int mCallPromptId;
-    public int mAlertId;
-
-    public EriInfo (int roamingIndicator, int iconIndex, int iconMode, String eriText,
-            int callPromptId, int alertId) {
-
-        this.mRoamingIndicator = roamingIndicator;
-        this.mIconIndex = iconIndex;
-        this.mIconMode = iconMode;
-        this.mEriText = eriText;
-        this.mCallPromptId = callPromptId;
-        this.mAlertId = alertId;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/EriManager.java b/telephony/java/com/android/internal/telephony/cdma/EriManager.java
deleted file mode 100644
index 1bcc90a..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/EriManager.java
+++ /dev/null
@@ -1,492 +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.
- */
-
-package com.android.internal.telephony.cdma;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.XmlResourceParser;
-import android.os.Message;
-import android.util.Log;
-import android.util.Xml;
-
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.util.XmlUtils;
-
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.HashMap;
-
-/**
- * EriManager loads the ERI file definitions and manages the CDMA roaming information.
- *
- */
-public final class EriManager {
-
-    class EriFile {
-
-        public int mVersionNumber;                      // File version number
-        public int mNumberOfEriEntries;                 // Number of entries
-        public int mEriFileType;                        // Eri Phase 0/1
-        //public int mNumberOfIconImages;               // reserved for future use
-        //public int mIconImageType;                    // reserved for future use
-        public String[] mCallPromptId;                  // reserved for future use
-        public HashMap<Integer, EriInfo> mRoamIndTable; // Roaming Indicator Table
-
-        public EriFile() {
-            this.mVersionNumber = -1;
-            this.mNumberOfEriEntries = 0;
-            this.mEriFileType = -1;
-            this.mCallPromptId = new String[] { "", "", "" };
-            this.mRoamIndTable = new HashMap<Integer, EriInfo>();
-        }
-    }
-
-    class EriDisplayInformation {
-        public int mEriIconIndex;
-        public int mEriIconMode;
-        public String mEriIconText;
-
-        public EriDisplayInformation(int eriIconIndex, int eriIconMode, String eriIconText) {
-            mEriIconIndex = eriIconIndex;
-            mEriIconMode = eriIconMode;
-            mEriIconText = eriIconText;
-        }
-
-//        public void setParameters(int eriIconIndex, int eriIconMode, String eriIconText){
-//            this.mEriIconIndex = eriIconIndex;
-//            this.mEriIconMode = eriIconMode;
-//            this.mEriIconText = eriIconText;
-//        }
-
-        @Override
-        public String toString() {
-            return "EriDisplayInformation: {" + " IconIndex: " + mEriIconIndex + " EriIconMode: "
-                    + mEriIconMode + " EriIconText: " + mEriIconText + " }";
-        }
-    }
-
-    private static final String LOG_TAG = "CDMA";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    public static final int ERI_FROM_XML          = 0;
-    public static final int ERI_FROM_FILE_SYSTEM  = 1;
-    public static final int ERI_FROM_MODEM        = 2;
-
-    private PhoneBase mPhone;
-    private Context mContext;
-    private int mEriFileSource = ERI_FROM_XML;
-    private boolean isEriFileLoaded;
-    private EriFile mEriFile;
-
-    public EriManager(PhoneBase phone, Context context, int eriFileSource) {
-        this.mPhone = phone;
-        this.mContext = context;
-        this.mEriFileSource = eriFileSource;
-        this.mEriFile = new EriFile();
-    }
-
-    public void dispose() {
-        mEriFile = new EriFile();
-        isEriFileLoaded = false;
-    }
-
-
-    public void loadEriFile() {
-        switch (mEriFileSource) {
-        case ERI_FROM_MODEM:
-            loadEriFileFromModem();
-            break;
-
-        case ERI_FROM_FILE_SYSTEM:
-            loadEriFileFromFileSystem();
-            break;
-
-        case ERI_FROM_XML:
-        default:
-            loadEriFileFromXml();
-            break;
-        }
-    }
-
-    /**
-     * Load the ERI file from the MODEM through chipset specific RIL_REQUEST_OEM_HOOK
-     *
-     * In this case the ERI file can be updated from the Phone Support Tool available
-     * from the Chipset vendor
-     */
-    private void loadEriFileFromModem() {
-        // NOT IMPLEMENTED, Chipset vendor/Operator specific
-    }
-
-    /**
-     * Load the ERI file from a File System file
-     *
-     * In this case the a Phone Support Tool to update the ERI file must be provided
-     * to the Operator
-     */
-    private void loadEriFileFromFileSystem() {
-        // NOT IMPLEMENTED, Chipset vendor/Operator specific
-    }
-
-    /**
-     * Load the ERI file from the application framework resources encoded in XML
-     *
-     */
-    private void loadEriFileFromXml() {
-        XmlPullParser parser = null;
-        FileInputStream stream = null;
-        Resources r = mContext.getResources();
-
-        try {
-            if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: check for alternate file");
-            stream = new FileInputStream(
-                            r.getString(com.android.internal.R.string.alternate_eri_file));
-            parser = Xml.newPullParser();
-            parser.setInput(stream, null);
-            if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: opened alternate file");
-        } catch (FileNotFoundException e) {
-            if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: no alternate file");
-            parser = null;
-        } catch (XmlPullParserException e) {
-            if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: no parser for alternate file");
-            parser = null;
-        }
-
-        if (parser == null) {
-            if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: open normal file");
-            parser = r.getXml(com.android.internal.R.xml.eri);
-        }
-
-        try {
-            XmlUtils.beginDocument(parser, "EriFile");
-            mEriFile.mVersionNumber = Integer.parseInt(
-                    parser.getAttributeValue(null, "VersionNumber"));
-            mEriFile.mNumberOfEriEntries = Integer.parseInt(
-                    parser.getAttributeValue(null, "NumberOfEriEntries"));
-            mEriFile.mEriFileType = Integer.parseInt(
-                    parser.getAttributeValue(null, "EriFileType"));
-
-            int parsedEriEntries = 0;
-            while(true) {
-                XmlUtils.nextElement(parser);
-                String name = parser.getName();
-                if (name == null) {
-                    if (parsedEriEntries != mEriFile.mNumberOfEriEntries)
-                        Log.e(LOG_TAG, "Error Parsing ERI file: " +  mEriFile.mNumberOfEriEntries
-                                + " defined, " + parsedEriEntries + " parsed!");
-                    break;
-                } else if (name.equals("CallPromptId")) {
-                    int id = Integer.parseInt(parser.getAttributeValue(null, "Id"));
-                    String text = parser.getAttributeValue(null, "CallPromptText");
-                    if (id >= 0 && id <= 2) {
-                        mEriFile.mCallPromptId[id] = text;
-                    } else {
-                        Log.e(LOG_TAG, "Error Parsing ERI file: found" + id + " CallPromptId");
-                    }
-
-                } else if (name.equals("EriInfo")) {
-                    int roamingIndicator = Integer.parseInt(
-                            parser.getAttributeValue(null, "RoamingIndicator"));
-                    int iconIndex = Integer.parseInt(parser.getAttributeValue(null, "IconIndex"));
-                    int iconMode = Integer.parseInt(parser.getAttributeValue(null, "IconMode"));
-                    String eriText = parser.getAttributeValue(null, "EriText");
-                    int callPromptId = Integer.parseInt(
-                            parser.getAttributeValue(null, "CallPromptId"));
-                    int alertId = Integer.parseInt(parser.getAttributeValue(null, "AlertId"));
-                    parsedEriEntries++;
-                    mEriFile.mRoamIndTable.put(roamingIndicator, new EriInfo (roamingIndicator,
-                            iconIndex, iconMode, eriText, callPromptId, alertId));
-                }
-            }
-
-            if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: eri parsing successful, file loaded");
-            isEriFileLoaded = true;
-
-        } catch (Exception e) {
-            Log.e(LOG_TAG, "Got exception while loading ERI file.", e);
-        } finally {
-            if (parser instanceof XmlResourceParser) {
-                ((XmlResourceParser)parser).close();
-            }
-            try {
-                if (stream != null) {
-                    stream.close();
-                }
-            } catch (IOException e) {
-                // Ignore
-            }
-        }
-    }
-
-    /**
-     * Returns the version of the ERI file
-     *
-     */
-    public int getEriFileVersion() {
-        return mEriFile.mVersionNumber;
-    }
-
-    /**
-     * Returns the number of ERI entries parsed
-     *
-     */
-    public int getEriNumberOfEntries() {
-        return mEriFile.mNumberOfEriEntries;
-    }
-
-    /**
-     * Returns the ERI file type value ( 0 for Phase 0, 1 for Phase 1)
-     *
-     */
-    public int getEriFileType() {
-        return mEriFile.mEriFileType;
-    }
-
-    /**
-     * Returns if the ERI file has been loaded
-     *
-     */
-    public boolean isEriFileLoaded() {
-        return isEriFileLoaded;
-    }
-
-    /**
-     * Returns the EriInfo record associated with roamingIndicator
-     * or null if the entry is not found
-     */
-    private EriInfo getEriInfo(int roamingIndicator) {
-        if (mEriFile.mRoamIndTable.containsKey(roamingIndicator)) {
-            return mEriFile.mRoamIndTable.get(roamingIndicator);
-        } else {
-            return null;
-        }
-    }
-
-    private EriDisplayInformation getEriDisplayInformation(int roamInd, int defRoamInd){
-        EriDisplayInformation ret;
-
-        // Carrier can use eri.xml to customize any built-in roaming display indications
-        if (isEriFileLoaded) {
-            EriInfo eriInfo = getEriInfo(roamInd);
-            if (eriInfo != null) {
-                if (VDBG) Log.v(LOG_TAG, "ERI roamInd " + roamInd + " found in ERI file");
-                ret = new EriDisplayInformation(
-                        eriInfo.mIconIndex,
-                        eriInfo.mIconMode,
-                        eriInfo.mEriText);
-                return ret;
-            }
-        }
-
-        switch (roamInd) {
-        // Handling the standard roaming indicator (non-ERI)
-        case EriInfo.ROAMING_INDICATOR_ON:
-            ret = new EriDisplayInformation(
-                    EriInfo.ROAMING_INDICATOR_ON,
-                    EriInfo.ROAMING_ICON_MODE_NORMAL,
-                    mContext.getText(com.android.internal.R.string.roamingText0).toString());
-            break;
-
-        case EriInfo.ROAMING_INDICATOR_OFF:
-            ret = new EriDisplayInformation(
-                    EriInfo.ROAMING_INDICATOR_OFF,
-                    EriInfo.ROAMING_ICON_MODE_NORMAL,
-                    mContext.getText(com.android.internal.R.string.roamingText1).toString());
-            break;
-
-        case EriInfo.ROAMING_INDICATOR_FLASH:
-            ret = new EriDisplayInformation(
-                    EriInfo.ROAMING_INDICATOR_FLASH,
-                    EriInfo.ROAMING_ICON_MODE_FLASH,
-                    mContext.getText(com.android.internal.R.string.roamingText2).toString());
-            break;
-
-
-        // Handling the standard ERI
-        case 3:
-            ret = new EriDisplayInformation(
-                    roamInd,
-                    EriInfo.ROAMING_ICON_MODE_NORMAL,
-                    mContext.getText(com.android.internal.R.string.roamingText3).toString());
-            break;
-
-        case 4:
-            ret = new EriDisplayInformation(
-                    roamInd,
-                    EriInfo.ROAMING_ICON_MODE_NORMAL,
-                    mContext.getText(com.android.internal.R.string.roamingText4).toString());
-            break;
-
-        case 5:
-            ret = new EriDisplayInformation(
-                    roamInd,
-                    EriInfo.ROAMING_ICON_MODE_NORMAL,
-                    mContext.getText(com.android.internal.R.string.roamingText5).toString());
-            break;
-
-        case 6:
-            ret = new EriDisplayInformation(
-                    roamInd,
-                    EriInfo.ROAMING_ICON_MODE_NORMAL,
-                    mContext.getText(com.android.internal.R.string.roamingText6).toString());
-            break;
-
-        case 7:
-            ret = new EriDisplayInformation(
-                    roamInd,
-                    EriInfo.ROAMING_ICON_MODE_NORMAL,
-                    mContext.getText(com.android.internal.R.string.roamingText7).toString());
-            break;
-
-        case 8:
-            ret = new EriDisplayInformation(
-                    roamInd,
-                    EriInfo.ROAMING_ICON_MODE_NORMAL,
-                    mContext.getText(com.android.internal.R.string.roamingText8).toString());
-            break;
-
-        case 9:
-            ret = new EriDisplayInformation(
-                    roamInd,
-                    EriInfo.ROAMING_ICON_MODE_NORMAL,
-                    mContext.getText(com.android.internal.R.string.roamingText9).toString());
-            break;
-
-        case 10:
-            ret = new EriDisplayInformation(
-                    roamInd,
-                    EriInfo.ROAMING_ICON_MODE_NORMAL,
-                    mContext.getText(com.android.internal.R.string.roamingText10).toString());
-            break;
-
-        case 11:
-            ret = new EriDisplayInformation(
-                    roamInd,
-                    EriInfo.ROAMING_ICON_MODE_NORMAL,
-                    mContext.getText(com.android.internal.R.string.roamingText11).toString());
-            break;
-
-        case 12:
-            ret = new EriDisplayInformation(
-                    roamInd,
-                    EriInfo.ROAMING_ICON_MODE_NORMAL,
-                    mContext.getText(com.android.internal.R.string.roamingText12).toString());
-            break;
-
-        // Handling the non standard Enhanced Roaming Indicator (roamInd > 63)
-        default:
-            if (!isEriFileLoaded) {
-                // ERI file NOT loaded
-                if (DBG) Log.d(LOG_TAG, "ERI File not loaded");
-                if(defRoamInd > 2) {
-                    if (VDBG) Log.v(LOG_TAG, "ERI defRoamInd > 2 ...flashing");
-                    ret = new EriDisplayInformation(
-                            EriInfo.ROAMING_INDICATOR_FLASH,
-                            EriInfo.ROAMING_ICON_MODE_FLASH,
-                            mContext.getText(com.android.internal
-                                                            .R.string.roamingText2).toString());
-                } else {
-                    if (VDBG) Log.v(LOG_TAG, "ERI defRoamInd <= 2");
-                    switch (defRoamInd) {
-                    case EriInfo.ROAMING_INDICATOR_ON:
-                        ret = new EriDisplayInformation(
-                                EriInfo.ROAMING_INDICATOR_ON,
-                                EriInfo.ROAMING_ICON_MODE_NORMAL,
-                                mContext.getText(com.android.internal
-                                                            .R.string.roamingText0).toString());
-                        break;
-
-                    case EriInfo.ROAMING_INDICATOR_OFF:
-                        ret = new EriDisplayInformation(
-                                EriInfo.ROAMING_INDICATOR_OFF,
-                                EriInfo.ROAMING_ICON_MODE_NORMAL,
-                                mContext.getText(com.android.internal
-                                                            .R.string.roamingText1).toString());
-                        break;
-
-                    case EriInfo.ROAMING_INDICATOR_FLASH:
-                        ret = new EriDisplayInformation(
-                                EriInfo.ROAMING_INDICATOR_FLASH,
-                                EriInfo.ROAMING_ICON_MODE_FLASH,
-                                mContext.getText(com.android.internal
-                                                            .R.string.roamingText2).toString());
-                        break;
-
-                    default:
-                        ret = new EriDisplayInformation(-1, -1, "ERI text");
-                    }
-                }
-            } else {
-                // ERI file loaded
-                EriInfo eriInfo = getEriInfo(roamInd);
-                EriInfo defEriInfo = getEriInfo(defRoamInd);
-                if (eriInfo == null) {
-                    if (VDBG) {
-                        Log.v(LOG_TAG, "ERI roamInd " + roamInd
-                            + " not found in ERI file ...using defRoamInd " + defRoamInd);
-                    }
-                    if(defEriInfo == null) {
-                        Log.e(LOG_TAG, "ERI defRoamInd " + defRoamInd
-                                + " not found in ERI file ...on");
-                        ret = new EriDisplayInformation(
-                                EriInfo.ROAMING_INDICATOR_ON,
-                                EriInfo.ROAMING_ICON_MODE_NORMAL,
-                                mContext.getText(com.android.internal
-                                                             .R.string.roamingText0).toString());
-
-                    } else {
-                        if (VDBG) {
-                            Log.v(LOG_TAG, "ERI defRoamInd " + defRoamInd + " found in ERI file");
-                        }
-                        ret = new EriDisplayInformation(
-                                defEriInfo.mIconIndex,
-                                defEriInfo.mIconMode,
-                                defEriInfo.mEriText);
-                    }
-                } else {
-                    if (VDBG) Log.v(LOG_TAG, "ERI roamInd " + roamInd + " found in ERI file");
-                    ret = new EriDisplayInformation(
-                            eriInfo.mIconIndex,
-                            eriInfo.mIconMode,
-                            eriInfo.mEriText);
-                }
-            }
-            break;
-        }
-        if (VDBG) Log.v(LOG_TAG, "Displaying ERI " + ret.toString());
-        return ret;
-    }
-
-    public int getCdmaEriIconIndex(int roamInd, int defRoamInd){
-        return getEriDisplayInformation(roamInd, defRoamInd).mEriIconIndex;
-    }
-
-    public int getCdmaEriIconMode(int roamInd, int defRoamInd){
-        return getEriDisplayInformation(roamInd, defRoamInd).mEriIconMode;
-    }
-
-    public String getCdmaEriText(int roamInd, int defRoamInd){
-        return getEriDisplayInformation(roamInd, defRoamInd).mEriIconText;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java b/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java
deleted file mode 100644
index f440935..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.internal.telephony.cdma;
-
-import android.os.*;
-import android.util.Log;
-
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccConstants;
-import com.android.internal.telephony.IccException;
-import com.android.internal.telephony.IccFileHandler;
-import com.android.internal.telephony.IccFileTypeMismatch;
-import com.android.internal.telephony.IccIoResult;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.PhoneProxy;
-
-import java.util.ArrayList;
-
-/**
- * {@hide}
- */
-public final class RuimFileHandler extends IccFileHandler {
-    static final String LOG_TAG = "CDMA";
-
-    //***** Instance Variables
-
-    //***** Constructor
-    public RuimFileHandler(IccCard card, String aid, CommandsInterface ci) {
-        super(card, aid, ci);
-    }
-
-    protected void finalize() {
-        Log.d(LOG_TAG, "RuimFileHandler finalized");
-    }
-
-    //***** Overridden from IccFileHandler
-
-    @Override
-    public void loadEFImgTransparent(int fileid, int highOffset, int lowOffset,
-            int length, Message onLoaded) {
-        Message response = obtainMessage(EVENT_READ_ICON_DONE, fileid, 0,
-                onLoaded);
-
-        mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, "img", 0, 0,
-                GET_RESPONSE_EF_IMG_SIZE_BYTES, null, null,
-                mAid, response);
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-
-        super.handleMessage(msg);
-    }
-
-    protected String getEFPath(int efid) {
-        switch(efid) {
-        case EF_SMS:
-        case EF_CST:
-        case EF_RUIM_SPN:
-            return MF_SIM + DF_CDMA;
-        }
-        return getCommonIccEFPath(efid);
-    }
-
-    protected void logd(String msg) {
-        Log.d(LOG_TAG, "[RuimFileHandler] " + msg);
-    }
-
-    protected void loge(String msg) {
-        Log.e(LOG_TAG, "[RuimFileHandler] " + msg);
-    }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java
deleted file mode 100644
index 04ee2dd8..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-** Copyright 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.internal.telephony.cdma;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import android.os.Message;
-import android.util.Log;
-
-import com.android.internal.telephony.IccPhoneBookInterfaceManager;
-
-/**
- * RuimPhoneBookInterfaceManager to provide an inter-process communication to
- * access ADN-like SIM records.
- */
-
-
-public class RuimPhoneBookInterfaceManager extends IccPhoneBookInterfaceManager {
-    static final String LOG_TAG = "CDMA";
-
-    public RuimPhoneBookInterfaceManager(CDMAPhone phone) {
-        super(phone);
-        adnCache = phone.mIccRecords.getAdnCache();
-        //NOTE service "simphonebook" added by IccSmsInterfaceManagerProxy
-    }
-
-    public void dispose() {
-        super.dispose();
-    }
-
-    protected void finalize() {
-        try {
-            super.finalize();
-        } catch (Throwable throwable) {
-            Log.e(LOG_TAG, "Error while finalizing:", throwable);
-        }
-        if(DBG) Log.d(LOG_TAG, "RuimPhoneBookInterfaceManager finalized");
-    }
-
-    public int[] getAdnRecordsSize(int efid) {
-        if (DBG) logd("getAdnRecordsSize: efid=" + efid);
-        synchronized(mLock) {
-            checkThread();
-            recordSize = new int[3];
-
-            //Using mBaseHandler, no difference in EVENT_GET_SIZE_DONE handling
-            AtomicBoolean status = new AtomicBoolean(false);
-            Message response = mBaseHandler.obtainMessage(EVENT_GET_SIZE_DONE, status);
-
-            phone.getIccFileHandler().getEFLinearRecordSize(efid, response);
-            waitForResult(status);
-        }
-
-        return recordSize;
-    }
-
-    protected void logd(String msg) {
-        Log.d(LOG_TAG, "[RuimPbInterfaceManager] " + msg);
-    }
-
-    protected void loge(String msg) {
-        Log.e(LOG_TAG, "[RuimPbInterfaceManager] " + msg);
-    }
-}
-
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
deleted file mode 100755
index 2fefa3f..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * 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.internal.telephony.cdma;
-
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
-import android.content.Context;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Registrant;
-import android.os.SystemProperties;
-import android.util.Log;
-
-import com.android.internal.telephony.AdnRecord;
-import com.android.internal.telephony.AdnRecordCache;
-import com.android.internal.telephony.AdnRecordLoader;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.IccRefreshResponse;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.telephony.MccTable;
-
-// can't be used since VoiceMailConstants is not public
-//import com.android.internal.telephony.gsm.VoiceMailConstants;
-import com.android.internal.telephony.IccException;
-import com.android.internal.telephony.IccRecords;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.PhoneProxy;
-
-
-/**
- * {@hide}
- */
-public final class RuimRecords extends IccRecords {
-    static final String LOG_TAG = "CDMA";
-
-    private static final boolean DBG = true;
-    private boolean  m_ota_commited=false;
-
-    // ***** Instance Variables
-
-    private String mImsi;
-    private String mMyMobileNumber;
-    private String mMin2Min1;
-
-    private String mPrlVersion;
-
-    // ***** Event Constants
-
-    private static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 2;
-    private static final int EVENT_GET_IMSI_DONE = 3;
-    private static final int EVENT_GET_DEVICE_IDENTITY_DONE = 4;
-    private static final int EVENT_GET_ICCID_DONE = 5;
-    private static final int EVENT_GET_CDMA_SUBSCRIPTION_DONE = 10;
-    private static final int EVENT_UPDATE_DONE = 14;
-    private static final int EVENT_GET_SST_DONE = 17;
-    private static final int EVENT_GET_ALL_SMS_DONE = 18;
-    private static final int EVENT_MARK_SMS_READ_DONE = 19;
-
-    private static final int EVENT_SMS_ON_RUIM = 21;
-    private static final int EVENT_GET_SMS_DONE = 22;
-
-    private static final int EVENT_RUIM_REFRESH = 31;
-
-
-    public RuimRecords(IccCard card, Context c, CommandsInterface ci) {
-        super(card, c, ci);
-
-        adnCache = new AdnRecordCache(mFh);
-
-        recordsRequested = false;  // No load request is made till SIM ready
-
-        // recordsToLoad is set to 0 because no requests are made yet
-        recordsToLoad = 0;
-
-        mCi.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
-        // NOTE the EVENT_SMS_ON_RUIM is not registered
-        mCi.registerForIccRefresh(this, EVENT_RUIM_REFRESH, null);
-
-        // Start off by setting empty state
-        onRadioOffOrNotAvailable();
-
-    }
-
-    @Override
-    public void dispose() {
-        if (DBG) log("Disposing RuimRecords " + this);
-        //Unregister for all events
-        mCi.unregisterForOffOrNotAvailable( this);
-        mCi.unregisterForIccRefresh(this);
-        super.dispose();
-    }
-
-    @Override
-    protected void finalize() {
-        if(DBG) log("RuimRecords finalized");
-    }
-
-    @Override
-    protected void onRadioOffOrNotAvailable() {
-        countVoiceMessages = 0;
-        mncLength = UNINITIALIZED;
-        iccid = null;
-
-        adnCache.reset();
-
-        // Don't clean up PROPERTY_ICC_OPERATOR_ISO_COUNTRY and
-        // PROPERTY_ICC_OPERATOR_NUMERIC here. Since not all CDMA
-        // devices have RUIM, these properties should keep the original
-        // values, e.g. build time settings, when there is no RUIM but
-        // set new values when RUIM is available and loaded.
-
-        // recordsRequested is set to false indicating that the SIM
-        // read requests made so far are not valid. This is set to
-        // true only when fresh set of read requests are made.
-        recordsRequested = false;
-    }
-
-    public String getMdnNumber() {
-        return mMyMobileNumber;
-    }
-
-    public String getCdmaMin() {
-         return mMin2Min1;
-    }
-
-    /** Returns null if RUIM is not yet ready */
-    public String getPrlVersion() {
-        return mPrlVersion;
-    }
-
-    @Override
-    public void setVoiceMailNumber(String alphaTag, String voiceNumber, Message onComplete){
-        // In CDMA this is Operator/OEM dependent
-        AsyncResult.forMessage((onComplete)).exception =
-                new IccException("setVoiceMailNumber not implemented");
-        onComplete.sendToTarget();
-        loge("method setVoiceMailNumber is not implemented");
-    }
-
-    /**
-     * Called by CCAT Service when REFRESH is received.
-     * @param fileChanged indicates whether any files changed
-     * @param fileList if non-null, a list of EF files that changed
-     */
-    @Override
-    public void onRefresh(boolean fileChanged, int[] fileList) {
-        if (fileChanged) {
-            // A future optimization would be to inspect fileList and
-            // only reload those files that we care about.  For now,
-            // just re-fetch all RUIM records that we cache.
-            fetchRuimRecords();
-        }
-    }
-
-    /**
-     * Returns the 5 or 6 digit MCC/MNC of the operator that
-     *  provided the RUIM card. Returns null of RUIM is not yet ready
-     */
-    public String getRUIMOperatorNumeric() {
-        if (mImsi == null) {
-            return null;
-        }
-
-        if (mncLength != UNINITIALIZED && mncLength != UNKNOWN) {
-            // Length = length of MCC + length of MNC
-            // length of mcc = 3 (3GPP2 C.S0005 - Section 2.3)
-            return mImsi.substring(0, 3 + mncLength);
-        }
-
-        // Guess the MNC length based on the MCC if we don't
-        // have a valid value in ef[ad]
-
-        int mcc = Integer.parseInt(mImsi.substring(0,3));
-        return mImsi.substring(0, 3 + MccTable.smallestDigitsMccForMnc(mcc));
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-        AsyncResult ar;
-
-        byte data[];
-
-        boolean isRecordLoadResponse = false;
-
-        if (mDestroyed) {
-            loge("Received message " + msg +
-                    "[" + msg.what + "] while being destroyed. Ignoring.");
-            return;
-        }
-
-        try { switch (msg.what) {
-            case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
-                onRadioOffOrNotAvailable();
-            break;
-
-            case EVENT_GET_DEVICE_IDENTITY_DONE:
-                log("Event EVENT_GET_DEVICE_IDENTITY_DONE Received");
-            break;
-
-            /* IO events */
-            case EVENT_GET_IMSI_DONE:
-                isRecordLoadResponse = true;
-
-                ar = (AsyncResult)msg.obj;
-                if (ar.exception != null) {
-                    loge("Exception querying IMSI, Exception:" + ar.exception);
-                    break;
-                }
-
-                mImsi = (String) ar.result;
-
-                // IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more
-                // than 15 (and usually 15).
-                if (mImsi != null && (mImsi.length() < 6 || mImsi.length() > 15)) {
-                    loge("invalid IMSI " + mImsi);
-                    mImsi = null;
-                }
-
-                log("IMSI: " + mImsi.substring(0, 6) + "xxxxxxxxx");
-
-                String operatorNumeric = getRUIMOperatorNumeric();
-                if (operatorNumeric != null) {
-                    if(operatorNumeric.length() <= 6){
-                        MccTable.updateMccMncConfiguration(mContext, operatorNumeric);
-                    }
-                }
-            break;
-
-            case EVENT_GET_CDMA_SUBSCRIPTION_DONE:
-                ar = (AsyncResult)msg.obj;
-                String localTemp[] = (String[])ar.result;
-                if (ar.exception != null) {
-                    break;
-                }
-
-                mMyMobileNumber = localTemp[0];
-                mMin2Min1 = localTemp[3];
-                mPrlVersion = localTemp[4];
-
-                log("MDN: " + mMyMobileNumber + " MIN: " + mMin2Min1);
-
-            break;
-
-            case EVENT_GET_ICCID_DONE:
-                isRecordLoadResponse = true;
-
-                ar = (AsyncResult)msg.obj;
-                data = (byte[])ar.result;
-
-                if (ar.exception != null) {
-                    break;
-                }
-
-                iccid = IccUtils.bcdToString(data, 0, data.length);
-
-                log("iccid: " + iccid);
-
-            break;
-
-            case EVENT_UPDATE_DONE:
-                ar = (AsyncResult)msg.obj;
-                if (ar.exception != null) {
-                    Log.i(LOG_TAG, "RuimRecords update failed", ar.exception);
-                }
-            break;
-
-            case EVENT_GET_ALL_SMS_DONE:
-            case EVENT_MARK_SMS_READ_DONE:
-            case EVENT_SMS_ON_RUIM:
-            case EVENT_GET_SMS_DONE:
-                Log.w(LOG_TAG, "Event not supported: " + msg.what);
-                break;
-
-            // TODO: probably EF_CST should be read instead
-            case EVENT_GET_SST_DONE:
-                log("Event EVENT_GET_SST_DONE Received");
-            break;
-
-            case EVENT_RUIM_REFRESH:
-                isRecordLoadResponse = false;
-                ar = (AsyncResult)msg.obj;
-                if (ar.exception == null) {
-                    handleRuimRefresh((IccRefreshResponse)ar.result);
-                }
-                break;
-
-        }}catch (RuntimeException exc) {
-            // I don't want these exceptions to be fatal
-            Log.w(LOG_TAG, "Exception parsing RUIM record", exc);
-        } finally {
-            // Count up record load responses even if they are fails
-            if (isRecordLoadResponse) {
-                onRecordLoaded();
-            }
-        }
-    }
-
-    @Override
-    protected void onRecordLoaded() {
-        // One record loaded successfully or failed, In either case
-        // we need to update the recordsToLoad count
-        recordsToLoad -= 1;
-        if (DBG) log("RuimRecords:onRecordLoaded " + recordsToLoad + " requested: " + recordsRequested);
-
-        if (recordsToLoad == 0 && recordsRequested == true) {
-            onAllRecordsLoaded();
-        } else if (recordsToLoad < 0) {
-            loge("RuimRecords: recordsToLoad <0, programmer error suspected");
-            recordsToLoad = 0;
-        }
-    }
-
-    @Override
-    protected void onAllRecordsLoaded() {
-        // Further records that can be inserted are Operator/OEM dependent
-
-        String operator = getRUIMOperatorNumeric();
-        log("RuimRecords: onAllRecordsLoaded set 'gsm.sim.operator.numeric' to operator='" +
-                operator + "'");
-        SystemProperties.set(PROPERTY_ICC_OPERATOR_NUMERIC, operator);
-
-        if (mImsi != null) {
-            SystemProperties.set(PROPERTY_ICC_OPERATOR_ISO_COUNTRY,
-                    MccTable.countryCodeForMcc(Integer.parseInt(mImsi.substring(0,3))));
-        }
-        recordsLoadedRegistrants.notifyRegistrants(
-            new AsyncResult(null, null, null));
-        mParentCard.broadcastIccStateChangedIntent(
-                IccCard.INTENT_VALUE_ICC_LOADED, null);
-    }
-
-    @Override
-    public void onReady() {
-        /* broadcast intent ICC_READY here so that we can make sure
-          READY is sent before IMSI ready
-        */
-
-        mParentCard.broadcastIccStateChangedIntent(
-                IccCard.INTENT_VALUE_ICC_READY, null);
-
-        fetchRuimRecords();
-
-        mCi.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE));
-    }
-
-
-    private void fetchRuimRecords() {
-        recordsRequested = true;
-
-        Log.v(LOG_TAG, "RuimRecords:fetchRuimRecords " + recordsToLoad);
-
-        mCi.getIMSI(obtainMessage(EVENT_GET_IMSI_DONE));
-        recordsToLoad++;
-
-        mFh.loadEFTransparent(EF_ICCID,
-                obtainMessage(EVENT_GET_ICCID_DONE));
-        recordsToLoad++;
-
-        log("RuimRecords:fetchRuimRecords " + recordsToLoad + " requested: " + recordsRequested);
-        // Further records that can be inserted are Operator/OEM dependent
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * No Display rule for RUIMs yet.
-     */
-    @Override
-    public int getDisplayRule(String plmn) {
-        // TODO together with spn
-        return 0;
-    }
-
-    @Override
-    public void setVoiceMessageWaiting(int line, int countWaiting) {
-        if (line != 1) {
-            // only profile 1 is supported
-            return;
-        }
-
-        // range check
-        if (countWaiting < 0) {
-            countWaiting = -1;
-        } else if (countWaiting > 0xff) {
-            // C.S0015-B v2, 4.5.12
-            // range: 0-99
-            countWaiting = 0xff;
-        }
-        countVoiceMessages = countWaiting;
-
-        mRecordsEventsRegistrants.notifyResult(EVENT_MWI);
-    }
-
-    private void handleRuimRefresh(IccRefreshResponse refreshResponse) {
-        if (refreshResponse == null) {
-            if (DBG) log("handleRuimRefresh received without input");
-            return;
-        }
-
-        if (refreshResponse.aid != null &&
-                !refreshResponse.aid.equals(mParentCard.getAid())) {
-            // This is for different app. Ignore.
-            return;
-        }
-
-        switch (refreshResponse.refreshResult) {
-            case IccRefreshResponse.REFRESH_RESULT_FILE_UPDATE:
-                if (DBG) log("handleRuimRefresh with SIM_REFRESH_FILE_UPDATED");
-                adnCache.reset();
-                fetchRuimRecords();
-                break;
-            case IccRefreshResponse.REFRESH_RESULT_INIT:
-                if (DBG) log("handleRuimRefresh with SIM_REFRESH_INIT");
-                // need to reload all files (that we care about)
-                fetchRuimRecords();
-                break;
-            case IccRefreshResponse.REFRESH_RESULT_RESET:
-                if (DBG) log("handleRuimRefresh with SIM_REFRESH_RESET");
-                mCi.setRadioPower(false, null);
-                /* Note: no need to call setRadioPower(true).  Assuming the desired
-                * radio power state is still ON (as tracked by ServiceStateTracker),
-                * ServiceStateTracker will call setRadioPower when it receives the
-                * RADIO_STATE_CHANGED notification for the power off.  And if the
-                * desired power state has changed in the interim, we don't want to
-                * override it with an unconditional power on.
-                */
-                break;
-            default:
-                // unknown refresh operation
-                if (DBG) log("handleRuimRefresh with unknown operation");
-                break;
-        }
-    }
-
-    @Override
-    protected void log(String s) {
-        Log.d(LOG_TAG, "[RuimRecords] " + s);
-    }
-
-    @Override
-    protected void loge(String s) {
-        Log.e(LOG_TAG, "[RuimRecords] " + s);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java
deleted file mode 100644
index 9cd059d..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * 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.internal.telephony.cdma;
-
-import android.content.Context;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-
-import com.android.internal.telephony.IccConstants;
-import com.android.internal.telephony.IccSmsInterfaceManager;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.PhoneProxy;
-import com.android.internal.telephony.SMSDispatcher;
-import com.android.internal.telephony.SmsRawData;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import static android.telephony.SmsManager.STATUS_ON_ICC_FREE;
-
-/**
- * RuimSmsInterfaceManager to provide an inter-process communication to
- * access Sms in Ruim.
- */
-public class RuimSmsInterfaceManager extends IccSmsInterfaceManager {
-    static final String LOG_TAG = "CDMA";
-    static final boolean DBG = true;
-
-    private final Object mLock = new Object();
-    private boolean mSuccess;
-    private List<SmsRawData> mSms;
-
-    private static final int EVENT_LOAD_DONE = 1;
-    private static final int EVENT_UPDATE_DONE = 2;
-
-    Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            AsyncResult ar;
-
-            switch (msg.what) {
-                case EVENT_UPDATE_DONE:
-                    ar = (AsyncResult) msg.obj;
-                    synchronized (mLock) {
-                        mSuccess = (ar.exception == null);
-                        mLock.notifyAll();
-                    }
-                    break;
-                case EVENT_LOAD_DONE:
-                    ar = (AsyncResult)msg.obj;
-                    synchronized (mLock) {
-                        if (ar.exception == null) {
-                            mSms = buildValidRawData((ArrayList<byte[]>) ar.result);
-                        } else {
-                            if(DBG) log("Cannot load Sms records");
-                            if (mSms != null)
-                                mSms.clear();
-                        }
-                        mLock.notifyAll();
-                    }
-                    break;
-            }
-        }
-    };
-
-    public RuimSmsInterfaceManager(CDMAPhone phone, SMSDispatcher dispatcher) {
-        super(phone);
-        mDispatcher = dispatcher;
-    }
-
-    public void dispose() {
-    }
-
-    protected void finalize() {
-        try {
-            super.finalize();
-        } catch (Throwable throwable) {
-            Log.e(LOG_TAG, "Error while finalizing:", throwable);
-        }
-        if(DBG) Log.d(LOG_TAG, "RuimSmsInterfaceManager finalized");
-    }
-
-    /**
-     * Update the specified message on the RUIM.
-     *
-     * @param index record index of message to update
-     * @param status new message status (STATUS_ON_ICC_READ,
-     *                  STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT,
-     *                  STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE)
-     * @param pdu the raw PDU to store
-     * @return success or not
-     *
-     */
-    public boolean
-    updateMessageOnIccEf(int index, int status, byte[] pdu) {
-        if (DBG) log("updateMessageOnIccEf: index=" + index +
-                " status=" + status + " ==> " +
-                "("+ pdu + ")");
-        enforceReceiveAndSend("Updating message on RUIM");
-        synchronized(mLock) {
-            mSuccess = false;
-            Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
-
-            if (status == STATUS_ON_ICC_FREE) {
-                // Special case FREE: call deleteSmsOnRuim instead of
-                // manipulating the RUIM record
-                mPhone.mCM.deleteSmsOnRuim(index, response);
-            } else {
-                byte[] record = makeSmsRecordData(status, pdu);
-                mPhone.getIccFileHandler().updateEFLinearFixed(
-                        IccConstants.EF_SMS, index, record, null, response);
-            }
-            try {
-                mLock.wait();
-            } catch (InterruptedException e) {
-                log("interrupted while trying to update by index");
-            }
-        }
-        return mSuccess;
-    }
-
-    /**
-     * Copy a raw SMS PDU to the RUIM.
-     *
-     * @param pdu the raw PDU to store
-     * @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD,
-     *               STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT)
-     * @return success or not
-     *
-     */
-    public boolean copyMessageToIccEf(int status, byte[] pdu, byte[] smsc) {
-        //NOTE smsc not used in RUIM
-        if (DBG) log("copyMessageToIccEf: status=" + status + " ==> " +
-                "pdu=("+ Arrays.toString(pdu) + ")");
-        enforceReceiveAndSend("Copying message to RUIM");
-        synchronized(mLock) {
-            mSuccess = false;
-            Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
-
-            mPhone.mCM.writeSmsToRuim(status, IccUtils.bytesToHexString(pdu),
-                    response);
-
-            try {
-                mLock.wait();
-            } catch (InterruptedException e) {
-                log("interrupted while trying to update by index");
-            }
-        }
-        return mSuccess;
-    }
-
-    /**
-     * Retrieves all messages currently stored on RUIM.
-     */
-    public List<SmsRawData> getAllMessagesFromIccEf() {
-        if (DBG) log("getAllMessagesFromEF");
-
-        Context context = mPhone.getContext();
-
-        context.enforceCallingPermission(
-                "android.permission.RECEIVE_SMS",
-                "Reading messages from RUIM");
-        synchronized(mLock) {
-            Message response = mHandler.obtainMessage(EVENT_LOAD_DONE);
-            mPhone.getIccFileHandler().loadEFLinearFixedAll(IccConstants.EF_SMS, response);
-
-            try {
-                mLock.wait();
-            } catch (InterruptedException e) {
-                log("interrupted while trying to load from the RUIM");
-            }
-        }
-        return mSms;
-    }
-
-    public boolean enableCellBroadcast(int messageIdentifier) {
-        // Not implemented
-        Log.e(LOG_TAG, "Error! Not implemented for CDMA.");
-        return false;
-    }
-
-    public boolean disableCellBroadcast(int messageIdentifier) {
-        // Not implemented
-        Log.e(LOG_TAG, "Error! Not implemented for CDMA.");
-        return false;
-    }
-
-    public boolean enableCellBroadcastRange(int startMessageId, int endMessageId) {
-        // Not implemented
-        Log.e(LOG_TAG, "Error! Not implemented for CDMA.");
-        return false;
-    }
-
-    public boolean disableCellBroadcastRange(int startMessageId, int endMessageId) {
-        // Not implemented
-        Log.e(LOG_TAG, "Error! Not implemented for CDMA.");
-        return false;
-    }
-
-    protected void log(String msg) {
-        Log.d(LOG_TAG, "[RuimSmsInterfaceManager] " + msg);
-    }
-}
-
diff --git a/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java b/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java
deleted file mode 100644
index a149e72..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java
+++ /dev/null
@@ -1,294 +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.
- */
-
-package com.android.internal.telephony.cdma;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import android.util.Log;
-import android.media.ToneGenerator;
-
-public class SignalToneUtil {
-    /** A marker that isn't a valid TONE */
-    public static final int CDMA_INVALID_TONE = -1;
-
-    // public final int int IS95_CONST_IR_SIGNAL_TYPE_TYPE;
-    static public final int IS95_CONST_IR_SIGNAL_TONE = 0;
-    static public final int IS95_CONST_IR_SIGNAL_ISDN = 1;
-    static public final int IS95_CONST_IR_SIGNAL_IS54B = 2;
-    static public final int IS95_CONST_IR_SIGNAL_USR_DEFD_ALERT = 4;
-
-    // public final int int IS95_CONST_IR_ALERT_PITCH_TYPE;
-    static public final int IS95_CONST_IR_ALERT_MED = 0;
-    static public final int IS95_CONST_IR_ALERT_HIGH = 1;
-    static public final int IS95_CONST_IR_ALERT_LOW = 2;
-
-    // Based on 3GPP2 C.S0005-E, seciton 3.7.5.5 Signal,
-    // set TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN to 0 to avoid
-    // the alert pitch to be involved in hash calculation for
-    // signal type other than IS54B.
-    static public final int TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN = 0;
-
-    // public final int int IS95_CONST_IR_SIGNAL_TYPE;
-    static public final int IS95_CONST_IR_SIG_ISDN_NORMAL = 0;
-    static public final int IS95_CONST_IR_SIG_ISDN_INTGRP = 1;
-    static public final int IS95_CONST_IR_SIG_ISDN_SP_PRI = 2;
-    static public final int IS95_CONST_IR_SIG_ISDN_PAT_3 = 3;
-    static public final int IS95_CONST_IR_SIG_ISDN_PING = 4;
-    static public final int IS95_CONST_IR_SIG_ISDN_PAT_5 = 5;
-    static public final int IS95_CONST_IR_SIG_ISDN_PAT_6 = 6;
-    static public final int IS95_CONST_IR_SIG_ISDN_PAT_7 = 7;
-    static public final int IS95_CONST_IR_SIG_ISDN_OFF = 15;
-    static public final int IS95_CONST_IR_SIG_TONE_DIAL = 0;
-    static public final int IS95_CONST_IR_SIG_TONE_RING = 1;
-    static public final int IS95_CONST_IR_SIG_TONE_INT = 2;
-    static public final int IS95_CONST_IR_SIG_TONE_ABB_INT = 3;
-    static public final int IS95_CONST_IR_SIG_TONE_REORDER = 4;
-    static public final int IS95_CONST_IR_SIG_TONE_ABB_RE = 5;
-    static public final int IS95_CONST_IR_SIG_TONE_BUSY = 6;
-    static public final int IS95_CONST_IR_SIG_TONE_CONFIRM = 7;
-    static public final int IS95_CONST_IR_SIG_TONE_ANSWER = 8;
-    static public final int IS95_CONST_IR_SIG_TONE_CALL_W = 9;
-    static public final int IS95_CONST_IR_SIG_TONE_PIP = 10;
-    static public final int IS95_CONST_IR_SIG_TONE_NO_TONE = 63;
-    static public final int IS95_CONST_IR_SIG_IS54B_NO_TONE = 0;
-    static public final int IS95_CONST_IR_SIG_IS54B_L = 1;
-    static public final int IS95_CONST_IR_SIG_IS54B_SS = 2;
-    static public final int IS95_CONST_IR_SIG_IS54B_SSL = 3;
-    static public final int IS95_CONST_IR_SIG_IS54B_SS_2 = 4;
-    static public final int IS95_CONST_IR_SIG_IS54B_SLS = 5;
-    static public final int IS95_CONST_IR_SIG_IS54B_S_X4 = 6;
-    static public final int IS95_CONST_IR_SIG_IS54B_PBX_L = 7;
-    static public final int IS95_CONST_IR_SIG_IS54B_PBX_SS = 8;
-    static public final int IS95_CONST_IR_SIG_IS54B_PBX_SSL = 9;
-    static public final int IS95_CONST_IR_SIG_IS54B_PBX_SLS = 10;
-    static public final int IS95_CONST_IR_SIG_IS54B_PBX_S_X4 = 11;
-    static public final int IS95_CONST_IR_SIG_TONE_ABBR_ALRT = 0;
-
-    // Hashmap to map signalInfo To AudioTone
-    static private HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();
-
-    private static Integer signalParamHash(int signalType, int alertPitch, int signal) {
-        if ((signalType < 0) || (signalType > 256) || (alertPitch > 256) ||
-                (alertPitch < 0) || (signal > 256) || (signal < 0)) {
-            return new Integer(CDMA_INVALID_TONE);
-        }
-        // Based on 3GPP2 C.S0005-E, seciton 3.7.5.5 Signal,
-        // the alert pitch field is ignored by the mobile station unless
-        // SIGNAL_TYPE is '10',IS-54B Alerting.
-        // Set alert pitch to TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN
-        // so the alert pitch is not involved in hash calculation
-        // when signal type is not IS-54B.
-        if (signalType != IS95_CONST_IR_SIGNAL_IS54B) {
-            alertPitch = TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN;
-        }
-        return new Integer(signalType * 256 * 256 + alertPitch * 256 + signal);
-    }
-
-    public static int getAudioToneFromSignalInfo(int signalType, int alertPitch, int signal) {
-        Integer result = hm.get(signalParamHash(signalType, alertPitch, signal));
-        if (result == null) {
-            return CDMA_INVALID_TONE;
-        }
-        return result;
-    }
-
-    static {
-
-        /* SIGNAL_TYPE_ISDN */
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
-                IS95_CONST_IR_SIG_ISDN_NORMAL), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_NORMAL);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
-                        IS95_CONST_IR_SIG_ISDN_INTGRP),
-                        ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_INTERGROUP);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
-                IS95_CONST_IR_SIG_ISDN_SP_PRI), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_SP_PRI);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
-                IS95_CONST_IR_SIG_ISDN_PAT_3), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_PAT3);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
-                IS95_CONST_IR_SIG_ISDN_PING), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_PING_RING);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
-                IS95_CONST_IR_SIG_ISDN_PAT_5), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_PAT5);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
-                IS95_CONST_IR_SIG_ISDN_PAT_6), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_PAT6);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
-                IS95_CONST_IR_SIG_ISDN_PAT_7), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_PAT7);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
-                IS95_CONST_IR_SIG_ISDN_OFF), ToneGenerator.TONE_CDMA_SIGNAL_OFF);
-
-        /* SIGNAL_TYPE_TONE */
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
-                IS95_CONST_IR_SIG_TONE_DIAL), ToneGenerator.TONE_CDMA_DIAL_TONE_LITE);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
-                IS95_CONST_IR_SIG_TONE_RING), ToneGenerator.TONE_CDMA_NETWORK_USA_RINGBACK);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
-                IS95_CONST_IR_SIG_TONE_INT), ToneGenerator.TONE_SUP_INTERCEPT);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
-                IS95_CONST_IR_SIG_TONE_ABB_INT), ToneGenerator.TONE_SUP_INTERCEPT_ABBREV);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
-                IS95_CONST_IR_SIG_TONE_REORDER), ToneGenerator.TONE_CDMA_REORDER);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
-                IS95_CONST_IR_SIG_TONE_ABB_RE), ToneGenerator.TONE_CDMA_ABBR_REORDER);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
-                IS95_CONST_IR_SIG_TONE_BUSY), ToneGenerator.TONE_CDMA_NETWORK_BUSY);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
-                IS95_CONST_IR_SIG_TONE_CONFIRM), ToneGenerator.TONE_SUP_CONFIRM);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
-                IS95_CONST_IR_SIG_TONE_ANSWER), ToneGenerator.TONE_CDMA_ANSWER);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
-                IS95_CONST_IR_SIG_TONE_CALL_W), ToneGenerator.TONE_CDMA_NETWORK_CALLWAITING);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
-                IS95_CONST_IR_SIG_TONE_PIP), ToneGenerator.TONE_CDMA_PIP);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
-                IS95_CONST_IR_SIG_TONE_NO_TONE), ToneGenerator.TONE_CDMA_SIGNAL_OFF);
-
-        /* SIGNAL_TYPE_IS54B */
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
-                IS95_CONST_IR_SIG_IS54B_L), ToneGenerator.TONE_CDMA_HIGH_L);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
-                IS95_CONST_IR_SIG_IS54B_L), ToneGenerator.TONE_CDMA_MED_L);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
-                IS95_CONST_IR_SIG_IS54B_L), ToneGenerator.TONE_CDMA_LOW_L);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
-                IS95_CONST_IR_SIG_IS54B_SS), ToneGenerator.TONE_CDMA_HIGH_SS);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
-                IS95_CONST_IR_SIG_IS54B_SS), ToneGenerator.TONE_CDMA_MED_SS);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
-                IS95_CONST_IR_SIG_IS54B_SS), ToneGenerator.TONE_CDMA_LOW_SS);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
-                IS95_CONST_IR_SIG_IS54B_SSL), ToneGenerator.TONE_CDMA_HIGH_SSL);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
-                IS95_CONST_IR_SIG_IS54B_SSL), ToneGenerator.TONE_CDMA_MED_SSL);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
-                IS95_CONST_IR_SIG_IS54B_SSL), ToneGenerator.TONE_CDMA_LOW_SSL);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
-                IS95_CONST_IR_SIG_IS54B_SS_2), ToneGenerator.TONE_CDMA_HIGH_SS_2);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
-                IS95_CONST_IR_SIG_IS54B_SS_2), ToneGenerator.TONE_CDMA_MED_SS_2);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
-                IS95_CONST_IR_SIG_IS54B_SS_2), ToneGenerator.TONE_CDMA_LOW_SS_2);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
-                IS95_CONST_IR_SIG_IS54B_SLS), ToneGenerator.TONE_CDMA_HIGH_SLS);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
-                IS95_CONST_IR_SIG_IS54B_SLS), ToneGenerator.TONE_CDMA_MED_SLS);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
-                IS95_CONST_IR_SIG_IS54B_SLS), ToneGenerator.TONE_CDMA_LOW_SLS);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
-                IS95_CONST_IR_SIG_IS54B_S_X4), ToneGenerator.TONE_CDMA_HIGH_S_X4);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
-                IS95_CONST_IR_SIG_IS54B_S_X4), ToneGenerator.TONE_CDMA_MED_S_X4);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
-                IS95_CONST_IR_SIG_IS54B_S_X4), ToneGenerator.TONE_CDMA_LOW_S_X4);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
-                IS95_CONST_IR_SIG_IS54B_PBX_L), ToneGenerator.TONE_CDMA_HIGH_PBX_L);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
-                IS95_CONST_IR_SIG_IS54B_PBX_L), ToneGenerator.TONE_CDMA_MED_PBX_L);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
-                IS95_CONST_IR_SIG_IS54B_PBX_L), ToneGenerator.TONE_CDMA_LOW_PBX_L);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
-                IS95_CONST_IR_SIG_IS54B_PBX_SS), ToneGenerator.TONE_CDMA_HIGH_PBX_SS);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
-                IS95_CONST_IR_SIG_IS54B_PBX_SS), ToneGenerator.TONE_CDMA_MED_PBX_SS);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
-                IS95_CONST_IR_SIG_IS54B_PBX_SS), ToneGenerator.TONE_CDMA_LOW_PBX_SS);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
-                IS95_CONST_IR_SIG_IS54B_PBX_SSL), ToneGenerator.TONE_CDMA_HIGH_PBX_SSL);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
-                IS95_CONST_IR_SIG_IS54B_PBX_SSL), ToneGenerator.TONE_CDMA_MED_PBX_SSL);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
-                IS95_CONST_IR_SIG_IS54B_PBX_SSL), ToneGenerator.TONE_CDMA_LOW_PBX_SSL);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
-                IS95_CONST_IR_SIG_IS54B_PBX_SLS), ToneGenerator.TONE_CDMA_HIGH_PBX_SLS);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
-                IS95_CONST_IR_SIG_IS54B_PBX_SLS), ToneGenerator.TONE_CDMA_MED_PBX_SLS);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
-                IS95_CONST_IR_SIG_IS54B_PBX_SLS), ToneGenerator.TONE_CDMA_LOW_PBX_SLS);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
-                IS95_CONST_IR_SIG_IS54B_PBX_S_X4), ToneGenerator.TONE_CDMA_HIGH_PBX_S_X4);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
-                IS95_CONST_IR_SIG_IS54B_PBX_S_X4), ToneGenerator.TONE_CDMA_MED_PBX_S_X4);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
-                IS95_CONST_IR_SIG_IS54B_PBX_S_X4), ToneGenerator.TONE_CDMA_LOW_PBX_S_X4);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
-                IS95_CONST_IR_SIG_IS54B_NO_TONE), ToneGenerator.TONE_CDMA_SIGNAL_OFF);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_USR_DEFD_ALERT,
-                TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, IS95_CONST_IR_SIG_TONE_ABBR_ALRT),
-                ToneGenerator.TONE_CDMA_ABBR_ALERT);
-
-        hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_USR_DEFD_ALERT,
-                TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, IS95_CONST_IR_SIG_TONE_NO_TONE),
-                ToneGenerator.TONE_CDMA_ABBR_ALERT);
-
-    }
-
-    // suppress default constructor for noninstantiability
-    private SignalToneUtil() {
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
deleted file mode 100644
index 9a0ebed..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ /dev/null
@@ -1,1004 +0,0 @@
-/*
- * 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.internal.telephony.cdma;
-
-import android.os.Parcel;
-import android.os.SystemProperties;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.SmsCbLocation;
-import android.telephony.SmsCbMessage;
-import android.telephony.cdma.CdmaSmsCbProgramData;
-import android.util.Log;
-
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.SmsHeader;
-import com.android.internal.telephony.SmsMessageBase;
-import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.telephony.cdma.sms.BearerData;
-import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
-import com.android.internal.telephony.cdma.sms.CdmaSmsSubaddress;
-import com.android.internal.telephony.cdma.sms.SmsEnvelope;
-import com.android.internal.telephony.cdma.sms.UserData;
-import com.android.internal.util.BitwiseInputStream;
-import com.android.internal.util.HexDump;
-
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import static android.telephony.SmsMessage.MessageClass;
-
-/**
- * TODO(cleanup): these constants are disturbing... are they not just
- * different interpretations on one number?  And if we did not have
- * terrible class name overlap, they would not need to be directly
- * imported like this.  The class in this file could just as well be
- * named CdmaSmsMessage, could it not?
- */
-
-/**
- * TODO(cleanup): internally returning null in many places makes
- * debugging very hard (among many other reasons) and should be made
- * more meaningful (replaced with exceptions for example).  Null
- * returns should only occur at the very outside of the module/class
- * scope.
- */
-
-/**
- * A Short Message Service message.
- *
- */
-public class SmsMessage extends SmsMessageBase {
-    static final String LOG_TAG = "CDMA";
-    static private final String LOGGABLE_TAG = "CDMA:SMS";
-
-    private final static byte TELESERVICE_IDENTIFIER                    = 0x00;
-    private final static byte SERVICE_CATEGORY                          = 0x01;
-    private final static byte ORIGINATING_ADDRESS                       = 0x02;
-    private final static byte ORIGINATING_SUB_ADDRESS                   = 0x03;
-    private final static byte DESTINATION_ADDRESS                       = 0x04;
-    private final static byte DESTINATION_SUB_ADDRESS                   = 0x05;
-    private final static byte BEARER_REPLY_OPTION                       = 0x06;
-    private final static byte CAUSE_CODES                               = 0x07;
-    private final static byte BEARER_DATA                               = 0x08;
-
-    /**
-     *  Status of a previously submitted SMS.
-     *  This field applies to SMS Delivery Acknowledge messages. 0 indicates success;
-     *  Here, the error class is defined by the bits from 9-8, the status code by the bits from 7-0.
-     *  See C.S0015-B, v2.0, 4.5.21 for a detailed description of possible values.
-     */
-    private int status;
-
-    /** Specifies if a return of an acknowledgment is requested for send SMS */
-    private static final int RETURN_NO_ACK  = 0;
-    private static final int RETURN_ACK     = 1;
-
-    private SmsEnvelope mEnvelope;
-    private BearerData mBearerData;
-
-    public static class SubmitPdu extends SubmitPduBase {
-    }
-
-    /**
-     * Create an SmsMessage from a raw PDU.
-     * Note: In CDMA the PDU is just a byte representation of the received Sms.
-     */
-    public static SmsMessage createFromPdu(byte[] pdu) {
-        SmsMessage msg = new SmsMessage();
-
-        try {
-            msg.parsePdu(pdu);
-            return msg;
-        } catch (RuntimeException ex) {
-            Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
-            return null;
-        }
-    }
-
-    /**
-     *  Create a "raw" CDMA SmsMessage from a Parcel that was forged in ril.cpp.
-     *  Note: Only primitive fields are set.
-     */
-    public static SmsMessage newFromParcel(Parcel p) {
-        // Note: Parcel.readByte actually reads one Int and masks to byte
-        SmsMessage msg = new SmsMessage();
-        SmsEnvelope env = new SmsEnvelope();
-        CdmaSmsAddress addr = new CdmaSmsAddress();
-        CdmaSmsSubaddress subaddr = new CdmaSmsSubaddress();
-        byte[] data;
-        byte count;
-        int countInt;
-        int addressDigitMode;
-
-        //currently not supported by the modem-lib: env.mMessageType
-        env.teleService = p.readInt(); //p_cur->uTeleserviceID
-
-        if (0 != p.readByte()) { //p_cur->bIsServicePresent
-            env.messageType = SmsEnvelope.MESSAGE_TYPE_BROADCAST;
-        }
-        else {
-            if (SmsEnvelope.TELESERVICE_NOT_SET == env.teleService) {
-                // assume type ACK
-                env.messageType = SmsEnvelope.MESSAGE_TYPE_ACKNOWLEDGE;
-            } else {
-                env.messageType = SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT;
-            }
-        }
-        env.serviceCategory = p.readInt(); //p_cur->uServicecategory
-
-        // address
-        addressDigitMode = p.readInt();
-        addr.digitMode = (byte) (0xFF & addressDigitMode); //p_cur->sAddress.digit_mode
-        addr.numberMode = (byte) (0xFF & p.readInt()); //p_cur->sAddress.number_mode
-        addr.ton = p.readInt(); //p_cur->sAddress.number_type
-        addr.numberPlan = (byte) (0xFF & p.readInt()); //p_cur->sAddress.number_plan
-        count = p.readByte(); //p_cur->sAddress.number_of_digits
-        addr.numberOfDigits = count;
-        data = new byte[count];
-        //p_cur->sAddress.digits[digitCount]
-        for (int index=0; index < count; index++) {
-            data[index] = p.readByte();
-
-            // convert the value if it is 4-bit DTMF to 8 bit
-            if (addressDigitMode == CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF) {
-                data[index] = msg.convertDtmfToAscii(data[index]);
-            }
-        }
-
-        addr.origBytes = data;
-
-        subaddr.type = p.readInt(); // p_cur->sSubAddress.subaddressType
-        subaddr.odd = p.readByte();     // p_cur->sSubAddress.odd
-        count = p.readByte();           // p_cur->sSubAddress.number_of_digits
-
-        if (count < 0) {
-            count = 0;
-        }
-
-        // p_cur->sSubAddress.digits[digitCount] :
-
-        data = new byte[count];
-
-        for (int index = 0; index < count; ++index) {
-            data[index] = p.readByte();
-        }
-
-        subaddr.origBytes = data;
-
-        /* currently not supported by the modem-lib:
-            env.bearerReply
-            env.replySeqNo
-            env.errorClass
-            env.causeCode
-        */
-
-        // bearer data
-        countInt = p.readInt(); //p_cur->uBearerDataLen
-        if (countInt < 0) {
-            countInt = 0;
-        }
-
-        data = new byte[countInt];
-        for (int index=0; index < countInt; index++) {
-            data[index] = p.readByte();
-        }
-        // BD gets further decoded when accessed in SMSDispatcher
-        env.bearerData = data;
-
-        // link the the filled objects to the SMS
-        env.origAddress = addr;
-        env.origSubaddress = subaddr;
-        msg.originatingAddress = addr;
-        msg.mEnvelope = env;
-
-        // create byte stream representation for transportation through the layers.
-        msg.createPdu();
-
-        return msg;
-    }
-
-    /**
-     * Create an SmsMessage from an SMS EF record.
-     *
-     * @param index Index of SMS record. This should be index in ArrayList
-     *              returned by RuimSmsInterfaceManager.getAllMessagesFromIcc + 1.
-     * @param data Record data.
-     * @return An SmsMessage representing the record.
-     *
-     * @hide
-     */
-    public static SmsMessage createFromEfRecord(int index, byte[] data) {
-        try {
-            SmsMessage msg = new SmsMessage();
-
-            msg.indexOnIcc = index;
-
-            // First byte is status: RECEIVED_READ, RECEIVED_UNREAD, STORED_SENT,
-            // or STORED_UNSENT
-            // See 3GPP2 C.S0023 3.4.27
-            if ((data[0] & 1) == 0) {
-                Log.w(LOG_TAG, "SMS parsing failed: Trying to parse a free record");
-                return null;
-            } else {
-                msg.statusOnIcc = data[0] & 0x07;
-            }
-
-            // Second byte is the MSG_LEN, length of the message
-            // See 3GPP2 C.S0023 3.4.27
-            int size = data[1];
-
-            // Note: Data may include trailing FF's.  That's OK; message
-            // should still parse correctly.
-            byte[] pdu = new byte[size];
-            System.arraycopy(data, 2, pdu, 0, size);
-            // the message has to be parsed before it can be displayed
-            // see gsm.SmsMessage
-            msg.parsePduFromEfRecord(pdu);
-            return msg;
-        } catch (RuntimeException ex) {
-            Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
-            return null;
-        }
-
-    }
-
-    /**
-     * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
-     */
-    public static int getTPLayerLengthForPDU(String pdu) {
-        Log.w(LOG_TAG, "getTPLayerLengthForPDU: is not supported in CDMA mode.");
-        return 0;
-    }
-
-    /**
-     * TODO(cleanup): why do getSubmitPdu methods take an scAddr input
-     * and do nothing with it?  GSM allows us to specify a SC (eg,
-     * when responding to an SMS that explicitly requests the response
-     * is sent to a specific SC), or pass null to use the default
-     * value.  Is there no similar notion in CDMA? Or do we just not
-     * have it hooked up?
-     */
-
-    /**
-     * Get an SMS-SUBMIT PDU for a destination address and a message
-     *
-     * @param scAddr                Service Centre address.  Null means use default.
-     * @param destAddr              Address of the recipient.
-     * @param message               String representation of the message payload.
-     * @param statusReportRequested Indicates whether a report is requested for this message.
-     * @param smsHeader             Array containing the data for the User Data Header, preceded
-     *                              by the Element Identifiers.
-     * @return a <code>SubmitPdu</code> containing the encoded SC
-     *         address, if applicable, and the encoded message.
-     *         Returns null on encode error.
-     * @hide
-     */
-    public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, String message,
-            boolean statusReportRequested, SmsHeader smsHeader) {
-
-        /**
-         * TODO(cleanup): Do we really want silent failure like this?
-         * Would it not be much more reasonable to make sure we don't
-         * call this function if we really want nothing done?
-         */
-        if (message == null || destAddr == null) {
-            return null;
-        }
-
-        UserData uData = new UserData();
-        uData.payloadStr = message;
-        uData.userDataHeader = smsHeader;
-        return privateGetSubmitPdu(destAddr, statusReportRequested, uData);
-    }
-
-    /**
-     * Get an SMS-SUBMIT PDU for a data message to a destination address and port.
-     *
-     * @param scAddr Service Centre address. null == use default
-     * @param destAddr the address of the destination for the message
-     * @param destPort the port to deliver the message to at the
-     *        destination
-     * @param data the data for the message
-     * @return a <code>SubmitPdu</code> containing the encoded SC
-     *         address, if applicable, and the encoded message.
-     *         Returns null on encode error.
-     */
-    public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, int destPort,
-            byte[] data, boolean statusReportRequested) {
-
-        /**
-         * TODO(cleanup): this is not a general-purpose SMS creation
-         * method, but rather something specialized to messages
-         * containing OCTET encoded (meaning non-human-readable) user
-         * data.  The name should reflect that, and not just overload.
-         */
-
-        SmsHeader.PortAddrs portAddrs = new SmsHeader.PortAddrs();
-        portAddrs.destPort = destPort;
-        portAddrs.origPort = 0;
-        portAddrs.areEightBits = false;
-
-        SmsHeader smsHeader = new SmsHeader();
-        smsHeader.portAddrs = portAddrs;
-
-        UserData uData = new UserData();
-        uData.userDataHeader = smsHeader;
-        uData.msgEncoding = UserData.ENCODING_OCTET;
-        uData.msgEncodingSet = true;
-        uData.payload = data;
-
-        return privateGetSubmitPdu(destAddr, statusReportRequested, uData);
-    }
-
-    /**
-     * Get an SMS-SUBMIT PDU for a data message to a destination address &amp; port
-     *
-     * @param destAddr the address of the destination for the message
-     * @param userData the data for the message
-     * @param statusReportRequested Indicates whether a report is requested for this message.
-     * @return a <code>SubmitPdu</code> containing the encoded SC
-     *         address, if applicable, and the encoded message.
-     *         Returns null on encode error.
-     */
-    public static SubmitPdu getSubmitPdu(String destAddr, UserData userData,
-            boolean statusReportRequested) {
-        return privateGetSubmitPdu(destAddr, statusReportRequested, userData);
-    }
-
-    /**
-     * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
-     */
-    public int getProtocolIdentifier() {
-        Log.w(LOG_TAG, "getProtocolIdentifier: is not supported in CDMA mode.");
-        // (3GPP TS 23.040): "no interworking, but SME to SME protocol":
-        return 0;
-    }
-
-    /**
-     * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
-     */
-    public boolean isReplace() {
-        Log.w(LOG_TAG, "isReplace: is not supported in CDMA mode.");
-        return false;
-    }
-
-    /**
-     * {@inheritDoc}
-     * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
-     */
-    public boolean isCphsMwiMessage() {
-        Log.w(LOG_TAG, "isCphsMwiMessage: is not supported in CDMA mode.");
-        return false;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public boolean isMWIClearMessage() {
-        return ((mBearerData != null) && (mBearerData.numberOfMessages == 0));
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public boolean isMWISetMessage() {
-        return ((mBearerData != null) && (mBearerData.numberOfMessages > 0));
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public boolean isMwiDontStore() {
-        return ((mBearerData != null) &&
-                (mBearerData.numberOfMessages > 0) &&
-                (mBearerData.userData == null));
-    }
-
-    /**
-     * Returns the status for a previously submitted message.
-     * For not interfering with status codes from GSM, this status code is
-     * shifted to the bits 31-16.
-     */
-    public int getStatus() {
-        return (status << 16);
-    }
-
-    /** Return true iff the bearer data message type is DELIVERY_ACK. */
-    public boolean isStatusReportMessage() {
-        return (mBearerData.messageType == BearerData.MESSAGE_TYPE_DELIVERY_ACK);
-    }
-
-    /**
-     * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
-     */
-    public boolean isReplyPathPresent() {
-        Log.w(LOG_TAG, "isReplyPathPresent: is not supported in CDMA mode.");
-        return false;
-    }
-
-    /**
-     * Calculate the number of septets needed to encode the message.
-     *
-     * @param messageBody the message to encode
-     * @param use7bitOnly ignore (but still count) illegal characters if true
-     * @return TextEncodingDetails
-     */
-    public static TextEncodingDetails calculateLength(CharSequence messageBody,
-            boolean use7bitOnly) {
-        return BearerData.calcTextEncodingDetails(messageBody, use7bitOnly);
-    }
-
-    /**
-     * Returns the teleservice type of the message.
-     * @return the teleservice:
-     *  {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_NOT_SET},
-     *  {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_WMT},
-     *  {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_WEMT},
-     *  {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_VMN},
-     *  {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_WAP}
-    */
-    /* package */ int getTeleService() {
-        return mEnvelope.teleService;
-    }
-
-    /**
-     * Returns the message type of the message.
-     * @return the message type:
-     *  {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#MESSAGE_TYPE_POINT_TO_POINT},
-     *  {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#MESSAGE_TYPE_BROADCAST},
-     *  {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#MESSAGE_TYPE_ACKNOWLEDGE},
-    */
-    /* package */ int getMessageType() {
-        // NOTE: mEnvelope.messageType is not set correctly for cell broadcasts with some RILs.
-        // Use the service category parameter to detect CMAS and other cell broadcast messages.
-        if (mEnvelope.serviceCategory != 0) {
-            return SmsEnvelope.MESSAGE_TYPE_BROADCAST;
-        } else {
-            return SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT;
-        }
-    }
-
-    /**
-     * Decodes pdu to an empty SMS object.
-     * In the CDMA case the pdu is just an internal byte stream representation
-     * of the SMS Java-object.
-     * @see #createPdu()
-     */
-    private void parsePdu(byte[] pdu) {
-        ByteArrayInputStream bais = new ByteArrayInputStream(pdu);
-        DataInputStream dis = new DataInputStream(bais);
-        byte length;
-        int bearerDataLength;
-        SmsEnvelope env = new SmsEnvelope();
-        CdmaSmsAddress addr = new CdmaSmsAddress();
-
-        try {
-            env.messageType = dis.readInt();
-            env.teleService = dis.readInt();
-            env.serviceCategory = dis.readInt();
-
-            addr.digitMode = dis.readByte();
-            addr.numberMode = dis.readByte();
-            addr.ton = dis.readByte();
-            addr.numberPlan = dis.readByte();
-
-            length = dis.readByte();
-            addr.numberOfDigits = length;
-            addr.origBytes = new byte[length];
-            dis.read(addr.origBytes, 0, length); // digits
-
-            env.bearerReply = dis.readInt();
-            // CauseCode values:
-            env.replySeqNo = dis.readByte();
-            env.errorClass = dis.readByte();
-            env.causeCode = dis.readByte();
-
-            //encoded BearerData:
-            bearerDataLength = dis.readInt();
-            env.bearerData = new byte[bearerDataLength];
-            dis.read(env.bearerData, 0, bearerDataLength);
-            dis.close();
-        } catch (Exception ex) {
-            Log.e(LOG_TAG, "createFromPdu: conversion from byte array to object failed: " + ex);
-        }
-
-        // link the filled objects to this SMS
-        originatingAddress = addr;
-        env.origAddress = addr;
-        mEnvelope = env;
-        mPdu = pdu;
-
-        parseSms();
-    }
-
-    /**
-     * Decodes 3GPP2 sms stored in CSIM/RUIM cards As per 3GPP2 C.S0015-0
-     */
-    private void parsePduFromEfRecord(byte[] pdu) {
-        ByteArrayInputStream bais = new ByteArrayInputStream(pdu);
-        DataInputStream dis = new DataInputStream(bais);
-        SmsEnvelope env = new SmsEnvelope();
-        CdmaSmsAddress addr = new CdmaSmsAddress();
-        CdmaSmsSubaddress subAddr = new CdmaSmsSubaddress();
-
-        try {
-            env.messageType = dis.readByte();
-
-            while (dis.available() > 0) {
-                int parameterId = dis.readByte();
-                int parameterLen = dis.readByte();
-                byte[] parameterData = new byte[parameterLen];
-
-                switch (parameterId) {
-                    case TELESERVICE_IDENTIFIER:
-                        /*
-                         * 16 bit parameter that identifies which upper layer
-                         * service access point is sending or should receive
-                         * this message
-                         */
-                        env.teleService = dis.readUnsignedShort();
-                        Log.i(LOG_TAG, "teleservice = " + env.teleService);
-                        break;
-                    case SERVICE_CATEGORY:
-                        /*
-                         * 16 bit parameter that identifies type of service as
-                         * in 3GPP2 C.S0015-0 Table 3.4.3.2-1
-                         */
-                        env.serviceCategory = dis.readUnsignedShort();
-                        break;
-                    case ORIGINATING_ADDRESS:
-                    case DESTINATION_ADDRESS:
-                        dis.read(parameterData, 0, parameterLen);
-                        BitwiseInputStream addrBis = new BitwiseInputStream(parameterData);
-                        addr.digitMode = addrBis.read(1);
-                        addr.numberMode = addrBis.read(1);
-                        int numberType = 0;
-                        if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
-                            numberType = addrBis.read(3);
-                            addr.ton = numberType;
-
-                            if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK)
-                                addr.numberPlan = addrBis.read(4);
-                        }
-
-                        addr.numberOfDigits = addrBis.read(8);
-
-                        byte[] data = new byte[addr.numberOfDigits];
-                        byte b = 0x00;
-
-                        if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF) {
-                            /* As per 3GPP2 C.S0005-0 Table 2.7.1.3.2.4-4 */
-                            for (int index = 0; index < addr.numberOfDigits; index++) {
-                                b = (byte) (0xF & addrBis.read(4));
-                                // convert the value if it is 4-bit DTMF to 8
-                                // bit
-                                data[index] = convertDtmfToAscii(b);
-                            }
-                        } else if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
-                            if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK) {
-                                for (int index = 0; index < addr.numberOfDigits; index++) {
-                                    b = (byte) (0xFF & addrBis.read(8));
-                                    data[index] = b;
-                                }
-
-                            } else if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_DATA_NETWORK) {
-                                if (numberType == 2)
-                                    Log.e(LOG_TAG, "TODO: Originating Addr is email id");
-                                else
-                                    Log.e(LOG_TAG,
-                                          "TODO: Originating Addr is data network address");
-                            } else {
-                                Log.e(LOG_TAG, "Originating Addr is of incorrect type");
-                            }
-                        } else {
-                            Log.e(LOG_TAG, "Incorrect Digit mode");
-                        }
-                        addr.origBytes = data;
-                        Log.i(LOG_TAG, "Originating Addr=" + addr.toString());
-                        break;
-                    case ORIGINATING_SUB_ADDRESS:
-                    case DESTINATION_SUB_ADDRESS:
-                        dis.read(parameterData, 0, parameterLen);
-                        BitwiseInputStream subAddrBis = new BitwiseInputStream(parameterData);
-                        subAddr.type = subAddrBis.read(3);
-                        subAddr.odd = subAddrBis.readByteArray(1)[0];
-                        int subAddrLen = subAddrBis.read(8);
-                        byte[] subdata = new byte[subAddrLen];
-                        for (int index = 0; index < subAddrLen; index++) {
-                            b = (byte) (0xFF & subAddrBis.read(4));
-                            // convert the value if it is 4-bit DTMF to 8 bit
-                            subdata[index] = convertDtmfToAscii(b);
-                        }
-                        subAddr.origBytes = subdata;
-                        break;
-                    case BEARER_REPLY_OPTION:
-                        dis.read(parameterData, 0, parameterLen);
-                        BitwiseInputStream replyOptBis = new BitwiseInputStream(parameterData);
-                        env.bearerReply = replyOptBis.read(6);
-                        break;
-                    case CAUSE_CODES:
-                        dis.read(parameterData, 0, parameterLen);
-                        BitwiseInputStream ccBis = new BitwiseInputStream(parameterData);
-                        env.replySeqNo = ccBis.readByteArray(6)[0];
-                        env.errorClass = ccBis.readByteArray(2)[0];
-                        if (env.errorClass != 0x00)
-                            env.causeCode = ccBis.readByteArray(8)[0];
-                        break;
-                    case BEARER_DATA:
-                        dis.read(parameterData, 0, parameterLen);
-                        env.bearerData = parameterData;
-                        break;
-                    default:
-                        throw new Exception("unsupported parameterId (" + parameterId + ")");
-                }
-            }
-            bais.close();
-            dis.close();
-        } catch (Exception ex) {
-            Log.e(LOG_TAG, "parsePduFromEfRecord: conversion from pdu to SmsMessage failed" + ex);
-        }
-
-        // link the filled objects to this SMS
-        originatingAddress = addr;
-        env.origAddress = addr;
-        env.origSubaddress = subAddr;
-        mEnvelope = env;
-        mPdu = pdu;
-
-        parseSms();
-    }
-
-    /**
-     * Parses a SMS message from its BearerData stream. (mobile-terminated only)
-     */
-    protected void parseSms() {
-        // Message Waiting Info Record defined in 3GPP2 C.S-0005, 3.7.5.6
-        // It contains only an 8-bit number with the number of messages waiting
-        if (mEnvelope.teleService == SmsEnvelope.TELESERVICE_MWI) {
-            mBearerData = new BearerData();
-            if (mEnvelope.bearerData != null) {
-                mBearerData.numberOfMessages = 0x000000FF & mEnvelope.bearerData[0];
-            }
-            if (false) {
-                Log.d(LOG_TAG, "parseSms: get MWI " +
-                      Integer.toString(mBearerData.numberOfMessages));
-            }
-            return;
-        }
-        mBearerData = BearerData.decode(mEnvelope.bearerData);
-        if (Log.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) {
-            Log.d(LOG_TAG, "MT raw BearerData = '" +
-                      HexDump.toHexString(mEnvelope.bearerData) + "'");
-            Log.d(LOG_TAG, "MT (decoded) BearerData = " + mBearerData);
-        }
-        messageRef = mBearerData.messageId;
-        if (mBearerData.userData != null) {
-            userData = mBearerData.userData.payload;
-            userDataHeader = mBearerData.userData.userDataHeader;
-            messageBody = mBearerData.userData.payloadStr;
-        }
-
-        if (originatingAddress != null) {
-            originatingAddress.address = new String(originatingAddress.origBytes);
-            if (false) Log.v(LOG_TAG, "SMS originating address: "
-                    + originatingAddress.address);
-        }
-
-        if (mBearerData.msgCenterTimeStamp != null) {
-            scTimeMillis = mBearerData.msgCenterTimeStamp.toMillis(true);
-        }
-
-        if (false) Log.d(LOG_TAG, "SMS SC timestamp: " + scTimeMillis);
-
-        // Message Type (See 3GPP2 C.S0015-B, v2, 4.5.1)
-        if (mBearerData.messageType == BearerData.MESSAGE_TYPE_DELIVERY_ACK) {
-            // The BearerData MsgStatus subparameter should only be
-            // included for DELIVERY_ACK messages.  If it occurred for
-            // other messages, it would be unclear what the status
-            // being reported refers to.  The MsgStatus subparameter
-            // is primarily useful to indicate error conditions -- a
-            // message without this subparameter is assumed to
-            // indicate successful delivery (status == 0).
-            if (! mBearerData.messageStatusSet) {
-                Log.d(LOG_TAG, "DELIVERY_ACK message without msgStatus (" +
-                        (userData == null ? "also missing" : "does have") +
-                        " userData).");
-                status = 0;
-            } else {
-                status = mBearerData.errorClass << 8;
-                status |= mBearerData.messageStatus;
-            }
-        } else if (mBearerData.messageType != BearerData.MESSAGE_TYPE_DELIVER) {
-            throw new RuntimeException("Unsupported message type: " + mBearerData.messageType);
-        }
-
-        if (messageBody != null) {
-            if (false) Log.v(LOG_TAG, "SMS message body: '" + messageBody + "'");
-            parseMessageBody();
-        } else if ((userData != null) && (false)) {
-            Log.v(LOG_TAG, "SMS payload: '" + IccUtils.bytesToHexString(userData) + "'");
-        }
-    }
-
-    /**
-     * Parses a broadcast SMS, possibly containing a CMAS alert.
-     */
-    SmsCbMessage parseBroadcastSms() {
-        BearerData bData = BearerData.decode(mEnvelope.bearerData, mEnvelope.serviceCategory);
-        if (bData == null) {
-            Log.w(LOG_TAG, "BearerData.decode() returned null");
-            return null;
-        }
-
-        if (Log.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) {
-            Log.d(LOG_TAG, "MT raw BearerData = " + HexDump.toHexString(mEnvelope.bearerData));
-        }
-
-        String plmn = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC);
-        SmsCbLocation location = new SmsCbLocation(plmn);
-
-        return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP2,
-                SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE, bData.messageId, location,
-                mEnvelope.serviceCategory, bData.getLanguage(), bData.userData.payloadStr,
-                bData.priority, null, bData.cmasWarningInfo);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public MessageClass getMessageClass() {
-        if (BearerData.DISPLAY_MODE_IMMEDIATE == mBearerData.displayMode ) {
-            return MessageClass.CLASS_0;
-        } else {
-            return MessageClass.UNKNOWN;
-        }
-    }
-
-    /**
-     * Calculate the next message id, starting at 1 and iteratively
-     * incrementing within the range 1..65535 remembering the state
-     * via a persistent system property.  (See C.S0015-B, v2.0,
-     * 4.3.1.5) Since this routine is expected to be accessed via via
-     * binder-call, and hence should be thread-safe, it has been
-     * synchronized.
-     */
-    synchronized static int getNextMessageId() {
-        // Testing and dialog with partners has indicated that
-        // msgId==0 is (sometimes?) treated specially by lower levels.
-        // Specifically, the ID is not preserved for delivery ACKs.
-        // Hence, avoid 0 -- constraining the range to 1..65535.
-        int msgId = SystemProperties.getInt(TelephonyProperties.PROPERTY_CDMA_MSG_ID, 1);
-        String nextMsgId = Integer.toString((msgId % 0xFFFF) + 1);
-        SystemProperties.set(TelephonyProperties.PROPERTY_CDMA_MSG_ID, nextMsgId);
-        if (Log.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) {
-            Log.d(LOG_TAG, "next " + TelephonyProperties.PROPERTY_CDMA_MSG_ID + " = " + nextMsgId);
-            Log.d(LOG_TAG, "readback gets " +
-                    SystemProperties.get(TelephonyProperties.PROPERTY_CDMA_MSG_ID));
-        }
-        return msgId;
-    }
-
-    /**
-     * Creates BearerData and Envelope from parameters for a Submit SMS.
-     * @return byte stream for SubmitPdu.
-     */
-    private static SubmitPdu privateGetSubmitPdu(String destAddrStr, boolean statusReportRequested,
-            UserData userData) {
-
-        /**
-         * TODO(cleanup): give this function a more meaningful name.
-         */
-
-        /**
-         * TODO(cleanup): Make returning null from the getSubmitPdu
-         * variations meaningful -- clean up the error feedback
-         * mechanism, and avoid null pointer exceptions.
-         */
-
-        /**
-         * North America Plus Code :
-         * Convert + code to 011 and dial out for international SMS
-         */
-        CdmaSmsAddress destAddr = CdmaSmsAddress.parse(
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode(destAddrStr));
-        if (destAddr == null) return null;
-
-        BearerData bearerData = new BearerData();
-        bearerData.messageType = BearerData.MESSAGE_TYPE_SUBMIT;
-
-        bearerData.messageId = getNextMessageId();
-
-        bearerData.deliveryAckReq = statusReportRequested;
-        bearerData.userAckReq = false;
-        bearerData.readAckReq = false;
-        bearerData.reportReq = false;
-
-        bearerData.userData = userData;
-
-        byte[] encodedBearerData = BearerData.encode(bearerData);
-        if (Log.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) {
-            Log.d(LOG_TAG, "MO (encoded) BearerData = " + bearerData);
-            Log.d(LOG_TAG, "MO raw BearerData = '" + HexDump.toHexString(encodedBearerData) + "'");
-        }
-        if (encodedBearerData == null) return null;
-
-        int teleservice = bearerData.hasUserDataHeader ?
-                SmsEnvelope.TELESERVICE_WEMT : SmsEnvelope.TELESERVICE_WMT;
-
-        SmsEnvelope envelope = new SmsEnvelope();
-        envelope.messageType = SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT;
-        envelope.teleService = teleservice;
-        envelope.destAddress = destAddr;
-        envelope.bearerReply = RETURN_ACK;
-        envelope.bearerData = encodedBearerData;
-
-        /**
-         * TODO(cleanup): envelope looks to be a pointless class, get
-         * rid of it.  Also -- most of the envelope fields set here
-         * are ignored, why?
-         */
-
-        try {
-            /**
-             * TODO(cleanup): reference a spec and get rid of the ugly comments
-             */
-            ByteArrayOutputStream baos = new ByteArrayOutputStream(100);
-            DataOutputStream dos = new DataOutputStream(baos);
-            dos.writeInt(envelope.teleService);
-            dos.writeInt(0); //servicePresent
-            dos.writeInt(0); //serviceCategory
-            dos.write(destAddr.digitMode);
-            dos.write(destAddr.numberMode);
-            dos.write(destAddr.ton); // number_type
-            dos.write(destAddr.numberPlan);
-            dos.write(destAddr.numberOfDigits);
-            dos.write(destAddr.origBytes, 0, destAddr.origBytes.length); // digits
-            // Subaddress is not supported.
-            dos.write(0); //subaddressType
-            dos.write(0); //subaddr_odd
-            dos.write(0); //subaddr_nbr_of_digits
-            dos.write(encodedBearerData.length);
-            dos.write(encodedBearerData, 0, encodedBearerData.length);
-            dos.close();
-
-            SubmitPdu pdu = new SubmitPdu();
-            pdu.encodedMessage = baos.toByteArray();
-            pdu.encodedScAddress = null;
-            return pdu;
-        } catch(IOException ex) {
-            Log.e(LOG_TAG, "creating SubmitPdu failed: " + ex);
-        }
-        return null;
-    }
-
-    /**
-     * Creates byte array (pseudo pdu) from SMS object.
-     * Note: Do not call this method more than once per object!
-     */
-    private void createPdu() {
-        SmsEnvelope env = mEnvelope;
-        CdmaSmsAddress addr = env.origAddress;
-        ByteArrayOutputStream baos = new ByteArrayOutputStream(100);
-        DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(baos));
-
-        try {
-            dos.writeInt(env.messageType);
-            dos.writeInt(env.teleService);
-            dos.writeInt(env.serviceCategory);
-
-            dos.writeByte(addr.digitMode);
-            dos.writeByte(addr.numberMode);
-            dos.writeByte(addr.ton);
-            dos.writeByte(addr.numberPlan);
-            dos.writeByte(addr.numberOfDigits);
-            dos.write(addr.origBytes, 0, addr.origBytes.length); // digits
-
-            dos.writeInt(env.bearerReply);
-            // CauseCode values:
-            dos.writeByte(env.replySeqNo);
-            dos.writeByte(env.errorClass);
-            dos.writeByte(env.causeCode);
-            //encoded BearerData:
-            dos.writeInt(env.bearerData.length);
-            dos.write(env.bearerData, 0, env.bearerData.length);
-            dos.close();
-
-            /**
-             * TODO(cleanup) -- The mPdu field is managed in
-             * a fragile manner, and it would be much nicer if
-             * accessing the serialized representation used a less
-             * fragile mechanism.  Maybe the getPdu method could
-             * generate a representation if there was not yet one?
-             */
-
-            mPdu = baos.toByteArray();
-        } catch (IOException ex) {
-            Log.e(LOG_TAG, "createPdu: conversion from object to byte array failed: " + ex);
-        }
-    }
-
-    /**
-     * Converts a 4-Bit DTMF encoded symbol from the calling address number to ASCII character
-     */
-    private byte convertDtmfToAscii(byte dtmfDigit) {
-        byte asciiDigit;
-
-        switch (dtmfDigit) {
-        case  0: asciiDigit = 68; break; // 'D'
-        case  1: asciiDigit = 49; break; // '1'
-        case  2: asciiDigit = 50; break; // '2'
-        case  3: asciiDigit = 51; break; // '3'
-        case  4: asciiDigit = 52; break; // '4'
-        case  5: asciiDigit = 53; break; // '5'
-        case  6: asciiDigit = 54; break; // '6'
-        case  7: asciiDigit = 55; break; // '7'
-        case  8: asciiDigit = 56; break; // '8'
-        case  9: asciiDigit = 57; break; // '9'
-        case 10: asciiDigit = 48; break; // '0'
-        case 11: asciiDigit = 42; break; // '*'
-        case 12: asciiDigit = 35; break; // '#'
-        case 13: asciiDigit = 65; break; // 'A'
-        case 14: asciiDigit = 66; break; // 'B'
-        case 15: asciiDigit = 67; break; // 'C'
-        default:
-            asciiDigit = 32; // Invalid DTMF code
-            break;
-        }
-
-        return asciiDigit;
-    }
-
-    /** This function  shall be called to get the number of voicemails.
-     * @hide
-     */
-    /*package*/ int getNumOfVoicemails() {
-        return mBearerData.numberOfMessages;
-    }
-
-    /**
-     * Returns a byte array that can be use to uniquely identify a received SMS message.
-     * C.S0015-B  4.3.1.6 Unique Message Identification.
-     *
-     * @return byte array uniquely identifying the message.
-     * @hide
-     */
-    /* package */ byte[] getIncomingSmsFingerprint() {
-        ByteArrayOutputStream output = new ByteArrayOutputStream();
-
-        output.write(mEnvelope.teleService);
-        output.write(mEnvelope.origAddress.origBytes, 0, mEnvelope.origAddress.origBytes.length);
-        output.write(mEnvelope.bearerData, 0, mEnvelope.bearerData.length);
-        output.write(mEnvelope.origSubaddress.origBytes, 0,
-                mEnvelope.origSubaddress.origBytes.length);
-
-        return output.toByteArray();
-    }
-
-    /**
-     * Returns the list of service category program data, if present.
-     * @return a list of CdmaSmsCbProgramData objects, or null if not present
-     */
-    ArrayList<CdmaSmsCbProgramData> getSmsCbProgramData() {
-        return mBearerData.serviceCategoryProgramData;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/TtyIntent.java b/telephony/java/com/android/internal/telephony/cdma/TtyIntent.java
deleted file mode 100644
index 4907aa9..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/TtyIntent.java
+++ /dev/null
@@ -1,67 +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.internal.telephony.cdma;
-
-public class TtyIntent {
-
-    private static final String TAG = "TtyIntent";
-
-
-    /** Event for TTY mode change */
-
-    /**
-     * Broadcast intent action indicating that the TTY has either been
-     * enabled or disabled. An intent extra provides this state as a boolean,
-     * where {@code true} means enabled.
-     * @see #TTY_ENABLED
-     *
-     * {@hide}
-     */
-    public static final String TTY_ENABLED_CHANGE_ACTION =
-        "com.android.internal.telephony.cdma.intent.action.TTY_ENABLED_CHANGE";
-
-    /**
-     * The lookup key for a boolean that indicates whether TTY mode is enabled or
-     * disabled. {@code true} means TTY mode is enabled. Retrieve it with
-     * {@link android.content.Intent#getBooleanExtra(String,boolean)}.
-     *
-     * {@hide}
-     */
-    public static final String TTY_ENABLED = "ttyEnabled";
-
-    /**
-     * Broadcast intent action indicating that the TTY preferred operating mode
-     * has changed. An intent extra provides the new mode as an int.
-     * @see #TTY_PREFFERED_MODE
-     *
-     * {@hide}
-     */
-    public static final String TTY_PREFERRED_MODE_CHANGE_ACTION =
-        "com.android.internal.telephony.cdma.intent.action.TTY_PREFERRED_MODE_CHANGE";
-
-    /**
-     * The lookup key for an int that indicates preferred TTY mode.
-     * Valid modes are:
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
-     *
-     * {@hide}
-     */
-    public static final String TTY_PREFFERED_MODE = "ttyPreferredMode";
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/package.html b/telephony/java/com/android/internal/telephony/cdma/package.html
deleted file mode 100644
index 4eb1f9c..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/package.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<HTML>
-<BODY>
-Provides classes to control or read data from CDMA phones.
-@hide
-</BODY>
-</HTML>
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
deleted file mode 100755
index 3d88f50..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
+++ /dev/null
@@ -1,1968 +0,0 @@
-/*
- * 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.internal.telephony.cdma.sms;
-
-import android.content.res.Resources;
-import android.telephony.SmsCbCmasInfo;
-import android.telephony.SmsMessage;
-import android.telephony.cdma.CdmaSmsCbProgramData;
-import android.telephony.cdma.CdmaSmsCbProgramResults;
-import android.text.format.Time;
-import android.util.Log;
-
-import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.SmsHeader;
-import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails;
-import com.android.internal.util.BitwiseInputStream;
-import com.android.internal.util.BitwiseOutputStream;
-
-import java.util.ArrayList;
-import java.util.TimeZone;
-
-import static android.telephony.SmsMessage.ENCODING_16BIT;
-import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES;
-import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER;
-
-/**
- * An object to encode and decode CDMA SMS bearer data.
- */
-public final class BearerData {
-    private final static String LOG_TAG = "SMS";
-
-    /**
-     * Bearer Data Subparameter Identifiers
-     * (See 3GPP2 C.S0015-B, v2.0, table 4.5-1)
-     * NOTE: Commented subparameter types are not implemented.
-     */
-    private final static byte SUBPARAM_MESSAGE_IDENTIFIER               = 0x00;
-    private final static byte SUBPARAM_USER_DATA                        = 0x01;
-    private final static byte SUBPARAM_USER_RESPONSE_CODE               = 0x02;
-    private final static byte SUBPARAM_MESSAGE_CENTER_TIME_STAMP        = 0x03;
-    private final static byte SUBPARAM_VALIDITY_PERIOD_ABSOLUTE         = 0x04;
-    private final static byte SUBPARAM_VALIDITY_PERIOD_RELATIVE         = 0x05;
-    private final static byte SUBPARAM_DEFERRED_DELIVERY_TIME_ABSOLUTE  = 0x06;
-    private final static byte SUBPARAM_DEFERRED_DELIVERY_TIME_RELATIVE  = 0x07;
-    private final static byte SUBPARAM_PRIORITY_INDICATOR               = 0x08;
-    private final static byte SUBPARAM_PRIVACY_INDICATOR                = 0x09;
-    private final static byte SUBPARAM_REPLY_OPTION                     = 0x0A;
-    private final static byte SUBPARAM_NUMBER_OF_MESSAGES               = 0x0B;
-    private final static byte SUBPARAM_ALERT_ON_MESSAGE_DELIVERY        = 0x0C;
-    private final static byte SUBPARAM_LANGUAGE_INDICATOR               = 0x0D;
-    private final static byte SUBPARAM_CALLBACK_NUMBER                  = 0x0E;
-    private final static byte SUBPARAM_MESSAGE_DISPLAY_MODE             = 0x0F;
-    //private final static byte SUBPARAM_MULTIPLE_ENCODING_USER_DATA      = 0x10;
-    private final static byte SUBPARAM_MESSAGE_DEPOSIT_INDEX            = 0x11;
-    private final static byte SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA    = 0x12;
-    private final static byte SUBPARAM_SERVICE_CATEGORY_PROGRAM_RESULTS = 0x13;
-    private final static byte SUBPARAM_MESSAGE_STATUS                   = 0x14;
-    //private final static byte SUBPARAM_TP_FAILURE_CAUSE                 = 0x15;
-    //private final static byte SUBPARAM_ENHANCED_VMN                     = 0x16;
-    //private final static byte SUBPARAM_ENHANCED_VMN_ACK                 = 0x17;
-
-    /**
-     * Supported message types for CDMA SMS messages
-     * (See 3GPP2 C.S0015-B, v2.0, table 4.5.1-1)
-     */
-    public static final int MESSAGE_TYPE_DELIVER        = 0x01;
-    public static final int MESSAGE_TYPE_SUBMIT         = 0x02;
-    public static final int MESSAGE_TYPE_CANCELLATION   = 0x03;
-    public static final int MESSAGE_TYPE_DELIVERY_ACK   = 0x04;
-    public static final int MESSAGE_TYPE_USER_ACK       = 0x05;
-    public static final int MESSAGE_TYPE_READ_ACK       = 0x06;
-    public static final int MESSAGE_TYPE_DELIVER_REPORT = 0x07;
-    public static final int MESSAGE_TYPE_SUBMIT_REPORT  = 0x08;
-
-    public int messageType;
-
-    /**
-     * 16-bit value indicating the message ID, which increments modulo 65536.
-     * (Special rules apply for WAP-messages.)
-     * (See 3GPP2 C.S0015-B, v2, 4.5.1)
-     */
-    public int messageId;
-
-    /**
-     * Supported priority modes for CDMA SMS messages
-     * (See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1)
-     */
-    public static final int PRIORITY_NORMAL        = 0x0;
-    public static final int PRIORITY_INTERACTIVE   = 0x1;
-    public static final int PRIORITY_URGENT        = 0x2;
-    public static final int PRIORITY_EMERGENCY     = 0x3;
-
-    public boolean priorityIndicatorSet = false;
-    public int priority = PRIORITY_NORMAL;
-
-    /**
-     * Supported privacy modes for CDMA SMS messages
-     * (See 3GPP2 C.S0015-B, v2.0, table 4.5.10-1)
-     */
-    public static final int PRIVACY_NOT_RESTRICTED = 0x0;
-    public static final int PRIVACY_RESTRICTED     = 0x1;
-    public static final int PRIVACY_CONFIDENTIAL   = 0x2;
-    public static final int PRIVACY_SECRET         = 0x3;
-
-    public boolean privacyIndicatorSet = false;
-    public int privacy = PRIVACY_NOT_RESTRICTED;
-
-    /**
-     * Supported alert priority modes for CDMA SMS messages
-     * (See 3GPP2 C.S0015-B, v2.0, table 4.5.13-1)
-     */
-    public static final int ALERT_DEFAULT          = 0x0;
-    public static final int ALERT_LOW_PRIO         = 0x1;
-    public static final int ALERT_MEDIUM_PRIO      = 0x2;
-    public static final int ALERT_HIGH_PRIO        = 0x3;
-
-    public boolean alertIndicatorSet = false;
-    public int alert = ALERT_DEFAULT;
-
-    /**
-     * Supported display modes for CDMA SMS messages.  Display mode is
-     * a 2-bit value used to indicate to the mobile station when to
-     * display the received message.  (See 3GPP2 C.S0015-B, v2,
-     * 4.5.16)
-     */
-    public static final int DISPLAY_MODE_IMMEDIATE      = 0x0;
-    public static final int DISPLAY_MODE_DEFAULT        = 0x1;
-    public static final int DISPLAY_MODE_USER           = 0x2;
-
-    public boolean displayModeSet = false;
-    public int displayMode = DISPLAY_MODE_DEFAULT;
-
-    /**
-     * Language Indicator values.  NOTE: the spec (3GPP2 C.S0015-B,
-     * v2, 4.5.14) is ambiguous as to the meaning of this field, as it
-     * refers to C.R1001-D but that reference has been crossed out.
-     * It would seem reasonable to assume the values from C.R1001-F
-     * (table 9.2-1) are to be used instead.
-     */
-    public static final int LANGUAGE_UNKNOWN  = 0x00;
-    public static final int LANGUAGE_ENGLISH  = 0x01;
-    public static final int LANGUAGE_FRENCH   = 0x02;
-    public static final int LANGUAGE_SPANISH  = 0x03;
-    public static final int LANGUAGE_JAPANESE = 0x04;
-    public static final int LANGUAGE_KOREAN   = 0x05;
-    public static final int LANGUAGE_CHINESE  = 0x06;
-    public static final int LANGUAGE_HEBREW   = 0x07;
-
-    public boolean languageIndicatorSet = false;
-    public int language = LANGUAGE_UNKNOWN;
-
-    /**
-     * SMS Message Status Codes.  The first component of the Message
-     * status indicates if an error has occurred and whether the error
-     * is considered permanent or temporary.  The second component of
-     * the Message status indicates the cause of the error (if any).
-     * (See 3GPP2 C.S0015-B, v2.0, 4.5.21)
-     */
-    /* no-error codes */
-    public static final int ERROR_NONE                   = 0x00;
-    public static final int STATUS_ACCEPTED              = 0x00;
-    public static final int STATUS_DEPOSITED_TO_INTERNET = 0x01;
-    public static final int STATUS_DELIVERED             = 0x02;
-    public static final int STATUS_CANCELLED             = 0x03;
-    /* temporary-error and permanent-error codes */
-    public static final int ERROR_TEMPORARY              = 0x02;
-    public static final int STATUS_NETWORK_CONGESTION    = 0x04;
-    public static final int STATUS_NETWORK_ERROR         = 0x05;
-    public static final int STATUS_UNKNOWN_ERROR         = 0x1F;
-    /* permanent-error codes */
-    public static final int ERROR_PERMANENT              = 0x03;
-    public static final int STATUS_CANCEL_FAILED         = 0x06;
-    public static final int STATUS_BLOCKED_DESTINATION   = 0x07;
-    public static final int STATUS_TEXT_TOO_LONG         = 0x08;
-    public static final int STATUS_DUPLICATE_MESSAGE     = 0x09;
-    public static final int STATUS_INVALID_DESTINATION   = 0x0A;
-    public static final int STATUS_MESSAGE_EXPIRED       = 0x0D;
-    /* undefined-status codes */
-    public static final int ERROR_UNDEFINED              = 0xFF;
-    public static final int STATUS_UNDEFINED             = 0xFF;
-
-    public boolean messageStatusSet = false;
-    public int errorClass = ERROR_UNDEFINED;
-    public int messageStatus = STATUS_UNDEFINED;
-
-    /**
-     * 1-bit value that indicates whether a User Data Header (UDH) is present.
-     * (See 3GPP2 C.S0015-B, v2, 4.5.1)
-     *
-     * NOTE: during encoding, this value will be set based on the
-     * presence of a UDH in the structured data, any existing setting
-     * will be overwritten.
-     */
-    public boolean hasUserDataHeader;
-
-    /**
-     * provides the information for the user data
-     * (e.g. padding bits, user data, user data header, etc)
-     * (See 3GPP2 C.S.0015-B, v2, 4.5.2)
-     */
-    public UserData userData;
-
-    /**
-     * The User Response Code subparameter is used in the SMS User
-     * Acknowledgment Message to respond to previously received short
-     * messages. This message center-specific element carries the
-     * identifier of a predefined response. (See 3GPP2 C.S.0015-B, v2,
-     * 4.5.3)
-     */
-    public boolean userResponseCodeSet = false;
-    public int userResponseCode;
-
-    /**
-     * 6-byte-field, see 3GPP2 C.S0015-B, v2, 4.5.4
-     */
-    public static class TimeStamp extends Time {
-
-        public TimeStamp() {
-            super(TimeZone.getDefault().getID());   // 3GPP2 timestamps use the local timezone
-        }
-
-        public static TimeStamp fromByteArray(byte[] data) {
-            TimeStamp ts = new TimeStamp();
-            // C.S0015-B v2.0, 4.5.4: range is 1996-2095
-            int year = IccUtils.cdmaBcdByteToInt(data[0]);
-            if (year > 99 || year < 0) return null;
-            ts.year = year >= 96 ? year + 1900 : year + 2000;
-            int month = IccUtils.cdmaBcdByteToInt(data[1]);
-            if (month < 1 || month > 12) return null;
-            ts.month = month - 1;
-            int day = IccUtils.cdmaBcdByteToInt(data[2]);
-            if (day < 1 || day > 31) return null;
-            ts.monthDay = day;
-            int hour = IccUtils.cdmaBcdByteToInt(data[3]);
-            if (hour < 0 || hour > 23) return null;
-            ts.hour = hour;
-            int minute = IccUtils.cdmaBcdByteToInt(data[4]);
-            if (minute < 0 || minute > 59) return null;
-            ts.minute = minute;
-            int second = IccUtils.cdmaBcdByteToInt(data[5]);
-            if (second < 0 || second > 59) return null;
-            ts.second = second;
-            return ts;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder builder = new StringBuilder();
-            builder.append("TimeStamp ");
-            builder.append("{ year=" + year);
-            builder.append(", month=" + month);
-            builder.append(", day=" + monthDay);
-            builder.append(", hour=" + hour);
-            builder.append(", minute=" + minute);
-            builder.append(", second=" + second);
-            builder.append(" }");
-            return builder.toString();
-        }
-    }
-
-    public TimeStamp msgCenterTimeStamp;
-    public TimeStamp validityPeriodAbsolute;
-    public TimeStamp deferredDeliveryTimeAbsolute;
-
-    /**
-     * Relative time is specified as one byte, the value of which
-     * falls into a series of ranges, as specified below.  The idea is
-     * that shorter time intervals allow greater precision -- the
-     * value means minutes from zero until the MINS_LIMIT (inclusive),
-     * upon which it means hours until the HOURS_LIMIT, and so
-     * forth. (See 3GPP2 C.S0015-B, v2, 4.5.6-1)
-     */
-    public static final int RELATIVE_TIME_MINS_LIMIT      = 143;
-    public static final int RELATIVE_TIME_HOURS_LIMIT     = 167;
-    public static final int RELATIVE_TIME_DAYS_LIMIT      = 196;
-    public static final int RELATIVE_TIME_WEEKS_LIMIT     = 244;
-    public static final int RELATIVE_TIME_INDEFINITE      = 245;
-    public static final int RELATIVE_TIME_NOW             = 246;
-    public static final int RELATIVE_TIME_MOBILE_INACTIVE = 247;
-    public static final int RELATIVE_TIME_RESERVED        = 248;
-
-    public boolean validityPeriodRelativeSet;
-    public int validityPeriodRelative;
-    public boolean deferredDeliveryTimeRelativeSet;
-    public int deferredDeliveryTimeRelative;
-
-    /**
-     * The Reply Option subparameter contains 1-bit values which
-     * indicate whether SMS acknowledgment is requested or not.  (See
-     * 3GPP2 C.S0015-B, v2, 4.5.11)
-     */
-    public boolean userAckReq;
-    public boolean deliveryAckReq;
-    public boolean readAckReq;
-    public boolean reportReq;
-
-    /**
-     * The Number of Messages subparameter (8-bit value) is a decimal
-     * number in the 0 to 99 range representing the number of messages
-     * stored at the Voice Mail System. This element is used by the
-     * Voice Mail Notification service.  (See 3GPP2 C.S0015-B, v2,
-     * 4.5.12)
-     */
-    public int numberOfMessages;
-
-    /**
-     * The Message Deposit Index subparameter is assigned by the
-     * message center as a unique index to the contents of the User
-     * Data subparameter in each message sent to a particular mobile
-     * station. The mobile station, when replying to a previously
-     * received short message which included a Message Deposit Index
-     * subparameter, may include the Message Deposit Index of the
-     * received message to indicate to the message center that the
-     * original contents of the message are to be included in the
-     * reply.  (See 3GPP2 C.S0015-B, v2, 4.5.18)
-     */
-    public int depositIndex;
-
-    /**
-     * 4-bit or 8-bit value that indicates the number to be dialed in reply to a
-     * received SMS message.
-     * (See 3GPP2 C.S0015-B, v2, 4.5.15)
-     */
-    public CdmaSmsAddress callbackNumber;
-
-    /**
-     * CMAS warning notification information.
-     * @see #decodeCmasUserData(BearerData, int)
-     */
-    public SmsCbCmasInfo cmasWarningInfo;
-
-    /**
-     * The Service Category Program Data subparameter is used to enable and disable
-     * SMS broadcast service categories to display. If this subparameter is present,
-     * this field will contain a list of one or more
-     * {@link android.telephony.cdma.CdmaSmsCbProgramData} objects containing the
-     * operation(s) to perform.
-     */
-    public ArrayList<CdmaSmsCbProgramData> serviceCategoryProgramData;
-
-    /**
-     * The Service Category Program Results subparameter informs the message center
-     * of the results of a Service Category Program Data request.
-     */
-    public ArrayList<CdmaSmsCbProgramResults> serviceCategoryProgramResults;
-
-
-    private static class CodingException extends Exception {
-        public CodingException(String s) {
-            super(s);
-        }
-    }
-
-    /**
-     * Returns the language indicator as a two-character ISO 639 string.
-     * @return a two character ISO 639 language code
-     */
-    public String getLanguage() {
-        return getLanguageCodeForValue(language);
-    }
-
-    /**
-     * Converts a CDMA language indicator value to an ISO 639 two character language code.
-     * @param languageValue the CDMA language value to convert
-     * @return the two character ISO 639 language code for the specified value, or null if unknown
-     */
-    private static String getLanguageCodeForValue(int languageValue) {
-        switch (languageValue) {
-            case LANGUAGE_ENGLISH:
-                return "en";
-
-            case LANGUAGE_FRENCH:
-                return "fr";
-
-            case LANGUAGE_SPANISH:
-                return "es";
-
-            case LANGUAGE_JAPANESE:
-                return "ja";
-
-            case LANGUAGE_KOREAN:
-                return "ko";
-
-            case LANGUAGE_CHINESE:
-                return "zh";
-
-            case LANGUAGE_HEBREW:
-                return "he";
-
-            default:
-                return null;
-        }
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder builder = new StringBuilder();
-        builder.append("BearerData ");
-        builder.append("{ messageType=" + messageType);
-        builder.append(", messageId=" + (int)messageId);
-        builder.append(", priority=" + (priorityIndicatorSet ? priority : "unset"));
-        builder.append(", privacy=" + (privacyIndicatorSet ? privacy : "unset"));
-        builder.append(", alert=" + (alertIndicatorSet ? alert : "unset"));
-        builder.append(", displayMode=" + (displayModeSet ? displayMode : "unset"));
-        builder.append(", language=" + (languageIndicatorSet ? language : "unset"));
-        builder.append(", errorClass=" + (messageStatusSet ? errorClass : "unset"));
-        builder.append(", msgStatus=" + (messageStatusSet ? messageStatus : "unset"));
-        builder.append(", msgCenterTimeStamp=" +
-                ((msgCenterTimeStamp != null) ? msgCenterTimeStamp : "unset"));
-        builder.append(", validityPeriodAbsolute=" +
-                ((validityPeriodAbsolute != null) ? validityPeriodAbsolute : "unset"));
-        builder.append(", validityPeriodRelative=" +
-                ((validityPeriodRelativeSet) ? validityPeriodRelative : "unset"));
-        builder.append(", deferredDeliveryTimeAbsolute=" +
-                ((deferredDeliveryTimeAbsolute != null) ? deferredDeliveryTimeAbsolute : "unset"));
-        builder.append(", deferredDeliveryTimeRelative=" +
-                ((deferredDeliveryTimeRelativeSet) ? deferredDeliveryTimeRelative : "unset"));
-        builder.append(", userAckReq=" + userAckReq);
-        builder.append(", deliveryAckReq=" + deliveryAckReq);
-        builder.append(", readAckReq=" + readAckReq);
-        builder.append(", reportReq=" + reportReq);
-        builder.append(", numberOfMessages=" + numberOfMessages);
-        builder.append(", callbackNumber=" + callbackNumber);
-        builder.append(", depositIndex=" + depositIndex);
-        builder.append(", hasUserDataHeader=" + hasUserDataHeader);
-        builder.append(", userData=" + userData);
-        builder.append(" }");
-        return builder.toString();
-    }
-
-    private static void encodeMessageId(BearerData bData, BitwiseOutputStream outStream)
-        throws BitwiseOutputStream.AccessException
-    {
-        outStream.write(8, 3);
-        outStream.write(4, bData.messageType);
-        outStream.write(8, bData.messageId >> 8);
-        outStream.write(8, bData.messageId);
-        outStream.write(1, bData.hasUserDataHeader ? 1 : 0);
-        outStream.skip(3);
-    }
-
-    private static int countAsciiSeptets(CharSequence msg, boolean force) {
-        int msgLen = msg.length();
-        if (force) return msgLen;
-        for (int i = 0; i < msgLen; i++) {
-            if (UserData.charToAscii.get(msg.charAt(i), -1) == -1) {
-                return -1;
-            }
-        }
-        return msgLen;
-    }
-
-    /**
-     * Calculate the message text encoding length, fragmentation, and other details.
-     *
-     * @param msg message text
-     * @param force7BitEncoding ignore (but still count) illegal characters if true
-     * @return septet count, or -1 on failure
-     */
-    public static TextEncodingDetails calcTextEncodingDetails(CharSequence msg,
-            boolean force7BitEncoding) {
-        TextEncodingDetails ted;
-        int septets = countAsciiSeptets(msg, force7BitEncoding);
-        if (septets != -1 && septets <= SmsMessage.MAX_USER_DATA_SEPTETS) {
-            ted = new TextEncodingDetails();
-            ted.msgCount = 1;
-            ted.codeUnitCount = septets;
-            ted.codeUnitsRemaining = SmsMessage.MAX_USER_DATA_SEPTETS - septets;
-            ted.codeUnitSize = SmsMessage.ENCODING_7BIT;
-        } else {
-            ted = com.android.internal.telephony.gsm.SmsMessage.calculateLength(
-                    msg, force7BitEncoding);
-            if (ted.msgCount == 1 && ted.codeUnitSize == SmsMessage.ENCODING_7BIT) {
-                // We don't support single-segment EMS, so calculate for 16-bit
-                // TODO: Consider supporting single-segment EMS
-                ted.codeUnitCount = msg.length();
-                int octets = ted.codeUnitCount * 2;
-                if (octets > MAX_USER_DATA_BYTES) {
-                    ted.msgCount = (octets + (MAX_USER_DATA_BYTES_WITH_HEADER - 1)) /
-                            MAX_USER_DATA_BYTES_WITH_HEADER;
-                    ted.codeUnitsRemaining = ((ted.msgCount *
-                            MAX_USER_DATA_BYTES_WITH_HEADER) - octets) / 2;
-                } else {
-                    ted.msgCount = 1;
-                    ted.codeUnitsRemaining = (MAX_USER_DATA_BYTES - octets)/2;
-                }
-                ted.codeUnitSize = ENCODING_16BIT;
-            }
-        }
-        return ted;
-    }
-
-    private static byte[] encode7bitAscii(String msg, boolean force)
-        throws CodingException
-    {
-        try {
-            BitwiseOutputStream outStream = new BitwiseOutputStream(msg.length());
-            int msgLen = msg.length();
-            for (int i = 0; i < msgLen; i++) {
-                int charCode = UserData.charToAscii.get(msg.charAt(i), -1);
-                if (charCode == -1) {
-                    if (force) {
-                        outStream.write(7, UserData.UNENCODABLE_7_BIT_CHAR);
-                    } else {
-                        throw new CodingException("cannot ASCII encode (" + msg.charAt(i) + ")");
-                    }
-                } else {
-                    outStream.write(7, charCode);
-                }
-            }
-            return outStream.toByteArray();
-        } catch (BitwiseOutputStream.AccessException ex) {
-            throw new CodingException("7bit ASCII encode failed: " + ex);
-        }
-    }
-
-    private static byte[] encodeUtf16(String msg)
-        throws CodingException
-    {
-        try {
-            return msg.getBytes("utf-16be");
-        } catch (java.io.UnsupportedEncodingException ex) {
-            throw new CodingException("UTF-16 encode failed: " + ex);
-        }
-    }
-
-    private static class Gsm7bitCodingResult {
-        int septets;
-        byte[] data;
-    }
-
-    private static Gsm7bitCodingResult encode7bitGsm(String msg, int septetOffset, boolean force)
-        throws CodingException
-    {
-        try {
-            /*
-             * TODO(cleanup): It would be nice if GsmAlphabet provided
-             * an option to produce just the data without prepending
-             * the septet count, as this function is really just a
-             * wrapper to strip that off.  Not to mention that the
-             * septet count is generally known prior to invocation of
-             * the encoder.  Note that it cannot be derived from the
-             * resulting array length, since that cannot distinguish
-             * if the last contains either 1 or 8 valid bits.
-             *
-             * TODO(cleanup): The BitwiseXStreams could also be
-             * extended with byte-wise reversed endianness read/write
-             * routines to allow a corresponding implementation of
-             * stringToGsm7BitPacked, and potentially directly support
-             * access to the main bitwise stream from encode/decode.
-             */
-            byte[] fullData = GsmAlphabet.stringToGsm7BitPacked(msg, septetOffset, !force, 0, 0);
-            Gsm7bitCodingResult result = new Gsm7bitCodingResult();
-            result.data = new byte[fullData.length - 1];
-            System.arraycopy(fullData, 1, result.data, 0, fullData.length - 1);
-            result.septets = fullData[0] & 0x00FF;
-            return result;
-        } catch (com.android.internal.telephony.EncodeException ex) {
-            throw new CodingException("7bit GSM encode failed: " + ex);
-        }
-    }
-
-    private static void encode7bitEms(UserData uData, byte[] udhData, boolean force)
-        throws CodingException
-    {
-        int udhBytes = udhData.length + 1;  // Add length octet.
-        int udhSeptets = ((udhBytes * 8) + 6) / 7;
-        Gsm7bitCodingResult gcr = encode7bitGsm(uData.payloadStr, udhSeptets, force);
-        uData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET;
-        uData.msgEncodingSet = true;
-        uData.numFields = gcr.septets;
-        uData.payload = gcr.data;
-        uData.payload[0] = (byte)udhData.length;
-        System.arraycopy(udhData, 0, uData.payload, 1, udhData.length);
-    }
-
-    private static void encode16bitEms(UserData uData, byte[] udhData)
-        throws CodingException
-    {
-        byte[] payload = encodeUtf16(uData.payloadStr);
-        int udhBytes = udhData.length + 1;  // Add length octet.
-        int udhCodeUnits = (udhBytes + 1) / 2;
-        int payloadCodeUnits = payload.length / 2;
-        uData.msgEncoding = UserData.ENCODING_UNICODE_16;
-        uData.msgEncodingSet = true;
-        uData.numFields = udhCodeUnits + payloadCodeUnits;
-        uData.payload = new byte[uData.numFields * 2];
-        uData.payload[0] = (byte)udhData.length;
-        System.arraycopy(udhData, 0, uData.payload, 1, udhData.length);
-        System.arraycopy(payload, 0, uData.payload, udhBytes, payload.length);
-    }
-
-    private static void encodeEmsUserDataPayload(UserData uData)
-        throws CodingException
-    {
-        byte[] headerData = SmsHeader.toByteArray(uData.userDataHeader);
-        if (uData.msgEncodingSet) {
-            if (uData.msgEncoding == UserData.ENCODING_GSM_7BIT_ALPHABET) {
-                encode7bitEms(uData, headerData, true);
-            } else if (uData.msgEncoding == UserData.ENCODING_UNICODE_16) {
-                encode16bitEms(uData, headerData);
-            } else {
-                throw new CodingException("unsupported EMS user data encoding (" +
-                                          uData.msgEncoding + ")");
-            }
-        } else {
-            try {
-                encode7bitEms(uData, headerData, false);
-            } catch (CodingException ex) {
-                encode16bitEms(uData, headerData);
-            }
-        }
-    }
-
-    private static void encodeUserDataPayload(UserData uData)
-        throws CodingException
-    {
-        if ((uData.payloadStr == null) && (uData.msgEncoding != UserData.ENCODING_OCTET)) {
-            Log.e(LOG_TAG, "user data with null payloadStr");
-            uData.payloadStr = "";
-        }
-
-        if (uData.userDataHeader != null) {
-            encodeEmsUserDataPayload(uData);
-            return;
-        }
-
-        if (uData.msgEncodingSet) {
-            if (uData.msgEncoding == UserData.ENCODING_OCTET) {
-                if (uData.payload == null) {
-                    Log.e(LOG_TAG, "user data with octet encoding but null payload");
-                    uData.payload = new byte[0];
-                    uData.numFields = 0;
-                } else {
-                    uData.numFields = uData.payload.length;
-                }
-            } else {
-                if (uData.payloadStr == null) {
-                    Log.e(LOG_TAG, "non-octet user data with null payloadStr");
-                    uData.payloadStr = "";
-                }
-                if (uData.msgEncoding == UserData.ENCODING_GSM_7BIT_ALPHABET) {
-                    Gsm7bitCodingResult gcr = encode7bitGsm(uData.payloadStr, 0, true);
-                    uData.payload = gcr.data;
-                    uData.numFields = gcr.septets;
-                } else if (uData.msgEncoding == UserData.ENCODING_7BIT_ASCII) {
-                    uData.payload = encode7bitAscii(uData.payloadStr, true);
-                    uData.numFields = uData.payloadStr.length();
-                } else if (uData.msgEncoding == UserData.ENCODING_UNICODE_16) {
-                    uData.payload = encodeUtf16(uData.payloadStr);
-                    uData.numFields = uData.payloadStr.length();
-                } else {
-                    throw new CodingException("unsupported user data encoding (" +
-                                              uData.msgEncoding + ")");
-                }
-            }
-        } else {
-            try {
-                uData.payload = encode7bitAscii(uData.payloadStr, false);
-                uData.msgEncoding = UserData.ENCODING_7BIT_ASCII;
-            } catch (CodingException ex) {
-                uData.payload = encodeUtf16(uData.payloadStr);
-                uData.msgEncoding = UserData.ENCODING_UNICODE_16;
-            }
-            uData.numFields = uData.payloadStr.length();
-            uData.msgEncodingSet = true;
-        }
-    }
-
-    private static void encodeUserData(BearerData bData, BitwiseOutputStream outStream)
-        throws BitwiseOutputStream.AccessException, CodingException
-    {
-        /*
-         * TODO(cleanup): Do we really need to set userData.payload as
-         * a side effect of encoding?  If not, we could avoid data
-         * copies by passing outStream directly.
-         */
-        encodeUserDataPayload(bData.userData);
-        bData.hasUserDataHeader = bData.userData.userDataHeader != null;
-
-        if (bData.userData.payload.length > SmsMessage.MAX_USER_DATA_BYTES) {
-            throw new CodingException("encoded user data too large (" +
-                                      bData.userData.payload.length +
-                                      " > " + SmsMessage.MAX_USER_DATA_BYTES + " bytes)");
-        }
-
-        /*
-         * TODO(cleanup): figure out what the right answer is WRT paddingBits field
-         *
-         *   userData.paddingBits = (userData.payload.length * 8) - (userData.numFields * 7);
-         *   userData.paddingBits = 0; // XXX this seems better, but why?
-         *
-         */
-        int dataBits = (bData.userData.payload.length * 8) - bData.userData.paddingBits;
-        int paramBits = dataBits + 13;
-        if ((bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) ||
-            (bData.userData.msgEncoding == UserData.ENCODING_GSM_DCS)) {
-            paramBits += 8;
-        }
-        int paramBytes = (paramBits / 8) + ((paramBits % 8) > 0 ? 1 : 0);
-        int paddingBits = (paramBytes * 8) - paramBits;
-        outStream.write(8, paramBytes);
-        outStream.write(5, bData.userData.msgEncoding);
-        if ((bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) ||
-            (bData.userData.msgEncoding == UserData.ENCODING_GSM_DCS)) {
-            outStream.write(8, bData.userData.msgType);
-        }
-        outStream.write(8, bData.userData.numFields);
-        outStream.writeByteArray(dataBits, bData.userData.payload);
-        if (paddingBits > 0) outStream.write(paddingBits, 0);
-    }
-
-    private static void encodeReplyOption(BearerData bData, BitwiseOutputStream outStream)
-        throws BitwiseOutputStream.AccessException
-    {
-        outStream.write(8, 1);
-        outStream.write(1, bData.userAckReq     ? 1 : 0);
-        outStream.write(1, bData.deliveryAckReq ? 1 : 0);
-        outStream.write(1, bData.readAckReq     ? 1 : 0);
-        outStream.write(1, bData.reportReq      ? 1 : 0);
-        outStream.write(4, 0);
-    }
-
-    private static byte[] encodeDtmfSmsAddress(String address) {
-        int digits = address.length();
-        int dataBits = digits * 4;
-        int dataBytes = (dataBits / 8);
-        dataBytes += (dataBits % 8) > 0 ? 1 : 0;
-        byte[] rawData = new byte[dataBytes];
-        for (int i = 0; i < digits; i++) {
-            char c = address.charAt(i);
-            int val = 0;
-            if ((c >= '1') && (c <= '9')) val = c - '0';
-            else if (c == '0') val = 10;
-            else if (c == '*') val = 11;
-            else if (c == '#') val = 12;
-            else return null;
-            rawData[i / 2] |= val << (4 - ((i % 2) * 4));
-        }
-        return rawData;
-    }
-
-    /*
-     * TODO(cleanup): CdmaSmsAddress encoding should make use of
-     * CdmaSmsAddress.parse provided that DTMF encoding is unified,
-     * and the difference in 4-bit vs. 8-bit is resolved.
-     */
-
-    private static void encodeCdmaSmsAddress(CdmaSmsAddress addr) throws CodingException {
-        if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
-            try {
-                addr.origBytes = addr.address.getBytes("US-ASCII");
-            } catch (java.io.UnsupportedEncodingException ex) {
-                throw new CodingException("invalid SMS address, cannot convert to ASCII");
-            }
-        } else {
-            addr.origBytes = encodeDtmfSmsAddress(addr.address);
-        }
-    }
-
-    private static void encodeCallbackNumber(BearerData bData, BitwiseOutputStream outStream)
-        throws BitwiseOutputStream.AccessException, CodingException
-    {
-        CdmaSmsAddress addr = bData.callbackNumber;
-        encodeCdmaSmsAddress(addr);
-        int paramBits = 9;
-        int dataBits = 0;
-        if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
-            paramBits += 7;
-            dataBits = addr.numberOfDigits * 8;
-        } else {
-            dataBits = addr.numberOfDigits * 4;
-        }
-        paramBits += dataBits;
-        int paramBytes = (paramBits / 8) + ((paramBits % 8) > 0 ? 1 : 0);
-        int paddingBits = (paramBytes * 8) - paramBits;
-        outStream.write(8, paramBytes);
-        outStream.write(1, addr.digitMode);
-        if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
-            outStream.write(3, addr.ton);
-            outStream.write(4, addr.numberPlan);
-        }
-        outStream.write(8, addr.numberOfDigits);
-        outStream.writeByteArray(dataBits, addr.origBytes);
-        if (paddingBits > 0) outStream.write(paddingBits, 0);
-    }
-
-    private static void encodeMsgStatus(BearerData bData, BitwiseOutputStream outStream)
-        throws BitwiseOutputStream.AccessException
-    {
-        outStream.write(8, 1);
-        outStream.write(2, bData.errorClass);
-        outStream.write(6, bData.messageStatus);
-    }
-
-    private static void encodeMsgCount(BearerData bData, BitwiseOutputStream outStream)
-        throws BitwiseOutputStream.AccessException
-    {
-        outStream.write(8, 1);
-        outStream.write(8, bData.numberOfMessages);
-    }
-
-    private static void encodeValidityPeriodRel(BearerData bData, BitwiseOutputStream outStream)
-        throws BitwiseOutputStream.AccessException
-    {
-        outStream.write(8, 1);
-        outStream.write(8, bData.validityPeriodRelative);
-    }
-
-    private static void encodePrivacyIndicator(BearerData bData, BitwiseOutputStream outStream)
-        throws BitwiseOutputStream.AccessException
-    {
-        outStream.write(8, 1);
-        outStream.write(2, bData.privacy);
-        outStream.skip(6);
-    }
-
-    private static void encodeLanguageIndicator(BearerData bData, BitwiseOutputStream outStream)
-        throws BitwiseOutputStream.AccessException
-    {
-        outStream.write(8, 1);
-        outStream.write(8, bData.language);
-    }
-
-    private static void encodeDisplayMode(BearerData bData, BitwiseOutputStream outStream)
-        throws BitwiseOutputStream.AccessException
-    {
-        outStream.write(8, 1);
-        outStream.write(2, bData.displayMode);
-        outStream.skip(6);
-    }
-
-    private static void encodePriorityIndicator(BearerData bData, BitwiseOutputStream outStream)
-        throws BitwiseOutputStream.AccessException
-    {
-        outStream.write(8, 1);
-        outStream.write(2, bData.priority);
-        outStream.skip(6);
-    }
-
-    private static void encodeMsgDeliveryAlert(BearerData bData, BitwiseOutputStream outStream)
-        throws BitwiseOutputStream.AccessException
-    {
-        outStream.write(8, 1);
-        outStream.write(2, bData.alert);
-        outStream.skip(6);
-    }
-
-    private static void encodeScpResults(BearerData bData, BitwiseOutputStream outStream)
-        throws BitwiseOutputStream.AccessException
-    {
-        ArrayList<CdmaSmsCbProgramResults> results = bData.serviceCategoryProgramResults;
-        outStream.write(8, (results.size() * 4));   // 4 octets per program result
-        for (CdmaSmsCbProgramResults result : results) {
-            int category = result.getCategory();
-            outStream.write(8, category >> 8);
-            outStream.write(8, category);
-            outStream.write(8, result.getLanguage());
-            outStream.write(4, result.getCategoryResult());
-            outStream.skip(4);
-        }
-    }
-
-    /**
-     * Create serialized representation for BearerData object.
-     * (See 3GPP2 C.R1001-F, v1.0, section 4.5 for layout details)
-     *
-     * @param bData an instance of BearerData.
-     *
-     * @return byte array of raw encoded SMS bearer data.
-     */
-    public static byte[] encode(BearerData bData) {
-        bData.hasUserDataHeader = ((bData.userData != null) &&
-                (bData.userData.userDataHeader != null));
-        try {
-            BitwiseOutputStream outStream = new BitwiseOutputStream(200);
-            outStream.write(8, SUBPARAM_MESSAGE_IDENTIFIER);
-            encodeMessageId(bData, outStream);
-            if (bData.userData != null) {
-                outStream.write(8, SUBPARAM_USER_DATA);
-                encodeUserData(bData, outStream);
-            }
-            if (bData.callbackNumber != null) {
-                outStream.write(8, SUBPARAM_CALLBACK_NUMBER);
-                encodeCallbackNumber(bData, outStream);
-            }
-            if (bData.userAckReq || bData.deliveryAckReq || bData.readAckReq || bData.reportReq) {
-                outStream.write(8, SUBPARAM_REPLY_OPTION);
-                encodeReplyOption(bData, outStream);
-            }
-            if (bData.numberOfMessages != 0) {
-                outStream.write(8, SUBPARAM_NUMBER_OF_MESSAGES);
-                encodeMsgCount(bData, outStream);
-            }
-            if (bData.validityPeriodRelativeSet) {
-                outStream.write(8, SUBPARAM_VALIDITY_PERIOD_RELATIVE);
-                encodeValidityPeriodRel(bData, outStream);
-            }
-            if (bData.privacyIndicatorSet) {
-                outStream.write(8, SUBPARAM_PRIVACY_INDICATOR);
-                encodePrivacyIndicator(bData, outStream);
-            }
-            if (bData.languageIndicatorSet) {
-                outStream.write(8, SUBPARAM_LANGUAGE_INDICATOR);
-                encodeLanguageIndicator(bData, outStream);
-            }
-            if (bData.displayModeSet) {
-                outStream.write(8, SUBPARAM_MESSAGE_DISPLAY_MODE);
-                encodeDisplayMode(bData, outStream);
-            }
-            if (bData.priorityIndicatorSet) {
-                outStream.write(8, SUBPARAM_PRIORITY_INDICATOR);
-                encodePriorityIndicator(bData, outStream);
-            }
-            if (bData.alertIndicatorSet) {
-                outStream.write(8, SUBPARAM_ALERT_ON_MESSAGE_DELIVERY);
-                encodeMsgDeliveryAlert(bData, outStream);
-            }
-            if (bData.messageStatusSet) {
-                outStream.write(8, SUBPARAM_MESSAGE_STATUS);
-                encodeMsgStatus(bData, outStream);
-            }
-            if (bData.serviceCategoryProgramResults != null) {
-                outStream.write(8, SUBPARAM_SERVICE_CATEGORY_PROGRAM_RESULTS);
-                encodeScpResults(bData, outStream);
-            }
-            return outStream.toByteArray();
-        } catch (BitwiseOutputStream.AccessException ex) {
-            Log.e(LOG_TAG, "BearerData encode failed: " + ex);
-        } catch (CodingException ex) {
-            Log.e(LOG_TAG, "BearerData encode failed: " + ex);
-        }
-        return null;
-   }
-
-    private static boolean decodeMessageId(BearerData bData, BitwiseInputStream inStream)
-        throws BitwiseInputStream.AccessException, CodingException
-    {
-        final int EXPECTED_PARAM_SIZE = 3 * 8;
-        boolean decodeSuccess = false;
-        int paramBits = inStream.read(8) * 8;
-        if (paramBits >= EXPECTED_PARAM_SIZE) {
-            paramBits -= EXPECTED_PARAM_SIZE;
-            decodeSuccess = true;
-            bData.messageType = inStream.read(4);
-            bData.messageId = inStream.read(8) << 8;
-            bData.messageId |= inStream.read(8);
-            bData.hasUserDataHeader = (inStream.read(1) == 1);
-            inStream.skip(3);
-        }
-        if ((! decodeSuccess) || (paramBits > 0)) {
-            Log.d(LOG_TAG, "MESSAGE_IDENTIFIER decode " +
-                      (decodeSuccess ? "succeeded" : "failed") +
-                      " (extra bits = " + paramBits + ")");
-        }
-        inStream.skip(paramBits);
-        return decodeSuccess;
-    }
-
-    private static boolean decodeUserData(BearerData bData, BitwiseInputStream inStream)
-        throws BitwiseInputStream.AccessException
-    {
-        int paramBits = inStream.read(8) * 8;
-        bData.userData = new UserData();
-        bData.userData.msgEncoding = inStream.read(5);
-        bData.userData.msgEncodingSet = true;
-        bData.userData.msgType = 0;
-        int consumedBits = 5;
-        if ((bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) ||
-            (bData.userData.msgEncoding == UserData.ENCODING_GSM_DCS)) {
-            bData.userData.msgType = inStream.read(8);
-            consumedBits += 8;
-        }
-        bData.userData.numFields = inStream.read(8);
-        consumedBits += 8;
-        int dataBits = paramBits - consumedBits;
-        bData.userData.payload = inStream.readByteArray(dataBits);
-        return true;
-    }
-
-    private static String decodeUtf8(byte[] data, int offset, int numFields)
-        throws CodingException
-    {
-        return decodeCharset(data, offset, numFields, 1, "UTF-8");
-    }
-
-    private static String decodeUtf16(byte[] data, int offset, int numFields)
-        throws CodingException
-    {
-        // Subtract header and possible padding byte (at end) from num fields.
-        int padding = offset % 2;
-        numFields -= (offset + padding) / 2;
-        return decodeCharset(data, offset, numFields, 2, "utf-16be");
-    }
-
-    private static String decodeCharset(byte[] data, int offset, int numFields, int width,
-            String charset) throws CodingException
-    {
-        if (numFields < 0 || (numFields * width + offset) > data.length) {
-            // Try to decode the max number of characters in payload
-            int padding = offset % width;
-            int maxNumFields = (data.length - offset - padding) / width;
-            if (maxNumFields < 0) {
-                throw new CodingException(charset + " decode failed: offset out of range");
-            }
-            Log.e(LOG_TAG, charset + " decode error: offset = " + offset + " numFields = "
-                    + numFields + " data.length = " + data.length + " maxNumFields = "
-                    + maxNumFields);
-            numFields = maxNumFields;
-        }
-        try {
-            return new String(data, offset, numFields * width, charset);
-        } catch (java.io.UnsupportedEncodingException ex) {
-            throw new CodingException(charset + " decode failed: " + ex);
-        }
-    }
-
-    private static String decode7bitAscii(byte[] data, int offset, int numFields)
-        throws CodingException
-    {
-        try {
-            offset *= 8;
-            StringBuffer strBuf = new StringBuffer(numFields);
-            BitwiseInputStream inStream = new BitwiseInputStream(data);
-            int wantedBits = (offset * 8) + (numFields * 7);
-            if (inStream.available() < wantedBits) {
-                throw new CodingException("insufficient data (wanted " + wantedBits +
-                                          " bits, but only have " + inStream.available() + ")");
-            }
-            inStream.skip(offset);
-            for (int i = 0; i < numFields; i++) {
-                int charCode = inStream.read(7);
-                if ((charCode >= UserData.ASCII_MAP_BASE_INDEX) &&
-                        (charCode <= UserData.ASCII_MAP_MAX_INDEX)) {
-                    strBuf.append(UserData.ASCII_MAP[charCode - UserData.ASCII_MAP_BASE_INDEX]);
-                } else if (charCode == UserData.ASCII_NL_INDEX) {
-                    strBuf.append('\n');
-                } else if (charCode == UserData.ASCII_CR_INDEX) {
-                    strBuf.append('\r');
-                } else {
-                    /* For other charCodes, they are unprintable, and so simply use SPACE. */
-                    strBuf.append(' ');
-                }
-            }
-            return strBuf.toString();
-        } catch (BitwiseInputStream.AccessException ex) {
-            throw new CodingException("7bit ASCII decode failed: " + ex);
-        }
-    }
-
-    private static String decode7bitGsm(byte[] data, int offset, int numFields)
-        throws CodingException
-    {
-        // Start reading from the next 7-bit aligned boundary after offset.
-        int offsetBits = offset * 8;
-        int offsetSeptets = (offsetBits + 6) / 7;
-        numFields -= offsetSeptets;
-        int paddingBits = (offsetSeptets * 7) - offsetBits;
-        String result = GsmAlphabet.gsm7BitPackedToString(data, offset, numFields, paddingBits,
-                0, 0);
-        if (result == null) {
-            throw new CodingException("7bit GSM decoding failed");
-        }
-        return result;
-    }
-
-    private static String decodeLatin(byte[] data, int offset, int numFields)
-        throws CodingException
-    {
-        return decodeCharset(data, offset, numFields, 1, "ISO-8859-1");
-    }
-
-    private static void decodeUserDataPayload(UserData userData, boolean hasUserDataHeader)
-        throws CodingException
-    {
-        int offset = 0;
-        if (hasUserDataHeader) {
-            int udhLen = userData.payload[0] & 0x00FF;
-            offset += udhLen + 1;
-            byte[] headerData = new byte[udhLen];
-            System.arraycopy(userData.payload, 1, headerData, 0, udhLen);
-            userData.userDataHeader = SmsHeader.fromByteArray(headerData);
-        }
-        switch (userData.msgEncoding) {
-        case UserData.ENCODING_OCTET:
-            /*
-            *  Octet decoding depends on the carrier service.
-            */
-            boolean decodingtypeUTF8 = Resources.getSystem()
-                    .getBoolean(com.android.internal.R.bool.config_sms_utf8_support);
-
-            // Strip off any padding bytes, meaning any differences between the length of the
-            // array and the target length specified by numFields.  This is to avoid any
-            // confusion by code elsewhere that only considers the payload array length.
-            byte[] payload = new byte[userData.numFields];
-            int copyLen = userData.numFields < userData.payload.length
-                    ? userData.numFields : userData.payload.length;
-
-            System.arraycopy(userData.payload, 0, payload, 0, copyLen);
-            userData.payload = payload;
-
-            if (!decodingtypeUTF8) {
-                // There are many devices in the market that send 8bit text sms (latin encoded) as
-                // octet encoded.
-                userData.payloadStr = decodeLatin(userData.payload, offset, userData.numFields);
-            } else {
-                userData.payloadStr = decodeUtf8(userData.payload, offset, userData.numFields);
-            }
-            break;
-
-        case UserData.ENCODING_IA5:
-        case UserData.ENCODING_7BIT_ASCII:
-            userData.payloadStr = decode7bitAscii(userData.payload, offset, userData.numFields);
-            break;
-        case UserData.ENCODING_UNICODE_16:
-            userData.payloadStr = decodeUtf16(userData.payload, offset, userData.numFields);
-            break;
-        case UserData.ENCODING_GSM_7BIT_ALPHABET:
-            userData.payloadStr = decode7bitGsm(userData.payload, offset, userData.numFields);
-            break;
-        case UserData.ENCODING_LATIN:
-            userData.payloadStr = decodeLatin(userData.payload, offset, userData.numFields);
-            break;
-        default:
-            throw new CodingException("unsupported user data encoding ("
-                                      + userData.msgEncoding + ")");
-        }
-    }
-
-    /**
-     * IS-91 Voice Mail message decoding
-     * (See 3GPP2 C.S0015-A, Table 4.3.1.4.1-1)
-     * (For character encodings, see TIA/EIA/IS-91, Annex B)
-     *
-     * Protocol Summary: The user data payload may contain 3-14
-     * characters.  The first two characters are parsed as a number
-     * and indicate the number of voicemails.  The third character is
-     * either a SPACE or '!' to indicate normal or urgent priority,
-     * respectively.  Any following characters are treated as normal
-     * text user data payload.
-     *
-     * Note that the characters encoding is 6-bit packed.
-     */
-    private static void decodeIs91VoicemailStatus(BearerData bData)
-        throws BitwiseInputStream.AccessException, CodingException
-    {
-        BitwiseInputStream inStream = new BitwiseInputStream(bData.userData.payload);
-        int dataLen = inStream.available() / 6;  // 6-bit packed character encoding.
-        int numFields = bData.userData.numFields;
-        if ((dataLen > 14) || (dataLen < 3) || (dataLen < numFields)) {
-            throw new CodingException("IS-91 voicemail status decoding failed");
-        }
-        try {
-            StringBuffer strbuf = new StringBuffer(dataLen);
-            while (inStream.available() >= 6) {
-                strbuf.append(UserData.ASCII_MAP[inStream.read(6)]);
-            }
-            String data = strbuf.toString();
-            bData.numberOfMessages = Integer.parseInt(data.substring(0, 2));
-            char prioCode = data.charAt(2);
-            if (prioCode == ' ') {
-                bData.priority = PRIORITY_NORMAL;
-            } else if (prioCode == '!') {
-                bData.priority = PRIORITY_URGENT;
-            } else {
-                throw new CodingException("IS-91 voicemail status decoding failed: " +
-                        "illegal priority setting (" + prioCode + ")");
-            }
-            bData.priorityIndicatorSet = true;
-            bData.userData.payloadStr = data.substring(3, numFields - 3);
-       } catch (java.lang.NumberFormatException ex) {
-            throw new CodingException("IS-91 voicemail status decoding failed: " + ex);
-        } catch (java.lang.IndexOutOfBoundsException ex) {
-            throw new CodingException("IS-91 voicemail status decoding failed: " + ex);
-        }
-    }
-
-    /**
-     * IS-91 Short Message decoding
-     * (See 3GPP2 C.S0015-A, Table 4.3.1.4.1-1)
-     * (For character encodings, see TIA/EIA/IS-91, Annex B)
-     *
-     * Protocol Summary: The user data payload may contain 1-14
-     * characters, which are treated as normal text user data payload.
-     * Note that the characters encoding is 6-bit packed.
-     */
-    private static void decodeIs91ShortMessage(BearerData bData)
-        throws BitwiseInputStream.AccessException, CodingException
-    {
-        BitwiseInputStream inStream = new BitwiseInputStream(bData.userData.payload);
-        int dataLen = inStream.available() / 6;  // 6-bit packed character encoding.
-        int numFields = bData.userData.numFields;
-        // dataLen may be > 14 characters due to octet padding
-        if ((numFields > 14) || (dataLen < numFields)) {
-            throw new CodingException("IS-91 short message decoding failed");
-        }
-        StringBuffer strbuf = new StringBuffer(dataLen);
-        for (int i = 0; i < numFields; i++) {
-            strbuf.append(UserData.ASCII_MAP[inStream.read(6)]);
-        }
-        bData.userData.payloadStr = strbuf.toString();
-    }
-
-    /**
-     * IS-91 CLI message (callback number) decoding
-     * (See 3GPP2 C.S0015-A, Table 4.3.1.4.1-1)
-     *
-     * Protocol Summary: The data payload may contain 1-32 digits,
-     * encoded using standard 4-bit DTMF, which are treated as a
-     * callback number.
-     */
-    private static void decodeIs91Cli(BearerData bData) throws CodingException {
-        BitwiseInputStream inStream = new BitwiseInputStream(bData.userData.payload);
-        int dataLen = inStream.available() / 4;  // 4-bit packed DTMF digit encoding.
-        int numFields = bData.userData.numFields;
-        if ((dataLen > 14) || (dataLen < 3) || (dataLen < numFields)) {
-            throw new CodingException("IS-91 voicemail status decoding failed");
-        }
-        CdmaSmsAddress addr = new CdmaSmsAddress();
-        addr.digitMode = CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF;
-        addr.origBytes = bData.userData.payload;
-        addr.numberOfDigits = (byte)numFields;
-        decodeSmsAddress(addr);
-        bData.callbackNumber = addr;
-    }
-
-    private static void decodeIs91(BearerData bData)
-        throws BitwiseInputStream.AccessException, CodingException
-    {
-        switch (bData.userData.msgType) {
-        case UserData.IS91_MSG_TYPE_VOICEMAIL_STATUS:
-            decodeIs91VoicemailStatus(bData);
-            break;
-        case UserData.IS91_MSG_TYPE_CLI:
-            decodeIs91Cli(bData);
-            break;
-        case UserData.IS91_MSG_TYPE_SHORT_MESSAGE_FULL:
-        case UserData.IS91_MSG_TYPE_SHORT_MESSAGE:
-            decodeIs91ShortMessage(bData);
-            break;
-        default:
-            throw new CodingException("unsupported IS-91 message type (" +
-                    bData.userData.msgType + ")");
-        }
-    }
-
-    private static boolean decodeReplyOption(BearerData bData, BitwiseInputStream inStream)
-        throws BitwiseInputStream.AccessException, CodingException
-    {
-        final int EXPECTED_PARAM_SIZE = 1 * 8;
-        boolean decodeSuccess = false;
-        int paramBits = inStream.read(8) * 8;
-        if (paramBits >= EXPECTED_PARAM_SIZE) {
-            paramBits -= EXPECTED_PARAM_SIZE;
-            decodeSuccess = true;
-            bData.userAckReq     = (inStream.read(1) == 1);
-            bData.deliveryAckReq = (inStream.read(1) == 1);
-            bData.readAckReq     = (inStream.read(1) == 1);
-            bData.reportReq      = (inStream.read(1) == 1);
-            inStream.skip(4);
-        }
-        if ((! decodeSuccess) || (paramBits > 0)) {
-            Log.d(LOG_TAG, "REPLY_OPTION decode " +
-                      (decodeSuccess ? "succeeded" : "failed") +
-                      " (extra bits = " + paramBits + ")");
-        }
-        inStream.skip(paramBits);
-        return decodeSuccess;
-    }
-
-    private static boolean decodeMsgCount(BearerData bData, BitwiseInputStream inStream)
-        throws BitwiseInputStream.AccessException, CodingException
-    {
-        final int EXPECTED_PARAM_SIZE = 1 * 8;
-        boolean decodeSuccess = false;
-        int paramBits = inStream.read(8) * 8;
-        if (paramBits >= EXPECTED_PARAM_SIZE) {
-            paramBits -= EXPECTED_PARAM_SIZE;
-            decodeSuccess = true;
-            bData.numberOfMessages = IccUtils.cdmaBcdByteToInt((byte)inStream.read(8));
-        }
-        if ((! decodeSuccess) || (paramBits > 0)) {
-            Log.d(LOG_TAG, "NUMBER_OF_MESSAGES decode " +
-                      (decodeSuccess ? "succeeded" : "failed") +
-                      " (extra bits = " + paramBits + ")");
-        }
-        inStream.skip(paramBits);
-        return decodeSuccess;
-    }
-
-    private static boolean decodeDepositIndex(BearerData bData, BitwiseInputStream inStream)
-        throws BitwiseInputStream.AccessException, CodingException
-    {
-        final int EXPECTED_PARAM_SIZE = 2 * 8;
-        boolean decodeSuccess = false;
-        int paramBits = inStream.read(8) * 8;
-        if (paramBits >= EXPECTED_PARAM_SIZE) {
-            paramBits -= EXPECTED_PARAM_SIZE;
-            decodeSuccess = true;
-            bData.depositIndex = (inStream.read(8) << 8) | inStream.read(8);
-        }
-        if ((! decodeSuccess) || (paramBits > 0)) {
-            Log.d(LOG_TAG, "MESSAGE_DEPOSIT_INDEX decode " +
-                      (decodeSuccess ? "succeeded" : "failed") +
-                      " (extra bits = " + paramBits + ")");
-        }
-        inStream.skip(paramBits);
-        return decodeSuccess;
-    }
-
-    private static String decodeDtmfSmsAddress(byte[] rawData, int numFields)
-        throws CodingException
-    {
-        /* DTMF 4-bit digit encoding, defined in at
-         * 3GPP2 C.S005-D, v2.0, table 2.7.1.3.2.4-4 */
-        StringBuffer strBuf = new StringBuffer(numFields);
-        for (int i = 0; i < numFields; i++) {
-            int val = 0x0F & (rawData[i / 2] >>> (4 - ((i % 2) * 4)));
-            if ((val >= 1) && (val <= 9)) strBuf.append(Integer.toString(val, 10));
-            else if (val == 10) strBuf.append('0');
-            else if (val == 11) strBuf.append('*');
-            else if (val == 12) strBuf.append('#');
-            else throw new CodingException("invalid SMS address DTMF code (" + val + ")");
-        }
-        return strBuf.toString();
-    }
-
-    private static void decodeSmsAddress(CdmaSmsAddress addr) throws CodingException {
-        if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
-            try {
-                /* As specified in 3GPP2 C.S0015-B, v2, 4.5.15 -- actually
-                 * just 7-bit ASCII encoding, with the MSB being zero. */
-                addr.address = new String(addr.origBytes, 0, addr.origBytes.length, "US-ASCII");
-            } catch (java.io.UnsupportedEncodingException ex) {
-                throw new CodingException("invalid SMS address ASCII code");
-            }
-        } else {
-            addr.address = decodeDtmfSmsAddress(addr.origBytes, addr.numberOfDigits);
-        }
-    }
-
-    private static boolean decodeCallbackNumber(BearerData bData, BitwiseInputStream inStream)
-        throws BitwiseInputStream.AccessException, CodingException
-    {
-        int paramBits = inStream.read(8) * 8;
-        CdmaSmsAddress addr = new CdmaSmsAddress();
-        addr.digitMode = inStream.read(1);
-        byte fieldBits = 4;
-        byte consumedBits = 1;
-        if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
-            addr.ton = inStream.read(3);
-            addr.numberPlan = inStream.read(4);
-            fieldBits = 8;
-            consumedBits += 7;
-        }
-        addr.numberOfDigits = inStream.read(8);
-        consumedBits += 8;
-        int remainingBits = paramBits - consumedBits;
-        int dataBits = addr.numberOfDigits * fieldBits;
-        int paddingBits = remainingBits - dataBits;
-        if (remainingBits < dataBits) {
-            throw new CodingException("CALLBACK_NUMBER subparam encoding size error (" +
-                                      "remainingBits + " + remainingBits + ", dataBits + " +
-                                      dataBits + ", paddingBits + " + paddingBits + ")");
-        }
-        addr.origBytes = inStream.readByteArray(dataBits);
-        inStream.skip(paddingBits);
-        decodeSmsAddress(addr);
-        bData.callbackNumber = addr;
-        return true;
-    }
-
-    private static boolean decodeMsgStatus(BearerData bData, BitwiseInputStream inStream)
-        throws BitwiseInputStream.AccessException, CodingException
-    {
-        final int EXPECTED_PARAM_SIZE = 1 * 8;
-        boolean decodeSuccess = false;
-        int paramBits = inStream.read(8) * 8;
-        if (paramBits >= EXPECTED_PARAM_SIZE) {
-            paramBits -= EXPECTED_PARAM_SIZE;
-            decodeSuccess = true;
-            bData.errorClass = inStream.read(2);
-            bData.messageStatus = inStream.read(6);
-        }
-        if ((! decodeSuccess) || (paramBits > 0)) {
-            Log.d(LOG_TAG, "MESSAGE_STATUS decode " +
-                      (decodeSuccess ? "succeeded" : "failed") +
-                      " (extra bits = " + paramBits + ")");
-        }
-        inStream.skip(paramBits);
-        bData.messageStatusSet = decodeSuccess;
-        return decodeSuccess;
-    }
-
-    private static boolean decodeMsgCenterTimeStamp(BearerData bData, BitwiseInputStream inStream)
-        throws BitwiseInputStream.AccessException, CodingException
-    {
-        final int EXPECTED_PARAM_SIZE = 6 * 8;
-        boolean decodeSuccess = false;
-        int paramBits = inStream.read(8) * 8;
-        if (paramBits >= EXPECTED_PARAM_SIZE) {
-            paramBits -= EXPECTED_PARAM_SIZE;
-            decodeSuccess = true;
-            bData.msgCenterTimeStamp = TimeStamp.fromByteArray(inStream.readByteArray(6 * 8));
-        }
-        if ((! decodeSuccess) || (paramBits > 0)) {
-            Log.d(LOG_TAG, "MESSAGE_CENTER_TIME_STAMP decode " +
-                      (decodeSuccess ? "succeeded" : "failed") +
-                      " (extra bits = " + paramBits + ")");
-        }
-        inStream.skip(paramBits);
-        return decodeSuccess;
-    }
-
-    private static boolean decodeValidityAbs(BearerData bData, BitwiseInputStream inStream)
-        throws BitwiseInputStream.AccessException, CodingException
-    {
-        final int EXPECTED_PARAM_SIZE = 6 * 8;
-        boolean decodeSuccess = false;
-        int paramBits = inStream.read(8) * 8;
-        if (paramBits >= EXPECTED_PARAM_SIZE) {
-            paramBits -= EXPECTED_PARAM_SIZE;
-            decodeSuccess = true;
-            bData.validityPeriodAbsolute = TimeStamp.fromByteArray(inStream.readByteArray(6 * 8));
-        }
-        if ((! decodeSuccess) || (paramBits > 0)) {
-            Log.d(LOG_TAG, "VALIDITY_PERIOD_ABSOLUTE decode " +
-                      (decodeSuccess ? "succeeded" : "failed") +
-                      " (extra bits = " + paramBits + ")");
-        }
-        inStream.skip(paramBits);
-        return decodeSuccess;
-    }
-
-    private static boolean decodeDeferredDeliveryAbs(BearerData bData, BitwiseInputStream inStream)
-        throws BitwiseInputStream.AccessException, CodingException
-    {
-        final int EXPECTED_PARAM_SIZE = 6 * 8;
-        boolean decodeSuccess = false;
-        int paramBits = inStream.read(8) * 8;
-        if (paramBits >= EXPECTED_PARAM_SIZE) {
-            paramBits -= EXPECTED_PARAM_SIZE;
-            decodeSuccess = true;
-            bData.deferredDeliveryTimeAbsolute = TimeStamp.fromByteArray(
-                    inStream.readByteArray(6 * 8));
-        }
-        if ((! decodeSuccess) || (paramBits > 0)) {
-            Log.d(LOG_TAG, "DEFERRED_DELIVERY_TIME_ABSOLUTE decode " +
-                      (decodeSuccess ? "succeeded" : "failed") +
-                      " (extra bits = " + paramBits + ")");
-        }
-        inStream.skip(paramBits);
-        return decodeSuccess;
-    }
-
-    private static boolean decodeValidityRel(BearerData bData, BitwiseInputStream inStream)
-        throws BitwiseInputStream.AccessException, CodingException
-    {
-        final int EXPECTED_PARAM_SIZE = 1 * 8;
-        boolean decodeSuccess = false;
-        int paramBits = inStream.read(8) * 8;
-        if (paramBits >= EXPECTED_PARAM_SIZE) {
-            paramBits -= EXPECTED_PARAM_SIZE;
-            decodeSuccess = true;
-            bData.deferredDeliveryTimeRelative = inStream.read(8);
-        }
-        if ((! decodeSuccess) || (paramBits > 0)) {
-            Log.d(LOG_TAG, "VALIDITY_PERIOD_RELATIVE decode " +
-                      (decodeSuccess ? "succeeded" : "failed") +
-                      " (extra bits = " + paramBits + ")");
-        }
-        inStream.skip(paramBits);
-        bData.deferredDeliveryTimeRelativeSet = decodeSuccess;
-        return decodeSuccess;
-    }
-
-    private static boolean decodeDeferredDeliveryRel(BearerData bData, BitwiseInputStream inStream)
-        throws BitwiseInputStream.AccessException, CodingException
-    {
-        final int EXPECTED_PARAM_SIZE = 1 * 8;
-        boolean decodeSuccess = false;
-        int paramBits = inStream.read(8) * 8;
-        if (paramBits >= EXPECTED_PARAM_SIZE) {
-            paramBits -= EXPECTED_PARAM_SIZE;
-            decodeSuccess = true;
-            bData.validityPeriodRelative = inStream.read(8);
-        }
-        if ((! decodeSuccess) || (paramBits > 0)) {
-            Log.d(LOG_TAG, "DEFERRED_DELIVERY_TIME_RELATIVE decode " +
-                      (decodeSuccess ? "succeeded" : "failed") +
-                      " (extra bits = " + paramBits + ")");
-        }
-        inStream.skip(paramBits);
-        bData.validityPeriodRelativeSet = decodeSuccess;
-        return decodeSuccess;
-    }
-
-    private static boolean decodePrivacyIndicator(BearerData bData, BitwiseInputStream inStream)
-        throws BitwiseInputStream.AccessException, CodingException
-    {
-        final int EXPECTED_PARAM_SIZE = 1 * 8;
-        boolean decodeSuccess = false;
-        int paramBits = inStream.read(8) * 8;
-        if (paramBits >= EXPECTED_PARAM_SIZE) {
-            paramBits -= EXPECTED_PARAM_SIZE;
-            decodeSuccess = true;
-            bData.privacy = inStream.read(2);
-            inStream.skip(6);
-        }
-        if ((! decodeSuccess) || (paramBits > 0)) {
-            Log.d(LOG_TAG, "PRIVACY_INDICATOR decode " +
-                      (decodeSuccess ? "succeeded" : "failed") +
-                      " (extra bits = " + paramBits + ")");
-        }
-        inStream.skip(paramBits);
-        bData.privacyIndicatorSet = decodeSuccess;
-        return decodeSuccess;
-    }
-
-    private static boolean decodeLanguageIndicator(BearerData bData, BitwiseInputStream inStream)
-        throws BitwiseInputStream.AccessException, CodingException
-    {
-        final int EXPECTED_PARAM_SIZE = 1 * 8;
-        boolean decodeSuccess = false;
-        int paramBits = inStream.read(8) * 8;
-        if (paramBits >= EXPECTED_PARAM_SIZE) {
-            paramBits -= EXPECTED_PARAM_SIZE;
-            decodeSuccess = true;
-            bData.language = inStream.read(8);
-        }
-        if ((! decodeSuccess) || (paramBits > 0)) {
-            Log.d(LOG_TAG, "LANGUAGE_INDICATOR decode " +
-                      (decodeSuccess ? "succeeded" : "failed") +
-                      " (extra bits = " + paramBits + ")");
-        }
-        inStream.skip(paramBits);
-        bData.languageIndicatorSet = decodeSuccess;
-        return decodeSuccess;
-    }
-
-    private static boolean decodeDisplayMode(BearerData bData, BitwiseInputStream inStream)
-        throws BitwiseInputStream.AccessException, CodingException
-    {
-        final int EXPECTED_PARAM_SIZE = 1 * 8;
-        boolean decodeSuccess = false;
-        int paramBits = inStream.read(8) * 8;
-        if (paramBits >= EXPECTED_PARAM_SIZE) {
-            paramBits -= EXPECTED_PARAM_SIZE;
-            decodeSuccess = true;
-            bData.displayMode = inStream.read(2);
-            inStream.skip(6);
-        }
-        if ((! decodeSuccess) || (paramBits > 0)) {
-            Log.d(LOG_TAG, "DISPLAY_MODE decode " +
-                      (decodeSuccess ? "succeeded" : "failed") +
-                      " (extra bits = " + paramBits + ")");
-        }
-        inStream.skip(paramBits);
-        bData.displayModeSet = decodeSuccess;
-        return decodeSuccess;
-    }
-
-    private static boolean decodePriorityIndicator(BearerData bData, BitwiseInputStream inStream)
-        throws BitwiseInputStream.AccessException, CodingException
-    {
-        final int EXPECTED_PARAM_SIZE = 1 * 8;
-        boolean decodeSuccess = false;
-        int paramBits = inStream.read(8) * 8;
-        if (paramBits >= EXPECTED_PARAM_SIZE) {
-            paramBits -= EXPECTED_PARAM_SIZE;
-            decodeSuccess = true;
-            bData.priority = inStream.read(2);
-            inStream.skip(6);
-        }
-        if ((! decodeSuccess) || (paramBits > 0)) {
-            Log.d(LOG_TAG, "PRIORITY_INDICATOR decode " +
-                      (decodeSuccess ? "succeeded" : "failed") +
-                      " (extra bits = " + paramBits + ")");
-        }
-        inStream.skip(paramBits);
-        bData.priorityIndicatorSet = decodeSuccess;
-        return decodeSuccess;
-    }
-
-    private static boolean decodeMsgDeliveryAlert(BearerData bData, BitwiseInputStream inStream)
-        throws BitwiseInputStream.AccessException, CodingException
-    {
-        final int EXPECTED_PARAM_SIZE = 1 * 8;
-        boolean decodeSuccess = false;
-        int paramBits = inStream.read(8) * 8;
-        if (paramBits >= EXPECTED_PARAM_SIZE) {
-            paramBits -= EXPECTED_PARAM_SIZE;
-            decodeSuccess = true;
-            bData.alert = inStream.read(2);
-            inStream.skip(6);
-        }
-        if ((! decodeSuccess) || (paramBits > 0)) {
-            Log.d(LOG_TAG, "ALERT_ON_MESSAGE_DELIVERY decode " +
-                      (decodeSuccess ? "succeeded" : "failed") +
-                      " (extra bits = " + paramBits + ")");
-        }
-        inStream.skip(paramBits);
-        bData.alertIndicatorSet = decodeSuccess;
-        return decodeSuccess;
-    }
-
-    private static boolean decodeUserResponseCode(BearerData bData, BitwiseInputStream inStream)
-        throws BitwiseInputStream.AccessException, CodingException
-    {
-        final int EXPECTED_PARAM_SIZE = 1 * 8;
-        boolean decodeSuccess = false;
-        int paramBits = inStream.read(8) * 8;
-        if (paramBits >= EXPECTED_PARAM_SIZE) {
-            paramBits -= EXPECTED_PARAM_SIZE;
-            decodeSuccess = true;
-            bData.userResponseCode = inStream.read(8);
-        }
-        if ((! decodeSuccess) || (paramBits > 0)) {
-            Log.d(LOG_TAG, "USER_RESPONSE_CODE decode " +
-                      (decodeSuccess ? "succeeded" : "failed") +
-                      " (extra bits = " + paramBits + ")");
-        }
-        inStream.skip(paramBits);
-        bData.userResponseCodeSet = decodeSuccess;
-        return decodeSuccess;
-    }
-
-    private static boolean decodeServiceCategoryProgramData(BearerData bData,
-            BitwiseInputStream inStream) throws BitwiseInputStream.AccessException, CodingException
-    {
-        if (inStream.available() < 13) {
-            throw new CodingException("SERVICE_CATEGORY_PROGRAM_DATA decode failed: only "
-                    + inStream.available() + " bits available");
-        }
-
-        int paramBits = inStream.read(8) * 8;
-        int msgEncoding = inStream.read(5);
-        paramBits -= 5;
-
-        if (inStream.available() < paramBits) {
-            throw new CodingException("SERVICE_CATEGORY_PROGRAM_DATA decode failed: only "
-                    + inStream.available() + " bits available (" + paramBits + " bits expected)");
-        }
-
-        ArrayList<CdmaSmsCbProgramData> programDataList = new ArrayList<CdmaSmsCbProgramData>();
-
-        final int CATEGORY_FIELD_MIN_SIZE = 6 * 8;
-        boolean decodeSuccess = false;
-        while (paramBits >= CATEGORY_FIELD_MIN_SIZE) {
-            int operation = inStream.read(4);
-            int category = (inStream.read(8) << 8) | inStream.read(8);
-            int language = inStream.read(8);
-            int maxMessages = inStream.read(8);
-            int alertOption = inStream.read(4);
-            int numFields = inStream.read(8);
-            paramBits -= CATEGORY_FIELD_MIN_SIZE;
-
-            int textBits = getBitsForNumFields(msgEncoding, numFields);
-            if (paramBits < textBits) {
-                throw new CodingException("category name is " + textBits + " bits in length,"
-                        + " but there are only " + paramBits + " bits available");
-            }
-
-            UserData userData = new UserData();
-            userData.msgEncoding = msgEncoding;
-            userData.msgEncodingSet = true;
-            userData.numFields = numFields;
-            userData.payload = inStream.readByteArray(textBits);
-            paramBits -= textBits;
-
-            decodeUserDataPayload(userData, false);
-            String categoryName = userData.payloadStr;
-            CdmaSmsCbProgramData programData = new CdmaSmsCbProgramData(operation, category,
-                    language, maxMessages, alertOption, categoryName);
-            programDataList.add(programData);
-
-            decodeSuccess = true;
-        }
-
-        if ((! decodeSuccess) || (paramBits > 0)) {
-            Log.d(LOG_TAG, "SERVICE_CATEGORY_PROGRAM_DATA decode " +
-                      (decodeSuccess ? "succeeded" : "failed") +
-                      " (extra bits = " + paramBits + ')');
-        }
-
-        inStream.skip(paramBits);
-        bData.serviceCategoryProgramData = programDataList;
-        return decodeSuccess;
-    }
-
-    private static int serviceCategoryToCmasMessageClass(int serviceCategory) {
-        switch (serviceCategory) {
-            case SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT:
-                return SmsCbCmasInfo.CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT;
-
-            case SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT:
-                return SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT;
-
-            case SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT:
-                return SmsCbCmasInfo.CMAS_CLASS_SEVERE_THREAT;
-
-            case SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY:
-                return SmsCbCmasInfo.CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY;
-
-            case SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE:
-                return SmsCbCmasInfo.CMAS_CLASS_REQUIRED_MONTHLY_TEST;
-
-            default:
-                return SmsCbCmasInfo.CMAS_CLASS_UNKNOWN;
-        }
-    }
-
-    /**
-     * Calculates the number of bits to read for the specified number of encoded characters.
-     * @param msgEncoding the message encoding to use
-     * @param numFields the number of characters to read. For Shift-JIS and Korean encodings,
-     *  this is the number of bytes to read.
-     * @return the number of bits to read from the stream
-     * @throws CodingException if the specified encoding is not supported
-     */
-    private static int getBitsForNumFields(int msgEncoding, int numFields)
-            throws CodingException {
-        switch (msgEncoding) {
-            case UserData.ENCODING_OCTET:
-            case UserData.ENCODING_SHIFT_JIS:
-            case UserData.ENCODING_KOREAN:
-            case UserData.ENCODING_LATIN:
-            case UserData.ENCODING_LATIN_HEBREW:
-                return numFields * 8;
-
-            case UserData.ENCODING_IA5:
-            case UserData.ENCODING_7BIT_ASCII:
-            case UserData.ENCODING_GSM_7BIT_ALPHABET:
-                return numFields * 7;
-
-            case UserData.ENCODING_UNICODE_16:
-                return numFields * 16;
-
-            default:
-                throw new CodingException("unsupported message encoding (" + msgEncoding + ')');
-        }
-    }
-
-    /**
-     * CMAS message decoding.
-     * (See TIA-1149-0-1, CMAS over CDMA)
-     *
-     * @param serviceCategory is the service category from the SMS envelope
-     */
-    private static void decodeCmasUserData(BearerData bData, int serviceCategory)
-            throws BitwiseInputStream.AccessException, CodingException {
-        BitwiseInputStream inStream = new BitwiseInputStream(bData.userData.payload);
-        if (inStream.available() < 8) {
-            throw new CodingException("emergency CB with no CMAE_protocol_version");
-        }
-        int protocolVersion = inStream.read(8);
-        if (protocolVersion != 0) {
-            throw new CodingException("unsupported CMAE_protocol_version " + protocolVersion);
-        }
-
-        int messageClass = serviceCategoryToCmasMessageClass(serviceCategory);
-        int category = SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN;
-        int responseType = SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN;
-        int severity = SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN;
-        int urgency = SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN;
-        int certainty = SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN;
-
-        while (inStream.available() >= 16) {
-            int recordType = inStream.read(8);
-            int recordLen = inStream.read(8);
-            switch (recordType) {
-                case 0:     // Type 0 elements (Alert text)
-                    UserData alertUserData = new UserData();
-                    alertUserData.msgEncoding = inStream.read(5);
-                    alertUserData.msgEncodingSet = true;
-                    alertUserData.msgType = 0;
-
-                    int numFields;                          // number of chars to decode
-                    switch (alertUserData.msgEncoding) {
-                        case UserData.ENCODING_OCTET:
-                        case UserData.ENCODING_LATIN:
-                            numFields = recordLen - 1;      // subtract 1 byte for encoding
-                            break;
-
-                        case UserData.ENCODING_IA5:
-                        case UserData.ENCODING_7BIT_ASCII:
-                        case UserData.ENCODING_GSM_7BIT_ALPHABET:
-                            numFields = ((recordLen * 8) - 5) / 7;  // subtract 5 bits for encoding
-                            break;
-
-                        case UserData.ENCODING_UNICODE_16:
-                            numFields = (recordLen - 1) / 2;
-                            break;
-
-                        default:
-                            numFields = 0;      // unsupported encoding
-                    }
-
-                    alertUserData.numFields = numFields;
-                    alertUserData.payload = inStream.readByteArray(recordLen * 8 - 5);
-                    decodeUserDataPayload(alertUserData, false);
-                    bData.userData = alertUserData;
-                    break;
-
-                case 1:     // Type 1 elements
-                    category = inStream.read(8);
-                    responseType = inStream.read(8);
-                    severity = inStream.read(4);
-                    urgency = inStream.read(4);
-                    certainty = inStream.read(4);
-                    inStream.skip(recordLen * 8 - 28);
-                    break;
-
-                default:
-                    Log.w(LOG_TAG, "skipping unsupported CMAS record type " + recordType);
-                    inStream.skip(recordLen * 8);
-                    break;
-            }
-        }
-
-        bData.cmasWarningInfo = new SmsCbCmasInfo(messageClass, category, responseType, severity,
-                urgency, certainty);
-    }
-
-    /**
-     * Create BearerData object from serialized representation.
-     * (See 3GPP2 C.R1001-F, v1.0, section 4.5 for layout details)
-     *
-     * @param smsData byte array of raw encoded SMS bearer data.
-     * @return an instance of BearerData.
-     */
-    public static BearerData decode(byte[] smsData) {
-        return decode(smsData, 0);
-    }
-
-    private static boolean isCmasAlertCategory(int category) {
-        return category >= SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT
-                && category <= SmsEnvelope.SERVICE_CATEGORY_CMAS_LAST_RESERVED_VALUE;
-    }
-
-    /**
-     * Create BearerData object from serialized representation.
-     * (See 3GPP2 C.R1001-F, v1.0, section 4.5 for layout details)
-     *
-     * @param smsData byte array of raw encoded SMS bearer data.
-     * @param serviceCategory the envelope service category (for CMAS alert handling)
-     * @return an instance of BearerData.
-     */
-    public static BearerData decode(byte[] smsData, int serviceCategory) {
-        try {
-            BitwiseInputStream inStream = new BitwiseInputStream(smsData);
-            BearerData bData = new BearerData();
-            int foundSubparamMask = 0;
-            while (inStream.available() > 0) {
-                int subparamId = inStream.read(8);
-                int subparamIdBit = 1 << subparamId;
-                if ((foundSubparamMask & subparamIdBit) != 0) {
-                    throw new CodingException("illegal duplicate subparameter (" +
-                                              subparamId + ")");
-                }
-                boolean decodeSuccess;
-                switch (subparamId) {
-                case SUBPARAM_MESSAGE_IDENTIFIER:
-                    decodeSuccess = decodeMessageId(bData, inStream);
-                    break;
-                case SUBPARAM_USER_DATA:
-                    decodeSuccess = decodeUserData(bData, inStream);
-                    break;
-                case SUBPARAM_USER_RESPONSE_CODE:
-                    decodeSuccess = decodeUserResponseCode(bData, inStream);
-                    break;
-                case SUBPARAM_REPLY_OPTION:
-                    decodeSuccess = decodeReplyOption(bData, inStream);
-                    break;
-                case SUBPARAM_NUMBER_OF_MESSAGES:
-                    decodeSuccess = decodeMsgCount(bData, inStream);
-                    break;
-                case SUBPARAM_CALLBACK_NUMBER:
-                    decodeSuccess = decodeCallbackNumber(bData, inStream);
-                    break;
-                case SUBPARAM_MESSAGE_STATUS:
-                    decodeSuccess = decodeMsgStatus(bData, inStream);
-                    break;
-                case SUBPARAM_MESSAGE_CENTER_TIME_STAMP:
-                    decodeSuccess = decodeMsgCenterTimeStamp(bData, inStream);
-                    break;
-                case SUBPARAM_VALIDITY_PERIOD_ABSOLUTE:
-                    decodeSuccess = decodeValidityAbs(bData, inStream);
-                    break;
-                case SUBPARAM_VALIDITY_PERIOD_RELATIVE:
-                    decodeSuccess = decodeValidityRel(bData, inStream);
-                    break;
-                case SUBPARAM_DEFERRED_DELIVERY_TIME_ABSOLUTE:
-                    decodeSuccess = decodeDeferredDeliveryAbs(bData, inStream);
-                    break;
-                case SUBPARAM_DEFERRED_DELIVERY_TIME_RELATIVE:
-                    decodeSuccess = decodeDeferredDeliveryRel(bData, inStream);
-                    break;
-                case SUBPARAM_PRIVACY_INDICATOR:
-                    decodeSuccess = decodePrivacyIndicator(bData, inStream);
-                    break;
-                case SUBPARAM_LANGUAGE_INDICATOR:
-                    decodeSuccess = decodeLanguageIndicator(bData, inStream);
-                    break;
-                case SUBPARAM_MESSAGE_DISPLAY_MODE:
-                    decodeSuccess = decodeDisplayMode(bData, inStream);
-                    break;
-                case SUBPARAM_PRIORITY_INDICATOR:
-                    decodeSuccess = decodePriorityIndicator(bData, inStream);
-                    break;
-                case SUBPARAM_ALERT_ON_MESSAGE_DELIVERY:
-                    decodeSuccess = decodeMsgDeliveryAlert(bData, inStream);
-                    break;
-                case SUBPARAM_MESSAGE_DEPOSIT_INDEX:
-                    decodeSuccess = decodeDepositIndex(bData, inStream);
-                    break;
-                case SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA:
-                    decodeSuccess = decodeServiceCategoryProgramData(bData, inStream);
-                    break;
-                default:
-                    throw new CodingException("unsupported bearer data subparameter ("
-                                              + subparamId + ")");
-                }
-                if (decodeSuccess) foundSubparamMask |= subparamIdBit;
-            }
-            if ((foundSubparamMask & (1 << SUBPARAM_MESSAGE_IDENTIFIER)) == 0) {
-                throw new CodingException("missing MESSAGE_IDENTIFIER subparam");
-            }
-            if (bData.userData != null) {
-                if (isCmasAlertCategory(serviceCategory)) {
-                    decodeCmasUserData(bData, serviceCategory);
-                } else if (bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) {
-                    if ((foundSubparamMask ^
-                             (1 << SUBPARAM_MESSAGE_IDENTIFIER) ^
-                             (1 << SUBPARAM_USER_DATA))
-                            != 0) {
-                        Log.e(LOG_TAG, "IS-91 must occur without extra subparams (" +
-                              foundSubparamMask + ")");
-                    }
-                    decodeIs91(bData);
-                } else {
-                    decodeUserDataPayload(bData.userData, bData.hasUserDataHeader);
-                }
-            }
-            return bData;
-        } catch (BitwiseInputStream.AccessException ex) {
-            Log.e(LOG_TAG, "BearerData decode failed: " + ex);
-        } catch (CodingException ex) {
-            Log.e(LOG_TAG, "BearerData decode failed: " + ex);
-        }
-        return null;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java b/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java
deleted file mode 100644
index 5f2e561..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * 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.internal.telephony.cdma.sms;
-
-import android.util.SparseBooleanArray;
-
-import com.android.internal.telephony.SmsAddress;
-import com.android.internal.telephony.cdma.sms.UserData;
-import com.android.internal.util.HexDump;
-
-public class CdmaSmsAddress extends SmsAddress {
-
-    /**
-     * Digit Mode Indicator is a 1-bit value that indicates whether
-     * the address digits are 4-bit DTMF codes or 8-bit codes.  (See
-     * 3GPP2 C.S0015-B, v2, 3.4.3.3)
-     */
-    static public final int DIGIT_MODE_4BIT_DTMF              = 0x00;
-    static public final int DIGIT_MODE_8BIT_CHAR              = 0x01;
-
-    public int digitMode;
-
-    /**
-     * Number Mode Indicator is 1-bit value that indicates whether the
-     * address type is a data network address or not.  (See 3GPP2
-     * C.S0015-B, v2, 3.4.3.3)
-     */
-    static public final int NUMBER_MODE_NOT_DATA_NETWORK      = 0x00;
-    static public final int NUMBER_MODE_DATA_NETWORK          = 0x01;
-
-    public int numberMode;
-
-    /**
-     * Number Types for data networks.
-     * (See 3GPP2 C.S005-D, table2.7.1.3.2.4-2 for complete table)
-     * (See 3GPP2 C.S0015-B, v2, 3.4.3.3 for data network subset)
-     * NOTE: value is stored in the parent class ton field.
-     */
-    static public final int TON_UNKNOWN                   = 0x00;
-    static public final int TON_INTERNATIONAL_OR_IP       = 0x01;
-    static public final int TON_NATIONAL_OR_EMAIL         = 0x02;
-    static public final int TON_NETWORK                   = 0x03;
-    static public final int TON_SUBSCRIBER                = 0x04;
-    static public final int TON_ALPHANUMERIC              = 0x05;
-    static public final int TON_ABBREVIATED               = 0x06;
-    static public final int TON_RESERVED                  = 0x07;
-
-    /**
-     * Maximum lengths for fields as defined in ril_cdma_sms.h.
-     */
-    static public final int SMS_ADDRESS_MAX          =  36;
-    static public final int SMS_SUBADDRESS_MAX       =  36;
-
-    /**
-     * This field shall be set to the number of address digits
-     * (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
-     */
-    public int numberOfDigits;
-
-    /**
-     * Numbering Plan identification is a 0 or 4-bit value that
-     * indicates which numbering plan identification is set.  (See
-     * 3GPP2, C.S0015-B, v2, 3.4.3.3 and C.S005-D, table2.7.1.3.2.4-3)
-     */
-    static public final int NUMBERING_PLAN_UNKNOWN           = 0x0;
-    static public final int NUMBERING_PLAN_ISDN_TELEPHONY    = 0x1;
-    //static protected final int NUMBERING_PLAN_DATA              = 0x3;
-    //static protected final int NUMBERING_PLAN_TELEX             = 0x4;
-    //static protected final int NUMBERING_PLAN_PRIVATE           = 0x9;
-
-    public int numberPlan;
-
-    /**
-     * NOTE: the parsed string address and the raw byte array values
-     * are stored in the parent class address and origBytes fields,
-     * respectively.
-     */
-
-    public CdmaSmsAddress(){
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder builder = new StringBuilder();
-        builder.append("CdmaSmsAddress ");
-        builder.append("{ digitMode=" + digitMode);
-        builder.append(", numberMode=" + numberMode);
-        builder.append(", numberPlan=" + numberPlan);
-        builder.append(", numberOfDigits=" + numberOfDigits);
-        builder.append(", ton=" + ton);
-        builder.append(", address=\"" + address + "\"");
-        builder.append(", origBytes=" + HexDump.toHexString(origBytes));
-        builder.append(" }");
-        return builder.toString();
-    }
-
-    /*
-     * TODO(cleanup): Refactor the parsing for addresses to better
-     * share code and logic with GSM.  Also, gather all DTMF/BCD
-     * processing code in one place.
-     */
-
-    private static byte[] parseToDtmf(String address) {
-        int digits = address.length();
-        byte[] result = new byte[digits];
-        for (int i = 0; i < digits; i++) {
-            char c = address.charAt(i);
-            int val = 0;
-            if ((c >= '1') && (c <= '9')) val = c - '0';
-            else if (c == '0') val = 10;
-            else if (c == '*') val = 11;
-            else if (c == '#') val = 12;
-            else return null;
-            result[i] = (byte)val;
-        }
-        return result;
-    }
-
-    private static final char[] numericCharsDialable = {
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '#'
-    };
-
-    private static final char[] numericCharsSugar = {
-        '(', ')', ' ', '-', '+', '.', '/', '\\'
-    };
-
-    private static final SparseBooleanArray numericCharDialableMap = new SparseBooleanArray (
-            numericCharsDialable.length + numericCharsSugar.length);
-    static {
-        for (int i = 0; i < numericCharsDialable.length; i++) {
-            numericCharDialableMap.put(numericCharsDialable[i], true);
-        }
-        for (int i = 0; i < numericCharsSugar.length; i++) {
-            numericCharDialableMap.put(numericCharsSugar[i], false);
-        }
-    }
-
-    /**
-     * Given a numeric address string, return the string without
-     * syntactic sugar, meaning parens, spaces, hyphens/minuses, or
-     * plus signs.  If the input string contains non-numeric
-     * non-punctuation characters, return null.
-     */
-    private static String filterNumericSugar(String address) {
-        StringBuilder builder = new StringBuilder();
-        int len = address.length();
-        for (int i = 0; i < len; i++) {
-            char c = address.charAt(i);
-            int mapIndex = numericCharDialableMap.indexOfKey(c);
-            if (mapIndex < 0) return null;
-            if (! numericCharDialableMap.valueAt(mapIndex)) continue;
-            builder.append(c);
-        }
-        return builder.toString();
-    }
-
-    /**
-     * Given a string, return the string without whitespace,
-     * including CR/LF.
-     */
-    private static String filterWhitespace(String address) {
-        StringBuilder builder = new StringBuilder();
-        int len = address.length();
-        for (int i = 0; i < len; i++) {
-            char c = address.charAt(i);
-            if ((c == ' ') || (c == '\r') || (c == '\n') || (c == '\t')) continue;
-            builder.append(c);
-        }
-        return builder.toString();
-    }
-
-    /**
-     * Given a string, create a corresponding CdmaSmsAddress object.
-     *
-     * The result will be null if the input string is not
-     * representable using printable ASCII.
-     *
-     * For numeric addresses, the string is cleaned up by removing
-     * common punctuation.  For alpha addresses, the string is cleaned
-     * up by removing whitespace.
-     */
-    public static CdmaSmsAddress parse(String address) {
-        CdmaSmsAddress addr = new CdmaSmsAddress();
-        addr.address = address;
-        addr.ton = CdmaSmsAddress.TON_UNKNOWN;
-        byte[] origBytes = null;
-        String filteredAddr = filterNumericSugar(address);
-        if (filteredAddr != null) {
-            origBytes = parseToDtmf(filteredAddr);
-        }
-        if (origBytes != null) {
-            addr.digitMode = DIGIT_MODE_4BIT_DTMF;
-            addr.numberMode = NUMBER_MODE_NOT_DATA_NETWORK;
-            if (address.indexOf('+') != -1) {
-                addr.ton = TON_INTERNATIONAL_OR_IP;
-            }
-        } else {
-            filteredAddr = filterWhitespace(address);
-            origBytes = UserData.stringToAscii(filteredAddr);
-            if (origBytes == null) {
-                return null;
-            }
-            addr.digitMode = DIGIT_MODE_8BIT_CHAR;
-            addr.numberMode = NUMBER_MODE_DATA_NETWORK;
-            if (address.indexOf('@') != -1) {
-                addr.ton = TON_NATIONAL_OR_EMAIL;
-            }
-        }
-        addr.origBytes = origBytes;
-        addr.numberOfDigits = origBytes.length;
-        return addr;
-    }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsSubaddress.java b/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsSubaddress.java
deleted file mode 100644
index f9cebf5..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsSubaddress.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project. All rights reserved.
- * Copyright (C) 2010 Code Aurora Forum. All rights reserved.
- *
- * 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.internal.telephony.cdma.sms;
-
-public class CdmaSmsSubaddress {
-    public int type;
-
-    public byte odd;
-
-    public byte[] origBytes;
-}
-
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
deleted file mode 100644
index f73df56..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * 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.internal.telephony.cdma.sms;
-
-
-import com.android.internal.telephony.cdma.sms.CdmaSmsSubaddress;
-
-public final class SmsEnvelope {
-    /**
-     * Message Types
-     * (See 3GPP2 C.S0015-B 3.4.1)
-     */
-    static public final int MESSAGE_TYPE_POINT_TO_POINT   = 0x00;
-    static public final int MESSAGE_TYPE_BROADCAST        = 0x01;
-    static public final int MESSAGE_TYPE_ACKNOWLEDGE      = 0x02;
-
-    /**
-     * Supported Teleservices
-     * (See 3GPP2 N.S0005 and TIA-41)
-     */
-    static public final int TELESERVICE_NOT_SET           = 0x0000;
-    static public final int TELESERVICE_WMT               = 0x1002;
-    static public final int TELESERVICE_VMN               = 0x1003;
-    static public final int TELESERVICE_WAP               = 0x1004;
-    static public final int TELESERVICE_WEMT              = 0x1005;
-    static public final int TELESERVICE_SCPT              = 0x1006;
-
-    /**
-     * The following are defined as extensions to the standard teleservices
-     */
-    // Voice mail notification through Message Waiting Indication in CDMA mode or Analog mode.
-    // Defined in 3GPP2 C.S-0005, 3.7.5.6, an Info Record containing an 8-bit number with the
-    // number of messages waiting, it's used by some CDMA carriers for a voice mail count.
-    static public final int TELESERVICE_MWI               = 0x40000;
-
-    // Service Categories for Cell Broadcast, see 3GPP2 C.R1001 table 9.3.1-1
-    // static final int SERVICE_CATEGORY_EMERGENCY      = 0x0001;
-    //...
-
-    // CMAS alert service category assignments, see 3GPP2 C.R1001 table 9.3.3-1
-    public static final int SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT  = 0x1000;
-    public static final int SERVICE_CATEGORY_CMAS_EXTREME_THREAT            = 0x1001;
-    public static final int SERVICE_CATEGORY_CMAS_SEVERE_THREAT             = 0x1002;
-    public static final int SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = 0x1003;
-    public static final int SERVICE_CATEGORY_CMAS_TEST_MESSAGE              = 0x1004;
-    public static final int SERVICE_CATEGORY_CMAS_LAST_RESERVED_VALUE       = 0x10ff;
-
-    /**
-     * Provides the type of a SMS message like point to point, broadcast or acknowledge
-     */
-    public int messageType;
-
-    /**
-     * The 16-bit Teleservice parameter identifies which upper layer service access point is sending
-     * or receiving the message.
-     * (See 3GPP2 C.S0015-B, v2, 3.4.3.1)
-     */
-    public int teleService = TELESERVICE_NOT_SET;
-
-    /**
-     * The 16-bit service category parameter identifies the type of service provided
-     * by the SMS message.
-     * (See 3GPP2 C.S0015-B, v2, 3.4.3.2)
-     */
-    public int serviceCategory;
-
-    /**
-     * The origination address identifies the originator of the SMS message.
-     * (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
-     */
-    public CdmaSmsAddress origAddress;
-
-    /**
-     * The destination address identifies the target of the SMS message.
-     * (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
-     */
-    public CdmaSmsAddress destAddress;
-
-    /**
-     * The origination subaddress identifies the originator of the SMS message.
-     * (See 3GPP2 C.S0015-B, v2, 3.4.3.4)
-     */
-    public CdmaSmsSubaddress origSubaddress;
-
-    /**
-     * The 6-bit bearer reply parameter is used to request the return of a
-     * SMS Acknowledge Message.
-     * (See 3GPP2 C.S0015-B, v2, 3.4.3.5)
-     */
-    public int bearerReply;
-
-    /**
-     * Cause Code values:
-     * The cause code parameters are an indication whether an SMS error has occurred and if so,
-     * whether the condition is considered temporary or permanent.
-     * ReplySeqNo 6-bit value,
-     * ErrorClass 2-bit value,
-     * CauseCode 0-bit or 8-bit value
-     * (See 3GPP2 C.S0015-B, v2, 3.4.3.6)
-     */
-    public byte replySeqNo;
-    public byte errorClass;
-    public byte causeCode;
-
-    /**
-     * encoded bearer data
-     * (See 3GPP2 C.S0015-B, v2, 3.4.3.7)
-     */
-    public byte[] bearerData;
-
-    public SmsEnvelope() {
-        // nothing to see here
-    }
-
-}
-
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java b/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java
deleted file mode 100644
index 599c2b3..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * 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.internal.telephony.cdma.sms;
-
-import android.util.SparseIntArray;
-
-import com.android.internal.telephony.SmsHeader;
-import com.android.internal.util.HexDump;
-
-public class UserData {
-
-    /**
-     * User data encoding types.
-     * (See 3GPP2 C.R1001-F, v1.0, table 9.1-1)
-     */
-    public static final int ENCODING_OCTET                      = 0x00;
-    public static final int ENCODING_IS91_EXTENDED_PROTOCOL     = 0x01;
-    public static final int ENCODING_7BIT_ASCII                 = 0x02;
-    public static final int ENCODING_IA5                        = 0x03;
-    public static final int ENCODING_UNICODE_16                 = 0x04;
-    public static final int ENCODING_SHIFT_JIS                  = 0x05;
-    public static final int ENCODING_KOREAN                     = 0x06;
-    public static final int ENCODING_LATIN_HEBREW               = 0x07;
-    public static final int ENCODING_LATIN                      = 0x08;
-    public static final int ENCODING_GSM_7BIT_ALPHABET          = 0x09;
-    public static final int ENCODING_GSM_DCS                    = 0x0A;
-
-    /**
-     * IS-91 message types.
-     * (See TIA/EIS/IS-91-A-ENGL 1999, table 3.7.1.1-3)
-     */
-    public static final int IS91_MSG_TYPE_VOICEMAIL_STATUS   = 0x82;
-    public static final int IS91_MSG_TYPE_SHORT_MESSAGE_FULL = 0x83;
-    public static final int IS91_MSG_TYPE_CLI                = 0x84;
-    public static final int IS91_MSG_TYPE_SHORT_MESSAGE      = 0x85;
-
-    /**
-     * US ASCII character mapping table.
-     *
-     * This table contains only the printable ASCII characters, with a
-     * 0x20 offset, meaning that the ASCII SPACE character is at index
-     * 0, with the resulting code of 0x20.
-     *
-     * Note this mapping is also equivalent to that used by both the
-     * IA5 and the IS-91 encodings.  For the former this is defined
-     * using CCITT Rec. T.50 Tables 1 and 3.  For the latter IS 637 B,
-     * Table 4.3.1.4.1-1 -- and note the encoding uses only 6 bits,
-     * and hence only maps entries up to the '_' character.
-     *
-     */
-    public static final char[] ASCII_MAP = {
-        ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
-        '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
-        'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
-        '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
-        'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~'};
-
-    /**
-     * Character to use when forced to encode otherwise unencodable
-     * characters, meaning those not in the respective ASCII or GSM
-     * 7-bit encoding tables.  Current choice is SPACE, which is 0x20
-     * in both the GSM-7bit and ASCII-7bit encodings.
-     */
-    static final byte UNENCODABLE_7_BIT_CHAR = 0x20;
-
-    /**
-     * Only elements between these indices in the ASCII table are printable.
-     */
-    public static final int PRINTABLE_ASCII_MIN_INDEX = 0x20;
-    public static final int ASCII_NL_INDEX = 0x0A;
-    public static final int ASCII_CR_INDEX = 0x0D;
-    public static final SparseIntArray charToAscii = new SparseIntArray();
-    static {
-        for (int i = 0; i < ASCII_MAP.length; i++) {
-            charToAscii.put(ASCII_MAP[i], PRINTABLE_ASCII_MIN_INDEX + i);
-        }
-        charToAscii.put('\n', ASCII_NL_INDEX);
-        charToAscii.put('\r', ASCII_CR_INDEX);
-    }
-
-    /*
-     * TODO(cleanup): Move this very generic functionality somewhere
-     * more general.
-     */
-    /**
-     * Given a string generate a corresponding ASCII-encoded byte
-     * array, but limited to printable characters.  If the input
-     * contains unprintable characters, return null.
-     */
-    public static byte[] stringToAscii(String str) {
-        int len = str.length();
-        byte[] result = new byte[len];
-        for (int i = 0; i < len; i++) {
-            int charCode = charToAscii.get(str.charAt(i), -1);
-            if (charCode == -1) return null;
-            result[i] = (byte)charCode;
-        }
-        return result;
-    }
-
-    /**
-     * Mapping for ASCII values less than 32 are flow control signals
-     * and not used here.
-     */
-    public static final int ASCII_MAP_BASE_INDEX = 0x20;
-    public static final int ASCII_MAP_MAX_INDEX = ASCII_MAP_BASE_INDEX + ASCII_MAP.length - 1;
-
-    /**
-     * Contains the data header of the user data
-     */
-    public SmsHeader userDataHeader;
-
-    /**
-     * Contains the data encoding type for the SMS message
-     */
-    public int msgEncoding;
-    public boolean msgEncodingSet = false;
-
-    public int msgType;
-
-    /**
-     * Number of invalid bits in the last byte of data.
-     */
-    public int paddingBits;
-
-    public int numFields;
-
-    /**
-     * Contains the user data of a SMS message
-     * (See 3GPP2 C.S0015-B, v2, 4.5.2)
-     */
-    public byte[] payload;
-    public String payloadStr;
-
-    @Override
-    public String toString() {
-        StringBuilder builder = new StringBuilder();
-        builder.append("UserData ");
-        builder.append("{ msgEncoding=" + (msgEncodingSet ? msgEncoding : "unset"));
-        builder.append(", msgType=" + msgType);
-        builder.append(", paddingBits=" + paddingBits);
-        builder.append(", numFields=" + numFields);
-        builder.append(", userDataHeader=" + userDataHeader);
-        builder.append(", payload='" + HexDump.toHexString(payload) + "'");
-        builder.append(", payloadStr='" + payloadStr + "'");
-        builder.append(" }");
-        return builder.toString();
-    }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/package.html b/telephony/java/com/android/internal/telephony/cdma/sms/package.html
deleted file mode 100644
index b2bc736..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/sms/package.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<HTML>
-<BODY>
-Provides CDMA-specific features for text/data/PDU SMS messages
-@hide
-</BODY>
-</HTML>
diff --git a/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java b/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java
deleted file mode 100644
index af2ad48..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java
+++ /dev/null
@@ -1,53 +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.internal.telephony.gsm;
-
-/**
- * Call fail causes from TS 24.008 .
- * These are mostly the cause codes we need to distinguish for the UI.
- * See 22.001 Annex F.4 for mapping of cause codes to local tones.
- *
- * {@hide}
- *
- */
-public interface CallFailCause {
-    // Unassigned/Unobtainable number
-    static final int UNOBTAINABLE_NUMBER = 1;
-
-    static final int NORMAL_CLEARING     = 16;
-    // Busy Tone
-    static final int USER_BUSY           = 17;
-
-    // No Tone
-    static final int NUMBER_CHANGED      = 22;
-    static final int STATUS_ENQUIRY      = 30;
-    static final int NORMAL_UNSPECIFIED  = 31;
-
-    // Congestion Tone
-    static final int NO_CIRCUIT_AVAIL    = 34;
-    static final int TEMPORARY_FAILURE   = 41;
-    static final int SWITCHING_CONGESTION    = 42;
-    static final int CHANNEL_NOT_AVAIL   = 44;
-    static final int QOS_NOT_AVAIL       = 49;
-    static final int BEARER_NOT_AVAIL    = 58;
-
-    // others
-    static final int ACM_LIMIT_EXCEEDED = 68;
-    static final int CALL_BARRED        = 240;
-    static final int FDN_BLOCKED        = 241;
-    static final int ERROR_UNSPECIFIED = 0xffff;
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
deleted file mode 100644
index 6e9cd51..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ /dev/null
@@ -1,1507 +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.internal.telephony.gsm;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.database.SQLException;
-import android.net.Uri;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.os.SystemProperties;
-import android.preference.PreferenceManager;
-import android.provider.Telephony;
-import android.telephony.CellLocation;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import com.android.internal.telephony.CallTracker;
-import android.text.TextUtils;
-import android.util.Log;
-
-import static com.android.internal.telephony.CommandsInterface.CF_ACTION_DISABLE;
-import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ENABLE;
-import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ERASURE;
-import static com.android.internal.telephony.CommandsInterface.CF_ACTION_REGISTRATION;
-import static com.android.internal.telephony.CommandsInterface.CF_REASON_ALL;
-import static com.android.internal.telephony.CommandsInterface.CF_REASON_ALL_CONDITIONAL;
-import static com.android.internal.telephony.CommandsInterface.CF_REASON_NO_REPLY;
-import static com.android.internal.telephony.CommandsInterface.CF_REASON_NOT_REACHABLE;
-import static com.android.internal.telephony.CommandsInterface.CF_REASON_BUSY;
-import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDITIONAL;
-import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_BASEBAND_VERSION;
-
-import com.android.internal.telephony.cat.CatService;
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallForwardInfo;
-import com.android.internal.telephony.CallStateException;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccFileHandler;
-import com.android.internal.telephony.IccPhoneBookInterfaceManager;
-import com.android.internal.telephony.IccSmsInterfaceManager;
-import com.android.internal.telephony.MmiCode;
-import com.android.internal.telephony.OperatorInfo;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.PhoneNotifier;
-import com.android.internal.telephony.PhoneProxy;
-import com.android.internal.telephony.PhoneSubInfo;
-import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.telephony.UUSInfo;
-import com.android.internal.telephony.test.SimulatedRadioControl;
-import com.android.internal.telephony.uicc.UiccController;
-import com.android.internal.telephony.IccVmNotSupportedException;
-import com.android.internal.telephony.ServiceStateTracker;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * {@hide}
- */
-public class GSMPhone extends PhoneBase {
-    // NOTE that LOG_TAG here is "GSM", which means that log messages
-    // from this file will go into the radio log rather than the main
-    // log.  (Use "adb logcat -b radio" to see them.)
-    static final String LOG_TAG = "GSM";
-    private static final boolean LOCAL_DEBUG = true;
-    private static final boolean VDBG = false; /* STOP SHIP if true */
-
-    // Key used to read/write current ciphering state
-    public static final String CIPHERING_KEY = "ciphering_key";
-    // Key used to read/write voice mail number
-    public static final String VM_NUMBER = "vm_number_key";
-    // Key used to read/write the SIM IMSI used for storing the voice mail
-    public static final String VM_SIM_IMSI = "vm_sim_imsi_key";
-
-    // Instance Variables
-    GsmCallTracker mCT;
-    GsmServiceStateTracker mSST;
-    ArrayList <GsmMmiCode> mPendingMMIs = new ArrayList<GsmMmiCode>();
-    SimPhoneBookInterfaceManager mSimPhoneBookIntManager;
-    SimSmsInterfaceManager mSimSmsIntManager;
-    PhoneSubInfo mSubInfo;
-
-
-    Registrant mPostDialHandler;
-
-    /** List of Registrants to receive Supplementary Service Notifications. */
-    RegistrantList mSsnRegistrants = new RegistrantList();
-
-    Thread debugPortThread;
-    ServerSocket debugSocket;
-
-    private String mImei;
-    private String mImeiSv;
-    private String mVmNumber;
-
-
-    // Constructors
-
-    public
-    GSMPhone (Context context, CommandsInterface ci, PhoneNotifier notifier) {
-        this(context,ci,notifier, false);
-    }
-
-    public
-    GSMPhone (Context context, CommandsInterface ci, PhoneNotifier notifier, boolean unitTestMode) {
-        super(notifier, context, ci, unitTestMode);
-
-        if (ci instanceof SimulatedRadioControl) {
-            mSimulatedRadioControl = (SimulatedRadioControl) ci;
-        }
-
-        mCM.setPhoneType(Phone.PHONE_TYPE_GSM);
-        mIccCard.set(UiccController.getInstance(this).getIccCard());
-        mIccRecords = mIccCard.get().getIccRecords();
-        mCT = new GsmCallTracker(this);
-        mSST = new GsmServiceStateTracker (this);
-        mSMS = new GsmSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor);
-        mDataConnectionTracker = new GsmDataConnectionTracker (this);
-        if (!unitTestMode) {
-            mSimPhoneBookIntManager = new SimPhoneBookInterfaceManager(this);
-            mSimSmsIntManager = new SimSmsInterfaceManager(this, mSMS);
-            mSubInfo = new PhoneSubInfo(this);
-        }
-
-        mCM.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
-        registerForSimRecordEvents();
-        mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
-        mCM.registerForOn(this, EVENT_RADIO_ON, null);
-        mCM.setOnUSSD(this, EVENT_USSD, null);
-        mCM.setOnSuppServiceNotification(this, EVENT_SSN, null);
-        mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null);
-
-        if (false) {
-            try {
-                //debugSocket = new LocalServerSocket("com.android.internal.telephony.debug");
-                debugSocket = new ServerSocket();
-                debugSocket.setReuseAddress(true);
-                debugSocket.bind (new InetSocketAddress("127.0.0.1", 6666));
-
-                debugPortThread
-                    = new Thread(
-                        new Runnable() {
-                            public void run() {
-                                for(;;) {
-                                    try {
-                                        Socket sock;
-                                        sock = debugSocket.accept();
-                                        Log.i(LOG_TAG, "New connection; resetting radio");
-                                        mCM.resetRadio(null);
-                                        sock.close();
-                                    } catch (IOException ex) {
-                                        Log.w(LOG_TAG,
-                                            "Exception accepting socket", ex);
-                                    }
-                                }
-                            }
-                        },
-                        "GSMPhone debug");
-
-                debugPortThread.start();
-
-            } catch (IOException ex) {
-                Log.w(LOG_TAG, "Failure to open com.android.internal.telephony.debug socket", ex);
-            }
-        }
-
-        //Change the system property
-        SystemProperties.set(TelephonyProperties.CURRENT_ACTIVE_PHONE,
-                new Integer(Phone.PHONE_TYPE_GSM).toString());
-    }
-
-    @Override
-    public void dispose() {
-        synchronized(PhoneProxy.lockForRadioTechnologyChange) {
-            super.dispose();
-
-            //Unregister from all former registered events
-            mCM.unregisterForAvailable(this); //EVENT_RADIO_AVAILABLE
-            unregisterForSimRecordEvents();
-            mCM.unregisterForOffOrNotAvailable(this); //EVENT_RADIO_OFF_OR_NOT_AVAILABLE
-            mCM.unregisterForOn(this); //EVENT_RADIO_ON
-            mSST.unregisterForNetworkAttached(this); //EVENT_REGISTERED_TO_NETWORK
-            mCM.unSetOnUSSD(this);
-            mCM.unSetOnSuppServiceNotification(this);
-
-            mPendingMMIs.clear();
-
-            //Force all referenced classes to unregister their former registered events
-            mCT.dispose();
-            mDataConnectionTracker.dispose();
-            mSST.dispose();
-            mSimPhoneBookIntManager.dispose();
-            mSimSmsIntManager.dispose();
-            mSubInfo.dispose();
-        }
-    }
-
-    @Override
-    public void removeReferences() {
-        Log.d(LOG_TAG, "removeReferences");
-        mSimulatedRadioControl = null;
-        mSimPhoneBookIntManager = null;
-        mSimSmsIntManager = null;
-        mSubInfo = null;
-        mCT = null;
-        mSST = null;
-        super.removeReferences();
-    }
-
-    protected void finalize() {
-        if(LOCAL_DEBUG) Log.d(LOG_TAG, "GSMPhone finalized");
-    }
-
-
-    public ServiceState
-    getServiceState() {
-        return mSST.ss;
-    }
-
-    public CellLocation getCellLocation() {
-        return mSST.cellLoc;
-    }
-
-    public Phone.State getState() {
-        return mCT.state;
-    }
-
-    public String getPhoneName() {
-        return "GSM";
-    }
-
-    public int getPhoneType() {
-        return Phone.PHONE_TYPE_GSM;
-    }
-
-    public SignalStrength getSignalStrength() {
-        return mSST.mSignalStrength;
-    }
-
-    public CallTracker getCallTracker() {
-        return mCT;
-    }
-
-    public ServiceStateTracker getServiceStateTracker() {
-        return mSST;
-    }
-
-    public List<? extends MmiCode>
-    getPendingMmiCodes() {
-        return mPendingMMIs;
-    }
-
-    public DataState getDataConnectionState(String apnType) {
-        DataState ret = DataState.DISCONNECTED;
-
-        if (mSST == null) {
-            // Radio Technology Change is ongoning, dispose() and removeReferences() have
-            // already been called
-
-            ret = DataState.DISCONNECTED;
-        } else if (mSST.getCurrentGprsState()
-                != ServiceState.STATE_IN_SERVICE) {
-            // If we're out of service, open TCP sockets may still work
-            // but no data will flow
-            ret = DataState.DISCONNECTED;
-        } else if (mDataConnectionTracker.isApnTypeEnabled(apnType) == false ||
-                mDataConnectionTracker.isApnTypeActive(apnType) == false) {
-            //TODO: isApnTypeActive() is just checking whether ApnContext holds
-            //      Dataconnection or not. Checking each ApnState below should
-            //      provide the same state. Calling isApnTypeActive() can be removed.
-            ret = DataState.DISCONNECTED;
-        } else { /* mSST.gprsState == ServiceState.STATE_IN_SERVICE */
-            switch (mDataConnectionTracker.getState(apnType)) {
-                case FAILED:
-                case IDLE:
-                    ret = DataState.DISCONNECTED;
-                break;
-
-                case CONNECTED:
-                case DISCONNECTING:
-                    if ( mCT.state != Phone.State.IDLE
-                            && !mSST.isConcurrentVoiceAndDataAllowed()) {
-                        ret = DataState.SUSPENDED;
-                    } else {
-                        ret = DataState.CONNECTED;
-                    }
-                break;
-
-                case INITING:
-                case CONNECTING:
-                case SCANNING:
-                    ret = DataState.CONNECTING;
-                break;
-            }
-        }
-
-        return ret;
-    }
-
-    public DataActivityState getDataActivityState() {
-        DataActivityState ret = DataActivityState.NONE;
-
-        if (mSST.getCurrentGprsState() == ServiceState.STATE_IN_SERVICE) {
-            switch (mDataConnectionTracker.getActivity()) {
-                case DATAIN:
-                    ret = DataActivityState.DATAIN;
-                break;
-
-                case DATAOUT:
-                    ret = DataActivityState.DATAOUT;
-                break;
-
-                case DATAINANDOUT:
-                    ret = DataActivityState.DATAINANDOUT;
-                break;
-            }
-        }
-
-        return ret;
-    }
-
-    /**
-     * Notify any interested party of a Phone state change {@link Phone.State}
-     */
-    /*package*/ void notifyPhoneStateChanged() {
-        mNotifier.notifyPhoneState(this);
-    }
-
-    /**
-     * Notify registrants of a change in the call state. This notifies changes in {@link Call.State}
-     * Use this when changes in the precise call state are needed, else use notifyPhoneStateChanged.
-     */
-    /*package*/ void notifyPreciseCallStateChanged() {
-        /* we'd love it if this was package-scoped*/
-        super.notifyPreciseCallStateChangedP();
-    }
-
-    /*package*/ void
-    notifyNewRingingConnection(Connection c) {
-        /* we'd love it if this was package-scoped*/
-        super.notifyNewRingingConnectionP(c);
-    }
-
-    /*package*/ void
-    notifyDisconnect(Connection cn) {
-        mDisconnectRegistrants.notifyResult(cn);
-    }
-
-    void notifyUnknownConnection() {
-        mUnknownConnectionRegistrants.notifyResult(this);
-    }
-
-    void notifySuppServiceFailed(SuppService code) {
-        mSuppServiceFailedRegistrants.notifyResult(code);
-    }
-
-    /*package*/ void
-    notifyServiceStateChanged(ServiceState ss) {
-        super.notifyServiceStateChangedP(ss);
-    }
-
-    /*package*/
-    void notifyLocationChanged() {
-        mNotifier.notifyCellLocation(this);
-    }
-
-    /*package*/ void
-    notifySignalStrength() {
-        mNotifier.notifySignalStrength(this);
-    }
-
-    public void
-    notifyCallForwardingIndicator() {
-        mNotifier.notifyCallForwardingChanged(this);
-    }
-
-    // override for allowing access from other classes of this package
-    /**
-     * {@inheritDoc}
-     */
-    public final void
-    setSystemProperty(String property, String value) {
-        super.setSystemProperty(property, value);
-    }
-
-    public void registerForSuppServiceNotification(
-            Handler h, int what, Object obj) {
-        mSsnRegistrants.addUnique(h, what, obj);
-        if (mSsnRegistrants.size() == 1) mCM.setSuppServiceNotifications(true, null);
-    }
-
-    public void unregisterForSuppServiceNotification(Handler h) {
-        mSsnRegistrants.remove(h);
-        if (mSsnRegistrants.size() == 0) mCM.setSuppServiceNotifications(false, null);
-    }
-
-    public void
-    acceptCall() throws CallStateException {
-        mCT.acceptCall();
-    }
-
-    public void
-    rejectCall() throws CallStateException {
-        mCT.rejectCall();
-    }
-
-    public void
-    switchHoldingAndActive() throws CallStateException {
-        mCT.switchWaitingOrHoldingAndActive();
-    }
-
-    public boolean canConference() {
-        return mCT.canConference();
-    }
-
-    public boolean canDial() {
-        return mCT.canDial();
-    }
-
-    public void conference() throws CallStateException {
-        mCT.conference();
-    }
-
-    public void clearDisconnected() {
-        mCT.clearDisconnected();
-    }
-
-    public boolean canTransfer() {
-        return mCT.canTransfer();
-    }
-
-    public void explicitCallTransfer() throws CallStateException {
-        mCT.explicitCallTransfer();
-    }
-
-    public GsmCall
-    getForegroundCall() {
-        return mCT.foregroundCall;
-    }
-
-    public GsmCall
-    getBackgroundCall() {
-        return mCT.backgroundCall;
-    }
-
-    public GsmCall
-    getRingingCall() {
-        return mCT.ringingCall;
-    }
-
-    private boolean handleCallDeflectionIncallSupplementaryService(
-            String dialString) throws CallStateException {
-        if (dialString.length() > 1) {
-            return false;
-        }
-
-        if (getRingingCall().getState() != GsmCall.State.IDLE) {
-            if (LOCAL_DEBUG) Log.d(LOG_TAG, "MmiCode 0: rejectCall");
-            try {
-                mCT.rejectCall();
-            } catch (CallStateException e) {
-                if (LOCAL_DEBUG) Log.d(LOG_TAG,
-                    "reject failed", e);
-                notifySuppServiceFailed(Phone.SuppService.REJECT);
-            }
-        } else if (getBackgroundCall().getState() != GsmCall.State.IDLE) {
-            if (LOCAL_DEBUG) Log.d(LOG_TAG,
-                    "MmiCode 0: hangupWaitingOrBackground");
-            mCT.hangupWaitingOrBackground();
-        }
-
-        return true;
-    }
-
-    private boolean handleCallWaitingIncallSupplementaryService(
-            String dialString) throws CallStateException {
-        int len = dialString.length();
-
-        if (len > 2) {
-            return false;
-        }
-
-        GsmCall call = (GsmCall) getForegroundCall();
-
-        try {
-            if (len > 1) {
-                char ch = dialString.charAt(1);
-                int callIndex = ch - '0';
-
-                if (callIndex >= 1 && callIndex <= GsmCallTracker.MAX_CONNECTIONS) {
-                    if (LOCAL_DEBUG) Log.d(LOG_TAG,
-                            "MmiCode 1: hangupConnectionByIndex " +
-                            callIndex);
-                    mCT.hangupConnectionByIndex(call, callIndex);
-                }
-            } else {
-                if (call.getState() != GsmCall.State.IDLE) {
-                    if (LOCAL_DEBUG) Log.d(LOG_TAG,
-                            "MmiCode 1: hangup foreground");
-                    //mCT.hangupForegroundResumeBackground();
-                    mCT.hangup(call);
-                } else {
-                    if (LOCAL_DEBUG) Log.d(LOG_TAG,
-                            "MmiCode 1: switchWaitingOrHoldingAndActive");
-                    mCT.switchWaitingOrHoldingAndActive();
-                }
-            }
-        } catch (CallStateException e) {
-            if (LOCAL_DEBUG) Log.d(LOG_TAG,
-                "hangup failed", e);
-            notifySuppServiceFailed(Phone.SuppService.HANGUP);
-        }
-
-        return true;
-    }
-
-    private boolean handleCallHoldIncallSupplementaryService(String dialString)
-            throws CallStateException {
-        int len = dialString.length();
-
-        if (len > 2) {
-            return false;
-        }
-
-        GsmCall call = (GsmCall) getForegroundCall();
-
-        if (len > 1) {
-            try {
-                char ch = dialString.charAt(1);
-                int callIndex = ch - '0';
-                GsmConnection conn = mCT.getConnectionByIndex(call, callIndex);
-
-                // gsm index starts at 1, up to 5 connections in a call,
-                if (conn != null && callIndex >= 1 && callIndex <= GsmCallTracker.MAX_CONNECTIONS) {
-                    if (LOCAL_DEBUG) Log.d(LOG_TAG, "MmiCode 2: separate call "+
-                            callIndex);
-                    mCT.separate(conn);
-                } else {
-                    if (LOCAL_DEBUG) Log.d(LOG_TAG, "separate: invalid call index "+
-                            callIndex);
-                    notifySuppServiceFailed(Phone.SuppService.SEPARATE);
-                }
-            } catch (CallStateException e) {
-                if (LOCAL_DEBUG) Log.d(LOG_TAG,
-                    "separate failed", e);
-                notifySuppServiceFailed(Phone.SuppService.SEPARATE);
-            }
-        } else {
-            try {
-                if (getRingingCall().getState() != GsmCall.State.IDLE) {
-                    if (LOCAL_DEBUG) Log.d(LOG_TAG,
-                    "MmiCode 2: accept ringing call");
-                    mCT.acceptCall();
-                } else {
-                    if (LOCAL_DEBUG) Log.d(LOG_TAG,
-                    "MmiCode 2: switchWaitingOrHoldingAndActive");
-                    mCT.switchWaitingOrHoldingAndActive();
-                }
-            } catch (CallStateException e) {
-                if (LOCAL_DEBUG) Log.d(LOG_TAG,
-                    "switch failed", e);
-                notifySuppServiceFailed(Phone.SuppService.SWITCH);
-            }
-        }
-
-        return true;
-    }
-
-    private boolean handleMultipartyIncallSupplementaryService(
-            String dialString) throws CallStateException {
-        if (dialString.length() > 1) {
-            return false;
-        }
-
-        if (LOCAL_DEBUG) Log.d(LOG_TAG, "MmiCode 3: merge calls");
-        try {
-            conference();
-        } catch (CallStateException e) {
-            if (LOCAL_DEBUG) Log.d(LOG_TAG,
-                "conference failed", e);
-            notifySuppServiceFailed(Phone.SuppService.CONFERENCE);
-        }
-        return true;
-    }
-
-    private boolean handleEctIncallSupplementaryService(String dialString)
-            throws CallStateException {
-
-        int len = dialString.length();
-
-        if (len != 1) {
-            return false;
-        }
-
-        if (LOCAL_DEBUG) Log.d(LOG_TAG, "MmiCode 4: explicit call transfer");
-        try {
-            explicitCallTransfer();
-        } catch (CallStateException e) {
-            if (LOCAL_DEBUG) Log.d(LOG_TAG,
-                "transfer failed", e);
-            notifySuppServiceFailed(Phone.SuppService.TRANSFER);
-        }
-        return true;
-    }
-
-    private boolean handleCcbsIncallSupplementaryService(String dialString)
-            throws CallStateException {
-        if (dialString.length() > 1) {
-            return false;
-        }
-
-        Log.i(LOG_TAG, "MmiCode 5: CCBS not supported!");
-        // Treat it as an "unknown" service.
-        notifySuppServiceFailed(Phone.SuppService.UNKNOWN);
-        return true;
-    }
-
-    public boolean handleInCallMmiCommands(String dialString)
-            throws CallStateException {
-        if (!isInCall()) {
-            return false;
-        }
-
-        if (TextUtils.isEmpty(dialString)) {
-            return false;
-        }
-
-        boolean result = false;
-        char ch = dialString.charAt(0);
-        switch (ch) {
-            case '0':
-                result = handleCallDeflectionIncallSupplementaryService(
-                        dialString);
-                break;
-            case '1':
-                result = handleCallWaitingIncallSupplementaryService(
-                        dialString);
-                break;
-            case '2':
-                result = handleCallHoldIncallSupplementaryService(dialString);
-                break;
-            case '3':
-                result = handleMultipartyIncallSupplementaryService(dialString);
-                break;
-            case '4':
-                result = handleEctIncallSupplementaryService(dialString);
-                break;
-            case '5':
-                result = handleCcbsIncallSupplementaryService(dialString);
-                break;
-            default:
-                break;
-        }
-
-        return result;
-    }
-
-    boolean isInCall() {
-        GsmCall.State foregroundCallState = getForegroundCall().getState();
-        GsmCall.State backgroundCallState = getBackgroundCall().getState();
-        GsmCall.State ringingCallState = getRingingCall().getState();
-
-       return (foregroundCallState.isAlive() ||
-                backgroundCallState.isAlive() ||
-                ringingCallState.isAlive());
-    }
-
-    public Connection
-    dial(String dialString) throws CallStateException {
-        return dial(dialString, null);
-    }
-
-    public Connection
-    dial (String dialString, UUSInfo uusInfo) throws CallStateException {
-        // Need to make sure dialString gets parsed properly
-        String newDialString = PhoneNumberUtils.stripSeparators(dialString);
-
-        // handle in-call MMI first if applicable
-        if (handleInCallMmiCommands(newDialString)) {
-            return null;
-        }
-
-        // Only look at the Network portion for mmi
-        String networkPortion = PhoneNumberUtils.extractNetworkPortionAlt(newDialString);
-        GsmMmiCode mmi = GsmMmiCode.newFromDialString(networkPortion, this);
-        if (LOCAL_DEBUG) Log.d(LOG_TAG,
-                               "dialing w/ mmi '" + mmi + "'...");
-
-        if (mmi == null) {
-            return mCT.dial(newDialString, uusInfo);
-        } else if (mmi.isTemporaryModeCLIR()) {
-            return mCT.dial(mmi.dialingNumber, mmi.getCLIRMode(), uusInfo);
-        } else {
-            mPendingMMIs.add(mmi);
-            mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
-            mmi.processCode();
-
-            // FIXME should this return null or something else?
-            return null;
-        }
-    }
-
-    public boolean handlePinMmi(String dialString) {
-        GsmMmiCode mmi = GsmMmiCode.newFromDialString(dialString, this);
-
-        if (mmi != null && mmi.isPinCommand()) {
-            mPendingMMIs.add(mmi);
-            mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
-            mmi.processCode();
-            return true;
-        }
-
-        return false;
-    }
-
-    public void sendUssdResponse(String ussdMessge) {
-        GsmMmiCode mmi = GsmMmiCode.newFromUssdUserInput(ussdMessge, this);
-        mPendingMMIs.add(mmi);
-        mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
-        mmi.sendUssd(ussdMessge);
-    }
-
-    public void
-    sendDtmf(char c) {
-        if (!PhoneNumberUtils.is12Key(c)) {
-            Log.e(LOG_TAG,
-                    "sendDtmf called with invalid character '" + c + "'");
-        } else {
-            if (mCT.state ==  Phone.State.OFFHOOK) {
-                mCM.sendDtmf(c, null);
-            }
-        }
-    }
-
-    public void
-    startDtmf(char c) {
-        if (!PhoneNumberUtils.is12Key(c)) {
-            Log.e(LOG_TAG,
-                "startDtmf called with invalid character '" + c + "'");
-        } else {
-            mCM.startDtmf(c, null);
-        }
-    }
-
-    public void
-    stopDtmf() {
-        mCM.stopDtmf(null);
-    }
-
-    public void
-    sendBurstDtmf(String dtmfString) {
-        Log.e(LOG_TAG, "[GSMPhone] sendBurstDtmf() is a CDMA method");
-    }
-
-    public void
-    setRadioPower(boolean power) {
-        mSST.setRadioPower(power);
-    }
-
-    private void storeVoiceMailNumber(String number) {
-        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
-        SharedPreferences.Editor editor = sp.edit();
-        editor.putString(VM_NUMBER, number);
-        editor.apply();
-        setVmSimImsi(getSubscriberId());
-    }
-
-    public String getVoiceMailNumber() {
-        // Read from the SIM. If its null, try reading from the shared preference area.
-        String number = mIccRecords.getVoiceMailNumber();
-        if (TextUtils.isEmpty(number)) {
-            SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
-            number = sp.getString(VM_NUMBER, null);
-        }
-        return number;
-    }
-
-    private String getVmSimImsi() {
-        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
-        return sp.getString(VM_SIM_IMSI, null);
-    }
-
-    private void setVmSimImsi(String imsi) {
-        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
-        SharedPreferences.Editor editor = sp.edit();
-        editor.putString(VM_SIM_IMSI, imsi);
-        editor.apply();
-    }
-
-    public String getVoiceMailAlphaTag() {
-        String ret;
-
-        ret = mIccRecords.getVoiceMailAlphaTag();
-
-        if (ret == null || ret.length() == 0) {
-            return mContext.getText(
-                com.android.internal.R.string.defaultVoiceMailAlphaTag).toString();
-        }
-
-        return ret;
-    }
-
-    public String getDeviceId() {
-        return mImei;
-    }
-
-    public String getDeviceSvn() {
-        return mImeiSv;
-    }
-
-    public String getImei() {
-        return mImei;
-    }
-
-    public String getEsn() {
-        Log.e(LOG_TAG, "[GSMPhone] getEsn() is a CDMA method");
-        return "0";
-    }
-
-    public String getMeid() {
-        Log.e(LOG_TAG, "[GSMPhone] getMeid() is a CDMA method");
-        return "0";
-    }
-
-    public String getSubscriberId() {
-        return mIccRecords.getIMSI();
-    }
-
-    public String getLine1Number() {
-        return mIccRecords.getMsisdnNumber();
-    }
-
-    @Override
-    public String getMsisdn() {
-        return mIccRecords.getMsisdnNumber();
-    }
-
-    public String getLine1AlphaTag() {
-        return mIccRecords.getMsisdnAlphaTag();
-    }
-
-    public void setLine1Number(String alphaTag, String number, Message onComplete) {
-        mIccRecords.setMsisdnNumber(alphaTag, number, onComplete);
-    }
-
-    public void setVoiceMailNumber(String alphaTag,
-                            String voiceMailNumber,
-                            Message onComplete) {
-
-        Message resp;
-        mVmNumber = voiceMailNumber;
-        resp = obtainMessage(EVENT_SET_VM_NUMBER_DONE, 0, 0, onComplete);
-        mIccRecords.setVoiceMailNumber(alphaTag, mVmNumber, resp);
-    }
-
-    private boolean isValidCommandInterfaceCFReason (int commandInterfaceCFReason) {
-        switch (commandInterfaceCFReason) {
-        case CF_REASON_UNCONDITIONAL:
-        case CF_REASON_BUSY:
-        case CF_REASON_NO_REPLY:
-        case CF_REASON_NOT_REACHABLE:
-        case CF_REASON_ALL:
-        case CF_REASON_ALL_CONDITIONAL:
-            return true;
-        default:
-            return false;
-        }
-    }
-
-    private boolean isValidCommandInterfaceCFAction (int commandInterfaceCFAction) {
-        switch (commandInterfaceCFAction) {
-        case CF_ACTION_DISABLE:
-        case CF_ACTION_ENABLE:
-        case CF_ACTION_REGISTRATION:
-        case CF_ACTION_ERASURE:
-            return true;
-        default:
-            return false;
-        }
-    }
-
-    protected  boolean isCfEnable(int action) {
-        return (action == CF_ACTION_ENABLE) || (action == CF_ACTION_REGISTRATION);
-    }
-
-    public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) {
-        if (isValidCommandInterfaceCFReason(commandInterfaceCFReason)) {
-            if (LOCAL_DEBUG) Log.d(LOG_TAG, "requesting call forwarding query.");
-            Message resp;
-            if (commandInterfaceCFReason == CF_REASON_UNCONDITIONAL) {
-                resp = obtainMessage(EVENT_GET_CALL_FORWARD_DONE, onComplete);
-            } else {
-                resp = onComplete;
-            }
-            mCM.queryCallForwardStatus(commandInterfaceCFReason,0,null,resp);
-        }
-    }
-
-    public void setCallForwardingOption(int commandInterfaceCFAction,
-            int commandInterfaceCFReason,
-            String dialingNumber,
-            int timerSeconds,
-            Message onComplete) {
-        if (    (isValidCommandInterfaceCFAction(commandInterfaceCFAction)) &&
-                (isValidCommandInterfaceCFReason(commandInterfaceCFReason))) {
-
-            Message resp;
-            if (commandInterfaceCFReason == CF_REASON_UNCONDITIONAL) {
-                resp = obtainMessage(EVENT_SET_CALL_FORWARD_DONE,
-                        isCfEnable(commandInterfaceCFAction) ? 1 : 0, 0, onComplete);
-            } else {
-                resp = onComplete;
-            }
-            mCM.setCallForward(commandInterfaceCFAction,
-                    commandInterfaceCFReason,
-                    CommandsInterface.SERVICE_CLASS_VOICE,
-                    dialingNumber,
-                    timerSeconds,
-                    resp);
-        }
-    }
-
-    public void getOutgoingCallerIdDisplay(Message onComplete) {
-        mCM.getCLIR(onComplete);
-    }
-
-    public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode,
-                                           Message onComplete) {
-        mCM.setCLIR(commandInterfaceCLIRMode,
-                obtainMessage(EVENT_SET_CLIR_COMPLETE, commandInterfaceCLIRMode, 0, onComplete));
-    }
-
-    public void getCallWaiting(Message onComplete) {
-        //As per 3GPP TS 24.083, section 1.6 UE doesn't need to send service
-        //class parameter in call waiting interrogation  to network
-        mCM.queryCallWaiting(CommandsInterface.SERVICE_CLASS_NONE, onComplete);
-    }
-
-    public void setCallWaiting(boolean enable, Message onComplete) {
-        mCM.setCallWaiting(enable, CommandsInterface.SERVICE_CLASS_VOICE, onComplete);
-    }
-
-    public void
-    getAvailableNetworks(Message response) {
-        mCM.getAvailableNetworks(response);
-    }
-
-    /**
-     * Small container class used to hold information relevant to
-     * the carrier selection process. operatorNumeric can be ""
-     * if we are looking for automatic selection. operatorAlphaLong is the
-     * corresponding operator name.
-     */
-    private static class NetworkSelectMessage {
-        public Message message;
-        public String operatorNumeric;
-        public String operatorAlphaLong;
-    }
-
-    public void
-    setNetworkSelectionModeAutomatic(Message response) {
-        // wrap the response message in our own message along with
-        // an empty string (to indicate automatic selection) for the
-        // operator's id.
-        NetworkSelectMessage nsm = new NetworkSelectMessage();
-        nsm.message = response;
-        nsm.operatorNumeric = "";
-        nsm.operatorAlphaLong = "";
-
-        // get the message
-        Message msg = obtainMessage(EVENT_SET_NETWORK_AUTOMATIC_COMPLETE, nsm);
-        if (LOCAL_DEBUG)
-            Log.d(LOG_TAG, "wrapping and sending message to connect automatically");
-
-        mCM.setNetworkSelectionModeAutomatic(msg);
-    }
-
-    public void
-    selectNetworkManually(OperatorInfo network,
-            Message response) {
-        // wrap the response message in our own message along with
-        // the operator's id.
-        NetworkSelectMessage nsm = new NetworkSelectMessage();
-        nsm.message = response;
-        nsm.operatorNumeric = network.getOperatorNumeric();
-        nsm.operatorAlphaLong = network.getOperatorAlphaLong();
-
-        // get the message
-        Message msg = obtainMessage(EVENT_SET_NETWORK_MANUAL_COMPLETE, nsm);
-
-        mCM.setNetworkSelectionModeManual(network.getOperatorNumeric(), msg);
-    }
-
-    public void
-    getNeighboringCids(Message response) {
-        mCM.getNeighboringCids(response);
-    }
-
-    public void setOnPostDialCharacter(Handler h, int what, Object obj) {
-        mPostDialHandler = new Registrant(h, what, obj);
-    }
-
-    public void setMute(boolean muted) {
-        mCT.setMute(muted);
-    }
-
-    public boolean getMute() {
-        return mCT.getMute();
-    }
-
-    public void getDataCallList(Message response) {
-        mCM.getDataCallList(response);
-    }
-
-    public void updateServiceLocation() {
-        mSST.enableSingleLocationUpdate();
-    }
-
-    public void enableLocationUpdates() {
-        mSST.enableLocationUpdates();
-    }
-
-    public void disableLocationUpdates() {
-        mSST.disableLocationUpdates();
-    }
-
-    public boolean getDataRoamingEnabled() {
-        return mDataConnectionTracker.getDataOnRoamingEnabled();
-    }
-
-    public void setDataRoamingEnabled(boolean enable) {
-        mDataConnectionTracker.setDataOnRoamingEnabled(enable);
-    }
-
-    /**
-     * Removes the given MMI from the pending list and notifies
-     * registrants that it is complete.
-     * @param mmi MMI that is done
-     */
-    /*package*/ void
-    onMMIDone(GsmMmiCode mmi) {
-        /* Only notify complete if it's on the pending list.
-         * Otherwise, it's already been handled (eg, previously canceled).
-         * The exception is cancellation of an incoming USSD-REQUEST, which is
-         * not on the list.
-         */
-        if (mPendingMMIs.remove(mmi) || mmi.isUssdRequest()) {
-            mMmiCompleteRegistrants.notifyRegistrants(
-                new AsyncResult(null, mmi, null));
-        }
-    }
-
-
-    private void
-    onNetworkInitiatedUssd(GsmMmiCode mmi) {
-        mMmiCompleteRegistrants.notifyRegistrants(
-            new AsyncResult(null, mmi, null));
-    }
-
-
-    /** ussdMode is one of CommandsInterface.USSD_MODE_* */
-    private void
-    onIncomingUSSD (int ussdMode, String ussdMessage) {
-        boolean isUssdError;
-        boolean isUssdRequest;
-
-        isUssdRequest
-            = (ussdMode == CommandsInterface.USSD_MODE_REQUEST);
-
-        isUssdError
-            = (ussdMode != CommandsInterface.USSD_MODE_NOTIFY
-                && ussdMode != CommandsInterface.USSD_MODE_REQUEST);
-
-        // See comments in GsmMmiCode.java
-        // USSD requests aren't finished until one
-        // of these two events happen
-        GsmMmiCode found = null;
-        for (int i = 0, s = mPendingMMIs.size() ; i < s; i++) {
-            if(mPendingMMIs.get(i).isPendingUSSD()) {
-                found = mPendingMMIs.get(i);
-                break;
-            }
-        }
-
-        if (found != null) {
-            // Complete pending USSD
-
-            if (isUssdError) {
-                found.onUssdFinishedError();
-            } else {
-                found.onUssdFinished(ussdMessage, isUssdRequest);
-            }
-        } else { // pending USSD not found
-            // The network may initiate its own USSD request
-
-            // ignore everything that isnt a Notify or a Request
-            // also, discard if there is no message to present
-            if (!isUssdError && ussdMessage != null) {
-                GsmMmiCode mmi;
-                mmi = GsmMmiCode.newNetworkInitiatedUssd(ussdMessage,
-                                                   isUssdRequest,
-                                                   GSMPhone.this);
-                onNetworkInitiatedUssd(mmi);
-            }
-        }
-    }
-
-    /**
-     * Make sure the network knows our preferred setting.
-     */
-    protected  void syncClirSetting() {
-        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
-        int clirSetting = sp.getInt(CLIR_KEY, -1);
-        if (clirSetting >= 0) {
-            mCM.setCLIR(clirSetting, null);
-        }
-    }
-
-    @Override
-    public void handleMessage (Message msg) {
-        AsyncResult ar;
-        Message onComplete;
-
-        switch (msg.what) {
-            case EVENT_RADIO_AVAILABLE: {
-                mCM.getBasebandVersion(
-                        obtainMessage(EVENT_GET_BASEBAND_VERSION_DONE));
-
-                mCM.getIMEI(obtainMessage(EVENT_GET_IMEI_DONE));
-                mCM.getIMEISV(obtainMessage(EVENT_GET_IMEISV_DONE));
-            }
-            break;
-
-            case EVENT_RADIO_ON:
-            break;
-
-            case EVENT_REGISTERED_TO_NETWORK:
-                syncClirSetting();
-                break;
-
-            case EVENT_SIM_RECORDS_LOADED:
-                updateCurrentCarrierInProvider();
-
-                // Check if this is a different SIM than the previous one. If so unset the
-                // voice mail number.
-                String imsi = getVmSimImsi();
-                String imsiFromSIM = getSubscriberId();
-                if (imsi != null && imsiFromSIM != null && !imsiFromSIM.equals(imsi)) {
-                    storeVoiceMailNumber(null);
-                    setVmSimImsi(null);
-                }
-
-            break;
-
-            case EVENT_GET_BASEBAND_VERSION_DONE:
-                ar = (AsyncResult)msg.obj;
-
-                if (ar.exception != null) {
-                    break;
-                }
-
-                if (LOCAL_DEBUG) Log.d(LOG_TAG, "Baseband version: " + ar.result);
-                setSystemProperty(PROPERTY_BASEBAND_VERSION, (String)ar.result);
-            break;
-
-            case EVENT_GET_IMEI_DONE:
-                ar = (AsyncResult)msg.obj;
-
-                if (ar.exception != null) {
-                    break;
-                }
-
-                mImei = (String)ar.result;
-            break;
-
-            case EVENT_GET_IMEISV_DONE:
-                ar = (AsyncResult)msg.obj;
-
-                if (ar.exception != null) {
-                    break;
-                }
-
-                mImeiSv = (String)ar.result;
-            break;
-
-            case EVENT_USSD:
-                ar = (AsyncResult)msg.obj;
-
-                String[] ussdResult = (String[]) ar.result;
-
-                if (ussdResult.length > 1) {
-                    try {
-                        onIncomingUSSD(Integer.parseInt(ussdResult[0]), ussdResult[1]);
-                    } catch (NumberFormatException e) {
-                        Log.w(LOG_TAG, "error parsing USSD");
-                    }
-                }
-            break;
-
-            case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
-                // Some MMI requests (eg USSD) are not completed
-                // within the course of a CommandsInterface request
-                // If the radio shuts off or resets while one of these
-                // is pending, we need to clean up.
-
-                for (int i = 0, s = mPendingMMIs.size() ; i < s; i++) {
-                    if (mPendingMMIs.get(i).isPendingUSSD()) {
-                        mPendingMMIs.get(i).onUssdFinishedError();
-                    }
-                }
-            break;
-
-            case EVENT_SSN:
-                ar = (AsyncResult)msg.obj;
-                SuppServiceNotification not = (SuppServiceNotification) ar.result;
-                mSsnRegistrants.notifyRegistrants(ar);
-            break;
-
-            case EVENT_SET_CALL_FORWARD_DONE:
-                ar = (AsyncResult)msg.obj;
-                if (ar.exception == null) {
-                    mIccRecords.setVoiceCallForwardingFlag(1, msg.arg1 == 1);
-                }
-                onComplete = (Message) ar.userObj;
-                if (onComplete != null) {
-                    AsyncResult.forMessage(onComplete, ar.result, ar.exception);
-                    onComplete.sendToTarget();
-                }
-                break;
-
-            case EVENT_SET_VM_NUMBER_DONE:
-                ar = (AsyncResult)msg.obj;
-                if (IccVmNotSupportedException.class.isInstance(ar.exception)) {
-                    storeVoiceMailNumber(mVmNumber);
-                    ar.exception = null;
-                }
-                onComplete = (Message) ar.userObj;
-                if (onComplete != null) {
-                    AsyncResult.forMessage(onComplete, ar.result, ar.exception);
-                    onComplete.sendToTarget();
-                }
-                break;
-
-
-            case EVENT_GET_CALL_FORWARD_DONE:
-                ar = (AsyncResult)msg.obj;
-                if (ar.exception == null) {
-                    handleCfuQueryResult((CallForwardInfo[])ar.result);
-                }
-                onComplete = (Message) ar.userObj;
-                if (onComplete != null) {
-                    AsyncResult.forMessage(onComplete, ar.result, ar.exception);
-                    onComplete.sendToTarget();
-                }
-                break;
-
-            case EVENT_NEW_ICC_SMS:
-                ar = (AsyncResult)msg.obj;
-                mSMS.dispatchMessage((SmsMessage)ar.result);
-                break;
-
-            case EVENT_SET_NETWORK_AUTOMATIC:
-                ar = (AsyncResult)msg.obj;
-                setNetworkSelectionModeAutomatic((Message)ar.result);
-                break;
-
-            case EVENT_ICC_RECORD_EVENTS:
-                ar = (AsyncResult)msg.obj;
-                processIccRecordEvents((Integer)ar.result);
-                break;
-
-            // handle the select network completion callbacks.
-            case EVENT_SET_NETWORK_MANUAL_COMPLETE:
-            case EVENT_SET_NETWORK_AUTOMATIC_COMPLETE:
-                handleSetSelectNetwork((AsyncResult) msg.obj);
-                break;
-
-            case EVENT_SET_CLIR_COMPLETE:
-                ar = (AsyncResult)msg.obj;
-                if (ar.exception == null) {
-                    saveClirSetting(msg.arg1);
-                }
-                onComplete = (Message) ar.userObj;
-                if (onComplete != null) {
-                    AsyncResult.forMessage(onComplete, ar.result, ar.exception);
-                    onComplete.sendToTarget();
-                }
-                break;
-
-             default:
-                 super.handleMessage(msg);
-        }
-    }
-
-    private void processIccRecordEvents(int eventCode) {
-        switch (eventCode) {
-            case SIMRecords.EVENT_CFI:
-                notifyCallForwardingIndicator();
-                break;
-            case SIMRecords.EVENT_MWI:
-                notifyMessageWaitingIndicator();
-                break;
-        }
-    }
-
-   /**
-     * Sets the "current" field in the telephony provider according to the SIM's operator
-     *
-     * @return true for success; false otherwise.
-     */
-    boolean updateCurrentCarrierInProvider() {
-        if (mIccRecords != null) {
-            try {
-                Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current");
-                ContentValues map = new ContentValues();
-                map.put(Telephony.Carriers.NUMERIC, mIccRecords.getOperatorNumeric());
-                mContext.getContentResolver().insert(uri, map);
-                return true;
-            } catch (SQLException e) {
-                Log.e(LOG_TAG, "Can't store current operator", e);
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Used to track the settings upon completion of the network change.
-     */
-    private void handleSetSelectNetwork(AsyncResult ar) {
-        // look for our wrapper within the asyncresult, skip the rest if it
-        // is null.
-        if (!(ar.userObj instanceof NetworkSelectMessage)) {
-            if (LOCAL_DEBUG) Log.d(LOG_TAG, "unexpected result from user object.");
-            return;
-        }
-
-        NetworkSelectMessage nsm = (NetworkSelectMessage) ar.userObj;
-
-        // found the object, now we send off the message we had originally
-        // attached to the request.
-        if (nsm.message != null) {
-            if (LOCAL_DEBUG) Log.d(LOG_TAG, "sending original message to recipient");
-            AsyncResult.forMessage(nsm.message, ar.result, ar.exception);
-            nsm.message.sendToTarget();
-        }
-
-        // open the shared preferences editor, and write the value.
-        // nsm.operatorNumeric is "" if we're in automatic.selection.
-        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
-        SharedPreferences.Editor editor = sp.edit();
-        editor.putString(NETWORK_SELECTION_KEY, nsm.operatorNumeric);
-        editor.putString(NETWORK_SELECTION_NAME_KEY, nsm.operatorAlphaLong);
-
-        // commit and log the result.
-        if (! editor.commit()) {
-            Log.e(LOG_TAG, "failed to commit network selection preference");
-        }
-
-    }
-
-    /**
-     * Saves CLIR setting so that we can re-apply it as necessary
-     * (in case the RIL resets it across reboots).
-     */
-    public void saveClirSetting(int commandInterfaceCLIRMode) {
-        // open the shared preferences editor, and write the value.
-        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
-        SharedPreferences.Editor editor = sp.edit();
-        editor.putInt(CLIR_KEY, commandInterfaceCLIRMode);
-
-        // commit and log the result.
-        if (! editor.commit()) {
-            Log.e(LOG_TAG, "failed to commit CLIR preference");
-        }
-    }
-
-    private void handleCfuQueryResult(CallForwardInfo[] infos) {
-        if (infos == null || infos.length == 0) {
-            // Assume the default is not active
-            // Set unconditional CFF in SIM to false
-            mIccRecords.setVoiceCallForwardingFlag(1, false);
-        } else {
-            for (int i = 0, s = infos.length; i < s; i++) {
-                if ((infos[i].serviceClass & SERVICE_CLASS_VOICE) != 0) {
-                    mIccRecords.setVoiceCallForwardingFlag(1, (infos[i].status == 1));
-                    // should only have the one
-                    break;
-                }
-            }
-        }
-    }
-
-    /**
-     * Retrieves the PhoneSubInfo of the GSMPhone
-     */
-    public PhoneSubInfo getPhoneSubInfo(){
-        return mSubInfo;
-    }
-
-    /**
-     * Retrieves the IccSmsInterfaceManager of the GSMPhone
-     */
-    public IccSmsInterfaceManager getIccSmsInterfaceManager(){
-        return mSimSmsIntManager;
-    }
-
-    /**
-     * Retrieves the IccPhoneBookInterfaceManager of the GSMPhone
-     */
-    public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(){
-        return mSimPhoneBookIntManager;
-    }
-
-    /**
-     * Activate or deactivate cell broadcast SMS.
-     *
-     * @param activate 0 = activate, 1 = deactivate
-     * @param response Callback message is empty on completion
-     */
-    public void activateCellBroadcastSms(int activate, Message response) {
-        Log.e(LOG_TAG, "[GSMPhone] activateCellBroadcastSms() is obsolete; use SmsManager");
-        response.sendToTarget();
-    }
-
-    /**
-     * Query the current configuration of cdma cell broadcast SMS.
-     *
-     * @param response Callback message is empty on completion
-     */
-    public void getCellBroadcastSmsConfig(Message response) {
-        Log.e(LOG_TAG, "[GSMPhone] getCellBroadcastSmsConfig() is obsolete; use SmsManager");
-        response.sendToTarget();
-    }
-
-    /**
-     * Configure cdma cell broadcast SMS.
-     *
-     * @param response Callback message is empty on completion
-     */
-    public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response) {
-        Log.e(LOG_TAG, "[GSMPhone] setCellBroadcastSmsConfig() is obsolete; use SmsManager");
-        response.sendToTarget();
-    }
-
-    public boolean isCspPlmnEnabled() {
-        return mIccRecords.isCspPlmnEnabled();
-    }
-
-    private void registerForSimRecordEvents() {
-        mIccRecords.registerForNetworkSelectionModeAutomatic(
-                this, EVENT_SET_NETWORK_AUTOMATIC, null);
-        mIccRecords.registerForNewSms(this, EVENT_NEW_ICC_SMS, null);
-        mIccRecords.registerForRecordsEvents(this, EVENT_ICC_RECORD_EVENTS, null);
-        mIccRecords.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null);
-    }
-
-    private void unregisterForSimRecordEvents() {
-        mIccRecords.unregisterForNetworkSelectionModeAutomatic(this);
-        mIccRecords.unregisterForNewSms(this);
-        mIccRecords.unregisterForRecordsEvents(this);
-        mIccRecords.unregisterForRecordsLoaded(this);
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("GSMPhone extends:");
-        super.dump(fd, pw, args);
-        pw.println(" mCT=" + mCT);
-        pw.println(" mSST=" + mSST);
-        pw.println(" mPendingMMIs=" + mPendingMMIs);
-        pw.println(" mSimPhoneBookIntManager=" + mSimPhoneBookIntManager);
-        pw.println(" mSimSmsIntManager=" + mSimSmsIntManager);
-        pw.println(" mSubInfo=" + mSubInfo);
-        if (VDBG) pw.println(" mImei=" + mImei);
-        if (VDBG) pw.println(" mImeiSv=" + mImeiSv);
-        pw.println(" mVmNumber=" + mVmNumber);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmCall.java b/telephony/java/com/android/internal/telephony/gsm/GsmCall.java
deleted file mode 100644
index 58124a2..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GsmCall.java
+++ /dev/null
@@ -1,208 +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.internal.telephony.gsm;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallStateException;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.DriverCall;
-import com.android.internal.telephony.Phone;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * {@hide}
- */
-class GsmCall extends Call {
-    /*************************** Instance Variables **************************/
-
-    /*package*/ ArrayList<Connection> connections = new ArrayList<Connection>();
-    /*package*/ GsmCallTracker owner;
-
-
-    /***************************** Class Methods *****************************/
-
-    static State
-    stateFromDCState (DriverCall.State dcState) {
-        switch (dcState) {
-            case ACTIVE:        return State.ACTIVE;
-            case HOLDING:       return State.HOLDING;
-            case DIALING:       return State.DIALING;
-            case ALERTING:      return State.ALERTING;
-            case INCOMING:      return State.INCOMING;
-            case WAITING:       return State.WAITING;
-            default:            throw new RuntimeException ("illegal call state:" + dcState);
-        }
-    }
-
-
-    /****************************** Constructors *****************************/
-    /*package*/
-    GsmCall (GsmCallTracker owner) {
-        this.owner = owner;
-    }
-
-    public void dispose() {
-    }
-
-    /************************** Overridden from Call *************************/
-
-    public List<Connection>
-    getConnections() {
-        // FIXME should return Collections.unmodifiableList();
-        return connections;
-    }
-
-    public Phone
-    getPhone() {
-        return owner.phone;
-    }
-
-    public boolean
-    isMultiparty() {
-        return connections.size() > 1;
-    }
-
-    /** Please note: if this is the foreground call and a
-     *  background call exists, the background call will be resumed
-     *  because an AT+CHLD=1 will be sent
-     */
-    public void
-    hangup() throws CallStateException {
-        owner.hangup(this);
-    }
-
-    public String
-    toString() {
-        return state.toString();
-    }
-
-    //***** Called from GsmConnection
-
-    /*package*/ void
-    attach(Connection conn, DriverCall dc) {
-        connections.add(conn);
-
-        state = stateFromDCState (dc.state);
-    }
-
-    /*package*/ void
-    attachFake(Connection conn, State state) {
-        connections.add(conn);
-
-        this.state = state;
-    }
-
-    /**
-     * Called by GsmConnection when it has disconnected
-     */
-    void
-    connectionDisconnected(GsmConnection conn) {
-        if (state != State.DISCONNECTED) {
-            /* If only disconnected connections remain, we are disconnected*/
-
-            boolean hasOnlyDisconnectedConnections = true;
-
-            for (int i = 0, s = connections.size()  ; i < s; i ++) {
-                if (connections.get(i).getState()
-                    != State.DISCONNECTED
-                ) {
-                    hasOnlyDisconnectedConnections = false;
-                    break;
-                }
-            }
-
-            if (hasOnlyDisconnectedConnections) {
-                state = State.DISCONNECTED;
-            }
-        }
-    }
-
-
-    /*package*/ void
-    detach(GsmConnection conn) {
-        connections.remove(conn);
-
-        if (connections.size() == 0) {
-            state = State.IDLE;
-        }
-    }
-
-    /*package*/ boolean
-    update (GsmConnection conn, DriverCall dc) {
-        State newState;
-        boolean changed = false;
-
-        newState = stateFromDCState(dc.state);
-
-        if (newState != state) {
-            state = newState;
-            changed = true;
-        }
-
-        return changed;
-    }
-
-    /**
-     * @return true if there's no space in this call for additional
-     * connections to be added via "conference"
-     */
-    /*package*/ boolean
-    isFull() {
-        return connections.size() == GsmCallTracker.MAX_CONNECTIONS_PER_CALL;
-    }
-
-    //***** Called from GsmCallTracker
-
-
-    /**
-     * Called when this Call is being hung up locally (eg, user pressed "end")
-     * Note that at this point, the hangup request has been dispatched to the radio
-     * but no response has yet been received so update() has not yet been called
-     */
-    void
-    onHangupLocal() {
-        for (int i = 0, s = connections.size()
-                ; i < s; i++
-        ) {
-            GsmConnection cn = (GsmConnection)connections.get(i);
-
-            cn.onHangupLocal();
-        }
-        state = State.DISCONNECTING;
-    }
-
-    /**
-     * Called when it's time to clean up disconnected Connection objects
-     */
-    void
-    clearDisconnected() {
-        for (int i = connections.size() - 1 ; i >= 0 ; i--) {
-            GsmConnection cn = (GsmConnection)connections.get(i);
-
-            if (cn.getState() == State.DISCONNECTED) {
-                connections.remove(i);
-            }
-        }
-
-        if (connections.size() == 0) {
-            state = State.IDLE;
-        }
-    }
-}
-
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java
deleted file mode 100644
index e86d853..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java
+++ /dev/null
@@ -1,951 +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.internal.telephony.gsm;
-
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.os.SystemProperties;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.ServiceState;
-import android.telephony.TelephonyManager;
-import android.telephony.gsm.GsmCellLocation;
-import android.util.EventLog;
-import android.util.Log;
-
-import com.android.internal.telephony.CallStateException;
-import com.android.internal.telephony.CallTracker;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.DriverCall;
-import com.android.internal.telephony.EventLogTags;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.telephony.UUSInfo;
-import com.android.internal.telephony.gsm.CallFailCause;
-import com.android.internal.telephony.gsm.GSMPhone;
-import com.android.internal.telephony.gsm.GsmCall;
-import com.android.internal.telephony.gsm.GsmConnection;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * {@hide}
- */
-public final class GsmCallTracker extends CallTracker {
-    static final String LOG_TAG = "GSM";
-    private static final boolean REPEAT_POLLING = false;
-
-    private static final boolean DBG_POLL = false;
-
-    //***** Constants
-
-    static final int MAX_CONNECTIONS = 7;   // only 7 connections allowed in GSM
-    static final int MAX_CONNECTIONS_PER_CALL = 5; // only 5 connections allowed per call
-
-    //***** Instance Variables
-    GsmConnection connections[] = new GsmConnection[MAX_CONNECTIONS];
-    RegistrantList voiceCallEndedRegistrants = new RegistrantList();
-    RegistrantList voiceCallStartedRegistrants = new RegistrantList();
-
-
-    // connections dropped during last poll
-    ArrayList<GsmConnection> droppedDuringPoll
-        = new ArrayList<GsmConnection>(MAX_CONNECTIONS);
-
-    GsmCall ringingCall = new GsmCall(this);
-            // A call that is ringing or (call) waiting
-    GsmCall foregroundCall = new GsmCall(this);
-    GsmCall backgroundCall = new GsmCall(this);
-
-    GsmConnection pendingMO;
-    boolean hangupPendingMO;
-
-    GSMPhone phone;
-
-    boolean desiredMute = false;    // false = mute off
-
-    Phone.State state = Phone.State.IDLE;
-
-
-
-    //***** Events
-
-
-    //***** Constructors
-
-    GsmCallTracker (GSMPhone phone) {
-        this.phone = phone;
-        cm = phone.mCM;
-
-        cm.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null);
-
-        cm.registerForOn(this, EVENT_RADIO_AVAILABLE, null);
-        cm.registerForNotAvailable(this, EVENT_RADIO_NOT_AVAILABLE, null);
-    }
-
-    public void dispose() {
-        //Unregister for all events
-        cm.unregisterForCallStateChanged(this);
-        cm.unregisterForOn(this);
-        cm.unregisterForNotAvailable(this);
-
-        for(GsmConnection c : connections) {
-            try {
-                if(c != null) hangup(c);
-            } catch (CallStateException ex) {
-                Log.e(LOG_TAG, "unexpected error on hangup during dispose");
-            }
-        }
-
-        try {
-            if(pendingMO != null) hangup(pendingMO);
-        } catch (CallStateException ex) {
-            Log.e(LOG_TAG, "unexpected error on hangup during dispose");
-        }
-
-        clearDisconnected();
-    }
-
-    protected void finalize() {
-        Log.d(LOG_TAG, "GsmCallTracker finalized");
-    }
-
-    //***** Instance Methods
-
-    //***** Public Methods
-    public void registerForVoiceCallStarted(Handler h, int what, Object obj) {
-        Registrant r = new Registrant(h, what, obj);
-        voiceCallStartedRegistrants.add(r);
-    }
-
-    public void unregisterForVoiceCallStarted(Handler h) {
-        voiceCallStartedRegistrants.remove(h);
-    }
-
-    public void registerForVoiceCallEnded(Handler h, int what, Object obj) {
-        Registrant r = new Registrant(h, what, obj);
-        voiceCallEndedRegistrants.add(r);
-    }
-
-    public void unregisterForVoiceCallEnded(Handler h) {
-        voiceCallEndedRegistrants.remove(h);
-    }
-
-    private void
-    fakeHoldForegroundBeforeDial() {
-        List<Connection> connCopy;
-
-        // We need to make a copy here, since fakeHoldBeforeDial()
-        // modifies the lists, and we don't want to reverse the order
-        connCopy = (List<Connection>) foregroundCall.connections.clone();
-
-        for (int i = 0, s = connCopy.size() ; i < s ; i++) {
-            GsmConnection conn = (GsmConnection)connCopy.get(i);
-
-            conn.fakeHoldBeforeDial();
-        }
-    }
-
-    /**
-     * clirMode is one of the CLIR_ constants
-     */
-    synchronized Connection
-    dial (String dialString, int clirMode, UUSInfo uusInfo) throws CallStateException {
-        // note that this triggers call state changed notif
-        clearDisconnected();
-
-        if (!canDial()) {
-            throw new CallStateException("cannot dial in current state");
-        }
-
-        // The new call must be assigned to the foreground call.
-        // That call must be idle, so place anything that's
-        // there on hold
-        if (foregroundCall.getState() == GsmCall.State.ACTIVE) {
-            // this will probably be done by the radio anyway
-            // but the dial might fail before this happens
-            // and we need to make sure the foreground call is clear
-            // for the newly dialed connection
-            switchWaitingOrHoldingAndActive();
-
-            // Fake local state so that
-            // a) foregroundCall is empty for the newly dialed connection
-            // b) hasNonHangupStateChanged remains false in the
-            // next poll, so that we don't clear a failed dialing call
-            fakeHoldForegroundBeforeDial();
-        }
-
-        if (foregroundCall.getState() != GsmCall.State.IDLE) {
-            //we should have failed in !canDial() above before we get here
-            throw new CallStateException("cannot dial in current state");
-        }
-
-        pendingMO = new GsmConnection(phone.getContext(), checkForTestEmergencyNumber(dialString),
-                this, foregroundCall);
-        hangupPendingMO = false;
-
-        if (pendingMO.address == null || pendingMO.address.length() == 0
-            || pendingMO.address.indexOf(PhoneNumberUtils.WILD) >= 0
-        ) {
-            // Phone number is invalid
-            pendingMO.cause = Connection.DisconnectCause.INVALID_NUMBER;
-
-            // handlePollCalls() will notice this call not present
-            // and will mark it as dropped.
-            pollCallsWhenSafe();
-        } else {
-            // Always unmute when initiating a new call
-            setMute(false);
-
-            cm.dial(pendingMO.address, clirMode, uusInfo, obtainCompleteMessage());
-        }
-
-        updatePhoneState();
-        phone.notifyPreciseCallStateChanged();
-
-        return pendingMO;
-    }
-
-    Connection
-    dial(String dialString) throws CallStateException {
-        return dial(dialString, CommandsInterface.CLIR_DEFAULT, null);
-    }
-
-    Connection
-    dial(String dialString, UUSInfo uusInfo) throws CallStateException {
-        return dial(dialString, CommandsInterface.CLIR_DEFAULT, uusInfo);
-    }
-
-    Connection
-    dial(String dialString, int clirMode) throws CallStateException {
-        return dial(dialString, clirMode, null);
-    }
-
-    void
-    acceptCall () throws CallStateException {
-        // FIXME if SWITCH fails, should retry with ANSWER
-        // in case the active/holding call disappeared and this
-        // is no longer call waiting
-
-        if (ringingCall.getState() == GsmCall.State.INCOMING) {
-            Log.i("phone", "acceptCall: incoming...");
-            // Always unmute when answering a new call
-            setMute(false);
-            cm.acceptCall(obtainCompleteMessage());
-        } else if (ringingCall.getState() == GsmCall.State.WAITING) {
-            setMute(false);
-            switchWaitingOrHoldingAndActive();
-        } else {
-            throw new CallStateException("phone not ringing");
-        }
-    }
-
-    void
-    rejectCall () throws CallStateException {
-        // AT+CHLD=0 means "release held or UDUB"
-        // so if the phone isn't ringing, this could hang up held
-        if (ringingCall.getState().isRinging()) {
-            cm.rejectCall(obtainCompleteMessage());
-        } else {
-            throw new CallStateException("phone not ringing");
-        }
-    }
-
-    void
-    switchWaitingOrHoldingAndActive() throws CallStateException {
-        // Should we bother with this check?
-        if (ringingCall.getState() == GsmCall.State.INCOMING) {
-            throw new CallStateException("cannot be in the incoming state");
-        } else {
-            cm.switchWaitingOrHoldingAndActive(
-                    obtainCompleteMessage(EVENT_SWITCH_RESULT));
-        }
-    }
-
-    void
-    conference() throws CallStateException {
-        cm.conference(obtainCompleteMessage(EVENT_CONFERENCE_RESULT));
-    }
-
-    void
-    explicitCallTransfer() throws CallStateException {
-        cm.explicitCallTransfer(obtainCompleteMessage(EVENT_ECT_RESULT));
-    }
-
-    void
-    clearDisconnected() {
-        internalClearDisconnected();
-
-        updatePhoneState();
-        phone.notifyPreciseCallStateChanged();
-    }
-
-    boolean
-    canConference() {
-        return foregroundCall.getState() == GsmCall.State.ACTIVE
-                && backgroundCall.getState() == GsmCall.State.HOLDING
-                && !backgroundCall.isFull()
-                && !foregroundCall.isFull();
-    }
-
-    boolean
-    canDial() {
-        boolean ret;
-        int serviceState = phone.getServiceState().getState();
-        String disableCall = SystemProperties.get(
-                TelephonyProperties.PROPERTY_DISABLE_CALL, "false");
-
-        ret = (serviceState != ServiceState.STATE_POWER_OFF)
-                && pendingMO == null
-                && !ringingCall.isRinging()
-                && !disableCall.equals("true")
-                && (!foregroundCall.getState().isAlive()
-                    || !backgroundCall.getState().isAlive());
-
-        return ret;
-    }
-
-    boolean
-    canTransfer() {
-        return foregroundCall.getState() == GsmCall.State.ACTIVE
-                && backgroundCall.getState() == GsmCall.State.HOLDING;
-    }
-
-    //***** Private Instance Methods
-
-    private void
-    internalClearDisconnected() {
-        ringingCall.clearDisconnected();
-        foregroundCall.clearDisconnected();
-        backgroundCall.clearDisconnected();
-    }
-
-    /**
-     * Obtain a message to use for signalling "invoke getCurrentCalls() when
-     * this operation and all other pending operations are complete
-     */
-    private Message
-    obtainCompleteMessage() {
-        return obtainCompleteMessage(EVENT_OPERATION_COMPLETE);
-    }
-
-    /**
-     * Obtain a message to use for signalling "invoke getCurrentCalls() when
-     * this operation and all other pending operations are complete
-     */
-    private Message
-    obtainCompleteMessage(int what) {
-        pendingOperations++;
-        lastRelevantPoll = null;
-        needsPoll = true;
-
-        if (DBG_POLL) log("obtainCompleteMessage: pendingOperations=" +
-                pendingOperations + ", needsPoll=" + needsPoll);
-
-        return obtainMessage(what);
-    }
-
-    private void
-    operationComplete() {
-        pendingOperations--;
-
-        if (DBG_POLL) log("operationComplete: pendingOperations=" +
-                pendingOperations + ", needsPoll=" + needsPoll);
-
-        if (pendingOperations == 0 && needsPoll) {
-            lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
-            cm.getCurrentCalls(lastRelevantPoll);
-        } else if (pendingOperations < 0) {
-            // this should never happen
-            Log.e(LOG_TAG,"GsmCallTracker.pendingOperations < 0");
-            pendingOperations = 0;
-        }
-    }
-
-    private void
-    updatePhoneState() {
-        Phone.State oldState = state;
-
-        if (ringingCall.isRinging()) {
-            state = Phone.State.RINGING;
-        } else if (pendingMO != null ||
-                !(foregroundCall.isIdle() && backgroundCall.isIdle())) {
-            state = Phone.State.OFFHOOK;
-        } else {
-            state = Phone.State.IDLE;
-        }
-
-        if (state == Phone.State.IDLE && oldState != state) {
-            voiceCallEndedRegistrants.notifyRegistrants(
-                new AsyncResult(null, null, null));
-        } else if (oldState == Phone.State.IDLE && oldState != state) {
-            voiceCallStartedRegistrants.notifyRegistrants (
-                    new AsyncResult(null, null, null));
-        }
-
-        if (state != oldState) {
-            phone.notifyPhoneStateChanged();
-        }
-    }
-
-    protected synchronized void
-    handlePollCalls(AsyncResult ar) {
-        List polledCalls;
-
-        if (ar.exception == null) {
-            polledCalls = (List)ar.result;
-        } else if (isCommandExceptionRadioNotAvailable(ar.exception)) {
-            // just a dummy empty ArrayList to cause the loop
-            // to hang up all the calls
-            polledCalls = new ArrayList();
-        } else {
-            // Radio probably wasn't ready--try again in a bit
-            // But don't keep polling if the channel is closed
-            pollCallsAfterDelay();
-            return;
-        }
-
-        Connection newRinging = null; //or waiting
-        boolean hasNonHangupStateChanged = false;   // Any change besides
-                                                    // a dropped connection
-        boolean needsPollDelay = false;
-        boolean unknownConnectionAppeared = false;
-
-        for (int i = 0, curDC = 0, dcSize = polledCalls.size()
-                ; i < connections.length; i++) {
-            GsmConnection conn = connections[i];
-            DriverCall dc = null;
-
-            // polledCall list is sparse
-            if (curDC < dcSize) {
-                dc = (DriverCall) polledCalls.get(curDC);
-
-                if (dc.index == i+1) {
-                    curDC++;
-                } else {
-                    dc = null;
-                }
-            }
-
-            if (DBG_POLL) log("poll: conn[i=" + i + "]=" +
-                    conn+", dc=" + dc);
-
-            if (conn == null && dc != null) {
-                // Connection appeared in CLCC response that we don't know about
-                if (pendingMO != null && pendingMO.compareTo(dc)) {
-
-                    if (DBG_POLL) log("poll: pendingMO=" + pendingMO);
-
-                    // It's our pending mobile originating call
-                    connections[i] = pendingMO;
-                    pendingMO.index = i;
-                    pendingMO.update(dc);
-                    pendingMO = null;
-
-                    // Someone has already asked to hangup this call
-                    if (hangupPendingMO) {
-                        hangupPendingMO = false;
-                        try {
-                            if (Phone.DEBUG_PHONE) log(
-                                    "poll: hangupPendingMO, hangup conn " + i);
-                            hangup(connections[i]);
-                        } catch (CallStateException ex) {
-                            Log.e(LOG_TAG, "unexpected error on hangup");
-                        }
-
-                        // Do not continue processing this poll
-                        // Wait for hangup and repoll
-                        return;
-                    }
-                } else {
-                    connections[i] = new GsmConnection(phone.getContext(), dc, this, i);
-
-                    // it's a ringing call
-                    if (connections[i].getCall() == ringingCall) {
-                        newRinging = connections[i];
-                    } else {
-                        // Something strange happened: a call appeared
-                        // which is neither a ringing call or one we created.
-                        // Either we've crashed and re-attached to an existing
-                        // call, or something else (eg, SIM) initiated the call.
-
-                        Log.i(LOG_TAG,"Phantom call appeared " + dc);
-
-                        // If it's a connected call, set the connect time so that
-                        // it's non-zero.  It may not be accurate, but at least
-                        // it won't appear as a Missed Call.
-                        if (dc.state != DriverCall.State.ALERTING
-                                && dc.state != DriverCall.State.DIALING) {
-                            connections[i].connectTime = System.currentTimeMillis();
-                        }
-
-                        unknownConnectionAppeared = true;
-                    }
-                }
-                hasNonHangupStateChanged = true;
-            } else if (conn != null && dc == null) {
-                // Connection missing in CLCC response that we were
-                // tracking.
-                droppedDuringPoll.add(conn);
-                // Dropped connections are removed from the CallTracker
-                // list but kept in the GsmCall list
-                connections[i] = null;
-            } else if (conn != null && dc != null && !conn.compareTo(dc)) {
-                // Connection in CLCC response does not match what
-                // we were tracking. Assume dropped call and new call
-
-                droppedDuringPoll.add(conn);
-                connections[i] = new GsmConnection (phone.getContext(), dc, this, i);
-
-                if (connections[i].getCall() == ringingCall) {
-                    newRinging = connections[i];
-                } // else something strange happened
-                hasNonHangupStateChanged = true;
-            } else if (conn != null && dc != null) { /* implicit conn.compareTo(dc) */
-                boolean changed;
-                changed = conn.update(dc);
-                hasNonHangupStateChanged = hasNonHangupStateChanged || changed;
-            }
-
-            if (REPEAT_POLLING) {
-                if (dc != null) {
-                    // FIXME with RIL, we should not need this anymore
-                    if ((dc.state == DriverCall.State.DIALING
-                            /*&& cm.getOption(cm.OPTION_POLL_DIALING)*/)
-                        || (dc.state == DriverCall.State.ALERTING
-                            /*&& cm.getOption(cm.OPTION_POLL_ALERTING)*/)
-                        || (dc.state == DriverCall.State.INCOMING
-                            /*&& cm.getOption(cm.OPTION_POLL_INCOMING)*/)
-                        || (dc.state == DriverCall.State.WAITING
-                            /*&& cm.getOption(cm.OPTION_POLL_WAITING)*/)
-                    ) {
-                        // Sometimes there's no unsolicited notification
-                        // for state transitions
-                        needsPollDelay = true;
-                    }
-                }
-            }
-        }
-
-        // This is the first poll after an ATD.
-        // We expect the pending call to appear in the list
-        // If it does not, we land here
-        if (pendingMO != null) {
-            Log.d(LOG_TAG,"Pending MO dropped before poll fg state:"
-                            + foregroundCall.getState());
-
-            droppedDuringPoll.add(pendingMO);
-            pendingMO = null;
-            hangupPendingMO = false;
-        }
-
-        if (newRinging != null) {
-            phone.notifyNewRingingConnection(newRinging);
-        }
-
-        // clear the "local hangup" and "missed/rejected call"
-        // cases from the "dropped during poll" list
-        // These cases need no "last call fail" reason
-        for (int i = droppedDuringPoll.size() - 1; i >= 0 ; i--) {
-            GsmConnection conn = droppedDuringPoll.get(i);
-
-            if (conn.isIncoming() && conn.getConnectTime() == 0) {
-                // Missed or rejected call
-                Connection.DisconnectCause cause;
-                if (conn.cause == Connection.DisconnectCause.LOCAL) {
-                    cause = Connection.DisconnectCause.INCOMING_REJECTED;
-                } else {
-                    cause = Connection.DisconnectCause.INCOMING_MISSED;
-                }
-
-                if (Phone.DEBUG_PHONE) {
-                    log("missed/rejected call, conn.cause=" + conn.cause);
-                    log("setting cause to " + cause);
-                }
-                droppedDuringPoll.remove(i);
-                conn.onDisconnect(cause);
-            } else if (conn.cause == Connection.DisconnectCause.LOCAL) {
-                // Local hangup
-                droppedDuringPoll.remove(i);
-                conn.onDisconnect(Connection.DisconnectCause.LOCAL);
-            } else if (conn.cause ==
-                Connection.DisconnectCause.INVALID_NUMBER) {
-                droppedDuringPoll.remove(i);
-                conn.onDisconnect(Connection.DisconnectCause.INVALID_NUMBER);
-            }
-        }
-
-        // Any non-local disconnects: determine cause
-        if (droppedDuringPoll.size() > 0) {
-            cm.getLastCallFailCause(
-                obtainNoPollCompleteMessage(EVENT_GET_LAST_CALL_FAIL_CAUSE));
-        }
-
-        if (needsPollDelay) {
-            pollCallsAfterDelay();
-        }
-
-        // Cases when we can no longer keep disconnected Connection's
-        // with their previous calls
-        // 1) the phone has started to ring
-        // 2) A Call/Connection object has changed state...
-        //    we may have switched or held or answered (but not hung up)
-        if (newRinging != null || hasNonHangupStateChanged) {
-            internalClearDisconnected();
-        }
-
-        updatePhoneState();
-
-        if (unknownConnectionAppeared) {
-            phone.notifyUnknownConnection();
-        }
-
-        if (hasNonHangupStateChanged || newRinging != null) {
-            phone.notifyPreciseCallStateChanged();
-        }
-
-        //dumpState();
-    }
-
-    private void
-    handleRadioNotAvailable() {
-        // handlePollCalls will clear out its
-        // call list when it gets the CommandException
-        // error result from this
-        pollCallsWhenSafe();
-    }
-
-    private void
-    dumpState() {
-        List l;
-
-        Log.i(LOG_TAG,"Phone State:" + state);
-
-        Log.i(LOG_TAG,"Ringing call: " + ringingCall.toString());
-
-        l = ringingCall.getConnections();
-        for (int i = 0, s = l.size(); i < s; i++) {
-            Log.i(LOG_TAG,l.get(i).toString());
-        }
-
-        Log.i(LOG_TAG,"Foreground call: " + foregroundCall.toString());
-
-        l = foregroundCall.getConnections();
-        for (int i = 0, s = l.size(); i < s; i++) {
-            Log.i(LOG_TAG,l.get(i).toString());
-        }
-
-        Log.i(LOG_TAG,"Background call: " + backgroundCall.toString());
-
-        l = backgroundCall.getConnections();
-        for (int i = 0, s = l.size(); i < s; i++) {
-            Log.i(LOG_TAG,l.get(i).toString());
-        }
-
-    }
-
-    //***** Called from GsmConnection
-
-    /*package*/ void
-    hangup (GsmConnection conn) throws CallStateException {
-        if (conn.owner != this) {
-            throw new CallStateException ("GsmConnection " + conn
-                                    + "does not belong to GsmCallTracker " + this);
-        }
-
-        if (conn == pendingMO) {
-            // We're hanging up an outgoing call that doesn't have it's
-            // GSM index assigned yet
-
-            if (Phone.DEBUG_PHONE) log("hangup: set hangupPendingMO to true");
-            hangupPendingMO = true;
-        } else {
-            try {
-                cm.hangupConnection (conn.getGSMIndex(), obtainCompleteMessage());
-            } catch (CallStateException ex) {
-                // Ignore "connection not found"
-                // Call may have hung up already
-                Log.w(LOG_TAG,"GsmCallTracker WARN: hangup() on absent connection "
-                                + conn);
-            }
-        }
-
-        conn.onHangupLocal();
-    }
-
-    /*package*/ void
-    separate (GsmConnection conn) throws CallStateException {
-        if (conn.owner != this) {
-            throw new CallStateException ("GsmConnection " + conn
-                                    + "does not belong to GsmCallTracker " + this);
-        }
-        try {
-            cm.separateConnection (conn.getGSMIndex(),
-                obtainCompleteMessage(EVENT_SEPARATE_RESULT));
-        } catch (CallStateException ex) {
-            // Ignore "connection not found"
-            // Call may have hung up already
-            Log.w(LOG_TAG,"GsmCallTracker WARN: separate() on absent connection "
-                          + conn);
-        }
-    }
-
-    //***** Called from GSMPhone
-
-    /*package*/ void
-    setMute(boolean mute) {
-        desiredMute = mute;
-        cm.setMute(desiredMute, null);
-    }
-
-    /*package*/ boolean
-    getMute() {
-        return desiredMute;
-    }
-
-
-    //***** Called from GsmCall
-
-    /* package */ void
-    hangup (GsmCall call) throws CallStateException {
-        if (call.getConnections().size() == 0) {
-            throw new CallStateException("no connections in call");
-        }
-
-        if (call == ringingCall) {
-            if (Phone.DEBUG_PHONE) log("(ringing) hangup waiting or background");
-            cm.hangupWaitingOrBackground(obtainCompleteMessage());
-        } else if (call == foregroundCall) {
-            if (call.isDialingOrAlerting()) {
-                if (Phone.DEBUG_PHONE) {
-                    log("(foregnd) hangup dialing or alerting...");
-                }
-                hangup((GsmConnection)(call.getConnections().get(0)));
-            } else {
-                hangupForegroundResumeBackground();
-            }
-        } else if (call == backgroundCall) {
-            if (ringingCall.isRinging()) {
-                if (Phone.DEBUG_PHONE) {
-                    log("hangup all conns in background call");
-                }
-                hangupAllConnections(call);
-            } else {
-                hangupWaitingOrBackground();
-            }
-        } else {
-            throw new RuntimeException ("GsmCall " + call +
-                    "does not belong to GsmCallTracker " + this);
-        }
-
-        call.onHangupLocal();
-        phone.notifyPreciseCallStateChanged();
-    }
-
-    /* package */
-    void hangupWaitingOrBackground() {
-        if (Phone.DEBUG_PHONE) log("hangupWaitingOrBackground");
-        cm.hangupWaitingOrBackground(obtainCompleteMessage());
-    }
-
-    /* package */
-    void hangupForegroundResumeBackground() {
-        if (Phone.DEBUG_PHONE) log("hangupForegroundResumeBackground");
-        cm.hangupForegroundResumeBackground(obtainCompleteMessage());
-    }
-
-    void hangupConnectionByIndex(GsmCall call, int index)
-            throws CallStateException {
-        int count = call.connections.size();
-        for (int i = 0; i < count; i++) {
-            GsmConnection cn = (GsmConnection)call.connections.get(i);
-            if (cn.getGSMIndex() == index) {
-                cm.hangupConnection(index, obtainCompleteMessage());
-                return;
-            }
-        }
-
-        throw new CallStateException("no gsm index found");
-    }
-
-    void hangupAllConnections(GsmCall call) throws CallStateException{
-        try {
-            int count = call.connections.size();
-            for (int i = 0; i < count; i++) {
-                GsmConnection cn = (GsmConnection)call.connections.get(i);
-                cm.hangupConnection(cn.getGSMIndex(), obtainCompleteMessage());
-            }
-        } catch (CallStateException ex) {
-            Log.e(LOG_TAG, "hangupConnectionByIndex caught " + ex);
-        }
-    }
-
-    /* package */
-    GsmConnection getConnectionByIndex(GsmCall call, int index)
-            throws CallStateException {
-        int count = call.connections.size();
-        for (int i = 0; i < count; i++) {
-            GsmConnection cn = (GsmConnection)call.connections.get(i);
-            if (cn.getGSMIndex() == index) {
-                return cn;
-            }
-        }
-
-        return null;
-    }
-
-    private Phone.SuppService getFailedService(int what) {
-        switch (what) {
-            case EVENT_SWITCH_RESULT:
-                return Phone.SuppService.SWITCH;
-            case EVENT_CONFERENCE_RESULT:
-                return Phone.SuppService.CONFERENCE;
-            case EVENT_SEPARATE_RESULT:
-                return Phone.SuppService.SEPARATE;
-            case EVENT_ECT_RESULT:
-                return Phone.SuppService.TRANSFER;
-        }
-        return Phone.SuppService.UNKNOWN;
-    }
-
-    //****** Overridden from Handler
-
-    public void
-    handleMessage (Message msg) {
-        AsyncResult ar;
-
-        switch (msg.what) {
-            case EVENT_POLL_CALLS_RESULT:
-                ar = (AsyncResult)msg.obj;
-
-                if (msg == lastRelevantPoll) {
-                    if (DBG_POLL) log(
-                            "handle EVENT_POLL_CALL_RESULT: set needsPoll=F");
-                    needsPoll = false;
-                    lastRelevantPoll = null;
-                    handlePollCalls((AsyncResult)msg.obj);
-                }
-            break;
-
-            case EVENT_OPERATION_COMPLETE:
-                ar = (AsyncResult)msg.obj;
-                operationComplete();
-            break;
-
-            case EVENT_SWITCH_RESULT:
-            case EVENT_CONFERENCE_RESULT:
-            case EVENT_SEPARATE_RESULT:
-            case EVENT_ECT_RESULT:
-                ar = (AsyncResult)msg.obj;
-                if (ar.exception != null) {
-                    phone.notifySuppServiceFailed(getFailedService(msg.what));
-                }
-                operationComplete();
-            break;
-
-            case EVENT_GET_LAST_CALL_FAIL_CAUSE:
-                int causeCode;
-                ar = (AsyncResult)msg.obj;
-
-                operationComplete();
-
-                if (ar.exception != null) {
-                    // An exception occurred...just treat the disconnect
-                    // cause as "normal"
-                    causeCode = CallFailCause.NORMAL_CLEARING;
-                    Log.i(LOG_TAG,
-                            "Exception during getLastCallFailCause, assuming normal disconnect");
-                } else {
-                    causeCode = ((int[])ar.result)[0];
-                }
-                // Log the causeCode if its not normal
-                if (causeCode == CallFailCause.NO_CIRCUIT_AVAIL ||
-                    causeCode == CallFailCause.TEMPORARY_FAILURE ||
-                    causeCode == CallFailCause.SWITCHING_CONGESTION ||
-                    causeCode == CallFailCause.CHANNEL_NOT_AVAIL ||
-                    causeCode == CallFailCause.QOS_NOT_AVAIL ||
-                    causeCode == CallFailCause.BEARER_NOT_AVAIL ||
-                    causeCode == CallFailCause.ERROR_UNSPECIFIED) {
-                    GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation());
-                    EventLog.writeEvent(EventLogTags.CALL_DROP,
-                            causeCode, loc != null ? loc.getCid() : -1,
-                            TelephonyManager.getDefault().getNetworkType());
-                }
-
-                for (int i = 0, s =  droppedDuringPoll.size()
-                        ; i < s ; i++
-                ) {
-                    GsmConnection conn = droppedDuringPoll.get(i);
-
-                    conn.onRemoteDisconnect(causeCode);
-                }
-
-                updatePhoneState();
-
-                phone.notifyPreciseCallStateChanged();
-                droppedDuringPoll.clear();
-            break;
-
-            case EVENT_REPOLL_AFTER_DELAY:
-            case EVENT_CALL_STATE_CHANGE:
-                pollCallsWhenSafe();
-            break;
-
-            case EVENT_RADIO_AVAILABLE:
-                handleRadioAvailable();
-            break;
-
-            case EVENT_RADIO_NOT_AVAILABLE:
-                handleRadioNotAvailable();
-            break;
-        }
-    }
-
-    protected void log(String msg) {
-        Log.d(LOG_TAG, "[GsmCallTracker] " + msg);
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("GsmCallTracker extends:");
-        super.dump(fd, pw, args);
-        pw.println("connections: length=" + connections.length);
-        for(int i=0; i < connections.length; i++) {
-            pw.printf("  connections[%d]=%s\n", i, connections[i]);
-        }
-        pw.println(" voiceCallEndedRegistrants=" + voiceCallEndedRegistrants);
-        pw.println(" voiceCallStartedRegistrants=" + voiceCallStartedRegistrants);
-        pw.println(" droppedDuringPoll: size=" + droppedDuringPoll.size());
-        for(int i = 0; i < droppedDuringPoll.size(); i++) {
-            pw.printf( "  droppedDuringPoll[%d]=%s\n", i, droppedDuringPoll.get(i));
-        }
-        pw.println(" ringingCall=" + ringingCall);
-        pw.println(" foregroundCall=" + foregroundCall);
-        pw.println(" backgroundCall=" + backgroundCall);
-        pw.println(" pendingMO=" + pendingMO);
-        pw.println(" hangupPendingMO=" + hangupPendingMO);
-        pw.println(" phone=" + phone);
-        pw.println(" desiredMute=" + desiredMute);
-        pw.println(" state=" + state);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
deleted file mode 100644
index f7c6025..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
+++ /dev/null
@@ -1,740 +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.internal.telephony.gsm;
-import android.content.Context;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.Registrant;
-import android.os.SystemClock;
-import android.util.Log;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.ServiceState;
-
-import com.android.internal.telephony.*;
-
-/**
- * {@hide}
- */
-public class GsmConnection extends Connection {
-    static final String LOG_TAG = "GSM";
-
-    //***** Instance Variables
-
-    GsmCallTracker owner;
-    GsmCall parent;
-
-    String address;     // MAY BE NULL!!!
-    String dialString;          // outgoing calls only
-    String postDialString;      // outgoing calls only
-    boolean isIncoming;
-    boolean disconnected;
-
-    int index;          // index in GsmCallTracker.connections[], -1 if unassigned
-                        // The GSM index is 1 + this
-
-    /*
-     * These time/timespan values are based on System.currentTimeMillis(),
-     * i.e., "wall clock" time.
-     */
-    long createTime;
-    long connectTime;
-    long disconnectTime;
-
-    /*
-     * These time/timespan values are based on SystemClock.elapsedRealTime(),
-     * i.e., time since boot.  They are appropriate for comparison and
-     * calculating deltas.
-     */
-    long connectTimeReal;
-    long duration;
-    long holdingStartTime;  // The time when the Connection last transitioned
-                            // into HOLDING
-
-    int nextPostDialChar;       // index into postDialString
-
-    DisconnectCause cause = DisconnectCause.NOT_DISCONNECTED;
-    PostDialState postDialState = PostDialState.NOT_STARTED;
-    int numberPresentation = Connection.PRESENTATION_ALLOWED;
-    UUSInfo uusInfo;
-
-    Handler h;
-
-    private PowerManager.WakeLock mPartialWakeLock;
-
-    //***** Event Constants
-    static final int EVENT_DTMF_DONE = 1;
-    static final int EVENT_PAUSE_DONE = 2;
-    static final int EVENT_NEXT_POST_DIAL = 3;
-    static final int EVENT_WAKE_LOCK_TIMEOUT = 4;
-
-    //***** Constants
-    static final int PAUSE_DELAY_FIRST_MILLIS = 100;
-    static final int PAUSE_DELAY_MILLIS = 3 * 1000;
-    static final int WAKE_LOCK_TIMEOUT_MILLIS = 60*1000;
-
-    //***** Inner Classes
-
-    class MyHandler extends Handler {
-        MyHandler(Looper l) {super(l);}
-
-        public void
-        handleMessage(Message msg) {
-
-            switch (msg.what) {
-                case EVENT_NEXT_POST_DIAL:
-                case EVENT_DTMF_DONE:
-                case EVENT_PAUSE_DONE:
-                    processNextPostDialChar();
-                    break;
-                case EVENT_WAKE_LOCK_TIMEOUT:
-                    releaseWakeLock();
-                    break;
-            }
-        }
-    }
-
-    //***** Constructors
-
-    /** This is probably an MT call that we first saw in a CLCC response */
-    /*package*/
-    GsmConnection (Context context, DriverCall dc, GsmCallTracker ct, int index) {
-        createWakeLock(context);
-        acquireWakeLock();
-
-        owner = ct;
-        h = new MyHandler(owner.getLooper());
-
-        address = dc.number;
-
-        isIncoming = dc.isMT;
-        createTime = System.currentTimeMillis();
-        numberPresentation = dc.numberPresentation;
-        uusInfo = dc.uusInfo;
-
-        this.index = index;
-
-        parent = parentFromDCState (dc.state);
-        parent.attach(this, dc);
-    }
-
-    /** This is an MO call, created when dialing */
-    /*package*/
-    GsmConnection (Context context, String dialString, GsmCallTracker ct, GsmCall parent) {
-        createWakeLock(context);
-        acquireWakeLock();
-
-        owner = ct;
-        h = new MyHandler(owner.getLooper());
-
-        this.dialString = dialString;
-
-        this.address = PhoneNumberUtils.extractNetworkPortionAlt(dialString);
-        this.postDialString = PhoneNumberUtils.extractPostDialPortion(dialString);
-
-        index = -1;
-
-        isIncoming = false;
-        createTime = System.currentTimeMillis();
-
-        this.parent = parent;
-        parent.attachFake(this, GsmCall.State.DIALING);
-    }
-
-    public void dispose() {
-    }
-
-    static boolean
-    equalsHandlesNulls (Object a, Object b) {
-        return (a == null) ? (b == null) : a.equals (b);
-    }
-
-    /*package*/ boolean
-    compareTo(DriverCall c) {
-        // On mobile originated (MO) calls, the phone number may have changed
-        // due to a SIM Toolkit call control modification.
-        //
-        // We assume we know when MO calls are created (since we created them)
-        // and therefore don't need to compare the phone number anyway.
-        if (! (isIncoming || c.isMT)) return true;
-
-        // ... but we can compare phone numbers on MT calls, and we have
-        // no control over when they begin, so we might as well
-
-        String cAddress = PhoneNumberUtils.stringFromStringAndTOA(c.number, c.TOA);
-        return isIncoming == c.isMT && equalsHandlesNulls(address, cAddress);
-    }
-
-    public String getAddress() {
-        return address;
-    }
-
-    public GsmCall getCall() {
-        return parent;
-    }
-
-    public long getCreateTime() {
-        return createTime;
-    }
-
-    public long getConnectTime() {
-        return connectTime;
-    }
-
-    public long getDisconnectTime() {
-        return disconnectTime;
-    }
-
-    public long getDurationMillis() {
-        if (connectTimeReal == 0) {
-            return 0;
-        } else if (duration == 0) {
-            return SystemClock.elapsedRealtime() - connectTimeReal;
-        } else {
-            return duration;
-        }
-    }
-
-    public long getHoldDurationMillis() {
-        if (getState() != GsmCall.State.HOLDING) {
-            // If not holding, return 0
-            return 0;
-        } else {
-            return SystemClock.elapsedRealtime() - holdingStartTime;
-        }
-    }
-
-    public DisconnectCause getDisconnectCause() {
-        return cause;
-    }
-
-    public boolean isIncoming() {
-        return isIncoming;
-    }
-
-    public GsmCall.State getState() {
-        if (disconnected) {
-            return GsmCall.State.DISCONNECTED;
-        } else {
-            return super.getState();
-        }
-    }
-
-    public void hangup() throws CallStateException {
-        if (!disconnected) {
-            owner.hangup(this);
-        } else {
-            throw new CallStateException ("disconnected");
-        }
-    }
-
-    public void separate() throws CallStateException {
-        if (!disconnected) {
-            owner.separate(this);
-        } else {
-            throw new CallStateException ("disconnected");
-        }
-    }
-
-    public PostDialState getPostDialState() {
-        return postDialState;
-    }
-
-    public void proceedAfterWaitChar() {
-        if (postDialState != PostDialState.WAIT) {
-            Log.w(LOG_TAG, "GsmConnection.proceedAfterWaitChar(): Expected "
-                + "getPostDialState() to be WAIT but was " + postDialState);
-            return;
-        }
-
-        setPostDialState(PostDialState.STARTED);
-
-        processNextPostDialChar();
-    }
-
-    public void proceedAfterWildChar(String str) {
-        if (postDialState != PostDialState.WILD) {
-            Log.w(LOG_TAG, "GsmConnection.proceedAfterWaitChar(): Expected "
-                + "getPostDialState() to be WILD but was " + postDialState);
-            return;
-        }
-
-        setPostDialState(PostDialState.STARTED);
-
-        if (false) {
-            boolean playedTone = false;
-            int len = (str != null ? str.length() : 0);
-
-            for (int i=0; i<len; i++) {
-                char c = str.charAt(i);
-                Message msg = null;
-
-                if (i == len-1) {
-                    msg = h.obtainMessage(EVENT_DTMF_DONE);
-                }
-
-                if (PhoneNumberUtils.is12Key(c)) {
-                    owner.cm.sendDtmf(c, msg);
-                    playedTone = true;
-                }
-            }
-
-            if (!playedTone) {
-                processNextPostDialChar();
-            }
-        } else {
-            // make a new postDialString, with the wild char replacement string
-            // at the beginning, followed by the remaining postDialString.
-
-            StringBuilder buf = new StringBuilder(str);
-            buf.append(postDialString.substring(nextPostDialChar));
-            postDialString = buf.toString();
-            nextPostDialChar = 0;
-            if (Phone.DEBUG_PHONE) {
-                log("proceedAfterWildChar: new postDialString is " +
-                        postDialString);
-            }
-
-            processNextPostDialChar();
-        }
-    }
-
-    public void cancelPostDial() {
-        setPostDialState(PostDialState.CANCELLED);
-    }
-
-    /**
-     * Called when this Connection is being hung up locally (eg, user pressed "end")
-     * Note that at this point, the hangup request has been dispatched to the radio
-     * but no response has yet been received so update() has not yet been called
-     */
-    void
-    onHangupLocal() {
-        cause = DisconnectCause.LOCAL;
-    }
-
-    DisconnectCause
-    disconnectCauseFromCode(int causeCode) {
-        /**
-         * See 22.001 Annex F.4 for mapping of cause codes
-         * to local tones
-         */
-
-        switch (causeCode) {
-            case CallFailCause.USER_BUSY:
-                return DisconnectCause.BUSY;
-
-            case CallFailCause.NO_CIRCUIT_AVAIL:
-            case CallFailCause.TEMPORARY_FAILURE:
-            case CallFailCause.SWITCHING_CONGESTION:
-            case CallFailCause.CHANNEL_NOT_AVAIL:
-            case CallFailCause.QOS_NOT_AVAIL:
-            case CallFailCause.BEARER_NOT_AVAIL:
-                return DisconnectCause.CONGESTION;
-
-            case CallFailCause.ACM_LIMIT_EXCEEDED:
-                return DisconnectCause.LIMIT_EXCEEDED;
-
-            case CallFailCause.CALL_BARRED:
-                return DisconnectCause.CALL_BARRED;
-
-            case CallFailCause.FDN_BLOCKED:
-                return DisconnectCause.FDN_BLOCKED;
-
-            case CallFailCause.UNOBTAINABLE_NUMBER:
-                return DisconnectCause.UNOBTAINABLE_NUMBER;
-
-            case CallFailCause.ERROR_UNSPECIFIED:
-            case CallFailCause.NORMAL_CLEARING:
-            default:
-                GSMPhone phone = owner.phone;
-                int serviceState = phone.getServiceState().getState();
-                if (serviceState == ServiceState.STATE_POWER_OFF) {
-                    return DisconnectCause.POWER_OFF;
-                } else if (serviceState == ServiceState.STATE_OUT_OF_SERVICE
-                        || serviceState == ServiceState.STATE_EMERGENCY_ONLY ) {
-                    return DisconnectCause.OUT_OF_SERVICE;
-                } else if (phone.getIccCard().getState() != IccCard.State.READY) {
-                    return DisconnectCause.ICC_ERROR;
-                } else if (causeCode == CallFailCause.ERROR_UNSPECIFIED) {
-                    if (phone.mSST.mRestrictedState.isCsRestricted()) {
-                        return DisconnectCause.CS_RESTRICTED;
-                    } else if (phone.mSST.mRestrictedState.isCsEmergencyRestricted()) {
-                        return DisconnectCause.CS_RESTRICTED_EMERGENCY;
-                    } else if (phone.mSST.mRestrictedState.isCsNormalRestricted()) {
-                        return DisconnectCause.CS_RESTRICTED_NORMAL;
-                    } else {
-                        return DisconnectCause.ERROR_UNSPECIFIED;
-                    }
-                } else if (causeCode == CallFailCause.NORMAL_CLEARING) {
-                    return DisconnectCause.NORMAL;
-                } else {
-                    // If nothing else matches, report unknown call drop reason
-                    // to app, not NORMAL call end.
-                    return DisconnectCause.ERROR_UNSPECIFIED;
-                }
-        }
-    }
-
-    /*package*/ void
-    onRemoteDisconnect(int causeCode) {
-        onDisconnect(disconnectCauseFromCode(causeCode));
-    }
-
-    /** Called when the radio indicates the connection has been disconnected */
-    /*package*/ void
-    onDisconnect(DisconnectCause cause) {
-        this.cause = cause;
-
-        if (!disconnected) {
-            index = -1;
-
-            disconnectTime = System.currentTimeMillis();
-            duration = SystemClock.elapsedRealtime() - connectTimeReal;
-            disconnected = true;
-
-            if (false) Log.d(LOG_TAG,
-                    "[GSMConn] onDisconnect: cause=" + cause);
-
-            owner.phone.notifyDisconnect(this);
-
-            if (parent != null) {
-                parent.connectionDisconnected(this);
-            }
-        }
-        releaseWakeLock();
-    }
-
-    // Returns true if state has changed, false if nothing changed
-    /*package*/ boolean
-    update (DriverCall dc) {
-        GsmCall newParent;
-        boolean changed = false;
-        boolean wasConnectingInOrOut = isConnectingInOrOut();
-        boolean wasHolding = (getState() == GsmCall.State.HOLDING);
-
-        newParent = parentFromDCState(dc.state);
-
-        if (!equalsHandlesNulls(address, dc.number)) {
-            if (Phone.DEBUG_PHONE) log("update: phone # changed!");
-            address = dc.number;
-            changed = true;
-        }
-
-        if (newParent != parent) {
-            if (parent != null) {
-                parent.detach(this);
-            }
-            newParent.attach(this, dc);
-            parent = newParent;
-            changed = true;
-        } else {
-            boolean parentStateChange;
-            parentStateChange = parent.update (this, dc);
-            changed = changed || parentStateChange;
-        }
-
-        /** Some state-transition events */
-
-        if (Phone.DEBUG_PHONE) log(
-                "update: parent=" + parent +
-                ", hasNewParent=" + (newParent != parent) +
-                ", wasConnectingInOrOut=" + wasConnectingInOrOut +
-                ", wasHolding=" + wasHolding +
-                ", isConnectingInOrOut=" + isConnectingInOrOut() +
-                ", changed=" + changed);
-
-
-        if (wasConnectingInOrOut && !isConnectingInOrOut()) {
-            onConnectedInOrOut();
-        }
-
-        if (changed && !wasHolding && (getState() == GsmCall.State.HOLDING)) {
-            // We've transitioned into HOLDING
-            onStartedHolding();
-        }
-
-        return changed;
-    }
-
-    /**
-     * Called when this Connection is in the foregroundCall
-     * when a dial is initiated.
-     * We know we're ACTIVE, and we know we're going to end up
-     * HOLDING in the backgroundCall
-     */
-    void
-    fakeHoldBeforeDial() {
-        if (parent != null) {
-            parent.detach(this);
-        }
-
-        parent = owner.backgroundCall;
-        parent.attachFake(this, GsmCall.State.HOLDING);
-
-        onStartedHolding();
-    }
-
-    /*package*/ int
-    getGSMIndex() throws CallStateException {
-        if (index >= 0) {
-            return index + 1;
-        } else {
-            throw new CallStateException ("GSM index not yet assigned");
-        }
-    }
-
-    /**
-     * An incoming or outgoing call has connected
-     */
-    void
-    onConnectedInOrOut() {
-        connectTime = System.currentTimeMillis();
-        connectTimeReal = SystemClock.elapsedRealtime();
-        duration = 0;
-
-        // bug #678474: incoming call interpreted as missed call, even though
-        // it sounds like the user has picked up the call.
-        if (Phone.DEBUG_PHONE) {
-            log("onConnectedInOrOut: connectTime=" + connectTime);
-        }
-
-        if (!isIncoming) {
-            // outgoing calls only
-            processNextPostDialChar();
-        }
-        releaseWakeLock();
-    }
-
-    private void
-    onStartedHolding() {
-        holdingStartTime = SystemClock.elapsedRealtime();
-    }
-    /**
-     * Performs the appropriate action for a post-dial char, but does not
-     * notify application. returns false if the character is invalid and
-     * should be ignored
-     */
-    private boolean
-    processPostDialChar(char c) {
-        if (PhoneNumberUtils.is12Key(c)) {
-            owner.cm.sendDtmf(c, h.obtainMessage(EVENT_DTMF_DONE));
-        } else if (c == PhoneNumberUtils.PAUSE) {
-            // From TS 22.101:
-
-            // "The first occurrence of the "DTMF Control Digits Separator"
-            //  shall be used by the ME to distinguish between the addressing
-            //  digits (i.e. the phone number) and the DTMF digits...."
-
-            if (nextPostDialChar == 1) {
-                // The first occurrence.
-                // We don't need to pause here, but wait for just a bit anyway
-                h.sendMessageDelayed(h.obtainMessage(EVENT_PAUSE_DONE),
-                                            PAUSE_DELAY_FIRST_MILLIS);
-            } else {
-                // It continues...
-                // "Upon subsequent occurrences of the separator, the UE shall
-                //  pause again for 3 seconds (\u00B1 20 %) before sending any
-                //  further DTMF digits."
-                h.sendMessageDelayed(h.obtainMessage(EVENT_PAUSE_DONE),
-                                            PAUSE_DELAY_MILLIS);
-            }
-        } else if (c == PhoneNumberUtils.WAIT) {
-            setPostDialState(PostDialState.WAIT);
-        } else if (c == PhoneNumberUtils.WILD) {
-            setPostDialState(PostDialState.WILD);
-        } else {
-            return false;
-        }
-
-        return true;
-    }
-
-    public String
-    getRemainingPostDialString() {
-        if (postDialState == PostDialState.CANCELLED
-            || postDialState == PostDialState.COMPLETE
-            || postDialString == null
-            || postDialString.length() <= nextPostDialChar
-        ) {
-            return "";
-        }
-
-        return postDialString.substring(nextPostDialChar);
-    }
-
-    @Override
-    protected void finalize()
-    {
-        /**
-         * It is understood that This finializer is not guaranteed
-         * to be called and the release lock call is here just in
-         * case there is some path that doesn't call onDisconnect
-         * and or onConnectedInOrOut.
-         */
-        if (mPartialWakeLock.isHeld()) {
-            Log.e(LOG_TAG, "[GSMConn] UNEXPECTED; mPartialWakeLock is held when finalizing.");
-        }
-        releaseWakeLock();
-    }
-
-    private void
-    processNextPostDialChar() {
-        char c = 0;
-        Registrant postDialHandler;
-
-        if (postDialState == PostDialState.CANCELLED) {
-            //Log.v("GSM", "##### processNextPostDialChar: postDialState == CANCELLED, bail");
-            return;
-        }
-
-        if (postDialString == null ||
-                postDialString.length() <= nextPostDialChar) {
-            setPostDialState(PostDialState.COMPLETE);
-
-            // notifyMessage.arg1 is 0 on complete
-            c = 0;
-        } else {
-            boolean isValid;
-
-            setPostDialState(PostDialState.STARTED);
-
-            c = postDialString.charAt(nextPostDialChar++);
-
-            isValid = processPostDialChar(c);
-
-            if (!isValid) {
-                // Will call processNextPostDialChar
-                h.obtainMessage(EVENT_NEXT_POST_DIAL).sendToTarget();
-                // Don't notify application
-                Log.e("GSM", "processNextPostDialChar: c=" + c + " isn't valid!");
-                return;
-            }
-        }
-
-        postDialHandler = owner.phone.mPostDialHandler;
-
-        Message notifyMessage;
-
-        if (postDialHandler != null
-                && (notifyMessage = postDialHandler.messageForRegistrant()) != null) {
-            // The AsyncResult.result is the Connection object
-            PostDialState state = postDialState;
-            AsyncResult ar = AsyncResult.forMessage(notifyMessage);
-            ar.result = this;
-            ar.userObj = state;
-
-            // arg1 is the character that was/is being processed
-            notifyMessage.arg1 = c;
-
-            //Log.v("GSM", "##### processNextPostDialChar: send msg to postDialHandler, arg1=" + c);
-            notifyMessage.sendToTarget();
-        }
-    }
-
-
-    /** "connecting" means "has never been ACTIVE" for both incoming
-     *  and outgoing calls
-     */
-    private boolean
-    isConnectingInOrOut() {
-        return parent == null || parent == owner.ringingCall
-            || parent.state == GsmCall.State.DIALING
-            || parent.state == GsmCall.State.ALERTING;
-    }
-
-    private GsmCall
-    parentFromDCState (DriverCall.State state) {
-        switch (state) {
-            case ACTIVE:
-            case DIALING:
-            case ALERTING:
-                return owner.foregroundCall;
-            //break;
-
-            case HOLDING:
-                return owner.backgroundCall;
-            //break;
-
-            case INCOMING:
-            case WAITING:
-                return owner.ringingCall;
-            //break;
-
-            default:
-                throw new RuntimeException("illegal call state: " + state);
-        }
-    }
-
-    /**
-     * Set post dial state and acquire wake lock while switching to "started"
-     * state, the wake lock will be released if state switches out of "started"
-     * state or after WAKE_LOCK_TIMEOUT_MILLIS.
-     * @param s new PostDialState
-     */
-    private void setPostDialState(PostDialState s) {
-        if (postDialState != PostDialState.STARTED
-                && s == PostDialState.STARTED) {
-            acquireWakeLock();
-            Message msg = h.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT);
-            h.sendMessageDelayed(msg, WAKE_LOCK_TIMEOUT_MILLIS);
-        } else if (postDialState == PostDialState.STARTED
-                && s != PostDialState.STARTED) {
-            h.removeMessages(EVENT_WAKE_LOCK_TIMEOUT);
-            releaseWakeLock();
-        }
-        postDialState = s;
-    }
-
-    private void
-    createWakeLock(Context context) {
-        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-        mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
-    }
-
-    private void
-    acquireWakeLock() {
-        log("acquireWakeLock");
-        mPartialWakeLock.acquire();
-    }
-
-    private void
-    releaseWakeLock() {
-        synchronized(mPartialWakeLock) {
-            if (mPartialWakeLock.isHeld()) {
-                log("releaseWakeLock");
-                mPartialWakeLock.release();
-            }
-        }
-    }
-
-    private void log(String msg) {
-        Log.d(LOG_TAG, "[GSMConn] " + msg);
-    }
-
-    @Override
-    public int getNumberPresentation() {
-        return numberPresentation;
-    }
-
-    @Override
-    public UUSInfo getUUSInfo() {
-        return uusInfo;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
deleted file mode 100644
index 9801721..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
+++ /dev/null
@@ -1,167 +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.internal.telephony.gsm;
-
-import android.os.Message;
-import android.util.Log;
-import android.util.Patterns;
-import android.text.TextUtils;
-
-import com.android.internal.telephony.DataConnection;
-import com.android.internal.telephony.DataConnectionTracker;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.RetryManager;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * {@hide}
- */
-public class GsmDataConnection extends DataConnection {
-
-    private static final String LOG_TAG = "GSM";
-
-    //***** Instance Variables
-    protected int mProfileId = RILConstants.DATA_PROFILE_DEFAULT;
-    //***** Constructor
-    private GsmDataConnection(PhoneBase phone, String name, int id, RetryManager rm,
-            DataConnectionTracker dct) {
-        super(phone, name, id, rm, dct);
-    }
-
-    /**
-     * Create the connection object
-     *
-     * @param phone the Phone
-     * @param id the connection id
-     * @param rm the RetryManager
-     * @return GsmDataConnection that was created.
-     */
-    static GsmDataConnection makeDataConnection(PhoneBase phone, int id, RetryManager rm,
-            DataConnectionTracker dct) {
-        synchronized (mCountLock) {
-            mCount += 1;
-        }
-        GsmDataConnection gsmDc = new GsmDataConnection(phone, "GsmDC-" + mCount, id, rm, dct);
-        gsmDc.start();
-        if (DBG) gsmDc.log("Made " + gsmDc.getName());
-        return gsmDc;
-    }
-
-    /**
-     * Begin setting up a data connection, calls setupDataCall
-     * and the ConnectionParams will be returned with the
-     * EVENT_SETUP_DATA_CONNECTION_DONE AsyncResul.userObj.
-     *
-     * @param cp is the connection parameters
-     */
-    @Override
-    protected
-    void onConnect(ConnectionParams cp) {
-        mApn = cp.apn;
-
-        if (DBG) log("Connecting to carrier: '" + mApn.carrier
-                + "' APN: '" + mApn.apn
-                + "' proxy: '" + mApn.proxy + "' port: '" + mApn.port);
-
-        createTime = -1;
-        lastFailTime = -1;
-        lastFailCause = FailCause.NONE;
-
-        // msg.obj will be returned in AsyncResult.userObj;
-        Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp);
-        msg.obj = cp;
-
-        int authType = mApn.authType;
-        if (authType == -1) {
-            authType = TextUtils.isEmpty(mApn.user) ? RILConstants.SETUP_DATA_AUTH_NONE
-                    : RILConstants.SETUP_DATA_AUTH_PAP_CHAP;
-        }
-
-        String protocol;
-        if (phone.getServiceState().getRoaming()) {
-            protocol = mApn.roamingProtocol;
-        } else {
-            protocol = mApn.protocol;
-        }
-
-        phone.mCM.setupDataCall(
-                Integer.toString(getRilRadioTechnology(RILConstants.SETUP_DATA_TECH_GSM)),
-                Integer.toString(mProfileId),
-                mApn.apn, mApn.user, mApn.password,
-                Integer.toString(authType),
-                protocol, msg);
-    }
-
-    public void setProfileId(int profileId) {
-        mProfileId = profileId;
-    }
-
-    public int getProfileId() {
-        return mProfileId;
-    }
-
-    @Override
-    public String toString() {
-        return "{" + getName() + ": State=" + getCurrentState().getName() +
-                " apnSetting=" + mApn + " apnList= " + mApnList + " RefCount=" + mRefCount +
-                " cid=" + cid + " create=" + createTime + " lastFail=" + lastFailTime +
-                " lastFailCause=" + lastFailCause + "}";
-    }
-
-    @Override
-    protected boolean isDnsOk(String[] domainNameServers) {
-        if (NULL_IP.equals(domainNameServers[0]) && NULL_IP.equals(domainNameServers[1])
-                && !phone.isDnsCheckDisabled()) {
-            // Work around a race condition where QMI does not fill in DNS:
-            // Deactivate PDP and let DataConnectionTracker retry.
-            // Do not apply the race condition workaround for MMS APN
-            // if Proxy is an IP-address.
-            // Otherwise, the default APN will not be restored anymore.
-            if (!mApn.types[0].equals(Phone.APN_TYPE_MMS)
-                || !isIpAddress(mApn.mmsProxy)) {
-                log(String.format(
-                        "isDnsOk: return false apn.types[0]=%s APN_TYPE_MMS=%s isIpAddress(%s)=%s",
-                        mApn.types[0], Phone.APN_TYPE_MMS, mApn.mmsProxy,
-                        isIpAddress(mApn.mmsProxy)));
-                return false;
-            }
-        }
-        return true;
-    }
-
-    @Override
-    protected void log(String s) {
-        Log.d(LOG_TAG, "[" + getName() + "] " + s);
-    }
-
-    private boolean isIpAddress(String address) {
-        if (address == null) return false;
-
-        return Patterns.IP_ADDRESS.matcher(address).matches();
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("GsmDataConnection extends:");
-        super.dump(fd, pw, args);
-        pw.println(" mProfileId=" + mProfileId);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
deleted file mode 100644
index 23364b4..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ /dev/null
@@ -1,2646 +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.internal.telephony.gsm;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.net.ConnectivityManager;
-import android.net.LinkAddress;
-import android.net.LinkCapabilities;
-import android.net.LinkProperties;
-import android.net.LinkProperties.CompareResult;
-import android.net.NetworkConfig;
-import android.net.NetworkUtils;
-import android.net.ProxyProperties;
-import android.net.TrafficStats;
-import android.net.Uri;
-import android.os.AsyncResult;
-import android.os.Message;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.provider.Settings;
-import android.provider.Telephony;
-import android.telephony.CellLocation;
-import android.telephony.ServiceState;
-import android.telephony.TelephonyManager;
-import android.telephony.cdma.CdmaCellLocation;
-import android.telephony.gsm.GsmCellLocation;
-import android.text.TextUtils;
-import android.util.EventLog;
-import android.util.Log;
-
-import com.android.internal.telephony.ApnContext;
-import com.android.internal.telephony.ApnSetting;
-import com.android.internal.telephony.DataCallState;
-import com.android.internal.telephony.DataConnection;
-import com.android.internal.telephony.DataConnection.FailCause;
-import com.android.internal.telephony.DataConnection.UpdateLinkPropertyResult;
-import com.android.internal.telephony.DataConnectionAc;
-import com.android.internal.telephony.DataConnectionTracker;
-import com.android.internal.telephony.EventLogTags;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.RetryManager;
-import com.android.internal.util.AsyncChannel;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * {@hide}
- */
-public final class GsmDataConnectionTracker extends DataConnectionTracker {
-    protected final String LOG_TAG = "GSM";
-    private static final boolean RADIO_TESTS = false;
-
-    /**
-     * Handles changes to the APN db.
-     */
-    private class ApnChangeObserver extends ContentObserver {
-        public ApnChangeObserver () {
-            super(mDataConnectionTracker);
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            sendMessage(obtainMessage(EVENT_APN_CHANGED));
-        }
-    }
-
-    //***** Instance Variables
-
-    private boolean mReregisterOnReconnectFailure = false;
-    private ContentResolver mResolver;
-
-    // Recovery action taken in case of data stall
-    private static class RecoveryAction {
-        public static final int GET_DATA_CALL_LIST      = 0;
-        public static final int CLEANUP                 = 1;
-        public static final int REREGISTER              = 2;
-        public static final int RADIO_RESTART           = 3;
-        public static final int RADIO_RESTART_WITH_PROP = 4;
-
-        private static boolean isAggressiveRecovery(int value) {
-            return ((value == RecoveryAction.CLEANUP) ||
-                    (value == RecoveryAction.REREGISTER) ||
-                    (value == RecoveryAction.RADIO_RESTART) ||
-                    (value == RecoveryAction.RADIO_RESTART_WITH_PROP));
-        }
-    }
-
-    public int getRecoveryAction() {
-        int action = Settings.System.getInt(mPhone.getContext().getContentResolver(),
-                "radio.data.stall.recovery.action", RecoveryAction.GET_DATA_CALL_LIST);
-        if (VDBG) log("getRecoveryAction: " + action);
-        return action;
-    }
-    public void putRecoveryAction(int action) {
-        Settings.System.putInt(mPhone.getContext().getContentResolver(),
-                "radio.data.stall.recovery.action", action);
-        if (VDBG) log("putRecoveryAction: " + action);
-    }
-
-    //***** Constants
-
-    private static final int POLL_PDP_MILLIS = 5 * 1000;
-
-    private static final String INTENT_RECONNECT_ALARM =
-        "com.android.internal.telephony.gprs-reconnect";
-    private static final String INTENT_RECONNECT_ALARM_EXTRA_TYPE = "reconnect_alarm_extra_type";
-    private static final String INTENT_RECONNECT_ALARM_EXTRA_RETRY_COUNT =
-        "reconnect_alaram_extra_retry_count";
-
-    private static final String INTENT_DATA_STALL_ALARM =
-        "com.android.internal.telephony.gprs-data-stall";
-
-    static final Uri PREFERAPN_NO_UPDATE_URI =
-                        Uri.parse("content://telephony/carriers/preferapn_no_update");
-    static final String APN_ID = "apn_id";
-    private boolean canSetPreferApn = false;
-
-    private static final boolean DATA_STALL_SUSPECTED = true;
-    private static final boolean DATA_STALL_NOT_SUSPECTED = false;
-
-    @Override
-    protected void onActionIntentReconnectAlarm(Intent intent) {
-        String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON);
-        int connectionId = intent.getIntExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, -1);
-        int retryCount = intent.getIntExtra(INTENT_RECONNECT_ALARM_EXTRA_RETRY_COUNT, 0);
-
-        DataConnectionAc dcac= mDataConnectionAsyncChannels.get(connectionId);
-
-        if (DBG) {
-            log("onActionIntentReconnectAlarm: mState=" + mState + " reason=" + reason +
-                    " connectionId=" + connectionId + " retryCount=" + retryCount);
-        }
-
-        if (dcac != null) {
-            for (ApnContext apnContext : dcac.getApnListSync()) {
-                apnContext.setDataConnectionAc(null);
-                apnContext.setDataConnection(null);
-                apnContext.setReason(reason);
-                apnContext.setRetryCount(retryCount);
-                if (apnContext.getState() == State.FAILED) {
-                    apnContext.setState(State.IDLE);
-                }
-                sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA, apnContext));
-            }
-            // Alram had expired. Clear pending intent recorded on the DataConnection.
-            dcac.setReconnectIntentSync(null);
-        }
-    }
-
-    /** Watches for changes to the APN db. */
-    private ApnChangeObserver mApnObserver;
-
-    //***** Constructor
-
-    public GsmDataConnectionTracker(PhoneBase p) {
-        super(p);
-        if (DBG) log("GsmDCT.constructor");
-        p.mCM.registerForAvailable (this, EVENT_RADIO_AVAILABLE, null);
-        p.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
-        p.mIccRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null);
-        p.mCM.registerForDataNetworkStateChanged (this, EVENT_DATA_STATE_CHANGED, null);
-        p.getCallTracker().registerForVoiceCallEnded (this, EVENT_VOICE_CALL_ENDED, null);
-        p.getCallTracker().registerForVoiceCallStarted (this, EVENT_VOICE_CALL_STARTED, null);
-        p.getServiceStateTracker().registerForDataConnectionAttached(this,
-                EVENT_DATA_CONNECTION_ATTACHED, null);
-        p.getServiceStateTracker().registerForDataConnectionDetached(this,
-                EVENT_DATA_CONNECTION_DETACHED, null);
-        p.getServiceStateTracker().registerForRoamingOn(this, EVENT_ROAMING_ON, null);
-        p.getServiceStateTracker().registerForRoamingOff(this, EVENT_ROAMING_OFF, null);
-        p.getServiceStateTracker().registerForPsRestrictedEnabled(this,
-                EVENT_PS_RESTRICT_ENABLED, null);
-        p.getServiceStateTracker().registerForPsRestrictedDisabled(this,
-                EVENT_PS_RESTRICT_DISABLED, null);
-
-        // install reconnect intent filter for this data connection.
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(INTENT_DATA_STALL_ALARM);
-        p.getContext().registerReceiver(mIntentReceiver, filter, null, p);
-
-        mDataConnectionTracker = this;
-        mResolver = mPhone.getContext().getContentResolver();
-
-        mApnObserver = new ApnChangeObserver();
-        p.getContext().getContentResolver().registerContentObserver(
-                Telephony.Carriers.CONTENT_URI, true, mApnObserver);
-
-        initApnContextsAndDataConnection();
-        broadcastMessenger();
-    }
-
-    @Override
-    public void dispose() {
-        if (DBG) log("GsmDCT.dispose");
-        cleanUpAllConnections(false, null);
-
-        super.dispose();
-
-        //Unregister for all events
-        mPhone.mCM.unregisterForAvailable(this);
-        mPhone.mCM.unregisterForOffOrNotAvailable(this);
-        mPhone.mIccRecords.unregisterForRecordsLoaded(this);
-        mPhone.mCM.unregisterForDataNetworkStateChanged(this);
-        mPhone.getCallTracker().unregisterForVoiceCallEnded(this);
-        mPhone.getCallTracker().unregisterForVoiceCallStarted(this);
-        mPhone.getServiceStateTracker().unregisterForDataConnectionAttached(this);
-        mPhone.getServiceStateTracker().unregisterForDataConnectionDetached(this);
-        mPhone.getServiceStateTracker().unregisterForRoamingOn(this);
-        mPhone.getServiceStateTracker().unregisterForRoamingOff(this);
-        mPhone.getServiceStateTracker().unregisterForPsRestrictedEnabled(this);
-        mPhone.getServiceStateTracker().unregisterForPsRestrictedDisabled(this);
-
-        mPhone.getContext().getContentResolver().unregisterContentObserver(this.mApnObserver);
-        mApnContexts.clear();
-
-        destroyDataConnections();
-    }
-
-    @Override
-    public boolean isApnTypeActive(String type) {
-        ApnContext apnContext = mApnContexts.get(type);
-        if (apnContext == null) return false;
-
-        return (apnContext.getDataConnection() != null);
-    }
-
-    @Override
-    protected boolean isDataPossible(String apnType) {
-        ApnContext apnContext = mApnContexts.get(apnType);
-        if (apnContext == null) {
-            return false;
-        }
-        boolean apnContextIsEnabled = apnContext.isEnabled();
-        State apnContextState = apnContext.getState();
-        boolean apnTypePossible = !(apnContextIsEnabled &&
-                (apnContextState == State.FAILED));
-        boolean dataAllowed = isDataAllowed();
-        boolean possible = dataAllowed && apnTypePossible;
-
-        if (DBG) {
-            log(String.format("isDataPossible(%s): possible=%b isDataAllowed=%b " +
-                    "apnTypePossible=%b apnContextisEnabled=%b apnContextState()=%s",
-                    apnType, possible, dataAllowed, apnTypePossible,
-                    apnContextIsEnabled, apnContextState));
-        }
-        return possible;
-    }
-
-    @Override
-    protected void finalize() {
-        if(DBG) log("finalize");
-    }
-
-    @Override
-    protected String getActionIntentReconnectAlarm() {
-        return INTENT_RECONNECT_ALARM;
-    }
-
-    @Override
-    protected String getActionIntentDataStallAlarm() {
-        return INTENT_DATA_STALL_ALARM;
-    }
-
-    private ApnContext addApnContext(String type) {
-        ApnContext apnContext = new ApnContext(type, LOG_TAG);
-        apnContext.setDependencyMet(false);
-        mApnContexts.put(type, apnContext);
-        return apnContext;
-    }
-
-    protected void initApnContextsAndDataConnection() {
-        boolean defaultEnabled = SystemProperties.getBoolean(DEFALUT_DATA_ON_BOOT_PROP, true);
-        // Load device network attributes from resources
-        String[] networkConfigStrings = mPhone.getContext().getResources().getStringArray(
-                com.android.internal.R.array.networkAttributes);
-        for (String networkConfigString : networkConfigStrings) {
-            NetworkConfig networkConfig = new NetworkConfig(networkConfigString);
-            ApnContext apnContext = null;
-
-            switch (networkConfig.type) {
-            case ConnectivityManager.TYPE_MOBILE:
-                apnContext = addApnContext(Phone.APN_TYPE_DEFAULT);
-                apnContext.setEnabled(defaultEnabled);
-                break;
-            case ConnectivityManager.TYPE_MOBILE_MMS:
-                apnContext = addApnContext(Phone.APN_TYPE_MMS);
-                break;
-            case ConnectivityManager.TYPE_MOBILE_SUPL:
-                apnContext = addApnContext(Phone.APN_TYPE_SUPL);
-                break;
-            case ConnectivityManager.TYPE_MOBILE_DUN:
-                apnContext = addApnContext(Phone.APN_TYPE_DUN);
-                break;
-            case ConnectivityManager.TYPE_MOBILE_HIPRI:
-                apnContext = addApnContext(Phone.APN_TYPE_HIPRI);
-                ApnContext defaultContext = mApnContexts.get(Phone.APN_TYPE_DEFAULT);
-                if (defaultContext != null) {
-                    applyNewState(apnContext, apnContext.isEnabled(),
-                            defaultContext.getDependencyMet());
-                } else {
-                    // the default will set the hipri dep-met when it is created
-                }
-                continue;
-            case ConnectivityManager.TYPE_MOBILE_FOTA:
-                apnContext = addApnContext(Phone.APN_TYPE_FOTA);
-                break;
-            case ConnectivityManager.TYPE_MOBILE_IMS:
-                apnContext = addApnContext(Phone.APN_TYPE_IMS);
-                break;
-            case ConnectivityManager.TYPE_MOBILE_CBS:
-                apnContext = addApnContext(Phone.APN_TYPE_CBS);
-                break;
-            default:
-                // skip unknown types
-                continue;
-            }
-            if (apnContext != null) {
-                // set the prop, but also apply the newly set enabled and dependency values
-                onSetDependencyMet(apnContext.getApnType(), networkConfig.dependencyMet);
-            }
-        }
-    }
-
-    @Override
-    protected LinkProperties getLinkProperties(String apnType) {
-        ApnContext apnContext = mApnContexts.get(apnType);
-        if (apnContext != null) {
-            DataConnectionAc dcac = apnContext.getDataConnectionAc();
-            if (dcac != null) {
-                if (DBG) log("return link properites for " + apnType);
-                return dcac.getLinkPropertiesSync();
-            }
-        }
-        if (DBG) log("return new LinkProperties");
-        return new LinkProperties();
-    }
-
-    @Override
-    protected LinkCapabilities getLinkCapabilities(String apnType) {
-        ApnContext apnContext = mApnContexts.get(apnType);
-        if (apnContext!=null) {
-            DataConnectionAc dataConnectionAc = apnContext.getDataConnectionAc();
-            if (dataConnectionAc != null) {
-                if (DBG) log("get active pdp is not null, return link Capabilities for " + apnType);
-                return dataConnectionAc.getLinkCapabilitiesSync();
-            }
-        }
-        if (DBG) log("return new LinkCapabilities");
-        return new LinkCapabilities();
-    }
-
-    @Override
-    // Return all active apn types
-    public String[] getActiveApnTypes() {
-        if (DBG) log("get all active apn types");
-        ArrayList<String> result = new ArrayList<String>();
-
-        for (ApnContext apnContext : mApnContexts.values()) {
-            if (apnContext.isReady()) {
-                result.add(apnContext.getApnType());
-            }
-        }
-
-        return (String[])result.toArray(new String[0]);
-    }
-
-    @Override
-    // Return active apn of specific apn type
-    public String getActiveApnString(String apnType) {
-        if (DBG) log( "get active apn string for type:" + apnType);
-        ApnContext apnContext = mApnContexts.get(apnType);
-        if (apnContext != null) {
-            ApnSetting apnSetting = apnContext.getApnSetting();
-            if (apnSetting != null) {
-                return apnSetting.apn;
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public boolean isApnTypeEnabled(String apnType) {
-        ApnContext apnContext = mApnContexts.get(apnType);
-        if (apnContext == null) {
-            return false;
-        }
-        return apnContext.isEnabled();
-    }
-
-    @Override
-    protected void setState(State s) {
-        if (DBG) log("setState should not be used in GSM" + s);
-    }
-
-    // Return state of specific apn type
-    @Override
-    public State getState(String apnType) {
-        ApnContext apnContext = mApnContexts.get(apnType);
-        if (apnContext != null) {
-            return apnContext.getState();
-        }
-        return State.FAILED;
-    }
-
-    // Return state of overall
-    public State getOverallState() {
-        boolean isConnecting = false;
-        boolean isFailed = true; // All enabled Apns should be FAILED.
-        boolean isAnyEnabled = false;
-
-        for (ApnContext apnContext : mApnContexts.values()) {
-            if (apnContext.isEnabled()) {
-                isAnyEnabled = true;
-                switch (apnContext.getState()) {
-                case CONNECTED:
-                case DISCONNECTING:
-                    if (DBG) log("overall state is CONNECTED");
-                    return State.CONNECTED;
-                case CONNECTING:
-                case INITING:
-                    isConnecting = true;
-                    isFailed = false;
-                    break;
-                case IDLE:
-                case SCANNING:
-                    isFailed = false;
-                    break;
-                }
-            }
-        }
-
-        if (!isAnyEnabled) { // Nothing enabled. return IDLE.
-            if (DBG) log( "overall state is IDLE");
-            return State.IDLE;
-        }
-
-        if (isConnecting) {
-            if (DBG) log( "overall state is CONNECTING");
-            return State.CONNECTING;
-        } else if (!isFailed) {
-            if (DBG) log( "overall state is IDLE");
-            return State.IDLE;
-        } else {
-            if (DBG) log( "overall state is FAILED");
-            return State.FAILED;
-        }
-    }
-
-    /**
-     * Ensure that we are connected to an APN of the specified type.
-     *
-     * @param type the APN type
-     * @return Success is indicated by {@code Phone.APN_ALREADY_ACTIVE} or
-     *         {@code Phone.APN_REQUEST_STARTED}. In the latter case, a
-     *         broadcast will be sent by the ConnectivityManager when a
-     *         connection to the APN has been established.
-     */
-    @Override
-    public synchronized int enableApnType(String apnType) {
-        ApnContext apnContext = mApnContexts.get(apnType);
-        if (apnContext == null || !isApnTypeAvailable(apnType)) {
-            if (DBG) log("enableApnType: " + apnType + " is type not available");
-            return Phone.APN_TYPE_NOT_AVAILABLE;
-        }
-
-        // If already active, return
-        if (DBG) log("enableApnType: " + apnType + " mState(" + apnContext.getState() + ")");
-
-        if (apnContext.getState() == State.CONNECTED) {
-            if (DBG) log("enableApnType: return APN_ALREADY_ACTIVE");
-            return Phone.APN_ALREADY_ACTIVE;
-        }
-        setEnabled(apnTypeToId(apnType), true);
-        if (DBG) {
-            log("enableApnType: new apn request for type " + apnType +
-                    " return APN_REQUEST_STARTED");
-        }
-        return Phone.APN_REQUEST_STARTED;
-    }
-
-    // A new APN has gone active and needs to send events to catch up with the
-    // current condition
-    private void notifyApnIdUpToCurrent(String reason, ApnContext apnContext, String type) {
-        switch (apnContext.getState()) {
-            case IDLE:
-            case INITING:
-                break;
-            case CONNECTING:
-            case SCANNING:
-                mPhone.notifyDataConnection(reason, type, Phone.DataState.CONNECTING);
-                break;
-            case CONNECTED:
-            case DISCONNECTING:
-                mPhone.notifyDataConnection(reason, type, Phone.DataState.CONNECTING);
-                mPhone.notifyDataConnection(reason, type, Phone.DataState.CONNECTED);
-                break;
-        }
-    }
-
-    @Override
-    public synchronized int disableApnType(String type) {
-        if (DBG) log("disableApnType:" + type);
-        ApnContext apnContext = mApnContexts.get(type);
-
-        if (apnContext != null) {
-            setEnabled(apnTypeToId(type), false);
-            if (apnContext.getState() != State.IDLE && apnContext.getState() != State.FAILED) {
-                if (DBG) log("diableApnType: return APN_REQUEST_STARTED");
-                return Phone.APN_REQUEST_STARTED;
-            } else {
-                if (DBG) log("disableApnType: return APN_ALREADY_INACTIVE");
-                return Phone.APN_ALREADY_INACTIVE;
-            }
-
-        } else {
-            if (DBG) {
-                log("disableApnType: no apn context was found, return APN_REQUEST_FAILED");
-            }
-            return Phone.APN_REQUEST_FAILED;
-        }
-    }
-
-    @Override
-    protected boolean isApnTypeAvailable(String type) {
-        if (type.equals(Phone.APN_TYPE_DUN) && fetchDunApn() != null) {
-            return true;
-        }
-
-        if (mAllApns != null) {
-            for (ApnSetting apn : mAllApns) {
-                if (apn.canHandleType(type)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Report on whether data connectivity is enabled for any APN.
-     * @return {@code false} if data connectivity has been explicitly disabled,
-     * {@code true} otherwise.
-     */
-    @Override
-    public boolean getAnyDataEnabled() {
-        synchronized (mDataEnabledLock) {
-            if (!(mInternalDataEnabled && mUserDataEnabled && sPolicyDataEnabled)) return false;
-            for (ApnContext apnContext : mApnContexts.values()) {
-                // Make sure we dont have a context that going down
-                // and is explicitly disabled.
-                if (isDataAllowed(apnContext)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-    }
-
-    private boolean isDataAllowed(ApnContext apnContext) {
-        return apnContext.isReady() && isDataAllowed();
-    }
-
-    //****** Called from ServiceStateTracker
-    /**
-     * Invoked when ServiceStateTracker observes a transition from GPRS
-     * attach to detach.
-     */
-    protected void onDataConnectionDetached() {
-        /*
-         * We presently believe it is unnecessary to tear down the PDP context
-         * when GPRS detaches, but we should stop the network polling.
-         */
-        if (DBG) log ("onDataConnectionDetached: stop polling and notify detached");
-        stopNetStatPoll();
-        stopDataStallAlarm();
-        notifyDataConnection(Phone.REASON_DATA_DETACHED);
-    }
-
-    private void onDataConnectionAttached() {
-        if (DBG) log("onDataConnectionAttached");
-        if (getOverallState() == State.CONNECTED) {
-            if (DBG) log("onDataConnectionAttached: start polling notify attached");
-            startNetStatPoll();
-            startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
-            notifyDataConnection(Phone.REASON_DATA_ATTACHED);
-        } else {
-            // update APN availability so that APN can be enabled.
-            notifyOffApnsOfAvailability(Phone.REASON_DATA_ATTACHED);
-        }
-
-        setupDataOnReadyApns(Phone.REASON_DATA_ATTACHED);
-    }
-
-    @Override
-    protected boolean isDataAllowed() {
-        final boolean internalDataEnabled;
-        synchronized (mDataEnabledLock) {
-            internalDataEnabled = mInternalDataEnabled;
-        }
-
-        int gprsState = mPhone.getServiceStateTracker().getCurrentDataConnectionState();
-        boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
-
-        boolean allowed =
-                    (gprsState == ServiceState.STATE_IN_SERVICE || mAutoAttachOnCreation) &&
-                    mPhone.mIccRecords.getRecordsLoaded() &&
-                    (mPhone.getState() == Phone.State.IDLE ||
-                     mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) &&
-                    internalDataEnabled &&
-                    (!mPhone.getServiceState().getRoaming() || getDataOnRoamingEnabled()) &&
-                    !mIsPsRestricted &&
-                    desiredPowerState;
-        if (!allowed && DBG) {
-            String reason = "";
-            if (!((gprsState == ServiceState.STATE_IN_SERVICE) || mAutoAttachOnCreation)) {
-                reason += " - gprs= " + gprsState;
-            }
-            if (!mPhone.mIccRecords.getRecordsLoaded()) reason += " - SIM not loaded";
-            if (mPhone.getState() != Phone.State.IDLE &&
-                    !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
-                reason += " - PhoneState= " + mPhone.getState();
-                reason += " - Concurrent voice and data not allowed";
-            }
-            if (!internalDataEnabled) reason += " - mInternalDataEnabled= false";
-            if (mPhone.getServiceState().getRoaming() && !getDataOnRoamingEnabled()) {
-                reason += " - Roaming and data roaming not enabled";
-            }
-            if (mIsPsRestricted) reason += " - mIsPsRestricted= true";
-            if (!desiredPowerState) reason += " - desiredPowerState= false";
-            if (DBG) log("isDataAllowed: not allowed due to" + reason);
-        }
-        return allowed;
-    }
-
-    private void setupDataOnReadyApns(String reason) {
-        // Stop reconnect alarms on all data connections pending
-        // retry. Reset ApnContext state to IDLE.
-        for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
-            if (dcac.getReconnectIntentSync() != null) {
-                cancelReconnectAlarm(dcac);
-            }
-            // update retry config for existing calls to match up
-            // ones for the new RAT.
-            if (dcac.dataConnection != null) {
-                Collection<ApnContext> apns = dcac.getApnListSync();
-
-                boolean hasDefault = false;
-                for (ApnContext apnContext : apns) {
-                    if (apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT)) {
-                        hasDefault = true;
-                        break;
-                    }
-                }
-                configureRetry(dcac.dataConnection, hasDefault, 0);
-            }
-        }
-
-        // Be sure retry counts for Apncontexts and DC's are sync'd.
-        // When DCT/ApnContexts are refactored and we cleanup retrying
-        // this won't be needed.
-        resetAllRetryCounts();
-
-        // Only check for default APN state
-        for (ApnContext apnContext : mApnContexts.values()) {
-            if (apnContext.getState() == State.FAILED) {
-                // By this time, alarms for all failed Apns
-                // should be stopped if any.
-                // Make sure to set the state back to IDLE
-                // so that setup data can happen.
-                apnContext.setState(State.IDLE);
-            }
-            if (apnContext.isReady()) {
-                if (apnContext.getState() == State.IDLE) {
-                    apnContext.setReason(reason);
-                    trySetupData(apnContext);
-                }
-            }
-        }
-    }
-
-    private boolean trySetupData(String reason, String type) {
-        if (DBG) {
-            log("trySetupData: " + type + " due to " + (reason == null ? "(unspecified)" : reason)
-                    + " isPsRestricted=" + mIsPsRestricted);
-        }
-
-        if (type == null) {
-            type = Phone.APN_TYPE_DEFAULT;
-        }
-
-        ApnContext apnContext = mApnContexts.get(type);
-
-        if (apnContext == null ){
-            if (DBG) log("trySetupData new apn context for type:" + type);
-            apnContext = new ApnContext(type, LOG_TAG);
-            mApnContexts.put(type, apnContext);
-        }
-        apnContext.setReason(reason);
-
-        return trySetupData(apnContext);
-    }
-
-    private boolean trySetupData(ApnContext apnContext) {
-        if (DBG) {
-            log("trySetupData for type:" + apnContext.getApnType() +
-                    " due to " + apnContext.getReason());
-            log("trySetupData with mIsPsRestricted=" + mIsPsRestricted);
-        }
-
-        if (mPhone.getSimulatedRadioControl() != null) {
-            // Assume data is connected on the simulator
-            // FIXME  this can be improved
-            apnContext.setState(State.CONNECTED);
-            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
-
-            log("trySetupData: (fix?) We're on the simulator; assuming data is connected");
-            return true;
-        }
-
-        boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
-
-        if ((apnContext.getState() == State.IDLE || apnContext.getState() == State.SCANNING) &&
-                isDataAllowed(apnContext) && getAnyDataEnabled() && !isEmergency()) {
-
-            if (apnContext.getState() == State.IDLE) {
-                ArrayList<ApnSetting> waitingApns = buildWaitingApns(apnContext.getApnType());
-                if (waitingApns.isEmpty()) {
-                    if (DBG) log("trySetupData: No APN found");
-                    notifyNoData(GsmDataConnection.FailCause.MISSING_UNKNOWN_APN, apnContext);
-                    notifyOffApnsOfAvailability(apnContext.getReason());
-                    return false;
-                } else {
-                    apnContext.setWaitingApns(waitingApns);
-                    if (DBG) {
-                        log ("trySetupData: Create from mAllApns : " + apnListToString(mAllApns));
-                    }
-                }
-            }
-
-            if (DBG) {
-                log ("Setup watingApns : " + apnListToString(apnContext.getWaitingApns()));
-            }
-            // apnContext.setReason(apnContext.getReason());
-            boolean retValue = setupData(apnContext);
-            notifyOffApnsOfAvailability(apnContext.getReason());
-            return retValue;
-        } else {
-            // TODO: check the condition.
-            if (!apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT)
-                && (apnContext.getState() == State.IDLE
-                    || apnContext.getState() == State.SCANNING))
-                mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
-            notifyOffApnsOfAvailability(apnContext.getReason());
-            return false;
-        }
-    }
-
-    @Override
-    // Disabled apn's still need avail/unavail notificiations - send them out
-    protected void notifyOffApnsOfAvailability(String reason) {
-        for (ApnContext apnContext : mApnContexts.values()) {
-            if (!apnContext.isReady()) {
-                if (DBG) log("notifyOffApnOfAvailability type:" + apnContext.getApnType());
-                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
-                                            apnContext.getApnType(),
-                                            Phone.DataState.DISCONNECTED);
-            } else {
-                if (DBG) {
-                    log("notifyOffApnsOfAvailability skipped apn due to isReady==false: " +
-                            apnContext.toString());
-                }
-            }
-        }
-    }
-
-    /**
-     * If tearDown is true, this only tears down a CONNECTED session. Presently,
-     * there is no mechanism for abandoning an INITING/CONNECTING session,
-     * but would likely involve cancelling pending async requests or
-     * setting a flag or new state to ignore them when they came in
-     * @param tearDown true if the underlying GsmDataConnection should be
-     * disconnected.
-     * @param reason reason for the clean up.
-     */
-    protected void cleanUpAllConnections(boolean tearDown, String reason) {
-        if (DBG) log("cleanUpAllConnections: tearDown=" + tearDown + " reason=" + reason);
-
-        for (ApnContext apnContext : mApnContexts.values()) {
-            apnContext.setReason(reason);
-            cleanUpConnection(tearDown, apnContext);
-        }
-
-        stopNetStatPoll();
-        stopDataStallAlarm();
-
-        // TODO: Do we need mRequestedApnType?
-        mRequestedApnType = Phone.APN_TYPE_DEFAULT;
-    }
-
-    /**
-     * Cleanup all connections.
-     *
-     * TODO: Cleanup only a specified connection passed as a parameter.
-     *       Also, make sure when you clean up a conn, if it is last apply
-     *       logic as though it is cleanupAllConnections
-     *
-     * @param tearDown true if the underlying DataConnection should be disconnected.
-     * @param reason for the clean up.
-     */
-
-    @Override
-    protected void onCleanUpAllConnections(String cause) {
-        cleanUpAllConnections(true, cause);
-    }
-
-    private void cleanUpConnection(boolean tearDown, ApnContext apnContext) {
-
-        if (apnContext == null) {
-            if (DBG) log("cleanUpConnection: apn context is null");
-            return;
-        }
-
-        DataConnectionAc dcac = apnContext.getDataConnectionAc();
-        if (DBG) {
-            log("cleanUpConnection: E tearDown=" + tearDown + " reason=" + apnContext.getReason() +
-                    " apnContext=" + apnContext);
-        }
-        if (tearDown) {
-            if (apnContext.isDisconnected()) {
-                // The request is tearDown and but ApnContext is not connected.
-                // If apnContext is not enabled anymore, break the linkage to the DCAC/DC.
-                apnContext.setState(State.IDLE);
-                if (!apnContext.isReady()) {
-                    apnContext.setDataConnection(null);
-                    apnContext.setDataConnectionAc(null);
-                }
-            } else {
-                // Connection is still there. Try to clean up.
-                if (dcac != null) {
-                    if (apnContext.getState() != State.DISCONNECTING) {
-                        boolean disconnectAll = false;
-                        if (Phone.APN_TYPE_DUN.equals(apnContext.getApnType())) {
-                            ApnSetting dunSetting = fetchDunApn();
-                            if (dunSetting != null &&
-                                    dunSetting.equals(apnContext.getApnSetting())) {
-                                if (DBG) log("tearing down dedicated DUN connection");
-                                // we need to tear it down - we brought it up just for dun and
-                                // other people are camped on it and now dun is done.  We need
-                                // to stop using it and let the normal apn list get used to find
-                                // connections for the remaining desired connections
-                                disconnectAll = true;
-                            }
-                        }
-                        if (DBG) {
-                            log("cleanUpConnection: tearing down" + (disconnectAll ? " all" :""));
-                        }
-                        Message msg = obtainMessage(EVENT_DISCONNECT_DONE, apnContext);
-                        if (disconnectAll) {
-                            apnContext.getDataConnection().tearDownAll(apnContext.getReason(), msg);
-                        } else {
-                            apnContext.getDataConnection().tearDown(apnContext.getReason(), msg);
-                        }
-                        apnContext.setState(State.DISCONNECTING);
-                    }
-                } else {
-                    // apn is connected but no reference to dcac.
-                    // Should not be happen, but reset the state in case.
-                    apnContext.setState(State.IDLE);
-                    mPhone.notifyDataConnection(apnContext.getReason(),
-                                                apnContext.getApnType());
-                }
-            }
-        } else {
-            // force clean up the data connection.
-            if (dcac != null) dcac.resetSync();
-            apnContext.setState(State.IDLE);
-            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
-            apnContext.setDataConnection(null);
-            apnContext.setDataConnectionAc(null);
-        }
-
-        // make sure reconnection alarm is cleaned up if there is no ApnContext
-        // associated to the connection.
-        if (dcac != null) {
-            Collection<ApnContext> apnList = dcac.getApnListSync();
-            if (apnList.isEmpty()) {
-                cancelReconnectAlarm(dcac);
-            }
-        }
-        if (DBG) {
-            log("cleanUpConnection: X tearDown=" + tearDown + " reason=" + apnContext.getReason() +
-                    " apnContext=" + apnContext + " dc=" + apnContext.getDataConnection());
-        }
-    }
-
-    /**
-     * Cancels the alarm associated with DCAC.
-     *
-     * @param DataConnectionAc on which the alarm should be stopped.
-     */
-    private void cancelReconnectAlarm(DataConnectionAc dcac) {
-        if (dcac == null) return;
-
-        PendingIntent intent = dcac.getReconnectIntentSync();
-
-        if (intent != null) {
-                AlarmManager am =
-                    (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
-                am.cancel(intent);
-                dcac.setReconnectIntentSync(null);
-        }
-    }
-
-    /**
-     * @param types comma delimited list of APN types
-     * @return array of APN types
-     */
-    private String[] parseTypes(String types) {
-        String[] result;
-        // If unset, set to DEFAULT.
-        if (types == null || types.equals("")) {
-            result = new String[1];
-            result[0] = Phone.APN_TYPE_ALL;
-        } else {
-            result = types.split(",");
-        }
-        return result;
-    }
-
-    private ArrayList<ApnSetting> createApnList(Cursor cursor) {
-        ArrayList<ApnSetting> result = new ArrayList<ApnSetting>();
-        if (cursor.moveToFirst()) {
-            do {
-                String[] types = parseTypes(
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.TYPE)));
-                ApnSetting apn = new ApnSetting(
-                        cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)),
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NUMERIC)),
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)),
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)),
-                        NetworkUtils.trimV4AddrZeros(
-                                cursor.getString(
-                                cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY))),
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT)),
-                        NetworkUtils.trimV4AddrZeros(
-                                cursor.getString(
-                                cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC))),
-                        NetworkUtils.trimV4AddrZeros(
-                                cursor.getString(
-                                cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY))),
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT)),
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)),
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)),
-                        cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.AUTH_TYPE)),
-                        types,
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROTOCOL)),
-                        cursor.getString(cursor.getColumnIndexOrThrow(
-                                Telephony.Carriers.ROAMING_PROTOCOL)),
-                        cursor.getInt(cursor.getColumnIndexOrThrow(
-                                Telephony.Carriers.CARRIER_ENABLED)) == 1,
-                        cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.BEARER)));
-                result.add(apn);
-            } while (cursor.moveToNext());
-        }
-        if (DBG) log("createApnList: X result=" + result);
-        return result;
-    }
-
-    private boolean dataConnectionNotInUse(DataConnectionAc dcac) {
-        if (DBG) log("dataConnectionNotInUse: check if dcac is inuse dc=" + dcac.dataConnection);
-        for (ApnContext apnContext : mApnContexts.values()) {
-            if (apnContext.getDataConnectionAc() == dcac) {
-                if (DBG) log("dataConnectionNotInUse: in use by apnContext=" + apnContext);
-                return false;
-            }
-        }
-        // TODO: Fix retry handling so free DataConnections have empty apnlists.
-        // Probably move retry handling into DataConnections and reduce complexity
-        // of DCT.
-        for (ApnContext apnContext : dcac.getApnListSync()) {
-            if (DBG) {
-                log("dataConnectionNotInUse: removing apnContext=" + apnContext);
-            }
-            dcac.removeApnContextSync(apnContext);
-        }
-        if (DBG) log("dataConnectionNotInUse: not in use return true");
-        return true;
-    }
-
-    private GsmDataConnection findFreeDataConnection() {
-        for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
-            if (dcac.isInactiveSync() && dataConnectionNotInUse(dcac)) {
-                DataConnection dc = dcac.dataConnection;
-                if (DBG) {
-                    log("findFreeDataConnection: found free GsmDataConnection=" +
-                        " dcac=" + dcac + " dc=" + dc);
-                }
-                return (GsmDataConnection) dc;
-            }
-        }
-        log("findFreeDataConnection: NO free GsmDataConnection");
-        return null;
-    }
-
-    protected GsmDataConnection findReadyDataConnection(ApnSetting apn) {
-        if (apn == null) {
-            return null;
-        }
-        if (DBG) {
-            log("findReadyDataConnection: apn string <" + apn + ">" +
-                    " dcacs.size=" + mDataConnectionAsyncChannels.size());
-        }
-        for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
-            ApnSetting apnSetting = dcac.getApnSettingSync();
-            if (DBG) {
-                log("findReadyDataConnection: dc apn string <" +
-                         (apnSetting != null ? (apnSetting.toString()) : "null") + ">");
-            }
-            if ((apnSetting != null) && TextUtils.equals(apnSetting.toString(), apn.toString())) {
-                DataConnection dc = dcac.dataConnection;
-                if (DBG) {
-                    log("findReadyDataConnection: found ready GsmDataConnection=" +
-                        " dcac=" + dcac + " dc=" + dc);
-                }
-                return (GsmDataConnection) dc;
-            }
-        }
-        return null;
-    }
-
-
-    private boolean setupData(ApnContext apnContext) {
-        if (DBG) log("setupData: apnContext=" + apnContext);
-        ApnSetting apn;
-        GsmDataConnection dc;
-
-        int profileId = getApnProfileID(apnContext.getApnType());
-        apn = apnContext.getNextWaitingApn();
-        if (apn == null) {
-            if (DBG) log("setupData: return for no apn found!");
-            return false;
-        }
-
-
-        dc = (GsmDataConnection) checkForConnectionForApnContext(apnContext);
-
-        if (dc == null) {
-            dc = findReadyDataConnection(apn);
-
-            if (dc == null) {
-                if (DBG) log("setupData: No ready GsmDataConnection found!");
-                // TODO: When allocating you are mapping type to id. If more than 1 free,
-                // then could findFreeDataConnection get the wrong one??
-                dc = findFreeDataConnection();
-            }
-
-            if (dc == null) {
-                dc = createDataConnection();
-            }
-
-            if (dc == null) {
-                if (DBG) log("setupData: No free GsmDataConnection found!");
-                return false;
-            }
-        } else {
-            apn = mDataConnectionAsyncChannels.get(dc.getDataConnectionId()).getApnSettingSync();
-        }
-
-        DataConnectionAc dcac = mDataConnectionAsyncChannels.get(dc.getDataConnectionId());
-        dc.setProfileId( profileId );  //  assumed no connection sharing on profiled types
-
-        int refCount = dcac.getRefCountSync();
-        if (DBG) log("setupData: init dc and apnContext refCount=" + refCount);
-
-        // configure retry count if no other Apn is using the same connection.
-        if (refCount == 0) {
-            configureRetry(dc, apn.canHandleType(Phone.APN_TYPE_DEFAULT),
-                    apnContext.getRetryCount());
-        }
-        apnContext.setDataConnectionAc(dcac);
-        apnContext.setDataConnection(dc);
-
-        apnContext.setApnSetting(apn);
-        apnContext.setState(State.INITING);
-        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
-        // If reconnect alarm is active on this DataConnection, wait for the alarm being
-        // fired so that we don't disruppt data retry pattern engaged.
-        if (apnContext.getDataConnectionAc().getReconnectIntentSync() != null) {
-            if (DBG) log("setupData: data reconnection pending");
-            apnContext.setState(State.FAILED);
-            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
-            return true;
-        }
-
-        Message msg = obtainMessage();
-        msg.what = EVENT_DATA_SETUP_COMPLETE;
-        msg.obj = apnContext;
-        dc.bringUp(msg, apn);
-
-        if (DBG) log("setupData: initing!");
-        return true;
-    }
-
-    /**
-     * Handles changes to the APN database.
-     */
-    private void onApnChanged() {
-        State overallState = getOverallState();
-        boolean isDisconnected = (overallState == State.IDLE || overallState == State.FAILED);
-
-        if (mPhone instanceof GSMPhone) {
-            // The "current" may no longer be valid.  MMS depends on this to send properly. TBD
-            ((GSMPhone)mPhone).updateCurrentCarrierInProvider();
-        }
-
-        // TODO: It'd be nice to only do this if the changed entrie(s)
-        // match the current operator.
-        if (DBG) log("onApnChanged: createAllApnList and cleanUpAllConnections");
-        createAllApnList();
-        cleanUpAllConnections(!isDisconnected, Phone.REASON_APN_CHANGED);
-        if (isDisconnected) {
-            setupDataOnReadyApns(Phone.REASON_APN_CHANGED);
-        }
-    }
-
-    /**
-     * @param cid Connection id provided from RIL.
-     * @return DataConnectionAc associated with specified cid.
-     */
-    private DataConnectionAc findDataConnectionAcByCid(int cid) {
-        for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
-            if (dcac.getCidSync() == cid) {
-                return dcac;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * @param dcacs Collection of DataConnectionAc reported from RIL.
-     * @return List of ApnContext which is connected, but is not present in
-     *         data connection list reported from RIL.
-     */
-    private List<ApnContext> findApnContextToClean(Collection<DataConnectionAc> dcacs) {
-        if (dcacs == null) return null;
-
-        if (DBG) log("findApnContextToClean(ar): E dcacs=" + dcacs);
-
-        ArrayList<ApnContext> list = new ArrayList<ApnContext>();
-        for (ApnContext apnContext : mApnContexts.values()) {
-            if (apnContext.getState() == State.CONNECTED) {
-                boolean found = false;
-                for (DataConnectionAc dcac : dcacs) {
-                    if (dcac == apnContext.getDataConnectionAc()) {
-                        // ApnContext holds the ref to dcac present in data call list.
-                        found = true;
-                        break;
-                    }
-                }
-                if (!found) {
-                    // ApnContext does not have dcac reported in data call list.
-                    // Fetch all the ApnContexts that map to this dcac which are in
-                    // INITING state too.
-                    if (DBG) log("findApnContextToClean(ar): Connected apn not found in the list (" +
-                                 apnContext.toString() + ")");
-                    if (apnContext.getDataConnectionAc() != null) {
-                        list.addAll(apnContext.getDataConnectionAc().getApnListSync());
-                    } else {
-                        list.add(apnContext);
-                    }
-                }
-            }
-        }
-        if (DBG) log("findApnContextToClean(ar): X list=" + list);
-        return list;
-    }
-
-    /**
-     * @param ar is the result of RIL_REQUEST_DATA_CALL_LIST
-     * or RIL_UNSOL_DATA_CALL_LIST_CHANGED
-     */
-    private void onDataStateChanged (AsyncResult ar) {
-        ArrayList<DataCallState> dataCallStates;
-
-        if (DBG) log("onDataStateChanged(ar): E");
-        dataCallStates = (ArrayList<DataCallState>)(ar.result);
-
-        if (ar.exception != null) {
-            // This is probably "radio not available" or something
-            // of that sort. If so, the whole connection is going
-            // to come down soon anyway
-            if (DBG) log("onDataStateChanged(ar): exception; likely radio not available, ignore");
-            return;
-        }
-        if (DBG) log("onDataStateChanged(ar): DataCallState size=" + dataCallStates.size());
-
-        // Create a hash map to store the dataCallState of each DataConnectionAc
-        HashMap<DataCallState, DataConnectionAc> dataCallStateToDcac;
-        dataCallStateToDcac = new HashMap<DataCallState, DataConnectionAc>();
-        for (DataCallState dataCallState : dataCallStates) {
-            DataConnectionAc dcac = findDataConnectionAcByCid(dataCallState.cid);
-
-            if (dcac != null) dataCallStateToDcac.put(dataCallState, dcac);
-        }
-
-        // A list of apns to cleanup, those that aren't in the list we know we have to cleanup
-        List<ApnContext> apnsToCleanup = findApnContextToClean(dataCallStateToDcac.values());
-
-        // Find which connections have changed state and send a notification or cleanup
-        for (DataCallState newState : dataCallStates) {
-            DataConnectionAc dcac = dataCallStateToDcac.get(newState);
-
-            if (dcac == null) {
-                loge("onDataStateChanged(ar): No associated DataConnection ignore");
-                continue;
-            }
-
-            // The list of apn's associated with this DataConnection
-            Collection<ApnContext> apns = dcac.getApnListSync();
-
-            // Find which ApnContexts of this DC are in the "Connected/Connecting" state.
-            ArrayList<ApnContext> connectedApns = new ArrayList<ApnContext>();
-            for (ApnContext apnContext : apns) {
-                if (apnContext.getState() == State.CONNECTED ||
-                       apnContext.getState() == State.CONNECTING ||
-                       apnContext.getState() == State.INITING) {
-                    connectedApns.add(apnContext);
-                }
-            }
-            if (connectedApns.size() == 0) {
-                if (DBG) log("onDataStateChanged(ar): no connected apns");
-            } else {
-                // Determine if the connection/apnContext should be cleaned up
-                // or just a notification should be sent out.
-                if (DBG) log("onDataStateChanged(ar): Found ConnId=" + newState.cid
-                        + " newState=" + newState.toString());
-                if (newState.active == 0) {
-                    if (DBG) {
-                        log("onDataStateChanged(ar): inactive, cleanup apns=" + connectedApns);
-                    }
-                    apnsToCleanup.addAll(connectedApns);
-                } else {
-                    // Its active so update the DataConnections link properties
-                    UpdateLinkPropertyResult result =
-                        dcac.updateLinkPropertiesDataCallStateSync(newState);
-                    if (result.oldLp.equals(result.newLp)) {
-                        if (DBG) log("onDataStateChanged(ar): no change");
-                    } else {
-                        if (result.oldLp.isIdenticalInterfaceName(result.newLp)) {
-                            if (! result.oldLp.isIdenticalDnses(result.newLp) ||
-                                    ! result.oldLp.isIdenticalRoutes(result.newLp) ||
-                                    ! result.oldLp.isIdenticalHttpProxy(result.newLp) ||
-                                    ! result.oldLp.isIdenticalAddresses(result.newLp)) {
-                                // If the same address type was removed and added we need to cleanup
-                                CompareResult<LinkAddress> car =
-                                    result.oldLp.compareAddresses(result.newLp);
-                                if (DBG) {
-                                    log("onDataStateChanged: oldLp=" + result.oldLp +
-                                            " newLp=" + result.newLp + " car=" + car);
-                                }
-                                boolean needToClean = false;
-                                for (LinkAddress added : car.added) {
-                                    for (LinkAddress removed : car.removed) {
-                                        if (NetworkUtils.addressTypeMatches(removed.getAddress(),
-                                                added.getAddress())) {
-                                            needToClean = true;
-                                            break;
-                                        }
-                                    }
-                                }
-                                if (needToClean) {
-                                    if (DBG) {
-                                        log("onDataStateChanged(ar): addr change, cleanup apns=" +
-                                                connectedApns + " oldLp=" + result.oldLp +
-                                                " newLp=" + result.newLp);
-                                    }
-                                    apnsToCleanup.addAll(connectedApns);
-                                } else {
-                                    if (DBG) log("onDataStateChanged(ar): simple change");
-                                    for (ApnContext apnContext : connectedApns) {
-                                         mPhone.notifyDataConnection(
-                                                 Phone.REASON_LINK_PROPERTIES_CHANGED,
-                                                 apnContext.getApnType());
-                                    }
-                                }
-                            } else {
-                                if (DBG) {
-                                    log("onDataStateChanged(ar): no changes");
-                                }
-                            }
-                        } else {
-                            if (DBG) {
-                                log("onDataStateChanged(ar): interface change, cleanup apns="
-                                        + connectedApns);
-                            }
-                            apnsToCleanup.addAll(connectedApns);
-                        }
-                    }
-                }
-            }
-        }
-
-        if (apnsToCleanup.size() != 0) {
-            // Add an event log when the network drops PDP
-            int cid = getCellLocationId();
-            EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP, cid,
-                                TelephonyManager.getDefault().getNetworkType());
-        }
-
-        // Cleanup those dropped connections
-        if (DBG) log("onDataStateChange(ar): apnsToCleanup=" + apnsToCleanup);
-        for (ApnContext apnContext : apnsToCleanup) {
-            cleanUpConnection(true, apnContext);
-        }
-
-        if (DBG) log("onDataStateChanged(ar): X");
-    }
-
-    private void notifyDefaultData(ApnContext apnContext) {
-        if (DBG) {
-            log("notifyDefaultData: type=" + apnContext.getApnType()
-                + ", reason:" + apnContext.getReason());
-        }
-        apnContext.setState(State.CONNECTED);
-        // setState(State.CONNECTED);
-        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
-        startNetStatPoll();
-        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
-        // reset reconnect timer
-        apnContext.setRetryCount(0);
-    }
-
-    // TODO: For multiple Active APNs not exactly sure how to do this.
-    protected void gotoIdleAndNotifyDataConnection(String reason) {
-        if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason);
-        notifyDataConnection(reason);
-        mActiveApn = null;
-    }
-
-    private void resetPollStats() {
-        mTxPkts = -1;
-        mRxPkts = -1;
-        mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
-    }
-
-    private void doRecovery() {
-        if (getOverallState() == State.CONNECTED) {
-            // Go through a series of recovery steps, each action transitions to the next action
-            int recoveryAction = getRecoveryAction();
-            switch (recoveryAction) {
-            case RecoveryAction.GET_DATA_CALL_LIST:
-                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_GET_DATA_CALL_LIST,
-                        mSentSinceLastRecv);
-                if (DBG) log("doRecovery() get data call list");
-                mPhone.mCM.getDataCallList(obtainMessage(EVENT_DATA_STATE_CHANGED));
-                putRecoveryAction(RecoveryAction.CLEANUP);
-                break;
-            case RecoveryAction.CLEANUP:
-                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_CLEANUP, mSentSinceLastRecv);
-                if (DBG) log("doRecovery() cleanup all connections");
-                cleanUpAllConnections(true, Phone.REASON_PDP_RESET);
-                putRecoveryAction(RecoveryAction.REREGISTER);
-                break;
-            case RecoveryAction.REREGISTER:
-                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_REREGISTER,
-                        mSentSinceLastRecv);
-                if (DBG) log("doRecovery() re-register");
-                mPhone.getServiceStateTracker().reRegisterNetwork(null);
-                putRecoveryAction(RecoveryAction.RADIO_RESTART);
-                break;
-            case RecoveryAction.RADIO_RESTART:
-                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART,
-                        mSentSinceLastRecv);
-                if (DBG) log("restarting radio");
-                putRecoveryAction(RecoveryAction.RADIO_RESTART_WITH_PROP);
-                restartRadio();
-                break;
-            case RecoveryAction.RADIO_RESTART_WITH_PROP:
-                // This is in case radio restart has not recovered the data.
-                // It will set an additional "gsm.radioreset" property to tell
-                // RIL or system to take further action.
-                // The implementation of hard reset recovery action is up to OEM product.
-                // Once gsm.radioreset property is consumed, it is expected to set back
-                // to false by RIL.
-                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART_WITH_PROP, -1);
-                if (DBG) log("restarting radio with gsm.radioreset to true");
-                SystemProperties.set("gsm.radioreset", "true");
-                // give 1 sec so property change can be notified.
-                try {
-                    Thread.sleep(1000);
-                } catch (InterruptedException e) {}
-                restartRadio();
-                putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
-                break;
-            default:
-                throw new RuntimeException("doRecovery: Invalid recoveryAction=" +
-                    recoveryAction);
-            }
-        }
-    }
-
-    @Override
-    protected void startNetStatPoll() {
-        if (getOverallState() == State.CONNECTED && mNetStatPollEnabled == false) {
-            if (DBG) log("startNetStatPoll");
-            resetPollStats();
-            mNetStatPollEnabled = true;
-            mPollNetStat.run();
-        }
-    }
-
-    @Override
-    protected void stopNetStatPoll() {
-        mNetStatPollEnabled = false;
-        removeCallbacks(mPollNetStat);
-        if (DBG) log("stopNetStatPoll");
-    }
-
-    @Override
-    protected void restartRadio() {
-        if (DBG) log("restartRadio: ************TURN OFF RADIO**************");
-        cleanUpAllConnections(true, Phone.REASON_RADIO_TURNED_OFF);
-        mPhone.getServiceStateTracker().powerOffRadioSafely(this);
-        /* Note: no need to call setRadioPower(true).  Assuming the desired
-         * radio power state is still ON (as tracked by ServiceStateTracker),
-         * ServiceStateTracker will call setRadioPower when it receives the
-         * RADIO_STATE_CHANGED notification for the power off.  And if the
-         * desired power state has changed in the interim, we don't want to
-         * override it with an unconditional power on.
-         */
-
-        int reset = Integer.parseInt(SystemProperties.get("net.ppp.reset-by-timeout", "0"));
-        SystemProperties.set("net.ppp.reset-by-timeout", String.valueOf(reset+1));
-    }
-
-
-    private void updateDataStallInfo() {
-        long sent, received;
-
-        TxRxSum preTxRxSum = new TxRxSum(mDataStallTxRxSum);
-        mDataStallTxRxSum.updateTxRxSum();
-
-        if (VDBG) {
-            log("updateDataStallInfo: mDataStallTxRxSum=" + mDataStallTxRxSum +
-                    " preTxRxSum=" + preTxRxSum);
-        }
-
-        sent = mDataStallTxRxSum.txPkts - preTxRxSum.txPkts;
-        received = mDataStallTxRxSum.rxPkts - preTxRxSum.rxPkts;
-
-        if (RADIO_TESTS) {
-            if (SystemProperties.getBoolean("radio.test.data.stall", false)) {
-                log("updateDataStallInfo: radio.test.data.stall true received = 0;");
-                received = 0;
-            }
-        }
-        if ( sent > 0 && received > 0 ) {
-            if (VDBG) log("updateDataStallInfo: IN/OUT");
-            mSentSinceLastRecv = 0;
-            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
-        } else if (sent > 0 && received == 0) {
-            if (mPhone.getState() == Phone.State.IDLE) {
-                mSentSinceLastRecv += sent;
-            } else {
-                mSentSinceLastRecv = 0;
-            }
-            if (DBG) {
-                log("updateDataStallInfo: OUT sent=" + sent +
-                        " mSentSinceLastRecv=" + mSentSinceLastRecv);
-            }
-        } else if (sent == 0 && received > 0) {
-            if (VDBG) log("updateDataStallInfo: IN");
-            mSentSinceLastRecv = 0;
-            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
-        } else {
-            if (VDBG) log("updateDataStallInfo: NONE");
-        }
-    }
-
-    @Override
-    protected void onDataStallAlarm(int tag) {
-        if (mDataStallAlarmTag != tag) {
-            if (DBG) {
-                log("onDataStallAlarm: ignore, tag=" + tag + " expecting " + mDataStallAlarmTag);
-            }
-            return;
-        }
-        updateDataStallInfo();
-
-        int hangWatchdogTrigger = Settings.Secure.getInt(mResolver,
-                Settings.Secure.PDP_WATCHDOG_TRIGGER_PACKET_COUNT,
-                NUMBER_SENT_PACKETS_OF_HANG);
-
-        boolean suspectedStall = DATA_STALL_NOT_SUSPECTED;
-        if (mSentSinceLastRecv >= hangWatchdogTrigger) {
-            if (DBG) {
-                log("onDataStallAlarm: tag=" + tag + " do recovery action=" + getRecoveryAction());
-            }
-            suspectedStall = DATA_STALL_SUSPECTED;
-            sendMessage(obtainMessage(EVENT_DO_RECOVERY));
-        } else {
-            if (VDBG) {
-                log("onDataStallAlarm: tag=" + tag + " Sent " + String.valueOf(mSentSinceLastRecv) +
-                    " pkts since last received, < watchdogTrigger=" + hangWatchdogTrigger);
-            }
-        }
-        startDataStallAlarm(suspectedStall);
-    }
-
-
-    private void updateDataActivity() {
-        long sent, received;
-
-        Activity newActivity;
-
-        TxRxSum preTxRxSum = new TxRxSum(mTxPkts, mRxPkts);
-        TxRxSum curTxRxSum = new TxRxSum();
-        curTxRxSum.updateTxRxSum();
-        mTxPkts = curTxRxSum.txPkts;
-        mRxPkts = curTxRxSum.rxPkts;
-
-        if (VDBG) {
-            log("updateDataActivity: curTxRxSum=" + curTxRxSum + " preTxRxSum=" + preTxRxSum);
-        }
-
-        if (mNetStatPollEnabled && (preTxRxSum.txPkts > 0 || preTxRxSum.rxPkts > 0)) {
-            sent = mTxPkts - preTxRxSum.txPkts;
-            received = mRxPkts - preTxRxSum.rxPkts;
-
-            if (VDBG) log("updateDataActivity: sent=" + sent + " received=" + received);
-            if ( sent > 0 && received > 0 ) {
-                newActivity = Activity.DATAINANDOUT;
-            } else if (sent > 0 && received == 0) {
-                newActivity = Activity.DATAOUT;
-            } else if (sent == 0 && received > 0) {
-                newActivity = Activity.DATAIN;
-            } else {
-                newActivity = Activity.NONE;
-            }
-
-            if (mActivity != newActivity && mIsScreenOn) {
-                if (VDBG) log("updateDataActivity: newActivity=" + newActivity);
-                mActivity = newActivity;
-                mPhone.notifyDataActivity();
-            }
-        }
-    }
-
-    private Runnable mPollNetStat = new Runnable()
-    {
-        @Override
-        public void run() {
-            updateDataActivity();
-
-            if (mIsScreenOn) {
-                mNetStatPollPeriod = Settings.Secure.getInt(mResolver,
-                        Settings.Secure.PDP_WATCHDOG_POLL_INTERVAL_MS, POLL_NETSTAT_MILLIS);
-            } else {
-                mNetStatPollPeriod = Settings.Secure.getInt(mResolver,
-                        Settings.Secure.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS,
-                        POLL_NETSTAT_SCREEN_OFF_MILLIS);
-            }
-
-            if (mNetStatPollEnabled) {
-                mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod);
-            }
-        }
-    };
-
-    /**
-     * Returns true if the last fail cause is something that
-     * seems like it deserves an error notification.
-     * Transient errors are ignored
-     */
-    private boolean shouldPostNotification(GsmDataConnection.FailCause  cause) {
-        return (cause != GsmDataConnection.FailCause.UNKNOWN);
-    }
-
-    /**
-     * Return true if data connection need to be setup after disconnected due to
-     * reason.
-     *
-     * @param reason the reason why data is disconnected
-     * @return true if try setup data connection is need for this reason
-     */
-    private boolean retryAfterDisconnected(String reason) {
-        boolean retry = true;
-
-        if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ) {
-            retry = false;
-        }
-        return retry;
-    }
-
-    private void reconnectAfterFail(FailCause lastFailCauseCode,
-                                    ApnContext apnContext, int retryOverride) {
-        if (apnContext == null) {
-            loge("reconnectAfterFail: apnContext == null, impossible");
-            return;
-        }
-        if (DBG) {
-            log("reconnectAfterFail: lastFailCause=" + lastFailCauseCode +
-                    " retryOverride=" + retryOverride + " apnContext=" + apnContext);
-        }
-        if ((apnContext.getState() == State.FAILED) &&
-            (apnContext.getDataConnection() != null)) {
-            if (!apnContext.getDataConnection().isRetryNeeded()) {
-                if (!apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT)) {
-                    mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType());
-                    return;
-                }
-                if (mReregisterOnReconnectFailure) {
-                    // We've re-registerd once now just retry forever.
-                    apnContext.getDataConnection().retryForeverUsingLastTimeout();
-                } else {
-                    // Try to Re-register to the network.
-                    if (DBG) log("reconnectAfterFail: activate failed, Reregistering to network");
-                    mReregisterOnReconnectFailure = true;
-                    mPhone.getServiceStateTracker().reRegisterNetwork(null);
-                    apnContext.setRetryCount(0);
-                    return;
-                }
-            }
-
-            // If retry needs to be backed off for specific case (determined by RIL/Modem)
-            // use the specified timer instead of pre-configured retry pattern.
-            int nextReconnectDelay = retryOverride;
-            if (nextReconnectDelay < 0) {
-                nextReconnectDelay = apnContext.getDataConnection().getRetryTimer();
-                apnContext.getDataConnection().increaseRetryCount();
-                if (DBG) {
-                    log("reconnectAfterFail: increaseRetryCount=" +
-                            apnContext.getDataConnection().getRetryCount() +
-                            " nextReconnectDelay=" + nextReconnectDelay);
-                }
-            }
-            startAlarmForReconnect(nextReconnectDelay, apnContext);
-
-            if (!shouldPostNotification(lastFailCauseCode)) {
-                if (DBG) {
-                    log("reconnectAfterFail: NOT Posting GPRS Unavailable notification "
-                                + "-- likely transient error");
-                }
-            } else {
-                notifyNoData(lastFailCauseCode, apnContext);
-            }
-        }
-    }
-
-    private void startAlarmForReconnect(int delay, ApnContext apnContext) {
-
-        DataConnectionAc dcac = apnContext.getDataConnectionAc();
-
-        if ((dcac == null) || (dcac.dataConnection == null)) {
-            // should not happen, but just in case.
-            loge("startAlarmForReconnect: null dcac or dc.");
-            return;
-        }
-
-        AlarmManager am =
-            (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
-
-        Intent intent = new Intent(INTENT_RECONNECT_ALARM + '.' +
-                                   dcac.dataConnection.getDataConnectionId());
-        String reason = apnContext.getReason();
-        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, reason);
-        int connectionId = dcac.dataConnection.getDataConnectionId();
-        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, connectionId);
-
-        // TODO: Until a real fix is created, which probably entails pushing
-        // retires into the DC itself, this fix gets the retry count and
-        // puts it in the reconnect alarm. When the reconnect alarm fires
-        // onActionIntentReconnectAlarm is called which will use the value saved
-        // here and save it in the ApnContext and send the EVENT_CONNECT message
-        // which invokes setupData. Then setupData will use the value in the ApnContext
-        // and to tell the DC to set the retry count in the retry manager.
-        int retryCount = dcac.dataConnection.getRetryCount();
-        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_RETRY_COUNT, retryCount);
-
-        if (DBG) {
-            log("startAlarmForReconnect: next attempt in " + (delay / 1000) + "s" +
-                    " reason='" + reason + "' connectionId=" + connectionId +
-                    " retryCount=" + retryCount);
-        }
-
-        PendingIntent alarmIntent = PendingIntent.getBroadcast (mPhone.getContext(), 0,
-                                        intent, PendingIntent.FLAG_UPDATE_CURRENT);
-        dcac.setReconnectIntentSync(alarmIntent);
-        am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                SystemClock.elapsedRealtime() + delay, alarmIntent);
-
-    }
-
-    private void startDataStallAlarm(boolean suspectedStall) {
-        int nextAction = getRecoveryAction();
-        int delayInMs;
-
-        // If screen is on or data stall is currently suspected, set the alarm
-        // with an aggresive timeout.
-        if (mIsScreenOn || suspectedStall || RecoveryAction.isAggressiveRecovery(nextAction)) {
-            delayInMs = Settings.Secure.getInt(mResolver,
-                                       Settings.Secure.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS,
-                                       DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
-        } else {
-            delayInMs = Settings.Secure.getInt(mResolver,
-                                       Settings.Secure.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS,
-                                       DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
-        }
-
-        mDataStallAlarmTag += 1;
-        if (VDBG) {
-            log("startDataStallAlarm: tag=" + mDataStallAlarmTag +
-                    " delay=" + (delayInMs / 1000) + "s");
-        }
-        AlarmManager am =
-            (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
-
-        Intent intent = new Intent(INTENT_DATA_STALL_ALARM);
-        intent.putExtra(DATA_STALL_ALARM_TAG_EXTRA, mDataStallAlarmTag);
-        mDataStallAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
-                PendingIntent.FLAG_UPDATE_CURRENT);
-        am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                SystemClock.elapsedRealtime() + delayInMs, mDataStallAlarmIntent);
-    }
-
-    private void stopDataStallAlarm() {
-        AlarmManager am =
-            (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
-
-        if (VDBG) {
-            log("stopDataStallAlarm: current tag=" + mDataStallAlarmTag +
-                    " mDataStallAlarmIntent=" + mDataStallAlarmIntent);
-        }
-        mDataStallAlarmTag += 1;
-        if (mDataStallAlarmIntent != null) {
-            am.cancel(mDataStallAlarmIntent);
-            mDataStallAlarmIntent = null;
-        }
-    }
-
-    @Override
-    protected void restartDataStallAlarm() {
-        if (isConnected() == false) return;
-        // To be called on screen status change.
-        // Do not cancel the alarm if it is set with aggressive timeout.
-        int nextAction = getRecoveryAction();
-
-        if (RecoveryAction.isAggressiveRecovery(nextAction)) {
-            if (DBG) log("data stall recovery action is pending. not resetting the alarm.");
-            return;
-        }
-        stopDataStallAlarm();
-        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
-    }
-
-    private void notifyNoData(GsmDataConnection.FailCause lastFailCauseCode,
-                              ApnContext apnContext) {
-        if (DBG) log( "notifyNoData: type=" + apnContext.getApnType());
-        apnContext.setState(State.FAILED);
-        if (lastFailCauseCode.isPermanentFail()
-            && (!apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT))) {
-            mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
-        }
-    }
-
-    private void onRecordsLoaded() {
-        if (DBG) log("onRecordsLoaded: createAllApnList");
-        createAllApnList();
-        if (mPhone.mCM.getRadioState().isOn()) {
-            if (DBG) log("onRecordsLoaded: notifying data availability");
-            notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED);
-        }
-        setupDataOnReadyApns(Phone.REASON_SIM_LOADED);
-    }
-
-    @Override
-    protected void onSetDependencyMet(String apnType, boolean met) {
-        // don't allow users to tweak hipri to work around default dependency not met
-        if (Phone.APN_TYPE_HIPRI.equals(apnType)) return;
-
-        ApnContext apnContext = mApnContexts.get(apnType);
-        if (apnContext == null) {
-            loge("onSetDependencyMet: ApnContext not found in onSetDependencyMet(" +
-                    apnType + ", " + met + ")");
-            return;
-        }
-        applyNewState(apnContext, apnContext.isEnabled(), met);
-        if (Phone.APN_TYPE_DEFAULT.equals(apnType)) {
-            // tie actions on default to similar actions on HIPRI regarding dependencyMet
-            apnContext = mApnContexts.get(Phone.APN_TYPE_HIPRI);
-            if (apnContext != null) applyNewState(apnContext, apnContext.isEnabled(), met);
-        }
-    }
-
-    private void applyNewState(ApnContext apnContext, boolean enabled, boolean met) {
-        boolean cleanup = false;
-        boolean trySetup = false;
-        if (DBG) {
-            log("applyNewState(" + apnContext.getApnType() + ", " + enabled +
-                    "(" + apnContext.isEnabled() + "), " + met + "(" +
-                    apnContext.getDependencyMet() +"))");
-        }
-        if (apnContext.isReady()) {
-            if (enabled && met) return;
-            if (!enabled) {
-                apnContext.setReason(Phone.REASON_DATA_DISABLED);
-            } else {
-                apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_UNMET);
-            }
-            cleanup = true;
-        } else {
-            if (enabled && met) {
-                if (apnContext.isEnabled()) {
-                    apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_MET);
-                } else {
-                    apnContext.setReason(Phone.REASON_DATA_ENABLED);
-                }
-                if (apnContext.getState() == State.FAILED) {
-                    apnContext.setState(State.IDLE);
-                }
-                trySetup = true;
-            }
-        }
-        apnContext.setEnabled(enabled);
-        apnContext.setDependencyMet(met);
-        if (cleanup) cleanUpConnection(true, apnContext);
-        if (trySetup) trySetupData(apnContext);
-    }
-
-    private DataConnection checkForConnectionForApnContext(ApnContext apnContext) {
-        // Loop through all apnContexts looking for one with a conn that satisfies this apnType
-        String apnType = apnContext.getApnType();
-        ApnSetting dunSetting = null;
-
-        if (Phone.APN_TYPE_DUN.equals(apnType)) {
-            dunSetting = fetchDunApn();
-        }
-
-        DataConnection potential = null;
-        for (ApnContext c : mApnContexts.values()) {
-            DataConnection conn = c.getDataConnection();
-            if (conn != null) {
-                ApnSetting apnSetting = c.getApnSetting();
-                if (dunSetting != null) {
-                    if (dunSetting.equals(apnSetting)) {
-                        switch (c.getState()) {
-                            case CONNECTED:
-                                if (DBG) {
-                                    log("checkForConnectionForApnContext: apnContext=" +
-                                            apnContext + " found conn=" + conn);
-                                }
-                                return conn;
-                            case CONNECTING:
-                                potential = conn;
-                        }
-                    }
-                } else if (apnSetting != null && apnSetting.canHandleType(apnType)) {
-                    switch (c.getState()) {
-                        case CONNECTED:
-                            if (DBG) {
-                                log("checkForConnectionForApnContext: apnContext=" + apnContext +
-                                        " found conn=" + conn);
-                            }
-                            return conn;
-                        case CONNECTING:
-                            potential = conn;
-                    }
-                }
-            }
-        }
-        if (potential != null) {
-            if (DBG) {
-                log("checkForConnectionForApnContext: apnContext=" + apnContext +
-                    " found conn=" + potential);
-            }
-            return potential;
-        }
-
-        if (DBG) log("checkForConnectionForApnContext: apnContext=" + apnContext + " NO conn");
-        return null;
-    }
-
-    @Override
-    protected void onEnableApn(int apnId, int enabled) {
-        ApnContext apnContext = mApnContexts.get(apnIdToType(apnId));
-        if (apnContext == null) {
-            loge("onEnableApn(" + apnId + ", " + enabled + "): NO ApnContext");
-            return;
-        }
-        // TODO change our retry manager to use the appropriate numbers for the new APN
-        if (DBG) log("onEnableApn: apnContext=" + apnContext + " call applyNewState");
-        applyNewState(apnContext, enabled == ENABLED, apnContext.getDependencyMet());
-    }
-
-    @Override
-    // TODO: We shouldnt need this.
-    protected boolean onTrySetupData(String reason) {
-        if (DBG) log("onTrySetupData: reason=" + reason);
-        setupDataOnReadyApns(reason);
-        return true;
-    }
-
-    protected boolean onTrySetupData(ApnContext apnContext) {
-        if (DBG) log("onTrySetupData: apnContext=" + apnContext);
-        return trySetupData(apnContext);
-    }
-
-    @Override
-    protected void onRoamingOff() {
-        if (DBG) log("onRoamingOff");
-
-        if (mUserDataEnabled == false) return;
-
-        if (getDataOnRoamingEnabled() == false) {
-            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_OFF);
-            setupDataOnReadyApns(Phone.REASON_ROAMING_OFF);
-        } else {
-            notifyDataConnection(Phone.REASON_ROAMING_OFF);
-        }
-    }
-
-    @Override
-    protected void onRoamingOn() {
-        if (mUserDataEnabled == false) return;
-
-        if (getDataOnRoamingEnabled()) {
-            if (DBG) log("onRoamingOn: setup data on roaming");
-            setupDataOnReadyApns(Phone.REASON_ROAMING_ON);
-            notifyDataConnection(Phone.REASON_ROAMING_ON);
-        } else {
-            if (DBG) log("onRoamingOn: Tear down data connection on roaming.");
-            cleanUpAllConnections(true, Phone.REASON_ROAMING_ON);
-            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
-        }
-    }
-
-    @Override
-    protected void onRadioAvailable() {
-        if (DBG) log("onRadioAvailable");
-        if (mPhone.getSimulatedRadioControl() != null) {
-            // Assume data is connected on the simulator
-            // FIXME  this can be improved
-            // setState(State.CONNECTED);
-            notifyDataConnection(null);
-
-            log("onRadioAvailable: We're on the simulator; assuming data is connected");
-        }
-
-        if (mPhone.mIccRecords.getRecordsLoaded()) {
-            notifyOffApnsOfAvailability(null);
-        }
-
-        if (getOverallState() != State.IDLE) {
-            cleanUpConnection(true, null);
-        }
-    }
-
-    @Override
-    protected void onRadioOffOrNotAvailable() {
-        // Make sure our reconnect delay starts at the initial value
-        // next time the radio comes on
-
-        resetAllRetryCounts();
-        mReregisterOnReconnectFailure = false;
-
-        if (mPhone.getSimulatedRadioControl() != null) {
-            // Assume data is connected on the simulator
-            // FIXME  this can be improved
-            log("We're on the simulator; assuming radio off is meaningless");
-        } else {
-            if (DBG) log("onRadioOffOrNotAvailable: is off and clean up all connections");
-            cleanUpAllConnections(false, Phone.REASON_RADIO_TURNED_OFF);
-        }
-        notifyOffApnsOfAvailability(null);
-    }
-
-    @Override
-    protected void onDataSetupComplete(AsyncResult ar) {
-
-        DataConnection.FailCause cause = DataConnection.FailCause.UNKNOWN;
-        boolean handleError = false;
-        ApnContext apnContext = null;
-
-        if(ar.userObj instanceof ApnContext){
-            apnContext = (ApnContext)ar.userObj;
-        } else {
-            throw new RuntimeException("onDataSetupComplete: No apnContext");
-        }
-
-        if (isDataSetupCompleteOk(ar)) {
-            DataConnectionAc dcac = apnContext.getDataConnectionAc();
-
-            if (RADIO_TESTS) {
-                // Note: To change radio.test.onDSC.null.dcac from command line you need to
-                // adb root and adb remount and from the command line you can only change the
-                // value to 1 once. To change it a second time you can reboot or execute
-                // adb shell stop and then adb shell start. The command line to set the value is:
-                //   adb shell sqlite3 /data/data/com.android.providers.settings/databases/settings.db "insert into system (name,value) values ('radio.test.onDSC.null.dcac', '1');"
-                ContentResolver cr = mPhone.getContext().getContentResolver();
-                String radioTestProperty = "radio.test.onDSC.null.dcac";
-                if (Settings.System.getInt(cr, radioTestProperty, 0) == 1) {
-                    log("onDataSetupComplete: " + radioTestProperty +
-                            " is true, set dcac to null and reset property to false");
-                    dcac = null;
-                    Settings.System.putInt(cr, radioTestProperty, 0);
-                    log("onDataSetupComplete: " + radioTestProperty + "=" +
-                            Settings.System.getInt(mPhone.getContext().getContentResolver(),
-                                    radioTestProperty, -1));
-                }
-            }
-            if (dcac == null) {
-                log("onDataSetupComplete: no connection to DC, handle as error");
-                cause = DataConnection.FailCause.CONNECTION_TO_DATACONNECTIONAC_BROKEN;
-                handleError = true;
-            } else {
-                DataConnection dc = apnContext.getDataConnection();
-                ApnSetting apn = apnContext.getApnSetting();
-                if (DBG) {
-                    log("onDataSetupComplete: success apn=" + (apn == null ? "unknown" : apn.apn));
-                }
-                if (apn != null && apn.proxy != null && apn.proxy.length() != 0) {
-                    try {
-                        String port = apn.port;
-                        if (TextUtils.isEmpty(port)) port = "8080";
-                        ProxyProperties proxy = new ProxyProperties(apn.proxy,
-                                Integer.parseInt(port), null);
-                        dcac.setLinkPropertiesHttpProxySync(proxy);
-                    } catch (NumberFormatException e) {
-                        loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" +
-                                apn.port + "): " + e);
-                    }
-                }
-
-                // everything is setup
-                if(TextUtils.equals(apnContext.getApnType(),Phone.APN_TYPE_DEFAULT)) {
-                    SystemProperties.set("gsm.defaultpdpcontext.active", "true");
-                    if (canSetPreferApn && mPreferredApn == null) {
-                        if (DBG) log("onDataSetupComplete: PREFERED APN is null");
-                        mPreferredApn = apn;
-                        if (mPreferredApn != null) {
-                            setPreferredApn(mPreferredApn.id);
-                        }
-                    }
-                } else {
-                    SystemProperties.set("gsm.defaultpdpcontext.active", "false");
-                }
-                notifyDefaultData(apnContext);
-            }
-        } else {
-            cause = (DataConnection.FailCause) (ar.result);
-            if (DBG) {
-                ApnSetting apn = apnContext.getApnSetting();
-                log(String.format("onDataSetupComplete: error apn=%s cause=%s",
-                        (apn == null ? "unknown" : apn.apn), cause));
-            }
-            if (cause.isEventLoggable()) {
-                // Log this failure to the Event Logs.
-                int cid = getCellLocationId();
-                EventLog.writeEvent(EventLogTags.PDP_SETUP_FAIL,
-                        cause.ordinal(), cid, TelephonyManager.getDefault().getNetworkType());
-            }
-
-            // Count permanent failures and remove the APN we just tried
-            if (cause.isPermanentFail()) apnContext.decWaitingApnsPermFailCount();
-
-            apnContext.removeWaitingApn(apnContext.getApnSetting());
-            if (DBG) {
-                log(String.format("onDataSetupComplete: WaitingApns.size=%d" +
-                        " WaitingApnsPermFailureCountDown=%d",
-                        apnContext.getWaitingApns().size(),
-                        apnContext.getWaitingApnsPermFailCount()));
-            }
-            handleError = true;
-        }
-
-        if (handleError) {
-            // See if there are more APN's to try
-            if (apnContext.getWaitingApns().isEmpty()) {
-                if (apnContext.getWaitingApnsPermFailCount() == 0) {
-                    if (DBG) {
-                        log("onDataSetupComplete: All APN's had permanent failures, stop retrying");
-                    }
-                    apnContext.setState(State.FAILED);
-                    mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType());
-
-                    apnContext.setDataConnection(null);
-                    apnContext.setDataConnectionAc(null);
-                } else {
-                    if (DBG) log("onDataSetupComplete: Not all permanent failures, retry");
-                    // check to see if retry should be overridden for this failure.
-                    int retryOverride = -1;
-                    if (ar.exception instanceof DataConnection.CallSetupException) {
-                        retryOverride =
-                            ((DataConnection.CallSetupException)ar.exception).getRetryOverride();
-                    }
-                    if (retryOverride == RILConstants.MAX_INT) {
-                        if (DBG) log("No retry is suggested.");
-                    } else {
-                        startDelayedRetry(cause, apnContext, retryOverride);
-                    }
-                }
-            } else {
-                if (DBG) log("onDataSetupComplete: Try next APN");
-                apnContext.setState(State.SCANNING);
-                // Wait a bit before trying the next APN, so that
-                // we're not tying up the RIL command channel
-                startAlarmForReconnect(APN_DELAY_MILLIS, apnContext);
-            }
-        }
-    }
-
-    /**
-     * Called when EVENT_DISCONNECT_DONE is received.
-     */
-    @Override
-    protected void onDisconnectDone(int connId, AsyncResult ar) {
-        ApnContext apnContext = null;
-
-        if (ar.userObj instanceof ApnContext) {
-            apnContext = (ApnContext) ar.userObj;
-        } else {
-            loge("onDisconnectDone: Invalid ar in onDisconnectDone, ignore");
-            return;
-        }
-
-        if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE apnContext=" + apnContext);
-        apnContext.setState(State.IDLE);
-
-        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
-
-        // if all data connection are gone, check whether Airplane mode request was
-        // pending.
-        if (isDisconnected()) {
-            if (mPhone.getServiceStateTracker().processPendingRadioPowerOffAfterDataOff()) {
-                // Radio will be turned off. No need to retry data setup
-                apnContext.setApnSetting(null);
-                apnContext.setDataConnection(null);
-                apnContext.setDataConnectionAc(null);
-                return;
-            }
-        }
-
-        // If APN is still enabled, try to bring it back up automatically
-        if (apnContext.isReady() && retryAfterDisconnected(apnContext.getReason())) {
-            SystemProperties.set("gsm.defaultpdpcontext.active", "false");  // TODO - what the heck?  This shoudld go
-            // Wait a bit before trying the next APN, so that
-            // we're not tying up the RIL command channel.
-            // This also helps in any external dependency to turn off the context.
-            startAlarmForReconnect(APN_DELAY_MILLIS, apnContext);
-        } else {
-            apnContext.setApnSetting(null);
-            apnContext.setDataConnection(null);
-            apnContext.setDataConnectionAc(null);
-        }
-    }
-
-    protected void onPollPdp() {
-        if (getOverallState() == State.CONNECTED) {
-            // only poll when connected
-            mPhone.mCM.getDataCallList(this.obtainMessage(EVENT_DATA_STATE_CHANGED));
-            sendMessageDelayed(obtainMessage(EVENT_POLL_PDP), POLL_PDP_MILLIS);
-        }
-    }
-
-    @Override
-    protected void onVoiceCallStarted() {
-        if (DBG) log("onVoiceCallStarted");
-        if (isConnected() && ! mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
-            if (DBG) log("onVoiceCallStarted stop polling");
-            stopNetStatPoll();
-            stopDataStallAlarm();
-            notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
-        }
-    }
-
-    @Override
-    protected void onVoiceCallEnded() {
-        if (DBG) log("onVoiceCallEnded");
-        if (isConnected()) {
-            if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
-                startNetStatPoll();
-                startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
-                notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
-            } else {
-                // clean slate after call end.
-                resetPollStats();
-            }
-        }
-        // reset reconnect timer
-        setupDataOnReadyApns(Phone.REASON_VOICE_CALL_ENDED);
-    }
-
-    @Override
-    protected void onCleanUpConnection(boolean tearDown, int apnId, String reason) {
-        if (DBG) log("onCleanUpConnection");
-        ApnContext apnContext = mApnContexts.get(apnIdToType(apnId));
-        if (apnContext != null) {
-            apnContext.setReason(reason);
-            cleanUpConnection(tearDown, apnContext);
-        }
-    }
-
-    protected boolean isConnected() {
-        for (ApnContext apnContext : mApnContexts.values()) {
-            if (apnContext.getState() == State.CONNECTED) {
-                // At least one context is connected, return true
-                return true;
-            }
-        }
-        // There are not any contexts connected, return false
-        return false;
-    }
-
-    @Override
-    public boolean isDisconnected() {
-        for (ApnContext apnContext : mApnContexts.values()) {
-            if (!apnContext.isDisconnected()) {
-                // At least one context was not disconnected return false
-                return false;
-            }
-        }
-        // All contexts were disconnected so return true
-        return true;
-    }
-
-    @Override
-    protected void notifyDataConnection(String reason) {
-        if (DBG) log("notifyDataConnection: reason=" + reason);
-        for (ApnContext apnContext : mApnContexts.values()) {
-            if (apnContext.isReady()) {
-                if (DBG) log("notifyDataConnection: type:"+apnContext.getApnType());
-                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
-                        apnContext.getApnType());
-            }
-        }
-        notifyOffApnsOfAvailability(reason);
-    }
-
-    /**
-     * Based on the sim operator numeric, create a list for all possible
-     * Data Connections and setup the preferredApn.
-     */
-    private void createAllApnList() {
-        mAllApns = new ArrayList<ApnSetting>();
-        String operator = mPhone.mIccRecords.getOperatorNumeric();
-        if (operator != null) {
-            String selection = "numeric = '" + operator + "'";
-            // query only enabled apn.
-            // carrier_enabled : 1 means enabled apn, 0 disabled apn.
-            selection += " and carrier_enabled = 1";
-            if (DBG) log("createAllApnList: selection=" + selection);
-
-            Cursor cursor = mPhone.getContext().getContentResolver().query(
-                    Telephony.Carriers.CONTENT_URI, null, selection, null, null);
-
-            if (cursor != null) {
-                if (cursor.getCount() > 0) {
-                    mAllApns = createApnList(cursor);
-                }
-                cursor.close();
-            }
-        }
-
-        if (mAllApns.isEmpty()) {
-            if (DBG) log("createAllApnList: No APN found for carrier: " + operator);
-            mPreferredApn = null;
-            // TODO: What is the right behaviour?
-            //notifyNoData(GsmDataConnection.FailCause.MISSING_UNKNOWN_APN);
-        } else {
-            mPreferredApn = getPreferredApn();
-            if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) {
-                mPreferredApn = null;
-                setPreferredApn(-1);
-            }
-            if (DBG) log("createAllApnList: mPreferredApn=" + mPreferredApn);
-        }
-        if (DBG) log("createAllApnList: X mAllApns=" + mAllApns);
-    }
-
-    /** Return the id for a new data connection */
-    private GsmDataConnection createDataConnection() {
-        if (DBG) log("createDataConnection E");
-
-        RetryManager rm = new RetryManager();
-        int id = mUniqueIdGenerator.getAndIncrement();
-        GsmDataConnection conn = GsmDataConnection.makeDataConnection(mPhone, id, rm, this);
-        mDataConnections.put(id, conn);
-        DataConnectionAc dcac = new DataConnectionAc(conn, LOG_TAG);
-        int status = dcac.fullyConnectSync(mPhone.getContext(), this, conn.getHandler());
-        if (status == AsyncChannel.STATUS_SUCCESSFUL) {
-            mDataConnectionAsyncChannels.put(dcac.dataConnection.getDataConnectionId(), dcac);
-        } else {
-            loge("createDataConnection: Could not connect to dcac.mDc=" + dcac.dataConnection +
-                    " status=" + status);
-        }
-
-        // install reconnect intent filter for this data connection.
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(INTENT_RECONNECT_ALARM + '.' + id);
-        mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
-
-        if (DBG) log("createDataConnection() X id=" + id + " dc=" + conn);
-        return conn;
-    }
-
-    private void configureRetry(DataConnection dc, boolean forDefault, int retryCount) {
-        if (DBG) {
-            log("configureRetry: forDefault=" + forDefault + " retryCount=" + retryCount +
-                    " dc=" + dc);
-        }
-        if (dc == null) return;
-
-        if (!dc.configureRetry(getReryConfig(forDefault))) {
-            if (forDefault) {
-                if (!dc.configureRetry(DEFAULT_DATA_RETRY_CONFIG)) {
-                    // Should never happen, log an error and default to a simple linear sequence.
-                    loge("configureRetry: Could not configure using " +
-                            "DEFAULT_DATA_RETRY_CONFIG=" + DEFAULT_DATA_RETRY_CONFIG);
-                    dc.configureRetry(20, 2000, 1000);
-                }
-            } else {
-                if (!dc.configureRetry(SECONDARY_DATA_RETRY_CONFIG)) {
-                    // Should never happen, log an error and default to a simple sequence.
-                    loge("configureRetry: Could note configure using " +
-                            "SECONDARY_DATA_RETRY_CONFIG=" + SECONDARY_DATA_RETRY_CONFIG);
-                    dc.configureRetry("max_retries=3, 333, 333, 333");
-                }
-            }
-        }
-        dc.setRetryCount(retryCount);
-    }
-
-    private void destroyDataConnections() {
-        if(mDataConnections != null) {
-            if (DBG) log("destroyDataConnections: clear mDataConnectionList");
-            mDataConnections.clear();
-        } else {
-            if (DBG) log("destroyDataConnections: mDataConnecitonList is empty, ignore");
-        }
-    }
-
-    /**
-     * Build a list of APNs to be used to create PDP's.
-     *
-     * @param requestedApnType
-     * @return waitingApns list to be used to create PDP
-     *          error when waitingApns.isEmpty()
-     */
-    private ArrayList<ApnSetting> buildWaitingApns(String requestedApnType) {
-        ArrayList<ApnSetting> apnList = new ArrayList<ApnSetting>();
-
-        if (requestedApnType.equals(Phone.APN_TYPE_DUN)) {
-            ApnSetting dun = fetchDunApn();
-            if (dun != null) {
-                apnList.add(dun);
-                if (DBG) log("buildWaitingApns: X added APN_TYPE_DUN apnList=" + apnList);
-                return apnList;
-            }
-        }
-
-        String operator = mPhone.mIccRecords.getOperatorNumeric();
-        int radioTech = mPhone.getServiceState().getRilRadioTechnology();
-
-        if (canSetPreferApn && mPreferredApn != null &&
-                mPreferredApn.canHandleType(requestedApnType)) {
-            if (DBG) {
-                log("buildWaitingApns: Preferred APN:" + operator + ":"
-                        + mPreferredApn.numeric + ":" + mPreferredApn);
-            }
-            if (mPreferredApn.numeric.equals(operator)) {
-                if (mPreferredApn.bearer == 0 || mPreferredApn.bearer == radioTech) {
-                    apnList.add(mPreferredApn);
-                    if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
-                    return apnList;
-                } else {
-                    if (DBG) log("buildWaitingApns: no preferred APN");
-                    setPreferredApn(-1);
-                    mPreferredApn = null;
-                }
-            } else {
-                if (DBG) log("buildWaitingApns: no preferred APN");
-                setPreferredApn(-1);
-                mPreferredApn = null;
-            }
-        }
-        if (mAllApns != null) {
-            for (ApnSetting apn : mAllApns) {
-                if (apn.canHandleType(requestedApnType)) {
-                    if (apn.bearer == 0 || apn.bearer == radioTech) {
-                        if (DBG) log("apn info : " +apn.toString());
-                        apnList.add(apn);
-                    }
-                }
-            }
-        } else {
-            loge("mAllApns is empty!");
-        }
-        if (DBG) log("buildWaitingApns: X apnList=" + apnList);
-        return apnList;
-    }
-
-    private String apnListToString (ArrayList<ApnSetting> apns) {
-        StringBuilder result = new StringBuilder();
-        for (int i = 0, size = apns.size(); i < size; i++) {
-            result.append('[')
-                  .append(apns.get(i).toString())
-                  .append(']');
-        }
-        return result.toString();
-    }
-
-    private void startDelayedRetry(GsmDataConnection.FailCause cause,
-                                   ApnContext apnContext, int retryOverride) {
-        notifyNoData(cause, apnContext);
-        reconnectAfterFail(cause, apnContext, retryOverride);
-    }
-
-    private void setPreferredApn(int pos) {
-        if (!canSetPreferApn) {
-            log("setPreferredApn: X !canSEtPreferApn");
-            return;
-        }
-
-        log("setPreferredApn: delete");
-        ContentResolver resolver = mPhone.getContext().getContentResolver();
-        resolver.delete(PREFERAPN_NO_UPDATE_URI, null, null);
-
-        if (pos >= 0) {
-            log("setPreferredApn: insert");
-            ContentValues values = new ContentValues();
-            values.put(APN_ID, pos);
-            resolver.insert(PREFERAPN_NO_UPDATE_URI, values);
-        }
-    }
-
-    private ApnSetting getPreferredApn() {
-        if (mAllApns.isEmpty()) {
-            log("getPreferredApn: X not found mAllApns.isEmpty");
-            return null;
-        }
-
-        Cursor cursor = mPhone.getContext().getContentResolver().query(
-                PREFERAPN_NO_UPDATE_URI, new String[] { "_id", "name", "apn" },
-                null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
-
-        if (cursor != null) {
-            canSetPreferApn = true;
-        } else {
-            canSetPreferApn = false;
-        }
-
-        if (canSetPreferApn && cursor.getCount() > 0) {
-            int pos;
-            cursor.moveToFirst();
-            pos = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID));
-            for(ApnSetting p:mAllApns) {
-                if (p.id == pos && p.canHandleType(mRequestedApnType)) {
-                    log("getPreferredApn: X found apnSetting" + p);
-                    cursor.close();
-                    return p;
-                }
-            }
-        }
-
-        if (cursor != null) {
-            cursor.close();
-        }
-
-        log("getPreferredApn: X not found");
-        return null;
-    }
-
-    @Override
-    public void handleMessage (Message msg) {
-        if (DBG) log("handleMessage msg=" + msg);
-
-        if (!mPhone.mIsTheCurrentActivePhone || mIsDisposed) {
-            loge("handleMessage: Ignore GSM msgs since GSM phone is inactive");
-            return;
-        }
-
-        switch (msg.what) {
-            case EVENT_RECORDS_LOADED:
-                onRecordsLoaded();
-                break;
-
-            case EVENT_DATA_CONNECTION_DETACHED:
-                onDataConnectionDetached();
-                break;
-
-            case EVENT_DATA_CONNECTION_ATTACHED:
-                onDataConnectionAttached();
-                break;
-
-            case EVENT_DATA_STATE_CHANGED:
-                onDataStateChanged((AsyncResult) msg.obj);
-                break;
-
-            case EVENT_POLL_PDP:
-                onPollPdp();
-                break;
-
-            case EVENT_DO_RECOVERY:
-                doRecovery();
-                break;
-
-            case EVENT_APN_CHANGED:
-                onApnChanged();
-                break;
-
-            case EVENT_PS_RESTRICT_ENABLED:
-                /**
-                 * We don't need to explicitly to tear down the PDP context
-                 * when PS restricted is enabled. The base band will deactive
-                 * PDP context and notify us with PDP_CONTEXT_CHANGED.
-                 * But we should stop the network polling and prevent reset PDP.
-                 */
-                if (DBG) log("EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
-                stopNetStatPoll();
-                stopDataStallAlarm();
-                mIsPsRestricted = true;
-                break;
-
-            case EVENT_PS_RESTRICT_DISABLED:
-                /**
-                 * When PS restrict is removed, we need setup PDP connection if
-                 * PDP connection is down.
-                 */
-                if (DBG) log("EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted);
-                mIsPsRestricted  = false;
-                if (isConnected()) {
-                    startNetStatPoll();
-                    startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
-                } else {
-                    // TODO: Should all PDN states be checked to fail?
-                    if (mState == State.FAILED) {
-                        cleanUpAllConnections(false, Phone.REASON_PS_RESTRICT_ENABLED);
-                        resetAllRetryCounts();
-                        mReregisterOnReconnectFailure = false;
-                    }
-                    trySetupData(Phone.REASON_PS_RESTRICT_ENABLED, Phone.APN_TYPE_DEFAULT);
-                }
-                break;
-            case EVENT_TRY_SETUP_DATA:
-                if (msg.obj instanceof ApnContext) {
-                    onTrySetupData((ApnContext)msg.obj);
-                } else if (msg.obj instanceof String) {
-                    onTrySetupData((String)msg.obj);
-                } else {
-                    loge("EVENT_TRY_SETUP request w/o apnContext or String");
-                }
-                break;
-
-            case EVENT_CLEAN_UP_CONNECTION:
-                boolean tearDown = (msg.arg1 == 0) ? false : true;
-                if (DBG) log("EVENT_CLEAN_UP_CONNECTION tearDown=" + tearDown);
-                if (msg.obj instanceof ApnContext) {
-                    cleanUpConnection(tearDown, (ApnContext)msg.obj);
-                } else {
-                    loge("EVENT_CLEAN_UP_CONNECTION request w/o apn context");
-                }
-                break;
-            default:
-                // handle the message in the super class DataConnectionTracker
-                super.handleMessage(msg);
-                break;
-        }
-    }
-
-    protected int getApnProfileID(String apnType) {
-        if (TextUtils.equals(apnType, Phone.APN_TYPE_IMS)) {
-            return RILConstants.DATA_PROFILE_IMS;
-        } else if (TextUtils.equals(apnType, Phone.APN_TYPE_FOTA)) {
-            return RILConstants.DATA_PROFILE_FOTA;
-        } else if (TextUtils.equals(apnType, Phone.APN_TYPE_CBS)) {
-            return RILConstants.DATA_PROFILE_CBS;
-        } else {
-            return RILConstants.DATA_PROFILE_DEFAULT;
-        }
-    }
-
-    private int getCellLocationId() {
-        int cid = -1;
-        CellLocation loc = mPhone.getCellLocation();
-
-        if (loc != null) {
-            if (loc instanceof GsmCellLocation) {
-                cid = ((GsmCellLocation)loc).getCid();
-            } else if (loc instanceof CdmaCellLocation) {
-                cid = ((CdmaCellLocation)loc).getBaseStationId();
-            }
-        }
-        return cid;
-    }
-
-    @Override
-    protected void log(String s) {
-        Log.d(LOG_TAG, "[GsmDCT] "+ s);
-    }
-
-    @Override
-    protected void loge(String s) {
-        Log.e(LOG_TAG, "[GsmDCT] " + s);
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("GsmDataConnectionTracker extends:");
-        super.dump(fd, pw, args);
-        pw.println(" RADIO_TESTS=" + RADIO_TESTS);
-        pw.println(" mReregisterOnReconnectFailure=" + mReregisterOnReconnectFailure);
-        pw.println(" mResolver=" + mResolver);
-        pw.println(" canSetPreferApn=" + canSetPreferApn);
-        pw.println(" mApnObserver=" + mApnObserver);
-        pw.println(" getOverallState=" + getOverallState());
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
deleted file mode 100644
index 9b3d5cd..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
+++ /dev/null
@@ -1,1357 +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.internal.telephony.gsm;
-
-import android.content.Context;
-import com.android.internal.telephony.*;
-
-import android.os.*;
-import android.telephony.PhoneNumberUtils;
-import android.text.SpannableStringBuilder;
-import android.text.TextUtils;
-import android.util.Log;
-
-import static com.android.internal.telephony.CommandsInterface.*;
-
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
-
-/**
- * The motto for this file is:
- *
- * "NOTE:    By using the # as a separator, most cases are expected to be unambiguous."
- *   -- TS 22.030 6.5.2
- *
- * {@hide}
- *
- */
-public final class GsmMmiCode extends Handler implements MmiCode {
-    static final String LOG_TAG = "GSM";
-
-    //***** Constants
-
-    // Max Size of the Short Code (aka Short String from TS 22.030 6.5.2)
-    static final int MAX_LENGTH_SHORT_CODE = 2;
-
-    // TS 22.030 6.5.2 Every Short String USSD command will end with #-key
-    // (known as #-String)
-    static final char END_OF_USSD_COMMAND = '#';
-
-    // From TS 22.030 6.5.2
-    static final String ACTION_ACTIVATE = "*";
-    static final String ACTION_DEACTIVATE = "#";
-    static final String ACTION_INTERROGATE = "*#";
-    static final String ACTION_REGISTER = "**";
-    static final String ACTION_ERASURE = "##";
-
-    // Supp Service codes from TS 22.030 Annex B
-
-    //Called line presentation
-    static final String SC_CLIP    = "30";
-    static final String SC_CLIR    = "31";
-
-    // Call Forwarding
-    static final String SC_CFU     = "21";
-    static final String SC_CFB     = "67";
-    static final String SC_CFNRy   = "61";
-    static final String SC_CFNR    = "62";
-
-    static final String SC_CF_All = "002";
-    static final String SC_CF_All_Conditional = "004";
-
-    // Call Waiting
-    static final String SC_WAIT     = "43";
-
-    // Call Barring
-    static final String SC_BAOC         = "33";
-    static final String SC_BAOIC        = "331";
-    static final String SC_BAOICxH      = "332";
-    static final String SC_BAIC         = "35";
-    static final String SC_BAICr        = "351";
-
-    static final String SC_BA_ALL       = "330";
-    static final String SC_BA_MO        = "333";
-    static final String SC_BA_MT        = "353";
-
-    // Supp Service Password registration
-    static final String SC_PWD          = "03";
-
-    // PIN/PIN2/PUK/PUK2
-    static final String SC_PIN          = "04";
-    static final String SC_PIN2         = "042";
-    static final String SC_PUK          = "05";
-    static final String SC_PUK2         = "052";
-
-    //***** Event Constants
-
-    static final int EVENT_SET_COMPLETE         = 1;
-    static final int EVENT_GET_CLIR_COMPLETE    = 2;
-    static final int EVENT_QUERY_CF_COMPLETE    = 3;
-    static final int EVENT_USSD_COMPLETE        = 4;
-    static final int EVENT_QUERY_COMPLETE       = 5;
-    static final int EVENT_SET_CFF_COMPLETE     = 6;
-    static final int EVENT_USSD_CANCEL_COMPLETE = 7;
-
-    //***** Instance Variables
-
-    GSMPhone phone;
-    Context context;
-
-    String action;              // One of ACTION_*
-    String sc;                  // Service Code
-    String sia, sib, sic;       // Service Info a,b,c
-    String poundString;         // Entire MMI string up to and including #
-    String dialingNumber;
-    String pwd;                 // For password registration
-
-    /** Set to true in processCode, not at newFromDialString time */
-    private boolean isPendingUSSD;
-
-    private boolean isUssdRequest;
-
-    State state = State.PENDING;
-    CharSequence message;
-
-    //***** Class Variables
-
-
-    // See TS 22.030 6.5.2 "Structure of the MMI"
-
-    static Pattern sPatternSuppService = Pattern.compile(
-        "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)([^#]*)");
-/*       1  2                    3          4  5       6   7         8    9     10  11             12
-
-         1 = Full string up to and including #
-         2 = action (activation/interrogation/registration/erasure)
-         3 = service code
-         5 = SIA
-         7 = SIB
-         9 = SIC
-         10 = dialing number which must not include #, e.g. *SCn*SI#DN format
-*/
-
-    static final int MATCH_GROUP_POUND_STRING = 1;
-
-    static final int MATCH_GROUP_ACTION = 2;
-                        //(activation/interrogation/registration/erasure)
-
-    static final int MATCH_GROUP_SERVICE_CODE = 3;
-    static final int MATCH_GROUP_SIA = 5;
-    static final int MATCH_GROUP_SIB = 7;
-    static final int MATCH_GROUP_SIC = 9;
-    static final int MATCH_GROUP_PWD_CONFIRM = 11;
-    static final int MATCH_GROUP_DIALING_NUMBER = 12;
-    static private String[] sTwoDigitNumberPattern;
-
-    //***** Public Class methods
-
-    /**
-     * Some dial strings in GSM are defined to do non-call setup
-     * things, such as modify or query supplementary service settings (eg, call
-     * forwarding). These are generally referred to as "MMI codes".
-     * We look to see if the dial string contains a valid MMI code (potentially
-     * with a dial string at the end as well) and return info here.
-     *
-     * If the dial string contains no MMI code, we return an instance with
-     * only "dialingNumber" set
-     *
-     * Please see flow chart in TS 22.030 6.5.3.2
-     */
-
-    static GsmMmiCode
-    newFromDialString(String dialString, GSMPhone phone) {
-        Matcher m;
-        GsmMmiCode ret = null;
-
-        m = sPatternSuppService.matcher(dialString);
-
-        // Is this formatted like a standard supplementary service code?
-        if (m.matches()) {
-            ret = new GsmMmiCode(phone);
-            ret.poundString = makeEmptyNull(m.group(MATCH_GROUP_POUND_STRING));
-            ret.action = makeEmptyNull(m.group(MATCH_GROUP_ACTION));
-            ret.sc = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE));
-            ret.sia = makeEmptyNull(m.group(MATCH_GROUP_SIA));
-            ret.sib = makeEmptyNull(m.group(MATCH_GROUP_SIB));
-            ret.sic = makeEmptyNull(m.group(MATCH_GROUP_SIC));
-            ret.pwd = makeEmptyNull(m.group(MATCH_GROUP_PWD_CONFIRM));
-            ret.dialingNumber = makeEmptyNull(m.group(MATCH_GROUP_DIALING_NUMBER));
-
-        } else if (dialString.endsWith("#")) {
-            // TS 22.030 sec 6.5.3.2
-            // "Entry of any characters defined in the 3GPP TS 23.038 [8] Default Alphabet
-            // (up to the maximum defined in 3GPP TS 24.080 [10]), followed by #SEND".
-
-            ret = new GsmMmiCode(phone);
-            ret.poundString = dialString;
-        } else if (isTwoDigitShortCode(phone.getContext(), dialString)) {
-            //Is a country-specific exception to short codes as defined in TS 22.030, 6.5.3.2
-            ret = null;
-        } else if (isShortCode(dialString, phone)) {
-            // this may be a short code, as defined in TS 22.030, 6.5.3.2
-            ret = new GsmMmiCode(phone);
-            ret.dialingNumber = dialString;
-        }
-
-        return ret;
-    }
-
-    static GsmMmiCode
-    newNetworkInitiatedUssd (String ussdMessage,
-                                boolean isUssdRequest, GSMPhone phone) {
-        GsmMmiCode ret;
-
-        ret = new GsmMmiCode(phone);
-
-        ret.message = ussdMessage;
-        ret.isUssdRequest = isUssdRequest;
-
-        // If it's a request, set to PENDING so that it's cancelable.
-        if (isUssdRequest) {
-            ret.isPendingUSSD = true;
-            ret.state = State.PENDING;
-        } else {
-            ret.state = State.COMPLETE;
-        }
-
-        return ret;
-    }
-
-    static GsmMmiCode newFromUssdUserInput(String ussdMessge, GSMPhone phone) {
-        GsmMmiCode ret = new GsmMmiCode(phone);
-
-        ret.message = ussdMessge;
-        ret.state = State.PENDING;
-        ret.isPendingUSSD = true;
-
-        return ret;
-    }
-
-    //***** Private Class methods
-
-    /** make empty strings be null.
-     *  Regexp returns empty strings for empty groups
-     */
-    private static String
-    makeEmptyNull (String s) {
-        if (s != null && s.length() == 0) return null;
-
-        return s;
-    }
-
-    /** returns true of the string is empty or null */
-    private static boolean
-    isEmptyOrNull(CharSequence s) {
-        return s == null || (s.length() == 0);
-    }
-
-
-    private static int
-    scToCallForwardReason(String sc) {
-        if (sc == null) {
-            throw new RuntimeException ("invalid call forward sc");
-        }
-
-        if (sc.equals(SC_CF_All)) {
-           return CommandsInterface.CF_REASON_ALL;
-        } else if (sc.equals(SC_CFU)) {
-            return CommandsInterface.CF_REASON_UNCONDITIONAL;
-        } else if (sc.equals(SC_CFB)) {
-            return CommandsInterface.CF_REASON_BUSY;
-        } else if (sc.equals(SC_CFNR)) {
-            return CommandsInterface.CF_REASON_NOT_REACHABLE;
-        } else if (sc.equals(SC_CFNRy)) {
-            return CommandsInterface.CF_REASON_NO_REPLY;
-        } else if (sc.equals(SC_CF_All_Conditional)) {
-           return CommandsInterface.CF_REASON_ALL_CONDITIONAL;
-        } else {
-            throw new RuntimeException ("invalid call forward sc");
-        }
-    }
-
-    private static int
-    siToServiceClass(String si) {
-        if (si == null || si.length() == 0) {
-                return  SERVICE_CLASS_NONE;
-        } else {
-            // NumberFormatException should cause MMI fail
-            int serviceCode = Integer.parseInt(si, 10);
-
-            switch (serviceCode) {
-                case 10: return SERVICE_CLASS_SMS + SERVICE_CLASS_FAX  + SERVICE_CLASS_VOICE;
-                case 11: return SERVICE_CLASS_VOICE;
-                case 12: return SERVICE_CLASS_SMS + SERVICE_CLASS_FAX;
-                case 13: return SERVICE_CLASS_FAX;
-
-                case 16: return SERVICE_CLASS_SMS;
-
-                case 19: return SERVICE_CLASS_FAX + SERVICE_CLASS_VOICE;
-/*
-    Note for code 20:
-     From TS 22.030 Annex C:
-                "All GPRS bearer services" are not included in "All tele and bearer services"
-                    and "All bearer services"."
-....so SERVICE_CLASS_DATA, which (according to 27.007) includes GPRS
-*/
-                case 20: return SERVICE_CLASS_DATA_ASYNC + SERVICE_CLASS_DATA_SYNC;
-
-                case 21: return SERVICE_CLASS_PAD + SERVICE_CLASS_DATA_ASYNC;
-                case 22: return SERVICE_CLASS_PACKET + SERVICE_CLASS_DATA_SYNC;
-                case 24: return SERVICE_CLASS_DATA_SYNC;
-                case 25: return SERVICE_CLASS_DATA_ASYNC;
-                case 26: return SERVICE_CLASS_DATA_SYNC + SERVICE_CLASS_VOICE;
-                case 99: return SERVICE_CLASS_PACKET;
-
-                default:
-                    throw new RuntimeException("unsupported MMI service code " + si);
-            }
-        }
-    }
-
-    private static int
-    siToTime (String si) {
-        if (si == null || si.length() == 0) {
-            return 0;
-        } else {
-            // NumberFormatException should cause MMI fail
-            return Integer.parseInt(si, 10);
-        }
-    }
-
-    static boolean
-    isServiceCodeCallForwarding(String sc) {
-        return sc != null &&
-                (sc.equals(SC_CFU)
-                || sc.equals(SC_CFB) || sc.equals(SC_CFNRy)
-                || sc.equals(SC_CFNR) || sc.equals(SC_CF_All)
-                || sc.equals(SC_CF_All_Conditional));
-    }
-
-    static boolean
-    isServiceCodeCallBarring(String sc) {
-        return sc != null &&
-                (sc.equals(SC_BAOC)
-                || sc.equals(SC_BAOIC)
-                || sc.equals(SC_BAOICxH)
-                || sc.equals(SC_BAIC)
-                || sc.equals(SC_BAICr)
-                || sc.equals(SC_BA_ALL)
-                || sc.equals(SC_BA_MO)
-                || sc.equals(SC_BA_MT));
-    }
-
-    static String
-    scToBarringFacility(String sc) {
-        if (sc == null) {
-            throw new RuntimeException ("invalid call barring sc");
-        }
-
-        if (sc.equals(SC_BAOC)) {
-            return CommandsInterface.CB_FACILITY_BAOC;
-        } else if (sc.equals(SC_BAOIC)) {
-            return CommandsInterface.CB_FACILITY_BAOIC;
-        } else if (sc.equals(SC_BAOICxH)) {
-            return CommandsInterface.CB_FACILITY_BAOICxH;
-        } else if (sc.equals(SC_BAIC)) {
-            return CommandsInterface.CB_FACILITY_BAIC;
-        } else if (sc.equals(SC_BAICr)) {
-            return CommandsInterface.CB_FACILITY_BAICr;
-        } else if (sc.equals(SC_BA_ALL)) {
-            return CommandsInterface.CB_FACILITY_BA_ALL;
-        } else if (sc.equals(SC_BA_MO)) {
-            return CommandsInterface.CB_FACILITY_BA_MO;
-        } else if (sc.equals(SC_BA_MT)) {
-            return CommandsInterface.CB_FACILITY_BA_MT;
-        } else {
-            throw new RuntimeException ("invalid call barring sc");
-        }
-    }
-
-    //***** Constructor
-
-    GsmMmiCode (GSMPhone phone) {
-        // The telephony unit-test cases may create GsmMmiCode's
-        // in secondary threads
-        super(phone.getHandler().getLooper());
-        this.phone = phone;
-        this.context = phone.getContext();
-    }
-
-    //***** MmiCode implementation
-
-    public State
-    getState() {
-        return state;
-    }
-
-    public CharSequence
-    getMessage() {
-        return message;
-    }
-
-    // inherited javadoc suffices
-    public void
-    cancel() {
-        // Complete or failed cannot be cancelled
-        if (state == State.COMPLETE || state == State.FAILED) {
-            return;
-        }
-
-        state = State.CANCELLED;
-
-        if (isPendingUSSD) {
-            /*
-             * There can only be one pending USSD session, so tell the radio to
-             * cancel it.
-             */
-            phone.mCM.cancelPendingUssd(obtainMessage(EVENT_USSD_CANCEL_COMPLETE, this));
-
-            /*
-             * Don't call phone.onMMIDone here; wait for CANCEL_COMPLETE notice
-             * from RIL.
-             */
-        } else {
-            // TODO in cases other than USSD, it would be nice to cancel
-            // the pending radio operation. This requires RIL cancellation
-            // support, which does not presently exist.
-
-            phone.onMMIDone (this);
-        }
-
-    }
-
-    public boolean isCancelable() {
-        /* Can only cancel pending USSD sessions. */
-        return isPendingUSSD;
-    }
-
-    //***** Instance Methods
-
-    /** Does this dial string contain a structured or unstructured MMI code? */
-    boolean
-    isMMI() {
-        return poundString != null;
-    }
-
-    /* Is this a 1 or 2 digit "short code" as defined in TS 22.030 sec 6.5.3.2? */
-    boolean
-    isShortCode() {
-        return poundString == null
-                    && dialingNumber != null && dialingNumber.length() <= 2;
-
-    }
-
-    static private boolean
-    isTwoDigitShortCode(Context context, String dialString) {
-        Log.d(LOG_TAG, "isTwoDigitShortCode");
-
-        if (dialString == null || dialString.length() != 2) return false;
-
-        if (sTwoDigitNumberPattern == null) {
-            sTwoDigitNumberPattern = context.getResources().getStringArray(
-                    com.android.internal.R.array.config_twoDigitNumberPattern);
-        }
-
-        for (String dialnumber : sTwoDigitNumberPattern) {
-            Log.d(LOG_TAG, "Two Digit Number Pattern " + dialnumber);
-            if (dialString.equals(dialnumber)) {
-                Log.d(LOG_TAG, "Two Digit Number Pattern -true");
-                return true;
-            }
-        }
-        Log.d(LOG_TAG, "Two Digit Number Pattern -false");
-        return false;
-    }
-
-    /**
-     * Helper function for newFromDialString. Returns true if dialString appears
-     * to be a short code AND conditions are correct for it to be treated as
-     * such.
-     */
-    static private boolean isShortCode(String dialString, GSMPhone phone) {
-        // Refer to TS 22.030 Figure 3.5.3.2:
-        if (dialString == null) {
-            return false;
-        }
-
-        // Illegal dial string characters will give a ZERO length.
-        // At this point we do not want to crash as any application with
-        // call privileges may send a non dial string.
-        // It return false as when the dialString is equal to NULL.
-        if (dialString.length() == 0) {
-            return false;
-        }
-
-        if (PhoneNumberUtils.isLocalEmergencyNumber(dialString, phone.getContext())) {
-            return false;
-        } else {
-            return isShortCodeUSSD(dialString, phone);
-        }
-    }
-
-    /**
-     * Helper function for isShortCode. Returns true if dialString appears to be
-     * a short code and it is a USSD structure
-     *
-     * According to the 3PGG TS 22.030 specification Figure 3.5.3.2: A 1 or 2
-     * digit "short code" is treated as USSD if it is entered while on a call or
-     * does not satisfy the condition (exactly 2 digits && starts with '1'), there
-     * are however exceptions to this rule (see below)
-     *
-     * Exception (1) to Call initiation is: If the user of the device is already in a call
-     * and enters a Short String without any #-key at the end and the length of the Short String is
-     * equal or less then the MAX_LENGTH_SHORT_CODE [constant that is equal to 2]
-     *
-     * The phone shall initiate a USSD/SS commands.
-     *
-     * Exception (2) to Call initiation is: If the user of the device enters one
-     * Digit followed by the #-key. This rule defines this String as the
-     * #-String which is a USSD/SS command.
-     *
-     * The phone shall initiate a USSD/SS command.
-     */
-    static private boolean isShortCodeUSSD(String dialString, GSMPhone phone) {
-        if (dialString != null) {
-            if (phone.isInCall()) {
-                // The maximum length of a Short Code (aka Short String) is 2
-                if (dialString.length() <= MAX_LENGTH_SHORT_CODE) {
-                    return true;
-                }
-            }
-
-            // The maximum length of a Short Code (aka Short String) is 2
-            if (dialString.length() <= MAX_LENGTH_SHORT_CODE) {
-                if (dialString.charAt(dialString.length() - 1) == END_OF_USSD_COMMAND) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * @return true if the Service Code is PIN/PIN2/PUK/PUK2-related
-     */
-    boolean isPinCommand() {
-        return sc != null && (sc.equals(SC_PIN) || sc.equals(SC_PIN2)
-                              || sc.equals(SC_PUK) || sc.equals(SC_PUK2));
-     }
-
-    /**
-     * See TS 22.030 Annex B.
-     * In temporary mode, to suppress CLIR for a single call, enter:
-     *      " * 31 # [called number] SEND "
-     *  In temporary mode, to invoke CLIR for a single call enter:
-     *       " # 31 # [called number] SEND "
-     */
-    boolean
-    isTemporaryModeCLIR() {
-        return sc != null && sc.equals(SC_CLIR) && dialingNumber != null
-                && (isActivate() || isDeactivate());
-    }
-
-    /**
-     * returns CommandsInterface.CLIR_*
-     * See also isTemporaryModeCLIR()
-     */
-    int
-    getCLIRMode() {
-        if (sc != null && sc.equals(SC_CLIR)) {
-            if (isActivate()) {
-                return CommandsInterface.CLIR_SUPPRESSION;
-            } else if (isDeactivate()) {
-                return CommandsInterface.CLIR_INVOCATION;
-            }
-        }
-
-        return CommandsInterface.CLIR_DEFAULT;
-    }
-
-    boolean isActivate() {
-        return action != null && action.equals(ACTION_ACTIVATE);
-    }
-
-    boolean isDeactivate() {
-        return action != null && action.equals(ACTION_DEACTIVATE);
-    }
-
-    boolean isInterrogate() {
-        return action != null && action.equals(ACTION_INTERROGATE);
-    }
-
-    boolean isRegister() {
-        return action != null && action.equals(ACTION_REGISTER);
-    }
-
-    boolean isErasure() {
-        return action != null && action.equals(ACTION_ERASURE);
-    }
-
-    /**
-     * Returns true if this is a USSD code that's been submitted to the
-     * network...eg, after processCode() is called
-     */
-    public boolean isPendingUSSD() {
-        return isPendingUSSD;
-    }
-
-    public boolean isUssdRequest() {
-        return isUssdRequest;
-    }
-
-    /** Process a MMI code or short code...anything that isn't a dialing number */
-    void
-    processCode () {
-        try {
-            if (isShortCode()) {
-                Log.d(LOG_TAG, "isShortCode");
-                // These just get treated as USSD.
-                sendUssd(dialingNumber);
-            } else if (dialingNumber != null) {
-                // We should have no dialing numbers here
-                throw new RuntimeException ("Invalid or Unsupported MMI Code");
-            } else if (sc != null && sc.equals(SC_CLIP)) {
-                Log.d(LOG_TAG, "is CLIP");
-                if (isInterrogate()) {
-                    phone.mCM.queryCLIP(
-                            obtainMessage(EVENT_QUERY_COMPLETE, this));
-                } else {
-                    throw new RuntimeException ("Invalid or Unsupported MMI Code");
-                }
-            } else if (sc != null && sc.equals(SC_CLIR)) {
-                Log.d(LOG_TAG, "is CLIR");
-                if (isActivate()) {
-                    phone.mCM.setCLIR(CommandsInterface.CLIR_INVOCATION,
-                        obtainMessage(EVENT_SET_COMPLETE, this));
-                } else if (isDeactivate()) {
-                    phone.mCM.setCLIR(CommandsInterface.CLIR_SUPPRESSION,
-                        obtainMessage(EVENT_SET_COMPLETE, this));
-                } else if (isInterrogate()) {
-                    phone.mCM.getCLIR(
-                        obtainMessage(EVENT_GET_CLIR_COMPLETE, this));
-                } else {
-                    throw new RuntimeException ("Invalid or Unsupported MMI Code");
-                }
-            } else if (isServiceCodeCallForwarding(sc)) {
-                Log.d(LOG_TAG, "is CF");
-
-                String dialingNumber = sia;
-                int serviceClass = siToServiceClass(sib);
-                int reason = scToCallForwardReason(sc);
-                int time = siToTime(sic);
-
-                if (isInterrogate()) {
-                    phone.mCM.queryCallForwardStatus(
-                            reason, serviceClass,  dialingNumber,
-                                obtainMessage(EVENT_QUERY_CF_COMPLETE, this));
-                } else {
-                    int cfAction;
-
-                    if (isActivate()) {
-                        cfAction = CommandsInterface.CF_ACTION_ENABLE;
-                    } else if (isDeactivate()) {
-                        cfAction = CommandsInterface.CF_ACTION_DISABLE;
-                    } else if (isRegister()) {
-                        cfAction = CommandsInterface.CF_ACTION_REGISTRATION;
-                    } else if (isErasure()) {
-                        cfAction = CommandsInterface.CF_ACTION_ERASURE;
-                    } else {
-                        throw new RuntimeException ("invalid action");
-                    }
-
-                    int isSettingUnconditionalVoice =
-                        (((reason == CommandsInterface.CF_REASON_UNCONDITIONAL) ||
-                                (reason == CommandsInterface.CF_REASON_ALL)) &&
-                                (((serviceClass & CommandsInterface.SERVICE_CLASS_VOICE) != 0) ||
-                                 (serviceClass == CommandsInterface.SERVICE_CLASS_NONE))) ? 1 : 0;
-
-                    int isEnableDesired =
-                        ((cfAction == CommandsInterface.CF_ACTION_ENABLE) ||
-                                (cfAction == CommandsInterface.CF_ACTION_REGISTRATION)) ? 1 : 0;
-
-                    Log.d(LOG_TAG, "is CF setCallForward");
-                    phone.mCM.setCallForward(cfAction, reason, serviceClass,
-                            dialingNumber, time, obtainMessage(
-                                    EVENT_SET_CFF_COMPLETE,
-                                    isSettingUnconditionalVoice,
-                                    isEnableDesired, this));
-                }
-            } else if (isServiceCodeCallBarring(sc)) {
-                // sia = password
-                // sib = basic service group
-
-                String password = sia;
-                int serviceClass = siToServiceClass(sib);
-                String facility = scToBarringFacility(sc);
-
-                if (isInterrogate()) {
-                    phone.mCM.queryFacilityLock(facility, password,
-                            serviceClass, obtainMessage(EVENT_QUERY_COMPLETE, this));
-                } else if (isActivate() || isDeactivate()) {
-                    phone.mCM.setFacilityLock(facility, isActivate(), password,
-                            serviceClass, obtainMessage(EVENT_SET_COMPLETE, this));
-                } else {
-                    throw new RuntimeException ("Invalid or Unsupported MMI Code");
-                }
-
-            } else if (sc != null && sc.equals(SC_PWD)) {
-                // sia = fac
-                // sib = old pwd
-                // sic = new pwd
-                // pwd = new pwd
-                String facility;
-                String oldPwd = sib;
-                String newPwd = sic;
-                if (isActivate() || isRegister()) {
-                    // Even though ACTIVATE is acceptable, this is really termed a REGISTER
-                    action = ACTION_REGISTER;
-
-                    if (sia == null) {
-                        // If sc was not specified, treat it as BA_ALL.
-                        facility = CommandsInterface.CB_FACILITY_BA_ALL;
-                    } else {
-                        facility = scToBarringFacility(sia);
-                    }
-                    if (newPwd.equals(pwd)) {
-                        phone.mCM.changeBarringPassword(facility, oldPwd,
-                                newPwd, obtainMessage(EVENT_SET_COMPLETE, this));
-                    } else {
-                        // password mismatch; return error
-                        handlePasswordError(com.android.internal.R.string.passwordIncorrect);
-                    }
-                } else {
-                    throw new RuntimeException ("Invalid or Unsupported MMI Code");
-                }
-
-            } else if (sc != null && sc.equals(SC_WAIT)) {
-                // sia = basic service group
-                int serviceClass = siToServiceClass(sia);
-
-                if (isActivate() || isDeactivate()) {
-                    phone.mCM.setCallWaiting(isActivate(), serviceClass,
-                            obtainMessage(EVENT_SET_COMPLETE, this));
-                } else if (isInterrogate()) {
-                    phone.mCM.queryCallWaiting(serviceClass,
-                            obtainMessage(EVENT_QUERY_COMPLETE, this));
-                } else {
-                    throw new RuntimeException ("Invalid or Unsupported MMI Code");
-                }
-            } else if (isPinCommand()) {
-                // sia = old PIN or PUK
-                // sib = new PIN
-                // sic = new PIN
-                String oldPinOrPuk = sia;
-                String newPin = sib;
-                int pinLen = newPin.length();
-                if (isRegister()) {
-                    if (!newPin.equals(sic)) {
-                        // password mismatch; return error
-                        handlePasswordError(com.android.internal.R.string.mismatchPin);
-                    } else if (pinLen < 4 || pinLen > 8 ) {
-                        // invalid length
-                        handlePasswordError(com.android.internal.R.string.invalidPin);
-                    } else if (sc.equals(SC_PIN) &&
-                               phone.getIccCard().getState() == IccCard.State.PUK_REQUIRED ) {
-                        // Sim is puk-locked
-                        handlePasswordError(com.android.internal.R.string.needPuk);
-                    } else {
-                        // pre-checks OK
-                        if (sc.equals(SC_PIN)) {
-                            phone.mCM.changeIccPin(oldPinOrPuk, newPin,
-                                    obtainMessage(EVENT_SET_COMPLETE, this));
-                        } else if (sc.equals(SC_PIN2)) {
-                            phone.mCM.changeIccPin2(oldPinOrPuk, newPin,
-                                    obtainMessage(EVENT_SET_COMPLETE, this));
-                        } else if (sc.equals(SC_PUK)) {
-                            phone.mCM.supplyIccPuk(oldPinOrPuk, newPin,
-                                    obtainMessage(EVENT_SET_COMPLETE, this));
-                        } else if (sc.equals(SC_PUK2)) {
-                            phone.mCM.supplyIccPuk2(oldPinOrPuk, newPin,
-                                    obtainMessage(EVENT_SET_COMPLETE, this));
-                        }
-                    }
-                } else {
-                    throw new RuntimeException ("Invalid or Unsupported MMI Code");
-                }
-            } else if (poundString != null) {
-                sendUssd(poundString);
-            } else {
-                throw new RuntimeException ("Invalid or Unsupported MMI Code");
-            }
-        } catch (RuntimeException exc) {
-            state = State.FAILED;
-            message = context.getText(com.android.internal.R.string.mmiError);
-            phone.onMMIDone(this);
-        }
-    }
-
-    private void handlePasswordError(int res) {
-        state = State.FAILED;
-        StringBuilder sb = new StringBuilder(getScString());
-        sb.append("\n");
-        sb.append(context.getText(res));
-        message = sb;
-        phone.onMMIDone(this);
-    }
-
-    /**
-     * Called from GSMPhone
-     *
-     * An unsolicited USSD NOTIFY or REQUEST has come in matching
-     * up with this pending USSD request
-     *
-     * Note: If REQUEST, this exchange is complete, but the session remains
-     *       active (ie, the network expects user input).
-     */
-    void
-    onUssdFinished(String ussdMessage, boolean isUssdRequest) {
-        if (state == State.PENDING) {
-            if (ussdMessage == null) {
-                message = context.getText(com.android.internal.R.string.mmiComplete);
-            } else {
-                message = ussdMessage;
-            }
-            this.isUssdRequest = isUssdRequest;
-            // If it's a request, leave it PENDING so that it's cancelable.
-            if (!isUssdRequest) {
-                state = State.COMPLETE;
-            }
-
-            phone.onMMIDone(this);
-        }
-    }
-
-    /**
-     * Called from GSMPhone
-     *
-     * The radio has reset, and this is still pending
-     */
-
-    void
-    onUssdFinishedError() {
-        if (state == State.PENDING) {
-            state = State.FAILED;
-            message = context.getText(com.android.internal.R.string.mmiError);
-
-            phone.onMMIDone(this);
-        }
-    }
-
-    void sendUssd(String ussdMessage) {
-        // Treat this as a USSD string
-        isPendingUSSD = true;
-
-        // Note that unlike most everything else, the USSD complete
-        // response does not complete this MMI code...we wait for
-        // an unsolicited USSD "Notify" or "Request".
-        // The matching up of this is done in GSMPhone.
-
-        phone.mCM.sendUSSD(ussdMessage,
-            obtainMessage(EVENT_USSD_COMPLETE, this));
-    }
-
-    /** Called from GSMPhone.handleMessage; not a Handler subclass */
-    public void
-    handleMessage (Message msg) {
-        AsyncResult ar;
-
-        switch (msg.what) {
-            case EVENT_SET_COMPLETE:
-                ar = (AsyncResult) (msg.obj);
-
-                onSetComplete(ar);
-                break;
-
-            case EVENT_SET_CFF_COMPLETE:
-                ar = (AsyncResult) (msg.obj);
-
-                /*
-                * msg.arg1 = 1 means to set unconditional voice call forwarding
-                * msg.arg2 = 1 means to enable voice call forwarding
-                */
-                if ((ar.exception == null) && (msg.arg1 == 1)) {
-                    boolean cffEnabled = (msg.arg2 == 1);
-                    phone.mIccRecords.setVoiceCallForwardingFlag(1, cffEnabled);
-                }
-
-                onSetComplete(ar);
-                break;
-
-            case EVENT_GET_CLIR_COMPLETE:
-                ar = (AsyncResult) (msg.obj);
-                onGetClirComplete(ar);
-            break;
-
-            case EVENT_QUERY_CF_COMPLETE:
-                ar = (AsyncResult) (msg.obj);
-                onQueryCfComplete(ar);
-            break;
-
-            case EVENT_QUERY_COMPLETE:
-                ar = (AsyncResult) (msg.obj);
-                onQueryComplete(ar);
-            break;
-
-            case EVENT_USSD_COMPLETE:
-                ar = (AsyncResult) (msg.obj);
-
-                if (ar.exception != null) {
-                    state = State.FAILED;
-                    message = getErrorMessage(ar);
-
-                    phone.onMMIDone(this);
-                }
-
-                // Note that unlike most everything else, the USSD complete
-                // response does not complete this MMI code...we wait for
-                // an unsolicited USSD "Notify" or "Request".
-                // The matching up of this is done in GSMPhone.
-
-            break;
-
-            case EVENT_USSD_CANCEL_COMPLETE:
-                phone.onMMIDone(this);
-            break;
-        }
-    }
-    //***** Private instance methods
-
-    private CharSequence getErrorMessage(AsyncResult ar) {
-
-        if (ar.exception instanceof CommandException) {
-            CommandException.Error err = ((CommandException)(ar.exception)).getCommandError();
-            if (err == CommandException.Error.FDN_CHECK_FAILURE) {
-                Log.i(LOG_TAG, "FDN_CHECK_FAILURE");
-                return context.getText(com.android.internal.R.string.mmiFdnError);
-            }
-        }
-
-        return context.getText(com.android.internal.R.string.mmiError);
-    }
-
-    private CharSequence getScString() {
-        if (sc != null) {
-            if (isServiceCodeCallBarring(sc)) {
-                return context.getText(com.android.internal.R.string.BaMmi);
-            } else if (isServiceCodeCallForwarding(sc)) {
-                return context.getText(com.android.internal.R.string.CfMmi);
-            } else if (sc.equals(SC_CLIP)) {
-                return context.getText(com.android.internal.R.string.ClipMmi);
-            } else if (sc.equals(SC_CLIR)) {
-                return context.getText(com.android.internal.R.string.ClirMmi);
-            } else if (sc.equals(SC_PWD)) {
-                return context.getText(com.android.internal.R.string.PwdMmi);
-            } else if (sc.equals(SC_WAIT)) {
-                return context.getText(com.android.internal.R.string.CwMmi);
-            } else if (isPinCommand()) {
-                return context.getText(com.android.internal.R.string.PinMmi);
-            }
-        }
-
-        return "";
-    }
-
-    private void
-    onSetComplete(AsyncResult ar){
-        StringBuilder sb = new StringBuilder(getScString());
-        sb.append("\n");
-
-        if (ar.exception != null) {
-            state = State.FAILED;
-            if (ar.exception instanceof CommandException) {
-                CommandException.Error err = ((CommandException)(ar.exception)).getCommandError();
-                if (err == CommandException.Error.PASSWORD_INCORRECT) {
-                    if (isPinCommand()) {
-                        // look specifically for the PUK commands and adjust
-                        // the message accordingly.
-                        if (sc.equals(SC_PUK) || sc.equals(SC_PUK2)) {
-                            sb.append(context.getText(
-                                    com.android.internal.R.string.badPuk));
-                        } else {
-                            sb.append(context.getText(
-                                    com.android.internal.R.string.badPin));
-                        }
-                    } else {
-                        sb.append(context.getText(
-                                com.android.internal.R.string.passwordIncorrect));
-                    }
-                } else if (err == CommandException.Error.SIM_PUK2) {
-                    sb.append(context.getText(
-                            com.android.internal.R.string.badPin));
-                    sb.append("\n");
-                    sb.append(context.getText(
-                            com.android.internal.R.string.needPuk2));
-                } else if (err == CommandException.Error.FDN_CHECK_FAILURE) {
-                    Log.i(LOG_TAG, "FDN_CHECK_FAILURE");
-                    sb.append(context.getText(com.android.internal.R.string.mmiFdnError));
-                } else {
-                    sb.append(context.getText(
-                            com.android.internal.R.string.mmiError));
-                }
-            } else {
-                sb.append(context.getText(
-                        com.android.internal.R.string.mmiError));
-            }
-        } else if (isActivate()) {
-            state = State.COMPLETE;
-            sb.append(context.getText(
-                    com.android.internal.R.string.serviceEnabled));
-            // Record CLIR setting
-            if (sc.equals(SC_CLIR)) {
-                phone.saveClirSetting(CommandsInterface.CLIR_INVOCATION);
-            }
-        } else if (isDeactivate()) {
-            state = State.COMPLETE;
-            sb.append(context.getText(
-                    com.android.internal.R.string.serviceDisabled));
-            // Record CLIR setting
-            if (sc.equals(SC_CLIR)) {
-                phone.saveClirSetting(CommandsInterface.CLIR_SUPPRESSION);
-            }
-        } else if (isRegister()) {
-            state = State.COMPLETE;
-            sb.append(context.getText(
-                    com.android.internal.R.string.serviceRegistered));
-        } else if (isErasure()) {
-            state = State.COMPLETE;
-            sb.append(context.getText(
-                    com.android.internal.R.string.serviceErased));
-        } else {
-            state = State.FAILED;
-            sb.append(context.getText(
-                    com.android.internal.R.string.mmiError));
-        }
-
-        message = sb;
-        phone.onMMIDone(this);
-    }
-
-    private void
-    onGetClirComplete(AsyncResult ar) {
-        StringBuilder sb = new StringBuilder(getScString());
-        sb.append("\n");
-
-        if (ar.exception != null) {
-            state = State.FAILED;
-            sb.append(getErrorMessage(ar));
-        } else {
-            int clirArgs[];
-
-            clirArgs = (int[])ar.result;
-
-            // the 'm' parameter from TS 27.007 7.7
-            switch (clirArgs[1]) {
-                case 0: // CLIR not provisioned
-                    sb.append(context.getText(
-                                com.android.internal.R.string.serviceNotProvisioned));
-                    state = State.COMPLETE;
-                break;
-
-                case 1: // CLIR provisioned in permanent mode
-                    sb.append(context.getText(
-                                com.android.internal.R.string.CLIRPermanent));
-                    state = State.COMPLETE;
-                break;
-
-                case 2: // unknown (e.g. no network, etc.)
-                    sb.append(context.getText(
-                                com.android.internal.R.string.mmiError));
-                    state = State.FAILED;
-                break;
-
-                case 3: // CLIR temporary mode presentation restricted
-
-                    // the 'n' parameter from TS 27.007 7.7
-                    switch (clirArgs[0]) {
-                        default:
-                        case 0: // Default
-                            sb.append(context.getText(
-                                    com.android.internal.R.string.CLIRDefaultOnNextCallOn));
-                        break;
-                        case 1: // CLIR invocation
-                            sb.append(context.getText(
-                                    com.android.internal.R.string.CLIRDefaultOnNextCallOn));
-                        break;
-                        case 2: // CLIR suppression
-                            sb.append(context.getText(
-                                    com.android.internal.R.string.CLIRDefaultOnNextCallOff));
-                        break;
-                    }
-                    state = State.COMPLETE;
-                break;
-
-                case 4: // CLIR temporary mode presentation allowed
-                    // the 'n' parameter from TS 27.007 7.7
-                    switch (clirArgs[0]) {
-                        default:
-                        case 0: // Default
-                            sb.append(context.getText(
-                                    com.android.internal.R.string.CLIRDefaultOffNextCallOff));
-                        break;
-                        case 1: // CLIR invocation
-                            sb.append(context.getText(
-                                    com.android.internal.R.string.CLIRDefaultOffNextCallOn));
-                        break;
-                        case 2: // CLIR suppression
-                            sb.append(context.getText(
-                                    com.android.internal.R.string.CLIRDefaultOffNextCallOff));
-                        break;
-                    }
-
-                    state = State.COMPLETE;
-                break;
-            }
-        }
-
-        message = sb;
-        phone.onMMIDone(this);
-    }
-
-    /**
-     * @param serviceClass 1 bit of the service class bit vectory
-     * @return String to be used for call forward query MMI response text.
-     *        Returns null if unrecognized
-     */
-
-    private CharSequence
-    serviceClassToCFString (int serviceClass) {
-        switch (serviceClass) {
-            case SERVICE_CLASS_VOICE:
-                return context.getText(com.android.internal.R.string.serviceClassVoice);
-            case SERVICE_CLASS_DATA:
-                return context.getText(com.android.internal.R.string.serviceClassData);
-            case SERVICE_CLASS_FAX:
-                return context.getText(com.android.internal.R.string.serviceClassFAX);
-            case SERVICE_CLASS_SMS:
-                return context.getText(com.android.internal.R.string.serviceClassSMS);
-            case SERVICE_CLASS_DATA_SYNC:
-                return context.getText(com.android.internal.R.string.serviceClassDataSync);
-            case SERVICE_CLASS_DATA_ASYNC:
-                return context.getText(com.android.internal.R.string.serviceClassDataAsync);
-            case SERVICE_CLASS_PACKET:
-                return context.getText(com.android.internal.R.string.serviceClassPacket);
-            case SERVICE_CLASS_PAD:
-                return context.getText(com.android.internal.R.string.serviceClassPAD);
-            default:
-                return null;
-        }
-    }
-
-
-    /** one CallForwardInfo + serviceClassMask -> one line of text */
-    private CharSequence
-    makeCFQueryResultMessage(CallForwardInfo info, int serviceClassMask) {
-        CharSequence template;
-        String sources[] = {"{0}", "{1}", "{2}"};
-        CharSequence destinations[] = new CharSequence[3];
-        boolean needTimeTemplate;
-
-        // CF_REASON_NO_REPLY also has a time value associated with
-        // it. All others don't.
-
-        needTimeTemplate =
-            (info.reason == CommandsInterface.CF_REASON_NO_REPLY);
-
-        if (info.status == 1) {
-            if (needTimeTemplate) {
-                template = context.getText(
-                        com.android.internal.R.string.cfTemplateForwardedTime);
-            } else {
-                template = context.getText(
-                        com.android.internal.R.string.cfTemplateForwarded);
-            }
-        } else if (info.status == 0 && isEmptyOrNull(info.number)) {
-            template = context.getText(
-                        com.android.internal.R.string.cfTemplateNotForwarded);
-        } else { /* (info.status == 0) && !isEmptyOrNull(info.number) */
-            // A call forward record that is not active but contains
-            // a phone number is considered "registered"
-
-            if (needTimeTemplate) {
-                template = context.getText(
-                        com.android.internal.R.string.cfTemplateRegisteredTime);
-            } else {
-                template = context.getText(
-                        com.android.internal.R.string.cfTemplateRegistered);
-            }
-        }
-
-        // In the template (from strings.xmls)
-        //         {0} is one of "bearerServiceCode*"
-        //        {1} is dialing number
-        //      {2} is time in seconds
-
-        destinations[0] = serviceClassToCFString(info.serviceClass & serviceClassMask);
-        destinations[1] = PhoneNumberUtils.stringFromStringAndTOA(info.number, info.toa);
-        destinations[2] = Integer.toString(info.timeSeconds);
-
-        if (info.reason == CommandsInterface.CF_REASON_UNCONDITIONAL &&
-                (info.serviceClass & serviceClassMask)
-                        == CommandsInterface.SERVICE_CLASS_VOICE) {
-            boolean cffEnabled = (info.status == 1);
-            phone.mIccRecords.setVoiceCallForwardingFlag(1, cffEnabled);
-        }
-
-        return TextUtils.replace(template, sources, destinations);
-    }
-
-
-    private void
-    onQueryCfComplete(AsyncResult ar) {
-        StringBuilder sb = new StringBuilder(getScString());
-        sb.append("\n");
-
-        if (ar.exception != null) {
-            state = State.FAILED;
-            sb.append(getErrorMessage(ar));
-        } else {
-            CallForwardInfo infos[];
-
-            infos = (CallForwardInfo[]) ar.result;
-
-            if (infos.length == 0) {
-                // Assume the default is not active
-                sb.append(context.getText(com.android.internal.R.string.serviceDisabled));
-
-                // Set unconditional CFF in SIM to false
-                phone.mIccRecords.setVoiceCallForwardingFlag(1, false);
-            } else {
-
-                SpannableStringBuilder tb = new SpannableStringBuilder();
-
-                // Each bit in the service class gets its own result line
-                // The service classes may be split up over multiple
-                // CallForwardInfos. So, for each service class, find out
-                // which CallForwardInfo represents it and then build
-                // the response text based on that
-
-                for (int serviceClassMask = 1
-                            ; serviceClassMask <= SERVICE_CLASS_MAX
-                            ; serviceClassMask <<= 1
-                ) {
-                    for (int i = 0, s = infos.length; i < s ; i++) {
-                        if ((serviceClassMask & infos[i].serviceClass) != 0) {
-                            tb.append(makeCFQueryResultMessage(infos[i],
-                                            serviceClassMask));
-                            tb.append("\n");
-                        }
-                    }
-                }
-                sb.append(tb);
-            }
-
-            state = State.COMPLETE;
-        }
-
-        message = sb;
-        phone.onMMIDone(this);
-
-    }
-
-    private void
-    onQueryComplete(AsyncResult ar) {
-        StringBuilder sb = new StringBuilder(getScString());
-        sb.append("\n");
-
-        if (ar.exception != null) {
-            state = State.FAILED;
-            sb.append(getErrorMessage(ar));
-        } else {
-            int[] ints = (int[])ar.result;
-
-            if (ints.length != 0) {
-                if (ints[0] == 0) {
-                    sb.append(context.getText(com.android.internal.R.string.serviceDisabled));
-                } else if (sc.equals(SC_WAIT)) {
-                    // Call Waiting includes additional data in the response.
-                    sb.append(createQueryCallWaitingResultMessage(ints[1]));
-                } else if (isServiceCodeCallBarring(sc)) {
-                    // ints[0] for Call Barring is a bit vector of services
-                    sb.append(createQueryCallBarringResultMessage(ints[0]));
-                } else if (ints[0] == 1) {
-                    // for all other services, treat it as a boolean
-                    sb.append(context.getText(com.android.internal.R.string.serviceEnabled));
-                } else {
-                    sb.append(context.getText(com.android.internal.R.string.mmiError));
-                }
-            } else {
-                sb.append(context.getText(com.android.internal.R.string.mmiError));
-            }
-            state = State.COMPLETE;
-        }
-
-        message = sb;
-        phone.onMMIDone(this);
-    }
-
-    private CharSequence
-    createQueryCallWaitingResultMessage(int serviceClass) {
-        StringBuilder sb =
-                new StringBuilder(context.getText(com.android.internal.R.string.serviceEnabledFor));
-
-        for (int classMask = 1
-                    ; classMask <= SERVICE_CLASS_MAX
-                    ; classMask <<= 1
-        ) {
-            if ((classMask & serviceClass) != 0) {
-                sb.append("\n");
-                sb.append(serviceClassToCFString(classMask & serviceClass));
-            }
-        }
-        return sb;
-    }
-    private CharSequence
-    createQueryCallBarringResultMessage(int serviceClass)
-    {
-        StringBuilder sb = new StringBuilder(context.getText(com.android.internal.R.string.serviceEnabledFor));
-
-        for (int classMask = 1
-                    ; classMask <= SERVICE_CLASS_MAX
-                    ; classMask <<= 1
-        ) {
-            if ((classMask & serviceClass) != 0) {
-                sb.append("\n");
-                sb.append(serviceClassToCFString(classMask & serviceClass));
-            }
-        }
-        return sb;
-    }
-
-    /***
-     * TODO: It would be nice to have a method here that can take in a dialstring and
-     * figure out if there is an MMI code embedded within it.  This code would replace
-     * some of the string parsing functionality in the Phone App's
-     * SpecialCharSequenceMgr class.
-     */
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder("GsmMmiCode {");
-
-        sb.append("State=" + getState());
-        if (action != null) sb.append(" action=" + action);
-        if (sc != null) sb.append(" sc=" + sc);
-        if (sia != null) sb.append(" sia=" + sia);
-        if (sib != null) sb.append(" sib=" + sib);
-        if (sic != null) sb.append(" sic=" + sic);
-        if (poundString != null) sb.append(" poundString=" + poundString);
-        if (dialingNumber != null) sb.append(" dialingNumber=" + dialingNumber);
-        if (pwd != null) sb.append(" pwd=" + pwd);
-        sb.append("}");
-        return sb.toString();
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
deleted file mode 100644
index bfa2bb1..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
+++ /dev/null
@@ -1,472 +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.internal.telephony.gsm;
-
-import android.app.Activity;
-import android.app.PendingIntent;
-import android.app.PendingIntent.CanceledException;
-import android.content.Intent;
-import android.os.AsyncResult;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.provider.Telephony.Sms;
-import android.provider.Telephony.Sms.Intents;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.SmsCbLocation;
-import android.telephony.SmsCbMessage;
-import android.telephony.SmsManager;
-import android.telephony.gsm.GsmCellLocation;
-import android.util.Log;
-
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.SMSDispatcher;
-import com.android.internal.telephony.SmsHeader;
-import com.android.internal.telephony.SmsMessageBase;
-import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails;
-import com.android.internal.telephony.SmsStorageMonitor;
-import com.android.internal.telephony.SmsUsageMonitor;
-import com.android.internal.telephony.TelephonyProperties;
-
-import java.util.HashMap;
-import java.util.Iterator;
-
-import static android.telephony.SmsMessage.MessageClass;
-
-public final class GsmSMSDispatcher extends SMSDispatcher {
-    private static final String TAG = "GSM";
-
-    /** Status report received */
-    private static final int EVENT_NEW_SMS_STATUS_REPORT = 100;
-
-    /** New broadcast SMS */
-    private static final int EVENT_NEW_BROADCAST_SMS = 101;
-
-    /** Result of writing SM to UICC (when SMS-PP service is not available). */
-    private static final int EVENT_WRITE_SMS_COMPLETE = 102;
-
-    /** Handler for SMS-PP data download messages to UICC. */
-    private final UsimDataDownloadHandler mDataDownloadHandler;
-
-    public GsmSMSDispatcher(PhoneBase phone, SmsStorageMonitor storageMonitor,
-            SmsUsageMonitor usageMonitor) {
-        super(phone, storageMonitor, usageMonitor);
-        mDataDownloadHandler = new UsimDataDownloadHandler(mCm);
-        mCm.setOnNewGsmSms(this, EVENT_NEW_SMS, null);
-        mCm.setOnSmsStatus(this, EVENT_NEW_SMS_STATUS_REPORT, null);
-        mCm.setOnNewGsmBroadcastSms(this, EVENT_NEW_BROADCAST_SMS, null);
-    }
-
-    @Override
-    public void dispose() {
-        mCm.unSetOnNewGsmSms(this);
-        mCm.unSetOnSmsStatus(this);
-        mCm.unSetOnNewGsmBroadcastSms(this);
-    }
-
-    @Override
-    protected String getFormat() {
-        return android.telephony.SmsMessage.FORMAT_3GPP;
-    }
-
-    /**
-     * Handles 3GPP format-specific events coming from the phone stack.
-     * Other events are handled by {@link SMSDispatcher#handleMessage}.
-     *
-     * @param msg the message to handle
-     */
-    @Override
-    public void handleMessage(Message msg) {
-        switch (msg.what) {
-        case EVENT_NEW_SMS_STATUS_REPORT:
-            handleStatusReport((AsyncResult) msg.obj);
-            break;
-
-        case EVENT_NEW_BROADCAST_SMS:
-            handleBroadcastSms((AsyncResult)msg.obj);
-            break;
-
-        case EVENT_WRITE_SMS_COMPLETE:
-            AsyncResult ar = (AsyncResult) msg.obj;
-            if (ar.exception == null) {
-                Log.d(TAG, "Successfully wrote SMS-PP message to UICC");
-                mCm.acknowledgeLastIncomingGsmSms(true, 0, null);
-            } else {
-                Log.d(TAG, "Failed to write SMS-PP message to UICC", ar.exception);
-                mCm.acknowledgeLastIncomingGsmSms(false,
-                        CommandsInterface.GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR, null);
-            }
-            break;
-
-        default:
-            super.handleMessage(msg);
-        }
-    }
-
-    /**
-     * Called when a status report is received.  This should correspond to
-     * a previously successful SEND.
-     *
-     * @param ar AsyncResult passed into the message handler.  ar.result should
-     *           be a String representing the status report PDU, as ASCII hex.
-     */
-    private void handleStatusReport(AsyncResult ar) {
-        String pduString = (String) ar.result;
-        SmsMessage sms = SmsMessage.newFromCDS(pduString);
-
-        if (sms != null) {
-            int tpStatus = sms.getStatus();
-            int messageRef = sms.messageRef;
-            for (int i = 0, count = deliveryPendingList.size(); i < count; i++) {
-                SmsTracker tracker = deliveryPendingList.get(i);
-                if (tracker.mMessageRef == messageRef) {
-                    // Found it.  Remove from list and broadcast.
-                    if(tpStatus >= Sms.STATUS_FAILED || tpStatus < Sms.STATUS_PENDING ) {
-                       deliveryPendingList.remove(i);
-                    }
-                    PendingIntent intent = tracker.mDeliveryIntent;
-                    Intent fillIn = new Intent();
-                    fillIn.putExtra("pdu", IccUtils.hexStringToBytes(pduString));
-                    fillIn.putExtra("format", android.telephony.SmsMessage.FORMAT_3GPP);
-                    try {
-                        intent.send(mContext, Activity.RESULT_OK, fillIn);
-                    } catch (CanceledException ex) {}
-
-                    // Only expect to see one tracker matching this messageref
-                    break;
-                }
-            }
-        }
-        acknowledgeLastIncomingSms(true, Intents.RESULT_SMS_HANDLED, null);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int dispatchMessage(SmsMessageBase smsb) {
-
-        // If sms is null, means there was a parsing error.
-        if (smsb == null) {
-            Log.e(TAG, "dispatchMessage: message is null");
-            return Intents.RESULT_SMS_GENERIC_ERROR;
-        }
-
-        SmsMessage sms = (SmsMessage) smsb;
-
-        if (sms.isTypeZero()) {
-            // As per 3GPP TS 23.040 9.2.3.9, Type Zero messages should not be
-            // Displayed/Stored/Notified. They should only be acknowledged.
-            Log.d(TAG, "Received short message type 0, Don't display or store it. Send Ack");
-            return Intents.RESULT_SMS_HANDLED;
-        }
-
-        // Send SMS-PP data download messages to UICC. See 3GPP TS 31.111 section 7.1.1.
-        if (sms.isUsimDataDownload()) {
-            UsimServiceTable ust = mPhone.getUsimServiceTable();
-            // If we receive an SMS-PP message before the UsimServiceTable has been loaded,
-            // assume that the data download service is not present. This is very unlikely to
-            // happen because the IMS connection will not be established until after the ISIM
-            // records have been loaded, after the USIM service table has been loaded.
-            if (ust != null && ust.isAvailable(
-                    UsimServiceTable.UsimService.DATA_DL_VIA_SMS_PP)) {
-                Log.d(TAG, "Received SMS-PP data download, sending to UICC.");
-                return mDataDownloadHandler.startDataDownload(sms);
-            } else {
-                Log.d(TAG, "DATA_DL_VIA_SMS_PP service not available, storing message to UICC.");
-                String smsc = IccUtils.bytesToHexString(
-                        PhoneNumberUtils.networkPortionToCalledPartyBCDWithLength(
-                                sms.getServiceCenterAddress()));
-                mCm.writeSmsToSim(SmsManager.STATUS_ON_ICC_UNREAD, smsc,
-                        IccUtils.bytesToHexString(sms.getPdu()),
-                        obtainMessage(EVENT_WRITE_SMS_COMPLETE));
-                return Activity.RESULT_OK;  // acknowledge after response from write to USIM
-            }
-        }
-
-        if (mSmsReceiveDisabled) {
-            // Device doesn't support SMS service,
-            Log.d(TAG, "Received short message on device which doesn't support "
-                    + "SMS service. Ignored.");
-            return Intents.RESULT_SMS_HANDLED;
-        }
-
-        // Special case the message waiting indicator messages
-        boolean handled = false;
-        if (sms.isMWISetMessage()) {
-            mPhone.setVoiceMessageWaiting(1, -1);  // line 1: unknown number of msgs waiting
-            handled = sms.isMwiDontStore();
-            if (false) {
-                Log.d(TAG, "Received voice mail indicator set SMS shouldStore=" + !handled);
-            }
-        } else if (sms.isMWIClearMessage()) {
-            mPhone.setVoiceMessageWaiting(1, 0);   // line 1: no msgs waiting
-            handled = sms.isMwiDontStore();
-            if (false) {
-                Log.d(TAG, "Received voice mail indicator clear SMS shouldStore=" + !handled);
-            }
-        }
-
-        if (handled) {
-            return Intents.RESULT_SMS_HANDLED;
-        }
-
-        if (!mStorageMonitor.isStorageAvailable() &&
-                sms.getMessageClass() != MessageClass.CLASS_0) {
-            // It's a storable message and there's no storage available.  Bail.
-            // (See TS 23.038 for a description of class 0 messages.)
-            return Intents.RESULT_SMS_OUT_OF_MEMORY;
-        }
-
-        return dispatchNormalMessage(smsb);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void sendData(String destAddr, String scAddr, int destPort,
-            byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
-        SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
-                scAddr, destAddr, destPort, data, (deliveryIntent != null));
-        if (pdu != null) {
-            sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent,
-                    destAddr);
-        } else {
-            Log.e(TAG, "GsmSMSDispatcher.sendData(): getSubmitPdu() returned null");
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void sendText(String destAddr, String scAddr, String text,
-            PendingIntent sentIntent, PendingIntent deliveryIntent) {
-        SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
-                scAddr, destAddr, text, (deliveryIntent != null));
-        if (pdu != null) {
-            sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent,
-                    destAddr);
-        } else {
-            Log.e(TAG, "GsmSMSDispatcher.sendText(): getSubmitPdu() returned null");
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected TextEncodingDetails calculateLength(CharSequence messageBody,
-            boolean use7bitOnly) {
-        return SmsMessage.calculateLength(messageBody, use7bitOnly);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void sendNewSubmitPdu(String destinationAddress, String scAddress,
-            String message, SmsHeader smsHeader, int encoding,
-            PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart) {
-        SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(scAddress, destinationAddress,
-                message, deliveryIntent != null, SmsHeader.toByteArray(smsHeader),
-                encoding, smsHeader.languageTable, smsHeader.languageShiftTable);
-        if (pdu != null) {
-            sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent,
-                    destinationAddress);
-        } else {
-            Log.e(TAG, "GsmSMSDispatcher.sendNewSubmitPdu(): getSubmitPdu() returned null");
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void sendSms(SmsTracker tracker) {
-        HashMap<String, Object> map = tracker.mData;
-
-        byte smsc[] = (byte[]) map.get("smsc");
-        byte pdu[] = (byte[]) map.get("pdu");
-
-        Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker);
-        mCm.sendSMS(IccUtils.bytesToHexString(smsc), IccUtils.bytesToHexString(pdu), reply);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void acknowledgeLastIncomingSms(boolean success, int result, Message response) {
-        mCm.acknowledgeLastIncomingGsmSms(success, resultToCause(result), response);
-    }
-
-    private static int resultToCause(int rc) {
-        switch (rc) {
-            case Activity.RESULT_OK:
-            case Intents.RESULT_SMS_HANDLED:
-                // Cause code is ignored on success.
-                return 0;
-            case Intents.RESULT_SMS_OUT_OF_MEMORY:
-                return CommandsInterface.GSM_SMS_FAIL_CAUSE_MEMORY_CAPACITY_EXCEEDED;
-            case Intents.RESULT_SMS_GENERIC_ERROR:
-            default:
-                return CommandsInterface.GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR;
-        }
-    }
-
-    /**
-     * Holds all info about a message page needed to assemble a complete
-     * concatenated message
-     */
-    private static final class SmsCbConcatInfo {
-
-        private final SmsCbHeader mHeader;
-        private final SmsCbLocation mLocation;
-
-        public SmsCbConcatInfo(SmsCbHeader header, SmsCbLocation location) {
-            mHeader = header;
-            mLocation = location;
-        }
-
-        @Override
-        public int hashCode() {
-            return (mHeader.getSerialNumber() * 31) + mLocation.hashCode();
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj instanceof SmsCbConcatInfo) {
-                SmsCbConcatInfo other = (SmsCbConcatInfo)obj;
-
-                // Two pages match if they have the same serial number (which includes the
-                // geographical scope and update number), and both pages belong to the same
-                // location (PLMN, plus LAC and CID if these are part of the geographical scope).
-                return mHeader.getSerialNumber() == other.mHeader.getSerialNumber()
-                        && mLocation.equals(other.mLocation);
-            }
-
-            return false;
-        }
-
-        /**
-         * Compare the location code for this message to the current location code. The match is
-         * relative to the geographical scope of the message, which determines whether the LAC
-         * and Cell ID are saved in mLocation or set to -1 to match all values.
-         *
-         * @param plmn the current PLMN
-         * @param lac the current Location Area (GSM) or Service Area (UMTS)
-         * @param cid the current Cell ID
-         * @return true if this message is valid for the current location; false otherwise
-         */
-        public boolean matchesLocation(String plmn, int lac, int cid) {
-            return mLocation.isInLocationArea(plmn, lac, cid);
-        }
-    }
-
-    // This map holds incomplete concatenated messages waiting for assembly
-    private final HashMap<SmsCbConcatInfo, byte[][]> mSmsCbPageMap =
-            new HashMap<SmsCbConcatInfo, byte[][]>();
-
-    /**
-     * Handle 3GPP format SMS-CB message.
-     * @param ar the AsyncResult containing the received PDUs
-     */
-    private void handleBroadcastSms(AsyncResult ar) {
-        try {
-            byte[] receivedPdu = (byte[])ar.result;
-
-            if (false) {
-                for (int i = 0; i < receivedPdu.length; i += 8) {
-                    StringBuilder sb = new StringBuilder("SMS CB pdu data: ");
-                    for (int j = i; j < i + 8 && j < receivedPdu.length; j++) {
-                        int b = receivedPdu[j] & 0xff;
-                        if (b < 0x10) {
-                            sb.append('0');
-                        }
-                        sb.append(Integer.toHexString(b)).append(' ');
-                    }
-                    Log.d(TAG, sb.toString());
-                }
-            }
-
-            SmsCbHeader header = new SmsCbHeader(receivedPdu);
-            String plmn = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC);
-            GsmCellLocation cellLocation = (GsmCellLocation) mPhone.getCellLocation();
-            int lac = cellLocation.getLac();
-            int cid = cellLocation.getCid();
-
-            SmsCbLocation location;
-            switch (header.getGeographicalScope()) {
-                case SmsCbMessage.GEOGRAPHICAL_SCOPE_LA_WIDE:
-                    location = new SmsCbLocation(plmn, lac, -1);
-                    break;
-
-                case SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE:
-                case SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE:
-                    location = new SmsCbLocation(plmn, lac, cid);
-                    break;
-
-                case SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE:
-                default:
-                    location = new SmsCbLocation(plmn);
-                    break;
-            }
-
-            byte[][] pdus;
-            int pageCount = header.getNumberOfPages();
-            if (pageCount > 1) {
-                // Multi-page message
-                SmsCbConcatInfo concatInfo = new SmsCbConcatInfo(header, location);
-
-                // Try to find other pages of the same message
-                pdus = mSmsCbPageMap.get(concatInfo);
-
-                if (pdus == null) {
-                    // This is the first page of this message, make room for all
-                    // pages and keep until complete
-                    pdus = new byte[pageCount][];
-
-                    mSmsCbPageMap.put(concatInfo, pdus);
-                }
-
-                // Page parameter is one-based
-                pdus[header.getPageIndex() - 1] = receivedPdu;
-
-                for (int i = 0; i < pdus.length; i++) {
-                    if (pdus[i] == null) {
-                        // Still missing pages, exit
-                        return;
-                    }
-                }
-
-                // Message complete, remove and dispatch
-                mSmsCbPageMap.remove(concatInfo);
-            } else {
-                // Single page message
-                pdus = new byte[1][];
-                pdus[0] = receivedPdu;
-            }
-
-            SmsCbMessage message = GsmSmsCbMessage.createSmsCbMessage(header, location, pdus);
-            dispatchBroadcastMessage(message);
-
-            // Remove messages that are out of scope to prevent the map from
-            // growing indefinitely, containing incomplete messages that were
-            // never assembled
-            Iterator<SmsCbConcatInfo> iter = mSmsCbPageMap.keySet().iterator();
-
-            while (iter.hasNext()) {
-                SmsCbConcatInfo info = iter.next();
-
-                if (!info.matchesLocation(plmn, lac, cid)) {
-                    iter.remove();
-                }
-            }
-        } catch (RuntimeException e) {
-            Log.e(TAG, "Error in decoding SMS CB pdu", e);
-        }
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
deleted file mode 100644
index 4896efb..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ /dev/null
@@ -1,1727 +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.internal.telephony.gsm;
-
-import com.android.internal.telephony.CommandException;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.DataConnectionTracker;
-import com.android.internal.telephony.EventLogTags;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccCardStatus;
-import com.android.internal.telephony.MccTable;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.RestrictedState;
-import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.ServiceStateTracker;
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.telephony.TelephonyProperties;
-
-import android.app.AlarmManager;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.database.ContentObserver;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
-import android.provider.Telephony.Intents;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.telephony.gsm.GsmCellLocation;
-import android.text.TextUtils;
-import android.util.EventLog;
-import android.util.Log;
-import android.util.TimeUtils;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.TimeZone;
-
-/**
- * {@hide}
- */
-final class GsmServiceStateTracker extends ServiceStateTracker {
-    static final String LOG_TAG = "GSM";
-    static final boolean DBG = true;
-
-    GSMPhone phone;
-    GsmCellLocation cellLoc;
-    GsmCellLocation newCellLoc;
-    int mPreferredNetworkType;
-
-    private int gprsState = ServiceState.STATE_OUT_OF_SERVICE;
-    private int newGPRSState = ServiceState.STATE_OUT_OF_SERVICE;
-    private int mMaxDataCalls = 1;
-    private int mNewMaxDataCalls = 1;
-    private int mReasonDataDenied = -1;
-    private int mNewReasonDataDenied = -1;
-
-    /**
-     * GSM roaming status solely based on TS 27.007 7.2 CREG. Only used by
-     * handlePollStateResult to store CREG roaming result.
-     */
-    private boolean mGsmRoaming = false;
-
-    /**
-     * Data roaming status solely based on TS 27.007 10.1.19 CGREG. Only used by
-     * handlePollStateResult to store CGREG roaming result.
-     */
-    private boolean mDataRoaming = false;
-
-    /**
-     * Mark when service state is in emergency call only mode
-     */
-    private boolean mEmergencyOnly = false;
-
-    /**
-     * Sometimes we get the NITZ time before we know what country we
-     * are in. Keep the time zone information from the NITZ string so
-     * we can fix the time zone once know the country.
-     */
-    private boolean mNeedFixZoneAfterNitz = false;
-    private int mZoneOffset;
-    private boolean mZoneDst;
-    private long mZoneTime;
-    private boolean mGotCountryCode = false;
-    private ContentResolver cr;
-
-    /** Boolean is true is setTimeFromNITZString was called */
-    private boolean mNitzUpdatedTime = false;
-
-    String mSavedTimeZone;
-    long mSavedTime;
-    long mSavedAtTime;
-
-    /**
-     * We can't register for SIM_RECORDS_LOADED immediately because the
-     * SIMRecords object may not be instantiated yet.
-     */
-    private boolean mNeedToRegForSimLoaded;
-
-    /** Started the recheck process after finding gprs should registered but not. */
-    private boolean mStartedGprsRegCheck = false;
-
-    /** Already sent the event-log for no gprs register. */
-    private boolean mReportedGprsNoReg = false;
-
-    /**
-     * The Notification object given to the NotificationManager.
-     */
-    private Notification mNotification;
-
-    /** Wake lock used while setting time of day. */
-    private PowerManager.WakeLock mWakeLock;
-    private static final String WAKELOCK_TAG = "ServiceStateTracker";
-
-    /** Keep track of SPN display rules, so we only broadcast intent if something changes. */
-    private String curSpn = null;
-    private String curPlmn = null;
-    private int curSpnRule = 0;
-
-    /** waiting period before recheck gprs and voice registration. */
-    static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000;
-
-    /** Notification type. */
-    static final int PS_ENABLED = 1001;            // Access Control blocks data service
-    static final int PS_DISABLED = 1002;           // Access Control enables data service
-    static final int CS_ENABLED = 1003;            // Access Control blocks all voice/sms service
-    static final int CS_DISABLED = 1004;           // Access Control enables all voice/sms service
-    static final int CS_NORMAL_ENABLED = 1005;     // Access Control blocks normal voice/sms service
-    static final int CS_EMERGENCY_ENABLED = 1006;  // Access Control blocks emergency call service
-
-    /** Notification id. */
-    static final int PS_NOTIFICATION = 888;  // Id to update and cancel PS restricted
-    static final int CS_NOTIFICATION = 999;  // Id to update and cancel CS restricted
-
-    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(Intent.ACTION_LOCALE_CHANGED)) {
-                // update emergency string whenever locale changed
-                updateSpnDisplay();
-            }
-        }
-    };
-
-    private ContentObserver mAutoTimeObserver = new ContentObserver(new Handler()) {
-        @Override
-        public void onChange(boolean selfChange) {
-            Log.i("GsmServiceStateTracker", "Auto time state changed");
-            revertToNitzTime();
-        }
-    };
-
-    private ContentObserver mAutoTimeZoneObserver = new ContentObserver(new Handler()) {
-        @Override
-        public void onChange(boolean selfChange) {
-            Log.i("GsmServiceStateTracker", "Auto time zone state changed");
-            revertToNitzTimeZone();
-        }
-    };
-
-    public GsmServiceStateTracker(GSMPhone phone) {
-        super();
-
-        this.phone = phone;
-        cm = phone.mCM;
-        ss = new ServiceState();
-        newSS = new ServiceState();
-        cellLoc = new GsmCellLocation();
-        newCellLoc = new GsmCellLocation();
-        mSignalStrength = new SignalStrength();
-
-        PowerManager powerManager =
-                (PowerManager)phone.getContext().getSystemService(Context.POWER_SERVICE);
-        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG);
-
-        cm.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
-        cm.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
-
-        cm.registerForVoiceNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED, null);
-        cm.setOnNITZTime(this, EVENT_NITZ_TIME, null);
-        cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
-        cm.setOnRestrictedStateChanged(this, EVENT_RESTRICTED_STATE_CHANGED, null);
-        phone.getIccCard().registerForReady(this, EVENT_SIM_READY, null);
-
-        // system setting property AIRPLANE_MODE_ON is set in Settings.
-        int airplaneMode = Settings.System.getInt(
-                phone.getContext().getContentResolver(),
-                Settings.System.AIRPLANE_MODE_ON, 0);
-        mDesiredPowerState = ! (airplaneMode > 0);
-
-        cr = phone.getContext().getContentResolver();
-        cr.registerContentObserver(
-                Settings.System.getUriFor(Settings.System.AUTO_TIME), true,
-                mAutoTimeObserver);
-        cr.registerContentObserver(
-                Settings.System.getUriFor(Settings.System.AUTO_TIME_ZONE), true,
-                mAutoTimeZoneObserver);
-
-        setSignalStrengthDefaultValues();
-        mNeedToRegForSimLoaded = true;
-
-        // Monitor locale change
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_LOCALE_CHANGED);
-        phone.getContext().registerReceiver(mIntentReceiver, filter);
-
-        // Gsm doesn't support OTASP so its not needed
-        phone.notifyOtaspChanged(OTASP_NOT_NEEDED);
-    }
-
-    public void dispose() {
-        // Unregister for all events.
-        cm.unregisterForAvailable(this);
-        cm.unregisterForRadioStateChanged(this);
-        cm.unregisterForVoiceNetworkStateChanged(this);
-        phone.getIccCard().unregisterForReady(this);
-        phone.mIccRecords.unregisterForRecordsLoaded(this);
-        cm.unSetOnSignalStrengthUpdate(this);
-        cm.unSetOnRestrictedStateChanged(this);
-        cm.unSetOnNITZTime(this);
-        cr.unregisterContentObserver(this.mAutoTimeObserver);
-        cr.unregisterContentObserver(this.mAutoTimeZoneObserver);
-    }
-
-    protected void finalize() {
-        if(DBG) log("finalize");
-    }
-
-    @Override
-    protected Phone getPhone() {
-        return phone;
-    }
-
-    public void handleMessage (Message msg) {
-        AsyncResult ar;
-        int[] ints;
-        String[] strings;
-        Message message;
-
-        if (!phone.mIsTheCurrentActivePhone) {
-            Log.e(LOG_TAG, "Received message " + msg +
-                    "[" + msg.what + "] while being destroyed. Ignoring.");
-            return;
-        }
-        switch (msg.what) {
-            case EVENT_RADIO_AVAILABLE:
-                //this is unnecessary
-                //setPowerStateToDesired();
-                break;
-
-            case EVENT_SIM_READY:
-                // Set the network type, in case the radio does not restore it.
-                cm.setCurrentPreferredNetworkType();
-
-                // The SIM is now ready i.e if it was locked
-                // it has been unlocked. At this stage, the radio is already
-                // powered on.
-                if (mNeedToRegForSimLoaded) {
-                    phone.mIccRecords.registerForRecordsLoaded(this,
-                            EVENT_SIM_RECORDS_LOADED, null);
-                    mNeedToRegForSimLoaded = false;
-                }
-
-                boolean skipRestoringSelection = phone.getContext().getResources().getBoolean(
-                        com.android.internal.R.bool.skip_restoring_network_selection);
-
-                if (!skipRestoringSelection) {
-                    // restore the previous network selection.
-                    phone.restoreSavedNetworkSelection(null);
-                }
-                pollState();
-                // Signal strength polling stops when radio is off
-                queueNextSignalStrengthPoll();
-                break;
-
-            case EVENT_RADIO_STATE_CHANGED:
-                // This will do nothing in the radio not
-                // available case
-                setPowerStateToDesired();
-                pollState();
-                break;
-
-            case EVENT_NETWORK_STATE_CHANGED:
-                pollState();
-                break;
-
-            case EVENT_GET_SIGNAL_STRENGTH:
-                // This callback is called when signal strength is polled
-                // all by itself
-
-                if (!(cm.getRadioState().isOn())) {
-                    // Polling will continue when radio turns back on
-                    return;
-                }
-                ar = (AsyncResult) msg.obj;
-                onSignalStrengthResult(ar);
-                queueNextSignalStrengthPoll();
-
-                break;
-
-            case EVENT_GET_LOC_DONE:
-                ar = (AsyncResult) msg.obj;
-
-                if (ar.exception == null) {
-                    String states[] = (String[])ar.result;
-                    int lac = -1;
-                    int cid = -1;
-                    if (states.length >= 3) {
-                        try {
-                            if (states[1] != null && states[1].length() > 0) {
-                                lac = Integer.parseInt(states[1], 16);
-                            }
-                            if (states[2] != null && states[2].length() > 0) {
-                                cid = Integer.parseInt(states[2], 16);
-                            }
-                        } catch (NumberFormatException ex) {
-                            Log.w(LOG_TAG, "error parsing location: " + ex);
-                        }
-                    }
-                    cellLoc.setLacAndCid(lac, cid);
-                    phone.notifyLocationChanged();
-                }
-
-                // Release any temporary cell lock, which could have been
-                // acquired to allow a single-shot location update.
-                disableSingleLocationUpdate();
-                break;
-
-            case EVENT_POLL_STATE_REGISTRATION:
-            case EVENT_POLL_STATE_GPRS:
-            case EVENT_POLL_STATE_OPERATOR:
-            case EVENT_POLL_STATE_NETWORK_SELECTION_MODE:
-                ar = (AsyncResult) msg.obj;
-
-                handlePollStateResult(msg.what, ar);
-                break;
-
-            case EVENT_POLL_SIGNAL_STRENGTH:
-                // Just poll signal strength...not part of pollState()
-
-                cm.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
-                break;
-
-            case EVENT_NITZ_TIME:
-                ar = (AsyncResult) msg.obj;
-
-                String nitzString = (String)((Object[])ar.result)[0];
-                long nitzReceiveTime = ((Long)((Object[])ar.result)[1]).longValue();
-
-                setTimeFromNITZString(nitzString, nitzReceiveTime);
-                break;
-
-            case EVENT_SIGNAL_STRENGTH_UPDATE:
-                // This is a notification from
-                // CommandsInterface.setOnSignalStrengthUpdate
-
-                ar = (AsyncResult) msg.obj;
-
-                // The radio is telling us about signal strength changes
-                // we don't have to ask it
-                dontPollSignalStrength = true;
-
-                onSignalStrengthResult(ar);
-                break;
-
-            case EVENT_SIM_RECORDS_LOADED:
-                updateSpnDisplay();
-                break;
-
-            case EVENT_LOCATION_UPDATES_ENABLED:
-                ar = (AsyncResult) msg.obj;
-
-                if (ar.exception == null) {
-                    cm.getVoiceRegistrationState(obtainMessage(EVENT_GET_LOC_DONE, null));
-                }
-                break;
-
-            case EVENT_SET_PREFERRED_NETWORK_TYPE:
-                ar = (AsyncResult) msg.obj;
-                // Don't care the result, only use for dereg network (COPS=2)
-                message = obtainMessage(EVENT_RESET_PREFERRED_NETWORK_TYPE, ar.userObj);
-                cm.setPreferredNetworkType(mPreferredNetworkType, message);
-                break;
-
-            case EVENT_RESET_PREFERRED_NETWORK_TYPE:
-                ar = (AsyncResult) msg.obj;
-                if (ar.userObj != null) {
-                    AsyncResult.forMessage(((Message) ar.userObj)).exception
-                            = ar.exception;
-                    ((Message) ar.userObj).sendToTarget();
-                }
-                break;
-
-            case EVENT_GET_PREFERRED_NETWORK_TYPE:
-                ar = (AsyncResult) msg.obj;
-
-                if (ar.exception == null) {
-                    mPreferredNetworkType = ((int[])ar.result)[0];
-                } else {
-                    mPreferredNetworkType = RILConstants.NETWORK_MODE_GLOBAL;
-                }
-
-                message = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE, ar.userObj);
-                int toggledNetworkType = RILConstants.NETWORK_MODE_GLOBAL;
-
-                cm.setPreferredNetworkType(toggledNetworkType, message);
-                break;
-
-            case EVENT_CHECK_REPORT_GPRS:
-                if (ss != null && !isGprsConsistent(gprsState, ss.getState())) {
-
-                    // Can't register data service while voice service is ok
-                    // i.e. CREG is ok while CGREG is not
-                    // possible a network or baseband side error
-                    GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation());
-                    EventLog.writeEvent(EventLogTags.DATA_NETWORK_REGISTRATION_FAIL,
-                            ss.getOperatorNumeric(), loc != null ? loc.getCid() : -1);
-                    mReportedGprsNoReg = true;
-                }
-                mStartedGprsRegCheck = false;
-                break;
-
-            case EVENT_RESTRICTED_STATE_CHANGED:
-                // This is a notification from
-                // CommandsInterface.setOnRestrictedStateChanged
-
-                if (DBG) log("EVENT_RESTRICTED_STATE_CHANGED");
-
-                ar = (AsyncResult) msg.obj;
-
-                onRestrictedStateChanged(ar);
-                break;
-
-            default:
-                super.handleMessage(msg);
-            break;
-        }
-    }
-
-    protected void setPowerStateToDesired() {
-        // If we want it on and it's off, turn it on
-        if (mDesiredPowerState
-            && cm.getRadioState() == CommandsInterface.RadioState.RADIO_OFF) {
-            cm.setRadioPower(true, null);
-        } else if (!mDesiredPowerState && cm.getRadioState().isOn()) {
-            // If it's on and available and we want it off gracefully
-            DataConnectionTracker dcTracker = phone.mDataConnectionTracker;
-            powerOffRadioSafely(dcTracker);
-        } // Otherwise, we're in the desired state
-    }
-
-    @Override
-    protected void hangupAndPowerOff() {
-        // hang up all active voice calls
-        if (phone.isInCall()) {
-            phone.mCT.ringingCall.hangupIfAlive();
-            phone.mCT.backgroundCall.hangupIfAlive();
-            phone.mCT.foregroundCall.hangupIfAlive();
-        }
-
-        cm.setRadioPower(false, null);
-    }
-
-    protected void updateSpnDisplay() {
-        int rule = phone.mIccRecords.getDisplayRule(ss.getOperatorNumeric());
-        String spn = phone.mIccRecords.getServiceProviderName();
-        String plmn = ss.getOperatorAlphaLong();
-
-        // For emergency calls only, pass the EmergencyCallsOnly string via EXTRA_PLMN
-        if (mEmergencyOnly && cm.getRadioState().isOn()) {
-            plmn = Resources.getSystem().
-                getText(com.android.internal.R.string.emergency_calls_only).toString();
-            if (DBG) log("updateSpnDisplay: emergency only and radio is on plmn='" + plmn + "'");
-        }
-
-        if (rule != curSpnRule
-                || !TextUtils.equals(spn, curSpn)
-                || !TextUtils.equals(plmn, curPlmn)) {
-            boolean showSpn = !mEmergencyOnly && !TextUtils.isEmpty(spn)
-                && (rule & SIMRecords.SPN_RULE_SHOW_SPN) == SIMRecords.SPN_RULE_SHOW_SPN;
-            boolean showPlmn = !TextUtils.isEmpty(plmn) && (mEmergencyOnly ||
-                ((rule & SIMRecords.SPN_RULE_SHOW_PLMN) == SIMRecords.SPN_RULE_SHOW_PLMN));
-
-            if (DBG) {
-                log(String.format("updateSpnDisplay: changed sending intent" + " rule=" + rule +
-                            " showPlmn='%b' plmn='%s' showSpn='%b' spn='%s'",
-                            showPlmn, plmn, showSpn, spn));
-            }
-            Intent intent = new Intent(Intents.SPN_STRINGS_UPDATED_ACTION);
-            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
-            intent.putExtra(Intents.EXTRA_SHOW_SPN, showSpn);
-            intent.putExtra(Intents.EXTRA_SPN, spn);
-            intent.putExtra(Intents.EXTRA_SHOW_PLMN, showPlmn);
-            intent.putExtra(Intents.EXTRA_PLMN, plmn);
-            phone.getContext().sendStickyBroadcast(intent);
-        }
-
-        curSpnRule = rule;
-        curSpn = spn;
-        curPlmn = plmn;
-    }
-
-    /**
-     * Handle the result of one of the pollState()-related requests
-     */
-    protected void handlePollStateResult (int what, AsyncResult ar) {
-        int ints[];
-        String states[];
-
-        // Ignore stale requests from last poll
-        if (ar.userObj != pollingContext) return;
-
-        if (ar.exception != null) {
-            CommandException.Error err=null;
-
-            if (ar.exception instanceof CommandException) {
-                err = ((CommandException)(ar.exception)).getCommandError();
-            }
-
-            if (err == CommandException.Error.RADIO_NOT_AVAILABLE) {
-                // Radio has crashed or turned off
-                cancelPollState();
-                return;
-            }
-
-            if (!cm.getRadioState().isOn()) {
-                // Radio has crashed or turned off
-                cancelPollState();
-                return;
-            }
-
-            if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) {
-                loge("RIL implementation has returned an error where it must succeed" +
-                        ar.exception);
-            }
-        } else try {
-            switch (what) {
-                case EVENT_POLL_STATE_REGISTRATION:
-                    states = (String[])ar.result;
-                    int lac = -1;
-                    int cid = -1;
-                    int regState = -1;
-                    int reasonRegStateDenied = -1;
-                    int psc = -1;
-                    if (states.length > 0) {
-                        try {
-                            regState = Integer.parseInt(states[0]);
-                            if (states.length >= 3) {
-                                if (states[1] != null && states[1].length() > 0) {
-                                    lac = Integer.parseInt(states[1], 16);
-                                }
-                                if (states[2] != null && states[2].length() > 0) {
-                                    cid = Integer.parseInt(states[2], 16);
-                                }
-                            }
-                            if (states.length > 14) {
-                                if (states[14] != null && states[14].length() > 0) {
-                                    psc = Integer.parseInt(states[14], 16);
-                                }
-                            }
-                        } catch (NumberFormatException ex) {
-                            loge("error parsing RegistrationState: " + ex);
-                        }
-                    }
-
-                    mGsmRoaming = regCodeIsRoaming(regState);
-                    newSS.setState (regCodeToServiceState(regState));
-
-                    if (regState == 10 || regState == 12 || regState == 13 || regState == 14) {
-                        mEmergencyOnly = true;
-                    } else {
-                        mEmergencyOnly = false;
-                    }
-
-                    // LAC and CID are -1 if not avail
-                    newCellLoc.setLacAndCid(lac, cid);
-                    newCellLoc.setPsc(psc);
-                break;
-
-                case EVENT_POLL_STATE_GPRS:
-                    states = (String[])ar.result;
-
-                    int type = 0;
-                    regState = -1;
-                    mNewReasonDataDenied = -1;
-                    mNewMaxDataCalls = 1;
-                    if (states.length > 0) {
-                        try {
-                            regState = Integer.parseInt(states[0]);
-
-                            // states[3] (if present) is the current radio technology
-                            if (states.length >= 4 && states[3] != null) {
-                                type = Integer.parseInt(states[3]);
-                            }
-                            if ((states.length >= 5 ) && (regState == 3)) {
-                                mNewReasonDataDenied = Integer.parseInt(states[4]);
-                            }
-                            if (states.length >= 6) {
-                                mNewMaxDataCalls = Integer.parseInt(states[5]);
-                            }
-                        } catch (NumberFormatException ex) {
-                            loge("error parsing GprsRegistrationState: " + ex);
-                        }
-                    }
-                    newGPRSState = regCodeToServiceState(regState);
-                    mDataRoaming = regCodeIsRoaming(regState);
-                    mNewRilRadioTechnology = type;
-                    newSS.setRadioTechnology(type);
-                break;
-
-                case EVENT_POLL_STATE_OPERATOR:
-                    String opNames[] = (String[])ar.result;
-
-                    if (opNames != null && opNames.length >= 3) {
-                         newSS.setOperatorName (opNames[0], opNames[1], opNames[2]);
-                    }
-                break;
-
-                case EVENT_POLL_STATE_NETWORK_SELECTION_MODE:
-                    ints = (int[])ar.result;
-                    newSS.setIsManualSelection(ints[0] == 1);
-                break;
-            }
-
-        } catch (RuntimeException ex) {
-            loge("Exception while polling service state. Probably malformed RIL response." + ex);
-        }
-
-        pollingContext[0]--;
-
-        if (pollingContext[0] == 0) {
-            /**
-             *  Since the roaming states of gsm service (from +CREG) and
-             *  data service (from +CGREG) could be different, the new SS
-             *  is set roaming while either one is roaming.
-             *
-             *  There is an exception for the above rule. The new SS is not set
-             *  as roaming while gsm service reports roaming but indeed it is
-             *  not roaming between operators.
-             */
-            boolean roaming = (mGsmRoaming || mDataRoaming);
-            if (mGsmRoaming && !isRoamingBetweenOperators(mGsmRoaming, newSS)) {
-                roaming = false;
-            }
-            newSS.setRoaming(roaming);
-            newSS.setEmergencyOnly(mEmergencyOnly);
-            pollStateDone();
-        }
-    }
-
-    private void setSignalStrengthDefaultValues() {
-        // TODO Make a constructor only has boolean gsm as parameter
-        mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1,
-                -1, -1, -1, SignalStrength.INVALID_SNR, -1, true);
-    }
-
-    /**
-     * A complete "service state" from our perspective is
-     * composed of a handful of separate requests to the radio.
-     *
-     * We make all of these requests at once, but then abandon them
-     * and start over again if the radio notifies us that some
-     * event has changed
-     */
-    private void pollState() {
-        pollingContext = new int[1];
-        pollingContext[0] = 0;
-
-        switch (cm.getRadioState()) {
-            case RADIO_UNAVAILABLE:
-                newSS.setStateOutOfService();
-                newCellLoc.setStateInvalid();
-                setSignalStrengthDefaultValues();
-                mGotCountryCode = false;
-                mNitzUpdatedTime = false;
-                pollStateDone();
-            break;
-
-            case RADIO_OFF:
-                newSS.setStateOff();
-                newCellLoc.setStateInvalid();
-                setSignalStrengthDefaultValues();
-                mGotCountryCode = false;
-                mNitzUpdatedTime = false;
-                pollStateDone();
-            break;
-
-            default:
-                // Issue all poll-related commands at once
-                // then count down the responses, which
-                // are allowed to arrive out-of-order
-
-                pollingContext[0]++;
-                cm.getOperator(
-                    obtainMessage(
-                        EVENT_POLL_STATE_OPERATOR, pollingContext));
-
-                pollingContext[0]++;
-                cm.getDataRegistrationState(
-                    obtainMessage(
-                        EVENT_POLL_STATE_GPRS, pollingContext));
-
-                pollingContext[0]++;
-                cm.getVoiceRegistrationState(
-                    obtainMessage(
-                        EVENT_POLL_STATE_REGISTRATION, pollingContext));
-
-                pollingContext[0]++;
-                cm.getNetworkSelectionMode(
-                    obtainMessage(
-                        EVENT_POLL_STATE_NETWORK_SELECTION_MODE, pollingContext));
-            break;
-        }
-    }
-
-    private void pollStateDone() {
-        if (DBG) {
-            log("Poll ServiceState done: " +
-                " oldSS=[" + ss + "] newSS=[" + newSS +
-                "] oldGprs=" + gprsState + " newData=" + newGPRSState +
-                " oldMaxDataCalls=" + mMaxDataCalls +
-                " mNewMaxDataCalls=" + mNewMaxDataCalls +
-                " oldReasonDataDenied=" + mReasonDataDenied +
-                " mNewReasonDataDenied=" + mNewReasonDataDenied +
-                " oldType=" + ServiceState.rilRadioTechnologyToString(mRilRadioTechnology) +
-                " newType=" + ServiceState.rilRadioTechnologyToString(mNewRilRadioTechnology));
-        }
-
-        boolean hasRegistered =
-            ss.getState() != ServiceState.STATE_IN_SERVICE
-            && newSS.getState() == ServiceState.STATE_IN_SERVICE;
-
-        boolean hasDeregistered =
-            ss.getState() == ServiceState.STATE_IN_SERVICE
-            && newSS.getState() != ServiceState.STATE_IN_SERVICE;
-
-        boolean hasGprsAttached =
-                gprsState != ServiceState.STATE_IN_SERVICE
-                && newGPRSState == ServiceState.STATE_IN_SERVICE;
-
-        boolean hasGprsDetached =
-                gprsState == ServiceState.STATE_IN_SERVICE
-                && newGPRSState != ServiceState.STATE_IN_SERVICE;
-
-        boolean hasRadioTechnologyChanged = mRilRadioTechnology != mNewRilRadioTechnology;
-
-        boolean hasChanged = !newSS.equals(ss);
-
-        boolean hasRoamingOn = !ss.getRoaming() && newSS.getRoaming();
-
-        boolean hasRoamingOff = ss.getRoaming() && !newSS.getRoaming();
-
-        boolean hasLocationChanged = !newCellLoc.equals(cellLoc);
-
-        // Add an event log when connection state changes
-        if (ss.getState() != newSS.getState() || gprsState != newGPRSState) {
-            EventLog.writeEvent(EventLogTags.GSM_SERVICE_STATE_CHANGE,
-                ss.getState(), gprsState, newSS.getState(), newGPRSState);
-        }
-
-        ServiceState tss;
-        tss = ss;
-        ss = newSS;
-        newSS = tss;
-        // clean slate for next time
-        newSS.setStateOutOfService();
-
-        GsmCellLocation tcl = cellLoc;
-        cellLoc = newCellLoc;
-        newCellLoc = tcl;
-
-        // Add an event log when network type switched
-        // TODO: we may add filtering to reduce the event logged,
-        // i.e. check preferred network setting, only switch to 2G, etc
-        if (hasRadioTechnologyChanged) {
-            int cid = -1;
-            GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation());
-            if (loc != null) cid = loc.getCid();
-            EventLog.writeEvent(EventLogTags.GSM_RAT_SWITCHED, cid, mRilRadioTechnology,
-                    mNewRilRadioTechnology);
-            if (DBG) {
-                log("RAT switched " + ServiceState.rilRadioTechnologyToString(mRilRadioTechnology) +
-                        " -> " + ServiceState.rilRadioTechnologyToString(mNewRilRadioTechnology) +
-                        " at cell " + cid);
-            }
-        }
-
-        gprsState = newGPRSState;
-        mReasonDataDenied = mNewReasonDataDenied;
-        mMaxDataCalls = mNewMaxDataCalls;
-        mRilRadioTechnology = mNewRilRadioTechnology;
-        // this new state has been applied - forget it until we get a new new state
-        mNewRilRadioTechnology = 0;
-
-
-        newSS.setStateOutOfService(); // clean slate for next time
-
-        if (hasRadioTechnologyChanged) {
-            phone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
-                    ServiceState.rilRadioTechnologyToString(mRilRadioTechnology));
-        }
-
-        if (hasRegistered) {
-            mNetworkAttachedRegistrants.notifyRegistrants();
-
-            if (DBG) {
-                log("pollStateDone: registering current mNitzUpdatedTime=" +
-                        mNitzUpdatedTime + " changing to false");
-            }
-            mNitzUpdatedTime = false;
-        }
-
-        if (hasChanged) {
-            String operatorNumeric;
-
-            updateSpnDisplay();
-
-            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA,
-                ss.getOperatorAlphaLong());
-
-            String prevOperatorNumeric =
-                    SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, "");
-            operatorNumeric = ss.getOperatorNumeric();
-            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric);
-
-            if (operatorNumeric == null) {
-                if (DBG) log("operatorNumeric is null");
-                phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
-                mGotCountryCode = false;
-                mNitzUpdatedTime = false;
-            } else {
-                String iso = "";
-                String mcc = operatorNumeric.substring(0, 3);
-                try{
-                    iso = MccTable.countryCodeForMcc(Integer.parseInt(mcc));
-                } catch ( NumberFormatException ex){
-                    loge("pollStateDone: countryCodeForMcc error" + ex);
-                } catch ( StringIndexOutOfBoundsException ex) {
-                    loge("pollStateDone: countryCodeForMcc error" + ex);
-                }
-
-                phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, iso);
-                mGotCountryCode = true;
-
-                TimeZone zone = null;
-
-                if (!mNitzUpdatedTime && !mcc.equals("000") && !TextUtils.isEmpty(iso) &&
-                        getAutoTimeZone()) {
-
-                    // Test both paths if ignore nitz is true
-                    boolean testOneUniqueOffsetPath = SystemProperties.getBoolean(
-                                TelephonyProperties.PROPERTY_IGNORE_NITZ, false) &&
-                                    ((SystemClock.uptimeMillis() & 1) == 0);
-
-                    ArrayList<TimeZone> uniqueZones = TimeUtils.getTimeZonesWithUniqueOffsets(iso);
-                    if ((uniqueZones.size() == 1) || testOneUniqueOffsetPath) {
-                        zone = uniqueZones.get(0);
-                        if (DBG) {
-                           log("pollStateDone: no nitz but one TZ for iso-cc=" + iso +
-                                   " with zone.getID=" + zone.getID() +
-                                   " testOneUniqueOffsetPath=" + testOneUniqueOffsetPath);
-                        }
-                        setAndBroadcastNetworkSetTimeZone(zone.getID());
-                    } else {
-                        if (DBG) {
-                            log("pollStateDone: there are " + uniqueZones.size() +
-                                " unique offsets for iso-cc='" + iso +
-                                " testOneUniqueOffsetPath=" + testOneUniqueOffsetPath +
-                                "', do nothing");
-                        }
-                    }
-                }
-
-                if (shouldFixTimeZoneNow(phone, operatorNumeric, prevOperatorNumeric,
-                        mNeedFixZoneAfterNitz)) {
-                    // If the offset is (0, false) and the timezone property
-                    // is set, use the timezone property rather than
-                    // GMT.
-                    String zoneName = SystemProperties.get(TIMEZONE_PROPERTY);
-                    if (DBG) {
-                        log("pollStateDone: fix time zone zoneName='" + zoneName +
-                            "' mZoneOffset=" + mZoneOffset + " mZoneDst=" + mZoneDst +
-                            " iso-cc='" + iso +
-                            "' iso-cc-idx=" + Arrays.binarySearch(GMT_COUNTRY_CODES, iso));
-                    }
-
-                    // "(mZoneOffset == 0) && (mZoneDst == false) &&
-                    //  (Arrays.binarySearch(GMT_COUNTRY_CODES, iso) < 0)"
-                    // means that we received a NITZ string telling
-                    // it is in GMT+0 w/ DST time zone
-                    // BUT iso tells is NOT, e.g, a wrong NITZ reporting
-                    // local time w/ 0 offset.
-                    if ((mZoneOffset == 0) && (mZoneDst == false) &&
-                        (zoneName != null) && (zoneName.length() > 0) &&
-                        (Arrays.binarySearch(GMT_COUNTRY_CODES, iso) < 0)) {
-                        zone = TimeZone.getDefault();
-                        if (mNeedFixZoneAfterNitz) {
-                            // For wrong NITZ reporting local time w/ 0 offset,
-                            // need adjust time to reflect default timezone setting
-                            long ctm = System.currentTimeMillis();
-                            long tzOffset = zone.getOffset(ctm);
-                            if (DBG) {
-                                log("pollStateDone: tzOffset=" + tzOffset + " ltod=" +
-                                        TimeUtils.logTimeOfDay(ctm));
-                            }
-                            if (getAutoTime()) {
-                                long adj = ctm - tzOffset;
-                                if (DBG) log("pollStateDone: adj ltod=" +
-                                        TimeUtils.logTimeOfDay(adj));
-                                setAndBroadcastNetworkSetTime(adj);
-                            } else {
-                                // Adjust the saved NITZ time to account for tzOffset.
-                                mSavedTime = mSavedTime - tzOffset;
-                            }
-                        }
-                        if (DBG) log("pollStateDone: using default TimeZone");
-                    } else if (iso.equals("")){
-                        // Country code not found.  This is likely a test network.
-                        // Get a TimeZone based only on the NITZ parameters (best guess).
-                        zone = getNitzTimeZone(mZoneOffset, mZoneDst, mZoneTime);
-                        if (DBG) log("pollStateDone: using NITZ TimeZone");
-                    } else {
-                        zone = TimeUtils.getTimeZone(mZoneOffset, mZoneDst, mZoneTime, iso);
-                        if (DBG) log("pollStateDone: using getTimeZone(off, dst, time, iso)");
-                    }
-
-                    mNeedFixZoneAfterNitz = false;
-
-                    if (zone != null) {
-                        log("pollStateDone: zone != null zone.getID=" + zone.getID());
-                        if (getAutoTimeZone()) {
-                            setAndBroadcastNetworkSetTimeZone(zone.getID());
-                        }
-                        saveNitzTimeZone(zone.getID());
-                    } else {
-                        log("pollStateDone: zone == null");
-                    }
-                }
-            }
-
-            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
-                ss.getRoaming() ? "true" : "false");
-
-            phone.notifyServiceStateChanged(ss);
-        }
-
-        if (hasGprsAttached) {
-            mAttachedRegistrants.notifyRegistrants();
-        }
-
-        if (hasGprsDetached) {
-            mDetachedRegistrants.notifyRegistrants();
-        }
-
-        if (hasRadioTechnologyChanged) {
-            phone.notifyDataConnection(Phone.REASON_NW_TYPE_CHANGED);
-        }
-
-        if (hasRoamingOn) {
-            mRoamingOnRegistrants.notifyRegistrants();
-        }
-
-        if (hasRoamingOff) {
-            mRoamingOffRegistrants.notifyRegistrants();
-        }
-
-        if (hasLocationChanged) {
-            phone.notifyLocationChanged();
-        }
-
-        if (! isGprsConsistent(gprsState, ss.getState())) {
-            if (!mStartedGprsRegCheck && !mReportedGprsNoReg) {
-                mStartedGprsRegCheck = true;
-
-                int check_period = Settings.Secure.getInt(
-                        phone.getContext().getContentResolver(),
-                        Settings.Secure.GPRS_REGISTER_CHECK_PERIOD_MS,
-                        DEFAULT_GPRS_CHECK_PERIOD_MILLIS);
-                sendMessageDelayed(obtainMessage(EVENT_CHECK_REPORT_GPRS),
-                        check_period);
-            }
-        } else {
-            mReportedGprsNoReg = false;
-        }
-    }
-
-    /**
-     * Check if GPRS got registered while voice is registered.
-     *
-     * @param gprsState for GPRS registration state, i.e. CGREG in GSM
-     * @param serviceState for voice registration state, i.e. CREG in GSM
-     * @return false if device only register to voice but not gprs
-     */
-    private boolean isGprsConsistent(int gprsState, int serviceState) {
-        return !((serviceState == ServiceState.STATE_IN_SERVICE) &&
-                (gprsState != ServiceState.STATE_IN_SERVICE));
-    }
-
-    /**
-     * Returns a TimeZone object based only on parameters from the NITZ string.
-     */
-    private TimeZone getNitzTimeZone(int offset, boolean dst, long when) {
-        TimeZone guess = findTimeZone(offset, dst, when);
-        if (guess == null) {
-            // Couldn't find a proper timezone.  Perhaps the DST data is wrong.
-            guess = findTimeZone(offset, !dst, when);
-        }
-        if (DBG) log("getNitzTimeZone returning " + (guess == null ? guess : guess.getID()));
-        return guess;
-    }
-
-    private TimeZone findTimeZone(int offset, boolean dst, long when) {
-        int rawOffset = offset;
-        if (dst) {
-            rawOffset -= 3600000;
-        }
-        String[] zones = TimeZone.getAvailableIDs(rawOffset);
-        TimeZone guess = null;
-        Date d = new Date(when);
-        for (String zone : zones) {
-            TimeZone tz = TimeZone.getTimeZone(zone);
-            if (tz.getOffset(when) == offset &&
-                tz.inDaylightTime(d) == dst) {
-                guess = tz;
-                break;
-            }
-        }
-
-        return guess;
-    }
-
-    private void queueNextSignalStrengthPoll() {
-        if (dontPollSignalStrength) {
-            // The radio is telling us about signal strength changes
-            // we don't have to ask it
-            return;
-        }
-
-        Message msg;
-
-        msg = obtainMessage();
-        msg.what = EVENT_POLL_SIGNAL_STRENGTH;
-
-        long nextTime;
-
-        // TODO Don't poll signal strength if screen is off
-        sendMessageDelayed(msg, POLL_PERIOD_MILLIS);
-    }
-
-    /**
-     *  Send signal-strength-changed notification if changed.
-     *  Called both for solicited and unsolicited signal strength updates.
-     */
-    private void onSignalStrengthResult(AsyncResult ar) {
-        SignalStrength oldSignalStrength = mSignalStrength;
-        int rssi = 99;
-        int lteSignalStrength = -1;
-        int lteRsrp = -1;
-        int lteRsrq = -1;
-        int lteRssnr = SignalStrength.INVALID_SNR;
-        int lteCqi = -1;
-
-        if (ar.exception != null) {
-            // -1 = unknown
-            // most likely radio is resetting/disconnected
-            setSignalStrengthDefaultValues();
-        } else {
-            int[] ints = (int[])ar.result;
-
-            // bug 658816 seems to be a case where the result is 0-length
-            if (ints.length != 0) {
-                rssi = ints[0];
-                lteSignalStrength = ints[7];
-                lteRsrp = ints[8];
-                lteRsrq = ints[9];
-                lteRssnr = ints[10];
-                lteCqi = ints[11];
-            } else {
-                loge("Bogus signal strength response");
-                rssi = 99;
-            }
-        }
-
-        mSignalStrength = new SignalStrength(rssi, -1, -1, -1,
-                -1, -1, -1, lteSignalStrength, lteRsrp, lteRsrq, lteRssnr, lteCqi, true);
-
-        if (!mSignalStrength.equals(oldSignalStrength)) {
-            try { // This takes care of delayed EVENT_POLL_SIGNAL_STRENGTH (scheduled after
-                  // POLL_PERIOD_MILLIS) during Radio Technology Change)
-                phone.notifySignalStrength();
-           } catch (NullPointerException ex) {
-                log("onSignalStrengthResult() Phone already destroyed: " + ex
-                        + "SignalStrength not notified");
-           }
-        }
-    }
-
-    /**
-     * Set restricted state based on the OnRestrictedStateChanged notification
-     * If any voice or packet restricted state changes, trigger a UI
-     * notification and notify registrants when sim is ready.
-     *
-     * @param ar an int value of RIL_RESTRICTED_STATE_*
-     */
-    private void onRestrictedStateChanged(AsyncResult ar) {
-        RestrictedState newRs = new RestrictedState();
-
-        if (DBG) log("onRestrictedStateChanged: E rs "+ mRestrictedState);
-
-        if (ar.exception == null) {
-            int[] ints = (int[])ar.result;
-            int state = ints[0];
-
-            newRs.setCsEmergencyRestricted(
-                    ((state & RILConstants.RIL_RESTRICTED_STATE_CS_EMERGENCY) != 0) ||
-                    ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
-            //ignore the normal call and data restricted state before SIM READY
-            if (phone.getIccCard().getState() == IccCard.State.READY) {
-                newRs.setCsNormalRestricted(
-                        ((state & RILConstants.RIL_RESTRICTED_STATE_CS_NORMAL) != 0) ||
-                        ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
-                newRs.setPsRestricted(
-                        (state & RILConstants.RIL_RESTRICTED_STATE_PS_ALL)!= 0);
-            }
-
-            if (DBG) log("onRestrictedStateChanged: new rs "+ newRs);
-
-            if (!mRestrictedState.isPsRestricted() && newRs.isPsRestricted()) {
-                mPsRestrictEnabledRegistrants.notifyRegistrants();
-                setNotification(PS_ENABLED);
-            } else if (mRestrictedState.isPsRestricted() && !newRs.isPsRestricted()) {
-                mPsRestrictDisabledRegistrants.notifyRegistrants();
-                setNotification(PS_DISABLED);
-            }
-
-            /**
-             * There are two kind of cs restriction, normal and emergency. So
-             * there are 4 x 4 combinations in current and new restricted states
-             * and we only need to notify when state is changed.
-             */
-            if (mRestrictedState.isCsRestricted()) {
-                if (!newRs.isCsRestricted()) {
-                    // remove all restriction
-                    setNotification(CS_DISABLED);
-                } else if (!newRs.isCsNormalRestricted()) {
-                    // remove normal restriction
-                    setNotification(CS_EMERGENCY_ENABLED);
-                } else if (!newRs.isCsEmergencyRestricted()) {
-                    // remove emergency restriction
-                    setNotification(CS_NORMAL_ENABLED);
-                }
-            } else if (mRestrictedState.isCsEmergencyRestricted() &&
-                    !mRestrictedState.isCsNormalRestricted()) {
-                if (!newRs.isCsRestricted()) {
-                    // remove all restriction
-                    setNotification(CS_DISABLED);
-                } else if (newRs.isCsRestricted()) {
-                    // enable all restriction
-                    setNotification(CS_ENABLED);
-                } else if (newRs.isCsNormalRestricted()) {
-                    // remove emergency restriction and enable normal restriction
-                    setNotification(CS_NORMAL_ENABLED);
-                }
-            } else if (!mRestrictedState.isCsEmergencyRestricted() &&
-                    mRestrictedState.isCsNormalRestricted()) {
-                if (!newRs.isCsRestricted()) {
-                    // remove all restriction
-                    setNotification(CS_DISABLED);
-                } else if (newRs.isCsRestricted()) {
-                    // enable all restriction
-                    setNotification(CS_ENABLED);
-                } else if (newRs.isCsEmergencyRestricted()) {
-                    // remove normal restriction and enable emergency restriction
-                    setNotification(CS_EMERGENCY_ENABLED);
-                }
-            } else {
-                if (newRs.isCsRestricted()) {
-                    // enable all restriction
-                    setNotification(CS_ENABLED);
-                } else if (newRs.isCsEmergencyRestricted()) {
-                    // enable emergency restriction
-                    setNotification(CS_EMERGENCY_ENABLED);
-                } else if (newRs.isCsNormalRestricted()) {
-                    // enable normal restriction
-                    setNotification(CS_NORMAL_ENABLED);
-                }
-            }
-
-            mRestrictedState = newRs;
-        }
-        log("onRestrictedStateChanged: X rs "+ mRestrictedState);
-    }
-
-    /** code is registration state 0-5 from TS 27.007 7.2 */
-    private int regCodeToServiceState(int code) {
-        switch (code) {
-            case 0:
-            case 2: // 2 is "searching"
-            case 3: // 3 is "registration denied"
-            case 4: // 4 is "unknown" no vaild in current baseband
-            case 10:// same as 0, but indicates that emergency call is possible.
-            case 12:// same as 2, but indicates that emergency call is possible.
-            case 13:// same as 3, but indicates that emergency call is possible.
-            case 14:// same as 4, but indicates that emergency call is possible.
-                return ServiceState.STATE_OUT_OF_SERVICE;
-
-            case 1:
-                return ServiceState.STATE_IN_SERVICE;
-
-            case 5:
-                // in service, roam
-                return ServiceState.STATE_IN_SERVICE;
-
-            default:
-                loge("regCodeToServiceState: unexpected service state " + code);
-                return ServiceState.STATE_OUT_OF_SERVICE;
-        }
-    }
-
-
-    /**
-     * code is registration state 0-5 from TS 27.007 7.2
-     * returns true if registered roam, false otherwise
-     */
-    private boolean regCodeIsRoaming (int code) {
-        // 5 is  "in service -- roam"
-        return 5 == code;
-    }
-
-    /**
-     * Set roaming state when gsmRoaming is true and, if operator mcc is the
-     * same as sim mcc, ons is different from spn
-     * @param gsmRoaming TS 27.007 7.2 CREG registered roaming
-     * @param s ServiceState hold current ons
-     * @return true for roaming state set
-     */
-    private boolean isRoamingBetweenOperators(boolean gsmRoaming, ServiceState s) {
-        String spn = SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, "empty");
-
-        String onsl = s.getOperatorAlphaLong();
-        String onss = s.getOperatorAlphaShort();
-
-        boolean equalsOnsl = onsl != null && spn.equals(onsl);
-        boolean equalsOnss = onss != null && spn.equals(onss);
-
-        String simNumeric = SystemProperties.get(
-                TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "");
-        String  operatorNumeric = s.getOperatorNumeric();
-
-        boolean equalsMcc = true;
-        try {
-            equalsMcc = simNumeric.substring(0, 3).
-                    equals(operatorNumeric.substring(0, 3));
-        } catch (Exception e){
-        }
-
-        return gsmRoaming && !(equalsMcc && (equalsOnsl || equalsOnss));
-    }
-
-    private static int twoDigitsAt(String s, int offset) {
-        int a, b;
-
-        a = Character.digit(s.charAt(offset), 10);
-        b = Character.digit(s.charAt(offset+1), 10);
-
-        if (a < 0 || b < 0) {
-
-            throw new RuntimeException("invalid format");
-        }
-
-        return a*10 + b;
-    }
-
-    /**
-     * @return The current GPRS state. IN_SERVICE is the same as "attached"
-     * and OUT_OF_SERVICE is the same as detached.
-     */
-    int getCurrentGprsState() {
-        return gprsState;
-    }
-
-    public int getCurrentDataConnectionState() {
-        return gprsState;
-    }
-
-    /**
-     * @return true if phone is camping on a technology (eg UMTS)
-     * that could support voice and data simultaneously.
-     */
-    public boolean isConcurrentVoiceAndDataAllowed() {
-        return (mRilRadioTechnology >= ServiceState.RIL_RADIO_TECHNOLOGY_UMTS);
-    }
-
-    /**
-     * Provides the name of the algorithmic time zone for the specified
-     * offset.  Taken from TimeZone.java.
-     */
-    private static String displayNameFor(int off) {
-        off = off / 1000 / 60;
-
-        char[] buf = new char[9];
-        buf[0] = 'G';
-        buf[1] = 'M';
-        buf[2] = 'T';
-
-        if (off < 0) {
-            buf[3] = '-';
-            off = -off;
-        } else {
-            buf[3] = '+';
-        }
-
-        int hours = off / 60;
-        int minutes = off % 60;
-
-        buf[4] = (char) ('0' + hours / 10);
-        buf[5] = (char) ('0' + hours % 10);
-
-        buf[6] = ':';
-
-        buf[7] = (char) ('0' + minutes / 10);
-        buf[8] = (char) ('0' + minutes % 10);
-
-        return new String(buf);
-    }
-
-    /**
-     * nitzReceiveTime is time_t that the NITZ time was posted
-     */
-    private void setTimeFromNITZString (String nitz, long nitzReceiveTime) {
-        // "yy/mm/dd,hh:mm:ss(+/-)tz"
-        // tz is in number of quarter-hours
-
-        long start = SystemClock.elapsedRealtime();
-        if (DBG) {log("NITZ: " + nitz + "," + nitzReceiveTime +
-                        " start=" + start + " delay=" + (start - nitzReceiveTime));
-        }
-
-        try {
-            /* NITZ time (hour:min:sec) will be in UTC but it supplies the timezone
-             * offset as well (which we won't worry about until later) */
-            Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
-
-            c.clear();
-            c.set(Calendar.DST_OFFSET, 0);
-
-            String[] nitzSubs = nitz.split("[/:,+-]");
-
-            int year = 2000 + Integer.parseInt(nitzSubs[0]);
-            c.set(Calendar.YEAR, year);
-
-            // month is 0 based!
-            int month = Integer.parseInt(nitzSubs[1]) - 1;
-            c.set(Calendar.MONTH, month);
-
-            int date = Integer.parseInt(nitzSubs[2]);
-            c.set(Calendar.DATE, date);
-
-            int hour = Integer.parseInt(nitzSubs[3]);
-            c.set(Calendar.HOUR, hour);
-
-            int minute = Integer.parseInt(nitzSubs[4]);
-            c.set(Calendar.MINUTE, minute);
-
-            int second = Integer.parseInt(nitzSubs[5]);
-            c.set(Calendar.SECOND, second);
-
-            boolean sign = (nitz.indexOf('-') == -1);
-
-            int tzOffset = Integer.parseInt(nitzSubs[6]);
-
-            int dst = (nitzSubs.length >= 8 ) ? Integer.parseInt(nitzSubs[7])
-                                              : 0;
-
-            // The zone offset received from NITZ is for current local time,
-            // so DST correction is already applied.  Don't add it again.
-            //
-            // tzOffset += dst * 4;
-            //
-            // We could unapply it if we wanted the raw offset.
-
-            tzOffset = (sign ? 1 : -1) * tzOffset * 15 * 60 * 1000;
-
-            TimeZone    zone = null;
-
-            // As a special extension, the Android emulator appends the name of
-            // the host computer's timezone to the nitz string. this is zoneinfo
-            // timezone name of the form Area!Location or Area!Location!SubLocation
-            // so we need to convert the ! into /
-            if (nitzSubs.length >= 9) {
-                String  tzname = nitzSubs[8].replace('!','/');
-                zone = TimeZone.getTimeZone( tzname );
-            }
-
-            String iso = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY);
-
-            if (zone == null) {
-
-                if (mGotCountryCode) {
-                    if (iso != null && iso.length() > 0) {
-                        zone = TimeUtils.getTimeZone(tzOffset, dst != 0,
-                                c.getTimeInMillis(),
-                                iso);
-                    } else {
-                        // We don't have a valid iso country code.  This is
-                        // most likely because we're on a test network that's
-                        // using a bogus MCC (eg, "001"), so get a TimeZone
-                        // based only on the NITZ parameters.
-                        zone = getNitzTimeZone(tzOffset, (dst != 0), c.getTimeInMillis());
-                    }
-                }
-            }
-
-            if ((zone == null) || (mZoneOffset != tzOffset) || (mZoneDst != (dst != 0))){
-                // We got the time before the country or the zone has changed
-                // so we don't know how to identify the DST rules yet.  Save
-                // the information and hope to fix it up later.
-
-                mNeedFixZoneAfterNitz = true;
-                mZoneOffset  = tzOffset;
-                mZoneDst     = dst != 0;
-                mZoneTime    = c.getTimeInMillis();
-            }
-
-            if (zone != null) {
-                if (getAutoTimeZone()) {
-                    setAndBroadcastNetworkSetTimeZone(zone.getID());
-                }
-                saveNitzTimeZone(zone.getID());
-            }
-
-            String ignore = SystemProperties.get("gsm.ignore-nitz");
-            if (ignore != null && ignore.equals("yes")) {
-                log("NITZ: Not setting clock because gsm.ignore-nitz is set");
-                return;
-            }
-
-            try {
-                mWakeLock.acquire();
-
-                if (getAutoTime()) {
-                    long millisSinceNitzReceived
-                            = SystemClock.elapsedRealtime() - nitzReceiveTime;
-
-                    if (millisSinceNitzReceived < 0) {
-                        // Sanity check: something is wrong
-                        if (DBG) {
-                            log("NITZ: not setting time, clock has rolled "
-                                            + "backwards since NITZ time was received, "
-                                            + nitz);
-                        }
-                        return;
-                    }
-
-                    if (millisSinceNitzReceived > Integer.MAX_VALUE) {
-                        // If the time is this far off, something is wrong > 24 days!
-                        if (DBG) {
-                            log("NITZ: not setting time, processing has taken "
-                                        + (millisSinceNitzReceived / (1000 * 60 * 60 * 24))
-                                        + " days");
-                        }
-                        return;
-                    }
-
-                    // Note: with range checks above, cast to int is safe
-                    c.add(Calendar.MILLISECOND, (int)millisSinceNitzReceived);
-
-                    if (DBG) {
-                        log("NITZ: Setting time of day to " + c.getTime()
-                            + " NITZ receive delay(ms): " + millisSinceNitzReceived
-                            + " gained(ms): "
-                            + (c.getTimeInMillis() - System.currentTimeMillis())
-                            + " from " + nitz);
-                    }
-
-                    setAndBroadcastNetworkSetTime(c.getTimeInMillis());
-                    Log.i(LOG_TAG, "NITZ: after Setting time of day");
-                }
-                SystemProperties.set("gsm.nitz.time", String.valueOf(c.getTimeInMillis()));
-                saveNitzTime(c.getTimeInMillis());
-                if (false) {
-                    long end = SystemClock.elapsedRealtime();
-                    log("NITZ: end=" + end + " dur=" + (end - start));
-                }
-                mNitzUpdatedTime = true;
-            } finally {
-                mWakeLock.release();
-            }
-        } catch (RuntimeException ex) {
-            loge("NITZ: Parsing NITZ time " + nitz + " ex=" + ex);
-        }
-    }
-
-    private boolean getAutoTime() {
-        try {
-            return Settings.System.getInt(phone.getContext().getContentResolver(),
-                    Settings.System.AUTO_TIME) > 0;
-        } catch (SettingNotFoundException snfe) {
-            return true;
-        }
-    }
-
-    private boolean getAutoTimeZone() {
-        try {
-            return Settings.System.getInt(phone.getContext().getContentResolver(),
-                    Settings.System.AUTO_TIME_ZONE) > 0;
-        } catch (SettingNotFoundException snfe) {
-            return true;
-        }
-    }
-
-    private void saveNitzTimeZone(String zoneId) {
-        mSavedTimeZone = zoneId;
-    }
-
-    private void saveNitzTime(long time) {
-        mSavedTime = time;
-        mSavedAtTime = SystemClock.elapsedRealtime();
-    }
-
-    /**
-     * Set the timezone and send out a sticky broadcast so the system can
-     * determine if the timezone was set by the carrier.
-     *
-     * @param zoneId timezone set by carrier
-     */
-    private void setAndBroadcastNetworkSetTimeZone(String zoneId) {
-        if (DBG) log("setAndBroadcastNetworkSetTimeZone: setTimeZone=" + zoneId);
-        AlarmManager alarm =
-            (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE);
-        alarm.setTimeZone(zoneId);
-        Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE);
-        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
-        intent.putExtra("time-zone", zoneId);
-        phone.getContext().sendStickyBroadcast(intent);
-        if (DBG) {
-            log("setAndBroadcastNetworkSetTimeZone: call alarm.setTimeZone and broadcast zoneId=" +
-                zoneId);
-        }
-    }
-
-    /**
-     * Set the time and Send out a sticky broadcast so the system can determine
-     * if the time was set by the carrier.
-     *
-     * @param time time set by network
-     */
-    private void setAndBroadcastNetworkSetTime(long time) {
-        if (DBG) log("setAndBroadcastNetworkSetTime: time=" + time + "ms");
-        SystemClock.setCurrentTimeMillis(time);
-        Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIME);
-        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
-        intent.putExtra("time", time);
-        phone.getContext().sendStickyBroadcast(intent);
-    }
-
-    private void revertToNitzTime() {
-        if (Settings.System.getInt(phone.getContext().getContentResolver(),
-                Settings.System.AUTO_TIME, 0) == 0) {
-            return;
-        }
-        if (DBG) {
-            log("Reverting to NITZ Time: mSavedTime=" + mSavedTime
-                + " mSavedAtTime=" + mSavedAtTime);
-        }
-        if (mSavedTime != 0 && mSavedAtTime != 0) {
-            setAndBroadcastNetworkSetTime(mSavedTime
-                    + (SystemClock.elapsedRealtime() - mSavedAtTime));
-        }
-    }
-
-    private void revertToNitzTimeZone() {
-        if (Settings.System.getInt(phone.getContext().getContentResolver(),
-                Settings.System.AUTO_TIME_ZONE, 0) == 0) {
-            return;
-        }
-        if (DBG) log("Reverting to NITZ TimeZone: tz='" + mSavedTimeZone);
-        if (mSavedTimeZone != null) {
-            setAndBroadcastNetworkSetTimeZone(mSavedTimeZone);
-        }
-    }
-
-    /**
-     * Post a notification to NotificationManager for restricted state
-     *
-     * @param notifyType is one state of PS/CS_*_ENABLE/DISABLE
-     */
-    private void setNotification(int notifyType) {
-
-        if (DBG) log("setNotification: create notification " + notifyType);
-        Context context = phone.getContext();
-
-        mNotification = new Notification();
-        mNotification.when = System.currentTimeMillis();
-        mNotification.flags = Notification.FLAG_AUTO_CANCEL;
-        mNotification.icon = com.android.internal.R.drawable.stat_sys_warning;
-        Intent intent = new Intent();
-        mNotification.contentIntent = PendingIntent
-        .getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
-
-        CharSequence details = "";
-        CharSequence title = context.getText(com.android.internal.R.string.RestrictedChangedTitle);
-        int notificationId = CS_NOTIFICATION;
-
-        switch (notifyType) {
-        case PS_ENABLED:
-            notificationId = PS_NOTIFICATION;
-            details = context.getText(com.android.internal.R.string.RestrictedOnData);;
-            break;
-        case PS_DISABLED:
-            notificationId = PS_NOTIFICATION;
-            break;
-        case CS_ENABLED:
-            details = context.getText(com.android.internal.R.string.RestrictedOnAllVoice);;
-            break;
-        case CS_NORMAL_ENABLED:
-            details = context.getText(com.android.internal.R.string.RestrictedOnNormal);;
-            break;
-        case CS_EMERGENCY_ENABLED:
-            details = context.getText(com.android.internal.R.string.RestrictedOnEmergency);;
-            break;
-        case CS_DISABLED:
-            // do nothing and cancel the notification later
-            break;
-        }
-
-        if (DBG) log("setNotification: put notification " + title + " / " +details);
-        mNotification.tickerText = title;
-        mNotification.setLatestEventInfo(context, title, details,
-                mNotification.contentIntent);
-
-        NotificationManager notificationManager = (NotificationManager)
-            context.getSystemService(Context.NOTIFICATION_SERVICE);
-
-        if (notifyType == PS_DISABLED || notifyType == CS_DISABLED) {
-            // cancel previous post notification
-            notificationManager.cancel(notificationId);
-        } else {
-            // update restricted state notification
-            notificationManager.notify(notificationId, mNotification);
-        }
-    }
-
-    @Override
-    protected void log(String s) {
-        Log.d(LOG_TAG, "[GsmSST] " + s);
-    }
-
-    @Override
-    protected void loge(String s) {
-        Log.e(LOG_TAG, "[GsmSST] " + s);
-    }
-
-    private static void sloge(String s) {
-        Log.e(LOG_TAG, "[GsmSST] " + s);
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("GsmServiceStateTracker extends:");
-        super.dump(fd, pw, args);
-        pw.println(" phone=" + phone);
-        pw.println(" cellLoc=" + cellLoc);
-        pw.println(" newCellLoc=" + newCellLoc);
-        pw.println(" mPreferredNetworkType=" + mPreferredNetworkType);
-        pw.println(" gprsState=" + gprsState);
-        pw.println(" newGPRSState=" + newGPRSState);
-        pw.println(" mMaxDataCalls=" + mMaxDataCalls);
-        pw.println(" mNewMaxDataCalls=" + mNewMaxDataCalls);
-        pw.println(" mReasonDataDenied=" + mReasonDataDenied);
-        pw.println(" mNewReasonDataDenied=" + mNewReasonDataDenied);
-        pw.println(" mGsmRoaming=" + mGsmRoaming);
-        pw.println(" mDataRoaming=" + mDataRoaming);
-        pw.println(" mEmergencyOnly=" + mEmergencyOnly);
-        pw.println(" mNeedFixZoneAfterNitz=" + mNeedFixZoneAfterNitz);
-        pw.println(" mZoneOffset=" + mZoneOffset);
-        pw.println(" mZoneDst=" + mZoneDst);
-        pw.println(" mZoneTime=" + mZoneTime);
-        pw.println(" mGotCountryCode=" + mGotCountryCode);
-        pw.println(" mNitzUpdatedTime=" + mNitzUpdatedTime);
-        pw.println(" mSavedTimeZone=" + mSavedTimeZone);
-        pw.println(" mSavedTime=" + mSavedTime);
-        pw.println(" mSavedAtTime=" + mSavedAtTime);
-        pw.println(" mNeedToRegForSimLoaded=" + mNeedToRegForSimLoaded);
-        pw.println(" mStartedGprsRegCheck=" + mStartedGprsRegCheck);
-        pw.println(" mReportedGprsNoReg=" + mReportedGprsNoReg);
-        pw.println(" mNotification=" + mNotification);
-        pw.println(" mWakeLock=" + mWakeLock);
-        pw.println(" curSpn=" + curSpn);
-        pw.println(" curPlmn=" + curPlmn);
-        pw.println(" curSpnRule=" + curSpnRule);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsAddress.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsAddress.java
deleted file mode 100644
index c163803..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsAddress.java
+++ /dev/null
@@ -1,148 +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.internal.telephony.gsm;
-
-import android.telephony.PhoneNumberUtils;
-
-import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.SmsAddress;
-
-public class GsmSmsAddress extends SmsAddress {
-
-    static final int OFFSET_ADDRESS_LENGTH = 0;
-
-    static final int OFFSET_TOA = 1;
-
-    static final int OFFSET_ADDRESS_VALUE = 2;
-
-    /**
-     * New GsmSmsAddress from TS 23.040 9.1.2.5 Address Field
-     *
-     * @param offset the offset of the Address-Length byte
-     * @param length the length in bytes rounded up, e.g. "2 +
-     *        (addressLength + 1) / 2"
-     */
-
-    public GsmSmsAddress(byte[] data, int offset, int length) {
-        origBytes = new byte[length];
-        System.arraycopy(data, offset, origBytes, 0, length);
-
-        // addressLength is the count of semi-octets, not bytes
-        int addressLength = origBytes[OFFSET_ADDRESS_LENGTH] & 0xff;
-
-        int toa = origBytes[OFFSET_TOA] & 0xff;
-        ton = 0x7 & (toa >> 4);
-
-        // TOA must have its high bit set
-        if ((toa & 0x80) != 0x80) {
-            throw new RuntimeException("Invalid TOA - high bit must be set");
-        }
-
-        if (isAlphanumeric()) {
-            // An alphanumeric address
-            int countSeptets = addressLength * 4 / 7;
-
-            address = GsmAlphabet.gsm7BitPackedToString(origBytes,
-                    OFFSET_ADDRESS_VALUE, countSeptets);
-        } else {
-            // TS 23.040 9.1.2.5 says
-            // that "the MS shall interpret reserved values as 'Unknown'
-            // but shall store them exactly as received"
-
-            byte lastByte = origBytes[length - 1];
-
-            if ((addressLength & 1) == 1) {
-                // Make sure the final unused BCD digit is 0xf
-                origBytes[length - 1] |= 0xf0;
-            }
-            address = PhoneNumberUtils.calledPartyBCDToString(origBytes,
-                    OFFSET_TOA, length - OFFSET_TOA);
-
-            // And restore origBytes
-            origBytes[length - 1] = lastByte;
-        }
-    }
-
-    public String getAddressString() {
-        return address;
-    }
-
-    /**
-     * Returns true if this is an alphanumeric address
-     */
-    public boolean isAlphanumeric() {
-        return ton == TON_ALPHANUMERIC;
-    }
-
-    public boolean isNetworkSpecific() {
-        return ton == TON_NETWORK;
-    }
-
-    /**
-     * Returns true of this is a valid CPHS voice message waiting indicator
-     * address
-     */
-    public boolean isCphsVoiceMessageIndicatorAddress() {
-        // CPHS-style MWI message
-        // See CPHS 4.7 B.4.2.1
-        //
-        // Basically:
-        //
-        // - Originating address should be 4 bytes long and alphanumeric
-        // - Decode will result with two chars:
-        // - Char 1
-        // 76543210
-        // ^ set/clear indicator (0 = clear)
-        // ^^^ type of indicator (000 = voice)
-        // ^^^^ must be equal to 0001
-        // - Char 2:
-        // 76543210
-        // ^ line number (0 = line 1)
-        // ^^^^^^^ set to 0
-        //
-        // Remember, since the alpha address is stored in 7-bit compact form,
-        // the "line number" is really the top bit of the first address value
-        // byte
-
-        return (origBytes[OFFSET_ADDRESS_LENGTH] & 0xff) == 4
-                && isAlphanumeric() && (origBytes[OFFSET_TOA] & 0x0f) == 0;
-    }
-
-    /**
-     * Returns true if this is a valid CPHS voice message waiting indicator
-     * address indicating a "set" of "indicator 1" of type "voice message
-     * waiting"
-     */
-    public boolean isCphsVoiceMessageSet() {
-        // 0x11 means "set" "voice message waiting" "indicator 1"
-        return isCphsVoiceMessageIndicatorAddress()
-                && (origBytes[OFFSET_ADDRESS_VALUE] & 0xff) == 0x11;
-
-    }
-
-    /**
-     * Returns true if this is a valid CPHS voice message waiting indicator
-     * address indicating a "clear" of "indicator 1" of type "voice message
-     * waiting"
-     */
-    public boolean isCphsVoiceMessageClear() {
-        // 0x10 means "clear" "voice message waiting" "indicator 1"
-        return isCphsVoiceMessageIndicatorAddress()
-                && (origBytes[OFFSET_ADDRESS_VALUE] & 0xff) == 0x10;
-
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
deleted file mode 100644
index dc9554a..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright (C) 2012 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.internal.telephony.gsm;
-
-import android.telephony.SmsCbLocation;
-import android.telephony.SmsCbMessage;
-import android.util.Pair;
-
-import com.android.internal.telephony.GsmAlphabet;
-
-import java.io.UnsupportedEncodingException;
-
-/**
- * Parses a GSM or UMTS format SMS-CB message into an {@link SmsCbMessage} object. The class is
- * public because {@link #createSmsCbMessage(SmsCbLocation, byte[][])} is used by some test cases.
- */
-public class GsmSmsCbMessage {
-
-    /**
-     * Languages in the 0000xxxx DCS group as defined in 3GPP TS 23.038, section 5.
-     */
-    private static final String[] LANGUAGE_CODES_GROUP_0 = {
-            "de", "en", "it", "fr", "es", "nl", "sv", "da", "pt", "fi", "no", "el", "tr", "hu",
-            "pl", null
-    };
-
-    /**
-     * Languages in the 0010xxxx DCS group as defined in 3GPP TS 23.038, section 5.
-     */
-    private static final String[] LANGUAGE_CODES_GROUP_2 = {
-            "cs", "he", "ar", "ru", "is", null, null, null, null, null, null, null, null, null,
-            null, null
-    };
-
-    private static final char CARRIAGE_RETURN = 0x0d;
-
-    private static final int PDU_BODY_PAGE_LENGTH = 82;
-
-    /** Utility class with only static methods. */
-    private GsmSmsCbMessage() { }
-
-    /**
-     * Create a new SmsCbMessage object from a header object plus one or more received PDUs.
-     *
-     * @param pdus PDU bytes
-     */
-    static SmsCbMessage createSmsCbMessage(SmsCbHeader header, SmsCbLocation location,
-            byte[][] pdus) throws IllegalArgumentException {
-        if (header.isEtwsPrimaryNotification()) {
-            return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP,
-                    header.getGeographicalScope(), header.getSerialNumber(),
-                    location, header.getServiceCategory(),
-                    null, "ETWS", SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY,
-                    header.getEtwsInfo(), header.getCmasInfo());
-        } else {
-            String language = null;
-            StringBuilder sb = new StringBuilder();
-            for (byte[] pdu : pdus) {
-                Pair<String, String> p = parseBody(header, pdu);
-                language = p.first;
-                sb.append(p.second);
-            }
-            int priority = header.isEmergencyMessage() ? SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY
-                    : SmsCbMessage.MESSAGE_PRIORITY_NORMAL;
-
-            return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP,
-                    header.getGeographicalScope(), header.getSerialNumber(), location,
-                    header.getServiceCategory(), language, sb.toString(), priority,
-                    header.getEtwsInfo(), header.getCmasInfo());
-        }
-    }
-
-    /**
-     * Create a new SmsCbMessage object from one or more received PDUs. This is used by some
-     * CellBroadcastReceiver test cases, because SmsCbHeader is now package local.
-     *
-     * @param location the location (geographical scope) for the message
-     * @param pdus PDU bytes
-     */
-    public static SmsCbMessage createSmsCbMessage(SmsCbLocation location, byte[][] pdus)
-            throws IllegalArgumentException {
-        SmsCbHeader header = new SmsCbHeader(pdus[0]);
-        return createSmsCbMessage(header, location, pdus);
-    }
-
-    /**
-     * Parse and unpack the body text according to the encoding in the DCS.
-     * After completing successfully this method will have assigned the body
-     * text into mBody, and optionally the language code into mLanguage
-     *
-     * @param header the message header to use
-     * @param pdu the PDU to decode
-     * @return a Pair of Strings containing the language and body of the message
-     */
-    private static Pair<String, String> parseBody(SmsCbHeader header, byte[] pdu) {
-        int encoding;
-        String language = null;
-        boolean hasLanguageIndicator = false;
-        int dataCodingScheme = header.getDataCodingScheme();
-
-        // Extract encoding and language from DCS, as defined in 3gpp TS 23.038,
-        // section 5.
-        switch ((dataCodingScheme & 0xf0) >> 4) {
-            case 0x00:
-                encoding = android.telephony.SmsMessage.ENCODING_7BIT;
-                language = LANGUAGE_CODES_GROUP_0[dataCodingScheme & 0x0f];
-                break;
-
-            case 0x01:
-                hasLanguageIndicator = true;
-                if ((dataCodingScheme & 0x0f) == 0x01) {
-                    encoding = android.telephony.SmsMessage.ENCODING_16BIT;
-                } else {
-                    encoding = android.telephony.SmsMessage.ENCODING_7BIT;
-                }
-                break;
-
-            case 0x02:
-                encoding = android.telephony.SmsMessage.ENCODING_7BIT;
-                language = LANGUAGE_CODES_GROUP_2[dataCodingScheme & 0x0f];
-                break;
-
-            case 0x03:
-                encoding = android.telephony.SmsMessage.ENCODING_7BIT;
-                break;
-
-            case 0x04:
-            case 0x05:
-                switch ((dataCodingScheme & 0x0c) >> 2) {
-                    case 0x01:
-                        encoding = android.telephony.SmsMessage.ENCODING_8BIT;
-                        break;
-
-                    case 0x02:
-                        encoding = android.telephony.SmsMessage.ENCODING_16BIT;
-                        break;
-
-                    case 0x00:
-                    default:
-                        encoding = android.telephony.SmsMessage.ENCODING_7BIT;
-                        break;
-                }
-                break;
-
-            case 0x06:
-            case 0x07:
-                // Compression not supported
-            case 0x09:
-                // UDH structure not supported
-            case 0x0e:
-                // Defined by the WAP forum not supported
-                throw new IllegalArgumentException("Unsupported GSM dataCodingScheme "
-                        + dataCodingScheme);
-
-            case 0x0f:
-                if (((dataCodingScheme & 0x04) >> 2) == 0x01) {
-                    encoding = android.telephony.SmsMessage.ENCODING_8BIT;
-                } else {
-                    encoding = android.telephony.SmsMessage.ENCODING_7BIT;
-                }
-                break;
-
-            default:
-                // Reserved values are to be treated as 7-bit
-                encoding = android.telephony.SmsMessage.ENCODING_7BIT;
-                break;
-        }
-
-        if (header.isUmtsFormat()) {
-            // Payload may contain multiple pages
-            int nrPages = pdu[SmsCbHeader.PDU_HEADER_LENGTH];
-
-            if (pdu.length < SmsCbHeader.PDU_HEADER_LENGTH + 1 + (PDU_BODY_PAGE_LENGTH + 1)
-                    * nrPages) {
-                throw new IllegalArgumentException("Pdu length " + pdu.length + " does not match "
-                        + nrPages + " pages");
-            }
-
-            StringBuilder sb = new StringBuilder();
-
-            for (int i = 0; i < nrPages; i++) {
-                // Each page is 82 bytes followed by a length octet indicating
-                // the number of useful octets within those 82
-                int offset = SmsCbHeader.PDU_HEADER_LENGTH + 1 + (PDU_BODY_PAGE_LENGTH + 1) * i;
-                int length = pdu[offset + PDU_BODY_PAGE_LENGTH];
-
-                if (length > PDU_BODY_PAGE_LENGTH) {
-                    throw new IllegalArgumentException("Page length " + length
-                            + " exceeds maximum value " + PDU_BODY_PAGE_LENGTH);
-                }
-
-                Pair<String, String> p = unpackBody(pdu, encoding, offset, length,
-                        hasLanguageIndicator, language);
-                language = p.first;
-                sb.append(p.second);
-            }
-            return new Pair<String, String>(language, sb.toString());
-        } else {
-            // Payload is one single page
-            int offset = SmsCbHeader.PDU_HEADER_LENGTH;
-            int length = pdu.length - offset;
-
-            return unpackBody(pdu, encoding, offset, length, hasLanguageIndicator, language);
-        }
-    }
-
-    /**
-     * Unpack body text from the pdu using the given encoding, position and
-     * length within the pdu
-     *
-     * @param pdu The pdu
-     * @param encoding The encoding, as derived from the DCS
-     * @param offset Position of the first byte to unpack
-     * @param length Number of bytes to unpack
-     * @param hasLanguageIndicator true if the body text is preceded by a
-     *            language indicator. If so, this method will as a side-effect
-     *            assign the extracted language code into mLanguage
-     * @param language the language to return if hasLanguageIndicator is false
-     * @return a Pair of Strings containing the language and body of the message
-     */
-    private static Pair<String, String> unpackBody(byte[] pdu, int encoding, int offset, int length,
-            boolean hasLanguageIndicator, String language) {
-        String body = null;
-
-        switch (encoding) {
-            case android.telephony.SmsMessage.ENCODING_7BIT:
-                body = GsmAlphabet.gsm7BitPackedToString(pdu, offset, length * 8 / 7);
-
-                if (hasLanguageIndicator && body != null && body.length() > 2) {
-                    // Language is two GSM characters followed by a CR.
-                    // The actual body text is offset by 3 characters.
-                    language = body.substring(0, 2);
-                    body = body.substring(3);
-                }
-                break;
-
-            case android.telephony.SmsMessage.ENCODING_16BIT:
-                if (hasLanguageIndicator && pdu.length >= offset + 2) {
-                    // Language is two GSM characters.
-                    // The actual body text is offset by 2 bytes.
-                    language = GsmAlphabet.gsm7BitPackedToString(pdu, offset, 2);
-                    offset += 2;
-                    length -= 2;
-                }
-
-                try {
-                    body = new String(pdu, offset, (length & 0xfffe), "utf-16");
-                } catch (UnsupportedEncodingException e) {
-                    // Apparently it wasn't valid UTF-16.
-                    throw new IllegalArgumentException("Error decoding UTF-16 message", e);
-                }
-                break;
-
-            default:
-                break;
-        }
-
-        if (body != null) {
-            // Remove trailing carriage return
-            for (int i = body.length() - 1; i >= 0; i--) {
-                if (body.charAt(i) != CARRIAGE_RETURN) {
-                    body = body.substring(0, i + 1);
-                    break;
-                }
-            }
-        } else {
-            body = "";
-        }
-
-        return new Pair<String, String>(language, body);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java b/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java
deleted file mode 100644
index dcc9cfd..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java
+++ /dev/null
@@ -1,107 +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.internal.telephony.gsm;
-
-import android.os.Message;
-import android.util.Log;
-
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccCardApplication;
-import com.android.internal.telephony.IccConstants;
-import com.android.internal.telephony.IccFileHandler;
-import com.android.internal.telephony.PhoneBase;
-
-/**
- * {@hide}
- */
-public final class SIMFileHandler extends IccFileHandler implements IccConstants {
-    static final String LOG_TAG = "GSM";
-
-    //***** Instance Variables
-
-    //***** Constructor
-
-    public SIMFileHandler(IccCard card, String aid, CommandsInterface ci) {
-        super(card, aid, ci);
-    }
-
-    protected void finalize() {
-        Log.d(LOG_TAG, "SIMFileHandler finalized");
-    }
-
-    //***** Overridden from IccFileHandler
-
-    @Override
-    public void handleMessage(Message msg) {
-        super.handleMessage(msg);
-    }
-
-    protected String getEFPath(int efid) {
-        // TODO(): DF_GSM can be 7F20 or 7F21 to handle backward compatibility.
-        // Implement this after discussion with OEMs.
-        switch(efid) {
-        case EF_SMS:
-            return MF_SIM + DF_TELECOM;
-
-        case EF_EXT6:
-        case EF_MWIS:
-        case EF_MBI:
-        case EF_SPN:
-        case EF_AD:
-        case EF_MBDN:
-        case EF_PNN:
-        case EF_SPDI:
-        case EF_SST:
-        case EF_CFIS:
-            return MF_SIM + DF_GSM;
-
-        case EF_MAILBOX_CPHS:
-        case EF_VOICE_MAIL_INDICATOR_CPHS:
-        case EF_CFF_CPHS:
-        case EF_SPN_CPHS:
-        case EF_SPN_SHORT_CPHS:
-        case EF_INFO_CPHS:
-        case EF_CSP_CPHS:
-            return MF_SIM + DF_GSM;
-
-        case EF_PBR:
-            // we only support global phonebook.
-            return MF_SIM + DF_TELECOM + DF_PHONEBOOK;
-        }
-        String path = getCommonIccEFPath(efid);
-        if (path == null) {
-            // The EFids in USIM phone book entries are decided by the card manufacturer.
-            // So if we don't match any of the cases above and if its a USIM return
-            // the phone book path.
-            if (mParentCard != null
-                    && mParentCard.isApplicationOnIcc(IccCardApplication.AppType.APPTYPE_USIM)) {
-                return MF_SIM + DF_TELECOM + DF_PHONEBOOK;
-            }
-            Log.e(LOG_TAG, "Error: EF Path being returned in null");
-        }
-        return path;
-    }
-
-    protected void logd(String msg) {
-        Log.d(LOG_TAG, "[SIMFileHandler] " + msg);
-    }
-
-    protected void loge(String msg) {
-        Log.e(LOG_TAG, "[SIMFileHandler] " + msg);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
deleted file mode 100755
index 52e2caf..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ /dev/null
@@ -1,1674 +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.internal.telephony.gsm;
-
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
-import android.content.Context;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.util.Log;
-
-import com.android.internal.telephony.AdnRecord;
-import com.android.internal.telephony.AdnRecordCache;
-import com.android.internal.telephony.AdnRecordLoader;
-import com.android.internal.telephony.BaseCommands;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccFileHandler;
-import com.android.internal.telephony.IccRecords;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.IccVmFixedException;
-import com.android.internal.telephony.IccVmNotSupportedException;
-import com.android.internal.telephony.MccTable;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.SmsMessageBase;
-import com.android.internal.telephony.IccRefreshResponse;
-
-import java.util.ArrayList;
-
-
-/**
- * {@hide}
- */
-public class SIMRecords extends IccRecords {
-    protected static final String LOG_TAG = "GSM";
-
-    private static final boolean CRASH_RIL = false;
-
-    protected static final boolean DBG = true;
-
-    // ***** Instance Variables
-
-    VoiceMailConstants mVmConfig;
-
-
-    SpnOverride mSpnOverride;
-
-    // ***** Cached SIM State; cleared on channel close
-
-    private String imsi;
-    private boolean callForwardingEnabled;
-
-
-    /**
-     * States only used by getSpnFsm FSM
-     */
-    private Get_Spn_Fsm_State spnState;
-
-    /** CPHS service information (See CPHS 4.2 B.3.1.1)
-     *  It will be set in onSimReady if reading GET_CPHS_INFO successfully
-     *  mCphsInfo[0] is CPHS Phase
-     *  mCphsInfo[1] and mCphsInfo[2] is CPHS Service Table
-     */
-    private byte[] mCphsInfo = null;
-    boolean mCspPlmnEnabled = true;
-
-    byte[] efMWIS = null;
-    byte[] efCPHS_MWI =null;
-    byte[] mEfCff = null;
-    byte[] mEfCfis = null;
-
-
-    int spnDisplayCondition;
-    // Numeric network codes listed in TS 51.011 EF[SPDI]
-    ArrayList<String> spdiNetworks = null;
-
-    String pnnHomeName = null;
-
-    UsimServiceTable mUsimServiceTable;
-
-    // ***** Constants
-
-    // Bitmasks for SPN display rules.
-    static final int SPN_RULE_SHOW_SPN  = 0x01;
-    static final int SPN_RULE_SHOW_PLMN = 0x02;
-
-    // From TS 51.011 EF[SPDI] section
-    static final int TAG_SPDI = 0xA3;
-    static final int TAG_SPDI_PLMN_LIST = 0x80;
-
-    // Full Name IEI from TS 24.008
-    static final int TAG_FULL_NETWORK_NAME = 0x43;
-
-    // Short Name IEI from TS 24.008
-    static final int TAG_SHORT_NETWORK_NAME = 0x45;
-
-    // active CFF from CPHS 4.2 B.4.5
-    static final int CFF_UNCONDITIONAL_ACTIVE = 0x0a;
-    static final int CFF_UNCONDITIONAL_DEACTIVE = 0x05;
-    static final int CFF_LINE1_MASK = 0x0f;
-    static final int CFF_LINE1_RESET = 0xf0;
-
-    // CPHS Service Table (See CPHS 4.2 B.3.1)
-    private static final int CPHS_SST_MBN_MASK = 0x30;
-    private static final int CPHS_SST_MBN_ENABLED = 0x30;
-
-    // ***** Event Constants
-
-    private static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 2;
-    protected static final int EVENT_GET_IMSI_DONE = 3;
-    protected static final int EVENT_GET_ICCID_DONE = 4;
-    private static final int EVENT_GET_MBI_DONE = 5;
-    private static final int EVENT_GET_MBDN_DONE = 6;
-    private static final int EVENT_GET_MWIS_DONE = 7;
-    private static final int EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE = 8;
-    protected static final int EVENT_GET_AD_DONE = 9; // Admin data on SIM
-    protected static final int EVENT_GET_MSISDN_DONE = 10;
-    private static final int EVENT_GET_CPHS_MAILBOX_DONE = 11;
-    private static final int EVENT_GET_SPN_DONE = 12;
-    private static final int EVENT_GET_SPDI_DONE = 13;
-    private static final int EVENT_UPDATE_DONE = 14;
-    private static final int EVENT_GET_PNN_DONE = 15;
-    protected static final int EVENT_GET_SST_DONE = 17;
-    private static final int EVENT_GET_ALL_SMS_DONE = 18;
-    private static final int EVENT_MARK_SMS_READ_DONE = 19;
-    private static final int EVENT_SET_MBDN_DONE = 20;
-    private static final int EVENT_SMS_ON_SIM = 21;
-    private static final int EVENT_GET_SMS_DONE = 22;
-    private static final int EVENT_GET_CFF_DONE = 24;
-    private static final int EVENT_SET_CPHS_MAILBOX_DONE = 25;
-    private static final int EVENT_GET_INFO_CPHS_DONE = 26;
-    private static final int EVENT_SET_MSISDN_DONE = 30;
-    private static final int EVENT_SIM_REFRESH = 31;
-    private static final int EVENT_GET_CFIS_DONE = 32;
-    private static final int EVENT_GET_CSP_CPHS_DONE = 33;
-
-    // Lookup table for carriers known to produce SIMs which incorrectly indicate MNC length.
-
-    private static final String[] MCCMNC_CODES_HAVING_3DIGITS_MNC = {
-        "405025", "405026", "405027", "405028", "405029", "405030", "405031", "405032",
-        "405033", "405034", "405035", "405036", "405037", "405038", "405039", "405040",
-        "405041", "405042", "405043", "405044", "405045", "405046", "405047", "405750",
-        "405751", "405752", "405753", "405754", "405755", "405756", "405799", "405800",
-        "405801", "405802", "405803", "405804", "405805", "405806", "405807", "405808",
-        "405809", "405810", "405811", "405812", "405813", "405814", "405815", "405816",
-        "405817", "405818", "405819", "405820", "405821", "405822", "405823", "405824",
-        "405825", "405826", "405827", "405828", "405829", "405830", "405831", "405832",
-        "405833", "405834", "405835", "405836", "405837", "405838", "405839", "405840",
-        "405841", "405842", "405843", "405844", "405845", "405846", "405847", "405848",
-        "405849", "405850", "405851", "405852", "405853", "405875", "405876", "405877",
-        "405878", "405879", "405880", "405881", "405882", "405883", "405884", "405885",
-        "405886", "405908", "405909", "405910", "405911", "405912", "405913", "405914",
-        "405915", "405916", "405917", "405918", "405919", "405920", "405921", "405922",
-        "405923", "405924", "405925", "405926", "405927", "405928", "405929", "405930",
-        "405931", "405932"
-    };
-
-    // ***** Constructor
-
-    public SIMRecords(IccCard card, Context c, CommandsInterface ci) {
-        super(card, c, ci);
-
-        adnCache = new AdnRecordCache(mFh);
-
-        mVmConfig = new VoiceMailConstants();
-        mSpnOverride = new SpnOverride();
-
-        recordsRequested = false;  // No load request is made till SIM ready
-
-        // recordsToLoad is set to 0 because no requests are made yet
-        recordsToLoad = 0;
-
-        mCi.registerForOffOrNotAvailable(
-                        this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
-        mCi.setOnSmsOnSim(this, EVENT_SMS_ON_SIM, null);
-        mCi.registerForIccRefresh(this, EVENT_SIM_REFRESH, null);
-
-        // Start off by setting empty state
-        onRadioOffOrNotAvailable();
-
-    }
-
-    @Override
-    public void dispose() {
-        if (DBG) log("Disposing SIMRecords " + this);
-        //Unregister for all events
-        mCi.unregisterForOffOrNotAvailable( this);
-        mCi.unregisterForIccRefresh(this);
-        mCi.unSetOnSmsOnSim(this);
-        super.dispose();
-    }
-
-    protected void finalize() {
-        if(DBG) log("finalized");
-    }
-
-    protected void onRadioOffOrNotAvailable() {
-        imsi = null;
-        msisdn = null;
-        voiceMailNum = null;
-        countVoiceMessages = 0;
-        mncLength = UNINITIALIZED;
-        iccid = null;
-        // -1 means no EF_SPN found; treat accordingly.
-        spnDisplayCondition = -1;
-        efMWIS = null;
-        efCPHS_MWI = null;
-        spdiNetworks = null;
-        pnnHomeName = null;
-
-        adnCache.reset();
-
-        log("SIMRecords: onRadioOffOrNotAvailable set 'gsm.sim.operator.numeric' to operator=null");
-        SystemProperties.set(PROPERTY_ICC_OPERATOR_NUMERIC, null);
-        SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, null);
-        SystemProperties.set(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, null);
-
-        // recordsRequested is set to false indicating that the SIM
-        // read requests made so far are not valid. This is set to
-        // true only when fresh set of read requests are made.
-        recordsRequested = false;
-    }
-
-
-    //***** Public Methods
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String getIMSI() {
-        return imsi;
-    }
-
-    public String getMsisdnNumber() {
-        return msisdn;
-    }
-
-    @Override
-    public UsimServiceTable getUsimServiceTable() {
-        return mUsimServiceTable;
-    }
-
-    /**
-     * Set subscriber number to SIM record
-     *
-     * The subscriber number is stored in EF_MSISDN (TS 51.011)
-     *
-     * When the operation is complete, onComplete will be sent to its handler
-     *
-     * @param alphaTag alpha-tagging of the dailing nubmer (up to 10 characters)
-     * @param number dailing nubmer (up to 20 digits)
-     *        if the number starts with '+', then set to international TOA
-     * @param onComplete
-     *        onComplete.obj will be an AsyncResult
-     *        ((AsyncResult)onComplete.obj).exception == null on success
-     *        ((AsyncResult)onComplete.obj).exception != null on fail
-     */
-    public void setMsisdnNumber(String alphaTag, String number,
-            Message onComplete) {
-
-        msisdn = number;
-        msisdnTag = alphaTag;
-
-        if(DBG) log("Set MSISDN: " + msisdnTag + " " + /*msisdn*/ "xxxxxxx");
-
-
-        AdnRecord adn = new AdnRecord(msisdnTag, msisdn);
-
-        new AdnRecordLoader(mFh).updateEF(adn, EF_MSISDN, EF_EXT1, 1, null,
-                obtainMessage(EVENT_SET_MSISDN_DONE, onComplete));
-    }
-
-    public String getMsisdnAlphaTag() {
-        return msisdnTag;
-    }
-
-    public String getVoiceMailNumber() {
-        return voiceMailNum;
-    }
-
-    /**
-     * Set voice mail number to SIM record
-     *
-     * The voice mail number can be stored either in EF_MBDN (TS 51.011) or
-     * EF_MAILBOX_CPHS (CPHS 4.2)
-     *
-     * If EF_MBDN is available, store the voice mail number to EF_MBDN
-     *
-     * If EF_MAILBOX_CPHS is enabled, store the voice mail number to EF_CHPS
-     *
-     * So the voice mail number will be stored in both EFs if both are available
-     *
-     * Return error only if both EF_MBDN and EF_MAILBOX_CPHS fail.
-     *
-     * When the operation is complete, onComplete will be sent to its handler
-     *
-     * @param alphaTag alpha-tagging of the dailing nubmer (upto 10 characters)
-     * @param voiceNumber dailing nubmer (upto 20 digits)
-     *        if the number is start with '+', then set to international TOA
-     * @param onComplete
-     *        onComplete.obj will be an AsyncResult
-     *        ((AsyncResult)onComplete.obj).exception == null on success
-     *        ((AsyncResult)onComplete.obj).exception != null on fail
-     */
-    public void setVoiceMailNumber(String alphaTag, String voiceNumber,
-            Message onComplete) {
-        if (isVoiceMailFixed) {
-            AsyncResult.forMessage((onComplete)).exception =
-                    new IccVmFixedException("Voicemail number is fixed by operator");
-            onComplete.sendToTarget();
-            return;
-        }
-
-        newVoiceMailNum = voiceNumber;
-        newVoiceMailTag = alphaTag;
-
-        AdnRecord adn = new AdnRecord(newVoiceMailTag, newVoiceMailNum);
-
-        if (mailboxIndex != 0 && mailboxIndex != 0xff) {
-
-            new AdnRecordLoader(mFh).updateEF(adn, EF_MBDN, EF_EXT6,
-                    mailboxIndex, null,
-                    obtainMessage(EVENT_SET_MBDN_DONE, onComplete));
-
-        } else if (isCphsMailboxEnabled()) {
-
-            new AdnRecordLoader(mFh).updateEF(adn, EF_MAILBOX_CPHS,
-                    EF_EXT1, 1, null,
-                    obtainMessage(EVENT_SET_CPHS_MAILBOX_DONE, onComplete));
-
-        } else {
-            AsyncResult.forMessage((onComplete)).exception =
-                    new IccVmNotSupportedException("Update SIM voice mailbox error");
-            onComplete.sendToTarget();
-        }
-    }
-
-    public String getVoiceMailAlphaTag()
-    {
-        return voiceMailTag;
-    }
-
-    /**
-     * Sets the SIM voice message waiting indicator records
-     * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
-     * @param countWaiting The number of messages waiting, if known. Use
-     *                     -1 to indicate that an unknown number of
-     *                      messages are waiting
-     */
-    public void
-    setVoiceMessageWaiting(int line, int countWaiting) {
-        if (line != 1) {
-            // only profile 1 is supported
-            return;
-        }
-
-        // range check
-        if (countWaiting < 0) {
-            countWaiting = -1;
-        } else if (countWaiting > 0xff) {
-            // TS 23.040 9.2.3.24.2
-            // "The value 255 shall be taken to mean 255 or greater"
-            countWaiting = 0xff;
-        }
-
-        countVoiceMessages = countWaiting;
-
-        mRecordsEventsRegistrants.notifyResult(EVENT_MWI);
-
-        try {
-            if (efMWIS != null) {
-                // TS 51.011 10.3.45
-
-                // lsb of byte 0 is 'voicemail' status
-                efMWIS[0] = (byte)((efMWIS[0] & 0xfe)
-                                    | (countVoiceMessages == 0 ? 0 : 1));
-
-                // byte 1 is the number of voice messages waiting
-                if (countWaiting < 0) {
-                    // The spec does not define what this should be
-                    // if we don't know the count
-                    efMWIS[1] = 0;
-                } else {
-                    efMWIS[1] = (byte) countWaiting;
-                }
-
-                mFh.updateEFLinearFixed(
-                    EF_MWIS, 1, efMWIS, null,
-                    obtainMessage (EVENT_UPDATE_DONE, EF_MWIS));
-            }
-
-            if (efCPHS_MWI != null) {
-                    // Refer CPHS4_2.WW6 B4.2.3
-                efCPHS_MWI[0] = (byte)((efCPHS_MWI[0] & 0xf0)
-                            | (countVoiceMessages == 0 ? 0x5 : 0xa));
-
-                mFh.updateEFTransparent(
-                    EF_VOICE_MAIL_INDICATOR_CPHS, efCPHS_MWI,
-                    obtainMessage (EVENT_UPDATE_DONE, EF_VOICE_MAIL_INDICATOR_CPHS));
-            }
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            logw("Error saving voice mail state to SIM. Probably malformed SIM record", ex);
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean getVoiceCallForwardingFlag() {
-        return callForwardingEnabled;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setVoiceCallForwardingFlag(int line, boolean enable) {
-
-        if (line != 1) return; // only line 1 is supported
-
-        callForwardingEnabled = enable;
-
-        mRecordsEventsRegistrants.notifyResult(EVENT_CFI);
-
-        try {
-            if (mEfCfis != null) {
-                // lsb is of byte 1 is voice status
-                if (enable) {
-                    mEfCfis[1] |= 1;
-                } else {
-                    mEfCfis[1] &= 0xfe;
-                }
-
-                // TODO: Should really update other fields in EF_CFIS, eg,
-                // dialing number.  We don't read or use it right now.
-
-                mFh.updateEFLinearFixed(
-                        EF_CFIS, 1, mEfCfis, null,
-                        obtainMessage (EVENT_UPDATE_DONE, EF_CFIS));
-            }
-
-            if (mEfCff != null) {
-                if (enable) {
-                    mEfCff[0] = (byte) ((mEfCff[0] & CFF_LINE1_RESET)
-                            | CFF_UNCONDITIONAL_ACTIVE);
-                } else {
-                    mEfCff[0] = (byte) ((mEfCff[0] & CFF_LINE1_RESET)
-                            | CFF_UNCONDITIONAL_DEACTIVE);
-                }
-
-                mFh.updateEFTransparent(
-                        EF_CFF_CPHS, mEfCff,
-                        obtainMessage (EVENT_UPDATE_DONE, EF_CFF_CPHS));
-            }
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            logw("Error saving call fowarding flag to SIM. "
-                            + "Probably malformed SIM record", ex);
-
-        }
-    }
-
-    /**
-     * Called by STK Service when REFRESH is received.
-     * @param fileChanged indicates whether any files changed
-     * @param fileList if non-null, a list of EF files that changed
-     */
-    public void onRefresh(boolean fileChanged, int[] fileList) {
-        if (fileChanged) {
-            // A future optimization would be to inspect fileList and
-            // only reload those files that we care about.  For now,
-            // just re-fetch all SIM records that we cache.
-            fetchSimRecords();
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String getOperatorNumeric() {
-        if (imsi == null) {
-            log("getOperatorNumeric: IMSI == null");
-            return null;
-        }
-        if (mncLength == UNINITIALIZED || mncLength == UNKNOWN) {
-            log("getSIMOperatorNumeric: bad mncLength");
-            return null;
-        }
-
-        // Length = length of MCC + length of MNC
-        // length of mcc = 3 (TS 23.003 Section 2.2)
-        return imsi.substring(0, 3 + mncLength);
-    }
-
-    // ***** Overridden from Handler
-    public void handleMessage(Message msg) {
-        AsyncResult ar;
-        AdnRecord adn;
-
-        byte data[];
-
-        boolean isRecordLoadResponse = false;
-
-        if (mDestroyed) {
-            loge("Received message " + msg + "[" + msg.what + "] " +
-                    " while being destroyed. Ignoring.");
-            return;
-        }
-
-        try { switch (msg.what) {
-            case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
-                onRadioOffOrNotAvailable();
-            break;
-
-            /* IO events */
-            case EVENT_GET_IMSI_DONE:
-                isRecordLoadResponse = true;
-
-                ar = (AsyncResult)msg.obj;
-
-                if (ar.exception != null) {
-                    loge("Exception querying IMSI, Exception:" + ar.exception);
-                    break;
-                }
-
-                imsi = (String) ar.result;
-
-                // IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more
-                // than 15 (and usually 15).
-                if (imsi != null && (imsi.length() < 6 || imsi.length() > 15)) {
-                    loge("invalid IMSI " + imsi);
-                    imsi = null;
-                }
-
-                log("IMSI: " + /* imsi.substring(0, 6) +*/ "xxxxxxx");
-
-                if (((mncLength == UNKNOWN) || (mncLength == 2)) &&
-                        ((imsi != null) && (imsi.length() >= 6))) {
-                    String mccmncCode = imsi.substring(0, 6);
-                    for (String mccmnc : MCCMNC_CODES_HAVING_3DIGITS_MNC) {
-                        if (mccmnc.equals(mccmncCode)) {
-                            mncLength = 3;
-                            break;
-                        }
-                    }
-                }
-
-                if (mncLength == UNKNOWN) {
-                    // the SIM has told us all it knows, but it didn't know the mnc length.
-                    // guess using the mcc
-                    try {
-                        int mcc = Integer.parseInt(imsi.substring(0,3));
-                        mncLength = MccTable.smallestDigitsMccForMnc(mcc);
-                    } catch (NumberFormatException e) {
-                        mncLength = UNKNOWN;
-                        loge("Corrupt IMSI!");
-                    }
-                }
-
-                if (mncLength != UNKNOWN && mncLength != UNINITIALIZED) {
-                    // finally have both the imsi and the mncLength and can parse the imsi properly
-                    MccTable.updateMccMncConfiguration(mContext, imsi.substring(0, 3 + mncLength));
-                }
-                mParentCard.broadcastIccStateChangedIntent(
-                        IccCard.INTENT_VALUE_ICC_IMSI, null);
-            break;
-
-            case EVENT_GET_MBI_DONE:
-                boolean isValidMbdn;
-                isRecordLoadResponse = true;
-
-                ar = (AsyncResult)msg.obj;
-                data = (byte[]) ar.result;
-
-                isValidMbdn = false;
-                if (ar.exception == null) {
-                    // Refer TS 51.011 Section 10.3.44 for content details
-                    log("EF_MBI: " + IccUtils.bytesToHexString(data));
-
-                    // Voice mail record number stored first
-                    mailboxIndex = (int)data[0] & 0xff;
-
-                    // check if dailing numbe id valid
-                    if (mailboxIndex != 0 && mailboxIndex != 0xff) {
-                        log("Got valid mailbox number for MBDN");
-                        isValidMbdn = true;
-                    }
-                }
-
-                // one more record to load
-                recordsToLoad += 1;
-
-                if (isValidMbdn) {
-                    // Note: MBDN was not included in NUM_OF_SIM_RECORDS_LOADED
-                    new AdnRecordLoader(mFh).loadFromEF(EF_MBDN, EF_EXT6,
-                            mailboxIndex, obtainMessage(EVENT_GET_MBDN_DONE));
-                } else {
-                    // If this EF not present, try mailbox as in CPHS standard
-                    // CPHS (CPHS4_2.WW6) is a european standard.
-                    new AdnRecordLoader(mFh).loadFromEF(EF_MAILBOX_CPHS,
-                            EF_EXT1, 1,
-                            obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
-                }
-
-                break;
-            case EVENT_GET_CPHS_MAILBOX_DONE:
-            case EVENT_GET_MBDN_DONE:
-                //Resetting the voice mail number and voice mail tag to null
-                //as these should be updated from the data read from EF_MBDN.
-                //If they are not reset, incase of invalid data/exception these
-                //variables are retaining their previous values and are
-                //causing invalid voice mailbox info display to user.
-                voiceMailNum = null;
-                voiceMailTag = null;
-                isRecordLoadResponse = true;
-
-                ar = (AsyncResult)msg.obj;
-
-                if (ar.exception != null) {
-
-                    log("Invalid or missing EF"
-                        + ((msg.what == EVENT_GET_CPHS_MAILBOX_DONE) ? "[MAILBOX]" : "[MBDN]"));
-
-                    // Bug #645770 fall back to CPHS
-                    // FIXME should use SST to decide
-
-                    if (msg.what == EVENT_GET_MBDN_DONE) {
-                        //load CPHS on fail...
-                        // FIXME right now, only load line1's CPHS voice mail entry
-
-                        recordsToLoad += 1;
-                        new AdnRecordLoader(mFh).loadFromEF(
-                                EF_MAILBOX_CPHS, EF_EXT1, 1,
-                                obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
-                    }
-                    break;
-                }
-
-                adn = (AdnRecord)ar.result;
-
-                log("VM: " + adn +
-                        ((msg.what == EVENT_GET_CPHS_MAILBOX_DONE) ? " EF[MAILBOX]" : " EF[MBDN]"));
-
-                if (adn.isEmpty() && msg.what == EVENT_GET_MBDN_DONE) {
-                    // Bug #645770 fall back to CPHS
-                    // FIXME should use SST to decide
-                    // FIXME right now, only load line1's CPHS voice mail entry
-                    recordsToLoad += 1;
-                    new AdnRecordLoader(mFh).loadFromEF(
-                            EF_MAILBOX_CPHS, EF_EXT1, 1,
-                            obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
-
-                    break;
-                }
-
-                voiceMailNum = adn.getNumber();
-                voiceMailTag = adn.getAlphaTag();
-            break;
-
-            case EVENT_GET_MSISDN_DONE:
-                isRecordLoadResponse = true;
-
-                ar = (AsyncResult)msg.obj;
-
-                if (ar.exception != null) {
-                    log("Invalid or missing EF[MSISDN]");
-                    break;
-                }
-
-                adn = (AdnRecord)ar.result;
-
-                msisdn = adn.getNumber();
-                msisdnTag = adn.getAlphaTag();
-
-                log("MSISDN: " + /*msisdn*/ "xxxxxxx");
-            break;
-
-            case EVENT_SET_MSISDN_DONE:
-                isRecordLoadResponse = false;
-                ar = (AsyncResult)msg.obj;
-
-                if (ar.userObj != null) {
-                    AsyncResult.forMessage(((Message) ar.userObj)).exception
-                            = ar.exception;
-                    ((Message) ar.userObj).sendToTarget();
-                }
-                break;
-
-            case EVENT_GET_MWIS_DONE:
-                isRecordLoadResponse = true;
-
-                ar = (AsyncResult)msg.obj;
-                data = (byte[])ar.result;
-
-                if (ar.exception != null) {
-                    break;
-                }
-
-                log("EF_MWIS: " + IccUtils.bytesToHexString(data));
-
-                efMWIS = data;
-
-                if ((data[0] & 0xff) == 0xff) {
-                    log("Uninitialized record MWIS");
-                    break;
-                }
-
-                // Refer TS 51.011 Section 10.3.45 for the content description
-                boolean voiceMailWaiting = ((data[0] & 0x01) != 0);
-                countVoiceMessages = data[1] & 0xff;
-
-                if (voiceMailWaiting && countVoiceMessages == 0) {
-                    // Unknown count = -1
-                    countVoiceMessages = -1;
-                }
-
-                mRecordsEventsRegistrants.notifyResult(EVENT_MWI);
-            break;
-
-            case EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE:
-                isRecordLoadResponse = true;
-
-                ar = (AsyncResult)msg.obj;
-                data = (byte[])ar.result;
-
-                if (ar.exception != null) {
-                    break;
-                }
-
-                efCPHS_MWI = data;
-
-                // Use this data if the EF[MWIS] exists and
-                // has been loaded
-
-                if (efMWIS == null) {
-                    int indicator = (int)(data[0] & 0xf);
-
-                    // Refer CPHS4_2.WW6 B4.2.3
-                    if (indicator == 0xA) {
-                        // Unknown count = -1
-                        countVoiceMessages = -1;
-                    } else if (indicator == 0x5) {
-                        countVoiceMessages = 0;
-                    }
-
-                    mRecordsEventsRegistrants.notifyResult(EVENT_MWI);
-                }
-            break;
-
-            case EVENT_GET_ICCID_DONE:
-                isRecordLoadResponse = true;
-
-                ar = (AsyncResult)msg.obj;
-                data = (byte[])ar.result;
-
-                if (ar.exception != null) {
-                    break;
-                }
-
-                iccid = IccUtils.bcdToString(data, 0, data.length);
-
-                log("iccid: " + iccid);
-
-            break;
-
-
-            case EVENT_GET_AD_DONE:
-                try {
-                    isRecordLoadResponse = true;
-
-                    ar = (AsyncResult)msg.obj;
-                    data = (byte[])ar.result;
-
-                    if (ar.exception != null) {
-                        break;
-                    }
-
-                    log("EF_AD: " + IccUtils.bytesToHexString(data));
-
-                    if (data.length < 3) {
-                        log("Corrupt AD data on SIM");
-                        break;
-                    }
-
-                    if (data.length == 3) {
-                        log("MNC length not present in EF_AD");
-                        break;
-                    }
-
-                    mncLength = (int)data[3] & 0xf;
-
-                    if (mncLength == 0xf) {
-                        mncLength = UNKNOWN;
-                    }
-                } finally {
-                    if (((mncLength == UNINITIALIZED) || (mncLength == UNKNOWN) ||
-                            (mncLength == 2)) && ((imsi != null) && (imsi.length() >= 6))) {
-                        String mccmncCode = imsi.substring(0, 6);
-                        for (String mccmnc : MCCMNC_CODES_HAVING_3DIGITS_MNC) {
-                            if (mccmnc.equals(mccmncCode)) {
-                                mncLength = 3;
-                                break;
-                            }
-                        }
-                    }
-
-                    if (mncLength == UNKNOWN || mncLength == UNINITIALIZED) {
-                        if (imsi != null) {
-                            try {
-                                int mcc = Integer.parseInt(imsi.substring(0,3));
-
-                                mncLength = MccTable.smallestDigitsMccForMnc(mcc);
-                            } catch (NumberFormatException e) {
-                                mncLength = UNKNOWN;
-                                loge("Corrupt IMSI!");
-                            }
-                        } else {
-                            // Indicate we got this info, but it didn't contain the length.
-                            mncLength = UNKNOWN;
-
-                            log("MNC length not present in EF_AD");
-                        }
-                    }
-                    if (imsi != null && mncLength != UNKNOWN) {
-                        // finally have both imsi and the length of the mnc and can parse
-                        // the imsi properly
-                        MccTable.updateMccMncConfiguration(mContext,
-                                imsi.substring(0, 3 + mncLength));
-                    }
-                }
-            break;
-
-            case EVENT_GET_SPN_DONE:
-                isRecordLoadResponse = true;
-                ar = (AsyncResult) msg.obj;
-                getSpnFsm(false, ar);
-            break;
-
-            case EVENT_GET_CFF_DONE:
-                isRecordLoadResponse = true;
-
-                ar = (AsyncResult) msg.obj;
-                data = (byte[]) ar.result;
-
-                if (ar.exception != null) {
-                    break;
-                }
-
-                log("EF_CFF_CPHS: " + IccUtils.bytesToHexString(data));
-                mEfCff = data;
-
-                if (mEfCfis == null) {
-                    callForwardingEnabled =
-                        ((data[0] & CFF_LINE1_MASK) == CFF_UNCONDITIONAL_ACTIVE);
-
-                    mRecordsEventsRegistrants.notifyResult(EVENT_CFI);
-                }
-                break;
-
-            case EVENT_GET_SPDI_DONE:
-                isRecordLoadResponse = true;
-
-                ar = (AsyncResult)msg.obj;
-                data = (byte[])ar.result;
-
-                if (ar.exception != null) {
-                    break;
-                }
-
-                parseEfSpdi(data);
-            break;
-
-            case EVENT_UPDATE_DONE:
-                ar = (AsyncResult)msg.obj;
-                if (ar.exception != null) {
-                    logw("update failed. ", ar.exception);
-                }
-            break;
-
-            case EVENT_GET_PNN_DONE:
-                isRecordLoadResponse = true;
-
-                ar = (AsyncResult)msg.obj;
-                data = (byte[])ar.result;
-
-                if (ar.exception != null) {
-                    break;
-                }
-
-                SimTlv tlv = new SimTlv(data, 0, data.length);
-
-                for ( ; tlv.isValidObject() ; tlv.nextObject()) {
-                    if (tlv.getTag() == TAG_FULL_NETWORK_NAME) {
-                        pnnHomeName
-                            = IccUtils.networkNameToString(
-                                tlv.getData(), 0, tlv.getData().length);
-                        break;
-                    }
-                }
-            break;
-
-            case EVENT_GET_ALL_SMS_DONE:
-                isRecordLoadResponse = true;
-
-                ar = (AsyncResult)msg.obj;
-                if (ar.exception != null)
-                    break;
-
-                handleSmses((ArrayList) ar.result);
-                break;
-
-            case EVENT_MARK_SMS_READ_DONE:
-                Log.i("ENF", "marked read: sms " + msg.arg1);
-                break;
-
-
-            case EVENT_SMS_ON_SIM:
-                isRecordLoadResponse = false;
-
-                ar = (AsyncResult)msg.obj;
-
-                int[] index = (int[])ar.result;
-
-                if (ar.exception != null || index.length != 1) {
-                    loge("Error on SMS_ON_SIM with exp "
-                            + ar.exception + " length " + index.length);
-                } else {
-                    log("READ EF_SMS RECORD index=" + index[0]);
-                    mFh.loadEFLinearFixed(EF_SMS,index[0],
-                            obtainMessage(EVENT_GET_SMS_DONE));
-                }
-                break;
-
-            case EVENT_GET_SMS_DONE:
-                isRecordLoadResponse = false;
-                ar = (AsyncResult)msg.obj;
-                if (ar.exception == null) {
-                    handleSms((byte[])ar.result);
-                } else {
-                    loge("Error on GET_SMS with exp " + ar.exception);
-                }
-                break;
-            case EVENT_GET_SST_DONE:
-                isRecordLoadResponse = true;
-
-                ar = (AsyncResult)msg.obj;
-                data = (byte[])ar.result;
-
-                if (ar.exception != null) {
-                    break;
-                }
-
-                mUsimServiceTable = new UsimServiceTable(data);
-                if (DBG) log("SST: " + mUsimServiceTable);
-                break;
-
-            case EVENT_GET_INFO_CPHS_DONE:
-                isRecordLoadResponse = true;
-
-                ar = (AsyncResult)msg.obj;
-
-                if (ar.exception != null) {
-                    break;
-                }
-
-                mCphsInfo = (byte[])ar.result;
-
-                if (DBG) log("iCPHS: " + IccUtils.bytesToHexString(mCphsInfo));
-            break;
-
-            case EVENT_SET_MBDN_DONE:
-                isRecordLoadResponse = false;
-                ar = (AsyncResult)msg.obj;
-
-                if (ar.exception == null) {
-                    voiceMailNum = newVoiceMailNum;
-                    voiceMailTag = newVoiceMailTag;
-                }
-
-                if (isCphsMailboxEnabled()) {
-                    adn = new AdnRecord(voiceMailTag, voiceMailNum);
-                    Message onCphsCompleted = (Message) ar.userObj;
-
-                    /* write to cphs mailbox whenever it is available but
-                    * we only need notify caller once if both updating are
-                    * successful.
-                    *
-                    * so if set_mbdn successful, notify caller here and set
-                    * onCphsCompleted to null
-                    */
-                    if (ar.exception == null && ar.userObj != null) {
-                        AsyncResult.forMessage(((Message) ar.userObj)).exception
-                                = null;
-                        ((Message) ar.userObj).sendToTarget();
-
-                        if (DBG) log("Callback with MBDN successful.");
-
-                        onCphsCompleted = null;
-                    }
-
-                    new AdnRecordLoader(mFh).
-                            updateEF(adn, EF_MAILBOX_CPHS, EF_EXT1, 1, null,
-                            obtainMessage(EVENT_SET_CPHS_MAILBOX_DONE,
-                                    onCphsCompleted));
-                } else {
-                    if (ar.userObj != null) {
-                        AsyncResult.forMessage(((Message) ar.userObj)).exception
-                                = ar.exception;
-                        ((Message) ar.userObj).sendToTarget();
-                    }
-                }
-                break;
-            case EVENT_SET_CPHS_MAILBOX_DONE:
-                isRecordLoadResponse = false;
-                ar = (AsyncResult)msg.obj;
-                if(ar.exception == null) {
-                    voiceMailNum = newVoiceMailNum;
-                    voiceMailTag = newVoiceMailTag;
-                } else {
-                    if (DBG) log("Set CPHS MailBox with exception: "
-                            + ar.exception);
-                }
-                if (ar.userObj != null) {
-                    if (DBG) log("Callback with CPHS MB successful.");
-                    AsyncResult.forMessage(((Message) ar.userObj)).exception
-                            = ar.exception;
-                    ((Message) ar.userObj).sendToTarget();
-                }
-                break;
-            case EVENT_SIM_REFRESH:
-                isRecordLoadResponse = false;
-                ar = (AsyncResult)msg.obj;
-                if (DBG) log("Sim REFRESH with exception: " + ar.exception);
-                if (ar.exception == null) {
-                    handleSimRefresh((IccRefreshResponse)ar.result);
-                }
-                break;
-            case EVENT_GET_CFIS_DONE:
-                isRecordLoadResponse = true;
-
-                ar = (AsyncResult)msg.obj;
-                data = (byte[])ar.result;
-
-                if (ar.exception != null) {
-                    break;
-                }
-
-                log("EF_CFIS: " + IccUtils.bytesToHexString(data));
-
-                mEfCfis = data;
-
-                // Refer TS 51.011 Section 10.3.46 for the content description
-                callForwardingEnabled = ((data[1] & 0x01) != 0);
-
-                mRecordsEventsRegistrants.notifyResult(EVENT_CFI);
-                break;
-
-            case EVENT_GET_CSP_CPHS_DONE:
-                isRecordLoadResponse = true;
-
-                ar = (AsyncResult)msg.obj;
-
-                if (ar.exception != null) {
-                    loge("Exception in fetching EF_CSP data " + ar.exception);
-                    break;
-                }
-
-                data = (byte[])ar.result;
-
-                log("EF_CSP: " + IccUtils.bytesToHexString(data));
-                handleEfCspData(data);
-                break;
-
-            default:
-                super.handleMessage(msg);   // IccRecords handles generic record load responses
-
-        }}catch (RuntimeException exc) {
-            // I don't want these exceptions to be fatal
-            logw("Exception parsing SIM record", exc);
-        } finally {
-            // Count up record load responses even if they are fails
-            if (isRecordLoadResponse) {
-                onRecordLoaded();
-            }
-        }
-    }
-
-    private void handleFileUpdate(int efid) {
-        switch(efid) {
-            case EF_MBDN:
-                recordsToLoad++;
-                new AdnRecordLoader(mFh).loadFromEF(EF_MBDN, EF_EXT6,
-                        mailboxIndex, obtainMessage(EVENT_GET_MBDN_DONE));
-                break;
-            case EF_MAILBOX_CPHS:
-                recordsToLoad++;
-                new AdnRecordLoader(mFh).loadFromEF(EF_MAILBOX_CPHS, EF_EXT1,
-                        1, obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
-                break;
-            case EF_CSP_CPHS:
-                recordsToLoad++;
-                log("[CSP] SIM Refresh for EF_CSP_CPHS");
-                mFh.loadEFTransparent(EF_CSP_CPHS,
-                        obtainMessage(EVENT_GET_CSP_CPHS_DONE));
-                break;
-            default:
-                // For now, fetch all records if this is not a
-                // voicemail number.
-                // TODO: Handle other cases, instead of fetching all.
-                adnCache.reset();
-                fetchSimRecords();
-                break;
-        }
-    }
-
-    private void handleSimRefresh(IccRefreshResponse refreshResponse){
-        if (refreshResponse == null) {
-            if (DBG) log("handleSimRefresh received without input");
-            return;
-        }
-
-        if (refreshResponse.aid != null &&
-                !refreshResponse.aid.equals(mParentCard.getAid())) {
-            // This is for different app. Ignore.
-            return;
-        }
-
-        switch (refreshResponse.refreshResult) {
-            case IccRefreshResponse.REFRESH_RESULT_FILE_UPDATE:
-                if (DBG) log("handleSimRefresh with SIM_FILE_UPDATED");
-                handleFileUpdate(refreshResponse.efId);
-                break;
-            case IccRefreshResponse.REFRESH_RESULT_INIT:
-                if (DBG) log("handleSimRefresh with SIM_REFRESH_INIT");
-                // need to reload all files (that we care about)
-                adnCache.reset();
-                fetchSimRecords();
-                break;
-            case IccRefreshResponse.REFRESH_RESULT_RESET:
-                if (DBG) log("handleSimRefresh with SIM_REFRESH_RESET");
-                mCi.setRadioPower(false, null);
-                /* Note: no need to call setRadioPower(true).  Assuming the desired
-                * radio power state is still ON (as tracked by ServiceStateTracker),
-                * ServiceStateTracker will call setRadioPower when it receives the
-                * RADIO_STATE_CHANGED notification for the power off.  And if the
-                * desired power state has changed in the interim, we don't want to
-                * override it with an unconditional power on.
-                */
-                break;
-            default:
-                // unknown refresh operation
-                if (DBG) log("handleSimRefresh with unknown operation");
-                break;
-        }
-    }
-
-    /**
-     * Dispatch 3GPP format message. Overridden for CDMA/LTE phones by
-     * {@link com.android.internal.telephony.cdma.CdmaLteUiccRecords}
-     * to send messages to the secondary 3GPP format SMS dispatcher.
-     */
-    protected int dispatchGsmMessage(SmsMessageBase message) {
-        mNewSmsRegistrants.notifyResult(message);
-        return 0;
-    }
-
-    private void handleSms(byte[] ba) {
-        if (ba[0] != 0)
-            Log.d("ENF", "status : " + ba[0]);
-
-        // 3GPP TS 51.011 v5.0.0 (20011-12)  10.5.3
-        // 3 == "received by MS from network; message to be read"
-        if (ba[0] == 3) {
-            int n = ba.length;
-
-            // Note: Data may include trailing FF's.  That's OK; message
-            // should still parse correctly.
-            byte[] pdu = new byte[n - 1];
-            System.arraycopy(ba, 1, pdu, 0, n - 1);
-            SmsMessage message = SmsMessage.createFromPdu(pdu);
-
-            dispatchGsmMessage(message);
-        }
-    }
-
-
-    private void handleSmses(ArrayList messages) {
-        int count = messages.size();
-
-        for (int i = 0; i < count; i++) {
-            byte[] ba = (byte[]) messages.get(i);
-
-            if (ba[0] != 0)
-                Log.i("ENF", "status " + i + ": " + ba[0]);
-
-            // 3GPP TS 51.011 v5.0.0 (20011-12)  10.5.3
-            // 3 == "received by MS from network; message to be read"
-
-            if (ba[0] == 3) {
-                int n = ba.length;
-
-                // Note: Data may include trailing FF's.  That's OK; message
-                // should still parse correctly.
-                byte[] pdu = new byte[n - 1];
-                System.arraycopy(ba, 1, pdu, 0, n - 1);
-                SmsMessage message = SmsMessage.createFromPdu(pdu);
-
-                dispatchGsmMessage(message);
-
-                // 3GPP TS 51.011 v5.0.0 (20011-12)  10.5.3
-                // 1 == "received by MS from network; message read"
-
-                ba[0] = 1;
-
-                if (false) { // XXX writing seems to crash RdoServD
-                    mFh.updateEFLinearFixed(EF_SMS,
-                            i, ba, null, obtainMessage(EVENT_MARK_SMS_READ_DONE, i));
-                }
-            }
-        }
-    }
-
-    protected void onRecordLoaded() {
-        // One record loaded successfully or failed, In either case
-        // we need to update the recordsToLoad count
-        recordsToLoad -= 1;
-        if (DBG) log("onRecordLoaded " + recordsToLoad + " requested: " + recordsRequested);
-
-        if (recordsToLoad == 0 && recordsRequested == true) {
-            onAllRecordsLoaded();
-        } else if (recordsToLoad < 0) {
-            loge("recordsToLoad <0, programmer error suspected");
-            recordsToLoad = 0;
-        }
-    }
-
-    protected void onAllRecordsLoaded() {
-        String operator = getOperatorNumeric();
-
-        // Some fields require more than one SIM record to set
-
-        log("SIMRecords: onAllRecordsLoaded set 'gsm.sim.operator.numeric' to operator='" +
-                operator + "'");
-        SystemProperties.set(PROPERTY_ICC_OPERATOR_NUMERIC, operator);
-
-        if (imsi != null) {
-            SystemProperties.set(PROPERTY_ICC_OPERATOR_ISO_COUNTRY,
-                    MccTable.countryCodeForMcc(Integer.parseInt(imsi.substring(0,3))));
-        }
-        else {
-            loge("onAllRecordsLoaded: imsi is NULL!");
-        }
-
-        setVoiceMailByCountry(operator);
-        setSpnFromConfig(operator);
-
-        recordsLoadedRegistrants.notifyRegistrants(
-            new AsyncResult(null, null, null));
-        mParentCard.broadcastIccStateChangedIntent(
-                IccCard.INTENT_VALUE_ICC_LOADED, null);
-    }
-
-    //***** Private methods
-
-    private void setSpnFromConfig(String carrier) {
-        if (mSpnOverride.containsCarrier(carrier)) {
-            spn = mSpnOverride.getSpn(carrier);
-        }
-    }
-
-
-    private void setVoiceMailByCountry (String spn) {
-        if (mVmConfig.containsCarrier(spn)) {
-            isVoiceMailFixed = true;
-            voiceMailNum = mVmConfig.getVoiceMailNumber(spn);
-            voiceMailTag = mVmConfig.getVoiceMailTag(spn);
-        }
-    }
-
-    @Override
-    public void onReady() {
-        /* broadcast intent SIM_READY here so that we can make sure
-          READY is sent before IMSI ready
-        */
-        mParentCard.broadcastIccStateChangedIntent(
-                IccCard.INTENT_VALUE_ICC_READY, null);
-
-        fetchSimRecords();
-    }
-
-    protected void fetchSimRecords() {
-        recordsRequested = true;
-
-        if (DBG) log("fetchSimRecords " + recordsToLoad);
-
-        mCi.getIMSIForApp(mParentCard.getAid(), obtainMessage(EVENT_GET_IMSI_DONE));
-        recordsToLoad++;
-
-        mFh.loadEFTransparent(EF_ICCID, obtainMessage(EVENT_GET_ICCID_DONE));
-        recordsToLoad++;
-
-        // FIXME should examine EF[MSISDN]'s capability configuration
-        // to determine which is the voice/data/fax line
-        new AdnRecordLoader(mFh).loadFromEF(EF_MSISDN, EF_EXT1, 1,
-                    obtainMessage(EVENT_GET_MSISDN_DONE));
-        recordsToLoad++;
-
-        // Record number is subscriber profile
-        mFh.loadEFLinearFixed(EF_MBI, 1, obtainMessage(EVENT_GET_MBI_DONE));
-        recordsToLoad++;
-
-        mFh.loadEFTransparent(EF_AD, obtainMessage(EVENT_GET_AD_DONE));
-        recordsToLoad++;
-
-        // Record number is subscriber profile
-        mFh.loadEFLinearFixed(EF_MWIS, 1, obtainMessage(EVENT_GET_MWIS_DONE));
-        recordsToLoad++;
-
-
-        // Also load CPHS-style voice mail indicator, which stores
-        // the same info as EF[MWIS]. If both exist, both are updated
-        // but the EF[MWIS] data is preferred
-        // Please note this must be loaded after EF[MWIS]
-        mFh.loadEFTransparent(
-                EF_VOICE_MAIL_INDICATOR_CPHS,
-                obtainMessage(EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE));
-        recordsToLoad++;
-
-        // Same goes for Call Forward Status indicator: fetch both
-        // EF[CFIS] and CPHS-EF, with EF[CFIS] preferred.
-        mFh.loadEFLinearFixed(EF_CFIS, 1, obtainMessage(EVENT_GET_CFIS_DONE));
-        recordsToLoad++;
-        mFh.loadEFTransparent(EF_CFF_CPHS, obtainMessage(EVENT_GET_CFF_DONE));
-        recordsToLoad++;
-
-
-        getSpnFsm(true, null);
-
-        mFh.loadEFTransparent(EF_SPDI, obtainMessage(EVENT_GET_SPDI_DONE));
-        recordsToLoad++;
-
-        mFh.loadEFLinearFixed(EF_PNN, 1, obtainMessage(EVENT_GET_PNN_DONE));
-        recordsToLoad++;
-
-        mFh.loadEFTransparent(EF_SST, obtainMessage(EVENT_GET_SST_DONE));
-        recordsToLoad++;
-
-        mFh.loadEFTransparent(EF_INFO_CPHS, obtainMessage(EVENT_GET_INFO_CPHS_DONE));
-        recordsToLoad++;
-
-        mFh.loadEFTransparent(EF_CSP_CPHS,obtainMessage(EVENT_GET_CSP_CPHS_DONE));
-        recordsToLoad++;
-
-        // XXX should seek instead of examining them all
-        if (false) { // XXX
-            mFh.loadEFLinearFixedAll(EF_SMS, obtainMessage(EVENT_GET_ALL_SMS_DONE));
-            recordsToLoad++;
-        }
-
-        if (CRASH_RIL) {
-            String sms = "0107912160130310f20404d0110041007030208054832b0120"
-                         + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
-                         + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
-                         + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
-                         + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
-                         + "ffffffffffffffffffffffffffffff";
-            byte[] ba = IccUtils.hexStringToBytes(sms);
-
-            mFh.updateEFLinearFixed(EF_SMS, 1, ba, null,
-                            obtainMessage(EVENT_MARK_SMS_READ_DONE, 1));
-        }
-        if (DBG) log("fetchSimRecords " + recordsToLoad + " requested: " + recordsRequested);
-    }
-
-    /**
-     * Returns the SpnDisplayRule based on settings on the SIM and the
-     * specified plmn (currently-registered PLMN).  See TS 22.101 Annex A
-     * and TS 51.011 10.3.11 for details.
-     *
-     * If the SPN is not found on the SIM, the rule is always PLMN_ONLY.
-     */
-    @Override
-    public int getDisplayRule(String plmn) {
-        int rule;
-        if (spn == null || spnDisplayCondition == -1) {
-            // EF_SPN was not found on the SIM, or not yet loaded.  Just show ONS.
-            rule = SPN_RULE_SHOW_PLMN;
-        } else if (isOnMatchingPlmn(plmn)) {
-            rule = SPN_RULE_SHOW_SPN;
-            if ((spnDisplayCondition & 0x01) == 0x01) {
-                // ONS required when registered to HPLMN or PLMN in EF_SPDI
-                rule |= SPN_RULE_SHOW_PLMN;
-            }
-        } else {
-            rule = SPN_RULE_SHOW_PLMN;
-            if ((spnDisplayCondition & 0x02) == 0x00) {
-                // SPN required if not registered to HPLMN or PLMN in EF_SPDI
-                rule |= SPN_RULE_SHOW_SPN;
-            }
-        }
-        return rule;
-    }
-
-    /**
-     * Checks if plmn is HPLMN or on the spdiNetworks list.
-     */
-    private boolean isOnMatchingPlmn(String plmn) {
-        if (plmn == null) return false;
-
-        if (plmn.equals(getOperatorNumeric())) {
-            return true;
-        }
-
-        if (spdiNetworks != null) {
-            for (String spdiNet : spdiNetworks) {
-                if (plmn.equals(spdiNet)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * States of Get SPN Finite State Machine which only used by getSpnFsm()
-     */
-    private enum Get_Spn_Fsm_State {
-        IDLE,               // No initialized
-        INIT,               // Start FSM
-        READ_SPN_3GPP,      // Load EF_SPN firstly
-        READ_SPN_CPHS,      // Load EF_SPN_CPHS secondly
-        READ_SPN_SHORT_CPHS // Load EF_SPN_SHORT_CPHS last
-    }
-
-    /**
-     * Finite State Machine to load Service Provider Name , which can be stored
-     * in either EF_SPN (3GPP), EF_SPN_CPHS, or EF_SPN_SHORT_CPHS (CPHS4.2)
-     *
-     * After starting, FSM will search SPN EFs in order and stop after finding
-     * the first valid SPN
-     *
-     * If the FSM gets restart while waiting for one of
-     * SPN EFs results (i.e. a SIM refresh occurs after issuing
-     * read EF_CPHS_SPN), it will re-initialize only after
-     * receiving and discarding the unfinished SPN EF result.
-     *
-     * @param start set true only for initialize loading
-     * @param ar the AsyncResult from loadEFTransparent
-     *        ar.exception holds exception in error
-     *        ar.result is byte[] for data in success
-     */
-    private void getSpnFsm(boolean start, AsyncResult ar) {
-        byte[] data;
-
-        if (start) {
-            // Check previous state to see if there is outstanding
-            // SPN read
-            if(spnState == Get_Spn_Fsm_State.READ_SPN_3GPP ||
-               spnState == Get_Spn_Fsm_State.READ_SPN_CPHS ||
-               spnState == Get_Spn_Fsm_State.READ_SPN_SHORT_CPHS ||
-               spnState == Get_Spn_Fsm_State.INIT) {
-                // Set INIT then return so the INIT code
-                // will run when the outstanding read done.
-                spnState = Get_Spn_Fsm_State.INIT;
-                return;
-            } else {
-                spnState = Get_Spn_Fsm_State.INIT;
-            }
-        }
-
-        switch(spnState){
-            case INIT:
-                spn = null;
-
-                mFh.loadEFTransparent(EF_SPN,
-                        obtainMessage(EVENT_GET_SPN_DONE));
-                recordsToLoad++;
-
-                spnState = Get_Spn_Fsm_State.READ_SPN_3GPP;
-                break;
-            case READ_SPN_3GPP:
-                if (ar != null && ar.exception == null) {
-                    data = (byte[]) ar.result;
-                    spnDisplayCondition = 0xff & data[0];
-                    spn = IccUtils.adnStringFieldToString(data, 1, data.length - 1);
-
-                    if (DBG) log("Load EF_SPN: " + spn
-                            + " spnDisplayCondition: " + spnDisplayCondition);
-                    SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, spn);
-
-                    spnState = Get_Spn_Fsm_State.IDLE;
-                } else {
-                    mFh.loadEFTransparent( EF_SPN_CPHS,
-                            obtainMessage(EVENT_GET_SPN_DONE));
-                    recordsToLoad++;
-
-                    spnState = Get_Spn_Fsm_State.READ_SPN_CPHS;
-
-                    // See TS 51.011 10.3.11.  Basically, default to
-                    // show PLMN always, and SPN also if roaming.
-                    spnDisplayCondition = -1;
-                }
-                break;
-            case READ_SPN_CPHS:
-                if (ar != null && ar.exception == null) {
-                    data = (byte[]) ar.result;
-                    spn = IccUtils.adnStringFieldToString(
-                            data, 0, data.length - 1 );
-
-                    if (DBG) log("Load EF_SPN_CPHS: " + spn);
-                    SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, spn);
-
-                    spnState = Get_Spn_Fsm_State.IDLE;
-                } else {
-                    mFh.loadEFTransparent(
-                            EF_SPN_SHORT_CPHS, obtainMessage(EVENT_GET_SPN_DONE));
-                    recordsToLoad++;
-
-                    spnState = Get_Spn_Fsm_State.READ_SPN_SHORT_CPHS;
-                }
-                break;
-            case READ_SPN_SHORT_CPHS:
-                if (ar != null && ar.exception == null) {
-                    data = (byte[]) ar.result;
-                    spn = IccUtils.adnStringFieldToString(
-                            data, 0, data.length - 1);
-
-                    if (DBG) log("Load EF_SPN_SHORT_CPHS: " + spn);
-                    SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, spn);
-                }else {
-                    if (DBG) log("No SPN loaded in either CHPS or 3GPP");
-                }
-
-                spnState = Get_Spn_Fsm_State.IDLE;
-                break;
-            default:
-                spnState = Get_Spn_Fsm_State.IDLE;
-        }
-    }
-
-    /**
-     * Parse TS 51.011 EF[SPDI] record
-     * This record contains the list of numeric network IDs that
-     * are treated specially when determining SPN display
-     */
-    private void
-    parseEfSpdi(byte[] data) {
-        SimTlv tlv = new SimTlv(data, 0, data.length);
-
-        byte[] plmnEntries = null;
-
-        for ( ; tlv.isValidObject() ; tlv.nextObject()) {
-            // Skip SPDI tag, if existant
-            if (tlv.getTag() == TAG_SPDI) {
-              tlv = new SimTlv(tlv.getData(), 0, tlv.getData().length);
-            }
-            // There should only be one TAG_SPDI_PLMN_LIST
-            if (tlv.getTag() == TAG_SPDI_PLMN_LIST) {
-                plmnEntries = tlv.getData();
-                break;
-            }
-        }
-
-        if (plmnEntries == null) {
-            return;
-        }
-
-        spdiNetworks = new ArrayList<String>(plmnEntries.length / 3);
-
-        for (int i = 0 ; i + 2 < plmnEntries.length ; i += 3) {
-            String plmnCode;
-            plmnCode = IccUtils.bcdToString(plmnEntries, i, 3);
-
-            // Valid operator codes are 5 or 6 digits
-            if (plmnCode.length() >= 5) {
-                log("EF_SPDI network: " + plmnCode);
-                spdiNetworks.add(plmnCode);
-            }
-        }
-    }
-
-    /**
-     * check to see if Mailbox Number is allocated and activated in CPHS SST
-     */
-    private boolean isCphsMailboxEnabled() {
-        if (mCphsInfo == null)  return false;
-        return ((mCphsInfo[1] & CPHS_SST_MBN_MASK) == CPHS_SST_MBN_ENABLED );
-    }
-
-    protected void log(String s) {
-        Log.d(LOG_TAG, "[SIMRecords] " + s);
-    }
-
-    protected void loge(String s) {
-        Log.e(LOG_TAG, "[SIMRecords] " + s);
-    }
-
-    protected void logw(String s, Throwable tr) {
-        Log.w(LOG_TAG, "[SIMRecords] " + s, tr);
-    }
-
-    protected void logv(String s) {
-        Log.v(LOG_TAG, "[SIMRecords] " + s);
-    }
-
-    /**
-     * Return true if "Restriction of menu options for manual PLMN selection"
-     * bit is set or EF_CSP data is unavailable, return false otherwise.
-     */
-    public boolean isCspPlmnEnabled() {
-        return mCspPlmnEnabled;
-    }
-
-    /**
-     * Parse EF_CSP data and check if
-     * "Restriction of menu options for manual PLMN selection" is
-     * Enabled/Disabled
-     *
-     * @param data EF_CSP hex data.
-     */
-    private void handleEfCspData(byte[] data) {
-        // As per spec CPHS4_2.WW6, CPHS B.4.7.1, EF_CSP contains CPHS defined
-        // 18 bytes (i.e 9 service groups info) and additional data specific to
-        // operator. The valueAddedServicesGroup is not part of standard
-        // services. This is operator specific and can be programmed any where.
-        // Normally this is programmed as 10th service after the standard
-        // services.
-        int usedCspGroups = data.length / 2;
-        // This is the "Servive Group Number" of "Value Added Services Group".
-        byte valueAddedServicesGroup = (byte)0xC0;
-
-        mCspPlmnEnabled = true;
-        for (int i = 0; i < usedCspGroups; i++) {
-             if (data[2 * i] == valueAddedServicesGroup) {
-                 log("[CSP] found ValueAddedServicesGroup, value " + data[(2 * i) + 1]);
-                 if ((data[(2 * i) + 1] & 0x80) == 0x80) {
-                     // Bit 8 is for
-                     // "Restriction of menu options for manual PLMN selection".
-                     // Operator Selection menu should be enabled.
-                     mCspPlmnEnabled = true;
-                 } else {
-                     mCspPlmnEnabled = false;
-                     // Operator Selection menu should be disabled.
-                     // Operator Selection Mode should be set to Automatic.
-                     log("[CSP] Set Automatic Network Selection");
-                     mNetworkSelectionModeAutomaticRegistrants.notifyRegistrants();
-                 }
-                 return;
-             }
-        }
-
-        log("[CSP] Value Added Service Group (0xC0), not found!");
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java
deleted file mode 100644
index 35ba0d1..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-** Copyright 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.internal.telephony.gsm;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import android.os.Message;
-import android.util.Log;
-
-import com.android.internal.telephony.IccPhoneBookInterfaceManager;
-
-/**
- * SimPhoneBookInterfaceManager to provide an inter-process communication to
- * access ADN-like SIM records.
- */
-
-
-public class SimPhoneBookInterfaceManager extends IccPhoneBookInterfaceManager {
-    static final String LOG_TAG = "GSM";
-
-    public SimPhoneBookInterfaceManager(GSMPhone phone) {
-        super(phone);
-        adnCache = phone.mIccRecords.getAdnCache();
-        //NOTE service "simphonebook" added by IccSmsInterfaceManagerProxy
-    }
-
-    public void dispose() {
-        super.dispose();
-    }
-
-    protected void finalize() {
-        try {
-            super.finalize();
-        } catch (Throwable throwable) {
-            Log.e(LOG_TAG, "Error while finalizing:", throwable);
-        }
-        if(DBG) Log.d(LOG_TAG, "SimPhoneBookInterfaceManager finalized");
-    }
-
-    public int[] getAdnRecordsSize(int efid) {
-        if (DBG) logd("getAdnRecordsSize: efid=" + efid);
-        synchronized(mLock) {
-            checkThread();
-            recordSize = new int[3];
-
-            //Using mBaseHandler, no difference in EVENT_GET_SIZE_DONE handling
-            AtomicBoolean status = new AtomicBoolean(false);
-            Message response = mBaseHandler.obtainMessage(EVENT_GET_SIZE_DONE, status);
-
-            phone.getIccFileHandler().getEFLinearRecordSize(efid, response);
-            waitForResult(status);
-        }
-
-        return recordSize;
-    }
-
-    protected void logd(String msg) {
-        Log.d(LOG_TAG, "[SimPbInterfaceManager] " + msg);
-    }
-
-    protected void loge(String msg) {
-        Log.e(LOG_TAG, "[SimPbInterfaceManager] " + msg);
-    }
-}
-
diff --git a/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java
deleted file mode 100644
index 92bf390..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
-** Copyright 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.internal.telephony.gsm;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.AsyncResult;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-
-import com.android.internal.telephony.IccConstants;
-import com.android.internal.telephony.IccSmsInterfaceManager;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.IntRangeManager;
-import com.android.internal.telephony.SMSDispatcher;
-import com.android.internal.telephony.SmsRawData;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import static android.telephony.SmsManager.STATUS_ON_ICC_FREE;
-
-/**
- * SimSmsInterfaceManager to provide an inter-process communication to
- * access Sms in Sim.
- */
-public class SimSmsInterfaceManager extends IccSmsInterfaceManager {
-    static final String LOG_TAG = "GSM";
-    static final boolean DBG = true;
-
-    private final Object mLock = new Object();
-    private boolean mSuccess;
-    private List<SmsRawData> mSms;
-    private HashMap<Integer, HashSet<String>> mCellBroadcastSubscriptions =
-            new HashMap<Integer, HashSet<String>>();
-
-    private CellBroadcastRangeManager mCellBroadcastRangeManager =
-            new CellBroadcastRangeManager();
-
-    private static final int EVENT_LOAD_DONE = 1;
-    private static final int EVENT_UPDATE_DONE = 2;
-    private static final int EVENT_SET_BROADCAST_ACTIVATION_DONE = 3;
-    private static final int EVENT_SET_BROADCAST_CONFIG_DONE = 4;
-    private static final int SMS_CB_CODE_SCHEME_MIN = 0;
-    private static final int SMS_CB_CODE_SCHEME_MAX = 255;
-
-    Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            AsyncResult ar;
-
-            switch (msg.what) {
-                case EVENT_UPDATE_DONE:
-                    ar = (AsyncResult) msg.obj;
-                    synchronized (mLock) {
-                        mSuccess = (ar.exception == null);
-                        mLock.notifyAll();
-                    }
-                    break;
-                case EVENT_LOAD_DONE:
-                    ar = (AsyncResult)msg.obj;
-                    synchronized (mLock) {
-                        if (ar.exception == null) {
-                            mSms  = buildValidRawData((ArrayList<byte[]>) ar.result);
-                        } else {
-                            if(DBG) log("Cannot load Sms records");
-                            if (mSms != null)
-                                mSms.clear();
-                        }
-                        mLock.notifyAll();
-                    }
-                    break;
-                case EVENT_SET_BROADCAST_ACTIVATION_DONE:
-                case EVENT_SET_BROADCAST_CONFIG_DONE:
-                    ar = (AsyncResult) msg.obj;
-                    synchronized (mLock) {
-                        mSuccess = (ar.exception == null);
-                        mLock.notifyAll();
-                    }
-                    break;
-            }
-        }
-    };
-
-    public SimSmsInterfaceManager(GSMPhone phone, SMSDispatcher dispatcher) {
-        super(phone);
-        mDispatcher = dispatcher;
-    }
-
-    public void dispose() {
-    }
-
-    @Override
-    protected void finalize() {
-        try {
-            super.finalize();
-        } catch (Throwable throwable) {
-            Log.e(LOG_TAG, "Error while finalizing:", throwable);
-        }
-        if(DBG) Log.d(LOG_TAG, "SimSmsInterfaceManager finalized");
-    }
-
-    /**
-     * Update the specified message on the SIM.
-     *
-     * @param index record index of message to update
-     * @param status new message status (STATUS_ON_ICC_READ,
-     *                  STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT,
-     *                  STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE)
-     * @param pdu the raw PDU to store
-     * @return success or not
-     *
-     */
-    public boolean
-    updateMessageOnIccEf(int index, int status, byte[] pdu) {
-        if (DBG) log("updateMessageOnIccEf: index=" + index +
-                " status=" + status + " ==> " +
-                "("+ Arrays.toString(pdu) + ")");
-        enforceReceiveAndSend("Updating message on SIM");
-        synchronized(mLock) {
-            mSuccess = false;
-            Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
-
-            if (status == STATUS_ON_ICC_FREE) {
-                // Special case FREE: call deleteSmsOnSim instead of
-                // manipulating the SIM record
-                mPhone.mCM.deleteSmsOnSim(index, response);
-            } else {
-                byte[] record = makeSmsRecordData(status, pdu);
-                mPhone.getIccFileHandler().updateEFLinearFixed(
-                        IccConstants.EF_SMS,
-                        index, record, null, response);
-            }
-            try {
-                mLock.wait();
-            } catch (InterruptedException e) {
-                log("interrupted while trying to update by index");
-            }
-        }
-        return mSuccess;
-    }
-
-    /**
-     * Copy a raw SMS PDU to the SIM.
-     *
-     * @param pdu the raw PDU to store
-     * @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD,
-     *               STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT)
-     * @return success or not
-     *
-     */
-    public boolean copyMessageToIccEf(int status, byte[] pdu, byte[] smsc) {
-        if (DBG) log("copyMessageToIccEf: status=" + status + " ==> " +
-                "pdu=("+ Arrays.toString(pdu) +
-                "), smsm=(" + Arrays.toString(smsc) +")");
-        enforceReceiveAndSend("Copying message to SIM");
-        synchronized(mLock) {
-            mSuccess = false;
-            Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
-
-            mPhone.mCM.writeSmsToSim(status, IccUtils.bytesToHexString(smsc),
-                    IccUtils.bytesToHexString(pdu), response);
-
-            try {
-                mLock.wait();
-            } catch (InterruptedException e) {
-                log("interrupted while trying to update by index");
-            }
-        }
-        return mSuccess;
-    }
-
-    /**
-     * Retrieves all messages currently stored on ICC.
-     *
-     * @return list of SmsRawData of all sms on ICC
-     */
-    public List<SmsRawData> getAllMessagesFromIccEf() {
-        if (DBG) log("getAllMessagesFromEF");
-
-        Context context = mPhone.getContext();
-
-        context.enforceCallingPermission(
-                "android.permission.RECEIVE_SMS",
-                "Reading messages from SIM");
-        synchronized(mLock) {
-            Message response = mHandler.obtainMessage(EVENT_LOAD_DONE);
-            mPhone.getIccFileHandler().loadEFLinearFixedAll(IccConstants.EF_SMS, response);
-
-            try {
-                mLock.wait();
-            } catch (InterruptedException e) {
-                log("interrupted while trying to load from the SIM");
-            }
-        }
-        return mSms;
-    }
-
-    public boolean enableCellBroadcast(int messageIdentifier) {
-        return enableCellBroadcastRange(messageIdentifier, messageIdentifier);
-    }
-
-    public boolean disableCellBroadcast(int messageIdentifier) {
-        return disableCellBroadcastRange(messageIdentifier, messageIdentifier);
-    }
-
-    public boolean enableCellBroadcastRange(int startMessageId, int endMessageId) {
-        if (DBG) log("enableCellBroadcastRange");
-
-        Context context = mPhone.getContext();
-
-        context.enforceCallingPermission(
-                "android.permission.RECEIVE_SMS",
-                "Enabling cell broadcast SMS");
-
-        String client = context.getPackageManager().getNameForUid(
-                Binder.getCallingUid());
-
-        if (!mCellBroadcastRangeManager.enableRange(startMessageId, endMessageId, client)) {
-            log("Failed to add cell broadcast subscription for MID range " + startMessageId
-                    + " to " + endMessageId + " from client " + client);
-            return false;
-        }
-
-        if (DBG)
-            log("Added cell broadcast subscription for MID range " + startMessageId
-                    + " to " + endMessageId + " from client " + client);
-
-        setCellBroadcastActivation(!mCellBroadcastRangeManager.isEmpty());
-
-        return true;
-    }
-
-    public boolean disableCellBroadcastRange(int startMessageId, int endMessageId) {
-        if (DBG) log("disableCellBroadcastRange");
-
-        Context context = mPhone.getContext();
-
-        context.enforceCallingPermission(
-                "android.permission.RECEIVE_SMS",
-                "Disabling cell broadcast SMS");
-
-        String client = context.getPackageManager().getNameForUid(
-                Binder.getCallingUid());
-
-        if (!mCellBroadcastRangeManager.disableRange(startMessageId, endMessageId, client)) {
-            log("Failed to remove cell broadcast subscription for MID range " + startMessageId
-                    + " to " + endMessageId + " from client " + client);
-            return false;
-        }
-
-        if (DBG)
-            log("Removed cell broadcast subscription for MID range " + startMessageId
-                    + " to " + endMessageId + " from client " + client);
-
-        setCellBroadcastActivation(!mCellBroadcastRangeManager.isEmpty());
-
-        return true;
-    }
-
-    class CellBroadcastRangeManager extends IntRangeManager {
-        private ArrayList<SmsBroadcastConfigInfo> mConfigList =
-                new ArrayList<SmsBroadcastConfigInfo>();
-
-        /**
-         * Called when the list of enabled ranges has changed. This will be
-         * followed by zero or more calls to {@link #addRange} followed by
-         * a call to {@link #finishUpdate}.
-         */
-        protected void startUpdate() {
-            mConfigList.clear();
-        }
-
-        /**
-         * Called after {@link #startUpdate} to indicate a range of enabled
-         * values.
-         * @param startId the first id included in the range
-         * @param endId the last id included in the range
-         */
-        protected void addRange(int startId, int endId, boolean selected) {
-            mConfigList.add(new SmsBroadcastConfigInfo(startId, endId,
-                        SMS_CB_CODE_SCHEME_MIN, SMS_CB_CODE_SCHEME_MAX, selected));
-        }
-
-        /**
-         * Called to indicate the end of a range update started by the
-         * previous call to {@link #startUpdate}.
-         * @return true if successful, false otherwise
-         */
-        protected boolean finishUpdate() {
-            if (mConfigList.isEmpty()) {
-                return true;
-            } else {
-                SmsBroadcastConfigInfo[] configs =
-                        mConfigList.toArray(new SmsBroadcastConfigInfo[mConfigList.size()]);
-                return setCellBroadcastConfig(configs);
-            }
-        }
-    }
-
-    private boolean setCellBroadcastConfig(SmsBroadcastConfigInfo[] configs) {
-        if (DBG)
-            log("Calling setGsmBroadcastConfig with " + configs.length + " configurations");
-
-        synchronized (mLock) {
-            Message response = mHandler.obtainMessage(EVENT_SET_BROADCAST_CONFIG_DONE);
-
-            mSuccess = false;
-            mPhone.mCM.setGsmBroadcastConfig(configs, response);
-
-            try {
-                mLock.wait();
-            } catch (InterruptedException e) {
-                log("interrupted while trying to set cell broadcast config");
-            }
-        }
-
-        return mSuccess;
-    }
-
-    private boolean setCellBroadcastActivation(boolean activate) {
-        if (DBG)
-            log("Calling setCellBroadcastActivation(" + activate + ')');
-
-        synchronized (mLock) {
-            Message response = mHandler.obtainMessage(EVENT_SET_BROADCAST_ACTIVATION_DONE);
-
-            mSuccess = false;
-            mPhone.mCM.setGsmBroadcastActivation(activate, response);
-
-            try {
-                mLock.wait();
-            } catch (InterruptedException e) {
-                log("interrupted while trying to set cell broadcast activation");
-            }
-        }
-
-        return mSuccess;
-    }
-
-    @Override
-    protected void log(String msg) {
-        Log.d(LOG_TAG, "[SimSmsInterfaceManager] " + msg);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SimTlv.java b/telephony/java/com/android/internal/telephony/gsm/SimTlv.java
deleted file mode 100644
index 497cf5f..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/SimTlv.java
+++ /dev/null
@@ -1,118 +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.internal.telephony.gsm;
-
-/**
- * SIM Tag-Length-Value record
- * TS 102 223 Annex C
- *
- * {@hide}
- *
- */
-public class SimTlv
-{
-    //***** Private Instance Variables
-
-    byte record[];
-    int tlvOffset;
-    int tlvLength;
-    int curOffset;
-    int curDataOffset;
-    int curDataLength;
-    boolean hasValidTlvObject;
-
-    public SimTlv(byte[] record, int offset, int length) {
-        this.record = record;
-
-        this.tlvOffset = offset;
-        this.tlvLength = length;
-        curOffset = offset;
-
-        hasValidTlvObject = parseCurrentTlvObject();
-    }
-
-    public boolean nextObject() {
-        if (!hasValidTlvObject) return false;
-        curOffset = curDataOffset + curDataLength;
-        hasValidTlvObject = parseCurrentTlvObject();
-        return hasValidTlvObject;
-    }
-
-    public boolean isValidObject() {
-        return hasValidTlvObject;
-    }
-
-    /**
-     * Returns the tag for the current TLV object
-     * Return 0 if !isValidObject()
-     * 0 and 0xff are invalid tag values
-     * valid tags range from 1 - 0xfe
-     */
-    public int getTag() {
-        if (!hasValidTlvObject) return 0;
-        return record[curOffset] & 0xff;
-    }
-
-    /**
-     * Returns data associated with current TLV object
-     * returns null if !isValidObject()
-     */
-
-    public byte[] getData() {
-        if (!hasValidTlvObject) return null;
-
-        byte[] ret = new byte[curDataLength];
-        System.arraycopy(record, curDataOffset, ret, 0, curDataLength);
-        return ret;
-    }
-
-    /**
-     * Updates curDataLength and curDataOffset
-     * @return false on invalid record, true on valid record
-     */
-
-    private boolean parseCurrentTlvObject() {
-        // 0x00 and 0xff are invalid tag values
-
-        try {
-            if (record[curOffset] == 0 || (record[curOffset] & 0xff) == 0xff) {
-                return false;
-            }
-
-            if ((record[curOffset + 1] & 0xff) < 0x80) {
-                // one byte length 0 - 0x7f
-                curDataLength = record[curOffset + 1] & 0xff;
-                curDataOffset = curOffset + 2;
-            } else if ((record[curOffset + 1] & 0xff) == 0x81) {
-                // two byte length 0x80 - 0xff
-                curDataLength = record[curOffset + 2] & 0xff;
-                curDataOffset = curOffset + 3;
-            } else {
-                return false;
-            }
-        } catch (ArrayIndexOutOfBoundsException ex) {
-            return false;
-        }
-
-        if (curDataLength + curDataOffset > tlvOffset + tlvLength) {
-            return false;
-        }
-
-        return true;
-    }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java b/telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java
deleted file mode 100644
index 66e7ce0..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java
+++ /dev/null
@@ -1,133 +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.
- */
-
-package com.android.internal.telephony.gsm;
-
-/**
- * SmsBroadcastConfigInfo defines one configuration of Cell Broadcast
- * Message (CBM) to be received by the ME
- *
- * fromServiceId - toServiceId defines a range of CBM message identifiers
- * whose value is 0x0000 - 0xFFFF as defined in TS 23.041 9.4.1.2.2 for GMS
- * and 9.4.4.2.2 for UMTS. All other values can be treated as empty
- * CBM message ID.
- *
- * fromCodeScheme - toCodeScheme defines a range of CBM data coding schemes
- * whose value is 0x00 - 0xFF as defined in TS 23.041 9.4.1.2.3 for GMS
- * and 9.4.4.2.3 for UMTS.
- * All other values can be treated as empty CBM data coding scheme.
- *
- * selected false means message types specified in {@code <fromServiceId, toServiceId>}
- * and {@code <fromCodeScheme, toCodeScheme>} are not accepted, while true means accepted.
- *
- */
-public final class SmsBroadcastConfigInfo {
-    private int fromServiceId;
-    private int toServiceId;
-    private int fromCodeScheme;
-    private int toCodeScheme;
-    private boolean selected;
-
-    /**
-     * Initialize the object from rssi and cid.
-     */
-    public SmsBroadcastConfigInfo(int fromId, int toId, int fromScheme,
-            int toScheme, boolean selected) {
-        fromServiceId = fromId;
-        toServiceId = toId;
-        fromCodeScheme = fromScheme;
-        toCodeScheme = toScheme;
-        this.selected = selected;
-    }
-
-    /**
-     * @param fromServiceId the fromServiceId to set
-     */
-    public void setFromServiceId(int fromServiceId) {
-        this.fromServiceId = fromServiceId;
-    }
-
-    /**
-     * @return the fromServiceId
-     */
-    public int getFromServiceId() {
-        return fromServiceId;
-    }
-
-    /**
-     * @param toServiceId the toServiceId to set
-     */
-    public void setToServiceId(int toServiceId) {
-        this.toServiceId = toServiceId;
-    }
-
-    /**
-     * @return the toServiceId
-     */
-    public int getToServiceId() {
-        return toServiceId;
-    }
-
-    /**
-     * @param fromCodeScheme the fromCodeScheme to set
-     */
-    public void setFromCodeScheme(int fromCodeScheme) {
-        this.fromCodeScheme = fromCodeScheme;
-    }
-
-    /**
-     * @return the fromCodeScheme
-     */
-    public int getFromCodeScheme() {
-        return fromCodeScheme;
-    }
-
-    /**
-     * @param toCodeScheme the toCodeScheme to set
-     */
-    public void setToCodeScheme(int toCodeScheme) {
-        this.toCodeScheme = toCodeScheme;
-    }
-
-    /**
-     * @return the toCodeScheme
-     */
-    public int getToCodeScheme() {
-        return toCodeScheme;
-    }
-
-    /**
-     * @param selected the selected to set
-     */
-    public void setSelected(boolean selected) {
-        this.selected = selected;
-    }
-
-    /**
-     * @return the selected
-     */
-    public boolean isSelected() {
-        return selected;
-    }
-
-    @Override
-    public String toString() {
-        return "SmsBroadcastConfigInfo: Id [" +
-                fromServiceId + ',' + toServiceId + "] Code [" +
-                fromCodeScheme + ',' + toCodeScheme + "] " +
-            (selected ? "ENABLED" : "DISABLED");
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
deleted file mode 100644
index ebb4666..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2012 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.internal.telephony.gsm;
-
-/**
- * Constants used in SMS Cell Broadcast messages (see 3GPP TS 23.041). This class is used by the
- * boot-time broadcast channel enable and database upgrade code in CellBroadcastReceiver, so it
- * is public, but should be avoided in favor of the radio technology independent constants in
- * {@link android.telephony.SmsCbMessage}, {@link android.telephony.SmsCbEtwsInfo}, and
- * {@link android.telephony.SmsCbCmasInfo} classes.
- *
- * {@hide}
- */
-public class SmsCbConstants {
-
-    /** Private constructor for utility class. */
-    private SmsCbConstants() { }
-
-    /** Start of PWS Message Identifier range (includes ETWS and CMAS). */
-    public static final int MESSAGE_ID_PWS_FIRST_IDENTIFIER = 0x1100;
-
-    /** Bitmask for messages of ETWS type (including future extensions). */
-    public static final int MESSAGE_ID_ETWS_TYPE_MASK       = 0xFFF8;
-
-    /** Value for messages of ETWS type after applying {@link #MESSAGE_ID_ETWS_TYPE_MASK}. */
-    public static final int MESSAGE_ID_ETWS_TYPE            = 0x1100;
-
-    /** ETWS Message Identifier for earthquake warning message. */
-    public static final int MESSAGE_ID_ETWS_EARTHQUAKE_WARNING      = 0x1100;
-
-    /** ETWS Message Identifier for tsunami warning message. */
-    public static final int MESSAGE_ID_ETWS_TSUNAMI_WARNING         = 0x1101;
-
-    /** ETWS Message Identifier for earthquake and tsunami combined warning message. */
-    public static final int MESSAGE_ID_ETWS_EARTHQUAKE_AND_TSUNAMI_WARNING  = 0x1102;
-
-    /** ETWS Message Identifier for test message. */
-    public static final int MESSAGE_ID_ETWS_TEST_MESSAGE            = 0x1103;
-
-    /** ETWS Message Identifier for messages related to other emergency types. */
-    public static final int MESSAGE_ID_ETWS_OTHER_EMERGENCY_TYPE    = 0x1104;
-
-    /** Start of CMAS Message Identifier range. */
-    public static final int MESSAGE_ID_CMAS_FIRST_IDENTIFIER                = 0x1112;
-
-    /** CMAS Message Identifier for Presidential Level alerts. */
-    public static final int MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL        = 0x1112;
-
-    /** CMAS Message Identifier for Extreme alerts, Urgency=Immediate, Certainty=Observed. */
-    public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED = 0x1113;
-
-    /** CMAS Message Identifier for Extreme alerts, Urgency=Immediate, Certainty=Likely. */
-    public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY  = 0x1114;
-
-    /** CMAS Message Identifier for Extreme alerts, Urgency=Expected, Certainty=Observed. */
-    public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED = 0x1115;
-
-    /** CMAS Message Identifier for Extreme alerts, Urgency=Expected, Certainty=Likely. */
-    public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY   = 0x1116;
-
-    /** CMAS Message Identifier for Severe alerts, Urgency=Immediate, Certainty=Observed. */
-    public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED = 0x1117;
-
-    /** CMAS Message Identifier for Severe alerts, Urgency=Immediate, Certainty=Likely. */
-    public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY   = 0x1118;
-
-    /** CMAS Message Identifier for Severe alerts, Urgency=Expected, Certainty=Observed. */
-    public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED  = 0x1119;
-
-    /** CMAS Message Identifier for Severe alerts, Urgency=Expected, Certainty=Likely. */
-    public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY    = 0x111A;
-
-    /** CMAS Message Identifier for Child Abduction Emergency (Amber Alert). */
-    public static final int MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY = 0x111B;
-
-    /** CMAS Message Identifier for the Required Monthly Test. */
-    public static final int MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST     = 0x111C;
-
-    /** CMAS Message Identifier for CMAS Exercise. */
-    public static final int MESSAGE_ID_CMAS_ALERT_EXERCISE                  = 0x111D;
-
-    /** CMAS Message Identifier for operator defined use. */
-    public static final int MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE      = 0x111E;
-
-    /** End of CMAS Message Identifier range (including future extensions). */
-    public static final int MESSAGE_ID_CMAS_LAST_IDENTIFIER                 = 0x112F;
-
-    /** End of PWS Message Identifier range (includes ETWS, CMAS, and future extensions). */
-    public static final int MESSAGE_ID_PWS_LAST_IDENTIFIER                  = 0x18FF;
-
-    /** ETWS serial number flag to activate the popup display. */
-    public static final int SERIAL_NUMBER_ETWS_ACTIVATE_POPUP                = 0x1000;
-
-    /** ETWS serial number flag to activate the emergency user alert. */
-    public static final int SERIAL_NUMBER_ETWS_EMERGENCY_USER_ALERT          = 0x2000;
-
-    /** ETWS warning type value for earthquake. */
-    public static final int ETWS_WARNING_TYPE_EARTHQUAKE                    = 0x00;
-
-    /** ETWS warning type value for tsunami. */
-    public static final int ETWS_WARNING_TYPE_TSUNAMI                       = 0x01;
-
-    /** ETWS warning type value for earthquake and tsunami. */
-    public static final int ETWS_WARNING_TYPE_EARTHQUAKE_AND_TSUNAMI        = 0x02;
-
-    /** ETWS warning type value for test broadcast. */
-    public static final int ETWS_WARNING_TYPE_TEST                          = 0x03;
-
-    /** ETWS warning type value for other notifications. */
-    public static final int ETWS_WARNING_TYPE_OTHER                         = 0x04;
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java
deleted file mode 100644
index 5692044..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * Copyright (C) 2010 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.internal.telephony.gsm;
-
-import android.telephony.SmsCbCmasInfo;
-import android.telephony.SmsCbEtwsInfo;
-
-import java.util.Arrays;
-
-/**
- * Parses a 3GPP TS 23.041 cell broadcast message header. This class is public for use by
- * CellBroadcastReceiver test cases, but should not be used by applications.
- *
- * All relevant header information is now sent as a Parcelable
- * {@link android.telephony.SmsCbMessage} object in the "message" extra of the
- * {@link android.provider.Telephony.Sms.Intents#SMS_CB_RECEIVED_ACTION} or
- * {@link android.provider.Telephony.Sms.Intents#SMS_EMERGENCY_CB_RECEIVED_ACTION} intent.
- * The raw PDU is no longer sent to SMS CB applications.
- */
-class SmsCbHeader {
-
-    /**
-     * Length of SMS-CB header
-     */
-    static final int PDU_HEADER_LENGTH = 6;
-
-    /**
-     * GSM pdu format, as defined in 3gpp TS 23.041, section 9.4.1
-     */
-    static final int FORMAT_GSM = 1;
-
-    /**
-     * UMTS pdu format, as defined in 3gpp TS 23.041, section 9.4.2
-     */
-    static final int FORMAT_UMTS = 2;
-
-    /**
-     * GSM pdu format, as defined in 3gpp TS 23.041, section 9.4.1.3
-     */
-    static final int FORMAT_ETWS_PRIMARY = 3;
-
-    /**
-     * Message type value as defined in 3gpp TS 25.324, section 11.1.
-     */
-    private static final int MESSAGE_TYPE_CBS_MESSAGE = 1;
-
-    /**
-     * Length of GSM pdus
-     */
-    private static final int PDU_LENGTH_GSM = 88;
-
-    /**
-     * Maximum length of ETWS primary message GSM pdus
-     */
-    private static final int PDU_LENGTH_ETWS = 56;
-
-    private final int geographicalScope;
-
-    /** The serial number combines geographical scope, message code, and update number. */
-    private final int serialNumber;
-
-    /** The Message Identifier in 3GPP is the same as the Service Category in CDMA. */
-    private final int messageIdentifier;
-
-    private final int dataCodingScheme;
-
-    private final int pageIndex;
-
-    private final int nrOfPages;
-
-    private final int format;
-
-    /** ETWS warning notification info. */
-    private final SmsCbEtwsInfo mEtwsInfo;
-
-    /** CMAS warning notification info. */
-    private final SmsCbCmasInfo mCmasInfo;
-
-    public SmsCbHeader(byte[] pdu) throws IllegalArgumentException {
-        if (pdu == null || pdu.length < PDU_HEADER_LENGTH) {
-            throw new IllegalArgumentException("Illegal PDU");
-        }
-
-        if (pdu.length <= PDU_LENGTH_ETWS) {
-            format = FORMAT_ETWS_PRIMARY;
-            geographicalScope = (pdu[0] & 0xc0) >> 6;
-            serialNumber = ((pdu[0] & 0xff) << 8) | (pdu[1] & 0xff);
-            messageIdentifier = ((pdu[2] & 0xff) << 8) | (pdu[3] & 0xff);
-            dataCodingScheme = -1;
-            pageIndex = -1;
-            nrOfPages = -1;
-            boolean emergencyUserAlert = (pdu[4] & 0x1) != 0;
-            boolean activatePopup = (pdu[5] & 0x80) != 0;
-            int warningType = (pdu[4] & 0xfe) >> 1;
-            byte[] warningSecurityInfo;
-            // copy the Warning-Security-Information, if present
-            if (pdu.length > PDU_HEADER_LENGTH) {
-                warningSecurityInfo = Arrays.copyOfRange(pdu, 6, pdu.length);
-            } else {
-                warningSecurityInfo = null;
-            }
-            mEtwsInfo = new SmsCbEtwsInfo(warningType, emergencyUserAlert, activatePopup,
-                    warningSecurityInfo);
-            mCmasInfo = null;
-            return;     // skip the ETWS/CMAS initialization code for regular notifications
-        } else if (pdu.length <= PDU_LENGTH_GSM) {
-            // GSM pdus are no more than 88 bytes
-            format = FORMAT_GSM;
-            geographicalScope = (pdu[0] & 0xc0) >> 6;
-            serialNumber = ((pdu[0] & 0xff) << 8) | (pdu[1] & 0xff);
-            messageIdentifier = ((pdu[2] & 0xff) << 8) | (pdu[3] & 0xff);
-            dataCodingScheme = pdu[4] & 0xff;
-
-            // Check for invalid page parameter
-            int pageIndex = (pdu[5] & 0xf0) >> 4;
-            int nrOfPages = pdu[5] & 0x0f;
-
-            if (pageIndex == 0 || nrOfPages == 0 || pageIndex > nrOfPages) {
-                pageIndex = 1;
-                nrOfPages = 1;
-            }
-
-            this.pageIndex = pageIndex;
-            this.nrOfPages = nrOfPages;
-        } else {
-            // UMTS pdus are always at least 90 bytes since the payload includes
-            // a number-of-pages octet and also one length octet per page
-            format = FORMAT_UMTS;
-
-            int messageType = pdu[0];
-
-            if (messageType != MESSAGE_TYPE_CBS_MESSAGE) {
-                throw new IllegalArgumentException("Unsupported message type " + messageType);
-            }
-
-            messageIdentifier = ((pdu[1] & 0xff) << 8) | pdu[2] & 0xff;
-            geographicalScope = (pdu[3] & 0xc0) >> 6;
-            serialNumber = ((pdu[3] & 0xff) << 8) | (pdu[4] & 0xff);
-            dataCodingScheme = pdu[5] & 0xff;
-
-            // We will always consider a UMTS message as having one single page
-            // since there's only one instance of the header, even though the
-            // actual payload may contain several pages.
-            pageIndex = 1;
-            nrOfPages = 1;
-        }
-
-        if (isEtwsMessage()) {
-            boolean emergencyUserAlert = isEtwsEmergencyUserAlert();
-            boolean activatePopup = isEtwsPopupAlert();
-            int warningType = getEtwsWarningType();
-            mEtwsInfo = new SmsCbEtwsInfo(warningType, emergencyUserAlert, activatePopup, null);
-            mCmasInfo = null;
-        } else if (isCmasMessage()) {
-            int messageClass = getCmasMessageClass();
-            int severity = getCmasSeverity();
-            int urgency = getCmasUrgency();
-            int certainty = getCmasCertainty();
-            mEtwsInfo = null;
-            mCmasInfo = new SmsCbCmasInfo(messageClass, SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN,
-                    SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN, severity, urgency, certainty);
-        } else {
-            mEtwsInfo = null;
-            mCmasInfo = null;
-        }
-    }
-
-    int getGeographicalScope() {
-        return geographicalScope;
-    }
-
-    int getSerialNumber() {
-        return serialNumber;
-    }
-
-    int getServiceCategory() {
-        return messageIdentifier;
-    }
-
-    int getDataCodingScheme() {
-        return dataCodingScheme;
-    }
-
-    int getPageIndex() {
-        return pageIndex;
-    }
-
-    int getNumberOfPages() {
-        return nrOfPages;
-    }
-
-    SmsCbEtwsInfo getEtwsInfo() {
-        return mEtwsInfo;
-    }
-
-    SmsCbCmasInfo getCmasInfo() {
-        return mCmasInfo;
-    }
-
-    /**
-     * Return whether this broadcast is an emergency (PWS) message type.
-     * @return true if this message is emergency type; false otherwise
-     */
-    boolean isEmergencyMessage() {
-        return messageIdentifier >= SmsCbConstants.MESSAGE_ID_PWS_FIRST_IDENTIFIER
-                && messageIdentifier <= SmsCbConstants.MESSAGE_ID_PWS_LAST_IDENTIFIER;
-    }
-
-    /**
-     * Return whether this broadcast is an ETWS emergency message type.
-     * @return true if this message is ETWS emergency type; false otherwise
-     */
-    private boolean isEtwsMessage() {
-        return (messageIdentifier & SmsCbConstants.MESSAGE_ID_ETWS_TYPE_MASK)
-                == SmsCbConstants.MESSAGE_ID_ETWS_TYPE;
-    }
-
-    /**
-     * Return whether this broadcast is an ETWS primary notification.
-     * @return true if this message is an ETWS primary notification; false otherwise
-     */
-    boolean isEtwsPrimaryNotification() {
-        return format == FORMAT_ETWS_PRIMARY;
-    }
-
-    /**
-     * Return whether this broadcast is in UMTS format.
-     * @return true if this message is in UMTS format; false otherwise
-     */
-    boolean isUmtsFormat() {
-        return format == FORMAT_UMTS;
-    }
-
-    /**
-     * Return whether this message is a CMAS emergency message type.
-     * @return true if this message is CMAS emergency type; false otherwise
-     */
-    private boolean isCmasMessage() {
-        return messageIdentifier >= SmsCbConstants.MESSAGE_ID_CMAS_FIRST_IDENTIFIER
-                && messageIdentifier <= SmsCbConstants.MESSAGE_ID_CMAS_LAST_IDENTIFIER;
-    }
-
-    /**
-     * Return whether the popup alert flag is set for an ETWS warning notification.
-     * This method assumes that the message ID has already been checked for ETWS type.
-     *
-     * @return true if the message code indicates a popup alert should be displayed
-     */
-    private boolean isEtwsPopupAlert() {
-        return (serialNumber & SmsCbConstants.SERIAL_NUMBER_ETWS_ACTIVATE_POPUP) != 0;
-    }
-
-    /**
-     * Return whether the emergency user alert flag is set for an ETWS warning notification.
-     * This method assumes that the message ID has already been checked for ETWS type.
-     *
-     * @return true if the message code indicates an emergency user alert
-     */
-    private boolean isEtwsEmergencyUserAlert() {
-        return (serialNumber & SmsCbConstants.SERIAL_NUMBER_ETWS_EMERGENCY_USER_ALERT) != 0;
-    }
-
-    /**
-     * Returns the warning type for an ETWS warning notification.
-     * This method assumes that the message ID has already been checked for ETWS type.
-     *
-     * @return the ETWS warning type defined in 3GPP TS 23.041 section 9.3.24
-     */
-    private int getEtwsWarningType() {
-        return messageIdentifier - SmsCbConstants.MESSAGE_ID_ETWS_EARTHQUAKE_WARNING;
-    }
-
-    /**
-     * Returns the message class for a CMAS warning notification.
-     * This method assumes that the message ID has already been checked for CMAS type.
-     * @return the CMAS message class as defined in {@link SmsCbCmasInfo}
-     */
-    private int getCmasMessageClass() {
-        switch (messageIdentifier) {
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL:
-                return SmsCbCmasInfo.CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT;
-
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY:
-                return SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT;
-
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY:
-                return SmsCbCmasInfo.CMAS_CLASS_SEVERE_THREAT;
-
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY:
-                return SmsCbCmasInfo.CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY;
-
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST:
-                return SmsCbCmasInfo.CMAS_CLASS_REQUIRED_MONTHLY_TEST;
-
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXERCISE:
-                return SmsCbCmasInfo.CMAS_CLASS_CMAS_EXERCISE;
-
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE:
-                return SmsCbCmasInfo.CMAS_CLASS_OPERATOR_DEFINED_USE;
-
-            default:
-                return SmsCbCmasInfo.CMAS_CLASS_UNKNOWN;
-        }
-    }
-
-    /**
-     * Returns the severity for a CMAS warning notification. This is only available for extreme
-     * and severe alerts, not for other types such as Presidential Level and AMBER alerts.
-     * This method assumes that the message ID has already been checked for CMAS type.
-     * @return the CMAS severity as defined in {@link SmsCbCmasInfo}
-     */
-    private int getCmasSeverity() {
-        switch (messageIdentifier) {
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY:
-                return SmsCbCmasInfo.CMAS_SEVERITY_EXTREME;
-
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY:
-                return SmsCbCmasInfo.CMAS_SEVERITY_SEVERE;
-
-            default:
-                return SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN;
-        }
-    }
-
-    /**
-     * Returns the urgency for a CMAS warning notification. This is only available for extreme
-     * and severe alerts, not for other types such as Presidential Level and AMBER alerts.
-     * This method assumes that the message ID has already been checked for CMAS type.
-     * @return the CMAS urgency as defined in {@link SmsCbCmasInfo}
-     */
-    private int getCmasUrgency() {
-        switch (messageIdentifier) {
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY:
-                return SmsCbCmasInfo.CMAS_URGENCY_IMMEDIATE;
-
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY:
-                return SmsCbCmasInfo.CMAS_URGENCY_EXPECTED;
-
-            default:
-                return SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN;
-        }
-    }
-
-    /**
-     * Returns the certainty for a CMAS warning notification. This is only available for extreme
-     * and severe alerts, not for other types such as Presidential Level and AMBER alerts.
-     * This method assumes that the message ID has already been checked for CMAS type.
-     * @return the CMAS certainty as defined in {@link SmsCbCmasInfo}
-     */
-    private int getCmasCertainty() {
-        switch (messageIdentifier) {
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED:
-                return SmsCbCmasInfo.CMAS_CERTAINTY_OBSERVED;
-
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY:
-            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY:
-                return SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY;
-
-            default:
-                return SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN;
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "SmsCbHeader{GS=" + geographicalScope + ", serialNumber=0x" +
-                Integer.toHexString(serialNumber) +
-                ", messageIdentifier=0x" + Integer.toHexString(messageIdentifier) +
-                ", DCS=0x" + Integer.toHexString(dataCodingScheme) +
-                ", page " + pageIndex + " of " + nrOfPages + '}';
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
deleted file mode 100644
index da60584..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ /dev/null
@@ -1,1177 +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.internal.telephony.gsm;
-
-import android.telephony.PhoneNumberUtils;
-import android.text.format.Time;
-import android.util.Log;
-
-import com.android.internal.telephony.EncodeException;
-import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.SmsHeader;
-import com.android.internal.telephony.SmsMessageBase;
-
-import java.io.ByteArrayOutputStream;
-import java.io.UnsupportedEncodingException;
-
-import static android.telephony.SmsMessage.ENCODING_16BIT;
-import static android.telephony.SmsMessage.ENCODING_7BIT;
-import static android.telephony.SmsMessage.ENCODING_8BIT;
-import static android.telephony.SmsMessage.ENCODING_KSC5601;
-import static android.telephony.SmsMessage.ENCODING_UNKNOWN;
-import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES;
-import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER;
-import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS;
-import static android.telephony.SmsMessage.MessageClass;
-
-/**
- * A Short Message Service message.
- *
- */
-public class SmsMessage extends SmsMessageBase {
-    static final String LOG_TAG = "GSM";
-
-    private MessageClass messageClass;
-
-    /**
-     * TP-Message-Type-Indicator
-     * 9.2.3
-     */
-    private int mti;
-
-    /** TP-Protocol-Identifier (TP-PID) */
-    private int protocolIdentifier;
-
-    // TP-Data-Coding-Scheme
-    // see TS 23.038
-    private int dataCodingScheme;
-
-    // TP-Reply-Path
-    // e.g. 23.040 9.2.2.1
-    private boolean replyPathPresent = false;
-
-    // "Message Marked for Automatic Deletion Group"
-    // 23.038 Section 4
-    private boolean automaticDeletion;
-
-    /** True if Status Report is for SMS-SUBMIT; false for SMS-COMMAND. */
-    private boolean forSubmit;
-
-    /** The address of the receiver. */
-    private GsmSmsAddress recipientAddress;
-
-    /** Time when SMS-SUBMIT was delivered from SC to MSE. */
-    private long dischargeTimeMillis;
-
-    /**
-     *  TP-Status - status of a previously submitted SMS.
-     *  This field applies to SMS-STATUS-REPORT messages.  0 indicates success;
-     *  see TS 23.040, 9.2.3.15 for description of other possible values.
-     */
-    private int status;
-
-    /**
-     *  TP-Status - status of a previously submitted SMS.
-     *  This field is true iff the message is a SMS-STATUS-REPORT message.
-     */
-    private boolean isStatusReportMessage = false;
-
-    public static class SubmitPdu extends SubmitPduBase {
-    }
-
-    /**
-     * Create an SmsMessage from a raw PDU.
-     */
-    public static SmsMessage createFromPdu(byte[] pdu) {
-        try {
-            SmsMessage msg = new SmsMessage();
-            msg.parsePdu(pdu);
-            return msg;
-        } catch (RuntimeException ex) {
-            Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
-            return null;
-        }
-    }
-
-    /**
-     * 3GPP TS 23.040 9.2.3.9 specifies that Type Zero messages are indicated
-     * by TP_PID field set to value 0x40
-     */
-    public boolean isTypeZero() {
-        return (protocolIdentifier == 0x40);
-    }
-
-    /**
-     * TS 27.005 3.4.1 lines[0] and lines[1] are the two lines read from the
-     * +CMT unsolicited response (PDU mode, of course)
-     *  +CMT: [&lt;alpha>],<length><CR><LF><pdu>
-     *
-     * Only public for debugging
-     *
-     * {@hide}
-     */
-    public static SmsMessage newFromCMT(String[] lines) {
-        try {
-            SmsMessage msg = new SmsMessage();
-            msg.parsePdu(IccUtils.hexStringToBytes(lines[1]));
-            return msg;
-        } catch (RuntimeException ex) {
-            Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
-            return null;
-        }
-    }
-
-    /** @hide */
-    public static SmsMessage newFromCDS(String line) {
-        try {
-            SmsMessage msg = new SmsMessage();
-            msg.parsePdu(IccUtils.hexStringToBytes(line));
-            return msg;
-        } catch (RuntimeException ex) {
-            Log.e(LOG_TAG, "CDS SMS PDU parsing failed: ", ex);
-            return null;
-        }
-    }
-
-    /**
-     * Create an SmsMessage from an SMS EF record.
-     *
-     * @param index Index of SMS record. This should be index in ArrayList
-     *              returned by SmsManager.getAllMessagesFromSim + 1.
-     * @param data Record data.
-     * @return An SmsMessage representing the record.
-     *
-     * @hide
-     */
-    public static SmsMessage createFromEfRecord(int index, byte[] data) {
-        try {
-            SmsMessage msg = new SmsMessage();
-
-            msg.indexOnIcc = index;
-
-            // First byte is status: RECEIVED_READ, RECEIVED_UNREAD, STORED_SENT,
-            // or STORED_UNSENT
-            // See TS 51.011 10.5.3
-            if ((data[0] & 1) == 0) {
-                Log.w(LOG_TAG,
-                        "SMS parsing failed: Trying to parse a free record");
-                return null;
-            } else {
-                msg.statusOnIcc = data[0] & 0x07;
-            }
-
-            int size = data.length - 1;
-
-            // Note: Data may include trailing FF's.  That's OK; message
-            // should still parse correctly.
-            byte[] pdu = new byte[size];
-            System.arraycopy(data, 1, pdu, 0, size);
-            msg.parsePdu(pdu);
-            return msg;
-        } catch (RuntimeException ex) {
-            Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
-            return null;
-        }
-    }
-
-    /**
-     * Get the TP-Layer-Length for the given SMS-SUBMIT PDU Basically, the
-     * length in bytes (not hex chars) less the SMSC header
-     */
-    public static int getTPLayerLengthForPDU(String pdu) {
-        int len = pdu.length() / 2;
-        int smscLen = Integer.parseInt(pdu.substring(0, 2), 16);
-
-        return len - smscLen - 1;
-    }
-
-    /**
-     * Get an SMS-SUBMIT PDU for a destination address and a message
-     *
-     * @param scAddress Service Centre address.  Null means use default.
-     * @return a <code>SubmitPdu</code> containing the encoded SC
-     *         address, if applicable, and the encoded message.
-     *         Returns null on encode error.
-     * @hide
-     */
-    public static SubmitPdu getSubmitPdu(String scAddress,
-            String destinationAddress, String message,
-            boolean statusReportRequested, byte[] header) {
-        return getSubmitPdu(scAddress, destinationAddress, message, statusReportRequested, header,
-                ENCODING_UNKNOWN, 0, 0);
-    }
-
-
-    /**
-     * Get an SMS-SUBMIT PDU for a destination address and a message using the
-     * specified encoding.
-     *
-     * @param scAddress Service Centre address.  Null means use default.
-     * @param encoding Encoding defined by constants in android.telephony.SmsMessage.ENCODING_*
-     * @param languageTable
-     * @param languageShiftTable
-     * @return a <code>SubmitPdu</code> containing the encoded SC
-     *         address, if applicable, and the encoded message.
-     *         Returns null on encode error.
-     * @hide
-     */
-    public static SubmitPdu getSubmitPdu(String scAddress,
-            String destinationAddress, String message,
-            boolean statusReportRequested, byte[] header, int encoding,
-            int languageTable, int languageShiftTable) {
-
-        // Perform null parameter checks.
-        if (message == null || destinationAddress == null) {
-            return null;
-        }
-
-        if (encoding == ENCODING_UNKNOWN) {
-            // Find the best encoding to use
-            TextEncodingDetails ted = calculateLength(message, false);
-            encoding = ted.codeUnitSize;
-            languageTable = ted.languageTable;
-            languageShiftTable = ted.languageShiftTable;
-
-            if (encoding == ENCODING_7BIT && (languageTable != 0 || languageShiftTable != 0)) {
-                if (header != null) {
-                    SmsHeader smsHeader = SmsHeader.fromByteArray(header);
-                    if (smsHeader.languageTable != languageTable
-                            || smsHeader.languageShiftTable != languageShiftTable) {
-                        Log.w(LOG_TAG, "Updating language table in SMS header: "
-                                + smsHeader.languageTable + " -> " + languageTable + ", "
-                                + smsHeader.languageShiftTable + " -> " + languageShiftTable);
-                        smsHeader.languageTable = languageTable;
-                        smsHeader.languageShiftTable = languageShiftTable;
-                        header = SmsHeader.toByteArray(smsHeader);
-                    }
-                } else {
-                    SmsHeader smsHeader = new SmsHeader();
-                    smsHeader.languageTable = languageTable;
-                    smsHeader.languageShiftTable = languageShiftTable;
-                    header = SmsHeader.toByteArray(smsHeader);
-                }
-            }
-        }
-
-        SubmitPdu ret = new SubmitPdu();
-        // MTI = SMS-SUBMIT, UDHI = header != null
-        byte mtiByte = (byte)(0x01 | (header != null ? 0x40 : 0x00));
-        ByteArrayOutputStream bo = getSubmitPduHead(
-                scAddress, destinationAddress, mtiByte,
-                statusReportRequested, ret);
-
-        // User Data (and length)
-        byte[] userData;
-        try {
-            if (encoding == ENCODING_7BIT) {
-                userData = GsmAlphabet.stringToGsm7BitPackedWithHeader(message, header,
-                        languageTable, languageShiftTable);
-            } else { //assume UCS-2
-                try {
-                    userData = encodeUCS2(message, header);
-                } catch(UnsupportedEncodingException uex) {
-                    Log.e(LOG_TAG,
-                            "Implausible UnsupportedEncodingException ",
-                            uex);
-                    return null;
-                }
-            }
-        } catch (EncodeException ex) {
-            // Encoding to the 7-bit alphabet failed. Let's see if we can
-            // send it as a UCS-2 encoded message
-            try {
-                userData = encodeUCS2(message, header);
-                encoding = ENCODING_16BIT;
-            } catch(UnsupportedEncodingException uex) {
-                Log.e(LOG_TAG,
-                        "Implausible UnsupportedEncodingException ",
-                        uex);
-                return null;
-            }
-        }
-
-        if (encoding == ENCODING_7BIT) {
-            if ((0xff & userData[0]) > MAX_USER_DATA_SEPTETS) {
-                // Message too long
-                Log.e(LOG_TAG, "Message too long (" + (0xff & userData[0]) + " septets)");
-                return null;
-            }
-            // TP-Data-Coding-Scheme
-            // Default encoding, uncompressed
-            // To test writing messages to the SIM card, change this value 0x00
-            // to 0x12, which means "bits 1 and 0 contain message class, and the
-            // class is 2". Note that this takes effect for the sender. In other
-            // words, messages sent by the phone with this change will end up on
-            // the receiver's SIM card. You can then send messages to yourself
-            // (on a phone with this change) and they'll end up on the SIM card.
-            bo.write(0x00);
-        } else { // assume UCS-2
-            if ((0xff & userData[0]) > MAX_USER_DATA_BYTES) {
-                // Message too long
-                Log.e(LOG_TAG, "Message too long (" + (0xff & userData[0]) + " bytes)");
-                return null;
-            }
-            // TP-Data-Coding-Scheme
-            // UCS-2 encoding, uncompressed
-            bo.write(0x08);
-        }
-
-        // (no TP-Validity-Period)
-        bo.write(userData, 0, userData.length);
-        ret.encodedMessage = bo.toByteArray();
-        return ret;
-    }
-
-    /**
-     * Packs header and UCS-2 encoded message. Includes TP-UDL & TP-UDHL if necessary
-     *
-     * @return
-     * @throws UnsupportedEncodingException
-     */
-    private static byte[] encodeUCS2(String message, byte[] header)
-        throws UnsupportedEncodingException {
-        byte[] userData, textPart;
-        textPart = message.getBytes("utf-16be");
-
-        if (header != null) {
-            // Need 1 byte for UDHL
-            userData = new byte[header.length + textPart.length + 1];
-
-            userData[0] = (byte)header.length;
-            System.arraycopy(header, 0, userData, 1, header.length);
-            System.arraycopy(textPart, 0, userData, header.length + 1, textPart.length);
-        }
-        else {
-            userData = textPart;
-        }
-        byte[] ret = new byte[userData.length+1];
-        ret[0] = (byte) (userData.length & 0xff );
-        System.arraycopy(userData, 0, ret, 1, userData.length);
-        return ret;
-    }
-
-    /**
-     * Get an SMS-SUBMIT PDU for a destination address and a message
-     *
-     * @param scAddress Service Centre address.  Null means use default.
-     * @return a <code>SubmitPdu</code> containing the encoded SC
-     *         address, if applicable, and the encoded message.
-     *         Returns null on encode error.
-     */
-    public static SubmitPdu getSubmitPdu(String scAddress,
-            String destinationAddress, String message,
-            boolean statusReportRequested) {
-
-        return getSubmitPdu(scAddress, destinationAddress, message, statusReportRequested, null);
-    }
-
-    /**
-     * Get an SMS-SUBMIT PDU for a data message to a destination address &amp; port
-     *
-     * @param scAddress Service Centre address. null == use default
-     * @param destinationAddress the address of the destination for the message
-     * @param destinationPort the port to deliver the message to at the
-     *        destination
-     * @param data the data for the message
-     * @return a <code>SubmitPdu</code> containing the encoded SC
-     *         address, if applicable, and the encoded message.
-     *         Returns null on encode error.
-     */
-    public static SubmitPdu getSubmitPdu(String scAddress,
-            String destinationAddress, int destinationPort, byte[] data,
-            boolean statusReportRequested) {
-
-        SmsHeader.PortAddrs portAddrs = new SmsHeader.PortAddrs();
-        portAddrs.destPort = destinationPort;
-        portAddrs.origPort = 0;
-        portAddrs.areEightBits = false;
-
-        SmsHeader smsHeader = new SmsHeader();
-        smsHeader.portAddrs = portAddrs;
-
-        byte[] smsHeaderData = SmsHeader.toByteArray(smsHeader);
-
-        if ((data.length + smsHeaderData.length + 1) > MAX_USER_DATA_BYTES) {
-            Log.e(LOG_TAG, "SMS data message may only contain "
-                    + (MAX_USER_DATA_BYTES - smsHeaderData.length - 1) + " bytes");
-            return null;
-        }
-
-        SubmitPdu ret = new SubmitPdu();
-        ByteArrayOutputStream bo = getSubmitPduHead(
-                scAddress, destinationAddress, (byte) 0x41, // MTI = SMS-SUBMIT,
-                                                            // TP-UDHI = true
-                statusReportRequested, ret);
-
-        // TP-Data-Coding-Scheme
-        // No class, 8 bit data
-        bo.write(0x04);
-
-        // (no TP-Validity-Period)
-
-        // Total size
-        bo.write(data.length + smsHeaderData.length + 1);
-
-        // User data header
-        bo.write(smsHeaderData.length);
-        bo.write(smsHeaderData, 0, smsHeaderData.length);
-
-        // User data
-        bo.write(data, 0, data.length);
-
-        ret.encodedMessage = bo.toByteArray();
-        return ret;
-    }
-
-    /**
-     * Create the beginning of a SUBMIT PDU.  This is the part of the
-     * SUBMIT PDU that is common to the two versions of {@link #getSubmitPdu},
-     * one of which takes a byte array and the other of which takes a
-     * <code>String</code>.
-     *
-     * @param scAddress Service Centre address. null == use default
-     * @param destinationAddress the address of the destination for the message
-     * @param mtiByte
-     * @param ret <code>SubmitPdu</code> containing the encoded SC
-     *        address, if applicable, and the encoded message
-     */
-    private static ByteArrayOutputStream getSubmitPduHead(
-            String scAddress, String destinationAddress, byte mtiByte,
-            boolean statusReportRequested, SubmitPdu ret) {
-        ByteArrayOutputStream bo = new ByteArrayOutputStream(
-                MAX_USER_DATA_BYTES + 40);
-
-        // SMSC address with length octet, or 0
-        if (scAddress == null) {
-            ret.encodedScAddress = null;
-        } else {
-            ret.encodedScAddress = PhoneNumberUtils.networkPortionToCalledPartyBCDWithLength(
-                    scAddress);
-        }
-
-        // TP-Message-Type-Indicator (and friends)
-        if (statusReportRequested) {
-            // Set TP-Status-Report-Request bit.
-            mtiByte |= 0x20;
-            if (false) Log.d(LOG_TAG, "SMS status report requested");
-        }
-        bo.write(mtiByte);
-
-        // space for TP-Message-Reference
-        bo.write(0);
-
-        byte[] daBytes;
-
-        daBytes = PhoneNumberUtils.networkPortionToCalledPartyBCD(destinationAddress);
-
-        // destination address length in BCD digits, ignoring TON byte and pad
-        // TODO Should be better.
-        bo.write((daBytes.length - 1) * 2
-                - ((daBytes[daBytes.length - 1] & 0xf0) == 0xf0 ? 1 : 0));
-
-        // destination address
-        bo.write(daBytes, 0, daBytes.length);
-
-        // TP-Protocol-Identifier
-        bo.write(0);
-        return bo;
-    }
-
-    private static class PduParser {
-        byte pdu[];
-        int cur;
-        SmsHeader userDataHeader;
-        byte[] userData;
-        int mUserDataSeptetPadding;
-        int mUserDataSize;
-
-        PduParser(byte[] pdu) {
-            this.pdu = pdu;
-            cur = 0;
-            mUserDataSeptetPadding = 0;
-        }
-
-        /**
-         * Parse and return the SC address prepended to SMS messages coming via
-         * the TS 27.005 / AT interface.  Returns null on invalid address
-         */
-        String getSCAddress() {
-            int len;
-            String ret;
-
-            // length of SC Address
-            len = getByte();
-
-            if (len == 0) {
-                // no SC address
-                ret = null;
-            } else {
-                // SC address
-                try {
-                    ret = PhoneNumberUtils
-                            .calledPartyBCDToString(pdu, cur, len);
-                } catch (RuntimeException tr) {
-                    Log.d(LOG_TAG, "invalid SC address: ", tr);
-                    ret = null;
-                }
-            }
-
-            cur += len;
-
-            return ret;
-        }
-
-        /**
-         * returns non-sign-extended byte value
-         */
-        int getByte() {
-            return pdu[cur++] & 0xff;
-        }
-
-        /**
-         * Any address except the SC address (eg, originating address) See TS
-         * 23.040 9.1.2.5
-         */
-        GsmSmsAddress getAddress() {
-            GsmSmsAddress ret;
-
-            // "The Address-Length field is an integer representation of
-            // the number field, i.e. excludes any semi-octet containing only
-            // fill bits."
-            // The TOA field is not included as part of this
-            int addressLength = pdu[cur] & 0xff;
-            int lengthBytes = 2 + (addressLength + 1) / 2;
-
-            ret = new GsmSmsAddress(pdu, cur, lengthBytes);
-
-            cur += lengthBytes;
-
-            return ret;
-        }
-
-        /**
-         * Parses an SC timestamp and returns a currentTimeMillis()-style
-         * timestamp
-         */
-
-        long getSCTimestampMillis() {
-            // TP-Service-Centre-Time-Stamp
-            int year = IccUtils.gsmBcdByteToInt(pdu[cur++]);
-            int month = IccUtils.gsmBcdByteToInt(pdu[cur++]);
-            int day = IccUtils.gsmBcdByteToInt(pdu[cur++]);
-            int hour = IccUtils.gsmBcdByteToInt(pdu[cur++]);
-            int minute = IccUtils.gsmBcdByteToInt(pdu[cur++]);
-            int second = IccUtils.gsmBcdByteToInt(pdu[cur++]);
-
-            // For the timezone, the most significant bit of the
-            // least significant nibble is the sign byte
-            // (meaning the max range of this field is 79 quarter-hours,
-            // which is more than enough)
-
-            byte tzByte = pdu[cur++];
-
-            // Mask out sign bit.
-            int timezoneOffset = IccUtils.gsmBcdByteToInt((byte) (tzByte & (~0x08)));
-
-            timezoneOffset = ((tzByte & 0x08) == 0) ? timezoneOffset : -timezoneOffset;
-
-            Time time = new Time(Time.TIMEZONE_UTC);
-
-            // It's 2006.  Should I really support years < 2000?
-            time.year = year >= 90 ? year + 1900 : year + 2000;
-            time.month = month - 1;
-            time.monthDay = day;
-            time.hour = hour;
-            time.minute = minute;
-            time.second = second;
-
-            // Timezone offset is in quarter hours.
-            return time.toMillis(true) - (timezoneOffset * 15 * 60 * 1000);
-        }
-
-        /**
-         * Pulls the user data out of the PDU, and separates the payload from
-         * the header if there is one.
-         *
-         * @param hasUserDataHeader true if there is a user data header
-         * @param dataInSeptets true if the data payload is in septets instead
-         *  of octets
-         * @return the number of septets or octets in the user data payload
-         */
-        int constructUserData(boolean hasUserDataHeader, boolean dataInSeptets) {
-            int offset = cur;
-            int userDataLength = pdu[offset++] & 0xff;
-            int headerSeptets = 0;
-            int userDataHeaderLength = 0;
-
-            if (hasUserDataHeader) {
-                userDataHeaderLength = pdu[offset++] & 0xff;
-
-                byte[] udh = new byte[userDataHeaderLength];
-                System.arraycopy(pdu, offset, udh, 0, userDataHeaderLength);
-                userDataHeader = SmsHeader.fromByteArray(udh);
-                offset += userDataHeaderLength;
-
-                int headerBits = (userDataHeaderLength + 1) * 8;
-                headerSeptets = headerBits / 7;
-                headerSeptets += (headerBits % 7) > 0 ? 1 : 0;
-                mUserDataSeptetPadding = (headerSeptets * 7) - headerBits;
-            }
-
-            int bufferLen;
-            if (dataInSeptets) {
-                /*
-                 * Here we just create the user data length to be the remainder of
-                 * the pdu minus the user data header, since userDataLength means
-                 * the number of uncompressed septets.
-                 */
-                bufferLen = pdu.length - offset;
-            } else {
-                /*
-                 * userDataLength is the count of octets, so just subtract the
-                 * user data header.
-                 */
-                bufferLen = userDataLength - (hasUserDataHeader ? (userDataHeaderLength + 1) : 0);
-                if (bufferLen < 0) {
-                    bufferLen = 0;
-                }
-            }
-
-            userData = new byte[bufferLen];
-            System.arraycopy(pdu, offset, userData, 0, userData.length);
-            cur = offset;
-
-            if (dataInSeptets) {
-                // Return the number of septets
-                int count = userDataLength - headerSeptets;
-                // If count < 0, return 0 (means UDL was probably incorrect)
-                return count < 0 ? 0 : count;
-            } else {
-                // Return the number of octets
-                return userData.length;
-            }
-        }
-
-        /**
-         * Returns the user data payload, not including the headers
-         *
-         * @return the user data payload, not including the headers
-         */
-        byte[] getUserData() {
-            return userData;
-        }
-
-        /**
-         * Returns the number of padding bits at the beginning of the user data
-         * array before the start of the septets.
-         *
-         * @return the number of padding bits at the beginning of the user data
-         * array before the start of the septets
-         */
-        int getUserDataSeptetPadding() {
-            return mUserDataSeptetPadding;
-        }
-
-        /**
-         * Returns an object representing the user data headers
-         *
-         * {@hide}
-         */
-        SmsHeader getUserDataHeader() {
-            return userDataHeader;
-        }
-
-        /**
-         * Interprets the user data payload as packed GSM 7bit characters, and
-         * decodes them into a String.
-         *
-         * @param septetCount the number of septets in the user data payload
-         * @return a String with the decoded characters
-         */
-        String getUserDataGSM7Bit(int septetCount, int languageTable,
-                int languageShiftTable) {
-            String ret;
-
-            ret = GsmAlphabet.gsm7BitPackedToString(pdu, cur, septetCount,
-                    mUserDataSeptetPadding, languageTable, languageShiftTable);
-
-            cur += (septetCount * 7) / 8;
-
-            return ret;
-        }
-
-        /**
-         * Interprets the user data payload as UCS2 characters, and
-         * decodes them into a String.
-         *
-         * @param byteCount the number of bytes in the user data payload
-         * @return a String with the decoded characters
-         */
-        String getUserDataUCS2(int byteCount) {
-            String ret;
-
-            try {
-                ret = new String(pdu, cur, byteCount, "utf-16");
-            } catch (UnsupportedEncodingException ex) {
-                ret = "";
-                Log.e(LOG_TAG, "implausible UnsupportedEncodingException", ex);
-            }
-
-            cur += byteCount;
-            return ret;
-        }
-
-        /**
-         * Interprets the user data payload as KSC-5601 characters, and
-         * decodes them into a String.
-         *
-         * @param byteCount the number of bytes in the user data payload
-         * @return a String with the decoded characters
-         */
-        String getUserDataKSC5601(int byteCount) {
-            String ret;
-
-            try {
-                ret = new String(pdu, cur, byteCount, "KSC5601");
-            } catch (UnsupportedEncodingException ex) {
-                ret = "";
-                Log.e(LOG_TAG, "implausible UnsupportedEncodingException", ex);
-            }
-
-            cur += byteCount;
-            return ret;
-        }
-
-        boolean moreDataPresent() {
-            return (pdu.length > cur);
-        }
-    }
-
-    /**
-     * Calculate the number of septets needed to encode the message.
-     *
-     * @param msgBody the message to encode
-     * @param use7bitOnly ignore (but still count) illegal characters if true
-     * @return TextEncodingDetails
-     */
-    public static TextEncodingDetails calculateLength(CharSequence msgBody,
-            boolean use7bitOnly) {
-        TextEncodingDetails ted = GsmAlphabet.countGsmSeptets(msgBody, use7bitOnly);
-        if (ted == null) {
-            ted = new TextEncodingDetails();
-            int octets = msgBody.length() * 2;
-            ted.codeUnitCount = msgBody.length();
-            if (octets > MAX_USER_DATA_BYTES) {
-                ted.msgCount = (octets + (MAX_USER_DATA_BYTES_WITH_HEADER - 1)) /
-                        MAX_USER_DATA_BYTES_WITH_HEADER;
-                ted.codeUnitsRemaining = ((ted.msgCount *
-                        MAX_USER_DATA_BYTES_WITH_HEADER) - octets) / 2;
-            } else {
-                ted.msgCount = 1;
-                ted.codeUnitsRemaining = (MAX_USER_DATA_BYTES - octets)/2;
-            }
-            ted.codeUnitSize = ENCODING_16BIT;
-        }
-        return ted;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int getProtocolIdentifier() {
-        return protocolIdentifier;
-    }
-
-    /**
-     * Returns the TP-Data-Coding-Scheme byte, for acknowledgement of SMS-PP download messages.
-     * @return the TP-DCS field of the SMS header
-     */
-    int getDataCodingScheme() {
-        return dataCodingScheme;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isReplace() {
-        return (protocolIdentifier & 0xc0) == 0x40
-                && (protocolIdentifier & 0x3f) > 0
-                && (protocolIdentifier & 0x3f) < 8;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isCphsMwiMessage() {
-        return ((GsmSmsAddress) originatingAddress).isCphsVoiceMessageClear()
-                || ((GsmSmsAddress) originatingAddress).isCphsVoiceMessageSet();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isMWIClearMessage() {
-        if (isMwi && !mwiSense) {
-            return true;
-        }
-
-        return originatingAddress != null
-                && ((GsmSmsAddress) originatingAddress).isCphsVoiceMessageClear();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isMWISetMessage() {
-        if (isMwi && mwiSense) {
-            return true;
-        }
-
-        return originatingAddress != null
-                && ((GsmSmsAddress) originatingAddress).isCphsVoiceMessageSet();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isMwiDontStore() {
-        if (isMwi && mwiDontStore) {
-            return true;
-        }
-
-        if (isCphsMwiMessage()) {
-            // See CPHS 4.2 Section B.4.2.1
-            // If the user data is a single space char, do not store
-            // the message. Otherwise, store and display as usual
-            if (" ".equals(getMessageBody())) {
-                ;
-            }
-            return true;
-        }
-
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int getStatus() {
-        return status;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isStatusReportMessage() {
-        return isStatusReportMessage;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public boolean isReplyPathPresent() {
-        return replyPathPresent;
-    }
-
-    /**
-     * TS 27.005 3.1, &lt;pdu&gt; definition "In the case of SMS: 3GPP TS 24.011 [6]
-     * SC address followed by 3GPP TS 23.040 [3] TPDU in hexadecimal format:
-     * ME/TA converts each octet of TP data unit into two IRA character long
-     * hex number (e.g. octet with integer value 42 is presented to TE as two
-     * characters 2A (IRA 50 and 65))" ...in the case of cell broadcast,
-     * something else...
-     */
-    private void parsePdu(byte[] pdu) {
-        mPdu = pdu;
-        // Log.d(LOG_TAG, "raw sms message:");
-        // Log.d(LOG_TAG, s);
-
-        PduParser p = new PduParser(pdu);
-
-        scAddress = p.getSCAddress();
-
-        if (scAddress != null) {
-            if (false) Log.d(LOG_TAG, "SMS SC address: " + scAddress);
-        }
-
-        // TODO(mkf) support reply path, user data header indicator
-
-        // TP-Message-Type-Indicator
-        // 9.2.3
-        int firstByte = p.getByte();
-
-        mti = firstByte & 0x3;
-        switch (mti) {
-        // TP-Message-Type-Indicator
-        // 9.2.3
-        case 0:
-        case 3: //GSM 03.40 9.2.3.1: MTI == 3 is Reserved.
-                //This should be processed in the same way as MTI == 0 (Deliver)
-            parseSmsDeliver(p, firstByte);
-            break;
-        case 2:
-            parseSmsStatusReport(p, firstByte);
-            break;
-        default:
-            // TODO(mkf) the rest of these
-            throw new RuntimeException("Unsupported message type");
-        }
-    }
-
-    /**
-     * Parses a SMS-STATUS-REPORT message.
-     *
-     * @param p A PduParser, cued past the first byte.
-     * @param firstByte The first byte of the PDU, which contains MTI, etc.
-     */
-    private void parseSmsStatusReport(PduParser p, int firstByte) {
-        isStatusReportMessage = true;
-
-        // TP-Status-Report-Qualifier bit == 0 for SUBMIT
-        forSubmit = (firstByte & 0x20) == 0x00;
-        // TP-Message-Reference
-        messageRef = p.getByte();
-        // TP-Recipient-Address
-        recipientAddress = p.getAddress();
-        // TP-Service-Centre-Time-Stamp
-        scTimeMillis = p.getSCTimestampMillis();
-        // TP-Discharge-Time
-        dischargeTimeMillis = p.getSCTimestampMillis();
-        // TP-Status
-        status = p.getByte();
-
-        // The following are optional fields that may or may not be present.
-        if (p.moreDataPresent()) {
-            // TP-Parameter-Indicator
-            int extraParams = p.getByte();
-            int moreExtraParams = extraParams;
-            while ((moreExtraParams & 0x80) != 0) {
-                // We only know how to parse a few extra parameters, all
-                // indicated in the first TP-PI octet, so skip over any
-                // additional TP-PI octets.
-                moreExtraParams = p.getByte();
-            }
-            // TP-Protocol-Identifier
-            if ((extraParams & 0x01) != 0) {
-                protocolIdentifier = p.getByte();
-            }
-            // TP-Data-Coding-Scheme
-            if ((extraParams & 0x02) != 0) {
-                dataCodingScheme = p.getByte();
-            }
-            // TP-User-Data-Length (implies existence of TP-User-Data)
-            if ((extraParams & 0x04) != 0) {
-                boolean hasUserDataHeader = (firstByte & 0x40) == 0x40;
-                parseUserData(p, hasUserDataHeader);
-            }
-        }
-    }
-
-    private void parseSmsDeliver(PduParser p, int firstByte) {
-        replyPathPresent = (firstByte & 0x80) == 0x80;
-
-        originatingAddress = p.getAddress();
-
-        if (originatingAddress != null) {
-            if (false) Log.v(LOG_TAG, "SMS originating address: "
-                    + originatingAddress.address);
-        }
-
-        // TP-Protocol-Identifier (TP-PID)
-        // TS 23.040 9.2.3.9
-        protocolIdentifier = p.getByte();
-
-        // TP-Data-Coding-Scheme
-        // see TS 23.038
-        dataCodingScheme = p.getByte();
-
-        if (false) {
-            Log.v(LOG_TAG, "SMS TP-PID:" + protocolIdentifier
-                    + " data coding scheme: " + dataCodingScheme);
-        }
-
-        scTimeMillis = p.getSCTimestampMillis();
-
-        if (false) Log.d(LOG_TAG, "SMS SC timestamp: " + scTimeMillis);
-
-        boolean hasUserDataHeader = (firstByte & 0x40) == 0x40;
-
-        parseUserData(p, hasUserDataHeader);
-    }
-
-    /**
-     * Parses the User Data of an SMS.
-     *
-     * @param p The current PduParser.
-     * @param hasUserDataHeader Indicates whether a header is present in the
-     *                          User Data.
-     */
-    private void parseUserData(PduParser p, boolean hasUserDataHeader) {
-        boolean hasMessageClass = false;
-        boolean userDataCompressed = false;
-
-        int encodingType = ENCODING_UNKNOWN;
-
-        // Look up the data encoding scheme
-        if ((dataCodingScheme & 0x80) == 0) {
-            // Bits 7..4 == 0xxx
-            automaticDeletion = (0 != (dataCodingScheme & 0x40));
-            userDataCompressed = (0 != (dataCodingScheme & 0x20));
-            hasMessageClass = (0 != (dataCodingScheme & 0x10));
-
-            if (userDataCompressed) {
-                Log.w(LOG_TAG, "4 - Unsupported SMS data coding scheme "
-                        + "(compression) " + (dataCodingScheme & 0xff));
-            } else {
-                switch ((dataCodingScheme >> 2) & 0x3) {
-                case 0: // GSM 7 bit default alphabet
-                    encodingType = ENCODING_7BIT;
-                    break;
-
-                case 2: // UCS 2 (16bit)
-                    encodingType = ENCODING_16BIT;
-                    break;
-
-                case 1: // 8 bit data
-                case 3: // reserved
-                    Log.w(LOG_TAG, "1 - Unsupported SMS data coding scheme "
-                            + (dataCodingScheme & 0xff));
-                    encodingType = ENCODING_8BIT;
-                    break;
-                }
-            }
-        } else if ((dataCodingScheme & 0xf0) == 0xf0) {
-            automaticDeletion = false;
-            hasMessageClass = true;
-            userDataCompressed = false;
-
-            if (0 == (dataCodingScheme & 0x04)) {
-                // GSM 7 bit default alphabet
-                encodingType = ENCODING_7BIT;
-            } else {
-                // 8 bit data
-                encodingType = ENCODING_8BIT;
-            }
-        } else if ((dataCodingScheme & 0xF0) == 0xC0
-                || (dataCodingScheme & 0xF0) == 0xD0
-                || (dataCodingScheme & 0xF0) == 0xE0) {
-            // 3GPP TS 23.038 V7.0.0 (2006-03) section 4
-
-            // 0xC0 == 7 bit, don't store
-            // 0xD0 == 7 bit, store
-            // 0xE0 == UCS-2, store
-
-            if ((dataCodingScheme & 0xF0) == 0xE0) {
-                encodingType = ENCODING_16BIT;
-            } else {
-                encodingType = ENCODING_7BIT;
-            }
-
-            userDataCompressed = false;
-            boolean active = ((dataCodingScheme & 0x08) == 0x08);
-
-            // bit 0x04 reserved
-
-            if ((dataCodingScheme & 0x03) == 0x00) {
-                isMwi = true;
-                mwiSense = active;
-                mwiDontStore = ((dataCodingScheme & 0xF0) == 0xC0);
-            } else {
-                isMwi = false;
-
-                Log.w(LOG_TAG, "MWI for fax, email, or other "
-                        + (dataCodingScheme & 0xff));
-            }
-        } else if ((dataCodingScheme & 0xC0) == 0x80) {
-            // 3GPP TS 23.038 V7.0.0 (2006-03) section 4
-            // 0x80..0xBF == Reserved coding groups
-            if (dataCodingScheme == 0x84) {
-                // This value used for KSC5601 by carriers in Korea.
-                encodingType = ENCODING_KSC5601;
-            } else {
-                Log.w(LOG_TAG, "5 - Unsupported SMS data coding scheme "
-                        + (dataCodingScheme & 0xff));
-            }
-        } else {
-            Log.w(LOG_TAG, "3 - Unsupported SMS data coding scheme "
-                    + (dataCodingScheme & 0xff));
-        }
-
-        // set both the user data and the user data header.
-        int count = p.constructUserData(hasUserDataHeader,
-                encodingType == ENCODING_7BIT);
-        this.userData = p.getUserData();
-        this.userDataHeader = p.getUserDataHeader();
-
-        switch (encodingType) {
-        case ENCODING_UNKNOWN:
-        case ENCODING_8BIT:
-            messageBody = null;
-            break;
-
-        case ENCODING_7BIT:
-            messageBody = p.getUserDataGSM7Bit(count,
-                    hasUserDataHeader ? userDataHeader.languageTable : 0,
-                    hasUserDataHeader ? userDataHeader.languageShiftTable : 0);
-            break;
-
-        case ENCODING_16BIT:
-            messageBody = p.getUserDataUCS2(count);
-            break;
-
-        case ENCODING_KSC5601:
-            messageBody = p.getUserDataKSC5601(count);
-            break;
-        }
-
-        if (false) Log.v(LOG_TAG, "SMS message body (raw): '" + messageBody + "'");
-
-        if (messageBody != null) {
-            parseMessageBody();
-        }
-
-        if (!hasMessageClass) {
-            messageClass = MessageClass.UNKNOWN;
-        } else {
-            switch (dataCodingScheme & 0x3) {
-            case 0:
-                messageClass = MessageClass.CLASS_0;
-                break;
-            case 1:
-                messageClass = MessageClass.CLASS_1;
-                break;
-            case 2:
-                messageClass = MessageClass.CLASS_2;
-                break;
-            case 3:
-                messageClass = MessageClass.CLASS_3;
-                break;
-            }
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public MessageClass getMessageClass() {
-        return messageClass;
-    }
-
-    /**
-     * Returns true if this is a (U)SIM data download type SM.
-     * See 3GPP TS 31.111 section 9.1 and TS 23.040 section 9.2.3.9.
-     *
-     * @return true if this is a USIM data download message; false otherwise
-     */
-    boolean isUsimDataDownload() {
-        return messageClass == MessageClass.CLASS_2 &&
-                (protocolIdentifier == 0x7f || protocolIdentifier == 0x7c);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SpnOverride.java b/telephony/java/com/android/internal/telephony/gsm/SpnOverride.java
deleted file mode 100644
index 918c2d2..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/SpnOverride.java
+++ /dev/null
@@ -1,94 +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.
- */
-
-package com.android.internal.telephony.gsm;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.HashMap;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.os.Environment;
-import android.util.Log;
-import android.util.Xml;
-
-import com.android.internal.util.XmlUtils;
-
-public class SpnOverride {
-    private HashMap<String, String> CarrierSpnMap;
-
-
-    static final String LOG_TAG = "GSM";
-    static final String PARTNER_SPN_OVERRIDE_PATH ="etc/spn-conf.xml";
-
-    SpnOverride () {
-        CarrierSpnMap = new HashMap<String, String>();
-        loadSpnOverrides();
-    }
-
-    boolean containsCarrier(String carrier) {
-        return CarrierSpnMap.containsKey(carrier);
-    }
-
-    String getSpn(String carrier) {
-        return CarrierSpnMap.get(carrier);
-    }
-
-    private void loadSpnOverrides() {
-        FileReader spnReader;
-
-        final File spnFile = new File(Environment.getRootDirectory(),
-                PARTNER_SPN_OVERRIDE_PATH);
-
-        try {
-            spnReader = new FileReader(spnFile);
-        } catch (FileNotFoundException e) {
-            Log.w(LOG_TAG, "Can't open " +
-                    Environment.getRootDirectory() + "/" + PARTNER_SPN_OVERRIDE_PATH);
-            return;
-        }
-
-        try {
-            XmlPullParser parser = Xml.newPullParser();
-            parser.setInput(spnReader);
-
-            XmlUtils.beginDocument(parser, "spnOverrides");
-
-            while (true) {
-                XmlUtils.nextElement(parser);
-
-                String name = parser.getName();
-                if (!"spnOverride".equals(name)) {
-                    break;
-                }
-
-                String numeric = parser.getAttributeValue(null, "numeric");
-                String data    = parser.getAttributeValue(null, "spn");
-
-                CarrierSpnMap.put(numeric, data);
-            }
-        } catch (XmlPullParserException e) {
-            Log.w(LOG_TAG, "Exception in spn-conf parser " + e);
-        } catch (IOException e) {
-            Log.w(LOG_TAG, "Exception in spn-conf parser " + e);
-        }
-    }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java b/telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java
deleted file mode 100644
index e68655e..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.internal.telephony.gsm;
-
-import android.telephony.PhoneNumberUtils;
-
-/**
- * Represents a Supplementary Service Notification received from the network.
- *
- * {@hide}
- */
-public class SuppServiceNotification {
-    /** Type of notification: 0 = MO; 1 = MT */
-    public int notificationType;
-    /** TS 27.007 7.17 "code1" or "code2" */
-    public int code;
-    /** TS 27.007 7.17 "index" */
-    public int index;
-    /** TS 27.007 7.17 "type" (MT only) */
-    public int type;
-    /** TS 27.007 7.17 "number" (MT only) */
-    public String number;
-
-    static public final int MO_CODE_UNCONDITIONAL_CF_ACTIVE     = 0;
-    static public final int MO_CODE_SOME_CF_ACTIVE              = 1;
-    static public final int MO_CODE_CALL_FORWARDED              = 2;
-    static public final int MO_CODE_CALL_IS_WAITING             = 3;
-    static public final int MO_CODE_CUG_CALL                    = 4;
-    static public final int MO_CODE_OUTGOING_CALLS_BARRED       = 5;
-    static public final int MO_CODE_INCOMING_CALLS_BARRED       = 6;
-    static public final int MO_CODE_CLIR_SUPPRESSION_REJECTED   = 7;
-    static public final int MO_CODE_CALL_DEFLECTED              = 8;
-
-    static public final int MT_CODE_FORWARDED_CALL              = 0;
-    static public final int MT_CODE_CUG_CALL                    = 1;
-    static public final int MT_CODE_CALL_ON_HOLD                = 2;
-    static public final int MT_CODE_CALL_RETRIEVED              = 3;
-    static public final int MT_CODE_MULTI_PARTY_CALL            = 4;
-    static public final int MT_CODE_ON_HOLD_CALL_RELEASED       = 5;
-    static public final int MT_CODE_FORWARD_CHECK_RECEIVED      = 6;
-    static public final int MT_CODE_CALL_CONNECTING_ECT         = 7;
-    static public final int MT_CODE_CALL_CONNECTED_ECT          = 8;
-    static public final int MT_CODE_DEFLECTED_CALL              = 9;
-    static public final int MT_CODE_ADDITIONAL_CALL_FORWARDED   = 10;
-
-    public String toString()
-    {
-        return super.toString() + " mobile"
-            + (notificationType == 0 ? " originated " : " terminated ")
-            + " code: " + code
-            + " index: " + index
-            + " \""
-            + PhoneNumberUtils.stringFromStringAndTOA(number, type) + "\" ";
-    }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/UsimDataDownloadHandler.java b/telephony/java/com/android/internal/telephony/gsm/UsimDataDownloadHandler.java
deleted file mode 100644
index f47ff1b..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/UsimDataDownloadHandler.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2011 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.internal.telephony.gsm;
-
-import android.app.Activity;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.Telephony.Sms.Intents;
-import android.util.Log;
-
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.IccIoResult;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.cat.ComprehensionTlvTag;
-
-/**
- * Handler for SMS-PP data download messages.
- * See 3GPP TS 31.111 section 7.1.1
- */
-public class UsimDataDownloadHandler extends Handler {
-    private static final String TAG = "UsimDataDownloadHandler";
-
-    /** BER-TLV tag for SMS-PP download. TS 31.111 section 9.1. */
-    private static final int BER_SMS_PP_DOWNLOAD_TAG      = 0xd1;
-
-    /** Device identity value for UICC (destination). */
-    private static final int DEV_ID_UICC        = 0x81;
-
-    /** Device identity value for network (source). */
-    private static final int DEV_ID_NETWORK     = 0x83;
-
-    /** Message containing new SMS-PP message to process. */
-    private static final int EVENT_START_DATA_DOWNLOAD = 1;
-
-    /** Response to SMS-PP download envelope command. */
-    private static final int EVENT_SEND_ENVELOPE_RESPONSE = 2;
-
-    private final CommandsInterface mCI;
-
-    public UsimDataDownloadHandler(CommandsInterface commandsInterface) {
-        mCI = commandsInterface;
-    }
-
-    /**
-     * Start an SMS-PP data download for the specified message. Can be called from a different
-     * thread than this Handler is running on.
-     *
-     * @param smsMessage the message to process
-     * @return Activity.RESULT_OK on success; Intents.RESULT_SMS_GENERIC_ERROR on failure
-     */
-    public int startDataDownload(SmsMessage smsMessage) {
-        if (sendMessage(obtainMessage(EVENT_START_DATA_DOWNLOAD, smsMessage))) {
-            return Activity.RESULT_OK;  // we will send SMS ACK/ERROR based on UICC response
-        } else {
-            Log.e(TAG, "startDataDownload failed to send message to start data download.");
-            return Intents.RESULT_SMS_GENERIC_ERROR;
-        }
-    }
-
-    private void handleDataDownload(SmsMessage smsMessage) {
-        int dcs = smsMessage.getDataCodingScheme();
-        int pid = smsMessage.getProtocolIdentifier();
-        byte[] pdu = smsMessage.getPdu();           // includes SC address
-
-        int scAddressLength = pdu[0] & 0xff;
-        int tpduIndex = scAddressLength + 1;        // start of TPDU
-        int tpduLength = pdu.length - tpduIndex;
-
-        int bodyLength = getEnvelopeBodyLength(scAddressLength, tpduLength);
-
-        // Add 1 byte for SMS-PP download tag and 1-2 bytes for BER-TLV length.
-        // See ETSI TS 102 223 Annex C for encoding of length and tags.
-        int totalLength = bodyLength + 1 + (bodyLength > 127 ? 2 : 1);
-
-        byte[] envelope = new byte[totalLength];
-        int index = 0;
-
-        // SMS-PP download tag and length (assumed to be < 256 bytes).
-        envelope[index++] = (byte) BER_SMS_PP_DOWNLOAD_TAG;
-        if (bodyLength > 127) {
-            envelope[index++] = (byte) 0x81;    // length 128-255 encoded as 0x81 + length
-        }
-        envelope[index++] = (byte) bodyLength;
-
-        // Device identities TLV
-        envelope[index++] = (byte) (0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value());
-        envelope[index++] = (byte) 2;
-        envelope[index++] = (byte) DEV_ID_NETWORK;
-        envelope[index++] = (byte) DEV_ID_UICC;
-
-        // Address TLV (if present). Encoded length is assumed to be < 127 bytes.
-        if (scAddressLength != 0) {
-            envelope[index++] = (byte) ComprehensionTlvTag.ADDRESS.value();
-            envelope[index++] = (byte) scAddressLength;
-            System.arraycopy(pdu, 1, envelope, index, scAddressLength);
-            index += scAddressLength;
-        }
-
-        // SMS TPDU TLV. Length is assumed to be < 256 bytes.
-        envelope[index++] = (byte) (0x80 | ComprehensionTlvTag.SMS_TPDU.value());
-        if (tpduLength > 127) {
-            envelope[index++] = (byte) 0x81;    // length 128-255 encoded as 0x81 + length
-        }
-        envelope[index++] = (byte) tpduLength;
-        System.arraycopy(pdu, tpduIndex, envelope, index, tpduLength);
-        index += tpduLength;
-
-        // Verify that we calculated the payload size correctly.
-        if (index != envelope.length) {
-            Log.e(TAG, "startDataDownload() calculated incorrect envelope length, aborting.");
-            acknowledgeSmsWithError(CommandsInterface.GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR);
-            return;
-        }
-
-        String encodedEnvelope = IccUtils.bytesToHexString(envelope);
-        mCI.sendEnvelopeWithStatus(encodedEnvelope, obtainMessage(
-                EVENT_SEND_ENVELOPE_RESPONSE, new int[]{ dcs, pid }));
-    }
-
-    /**
-     * Return the size in bytes of the envelope to send to the UICC, excluding the
-     * SMS-PP download tag byte and length byte(s). If the size returned is <= 127,
-     * the BER-TLV length will be encoded in 1 byte, otherwise 2 bytes are required.
-     *
-     * @param scAddressLength the length of the SMSC address, or zero if not present
-     * @param tpduLength the length of the TPDU from the SMS-PP message
-     * @return the number of bytes to allocate for the envelope command
-     */
-    private static int getEnvelopeBodyLength(int scAddressLength, int tpduLength) {
-        // Add 4 bytes for device identities TLV + 1 byte for SMS TPDU tag byte
-        int length = tpduLength + 5;
-        // Add 1 byte for TPDU length, or 2 bytes if length > 127
-        length += (tpduLength > 127 ? 2 : 1);
-        // Add length of address tag, if present (+ 2 bytes for tag and length)
-        if (scAddressLength != 0) {
-            length = length + 2 + scAddressLength;
-        }
-        return length;
-    }
-
-    /**
-     * Handle the response to the ENVELOPE command.
-     * @param response UICC response encoded as hexadecimal digits. First two bytes are the
-     *  UICC SW1 and SW2 status bytes.
-     */
-    private void sendSmsAckForEnvelopeResponse(IccIoResult response, int dcs, int pid) {
-        int sw1 = response.sw1;
-        int sw2 = response.sw2;
-
-        boolean success;
-        if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
-            Log.d(TAG, "USIM data download succeeded: " + response.toString());
-            success = true;
-        } else if (sw1 == 0x93 && sw2 == 0x00) {
-            Log.e(TAG, "USIM data download failed: Toolkit busy");
-            acknowledgeSmsWithError(CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_APP_TOOLKIT_BUSY);
-            return;
-        } else if (sw1 == 0x62 || sw1 == 0x63) {
-            Log.e(TAG, "USIM data download failed: " + response.toString());
-            success = false;
-        } else {
-            Log.e(TAG, "Unexpected SW1/SW2 response from UICC: " + response.toString());
-            success = false;
-        }
-
-        byte[] responseBytes = response.payload;
-        if (responseBytes == null || responseBytes.length == 0) {
-            if (success) {
-                mCI.acknowledgeLastIncomingGsmSms(true, 0, null);
-            } else {
-                acknowledgeSmsWithError(
-                        CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR);
-            }
-            return;
-        }
-
-        byte[] smsAckPdu;
-        int index = 0;
-        if (success) {
-            smsAckPdu = new byte[responseBytes.length + 5];
-            smsAckPdu[index++] = 0x00;      // TP-MTI, TP-UDHI
-            smsAckPdu[index++] = 0x07;      // TP-PI: TP-PID, TP-DCS, TP-UDL present
-        } else {
-            smsAckPdu = new byte[responseBytes.length + 6];
-            smsAckPdu[index++] = 0x00;      // TP-MTI, TP-UDHI
-            smsAckPdu[index++] = (byte)
-                    CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR;  // TP-FCS
-            smsAckPdu[index++] = 0x07;      // TP-PI: TP-PID, TP-DCS, TP-UDL present
-        }
-
-        smsAckPdu[index++] = (byte) pid;
-        smsAckPdu[index++] = (byte) dcs;
-
-        if (is7bitDcs(dcs)) {
-            int septetCount = responseBytes.length * 8 / 7;
-            smsAckPdu[index++] = (byte) septetCount;
-        } else {
-            smsAckPdu[index++] = (byte) responseBytes.length;
-        }
-
-        System.arraycopy(responseBytes, 0, smsAckPdu, index, responseBytes.length);
-
-        mCI.acknowledgeIncomingGsmSmsWithPdu(success,
-                IccUtils.bytesToHexString(smsAckPdu), null);
-    }
-
-    private void acknowledgeSmsWithError(int cause) {
-        mCI.acknowledgeLastIncomingGsmSms(false, cause, null);
-    }
-
-    /**
-     * Returns whether the DCS is 7 bit. If so, set TP-UDL to the septet count of TP-UD;
-     * otherwise, set TP-UDL to the octet count of TP-UD.
-     * @param dcs the TP-Data-Coding-Scheme field from the original download SMS
-     * @return true if the DCS specifies 7 bit encoding; false otherwise
-     */
-    private static boolean is7bitDcs(int dcs) {
-        // See 3GPP TS 23.038 section 4
-        return ((dcs & 0x8C) == 0x00) || ((dcs & 0xF4) == 0xF0);
-    }
-
-    /**
-     * Handle UICC envelope response and send SMS acknowledgement.
-     *
-     * @param msg the message to handle
-     */
-    @Override
-    public void handleMessage(Message msg) {
-        switch (msg.what) {
-            case EVENT_START_DATA_DOWNLOAD:
-                handleDataDownload((SmsMessage) msg.obj);
-                break;
-
-            case EVENT_SEND_ENVELOPE_RESPONSE:
-                AsyncResult ar = (AsyncResult) msg.obj;
-
-                if (ar.exception != null) {
-                    Log.e(TAG, "UICC Send Envelope failure, exception: " + ar.exception);
-                    acknowledgeSmsWithError(
-                            CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR);
-                    return;
-                }
-
-                int[] dcsPid = (int[]) ar.userObj;
-                sendSmsAckForEnvelopeResponse((IccIoResult) ar.result, dcsPid[0], dcsPid[1]);
-                break;
-
-            default:
-                Log.e(TAG, "Ignoring unexpected message, what=" + msg.what);
-        }
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java b/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
deleted file mode 100755
index 8f5a420..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
+++ /dev/null
@@ -1,453 +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.
- */
-
-package com.android.internal.telephony.gsm;
-
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-
-import com.android.internal.telephony.AdnRecord;
-import com.android.internal.telephony.AdnRecordCache;
-import com.android.internal.telephony.IccConstants;
-import com.android.internal.telephony.IccFileHandler;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.PhoneBase;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * This class implements reading and parsing USIM records.
- * Refer to Spec 3GPP TS 31.102 for more details.
- *
- * {@hide}
- */
-public class UsimPhoneBookManager extends Handler implements IccConstants {
-    private static final String LOG_TAG = "GSM";
-    private static final boolean DBG = true;
-    private PbrFile mPbrFile;
-    private Boolean mIsPbrPresent;
-    private IccFileHandler mFh;
-    private AdnRecordCache mAdnCache;
-    private Object mLock = new Object();
-    private ArrayList<AdnRecord> mPhoneBookRecords;
-    private boolean mEmailPresentInIap = false;
-    private int mEmailTagNumberInIap = 0;
-    private ArrayList<byte[]> mIapFileRecord;
-    private ArrayList<byte[]> mEmailFileRecord;
-    private Map<Integer, ArrayList<String>> mEmailsForAdnRec;
-    private boolean mRefreshCache = false;
-
-    private static final int EVENT_PBR_LOAD_DONE = 1;
-    private static final int EVENT_USIM_ADN_LOAD_DONE = 2;
-    private static final int EVENT_IAP_LOAD_DONE = 3;
-    private static final int EVENT_EMAIL_LOAD_DONE = 4;
-
-    private static final int USIM_TYPE1_TAG   = 0xA8;
-    private static final int USIM_TYPE2_TAG   = 0xA9;
-    private static final int USIM_TYPE3_TAG   = 0xAA;
-    private static final int USIM_EFADN_TAG   = 0xC0;
-    private static final int USIM_EFIAP_TAG   = 0xC1;
-    private static final int USIM_EFEXT1_TAG  = 0xC2;
-    private static final int USIM_EFSNE_TAG   = 0xC3;
-    private static final int USIM_EFANR_TAG   = 0xC4;
-    private static final int USIM_EFPBC_TAG   = 0xC5;
-    private static final int USIM_EFGRP_TAG   = 0xC6;
-    private static final int USIM_EFAAS_TAG   = 0xC7;
-    private static final int USIM_EFGSD_TAG   = 0xC8;
-    private static final int USIM_EFUID_TAG   = 0xC9;
-    private static final int USIM_EFEMAIL_TAG = 0xCA;
-    private static final int USIM_EFCCP1_TAG  = 0xCB;
-
-    public UsimPhoneBookManager(IccFileHandler fh, AdnRecordCache cache) {
-        mFh = fh;
-        mPhoneBookRecords = new ArrayList<AdnRecord>();
-        mPbrFile = null;
-        // We assume its present, after the first read this is updated.
-        // So we don't have to read from UICC if its not present on subsequent reads.
-        mIsPbrPresent = true;
-        mAdnCache = cache;
-    }
-
-    public void reset() {
-        mPhoneBookRecords.clear();
-        mIapFileRecord = null;
-        mEmailFileRecord = null;
-        mPbrFile = null;
-        mIsPbrPresent = true;
-        mRefreshCache = false;
-    }
-
-    public ArrayList<AdnRecord> loadEfFilesFromUsim() {
-        synchronized (mLock) {
-            if (!mPhoneBookRecords.isEmpty()) {
-                if (mRefreshCache) {
-                    mRefreshCache = false;
-                    refreshCache();
-                }
-                return mPhoneBookRecords;
-            }
-
-            if (!mIsPbrPresent) return null;
-
-            // Check if the PBR file is present in the cache, if not read it
-            // from the USIM.
-            if (mPbrFile == null) {
-                readPbrFileAndWait();
-            }
-
-            if (mPbrFile == null) return null;
-
-            int numRecs = mPbrFile.mFileIds.size();
-            for (int i = 0; i < numRecs; i++) {
-                readAdnFileAndWait(i);
-                readEmailFileAndWait(i);
-            }
-            // All EF files are loaded, post the response.
-        }
-        return mPhoneBookRecords;
-    }
-
-    private void refreshCache() {
-        if (mPbrFile == null) return;
-        mPhoneBookRecords.clear();
-
-        int numRecs = mPbrFile.mFileIds.size();
-        for (int i = 0; i < numRecs; i++) {
-            readAdnFileAndWait(i);
-        }
-    }
-
-    public void invalidateCache() {
-        mRefreshCache = true;
-    }
-
-    private void readPbrFileAndWait() {
-        mFh.loadEFLinearFixedAll(EF_PBR, obtainMessage(EVENT_PBR_LOAD_DONE));
-        try {
-            mLock.wait();
-        } catch (InterruptedException e) {
-            Log.e(LOG_TAG, "Interrupted Exception in readAdnFileAndWait");
-        }
-    }
-
-    private void readEmailFileAndWait(int recNum) {
-        Map <Integer,Integer> fileIds;
-        fileIds = mPbrFile.mFileIds.get(recNum);
-        if (fileIds == null) return;
-
-        if (fileIds.containsKey(USIM_EFEMAIL_TAG)) {
-            int efid = fileIds.get(USIM_EFEMAIL_TAG);
-            // Check if the EFEmail is a Type 1 file or a type 2 file.
-            // If mEmailPresentInIap is true, its a type 2 file.
-            // So we read the IAP file and then read the email records.
-            // instead of reading directly.
-            if (mEmailPresentInIap) {
-                readIapFileAndWait(fileIds.get(USIM_EFIAP_TAG));
-                if (mIapFileRecord == null) {
-                    Log.e(LOG_TAG, "Error: IAP file is empty");
-                    return;
-                }
-            }
-            // Read the EFEmail file.
-            mFh.loadEFLinearFixedAll(fileIds.get(USIM_EFEMAIL_TAG),
-                    obtainMessage(EVENT_EMAIL_LOAD_DONE));
-            try {
-                mLock.wait();
-            } catch (InterruptedException e) {
-                Log.e(LOG_TAG, "Interrupted Exception in readEmailFileAndWait");
-            }
-
-            if (mEmailFileRecord == null) {
-                Log.e(LOG_TAG, "Error: Email file is empty");
-                return;
-            }
-            updatePhoneAdnRecord();
-        }
-
-    }
-
-    private void readIapFileAndWait(int efid) {
-        mFh.loadEFLinearFixedAll(efid, obtainMessage(EVENT_IAP_LOAD_DONE));
-        try {
-            mLock.wait();
-        } catch (InterruptedException e) {
-            Log.e(LOG_TAG, "Interrupted Exception in readIapFileAndWait");
-        }
-    }
-
-    private void updatePhoneAdnRecord() {
-        if (mEmailFileRecord == null) return;
-        int numAdnRecs = mPhoneBookRecords.size();
-        if (mIapFileRecord != null) {
-            // The number of records in the IAP file is same as the number of records in ADN file.
-            // The order of the pointers in an EFIAP shall be the same as the order of file IDs
-            // that appear in the TLV object indicated by Tag 'A9' in the reference file record.
-            // i.e value of mEmailTagNumberInIap
-
-            for (int i = 0; i < numAdnRecs; i++) {
-                byte[] record = null;
-                try {
-                    record = mIapFileRecord.get(i);
-                } catch (IndexOutOfBoundsException e) {
-                    Log.e(LOG_TAG, "Error: Improper ICC card: No IAP record for ADN, continuing");
-                    break;
-                }
-                int recNum = record[mEmailTagNumberInIap];
-
-                if (recNum != -1) {
-                    String[] emails = new String[1];
-                    // SIM record numbers are 1 based
-                    emails[0] = readEmailRecord(recNum - 1);
-                    AdnRecord rec = mPhoneBookRecords.get(i);
-                    if (rec != null) {
-                        rec.setEmails(emails);
-                    } else {
-                        // might be a record with only email
-                        rec = new AdnRecord("", "", emails);
-                    }
-                    mPhoneBookRecords.set(i, rec);
-                }
-            }
-        }
-
-        // ICC cards can be made such that they have an IAP file but all
-        // records are empty. So we read both type 1 and type 2 file
-        // email records, just to be sure.
-
-        int len = mPhoneBookRecords.size();
-        // Type 1 file, the number of records is the same as the number of
-        // records in the ADN file.
-        if (mEmailsForAdnRec == null) {
-            parseType1EmailFile(len);
-        }
-        for (int i = 0; i < numAdnRecs; i++) {
-            ArrayList<String> emailList = null;
-            try {
-                emailList = mEmailsForAdnRec.get(i);
-            } catch (IndexOutOfBoundsException e) {
-                break;
-            }
-            if (emailList == null) continue;
-
-            AdnRecord rec = mPhoneBookRecords.get(i);
-
-            String[] emails = new String[emailList.size()];
-            System.arraycopy(emailList.toArray(), 0, emails, 0, emailList.size());
-            rec.setEmails(emails);
-            mPhoneBookRecords.set(i, rec);
-        }
-    }
-
-    void parseType1EmailFile(int numRecs) {
-        mEmailsForAdnRec = new HashMap<Integer, ArrayList<String>>();
-        byte[] emailRec = null;
-        for (int i = 0; i < numRecs; i++) {
-            try {
-                emailRec = mEmailFileRecord.get(i);
-            } catch (IndexOutOfBoundsException e) {
-                Log.e(LOG_TAG, "Error: Improper ICC card: No email record for ADN, continuing");
-                break;
-            }
-            int adnRecNum = emailRec[emailRec.length - 1];
-
-            if (adnRecNum == -1) {
-                continue;
-            }
-
-            String email = readEmailRecord(i);
-
-            if (email == null || email.equals("")) {
-                continue;
-            }
-
-            // SIM record numbers are 1 based.
-            ArrayList<String> val = mEmailsForAdnRec.get(adnRecNum - 1);
-            if (val == null) {
-                val = new ArrayList<String>();
-            }
-            val.add(email);
-            // SIM record numbers are 1 based.
-            mEmailsForAdnRec.put(adnRecNum - 1, val);
-        }
-    }
-
-    private String readEmailRecord(int recNum) {
-        byte[] emailRec = null;
-        try {
-            emailRec = mEmailFileRecord.get(recNum);
-        } catch (IndexOutOfBoundsException e) {
-            return null;
-        }
-
-        // The length of the record is X+2 byte, where X bytes is the email address
-        String email = IccUtils.adnStringFieldToString(emailRec, 0, emailRec.length - 2);
-        return email;
-    }
-
-    private void readAdnFileAndWait(int recNum) {
-        Map <Integer,Integer> fileIds;
-        fileIds = mPbrFile.mFileIds.get(recNum);
-        if (fileIds == null || fileIds.isEmpty()) return;
-
-
-        int extEf = 0;
-        // Only call fileIds.get while EFEXT1_TAG is available
-        if (fileIds.containsKey(USIM_EFEXT1_TAG)) {
-            extEf = fileIds.get(USIM_EFEXT1_TAG);
-        }
-
-        mAdnCache.requestLoadAllAdnLike(fileIds.get(USIM_EFADN_TAG),
-            extEf, obtainMessage(EVENT_USIM_ADN_LOAD_DONE));
-        try {
-            mLock.wait();
-        } catch (InterruptedException e) {
-            Log.e(LOG_TAG, "Interrupted Exception in readAdnFileAndWait");
-        }
-    }
-
-    private void createPbrFile(ArrayList<byte[]> records) {
-        if (records == null) {
-            mPbrFile = null;
-            mIsPbrPresent = false;
-            return;
-        }
-        mPbrFile = new PbrFile(records);
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-        AsyncResult ar;
-
-        switch(msg.what) {
-        case EVENT_PBR_LOAD_DONE:
-            ar = (AsyncResult) msg.obj;
-            if (ar.exception == null) {
-                createPbrFile((ArrayList<byte[]>)ar.result);
-            }
-            synchronized (mLock) {
-                mLock.notify();
-            }
-            break;
-        case EVENT_USIM_ADN_LOAD_DONE:
-            log("Loading USIM ADN records done");
-            ar = (AsyncResult) msg.obj;
-            if (ar.exception == null) {
-                mPhoneBookRecords.addAll((ArrayList<AdnRecord>)ar.result);
-            }
-            synchronized (mLock) {
-                mLock.notify();
-            }
-            break;
-        case EVENT_IAP_LOAD_DONE:
-            log("Loading USIM IAP records done");
-            ar = (AsyncResult) msg.obj;
-            if (ar.exception == null) {
-                mIapFileRecord = ((ArrayList<byte[]>)ar.result);
-            }
-            synchronized (mLock) {
-                mLock.notify();
-            }
-            break;
-        case EVENT_EMAIL_LOAD_DONE:
-            log("Loading USIM Email records done");
-            ar = (AsyncResult) msg.obj;
-            if (ar.exception == null) {
-                mEmailFileRecord = ((ArrayList<byte[]>)ar.result);
-            }
-
-            synchronized (mLock) {
-                mLock.notify();
-            }
-            break;
-        }
-    }
-
-    private class PbrFile {
-        // RecNum <EF Tag, efid>
-        HashMap<Integer,Map<Integer,Integer>> mFileIds;
-
-        PbrFile(ArrayList<byte[]> records) {
-            mFileIds = new HashMap<Integer, Map<Integer, Integer>>();
-            SimTlv recTlv;
-            int recNum = 0;
-            for (byte[] record: records) {
-                recTlv = new SimTlv(record, 0, record.length);
-                parseTag(recTlv, recNum);
-                recNum ++;
-            }
-        }
-
-        void parseTag(SimTlv tlv, int recNum) {
-            SimTlv tlvEf;
-            int tag;
-            byte[] data;
-            Map<Integer, Integer> val = new HashMap<Integer, Integer>();
-            do {
-                tag = tlv.getTag();
-                switch(tag) {
-                case USIM_TYPE1_TAG: // A8
-                case USIM_TYPE3_TAG: // AA
-                case USIM_TYPE2_TAG: // A9
-                    data = tlv.getData();
-                    tlvEf = new SimTlv(data, 0, data.length);
-                    parseEf(tlvEf, val, tag);
-                    break;
-                }
-            } while (tlv.nextObject());
-            mFileIds.put(recNum, val);
-        }
-
-        void parseEf(SimTlv tlv, Map<Integer, Integer> val, int parentTag) {
-            int tag;
-            byte[] data;
-            int tagNumberWithinParentTag = 0;
-            do {
-                tag = tlv.getTag();
-                if (parentTag == USIM_TYPE2_TAG && tag == USIM_EFEMAIL_TAG) {
-                    mEmailPresentInIap = true;
-                    mEmailTagNumberInIap = tagNumberWithinParentTag;
-                }
-                switch(tag) {
-                    case USIM_EFEMAIL_TAG:
-                    case USIM_EFADN_TAG:
-                    case USIM_EFEXT1_TAG:
-                    case USIM_EFANR_TAG:
-                    case USIM_EFPBC_TAG:
-                    case USIM_EFGRP_TAG:
-                    case USIM_EFAAS_TAG:
-                    case USIM_EFGSD_TAG:
-                    case USIM_EFUID_TAG:
-                    case USIM_EFCCP1_TAG:
-                    case USIM_EFIAP_TAG:
-                    case USIM_EFSNE_TAG:
-                        data = tlv.getData();
-                        int efid = ((data[0] & 0xFF) << 8) | (data[1] & 0xFF);
-                        val.put(tag, efid);
-                        break;
-                }
-                tagNumberWithinParentTag ++;
-            } while(tlv.nextObject());
-        }
-    }
-
-    private void log(String msg) {
-        if(DBG) Log.d(LOG_TAG, msg);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/UsimServiceTable.java b/telephony/java/com/android/internal/telephony/gsm/UsimServiceTable.java
deleted file mode 100644
index 3fe200b..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/UsimServiceTable.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2011 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.internal.telephony.gsm;
-
-import com.android.internal.telephony.IccServiceTable;
-
-/**
- * Wrapper class for the USIM Service Table EF.
- * See 3GPP TS 31.102 Release 10 section 4.2.8
- */
-public final class UsimServiceTable extends IccServiceTable {
-    public enum UsimService {
-        PHONEBOOK,
-        FDN,                                // Fixed Dialing Numbers
-        FDN_EXTENSION,                      // FDN extension data in EF_EXT2
-        SDN,                                // Service Dialing Numbers
-        SDN_EXTENSION,                      // SDN extension data in EF_EXT3
-        BDN,                                // Barred Dialing Numbers
-        BDN_EXTENSION,                      // BDN extension data in EF_EXT4
-        OUTGOING_CALL_INFO,
-        INCOMING_CALL_INFO,
-        SM_STORAGE,
-        SM_STATUS_REPORTS,
-        SM_SERVICE_PARAMS,
-        ADVICE_OF_CHARGE,
-        CAP_CONFIG_PARAMS_2,
-        CB_MESSAGE_ID,
-        CB_MESSAGE_ID_RANGES,
-        GROUP_ID_LEVEL_1,
-        GROUP_ID_LEVEL_2,
-        SPN,                                // Service Provider Name
-        USER_PLMN_SELECT,
-        MSISDN,
-        IMAGE,
-        LOCALISED_SERVICE_AREAS,
-        EMLPP,                              // Enhanced Multi-Level Precedence and Preemption
-        EMLPP_AUTO_ANSWER,
-        RFU,
-        GSM_ACCESS,
-        DATA_DL_VIA_SMS_PP,
-        DATA_DL_VIA_SMS_CB,
-        CALL_CONTROL_BY_USIM,
-        MO_SMS_CONTROL_BY_USIM,
-        RUN_AT_COMMAND,
-        IGNORED_1,
-        ENABLED_SERVICES_TABLE,
-        APN_CONTROL_LIST,
-        DEPERSONALISATION_CONTROL_KEYS,
-        COOPERATIVE_NETWORK_LIST,
-        GSM_SECURITY_CONTEXT,
-        CPBCCH_INFO,
-        INVESTIGATION_SCAN,
-        MEXE,
-        OPERATOR_PLMN_SELECT,
-        HPLMN_SELECT,
-        EXTENSION_5,                        // Extension data for ICI, OCI, MSISDN in EF_EXT5
-        PLMN_NETWORK_NAME,
-        OPERATOR_PLMN_LIST,
-        MBDN,                               // Mailbox Dialing Numbers
-        MWI_STATUS,                         // Message Waiting Indication status
-        CFI_STATUS,                         // Call Forwarding Indication status
-        IGNORED_2,
-        SERVICE_PROVIDER_DISPLAY_INFO,
-        MMS_NOTIFICATION,
-        MMS_NOTIFICATION_EXTENSION,         // MMS Notification extension data in EF_EXT8
-        GPRS_CALL_CONTROL_BY_USIM,
-        MMS_CONNECTIVITY_PARAMS,
-        NETWORK_INDICATION_OF_ALERTING,
-        VGCS_GROUP_ID_LIST,
-        VBS_GROUP_ID_LIST,
-        PSEUDONYM,
-        IWLAN_USER_PLMN_SELECT,
-        IWLAN_OPERATOR_PLMN_SELECT,
-        USER_WSID_LIST,
-        OPERATOR_WSID_LIST,
-        VGCS_SECURITY,
-        VBS_SECURITY,
-        WLAN_REAUTH_IDENTITY,
-        MM_STORAGE,
-        GBA,                                // Generic Bootstrapping Architecture
-        MBMS_SECURITY,
-        DATA_DL_VIA_USSD,
-        EQUIVALENT_HPLMN,
-        TERMINAL_PROFILE_AFTER_UICC_ACTIVATION,
-        EQUIVALENT_HPLMN_PRESENTATION,
-        LAST_RPLMN_SELECTION_INDICATION,
-        OMA_BCAST_PROFILE,
-        GBA_LOCAL_KEY_ESTABLISHMENT,
-        TERMINAL_APPLICATIONS,
-        SPN_ICON,
-        PLMN_NETWORK_NAME_ICON,
-        USIM_IP_CONNECTION_PARAMS,
-        IWLAN_HOME_ID_LIST,
-        IWLAN_EQUIVALENT_HPLMN_PRESENTATION,
-        IWLAN_HPLMN_PRIORITY_INDICATION,
-        IWLAN_LAST_REGISTERED_PLMN,
-        EPS_MOBILITY_MANAGEMENT_INFO,
-        ALLOWED_CSG_LISTS_AND_INDICATIONS,
-        CALL_CONTROL_ON_EPS_PDN_CONNECTION_BY_USIM,
-        HPLMN_DIRECT_ACCESS,
-        ECALL_DATA,
-        OPERATOR_CSG_LISTS_AND_INDICATIONS,
-        SM_OVER_IP,
-        CSG_DISPLAY_CONTROL,
-        IMS_COMMUNICATION_CONTROL_BY_USIM,
-        EXTENDED_TERMINAL_APPLICATIONS,
-        UICC_ACCESS_TO_IMS,
-        NAS_CONFIG_BY_USIM
-    }
-
-    public UsimServiceTable(byte[] table) {
-        super(table);
-    }
-
-    public boolean isAvailable(UsimService service) {
-        return super.isAvailable(service.ordinal());
-    }
-
-    @Override
-    protected String getTag() {
-        return "UsimServiceTable";
-    }
-
-    @Override
-    protected Object[] getValues() {
-        return UsimService.values();
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/VoiceMailConstants.java b/telephony/java/com/android/internal/telephony/gsm/VoiceMailConstants.java
deleted file mode 100644
index 0e49e35..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/VoiceMailConstants.java
+++ /dev/null
@@ -1,115 +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.internal.telephony.gsm;
-
-import android.os.Environment;
-import android.util.Xml;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.io.FileReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import com.android.internal.util.XmlUtils;
-
-/**
- * {@hide}
- */
-class VoiceMailConstants {
-    private HashMap<String, String[]> CarrierVmMap;
-
-
-    static final String LOG_TAG = "GSM";
-    static final String PARTNER_VOICEMAIL_PATH ="etc/voicemail-conf.xml";
-
-    static final int NAME = 0;
-    static final int NUMBER = 1;
-    static final int TAG = 2;
-    static final int SIZE = 3;
-
-    VoiceMailConstants () {
-        CarrierVmMap = new HashMap<String, String[]>();
-        loadVoiceMail();
-    }
-
-    boolean containsCarrier(String carrier) {
-        return CarrierVmMap.containsKey(carrier);
-    }
-
-    String getCarrierName(String carrier) {
-        String[] data = CarrierVmMap.get(carrier);
-        return data[NAME];
-    }
-
-    String getVoiceMailNumber(String carrier) {
-        String[] data = CarrierVmMap.get(carrier);
-        return data[NUMBER];
-    }
-
-    String getVoiceMailTag(String carrier) {
-        String[] data = CarrierVmMap.get(carrier);
-        return data[TAG];
-    }
-
-    private void loadVoiceMail() {
-        FileReader vmReader;
-
-        final File vmFile = new File(Environment.getRootDirectory(),
-                PARTNER_VOICEMAIL_PATH);
-
-        try {
-            vmReader = new FileReader(vmFile);
-        } catch (FileNotFoundException e) {
-            Log.w(LOG_TAG, "Can't open " +
-                    Environment.getRootDirectory() + "/" + PARTNER_VOICEMAIL_PATH);
-            return;
-        }
-
-        try {
-            XmlPullParser parser = Xml.newPullParser();
-            parser.setInput(vmReader);
-
-            XmlUtils.beginDocument(parser, "voicemail");
-
-            while (true) {
-                XmlUtils.nextElement(parser);
-
-                String name = parser.getName();
-                if (!"voicemail".equals(name)) {
-                    break;
-                }
-
-                String[] data = new String[SIZE];
-                String numeric = parser.getAttributeValue(null, "numeric");
-                data[NAME]     = parser.getAttributeValue(null, "carrier");
-                data[NUMBER]   = parser.getAttributeValue(null, "vmnumber");
-                data[TAG]      = parser.getAttributeValue(null, "vmtag");
-
-                CarrierVmMap.put(numeric, data);
-            }
-        } catch (XmlPullParserException e) {
-            Log.w(LOG_TAG, "Exception in Voicemail parser " + e);
-        } catch (IOException e) {
-            Log.w(LOG_TAG, "Exception in Voicemail parser " + e);
-        }
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/package.html b/telephony/java/com/android/internal/telephony/gsm/package.html
deleted file mode 100755
index fed8399..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/package.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<HTML>
-<BODY>
-Provides classes to control or read data from GSM phones.
-@hide
-</BODY>
-</HTML>
diff --git a/telephony/java/com/android/internal/telephony/ims/IsimRecords.java b/telephony/java/com/android/internal/telephony/ims/IsimRecords.java
deleted file mode 100644
index b8b98b9..0000000
--- a/telephony/java/com/android/internal/telephony/ims/IsimRecords.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2011 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.internal.telephony.ims;
-
-/**
- * {@hide}
- */
-public interface IsimRecords {
-
-    /**
-     * Return the IMS private user identity (IMPI).
-     * Returns null if the IMPI hasn't been loaded or isn't present on the ISIM.
-     * @return the IMS private user identity string, or null if not available
-     */
-    String getIsimImpi();
-
-    /**
-     * Return the IMS home network domain name.
-     * Returns null if the IMS domain hasn't been loaded or isn't present on the ISIM.
-     * @return the IMS home network domain name, or null if not available
-     */
-    String getIsimDomain();
-
-    /**
-     * Return an array of IMS public user identities (IMPU).
-     * Returns null if the IMPU hasn't been loaded or isn't present on the ISIM.
-     * @return an array of IMS public user identity strings, or null if not available
-     */
-    String[] getIsimImpu();
-}
diff --git a/telephony/java/com/android/internal/telephony/ims/IsimUiccRecords.java b/telephony/java/com/android/internal/telephony/ims/IsimUiccRecords.java
deleted file mode 100644
index ee1a42d..0000000
--- a/telephony/java/com/android/internal/telephony/ims/IsimUiccRecords.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2011 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.internal.telephony.ims;
-
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.util.Log;
-
-import com.android.internal.telephony.IccFileHandler;
-import com.android.internal.telephony.IccRecords;
-import com.android.internal.telephony.gsm.SimTlv;
-
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-
-import static com.android.internal.telephony.IccConstants.EF_DOMAIN;
-import static com.android.internal.telephony.IccConstants.EF_IMPI;
-import static com.android.internal.telephony.IccConstants.EF_IMPU;
-
-/**
- * {@hide}
- */
-public final class IsimUiccRecords implements IsimRecords {
-    protected static final String LOG_TAG = "GSM";
-
-    private static final boolean DBG = true;
-    private static final boolean DUMP_RECORDS = false;   // Note: PII is logged when this is true
-
-    // ISIM EF records (see 3GPP TS 31.103)
-    private String mIsimImpi;               // IMS private user identity
-    private String mIsimDomain;             // IMS home network domain name
-    private String[] mIsimImpu;             // IMS public user identity(s)
-
-    private static final int TAG_ISIM_VALUE = 0x80;     // From 3GPP TS 31.103
-
-    private class EfIsimImpiLoaded implements IccRecords.IccRecordLoaded {
-        public String getEfName() {
-            return "EF_ISIM_IMPI";
-        }
-        public void onRecordLoaded(AsyncResult ar) {
-            byte[] data = (byte[]) ar.result;
-            mIsimImpi = isimTlvToString(data);
-            if (DUMP_RECORDS) log("EF_IMPI=" + mIsimImpi);
-        }
-    }
-
-    private class EfIsimImpuLoaded implements IccRecords.IccRecordLoaded {
-        public String getEfName() {
-            return "EF_ISIM_IMPU";
-        }
-        public void onRecordLoaded(AsyncResult ar) {
-            ArrayList<byte[]> impuList = (ArrayList<byte[]>) ar.result;
-            if (DBG) log("EF_IMPU record count: " + impuList.size());
-            mIsimImpu = new String[impuList.size()];
-            int i = 0;
-            for (byte[] identity : impuList) {
-                String impu = isimTlvToString(identity);
-                if (DUMP_RECORDS) log("EF_IMPU[" + i + "]=" + impu);
-                mIsimImpu[i++] = impu;
-            }
-        }
-    }
-
-    private class EfIsimDomainLoaded implements IccRecords.IccRecordLoaded {
-        public String getEfName() {
-            return "EF_ISIM_DOMAIN";
-        }
-        public void onRecordLoaded(AsyncResult ar) {
-            byte[] data = (byte[]) ar.result;
-            mIsimDomain = isimTlvToString(data);
-            if (DUMP_RECORDS) log("EF_DOMAIN=" + mIsimDomain);
-        }
-    }
-
-    /**
-     * Request the ISIM records to load.
-     * @param iccFh the IccFileHandler to load the records from
-     * @param h the Handler to which the response message will be sent
-     * @return the number of EF record requests that were added
-     */
-    public int fetchIsimRecords(IccFileHandler iccFh, Handler h) {
-        iccFh.loadEFTransparent(EF_IMPI, h.obtainMessage(
-                IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimImpiLoaded()));
-        iccFh.loadEFLinearFixedAll(EF_IMPU, h.obtainMessage(
-                IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimImpuLoaded()));
-        iccFh.loadEFTransparent(EF_DOMAIN, h.obtainMessage(
-                IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimDomainLoaded()));
-        return 3;   // number of EF record load requests
-    }
-
-    /**
-     * ISIM records for IMS are stored inside a Tag-Length-Value record as a UTF-8 string
-     * with tag value 0x80.
-     * @param record the byte array containing the IMS data string
-     * @return the decoded String value, or null if the record can't be decoded
-     */
-    private static String isimTlvToString(byte[] record) {
-        SimTlv tlv = new SimTlv(record, 0, record.length);
-        do {
-            if (tlv.getTag() == TAG_ISIM_VALUE) {
-                return new String(tlv.getData(), Charset.forName("UTF-8"));
-            }
-        } while (tlv.nextObject());
-
-        Log.e(LOG_TAG, "[ISIM] can't find TLV tag in ISIM record, returning null");
-        return null;
-    }
-
-    void log(String s) {
-        if (DBG) Log.d(LOG_TAG, "[ISIM] " + s);
-    }
-
-    void loge(String s) {
-        if (DBG) Log.e(LOG_TAG, "[ISIM] " + s);
-    }
-
-    /**
-     * Return the IMS private user identity (IMPI).
-     * Returns null if the IMPI hasn't been loaded or isn't present on the ISIM.
-     * @return the IMS private user identity string, or null if not available
-     */
-    public String getIsimImpi() {
-        return mIsimImpi;
-    }
-
-    /**
-     * Return the IMS home network domain name.
-     * Returns null if the IMS domain hasn't been loaded or isn't present on the ISIM.
-     * @return the IMS home network domain name, or null if not available
-     */
-    public String getIsimDomain() {
-        return mIsimDomain;
-    }
-
-    /**
-     * Return an array of IMS public user identities (IMPU).
-     * Returns null if the IMPU hasn't been loaded or isn't present on the ISIM.
-     * @return an array of IMS public user identity strings, or null if not available
-     */
-    public String[] getIsimImpu() {
-        return (mIsimImpu != null) ? mIsimImpu.clone() : null;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/sip/SipCallBase.java b/telephony/java/com/android/internal/telephony/sip/SipCallBase.java
deleted file mode 100644
index 9050a43..0000000
--- a/telephony/java/com/android/internal/telephony/sip/SipCallBase.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2010 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.internal.telephony.sip;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallStateException;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.Phone;
-
-import android.net.sip.SipManager;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-abstract class SipCallBase extends Call {
-    protected List<Connection> connections = new ArrayList<Connection>();
-
-    protected abstract void setState(State newState);
-
-    public List<Connection> getConnections() {
-        // FIXME should return Collections.unmodifiableList();
-        return connections;
-    }
-
-    public boolean isMultiparty() {
-        return connections.size() > 1;
-    }
-
-    public String toString() {
-        return state.toString() + ":" + super.toString();
-    }
-
-    void clearDisconnected() {
-        for (Iterator<Connection> it = connections.iterator(); it.hasNext(); ) {
-            Connection c = it.next();
-            if (c.getState() == State.DISCONNECTED) it.remove();
-        }
-
-        if (connections.isEmpty()) setState(State.IDLE);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java b/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java
deleted file mode 100644
index 99f4e0f..0000000
--- a/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Copyright (C) 2010 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.internal.telephony.sip;
-
-import android.content.Context;
-import android.os.Handler;
-import android.os.Message;
-
-import com.android.internal.telephony.BaseCommands;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.UUSInfo;
-import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
-
-/**
- * SIP doesn't need CommandsInterface. The class does nothing but made to work
- * with PhoneBase's constructor.
- */
-class SipCommandInterface extends BaseCommands implements CommandsInterface {
-    SipCommandInterface(Context context) {
-        super(context);
-    }
-
-    @Override public void setOnNITZTime(Handler h, int what, Object obj) {
-    }
-
-    public void getIccCardStatus(Message result) {
-    }
-
-    public void supplyIccPin(String pin, Message result) {
-    }
-
-    public void supplyIccPuk(String puk, String newPin, Message result) {
-    }
-
-    public void supplyIccPin2(String pin, Message result) {
-    }
-
-    public void supplyIccPuk2(String puk, String newPin2, Message result) {
-    }
-
-    public void changeIccPin(String oldPin, String newPin, Message result) {
-    }
-
-    public void changeIccPin2(String oldPin2, String newPin2, Message result) {
-    }
-
-    public void changeBarringPassword(String facility, String oldPwd,
-            String newPwd, Message result) {
-    }
-
-    public void supplyNetworkDepersonalization(String netpin, Message result) {
-    }
-
-    public void getCurrentCalls(Message result) {
-    }
-
-    @Deprecated public void getPDPContextList(Message result) {
-    }
-
-    public void getDataCallList(Message result) {
-    }
-
-    public void dial(String address, int clirMode, Message result) {
-    }
-
-    public void dial(String address, int clirMode, UUSInfo uusInfo,
-            Message result) {
-    }
-
-    public void getIMSI(Message result) {
-    }
-
-    public void getIMSIForApp(String aid, Message result) {
-    }
-
-    public void getIMEI(Message result) {
-    }
-
-    public void getIMEISV(Message result) {
-    }
-
-
-    public void hangupConnection (int gsmIndex, Message result) {
-    }
-
-    public void hangupWaitingOrBackground (Message result) {
-    }
-
-    public void hangupForegroundResumeBackground (Message result) {
-    }
-
-    public void switchWaitingOrHoldingAndActive (Message result) {
-    }
-
-    public void conference (Message result) {
-    }
-
-
-    public void setPreferredVoicePrivacy(boolean enable, Message result) {
-    }
-
-    public void getPreferredVoicePrivacy(Message result) {
-    }
-
-    public void separateConnection (int gsmIndex, Message result) {
-    }
-
-    public void acceptCall (Message result) {
-    }
-
-    public void rejectCall (Message result) {
-    }
-
-    public void explicitCallTransfer (Message result) {
-    }
-
-    public void getLastCallFailCause (Message result) {
-    }
-
-    /** @deprecated */
-    public void getLastPdpFailCause (Message result) {
-    }
-
-    public void getLastDataCallFailCause (Message result) {
-    }
-
-    public void setMute (boolean enableMute, Message response) {
-    }
-
-    public void getMute (Message response) {
-    }
-
-    public void getSignalStrength (Message result) {
-    }
-
-    public void getVoiceRegistrationState (Message result) {
-    }
-
-    public void getDataRegistrationState (Message result) {
-    }
-
-    public void getOperator(Message result) {
-    }
-
-    public void sendDtmf(char c, Message result) {
-    }
-
-    public void startDtmf(char c, Message result) {
-    }
-
-    public void stopDtmf(Message result) {
-    }
-
-    public void sendBurstDtmf(String dtmfString, int on, int off,
-            Message result) {
-    }
-
-    public void sendSMS (String smscPDU, String pdu, Message result) {
-    }
-
-    public void sendCdmaSms(byte[] pdu, Message result) {
-    }
-
-    public void deleteSmsOnSim(int index, Message response) {
-    }
-
-    public void deleteSmsOnRuim(int index, Message response) {
-    }
-
-    public void writeSmsToSim(int status, String smsc, String pdu, Message response) {
-    }
-
-    public void writeSmsToRuim(int status, String pdu, Message response) {
-    }
-
-    public void setupDataCall(String radioTechnology, String profile,
-            String apn, String user, String password, String authType,
-            String protocol, Message result) {
-    }
-
-    public void deactivateDataCall(int cid, int reason, Message result) {
-    }
-
-    public void setRadioPower(boolean on, Message result) {
-    }
-
-    public void setSuppServiceNotifications(boolean enable, Message result) {
-    }
-
-    public void acknowledgeLastIncomingGsmSms(boolean success, int cause,
-            Message result) {
-    }
-
-    public void acknowledgeLastIncomingCdmaSms(boolean success, int cause,
-            Message result) {
-    }
-
-    public void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu,
-            Message result) {
-    }
-
-    public void iccIO (int command, int fileid, String path, int p1, int p2,
-            int p3, String data, String pin2, Message result) {
-    }
-    public void iccIOForApp (int command, int fileid, String path, int p1, int p2,
-            int p3, String data, String pin2, String aid, Message result) {
-    }
-
-    public void getCLIR(Message result) {
-    }
-
-    public void setCLIR(int clirMode, Message result) {
-    }
-
-    public void queryCallWaiting(int serviceClass, Message response) {
-    }
-
-    public void setCallWaiting(boolean enable, int serviceClass,
-            Message response) {
-    }
-
-    public void setNetworkSelectionModeAutomatic(Message response) {
-    }
-
-    public void setNetworkSelectionModeManual(
-            String operatorNumeric, Message response) {
-    }
-
-    public void getNetworkSelectionMode(Message response) {
-    }
-
-    public void getAvailableNetworks(Message response) {
-    }
-
-    public void setCallForward(int action, int cfReason, int serviceClass,
-                String number, int timeSeconds, Message response) {
-    }
-
-    public void queryCallForwardStatus(int cfReason, int serviceClass,
-            String number, Message response) {
-    }
-
-    public void queryCLIP(Message response) {
-    }
-
-    public void getBasebandVersion (Message response) {
-    }
-
-    @Override
-    public void queryFacilityLock(String facility, String password,
-            int serviceClass, Message response) {
-    }
-
-    @Override
-    public void queryFacilityLockForApp(String facility, String password,
-            int serviceClass, String appId, Message response) {
-    }
-
-    @Override
-    public void setFacilityLock(String facility, boolean lockState,
-            String password, int serviceClass, Message response) {
-    }
-
-    @Override
-    public void setFacilityLockForApp(String facility, boolean lockState,
-            String password, int serviceClass, String appId, Message response) {
-    }
-
-    public void sendUSSD (String ussdString, Message response) {
-    }
-
-    public void cancelPendingUssd (Message response) {
-    }
-
-    public void resetRadio(Message result) {
-    }
-
-    public void invokeOemRilRequestRaw(byte[] data, Message response) {
-    }
-
-    public void invokeOemRilRequestStrings(String[] strings, Message response) {
-    }
-
-    public void setBandMode (int bandMode, Message response) {
-    }
-
-    public void queryAvailableBandMode (Message response) {
-    }
-
-    public void sendTerminalResponse(String contents, Message response) {
-    }
-
-    public void sendEnvelope(String contents, Message response) {
-    }
-
-    public void sendEnvelopeWithStatus(String contents, Message response) {
-    }
-
-    public void handleCallSetupRequestFromSim(
-            boolean accept, Message response) {
-    }
-
-    public void setPreferredNetworkType(int networkType , Message response) {
-    }
-
-    public void getPreferredNetworkType(Message response) {
-    }
-
-    public void getNeighboringCids(Message response) {
-    }
-
-    public void setLocationUpdates(boolean enable, Message response) {
-    }
-
-    public void getSmscAddress(Message result) {
-    }
-
-    public void setSmscAddress(String address, Message result) {
-    }
-
-    public void reportSmsMemoryStatus(boolean available, Message result) {
-    }
-
-    public void reportStkServiceIsRunning(Message result) {
-    }
-
-    @Override
-    public void getCdmaSubscriptionSource(Message response) {
-    }
-
-    public void getGsmBroadcastConfig(Message response) {
-    }
-
-    public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response) {
-    }
-
-    public void setGsmBroadcastActivation(boolean activate, Message response) {
-    }
-
-    // ***** Methods for CDMA support
-    public void getDeviceIdentity(Message response) {
-    }
-
-    public void getCDMASubscription(Message response) {
-    }
-
-    public void setPhoneType(int phoneType) { //Set by CDMAPhone and GSMPhone constructor
-    }
-
-    public void queryCdmaRoamingPreference(Message response) {
-    }
-
-    public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
-    }
-
-    public void setCdmaSubscriptionSource(int cdmaSubscription , Message response) {
-    }
-
-    public void queryTTYMode(Message response) {
-    }
-
-    public void setTTYMode(int ttyMode, Message response) {
-    }
-
-    public void sendCDMAFeatureCode(String FeatureCode, Message response) {
-    }
-
-    public void getCdmaBroadcastConfig(Message response) {
-    }
-
-    public void setCdmaBroadcastConfig(int[] configValuesArray, Message response) {
-    }
-
-    public void setCdmaBroadcastActivation(boolean activate, Message response) {
-    }
-
-    public void exitEmergencyCallbackMode(Message response) {
-    }
-
-    @Override
-    public void supplyIccPinForApp(String pin, String aid, Message response) {
-    }
-
-    @Override
-    public void supplyIccPukForApp(String puk, String newPin, String aid, Message response) {
-    }
-
-    @Override
-    public void supplyIccPin2ForApp(String pin2, String aid, Message response) {
-    }
-
-    @Override
-    public void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message response) {
-    }
-
-    @Override
-    public void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message response) {
-    }
-
-    @Override
-    public void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr,
-            Message response) {
-    }
-
-    public void requestIsimAuthentication(String nonce, Message response) {
-    }
-
-    public void getVoiceRadioTechnology(Message result) {
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java b/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java
deleted file mode 100644
index c83f696..0000000
--- a/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2010 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.internal.telephony.sip;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.UUSInfo;
-
-import android.net.sip.SipAudioCall;
-import android.os.SystemClock;
-import android.util.Log;
-import android.telephony.PhoneNumberUtils;
-
-abstract class SipConnectionBase extends Connection {
-    private static final String LOG_TAG = "SIP_CONN";
-
-    private SipAudioCall mSipAudioCall;
-
-    private String dialString;          // outgoing calls only
-    private String postDialString;      // outgoing calls only
-    private int nextPostDialChar;       // index into postDialString
-    private boolean isIncoming;
-
-    /*
-     * These time/timespan values are based on System.currentTimeMillis(),
-     * i.e., "wall clock" time.
-     */
-    private long createTime;
-    private long connectTime;
-    private long disconnectTime;
-
-    /*
-     * These time/timespan values are based on SystemClock.elapsedRealTime(),
-     * i.e., time since boot.  They are appropriate for comparison and
-     * calculating deltas.
-     */
-    private long connectTimeReal;
-    private long duration = -1L;
-    private long holdingStartTime;  // The time when the Connection last transitioned
-                            // into HOLDING
-
-    private DisconnectCause mCause = DisconnectCause.NOT_DISCONNECTED;
-    private PostDialState postDialState = PostDialState.NOT_STARTED;
-
-    SipConnectionBase(String dialString) {
-        this.dialString = dialString;
-
-        postDialString = PhoneNumberUtils.extractPostDialPortion(dialString);
-
-        isIncoming = false;
-        createTime = System.currentTimeMillis();
-    }
-
-    protected void setState(Call.State state) {
-        switch (state) {
-            case ACTIVE:
-                if (connectTime == 0) {
-                    connectTimeReal = SystemClock.elapsedRealtime();
-                    connectTime = System.currentTimeMillis();
-                }
-                break;
-            case DISCONNECTED:
-                duration = getDurationMillis();
-                disconnectTime = System.currentTimeMillis();
-                break;
-            case HOLDING:
-                holdingStartTime = SystemClock.elapsedRealtime();
-                break;
-        }
-    }
-
-    @Override
-    public long getCreateTime() {
-        return createTime;
-    }
-
-    @Override
-    public long getConnectTime() {
-        return connectTime;
-    }
-
-    @Override
-    public long getDisconnectTime() {
-        return disconnectTime;
-    }
-
-    @Override
-    public long getDurationMillis() {
-        if (connectTimeReal == 0) {
-            return 0;
-        } else if (duration < 0) {
-            return SystemClock.elapsedRealtime() - connectTimeReal;
-        } else {
-            return duration;
-        }
-    }
-
-    @Override
-    public long getHoldDurationMillis() {
-        if (getState() != Call.State.HOLDING) {
-            // If not holding, return 0
-            return 0;
-        } else {
-            return SystemClock.elapsedRealtime() - holdingStartTime;
-        }
-    }
-
-    @Override
-    public DisconnectCause getDisconnectCause() {
-        return mCause;
-    }
-
-    void setDisconnectCause(DisconnectCause cause) {
-        mCause = cause;
-    }
-
-    @Override
-    public PostDialState getPostDialState() {
-        return postDialState;
-    }
-
-    @Override
-    public void proceedAfterWaitChar() {
-        // TODO
-    }
-
-    @Override
-    public void proceedAfterWildChar(String str) {
-        // TODO
-    }
-
-    @Override
-    public void cancelPostDial() {
-        // TODO
-    }
-
-    protected abstract Phone getPhone();
-
-    @Override
-    public String getRemainingPostDialString() {
-        if (postDialState == PostDialState.CANCELLED
-            || postDialState == PostDialState.COMPLETE
-            || postDialString == null
-            || postDialString.length() <= nextPostDialChar) {
-            return "";
-        }
-
-        return postDialString.substring(nextPostDialChar);
-    }
-
-    private void log(String msg) {
-        Log.d(LOG_TAG, "[SipConn] " + msg);
-    }
-
-    @Override
-    public int getNumberPresentation() {
-        // TODO: add PRESENTATION_URL
-        return Connection.PRESENTATION_ALLOWED;
-    }
-
-    @Override
-    public UUSInfo getUUSInfo() {
-        // FIXME: what's this for SIP?
-        return null;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
deleted file mode 100644
index 5471289..0000000
--- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java
+++ /dev/null
@@ -1,938 +0,0 @@
-/*
- * Copyright (C) 2010 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.internal.telephony.sip;
-
-import android.content.Context;
-import android.media.AudioManager;
-import android.net.rtp.AudioGroup;
-import android.net.sip.SipAudioCall;
-import android.net.sip.SipErrorCode;
-import android.net.sip.SipException;
-import android.net.sip.SipManager;
-import android.net.sip.SipProfile;
-import android.net.sip.SipSession;
-import android.os.AsyncResult;
-import android.os.Message;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.ServiceState;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallStateException;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneNotifier;
-
-import java.text.ParseException;
-import java.util.List;
-import java.util.regex.Pattern;
-
-/**
- * {@hide}
- */
-public class SipPhone extends SipPhoneBase {
-    private static final String LOG_TAG = "SipPhone";
-    private static final boolean DEBUG = true;
-    private static final int TIMEOUT_MAKE_CALL = 15; // in seconds
-    private static final int TIMEOUT_ANSWER_CALL = 8; // in seconds
-    private static final int TIMEOUT_HOLD_CALL = 15; // in seconds
-
-    // A call that is ringing or (call) waiting
-    private SipCall ringingCall = new SipCall();
-    private SipCall foregroundCall = new SipCall();
-    private SipCall backgroundCall = new SipCall();
-
-    private SipManager mSipManager;
-    private SipProfile mProfile;
-
-    SipPhone (Context context, PhoneNotifier notifier, SipProfile profile) {
-        super(context, notifier);
-
-        if (DEBUG) Log.d(LOG_TAG, "new SipPhone: " + profile.getUriString());
-        ringingCall = new SipCall();
-        foregroundCall = new SipCall();
-        backgroundCall = new SipCall();
-        mProfile = profile;
-        mSipManager = SipManager.newInstance(context);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (o == this) return true;
-        if (!(o instanceof SipPhone)) return false;
-        SipPhone that = (SipPhone) o;
-        return mProfile.getUriString().equals(that.mProfile.getUriString());
-    }
-
-    public String getPhoneName() {
-        return "SIP:" + getUriString(mProfile);
-    }
-
-    public String getSipUri() {
-        return mProfile.getUriString();
-    }
-
-    public boolean equals(SipPhone phone) {
-        return getSipUri().equals(phone.getSipUri());
-    }
-
-    public boolean canTake(Object incomingCall) {
-        synchronized (SipPhone.class) {
-            if (!(incomingCall instanceof SipAudioCall)) return false;
-            if (ringingCall.getState().isAlive()) return false;
-
-            // FIXME: is it true that we cannot take any incoming call if
-            // both foreground and background are active
-            if (foregroundCall.getState().isAlive()
-                    && backgroundCall.getState().isAlive()) {
-                return false;
-            }
-
-            try {
-                SipAudioCall sipAudioCall = (SipAudioCall) incomingCall;
-                if (DEBUG) Log.d(LOG_TAG, "+++ taking call from: "
-                        + sipAudioCall.getPeerProfile().getUriString());
-                String localUri = sipAudioCall.getLocalProfile().getUriString();
-                if (localUri.equals(mProfile.getUriString())) {
-                    boolean makeCallWait = foregroundCall.getState().isAlive();
-                    ringingCall.initIncomingCall(sipAudioCall, makeCallWait);
-                    if (sipAudioCall.getState()
-                            != SipSession.State.INCOMING_CALL) {
-                        // Peer cancelled the call!
-                        if (DEBUG) Log.d(LOG_TAG, "    call cancelled !!");
-                        ringingCall.reset();
-                    }
-                    return true;
-                }
-            } catch (Exception e) {
-                // Peer may cancel the call at any time during the time we hook
-                // up ringingCall with sipAudioCall. Clean up ringingCall when
-                // that happens.
-                ringingCall.reset();
-            }
-            return false;
-        }
-    }
-
-    public void acceptCall() throws CallStateException {
-        synchronized (SipPhone.class) {
-            if ((ringingCall.getState() == Call.State.INCOMING) ||
-                    (ringingCall.getState() == Call.State.WAITING)) {
-                if (DEBUG) Log.d(LOG_TAG, "acceptCall");
-                // Always unmute when answering a new call
-                ringingCall.setMute(false);
-                ringingCall.acceptCall();
-            } else {
-                throw new CallStateException("phone not ringing");
-            }
-        }
-    }
-
-    public void rejectCall() throws CallStateException {
-        synchronized (SipPhone.class) {
-            if (ringingCall.getState().isRinging()) {
-                if (DEBUG) Log.d(LOG_TAG, "rejectCall");
-                ringingCall.rejectCall();
-            } else {
-                throw new CallStateException("phone not ringing");
-            }
-        }
-    }
-
-    public Connection dial(String dialString) throws CallStateException {
-        synchronized (SipPhone.class) {
-            return dialInternal(dialString);
-        }
-    }
-
-    private Connection dialInternal(String dialString)
-            throws CallStateException {
-        clearDisconnected();
-
-        if (!canDial()) {
-            throw new CallStateException("cannot dial in current state");
-        }
-        if (foregroundCall.getState() == SipCall.State.ACTIVE) {
-            switchHoldingAndActive();
-        }
-        if (foregroundCall.getState() != SipCall.State.IDLE) {
-            //we should have failed in !canDial() above before we get here
-            throw new CallStateException("cannot dial in current state");
-        }
-
-        foregroundCall.setMute(false);
-        try {
-            Connection c = foregroundCall.dial(dialString);
-            return c;
-        } catch (SipException e) {
-            Log.e(LOG_TAG, "dial()", e);
-            throw new CallStateException("dial error: " + e);
-        }
-    }
-
-    public void switchHoldingAndActive() throws CallStateException {
-        if (DEBUG) Log.d(LOG_TAG, " ~~~~~~  switch fg and bg");
-        synchronized (SipPhone.class) {
-            foregroundCall.switchWith(backgroundCall);
-            if (backgroundCall.getState().isAlive()) backgroundCall.hold();
-            if (foregroundCall.getState().isAlive()) foregroundCall.unhold();
-        }
-    }
-
-    public boolean canConference() {
-        return true;
-    }
-
-    public void conference() throws CallStateException {
-        synchronized (SipPhone.class) {
-            if ((foregroundCall.getState() != SipCall.State.ACTIVE)
-                    || (foregroundCall.getState() != SipCall.State.ACTIVE)) {
-                throw new CallStateException("wrong state to merge calls: fg="
-                        + foregroundCall.getState() + ", bg="
-                        + backgroundCall.getState());
-            }
-            foregroundCall.merge(backgroundCall);
-        }
-    }
-
-    public void conference(Call that) throws CallStateException {
-        synchronized (SipPhone.class) {
-            if (!(that instanceof SipCall)) {
-                throw new CallStateException("expect " + SipCall.class
-                        + ", cannot merge with " + that.getClass());
-            }
-            foregroundCall.merge((SipCall) that);
-        }
-    }
-
-    public boolean canTransfer() {
-        return false;
-    }
-
-    public void explicitCallTransfer() throws CallStateException {
-        //mCT.explicitCallTransfer();
-    }
-
-    public void clearDisconnected() {
-        synchronized (SipPhone.class) {
-            ringingCall.clearDisconnected();
-            foregroundCall.clearDisconnected();
-            backgroundCall.clearDisconnected();
-
-            updatePhoneState();
-            notifyPreciseCallStateChanged();
-        }
-    }
-
-    public void sendDtmf(char c) {
-        if (!PhoneNumberUtils.is12Key(c)) {
-            Log.e(LOG_TAG,
-                    "sendDtmf called with invalid character '" + c + "'");
-        } else if (foregroundCall.getState().isAlive()) {
-            synchronized (SipPhone.class) {
-                foregroundCall.sendDtmf(c);
-            }
-        }
-    }
-
-    public void startDtmf(char c) {
-        if (!PhoneNumberUtils.is12Key(c)) {
-            Log.e(LOG_TAG,
-                "startDtmf called with invalid character '" + c + "'");
-        } else {
-            sendDtmf(c);
-        }
-    }
-
-    public void stopDtmf() {
-        // no op
-    }
-
-    public void sendBurstDtmf(String dtmfString) {
-        Log.e(LOG_TAG, "[SipPhone] sendBurstDtmf() is a CDMA method");
-    }
-
-    public void getOutgoingCallerIdDisplay(Message onComplete) {
-        // FIXME: what to reply?
-        AsyncResult.forMessage(onComplete, null, null);
-        onComplete.sendToTarget();
-    }
-
-    public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode,
-                                           Message onComplete) {
-        // FIXME: what's this for SIP?
-        AsyncResult.forMessage(onComplete, null, null);
-        onComplete.sendToTarget();
-    }
-
-    public void getCallWaiting(Message onComplete) {
-        // FIXME: what to reply?
-        AsyncResult.forMessage(onComplete, null, null);
-        onComplete.sendToTarget();
-    }
-
-    public void setCallWaiting(boolean enable, Message onComplete) {
-        // FIXME: what to reply?
-        Log.e(LOG_TAG, "call waiting not supported");
-    }
-
-    @Override
-    public void setEchoSuppressionEnabled(boolean enabled) {
-        // TODO: Remove the enabled argument. We should check the speakerphone
-        // state with AudioManager instead of keeping a state here so the
-        // method with a state argument is redundant. Also rename the method
-        // to something like onSpeaerphoneStateChanged(). Echo suppression may
-        // not be available on every device.
-        synchronized (SipPhone.class) {
-            foregroundCall.setAudioGroupMode();
-        }
-    }
-
-    public void setMute(boolean muted) {
-        synchronized (SipPhone.class) {
-            foregroundCall.setMute(muted);
-        }
-    }
-
-    public boolean getMute() {
-        return (foregroundCall.getState().isAlive()
-                ? foregroundCall.getMute()
-                : backgroundCall.getMute());
-    }
-
-    public Call getForegroundCall() {
-        return foregroundCall;
-    }
-
-    public Call getBackgroundCall() {
-        return backgroundCall;
-    }
-
-    public Call getRingingCall() {
-        return ringingCall;
-    }
-
-    public ServiceState getServiceState() {
-        // FIXME: we may need to provide this when data connectivity is lost
-        // or when server is down
-        return super.getServiceState();
-    }
-
-    private String getUriString(SipProfile p) {
-        // SipProfile.getUriString() may contain "SIP:" and port
-        return p.getUserName() + "@" + getSipDomain(p);
-    }
-
-    private String getSipDomain(SipProfile p) {
-        String domain = p.getSipDomain();
-        // TODO: move this to SipProfile
-        if (domain.endsWith(":5060")) {
-            return domain.substring(0, domain.length() - 5);
-        } else {
-            return domain;
-        }
-    }
-
-    private class SipCall extends SipCallBase {
-        void reset() {
-            connections.clear();
-            setState(Call.State.IDLE);
-        }
-
-        void switchWith(SipCall that) {
-            synchronized (SipPhone.class) {
-                SipCall tmp = new SipCall();
-                tmp.takeOver(this);
-                this.takeOver(that);
-                that.takeOver(tmp);
-            }
-        }
-
-        private void takeOver(SipCall that) {
-            connections = that.connections;
-            state = that.state;
-            for (Connection c : connections) {
-                ((SipConnection) c).changeOwner(this);
-            }
-        }
-
-        @Override
-        public Phone getPhone() {
-            return SipPhone.this;
-        }
-
-        @Override
-        public List<Connection> getConnections() {
-            synchronized (SipPhone.class) {
-                // FIXME should return Collections.unmodifiableList();
-                return connections;
-            }
-        }
-
-        Connection dial(String originalNumber) throws SipException {
-            String calleeSipUri = originalNumber;
-            if (!calleeSipUri.contains("@")) {
-                String replaceStr = Pattern.quote(mProfile.getUserName() + "@");
-                calleeSipUri = mProfile.getUriString().replaceFirst(replaceStr,
-                        calleeSipUri + "@");
-            }
-            try {
-                SipProfile callee =
-                        new SipProfile.Builder(calleeSipUri).build();
-                SipConnection c = new SipConnection(this, callee,
-                        originalNumber);
-                c.dial();
-                connections.add(c);
-                setState(Call.State.DIALING);
-                return c;
-            } catch (ParseException e) {
-                throw new SipException("dial", e);
-            }
-        }
-
-        @Override
-        public void hangup() throws CallStateException {
-            synchronized (SipPhone.class) {
-                if (state.isAlive()) {
-                    if (DEBUG) Log.d(LOG_TAG, "hang up call: " + getState()
-                            + ": " + this + " on phone " + getPhone());
-                    setState(State.DISCONNECTING);
-                    CallStateException excp = null;
-                    for (Connection c : connections) {
-                        try {
-                            c.hangup();
-                        } catch (CallStateException e) {
-                            excp = e;
-                        }
-                    }
-                    if (excp != null) throw excp;
-                } else {
-                    if (DEBUG) Log.d(LOG_TAG, "hang up dead call: " + getState()
-                            + ": " + this + " on phone " + getPhone());
-                }
-            }
-        }
-
-        void initIncomingCall(SipAudioCall sipAudioCall, boolean makeCallWait) {
-            SipProfile callee = sipAudioCall.getPeerProfile();
-            SipConnection c = new SipConnection(this, callee);
-            connections.add(c);
-
-            Call.State newState = makeCallWait ? State.WAITING : State.INCOMING;
-            c.initIncomingCall(sipAudioCall, newState);
-
-            setState(newState);
-            notifyNewRingingConnectionP(c);
-        }
-
-        void rejectCall() throws CallStateException {
-            hangup();
-        }
-
-        void acceptCall() throws CallStateException {
-            if (this != ringingCall) {
-                throw new CallStateException("acceptCall() in a non-ringing call");
-            }
-            if (connections.size() != 1) {
-                throw new CallStateException("acceptCall() in a conf call");
-            }
-            ((SipConnection) connections.get(0)).acceptCall();
-        }
-
-        private boolean isSpeakerOn() {
-            return ((AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE))
-                    .isSpeakerphoneOn();
-        }
-
-        void setAudioGroupMode() {
-            AudioGroup audioGroup = getAudioGroup();
-            if (audioGroup == null) return;
-            int mode = audioGroup.getMode();
-            if (state == State.HOLDING) {
-                audioGroup.setMode(AudioGroup.MODE_ON_HOLD);
-            } else if (getMute()) {
-                audioGroup.setMode(AudioGroup.MODE_MUTED);
-            } else if (isSpeakerOn()) {
-                audioGroup.setMode(AudioGroup.MODE_ECHO_SUPPRESSION);
-            } else {
-                audioGroup.setMode(AudioGroup.MODE_NORMAL);
-            }
-            if (DEBUG) Log.d(LOG_TAG, String.format(
-                    "audioGroup mode change: %d --> %d", mode,
-                    audioGroup.getMode()));
-        }
-
-        void hold() throws CallStateException {
-            setState(State.HOLDING);
-            for (Connection c : connections) ((SipConnection) c).hold();
-            setAudioGroupMode();
-        }
-
-        void unhold() throws CallStateException {
-            setState(State.ACTIVE);
-            AudioGroup audioGroup = new AudioGroup();
-            for (Connection c : connections) {
-                ((SipConnection) c).unhold(audioGroup);
-            }
-            setAudioGroupMode();
-        }
-
-        void setMute(boolean muted) {
-            for (Connection c : connections) {
-                ((SipConnection) c).setMute(muted);
-            }
-        }
-
-        boolean getMute() {
-            return connections.isEmpty()
-                    ? false
-                    : ((SipConnection) connections.get(0)).getMute();
-        }
-
-        void merge(SipCall that) throws CallStateException {
-            AudioGroup audioGroup = getAudioGroup();
-
-            // copy to an array to avoid concurrent modification as connections
-            // in that.connections will be removed in add(SipConnection).
-            Connection[] cc = that.connections.toArray(
-                    new Connection[that.connections.size()]);
-            for (Connection c : cc) {
-                SipConnection conn = (SipConnection) c;
-                add(conn);
-                if (conn.getState() == Call.State.HOLDING) {
-                    conn.unhold(audioGroup);
-                }
-            }
-            that.setState(Call.State.IDLE);
-        }
-
-        private void add(SipConnection conn) {
-            SipCall call = conn.getCall();
-            if (call == this) return;
-            if (call != null) call.connections.remove(conn);
-
-            connections.add(conn);
-            conn.changeOwner(this);
-        }
-
-        void sendDtmf(char c) {
-            AudioGroup audioGroup = getAudioGroup();
-            if (audioGroup == null) return;
-            audioGroup.sendDtmf(convertDtmf(c));
-        }
-
-        private int convertDtmf(char c) {
-            int code = c - '0';
-            if ((code < 0) || (code > 9)) {
-                switch (c) {
-                    case '*': return 10;
-                    case '#': return 11;
-                    case 'A': return 12;
-                    case 'B': return 13;
-                    case 'C': return 14;
-                    case 'D': return 15;
-                    default:
-                        throw new IllegalArgumentException(
-                                "invalid DTMF char: " + (int) c);
-                }
-            }
-            return code;
-        }
-
-        @Override
-        protected void setState(State newState) {
-            if (state != newState) {
-                if (DEBUG) Log.v(LOG_TAG, "+***+ call state changed: " + state
-                        + " --> " + newState + ": " + this + ": on phone "
-                        + getPhone() + " " + connections.size());
-
-                if (newState == Call.State.ALERTING) {
-                    state = newState; // need in ALERTING to enable ringback
-                    SipPhone.this.startRingbackTone();
-                } else if (state == Call.State.ALERTING) {
-                    SipPhone.this.stopRingbackTone();
-                }
-                state = newState;
-                updatePhoneState();
-                notifyPreciseCallStateChanged();
-            }
-        }
-
-        void onConnectionStateChanged(SipConnection conn) {
-            // this can be called back when a conf call is formed
-            if (state != State.ACTIVE) {
-                setState(conn.getState());
-            }
-        }
-
-        void onConnectionEnded(SipConnection conn) {
-            // set state to DISCONNECTED only when all conns are disconnected
-            if (state != State.DISCONNECTED) {
-                boolean allConnectionsDisconnected = true;
-                if (DEBUG) Log.d(LOG_TAG, "---check connections: "
-                        + connections.size());
-                for (Connection c : connections) {
-                    if (DEBUG) Log.d(LOG_TAG, "   state=" + c.getState() + ": "
-                            + c);
-                    if (c.getState() != State.DISCONNECTED) {
-                        allConnectionsDisconnected = false;
-                        break;
-                    }
-                }
-                if (allConnectionsDisconnected) setState(State.DISCONNECTED);
-            }
-            notifyDisconnectP(conn);
-        }
-
-        private AudioGroup getAudioGroup() {
-            if (connections.isEmpty()) return null;
-            return ((SipConnection) connections.get(0)).getAudioGroup();
-        }
-    }
-
-    private class SipConnection extends SipConnectionBase {
-        private SipCall mOwner;
-        private SipAudioCall mSipAudioCall;
-        private Call.State mState = Call.State.IDLE;
-        private SipProfile mPeer;
-        private String mOriginalNumber; // may be a PSTN number
-        private boolean mIncoming = false;
-
-        private SipAudioCallAdapter mAdapter = new SipAudioCallAdapter() {
-            @Override
-            protected void onCallEnded(DisconnectCause cause) {
-                if (getDisconnectCause() != DisconnectCause.LOCAL) {
-                    setDisconnectCause(cause);
-                }
-                synchronized (SipPhone.class) {
-                    setState(Call.State.DISCONNECTED);
-                    SipAudioCall sipAudioCall = mSipAudioCall;
-                    mSipAudioCall = null;
-                    String sessionState = (sipAudioCall == null)
-                            ? ""
-                            : (sipAudioCall.getState() + ", ");
-                    if (DEBUG) Log.d(LOG_TAG, "--- connection ended: "
-                            + mPeer.getUriString() + ": " + sessionState
-                            + "cause: " + getDisconnectCause() + ", on phone "
-                            + getPhone());
-                    if (sipAudioCall != null) {
-                        sipAudioCall.setListener(null);
-                        sipAudioCall.close();
-                    }
-                    mOwner.onConnectionEnded(SipConnection.this);
-                }
-            }
-
-            @Override
-            public void onCallEstablished(SipAudioCall call) {
-                onChanged(call);
-                if (mState == Call.State.ACTIVE) call.startAudio();
-            }
-
-            @Override
-            public void onCallHeld(SipAudioCall call) {
-                onChanged(call);
-                if (mState == Call.State.HOLDING) call.startAudio();
-            }
-
-            @Override
-            public void onChanged(SipAudioCall call) {
-                synchronized (SipPhone.class) {
-                    Call.State newState = getCallStateFrom(call);
-                    if (mState == newState) return;
-                    if (newState == Call.State.INCOMING) {
-                        setState(mOwner.getState()); // INCOMING or WAITING
-                    } else {
-                        if (mOwner == ringingCall) {
-                            if (ringingCall.getState() == Call.State.WAITING) {
-                                try {
-                                    switchHoldingAndActive();
-                                } catch (CallStateException e) {
-                                    // disconnect the call.
-                                    onCallEnded(DisconnectCause.LOCAL);
-                                    return;
-                                }
-                            }
-                            foregroundCall.switchWith(ringingCall);
-                        }
-                        setState(newState);
-                    }
-                    mOwner.onConnectionStateChanged(SipConnection.this);
-                    if (DEBUG) Log.v(LOG_TAG, "+***+ connection state changed: "
-                            + mPeer.getUriString() + ": " + mState
-                            + " on phone " + getPhone());
-                }
-            }
-
-            @Override
-            protected void onError(DisconnectCause cause) {
-                if (DEBUG) Log.d(LOG_TAG, "SIP error: " + cause);
-                onCallEnded(cause);
-            }
-        };
-
-        public SipConnection(SipCall owner, SipProfile callee,
-                String originalNumber) {
-            super(originalNumber);
-            mOwner = owner;
-            mPeer = callee;
-            mOriginalNumber = originalNumber;
-        }
-
-        public SipConnection(SipCall owner, SipProfile callee) {
-            this(owner, callee, getUriString(callee));
-        }
-
-        @Override
-        public String getCnapName() {
-            String displayName = mPeer.getDisplayName();
-            return TextUtils.isEmpty(displayName) ? null
-                                                  : displayName;
-        }
-
-        @Override
-        public int getNumberPresentation() {
-            return Connection.PRESENTATION_ALLOWED;
-        }
-
-        void initIncomingCall(SipAudioCall sipAudioCall, Call.State newState) {
-            setState(newState);
-            mSipAudioCall = sipAudioCall;
-            sipAudioCall.setListener(mAdapter); // call back to set state
-            mIncoming = true;
-        }
-
-        void acceptCall() throws CallStateException {
-            try {
-                mSipAudioCall.answerCall(TIMEOUT_ANSWER_CALL);
-            } catch (SipException e) {
-                throw new CallStateException("acceptCall(): " + e);
-            }
-        }
-
-        void changeOwner(SipCall owner) {
-            mOwner = owner;
-        }
-
-        AudioGroup getAudioGroup() {
-            if (mSipAudioCall == null) return null;
-            return mSipAudioCall.getAudioGroup();
-        }
-
-        void dial() throws SipException {
-            setState(Call.State.DIALING);
-            mSipAudioCall = mSipManager.makeAudioCall(mProfile, mPeer, null,
-                    TIMEOUT_MAKE_CALL);
-            mSipAudioCall.setListener(mAdapter);
-        }
-
-        void hold() throws CallStateException {
-            setState(Call.State.HOLDING);
-            try {
-                mSipAudioCall.holdCall(TIMEOUT_HOLD_CALL);
-            } catch (SipException e) {
-                throw new CallStateException("hold(): " + e);
-            }
-        }
-
-        void unhold(AudioGroup audioGroup) throws CallStateException {
-            mSipAudioCall.setAudioGroup(audioGroup);
-            setState(Call.State.ACTIVE);
-            try {
-                mSipAudioCall.continueCall(TIMEOUT_HOLD_CALL);
-            } catch (SipException e) {
-                throw new CallStateException("unhold(): " + e);
-            }
-        }
-
-        void setMute(boolean muted) {
-            if ((mSipAudioCall != null) && (muted != mSipAudioCall.isMuted())) {
-                mSipAudioCall.toggleMute();
-            }
-        }
-
-        boolean getMute() {
-            return (mSipAudioCall == null) ? false
-                                           : mSipAudioCall.isMuted();
-        }
-
-        @Override
-        protected void setState(Call.State state) {
-            if (state == mState) return;
-            super.setState(state);
-            mState = state;
-        }
-
-        @Override
-        public Call.State getState() {
-            return mState;
-        }
-
-        @Override
-        public boolean isIncoming() {
-            return mIncoming;
-        }
-
-        @Override
-        public String getAddress() {
-            // Phone app uses this to query caller ID. Return the original dial
-            // number (which may be a PSTN number) instead of the peer's SIP
-            // URI.
-            return mOriginalNumber;
-        }
-
-        @Override
-        public SipCall getCall() {
-            return mOwner;
-        }
-
-        @Override
-        protected Phone getPhone() {
-            return mOwner.getPhone();
-        }
-
-        @Override
-        public void hangup() throws CallStateException {
-            synchronized (SipPhone.class) {
-                if (DEBUG) Log.d(LOG_TAG, "hangup conn: " + mPeer.getUriString()
-                        + ": " + mState + ": on phone "
-                        + getPhone().getPhoneName());
-                if (!mState.isAlive()) return;
-                try {
-                    SipAudioCall sipAudioCall = mSipAudioCall;
-                    if (sipAudioCall != null) {
-                        sipAudioCall.setListener(null);
-                        sipAudioCall.endCall();
-                    }
-                } catch (SipException e) {
-                    throw new CallStateException("hangup(): " + e);
-                } finally {
-                    mAdapter.onCallEnded(((mState == Call.State.INCOMING)
-                            || (mState == Call.State.WAITING))
-                            ? DisconnectCause.INCOMING_REJECTED
-                            : DisconnectCause.LOCAL);
-                }
-            }
-        }
-
-        @Override
-        public void separate() throws CallStateException {
-            synchronized (SipPhone.class) {
-                SipCall call = (getPhone() == SipPhone.this)
-                        ? (SipCall) SipPhone.this.getBackgroundCall()
-                        : (SipCall) SipPhone.this.getForegroundCall();
-                if (call.getState() != Call.State.IDLE) {
-                    throw new CallStateException(
-                            "cannot put conn back to a call in non-idle state: "
-                            + call.getState());
-                }
-                if (DEBUG) Log.d(LOG_TAG, "separate conn: "
-                        + mPeer.getUriString() + " from " + mOwner + " back to "
-                        + call);
-
-                // separate the AudioGroup and connection from the original call
-                Phone originalPhone = getPhone();
-                AudioGroup audioGroup = call.getAudioGroup(); // may be null
-                call.add(this);
-                mSipAudioCall.setAudioGroup(audioGroup);
-
-                // put the original call to bg; and the separated call becomes
-                // fg if it was in bg
-                originalPhone.switchHoldingAndActive();
-
-                // start audio and notify the phone app of the state change
-                call = (SipCall) SipPhone.this.getForegroundCall();
-                mSipAudioCall.startAudio();
-                call.onConnectionStateChanged(this);
-            }
-        }
-
-    }
-
-    private static Call.State getCallStateFrom(SipAudioCall sipAudioCall) {
-        if (sipAudioCall.isOnHold()) return Call.State.HOLDING;
-        int sessionState = sipAudioCall.getState();
-        switch (sessionState) {
-            case SipSession.State.READY_TO_CALL:            return Call.State.IDLE;
-            case SipSession.State.INCOMING_CALL:
-            case SipSession.State.INCOMING_CALL_ANSWERING:  return Call.State.INCOMING;
-            case SipSession.State.OUTGOING_CALL:            return Call.State.DIALING;
-            case SipSession.State.OUTGOING_CALL_RING_BACK:  return Call.State.ALERTING;
-            case SipSession.State.OUTGOING_CALL_CANCELING:  return Call.State.DISCONNECTING;
-            case SipSession.State.IN_CALL:                  return Call.State.ACTIVE;
-            default:
-                Log.w(LOG_TAG, "illegal connection state: " + sessionState);
-                return Call.State.DISCONNECTED;
-        }
-    }
-
-    private abstract class SipAudioCallAdapter extends SipAudioCall.Listener {
-        protected abstract void onCallEnded(Connection.DisconnectCause cause);
-        protected abstract void onError(Connection.DisconnectCause cause);
-
-        @Override
-        public void onCallEnded(SipAudioCall call) {
-            onCallEnded(call.isInCall()
-                    ? Connection.DisconnectCause.NORMAL
-                    : Connection.DisconnectCause.INCOMING_MISSED);
-        }
-
-        @Override
-        public void onCallBusy(SipAudioCall call) {
-            onCallEnded(Connection.DisconnectCause.BUSY);
-        }
-
-        @Override
-        public void onError(SipAudioCall call, int errorCode,
-                String errorMessage) {
-            switch (errorCode) {
-                case SipErrorCode.SERVER_UNREACHABLE:
-                    onError(Connection.DisconnectCause.SERVER_UNREACHABLE);
-                    break;
-                case SipErrorCode.PEER_NOT_REACHABLE:
-                    onError(Connection.DisconnectCause.NUMBER_UNREACHABLE);
-                    break;
-                case SipErrorCode.INVALID_REMOTE_URI:
-                    onError(Connection.DisconnectCause.INVALID_NUMBER);
-                    break;
-                case SipErrorCode.TIME_OUT:
-                case SipErrorCode.TRANSACTION_TERMINTED:
-                    onError(Connection.DisconnectCause.TIMED_OUT);
-                    break;
-                case SipErrorCode.DATA_CONNECTION_LOST:
-                    onError(Connection.DisconnectCause.LOST_SIGNAL);
-                    break;
-                case SipErrorCode.INVALID_CREDENTIALS:
-                    onError(Connection.DisconnectCause.INVALID_CREDENTIALS);
-                    break;
-                case SipErrorCode.CROSS_DOMAIN_AUTHENTICATION:
-                    onError(Connection.DisconnectCause.OUT_OF_NETWORK);
-                    break;
-                case SipErrorCode.SERVER_ERROR:
-                    onError(Connection.DisconnectCause.SERVER_ERROR);
-                    break;
-                case SipErrorCode.SOCKET_ERROR:
-                case SipErrorCode.CLIENT_ERROR:
-                default:
-                    Log.w(LOG_TAG, "error: " + SipErrorCode.toString(errorCode)
-                            + ": " + errorMessage);
-                    onError(Connection.DisconnectCause.ERROR_UNSPECIFIED);
-            }
-        }
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java b/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
deleted file mode 100755
index 5c4b446..0000000
--- a/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
+++ /dev/null
@@ -1,464 +0,0 @@
-/*
- * Copyright (C) 2010 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.internal.telephony.sip;
-
-import android.content.Context;
-import android.net.LinkProperties;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.os.SystemProperties;
-import android.telephony.CellLocation;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.util.Log;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallStateException;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.DataConnection;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccFileHandler;
-import com.android.internal.telephony.IccPhoneBookInterfaceManager;
-import com.android.internal.telephony.IccSmsInterfaceManager;
-import com.android.internal.telephony.MmiCode;
-import com.android.internal.telephony.OperatorInfo;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.PhoneNotifier;
-import com.android.internal.telephony.PhoneSubInfo;
-import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.telephony.UUSInfo;
-
-import java.util.ArrayList;
-import java.util.List;
-
-abstract class SipPhoneBase extends PhoneBase {
-    private static final String LOG_TAG = "SipPhone";
-
-    private RegistrantList mRingbackRegistrants = new RegistrantList();
-    private State state = State.IDLE;
-
-    public SipPhoneBase(Context context, PhoneNotifier notifier) {
-        super(notifier, context, new SipCommandInterface(context), false);
-    }
-
-    public abstract Call getForegroundCall();
-
-    public abstract Call getBackgroundCall();
-
-    public abstract Call getRingingCall();
-
-    public Connection dial(String dialString, UUSInfo uusInfo)
-            throws CallStateException {
-        // ignore UUSInfo
-        return dial(dialString);
-    }
-
-    void migrateFrom(SipPhoneBase from) {
-        migrate(mRingbackRegistrants, from.mRingbackRegistrants);
-        migrate(mPreciseCallStateRegistrants, from.mPreciseCallStateRegistrants);
-        migrate(mNewRingingConnectionRegistrants, from.mNewRingingConnectionRegistrants);
-        migrate(mIncomingRingRegistrants, from.mIncomingRingRegistrants);
-        migrate(mDisconnectRegistrants, from.mDisconnectRegistrants);
-        migrate(mServiceStateRegistrants, from.mServiceStateRegistrants);
-        migrate(mMmiCompleteRegistrants, from.mMmiCompleteRegistrants);
-        migrate(mMmiRegistrants, from.mMmiRegistrants);
-        migrate(mUnknownConnectionRegistrants, from.mUnknownConnectionRegistrants);
-        migrate(mSuppServiceFailedRegistrants, from.mSuppServiceFailedRegistrants);
-    }
-
-    static void migrate(RegistrantList to, RegistrantList from) {
-        from.removeCleared();
-        for (int i = 0, n = from.size(); i < n; i++) {
-            to.add((Registrant) from.get(i));
-        }
-    }
-
-    @Override
-    public void registerForRingbackTone(Handler h, int what, Object obj) {
-        mRingbackRegistrants.addUnique(h, what, obj);
-    }
-
-    @Override
-    public void unregisterForRingbackTone(Handler h) {
-        mRingbackRegistrants.remove(h);
-    }
-
-    protected void startRingbackTone() {
-        AsyncResult result = new AsyncResult(null, Boolean.TRUE, null);
-        mRingbackRegistrants.notifyRegistrants(result);
-    }
-
-    protected void stopRingbackTone() {
-        AsyncResult result = new AsyncResult(null, Boolean.FALSE, null);
-        mRingbackRegistrants.notifyRegistrants(result);
-    }
-
-    public ServiceState getServiceState() {
-        // FIXME: we may need to provide this when data connectivity is lost
-        // or when server is down
-        ServiceState s = new ServiceState();
-        s.setState(ServiceState.STATE_IN_SERVICE);
-        return s;
-    }
-
-    public CellLocation getCellLocation() {
-        return null;
-    }
-
-    public State getState() {
-        return state;
-    }
-
-    public int getPhoneType() {
-        return Phone.PHONE_TYPE_SIP;
-    }
-
-    public SignalStrength getSignalStrength() {
-        return new SignalStrength();
-    }
-
-    public boolean getMessageWaitingIndicator() {
-        return false;
-    }
-
-    public boolean getCallForwardingIndicator() {
-        return false;
-    }
-
-    public List<? extends MmiCode> getPendingMmiCodes() {
-        return new ArrayList<MmiCode>(0);
-    }
-
-    public DataState getDataConnectionState() {
-        return DataState.DISCONNECTED;
-    }
-
-    public DataState getDataConnectionState(String apnType) {
-        return DataState.DISCONNECTED;
-    }
-
-    public DataActivityState getDataActivityState() {
-        return DataActivityState.NONE;
-    }
-
-    /**
-     * Notify any interested party of a Phone state change {@link Phone.State}
-     */
-    void notifyPhoneStateChanged() {
-        mNotifier.notifyPhoneState(this);
-    }
-
-    /**
-     * Notify registrants of a change in the call state. This notifies changes in {@link Call.State}
-     * Use this when changes in the precise call state are needed, else use notifyPhoneStateChanged.
-     */
-    void notifyPreciseCallStateChanged() {
-        /* we'd love it if this was package-scoped*/
-        super.notifyPreciseCallStateChangedP();
-    }
-
-    void notifyNewRingingConnection(Connection c) {
-        super.notifyNewRingingConnectionP(c);
-    }
-
-    void notifyDisconnect(Connection cn) {
-        mDisconnectRegistrants.notifyResult(cn);
-    }
-
-    void notifyUnknownConnection() {
-        mUnknownConnectionRegistrants.notifyResult(this);
-    }
-
-    void notifySuppServiceFailed(SuppService code) {
-        mSuppServiceFailedRegistrants.notifyResult(code);
-    }
-
-    void notifyServiceStateChanged(ServiceState ss) {
-        super.notifyServiceStateChangedP(ss);
-    }
-
-    public void notifyCallForwardingIndicator() {
-        mNotifier.notifyCallForwardingChanged(this);
-    }
-
-    public boolean canDial() {
-        int serviceState = getServiceState().getState();
-        Log.v(LOG_TAG, "canDial(): serviceState = " + serviceState);
-        if (serviceState == ServiceState.STATE_POWER_OFF) return false;
-
-        String disableCall = SystemProperties.get(
-                TelephonyProperties.PROPERTY_DISABLE_CALL, "false");
-        Log.v(LOG_TAG, "canDial(): disableCall = " + disableCall);
-        if (disableCall.equals("true")) return false;
-
-        Log.v(LOG_TAG, "canDial(): ringingCall: " + getRingingCall().getState());
-        Log.v(LOG_TAG, "canDial(): foregndCall: " + getForegroundCall().getState());
-        Log.v(LOG_TAG, "canDial(): backgndCall: " + getBackgroundCall().getState());
-        return !getRingingCall().isRinging()
-                && (!getForegroundCall().getState().isAlive()
-                    || !getBackgroundCall().getState().isAlive());
-    }
-
-    public boolean handleInCallMmiCommands(String dialString)
-            throws CallStateException {
-        return false;
-    }
-
-    boolean isInCall() {
-        Call.State foregroundCallState = getForegroundCall().getState();
-        Call.State backgroundCallState = getBackgroundCall().getState();
-        Call.State ringingCallState = getRingingCall().getState();
-
-       return (foregroundCallState.isAlive() || backgroundCallState.isAlive()
-            || ringingCallState.isAlive());
-    }
-
-    public boolean handlePinMmi(String dialString) {
-        return false;
-    }
-
-    public void sendUssdResponse(String ussdMessge) {
-    }
-
-    public void registerForSuppServiceNotification(
-            Handler h, int what, Object obj) {
-    }
-
-    public void unregisterForSuppServiceNotification(Handler h) {
-    }
-
-    public void setRadioPower(boolean power) {
-    }
-
-    public String getVoiceMailNumber() {
-        return null;
-    }
-
-    public String getVoiceMailAlphaTag() {
-        return null;
-    }
-
-    public String getDeviceId() {
-        return null;
-    }
-
-    public String getDeviceSvn() {
-        return null;
-    }
-
-    public String getImei() {
-        return null;
-    }
-
-    public String getEsn() {
-        Log.e(LOG_TAG, "[SipPhone] getEsn() is a CDMA method");
-        return "0";
-    }
-
-    public String getMeid() {
-        Log.e(LOG_TAG, "[SipPhone] getMeid() is a CDMA method");
-        return "0";
-    }
-
-    public String getSubscriberId() {
-        return null;
-    }
-
-    public String getIccSerialNumber() {
-        return null;
-    }
-
-    public String getLine1Number() {
-        return null;
-    }
-
-    public String getLine1AlphaTag() {
-        return null;
-    }
-
-    public void setLine1Number(String alphaTag, String number, Message onComplete) {
-        // FIXME: what to reply for SIP?
-        AsyncResult.forMessage(onComplete, null, null);
-        onComplete.sendToTarget();
-    }
-
-    public void setVoiceMailNumber(String alphaTag, String voiceMailNumber,
-            Message onComplete) {
-        // FIXME: what to reply for SIP?
-        AsyncResult.forMessage(onComplete, null, null);
-        onComplete.sendToTarget();
-    }
-
-    public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) {
-    }
-
-    public void setCallForwardingOption(int commandInterfaceCFAction,
-            int commandInterfaceCFReason, String dialingNumber,
-            int timerSeconds, Message onComplete) {
-    }
-
-    public void getOutgoingCallerIdDisplay(Message onComplete) {
-        // FIXME: what to reply?
-        AsyncResult.forMessage(onComplete, null, null);
-        onComplete.sendToTarget();
-    }
-
-    public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode,
-                                           Message onComplete) {
-        // FIXME: what's this for SIP?
-        AsyncResult.forMessage(onComplete, null, null);
-        onComplete.sendToTarget();
-    }
-
-    public void getCallWaiting(Message onComplete) {
-        AsyncResult.forMessage(onComplete, null, null);
-        onComplete.sendToTarget();
-    }
-
-    public void setCallWaiting(boolean enable, Message onComplete) {
-        Log.e(LOG_TAG, "call waiting not supported");
-    }
-
-    public boolean getIccRecordsLoaded() {
-        return false;
-    }
-
-    public IccCard getIccCard() {
-        return null;
-    }
-
-    public void getAvailableNetworks(Message response) {
-    }
-
-    public void setNetworkSelectionModeAutomatic(Message response) {
-    }
-
-    public void selectNetworkManually(
-            OperatorInfo network,
-            Message response) {
-    }
-
-    public void getNeighboringCids(Message response) {
-    }
-
-    public void setOnPostDialCharacter(Handler h, int what, Object obj) {
-    }
-
-    public void getDataCallList(Message response) {
-    }
-
-    public List<DataConnection> getCurrentDataConnectionList () {
-        return null;
-    }
-
-    public void updateServiceLocation() {
-    }
-
-    public void enableLocationUpdates() {
-    }
-
-    public void disableLocationUpdates() {
-    }
-
-    public boolean getDataRoamingEnabled() {
-        return false;
-    }
-
-    public void setDataRoamingEnabled(boolean enable) {
-    }
-
-    public boolean enableDataConnectivity() {
-        return false;
-    }
-
-    public boolean disableDataConnectivity() {
-        return false;
-    }
-
-    public boolean isDataConnectivityPossible() {
-        return false;
-    }
-
-    boolean updateCurrentCarrierInProvider() {
-        return false;
-    }
-
-    public void saveClirSetting(int commandInterfaceCLIRMode) {
-    }
-
-    public PhoneSubInfo getPhoneSubInfo(){
-        return null;
-    }
-
-    public IccSmsInterfaceManager getIccSmsInterfaceManager(){
-        return null;
-    }
-
-    public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(){
-        return null;
-    }
-
-    public IccFileHandler getIccFileHandler(){
-        return null;
-    }
-
-    public void activateCellBroadcastSms(int activate, Message response) {
-        Log.e(LOG_TAG, "Error! This functionality is not implemented for SIP.");
-    }
-
-    public void getCellBroadcastSmsConfig(Message response) {
-        Log.e(LOG_TAG, "Error! This functionality is not implemented for SIP.");
-    }
-
-    public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response){
-        Log.e(LOG_TAG, "Error! This functionality is not implemented for SIP.");
-    }
-
-    //@Override
-    public boolean needsOtaServiceProvisioning() {
-        // FIXME: what's this for SIP?
-        return false;
-    }
-
-    //@Override
-    public LinkProperties getLinkProperties(String apnType) {
-        // FIXME: what's this for SIP?
-        return null;
-    }
-
-    void updatePhoneState() {
-        State oldState = state;
-
-        if (getRingingCall().isRinging()) {
-            state = State.RINGING;
-        } else if (getForegroundCall().isIdle()
-                && getBackgroundCall().isIdle()) {
-            state = State.IDLE;
-        } else {
-            state = State.OFFHOOK;
-        }
-
-        if (state != oldState) {
-            Log.d(LOG_TAG, " ^^^ new phone state: " + state);
-            notifyPhoneStateChanged();
-        }
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhoneFactory.java b/telephony/java/com/android/internal/telephony/sip/SipPhoneFactory.java
deleted file mode 100644
index 611e3ea..0000000
--- a/telephony/java/com/android/internal/telephony/sip/SipPhoneFactory.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2010 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.internal.telephony.sip;
-
-import com.android.internal.telephony.PhoneNotifier;
-
-import android.content.Context;
-import android.net.sip.SipProfile;
-import android.util.Log;
-
-import java.text.ParseException;
-
-/**
- * {@hide}
- */
-public class SipPhoneFactory {
-    /**
-     * Makes a {@link SipPhone} object.
-     * @param sipUri the local SIP URI the phone runs on
-     * @param context {@code Context} needed to create a Phone object
-     * @param phoneNotifier {@code PhoneNotifier} needed to create a Phone
-     *      object
-     * @return the {@code SipPhone} object or null if the SIP URI is not valid
-     */
-    public static SipPhone makePhone(String sipUri, Context context,
-            PhoneNotifier phoneNotifier) {
-        try {
-            SipProfile profile = new SipProfile.Builder(sipUri).build();
-            return new SipPhone(context, phoneNotifier, profile);
-        } catch (ParseException e) {
-            Log.w("SipPhoneFactory", "makePhone", e);
-            return null;
-        }
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/test/ModelInterpreter.java b/telephony/java/com/android/internal/telephony/test/ModelInterpreter.java
deleted file mode 100644
index b116c35..0000000
--- a/telephony/java/com/android/internal/telephony/test/ModelInterpreter.java
+++ /dev/null
@@ -1,741 +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.internal.telephony.test;
-
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.List;
-
-// Also in ATChannel.java
-class LineReader
-{
-    /**
-     * Not threadsafe
-     * Assumes input is ASCII
-     */
-
-    //***** Constants
-
-    // For what it's worth, this is also the size of an
-    // OMAP CSMI mailbox
-    static final int BUFFER_SIZE = 0x1000;
-
-    // just to prevent constant allocations
-    byte buffer[] = new byte[BUFFER_SIZE];
-
-    //***** Instance Variables
-
-    InputStream inStream;
-
-    LineReader (InputStream s)
-    {
-        inStream = s;
-    }
-
-    String
-    getNextLine()
-    {
-        return getNextLine(false);
-    }
-
-    String
-    getNextLineCtrlZ()
-    {
-        return getNextLine(true);
-    }
-
-    /**
-     * Note: doesn't return the last incomplete line read on EOF, since
-     * it doesn't typically matter anyway
-     *
-     * Returns NULL on EOF
-     */
-
-    String
-    getNextLine(boolean ctrlZ)
-    {
-        int i = 0;
-
-        try {
-            for (;;) {
-                int result;
-
-                result = inStream.read();
-
-                if (result < 0) {
-                    return null;
-                }
-
-                if (ctrlZ && result == 0x1a) {
-                    break;
-                } else if (result == '\r' || result == '\n') {
-                    if (i == 0) {
-                        // Skip leading cr/lf
-                        continue;
-                    } else {
-                        break;
-                    }
-                }
-
-                buffer[i++] = (byte)result;
-            }
-        } catch (IOException ex) {
-            return null;
-        } catch (IndexOutOfBoundsException ex) {
-            System.err.println("ATChannel: buffer overflow");
-        }
-
-        try {
-            return new String(buffer, 0, i, "US-ASCII");
-        } catch (UnsupportedEncodingException ex) {
-            System.err.println("ATChannel: implausable UnsupportedEncodingException");
-            return null;
-        }
-    }
-}
-
-
-
-class InterpreterEx extends Exception
-{
-    public
-    InterpreterEx (String result)
-    {
-        this.result = result;
-    }
-
-    String result;
-}
-
-public class ModelInterpreter
-            implements Runnable, SimulatedRadioControl
-{
-    static final int MAX_CALLS = 6;
-
-    /** number of msec between dialing -> alerting and alerting->active */
-    static final int CONNECTING_PAUSE_MSEC = 5 * 100;
-
-    static final String LOG_TAG = "ModelInterpreter";
-
-    //***** Instance Variables
-
-    InputStream in;
-    OutputStream out;
-    LineReader lineReader;
-    ServerSocket ss;
-
-    private String finalResponse;
-
-    SimulatedGsmCallState simulatedCallState;
-
-    HandlerThread mHandlerThread;
-
-    int pausedResponseCount;
-    Object pausedResponseMonitor = new Object();
-
-    //***** Events
-
-    static final int PROGRESS_CALL_STATE        = 1;
-
-    //***** Constructor
-
-    public
-    ModelInterpreter (InputStream in, OutputStream out)
-    {
-        this.in = in;
-        this.out = out;
-
-        init();
-    }
-
-    public
-    ModelInterpreter (InetSocketAddress sa) throws java.io.IOException
-    {
-        ss = new ServerSocket();
-
-        ss.setReuseAddress(true);
-        ss.bind(sa);
-
-        init();
-    }
-
-    private void
-    init()
-    {
-        new Thread(this, "ModelInterpreter").start();
-        mHandlerThread = new HandlerThread("ModelInterpreter");
-        mHandlerThread.start();
-        Looper looper = mHandlerThread.getLooper();
-        simulatedCallState = new SimulatedGsmCallState(looper);
-    }
-
-    //***** Runnable Implementation
-
-    public void run()
-    {
-        for (;;) {
-            if (ss != null) {
-                Socket s;
-
-                try {
-                    s = ss.accept();
-                } catch (java.io.IOException ex) {
-                    Log.w(LOG_TAG,
-                        "IOException on socket.accept(); stopping", ex);
-                    return;
-                }
-
-                try {
-                    in = s.getInputStream();
-                    out = s.getOutputStream();
-                } catch (java.io.IOException ex) {
-                    Log.w(LOG_TAG,
-                        "IOException on accepted socket(); re-listening", ex);
-                    continue;
-                }
-
-                Log.i(LOG_TAG, "New connection accepted");
-            }
-
-
-            lineReader = new LineReader (in);
-
-            println ("Welcome");
-
-            for (;;) {
-                String line;
-
-                line = lineReader.getNextLine();
-
-                //System.out.println("MI<< " + line);
-
-                if (line == null) {
-                    break;
-                }
-
-                synchronized(pausedResponseMonitor) {
-                    while (pausedResponseCount > 0) {
-                        try {
-                            pausedResponseMonitor.wait();
-                        } catch (InterruptedException ex) {
-                        }
-                    }
-                }
-
-                synchronized (this) {
-                    try {
-                        finalResponse = "OK";
-                        processLine(line);
-                        println(finalResponse);
-                    } catch (InterpreterEx ex) {
-                        println(ex.result);
-                    } catch (RuntimeException ex) {
-                        ex.printStackTrace();
-                        println("ERROR");
-                    }
-                }
-            }
-
-            Log.i(LOG_TAG, "Disconnected");
-
-            if (ss == null) {
-                // no reconnect in this case
-                break;
-            }
-        }
-    }
-
-
-    //***** Instance Methods
-
-    /** Start the simulated phone ringing */
-    public void
-    triggerRing(String number)
-    {
-        synchronized (this) {
-            boolean success;
-
-            success = simulatedCallState.triggerRing(number);
-
-            if (success) {
-                println ("RING");
-            }
-        }
-    }
-
-    /** If a call is DIALING or ALERTING, progress it to the next state */
-    public void
-    progressConnectingCallState()
-    {
-        simulatedCallState.progressConnectingCallState();
-    }
-
-
-    /** If a call is DIALING or ALERTING, progress it all the way to ACTIVE */
-    public void
-    progressConnectingToActive()
-    {
-        simulatedCallState.progressConnectingToActive();
-    }
-
-    /** automatically progress mobile originated calls to ACTIVE.
-     *  default to true
-     */
-    public void
-    setAutoProgressConnectingCall(boolean b)
-    {
-        simulatedCallState.setAutoProgressConnectingCall(b);
-    }
-
-    public void
-    setNextDialFailImmediately(boolean b)
-    {
-        simulatedCallState.setNextDialFailImmediately(b);
-    }
-
-    public void setNextCallFailCause(int gsmCause)
-    {
-        //FIXME implement
-    }
-
-
-    /** hangup ringing, dialing, or actuve calls */
-    public void
-    triggerHangupForeground()
-    {
-        boolean success;
-
-        success = simulatedCallState.triggerHangupForeground();
-
-        if (success) {
-            println ("NO CARRIER");
-        }
-    }
-
-    /** hangup holding calls */
-    public void
-    triggerHangupBackground()
-    {
-        boolean success;
-
-        success = simulatedCallState.triggerHangupBackground();
-
-        if (success) {
-            println ("NO CARRIER");
-        }
-    }
-
-    /** hangup all */
-
-    public void
-    triggerHangupAll()
-    {
-        boolean success;
-
-        success = simulatedCallState.triggerHangupAll();
-
-        if (success) {
-            println ("NO CARRIER");
-        }
-    }
-
-    public void
-    sendUnsolicited (String unsol)
-    {
-        synchronized (this) {
-            println(unsol);
-        }
-    }
-
-    public void triggerSsn(int a, int b) {}
-    public void triggerIncomingUssd(String statusCode, String message) {}
-
-    public void
-    triggerIncomingSMS(String message)
-    {
-/**************
-        StringBuilder pdu = new StringBuilder();
-
-        pdu.append ("00");      //SMSC address - 0 bytes
-
-        pdu.append ("04");      // Message type indicator
-
-        // source address: +18005551212
-        pdu.append("918100551521F0");
-
-        // protocol ID and data coding scheme
-        pdu.append("0000");
-
-        Calendar c = Calendar.getInstance();
-
-        pdu.append (c.
-
-
-
-        synchronized (this) {
-            println("+CMT: ,1\r" + pdu.toString());
-        }
-
-**************/
-    }
-
-    public void
-    pauseResponses()
-    {
-        synchronized(pausedResponseMonitor) {
-            pausedResponseCount++;
-        }
-    }
-
-    public void
-    resumeResponses()
-    {
-        synchronized(pausedResponseMonitor) {
-            pausedResponseCount--;
-
-            if (pausedResponseCount == 0) {
-                pausedResponseMonitor.notifyAll();
-            }
-        }
-    }
-
-    //***** Private Instance Methods
-
-    private void
-    onAnswer() throws InterpreterEx
-    {
-        boolean success;
-
-        success = simulatedCallState.onAnswer();
-
-        if (!success) {
-            throw new InterpreterEx("ERROR");
-        }
-    }
-
-    private void
-    onHangup() throws InterpreterEx
-    {
-        boolean success = false;
-
-        success = simulatedCallState.onAnswer();
-
-        if (!success) {
-            throw new InterpreterEx("ERROR");
-        }
-
-        finalResponse = "NO CARRIER";
-    }
-
-    private void
-    onCHLD(String command) throws InterpreterEx
-    {
-        // command starts with "+CHLD="
-        char c0;
-        char c1 = 0;
-        boolean success;
-
-        c0 = command.charAt(6);
-
-        if (command.length() >= 8) {
-            c1 = command.charAt(7);
-        }
-
-        success = simulatedCallState.onChld(c0, c1);
-
-        if (!success) {
-            throw new InterpreterEx("ERROR");
-        }
-    }
-
-    private void
-    releaseHeldOrUDUB() throws InterpreterEx
-    {
-        boolean success;
-
-        success = simulatedCallState.releaseHeldOrUDUB();
-
-        if (!success) {
-            throw new InterpreterEx("ERROR");
-        }
-    }
-
-    private void
-    releaseActiveAcceptHeldOrWaiting() throws InterpreterEx
-    {
-        boolean success;
-
-        success = simulatedCallState.releaseActiveAcceptHeldOrWaiting();
-
-        if (!success) {
-            throw new InterpreterEx("ERROR");
-        }
-    }
-
-    private void
-    switchActiveAndHeldOrWaiting() throws InterpreterEx
-    {
-        boolean success;
-
-        success = simulatedCallState.switchActiveAndHeldOrWaiting();
-
-        if (!success) {
-            throw new InterpreterEx("ERROR");
-        }
-    }
-
-    private void
-    separateCall(int index) throws InterpreterEx
-    {
-        boolean success;
-
-        success = simulatedCallState.separateCall(index);
-
-        if (!success) {
-            throw new InterpreterEx("ERROR");
-        }
-    }
-
-    private void
-    conference() throws InterpreterEx
-    {
-        boolean success;
-
-        success = simulatedCallState.conference();
-
-        if (!success) {
-            throw new InterpreterEx("ERROR");
-        }
-    }
-
-    private void
-    onDial(String command) throws InterpreterEx
-    {
-        boolean success;
-
-        success = simulatedCallState.onDial(command.substring(1));
-
-        if (!success) {
-            throw new InterpreterEx("ERROR");
-        }
-    }
-
-    private void
-    onCLCC() throws InterpreterEx
-    {
-        List<String> lines;
-
-        lines = simulatedCallState.getClccLines();
-
-        for (int i = 0, s = lines.size() ; i < s ; i++) {
-            println (lines.get(i));
-        }
-    }
-
-    private void
-    onSMSSend(String command) throws InterpreterEx
-    {
-        String pdu;
-
-        print ("> ");
-        pdu = lineReader.getNextLineCtrlZ();
-
-        println("+CMGS: 1");
-    }
-
-    void
-    processLine (String line) throws InterpreterEx
-    {
-        String[] commands;
-
-        commands = splitCommands(line);
-
-        for (int i = 0; i < commands.length ; i++) {
-            String command = commands[i];
-
-            if (command.equals("A")) {
-                onAnswer();
-            } else if (command.equals("H")) {
-                onHangup();
-            } else if (command.startsWith("+CHLD=")) {
-                onCHLD(command);
-            } else if (command.equals("+CLCC")) {
-                onCLCC();
-            } else if (command.startsWith("D")) {
-                onDial(command);
-            } else if (command.startsWith("+CMGS=")) {
-                onSMSSend(command);
-            } else {
-                boolean found = false;
-
-                for (int j = 0; j < sDefaultResponses.length ; j++) {
-                    if (command.equals(sDefaultResponses[j][0])) {
-                        String r = sDefaultResponses[j][1];
-                        if (r != null) {
-                            println(r);
-                        }
-                        found = true;
-                        break;
-                    }
-                }
-
-                if (!found) {
-                    throw new InterpreterEx ("ERROR");
-                }
-            }
-        }
-    }
-
-
-    String[]
-    splitCommands(String line) throws InterpreterEx
-    {
-        if (!line.startsWith ("AT")) {
-            throw new InterpreterEx("ERROR");
-        }
-
-        if (line.length() == 2) {
-            // Just AT by itself
-            return new String[0];
-        }
-
-        String ret[] = new String[1];
-
-        //TODO fix case here too
-        ret[0] = line.substring(2);
-
-        return ret;
-/****
-        try {
-            // i = 2 to skip over AT
-            for (int i = 2, s = line.length() ; i < s ; i++) {
-                // r"|([A-RT-Z]\d?)" # Normal commands eg ATA or I0
-                // r"|(&[A-Z]\d*)" # & commands eg &C
-                // r"|(S\d+(=\d+)?)" # S registers
-                // r"((\+|%)\w+(\?|=([^;]+(;|$)))?)" # extended command eg +CREG=2
-
-
-            }
-        } catch (StringIndexOutOfBoundsException ex) {
-            throw new InterpreterEx ("ERROR");
-        }
-***/
-    }
-
-    void
-    println (String s)
-    {
-        synchronized(this) {
-            try {
-                byte[] bytes =  s.getBytes("US-ASCII");
-
-                //System.out.println("MI>> " + s);
-
-                out.write(bytes);
-                out.write('\r');
-            } catch (IOException ex) {
-                ex.printStackTrace();
-            }
-        }
-    }
-
-    void
-    print (String s)
-    {
-        synchronized(this) {
-            try {
-                byte[] bytes =  s.getBytes("US-ASCII");
-
-                //System.out.println("MI>> " + s + " (no <cr>)");
-
-                out.write(bytes);
-            } catch (IOException ex) {
-                ex.printStackTrace();
-            }
-        }
-    }
-
-
-    public void
-    shutdown()
-    {
-        Looper looper = mHandlerThread.getLooper();
-        if (looper != null) {
-            looper.quit();
-        }
-
-        try {
-            in.close();
-        } catch (IOException ex) {
-        }
-        try {
-            out.close();
-        } catch (IOException ex) {
-        }
-    }
-
-
-    static final String [][] sDefaultResponses = {
-        {"E0Q0V1",   null},
-        {"+CMEE=2",  null},
-        {"+CREG=2",  null},
-        {"+CGREG=2", null},
-        {"+CCWA=1",  null},
-        {"+COPS=0",  null},
-        {"+CFUN=1",  null},
-        {"+CGMI",    "+CGMI: Android Model AT Interpreter\r"},
-        {"+CGMM",    "+CGMM: Android Model AT Interpreter\r"},
-        {"+CGMR",    "+CGMR: 1.0\r"},
-        {"+CGSN",    "000000000000000\r"},
-        {"+CIMI",    "320720000000000\r"},
-        {"+CSCS=?",  "+CSCS: (\"HEX\",\"UCS2\")\r"},
-        {"+CFUN?",   "+CFUN: 1\r"},
-        {"+COPS=3,0;+COPS?;+COPS=3,1;+COPS?;+COPS=3,2;+COPS?",
-                "+COPS: 0,0,\"Android\"\r"
-                + "+COPS: 0,1,\"Android\"\r"
-                + "+COPS: 0,2,\"310995\"\r"},
-        {"+CREG?",   "+CREG: 2,5, \"0113\", \"6614\"\r"},
-        {"+CGREG?",  "+CGREG: 2,0\r"},
-        {"+CSQ",     "+CSQ: 16,99\r"},
-        {"+CNMI?",   "+CNMI: 1,2,2,1,1\r"},
-        {"+CLIR?",   "+CLIR: 1,3\r"},
-        {"%CPVWI=2", "%CPVWI: 0\r"},
-        {"+CUSD=1,\"#646#\"",  "+CUSD=0,\"You have used 23 minutes\"\r"},
-        {"+CRSM=176,12258,0,0,10", "+CRSM: 144,0,981062200050259429F6\r"},
-        {"+CRSM=192,12258,0,0,15", "+CRSM: 144,0,0000000A2FE204000FF55501020000\r"},
-
-        /* EF[ADN] */
-        {"+CRSM=192,28474,0,0,15", "+CRSM: 144,0,0000005a6f3a040011f5220102011e\r"},
-        {"+CRSM=178,28474,1,4,30", "+CRSM: 144,0,437573746f6d65722043617265ffffff07818100398799f7ffffffffffff\r"},
-        {"+CRSM=178,28474,2,4,30", "+CRSM: 144,0,566f696365204d61696cffffffffffff07918150367742f3ffffffffffff\r"},
-        {"+CRSM=178,28474,3,4,30", "+CRSM: 144,0,4164676a6dffffffffffffffffffffff0b918188551512c221436587ff01\r"},
-        {"+CRSM=178,28474,4,4,30", "+CRSM: 144,0,810101c1ffffffffffffffffffffffff068114455245f8ffffffffffffff\r"},
-        /* EF[EXT1] */
-        {"+CRSM=192,28490,0,0,15", "+CRSM: 144,0,000000416f4a040011f5550102010d\r"},
-        {"+CRSM=178,28490,1,4,13", "+CRSM: 144,0,0206092143658709ffffffffff\r"}
-    };
-}
diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
deleted file mode 100644
index 4f61509..0000000
--- a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
+++ /dev/null
@@ -1,1525 +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.internal.telephony.test;
-
-import android.os.AsyncResult;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-import com.android.internal.telephony.BaseCommands;
-import com.android.internal.telephony.CommandException;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.DataCallState;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.UUSInfo;
-import com.android.internal.telephony.gsm.CallFailCause;
-import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
-import com.android.internal.telephony.gsm.SuppServiceNotification;
-
-import java.util.ArrayList;
-
-public final class SimulatedCommands extends BaseCommands
-        implements CommandsInterface, SimulatedRadioControl {
-    private final static String LOG_TAG = "SIM";
-
-    private enum SimLockState {
-        NONE,
-        REQUIRE_PIN,
-        REQUIRE_PUK,
-        SIM_PERM_LOCKED
-    }
-
-    private enum SimFdnState {
-        NONE,
-        REQUIRE_PIN2,
-        REQUIRE_PUK2,
-        SIM_PERM_LOCKED
-    }
-
-    private final static SimLockState INITIAL_LOCK_STATE = SimLockState.NONE;
-    private final static String DEFAULT_SIM_PIN_CODE = "1234";
-    private final static String SIM_PUK_CODE = "12345678";
-    private final static SimFdnState INITIAL_FDN_STATE = SimFdnState.NONE;
-    private final static String DEFAULT_SIM_PIN2_CODE = "5678";
-    private final static String SIM_PUK2_CODE = "87654321";
-
-    //***** Instance Variables
-
-    SimulatedGsmCallState simulatedCallState;
-    HandlerThread mHandlerThread;
-    SimLockState mSimLockedState;
-    boolean mSimLockEnabled;
-    int mPinUnlockAttempts;
-    int mPukUnlockAttempts;
-    String mPinCode;
-    SimFdnState mSimFdnEnabledState;
-    boolean mSimFdnEnabled;
-    int mPin2UnlockAttempts;
-    int mPuk2UnlockAttempts;
-    int mNetworkType;
-    String mPin2Code;
-    boolean mSsnNotifyOn = false;
-
-    int pausedResponseCount;
-    ArrayList<Message> pausedResponses = new ArrayList<Message>();
-
-    int nextCallFailCause = CallFailCause.NORMAL_CLEARING;
-
-    //***** Constructor
-
-    public
-    SimulatedCommands() {
-        super(null);  // Don't log statistics
-        mHandlerThread = new HandlerThread("SimulatedCommands");
-        mHandlerThread.start();
-        Looper looper = mHandlerThread.getLooper();
-
-        simulatedCallState = new SimulatedGsmCallState(looper);
-
-        setRadioState(RadioState.RADIO_OFF);
-        mSimLockedState = INITIAL_LOCK_STATE;
-        mSimLockEnabled = (mSimLockedState != SimLockState.NONE);
-        mPinCode = DEFAULT_SIM_PIN_CODE;
-        mSimFdnEnabledState = INITIAL_FDN_STATE;
-        mSimFdnEnabled = (mSimFdnEnabledState != SimFdnState.NONE);
-        mPin2Code = DEFAULT_SIM_PIN2_CODE;
-    }
-
-    //***** CommandsInterface implementation
-
-    public void getIccCardStatus(Message result) {
-        unimplemented(result);
-    }
-
-    public void supplyIccPin(String pin, Message result)  {
-        if (mSimLockedState != SimLockState.REQUIRE_PIN) {
-            Log.i(LOG_TAG, "[SimCmd] supplyIccPin: wrong state, state=" +
-                    mSimLockedState);
-            CommandException ex = new CommandException(
-                    CommandException.Error.PASSWORD_INCORRECT);
-            AsyncResult.forMessage(result, null, ex);
-            result.sendToTarget();
-            return;
-        }
-
-        if (pin != null && pin.equals(mPinCode)) {
-            Log.i(LOG_TAG, "[SimCmd] supplyIccPin: success!");
-            mPinUnlockAttempts = 0;
-            mSimLockedState = SimLockState.NONE;
-            mIccStatusChangedRegistrants.notifyRegistrants();
-
-            if (result != null) {
-                AsyncResult.forMessage(result, null, null);
-                result.sendToTarget();
-            }
-
-            return;
-        }
-
-        if (result != null) {
-            mPinUnlockAttempts ++;
-
-            Log.i(LOG_TAG, "[SimCmd] supplyIccPin: failed! attempt=" +
-                    mPinUnlockAttempts);
-            if (mPinUnlockAttempts >= 3) {
-                Log.i(LOG_TAG, "[SimCmd] supplyIccPin: set state to REQUIRE_PUK");
-                mSimLockedState = SimLockState.REQUIRE_PUK;
-            }
-
-            CommandException ex = new CommandException(
-                    CommandException.Error.PASSWORD_INCORRECT);
-            AsyncResult.forMessage(result, null, ex);
-            result.sendToTarget();
-        }
-    }
-
-    public void supplyIccPuk(String puk, String newPin, Message result)  {
-        if (mSimLockedState != SimLockState.REQUIRE_PUK) {
-            Log.i(LOG_TAG, "[SimCmd] supplyIccPuk: wrong state, state=" +
-                    mSimLockedState);
-            CommandException ex = new CommandException(
-                    CommandException.Error.PASSWORD_INCORRECT);
-            AsyncResult.forMessage(result, null, ex);
-            result.sendToTarget();
-            return;
-        }
-
-        if (puk != null && puk.equals(SIM_PUK_CODE)) {
-            Log.i(LOG_TAG, "[SimCmd] supplyIccPuk: success!");
-            mSimLockedState = SimLockState.NONE;
-            mPukUnlockAttempts = 0;
-            mIccStatusChangedRegistrants.notifyRegistrants();
-
-            if (result != null) {
-                AsyncResult.forMessage(result, null, null);
-                result.sendToTarget();
-            }
-
-            return;
-        }
-
-        if (result != null) {
-            mPukUnlockAttempts ++;
-
-            Log.i(LOG_TAG, "[SimCmd] supplyIccPuk: failed! attempt=" +
-                    mPukUnlockAttempts);
-            if (mPukUnlockAttempts >= 10) {
-                Log.i(LOG_TAG, "[SimCmd] supplyIccPuk: set state to SIM_PERM_LOCKED");
-                mSimLockedState = SimLockState.SIM_PERM_LOCKED;
-            }
-
-            CommandException ex = new CommandException(
-                    CommandException.Error.PASSWORD_INCORRECT);
-            AsyncResult.forMessage(result, null, ex);
-            result.sendToTarget();
-        }
-    }
-
-    public void supplyIccPin2(String pin2, Message result)  {
-        if (mSimFdnEnabledState != SimFdnState.REQUIRE_PIN2) {
-            Log.i(LOG_TAG, "[SimCmd] supplyIccPin2: wrong state, state=" +
-                    mSimFdnEnabledState);
-            CommandException ex = new CommandException(
-                    CommandException.Error.PASSWORD_INCORRECT);
-            AsyncResult.forMessage(result, null, ex);
-            result.sendToTarget();
-            return;
-        }
-
-        if (pin2 != null && pin2.equals(mPin2Code)) {
-            Log.i(LOG_TAG, "[SimCmd] supplyIccPin2: success!");
-            mPin2UnlockAttempts = 0;
-            mSimFdnEnabledState = SimFdnState.NONE;
-
-            if (result != null) {
-                AsyncResult.forMessage(result, null, null);
-                result.sendToTarget();
-            }
-
-            return;
-        }
-
-        if (result != null) {
-            mPin2UnlockAttempts ++;
-
-            Log.i(LOG_TAG, "[SimCmd] supplyIccPin2: failed! attempt=" +
-                    mPin2UnlockAttempts);
-            if (mPin2UnlockAttempts >= 3) {
-                Log.i(LOG_TAG, "[SimCmd] supplyIccPin2: set state to REQUIRE_PUK2");
-                mSimFdnEnabledState = SimFdnState.REQUIRE_PUK2;
-            }
-
-            CommandException ex = new CommandException(
-                    CommandException.Error.PASSWORD_INCORRECT);
-            AsyncResult.forMessage(result, null, ex);
-            result.sendToTarget();
-        }
-    }
-
-    public void supplyIccPuk2(String puk2, String newPin2, Message result)  {
-        if (mSimFdnEnabledState != SimFdnState.REQUIRE_PUK2) {
-            Log.i(LOG_TAG, "[SimCmd] supplyIccPuk2: wrong state, state=" +
-                    mSimLockedState);
-            CommandException ex = new CommandException(
-                    CommandException.Error.PASSWORD_INCORRECT);
-            AsyncResult.forMessage(result, null, ex);
-            result.sendToTarget();
-            return;
-        }
-
-        if (puk2 != null && puk2.equals(SIM_PUK2_CODE)) {
-            Log.i(LOG_TAG, "[SimCmd] supplyIccPuk2: success!");
-            mSimFdnEnabledState = SimFdnState.NONE;
-            mPuk2UnlockAttempts = 0;
-
-            if (result != null) {
-                AsyncResult.forMessage(result, null, null);
-                result.sendToTarget();
-            }
-
-            return;
-        }
-
-        if (result != null) {
-            mPuk2UnlockAttempts ++;
-
-            Log.i(LOG_TAG, "[SimCmd] supplyIccPuk2: failed! attempt=" +
-                    mPuk2UnlockAttempts);
-            if (mPuk2UnlockAttempts >= 10) {
-                Log.i(LOG_TAG, "[SimCmd] supplyIccPuk2: set state to SIM_PERM_LOCKED");
-                mSimFdnEnabledState = SimFdnState.SIM_PERM_LOCKED;
-            }
-
-            CommandException ex = new CommandException(
-                    CommandException.Error.PASSWORD_INCORRECT);
-            AsyncResult.forMessage(result, null, ex);
-            result.sendToTarget();
-        }
-    }
-
-    public void changeIccPin(String oldPin, String newPin, Message result)  {
-        if (oldPin != null && oldPin.equals(mPinCode)) {
-            mPinCode = newPin;
-            if (result != null) {
-                AsyncResult.forMessage(result, null, null);
-                result.sendToTarget();
-            }
-
-            return;
-        }
-
-        if (result != null) {
-            Log.i(LOG_TAG, "[SimCmd] changeIccPin: pin failed!");
-
-            CommandException ex = new CommandException(
-                    CommandException.Error.PASSWORD_INCORRECT);
-            AsyncResult.forMessage(result, null, ex);
-            result.sendToTarget();
-        }
-    }
-
-    public void changeIccPin2(String oldPin2, String newPin2, Message result)  {
-        if (oldPin2 != null && oldPin2.equals(mPin2Code)) {
-            mPin2Code = newPin2;
-            if (result != null) {
-                AsyncResult.forMessage(result, null, null);
-                result.sendToTarget();
-            }
-
-            return;
-        }
-
-        if (result != null) {
-            Log.i(LOG_TAG, "[SimCmd] changeIccPin2: pin2 failed!");
-
-            CommandException ex = new CommandException(
-                    CommandException.Error.PASSWORD_INCORRECT);
-            AsyncResult.forMessage(result, null, ex);
-            result.sendToTarget();
-        }
-    }
-
-    public void
-    changeBarringPassword(String facility, String oldPwd, String newPwd, Message result) {
-        unimplemented(result);
-    }
-
-    public void
-    setSuppServiceNotifications(boolean enable, Message result) {
-        resultSuccess(result, null);
-
-        if (enable && mSsnNotifyOn) {
-            Log.w(LOG_TAG, "Supp Service Notifications already enabled!");
-        }
-
-        mSsnNotifyOn = enable;
-    }
-
-    @Override
-    public void queryFacilityLock(String facility, String pin,
-                                   int serviceClass, Message result) {
-        queryFacilityLockForApp(facility, pin, serviceClass, null, result);
-    }
-
-    @Override
-    public void queryFacilityLockForApp(String facility, String pin, int serviceClass,
-            String appId, Message result) {
-        if (facility != null && facility.equals(CommandsInterface.CB_FACILITY_BA_SIM)) {
-            if (result != null) {
-                int[] r = new int[1];
-                r[0] = (mSimLockEnabled ? 1 : 0);
-                Log.i(LOG_TAG, "[SimCmd] queryFacilityLock: SIM is "
-                        + (r[0] == 0 ? "unlocked" : "locked"));
-                AsyncResult.forMessage(result, r, null);
-                result.sendToTarget();
-            }
-            return;
-        } else if (facility != null && facility.equals(CommandsInterface.CB_FACILITY_BA_FD)) {
-            if (result != null) {
-                int[] r = new int[1];
-                r[0] = (mSimFdnEnabled ? 1 : 0);
-                Log.i(LOG_TAG, "[SimCmd] queryFacilityLock: FDN is "
-                        + (r[0] == 0 ? "disabled" : "enabled"));
-                AsyncResult.forMessage(result, r, null);
-                result.sendToTarget();
-            }
-            return;
-        }
-
-        unimplemented(result);
-    }
-
-    @Override
-    public void setFacilityLock(String facility, boolean lockEnabled, String pin, int serviceClass,
-            Message result) {
-        setFacilityLockForApp(facility, lockEnabled, pin, serviceClass, null, result);
-    }
-
-    @Override
-    public void setFacilityLockForApp(String facility, boolean lockEnabled,
-                                 String pin, int serviceClass, String appId,
-                                 Message result) {
-        if (facility != null &&
-                facility.equals(CommandsInterface.CB_FACILITY_BA_SIM)) {
-            if (pin != null && pin.equals(mPinCode)) {
-                Log.i(LOG_TAG, "[SimCmd] setFacilityLock: pin is valid");
-                mSimLockEnabled = lockEnabled;
-
-                if (result != null) {
-                    AsyncResult.forMessage(result, null, null);
-                    result.sendToTarget();
-                }
-
-                return;
-            }
-
-            if (result != null) {
-                Log.i(LOG_TAG, "[SimCmd] setFacilityLock: pin failed!");
-
-                CommandException ex = new CommandException(
-                        CommandException.Error.GENERIC_FAILURE);
-                AsyncResult.forMessage(result, null, ex);
-                result.sendToTarget();
-            }
-
-            return;
-        }  else if (facility != null &&
-                facility.equals(CommandsInterface.CB_FACILITY_BA_FD)) {
-            if (pin != null && pin.equals(mPin2Code)) {
-                Log.i(LOG_TAG, "[SimCmd] setFacilityLock: pin2 is valid");
-                mSimFdnEnabled = lockEnabled;
-
-                if (result != null) {
-                    AsyncResult.forMessage(result, null, null);
-                    result.sendToTarget();
-                }
-
-                return;
-            }
-
-            if (result != null) {
-                Log.i(LOG_TAG, "[SimCmd] setFacilityLock: pin2 failed!");
-
-                CommandException ex = new CommandException(
-                        CommandException.Error.GENERIC_FAILURE);
-                AsyncResult.forMessage(result, null, ex);
-                result.sendToTarget();
-            }
-
-            return;
-        }
-
-        unimplemented(result);
-    }
-
-    public void supplyNetworkDepersonalization(String netpin, Message result)  {
-        unimplemented(result);
-    }
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the original value of result.obj
-     *  ar.result contains a List of DriverCall
-     *      The ar.result List is sorted by DriverCall.index
-     */
-    public void getCurrentCalls (Message result) {
-        if ((mState == RadioState.RADIO_ON) && !isSimLocked()) {
-            //Log.i("GSM", "[SimCmds] getCurrentCalls");
-            resultSuccess(result, simulatedCallState.getDriverCalls());
-        } else {
-            //Log.i("GSM", "[SimCmds] getCurrentCalls: RADIO_OFF or SIM not ready!");
-            resultFail(result,
-                new CommandException(
-                    CommandException.Error.RADIO_NOT_AVAILABLE));
-        }
-    }
-
-    /**
-     *  @deprecated
-     */
-    public void getPDPContextList(Message result) {
-        getDataCallList(result);
-    }
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the original value of result.obj
-     *  ar.result contains a List of DataCallState
-     */
-    public void getDataCallList(Message result) {
-        resultSuccess(result, new ArrayList<DataCallState>(0));
-    }
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the original value of result.obj
-     *  ar.result is null on success and failure
-     *
-     * CLIR_DEFAULT     == on "use subscription default value"
-     * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation)
-     * CLIR_INVOCATION  == on "CLIR invocation" (restrict CLI presentation)
-     */
-    public void dial (String address, int clirMode, Message result) {
-        simulatedCallState.onDial(address);
-
-        resultSuccess(result, null);
-    }
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the original value of result.obj
-     *  ar.result is null on success and failure
-     *
-     * CLIR_DEFAULT     == on "use subscription default value"
-     * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation)
-     * CLIR_INVOCATION  == on "CLIR invocation" (restrict CLI presentation)
-     */
-    public void dial(String address, int clirMode, UUSInfo uusInfo, Message result) {
-        simulatedCallState.onDial(address);
-
-        resultSuccess(result, null);
-    }
-
-    public void getIMSI(Message result) {
-        getIMSIForApp(null, result);
-    }
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the original value of result.obj
-     *  ar.result is String containing IMSI on success
-     */
-    public void getIMSIForApp(String aid, Message result) {
-        resultSuccess(result, "012345678901234");
-    }
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the original value of result.obj
-     *  ar.result is String containing IMEI on success
-     */
-    public void getIMEI(Message result) {
-        resultSuccess(result, "012345678901234");
-    }
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the original value of result.obj
-     *  ar.result is String containing IMEISV on success
-     */
-    public void getIMEISV(Message result) {
-        resultSuccess(result, "99");
-    }
-
-    /**
-     * Hang up one individual connection.
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the original value of result.obj
-     *  ar.result is null on success and failure
-     *
-     *  3GPP 22.030 6.5.5
-     *  "Releases a specific active call X"
-     */
-    public void hangupConnection (int gsmIndex, Message result) {
-        boolean success;
-
-        success = simulatedCallState.onChld('1', (char)('0'+gsmIndex));
-
-        if (!success){
-            Log.i("GSM", "[SimCmd] hangupConnection: resultFail");
-            resultFail(result, new RuntimeException("Hangup Error"));
-        } else {
-            Log.i("GSM", "[SimCmd] hangupConnection: resultSuccess");
-            resultSuccess(result, null);
-        }
-    }
-
-    /**
-     * 3GPP 22.030 6.5.5
-     *  "Releases all held calls or sets User Determined User Busy (UDUB)
-     *   for a waiting call."
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the original value of result.obj
-     *  ar.result is null on success and failure
-     */
-    public void hangupWaitingOrBackground (Message result) {
-        boolean success;
-
-        success = simulatedCallState.onChld('0', '\0');
-
-        if (!success){
-            resultFail(result, new RuntimeException("Hangup Error"));
-        } else {
-            resultSuccess(result, null);
-        }
-    }
-
-    /**
-     * 3GPP 22.030 6.5.5
-     * "Releases all active calls (if any exist) and accepts
-     *  the other (held or waiting) call."
-     *
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the original value of result.obj
-     *  ar.result is null on success and failure
-     */
-    public void hangupForegroundResumeBackground (Message result) {
-        boolean success;
-
-        success = simulatedCallState.onChld('1', '\0');
-
-        if (!success){
-            resultFail(result, new RuntimeException("Hangup Error"));
-        } else {
-            resultSuccess(result, null);
-        }
-    }
-
-    /**
-     * 3GPP 22.030 6.5.5
-     * "Places all active calls (if any exist) on hold and accepts
-     *  the other (held or waiting) call."
-     *
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the original value of result.obj
-     *  ar.result is null on success and failure
-     */
-    public void switchWaitingOrHoldingAndActive (Message result) {
-        boolean success;
-
-        success = simulatedCallState.onChld('2', '\0');
-
-        if (!success){
-            resultFail(result, new RuntimeException("Hangup Error"));
-        } else {
-            resultSuccess(result, null);
-        }
-    }
-
-    /**
-     * 3GPP 22.030 6.5.5
-     * "Adds a held call to the conversation"
-     *
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the original value of result.obj
-     *  ar.result is null on success and failure
-     */
-    public void conference (Message result) {
-        boolean success;
-
-        success = simulatedCallState.onChld('3', '\0');
-
-        if (!success){
-            resultFail(result, new RuntimeException("Hangup Error"));
-        } else {
-            resultSuccess(result, null);
-        }
-    }
-
-    /**
-     * 3GPP 22.030 6.5.5
-     * "Connects the two calls and disconnects the subscriber from both calls"
-     *
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the original value of result.obj
-     *  ar.result is null on success and failure
-     */
-    public void explicitCallTransfer (Message result) {
-        boolean success;
-
-        success = simulatedCallState.onChld('4', '\0');
-
-        if (!success){
-            resultFail(result, new RuntimeException("Hangup Error"));
-        } else {
-            resultSuccess(result, null);
-        }
-    }
-
-    /**
-     * 3GPP 22.030 6.5.5
-     * "Places all active calls on hold except call X with which
-     *  communication shall be supported."
-     */
-    public void separateConnection (int gsmIndex, Message result) {
-        boolean success;
-
-        char ch = (char)(gsmIndex + '0');
-        success = simulatedCallState.onChld('2', ch);
-
-        if (!success){
-            resultFail(result, new RuntimeException("Hangup Error"));
-        } else {
-            resultSuccess(result, null);
-        }
-    }
-
-    /**
-     *
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the original value of result.obj
-     *  ar.result is null on success and failure
-     */
-    public void acceptCall (Message result) {
-        boolean success;
-
-        success = simulatedCallState.onAnswer();
-
-        if (!success){
-            resultFail(result, new RuntimeException("Hangup Error"));
-        } else {
-            resultSuccess(result, null);
-        }
-    }
-
-    /**
-     *  also known as UDUB
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the original value of result.obj
-     *  ar.result is null on success and failure
-     */
-    public void rejectCall (Message result) {
-        boolean success;
-
-        success = simulatedCallState.onChld('0', '\0');
-
-        if (!success){
-            resultFail(result, new RuntimeException("Hangup Error"));
-        } else {
-            resultSuccess(result, null);
-        }
-    }
-
-    /**
-     * cause code returned as Integer in Message.obj.response
-     * Returns integer cause code defined in TS 24.008
-     * Annex H or closest approximation.
-     * Most significant codes:
-     * - Any defined in 22.001 F.4 (for generating busy/congestion)
-     * - Cause 68: ACM >= ACMMax
-     */
-    public void getLastCallFailCause (Message result) {
-        int[] ret = new int[1];
-
-        ret[0] = nextCallFailCause;
-        resultSuccess(result, ret);
-    }
-
-    /**
-     * @deprecated
-     */
-    public void getLastPdpFailCause (Message result) {
-        unimplemented(result);
-    }
-
-    public void getLastDataCallFailCause(Message result) {
-        //
-        unimplemented(result);
-    }
-
-    public void setMute (boolean enableMute, Message result) {unimplemented(result);}
-
-    public void getMute (Message result) {unimplemented(result);}
-
-    /**
-     * response.obj is an AsyncResult
-     * response.obj.result is an int[2]
-     * response.obj.result[0] is received signal strength (0-31, 99)
-     * response.obj.result[1] is  bit error rate (0-7, 99)
-     * as defined in TS 27.007 8.5
-     */
-    public void getSignalStrength (Message result) {
-        int ret[] = new int[2];
-
-        ret[0] = 23;
-        ret[1] = 0;
-
-        resultSuccess(result, ret);
-    }
-
-     /**
-     * Assign a specified band for RF configuration.
-     *
-     * @param bandMode one of BM_*_BAND
-     * @param result is callback message
-     */
-    public void setBandMode (int bandMode, Message result) {
-        resultSuccess(result, null);
-    }
-
-    /**
-     * Query the list of band mode supported by RF.
-     *
-     * @param result is callback message
-     *        ((AsyncResult)response.obj).result  is an int[] with every
-     *        element representing one available BM_*_BAND
-     */
-    public void queryAvailableBandMode (Message result) {
-        int ret[] = new int [4];
-
-        ret[0] = 4;
-        ret[1] = Phone.BM_US_BAND;
-        ret[2] = Phone.BM_JPN_BAND;
-        ret[3] = Phone.BM_AUS_BAND;
-
-        resultSuccess(result, ret);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void sendTerminalResponse(String contents, Message response) {
-        resultSuccess(response, null);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void sendEnvelope(String contents, Message response) {
-        resultSuccess(response, null);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void sendEnvelopeWithStatus(String contents, Message response) {
-        resultSuccess(response, null);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void handleCallSetupRequestFromSim(
-            boolean accept, Message response) {
-        resultSuccess(response, null);
-    }
-
-    /**
-     * response.obj.result is an String[14]
-     * See ril.h for details
-     *
-     * Please note that registration state 4 ("unknown") is treated
-     * as "out of service" above
-     */
-    public void getVoiceRegistrationState (Message result) {
-        String ret[] = new String[14];
-
-        ret[0] = "5"; // registered roam
-        ret[1] = null;
-        ret[2] = null;
-        ret[3] = null;
-        ret[4] = null;
-        ret[5] = null;
-        ret[6] = null;
-        ret[7] = null;
-        ret[8] = null;
-        ret[9] = null;
-        ret[10] = null;
-        ret[11] = null;
-        ret[12] = null;
-        ret[13] = null;
-
-        resultSuccess(result, ret);
-    }
-
-    /**
-     * response.obj.result is an String[4]
-     * response.obj.result[0] is registration state 0-5 from TS 27.007 7.2
-     * response.obj.result[1] is LAC if registered or NULL if not
-     * response.obj.result[2] is CID if registered or NULL if not
-     * response.obj.result[3] indicates the available radio technology, where:
-     *      0 == unknown
-     *      1 == GPRS only
-     *      2 == EDGE
-     *      3 == UMTS
-     *
-     * valid LAC are 0x0000 - 0xffff
-     * valid CID are 0x00000000 - 0xffffffff
-     *
-     * Please note that registration state 4 ("unknown") is treated
-     * as "out of service" in the Android telephony system
-     */
-    public void getDataRegistrationState (Message result) {
-        String ret[] = new String[4];
-
-        ret[0] = "5"; // registered roam
-        ret[1] = null;
-        ret[2] = null;
-        ret[3] = "2";
-
-        resultSuccess(result, ret);
-    }
-
-    /**
-     * response.obj.result is a String[3]
-     * response.obj.result[0] is long alpha or null if unregistered
-     * response.obj.result[1] is short alpha or null if unregistered
-     * response.obj.result[2] is numeric or null if unregistered
-     */
-    public void getOperator(Message result) {
-        String[] ret = new String[3];
-
-        ret[0] = "El Telco Loco";
-        ret[1] = "Telco Loco";
-        ret[2] = "001001";
-
-        resultSuccess(result, ret);
-    }
-
-    /**
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the original value of result.obj
-     *  ar.result is null on success and failure
-     */
-    public void sendDtmf(char c, Message result) {
-        resultSuccess(result, null);
-    }
-
-    /**
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the original value of result.obj
-     *  ar.result is null on success and failure
-     */
-    public void startDtmf(char c, Message result) {
-        resultSuccess(result, null);
-    }
-
-    /**
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the original value of result.obj
-     *  ar.result is null on success and failure
-     */
-    public void stopDtmf(Message result) {
-        resultSuccess(result, null);
-    }
-
-    /**
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the original value of result.obj
-     *  ar.result is null on success and failure
-     */
-    public void sendBurstDtmf(String dtmfString, int on, int off, Message result) {
-        resultSuccess(result, null);
-    }
-
-    /**
-     * smscPDU is smsc address in PDU form GSM BCD format prefixed
-     *      by a length byte (as expected by TS 27.005) or NULL for default SMSC
-     * pdu is SMS in PDU format as an ASCII hex string
-     *      less the SMSC address
-     */
-    public void sendSMS (String smscPDU, String pdu, Message result) {unimplemented(result);}
-
-    public void deleteSmsOnSim(int index, Message response) {
-        Log.d(LOG_TAG, "Delete message at index " + index);
-        unimplemented(response);
-    }
-
-    public void deleteSmsOnRuim(int index, Message response) {
-        Log.d(LOG_TAG, "Delete RUIM message at index " + index);
-        unimplemented(response);
-    }
-
-    public void writeSmsToSim(int status, String smsc, String pdu, Message response) {
-        Log.d(LOG_TAG, "Write SMS to SIM with status " + status);
-        unimplemented(response);
-    }
-
-    public void writeSmsToRuim(int status, String pdu, Message response) {
-        Log.d(LOG_TAG, "Write SMS to RUIM with status " + status);
-        unimplemented(response);
-    }
-
-    public void setupDataCall(String radioTechnology, String profile,
-            String apn, String user, String password, String authType,
-            String protocol, Message result) {
-        unimplemented(result);
-    }
-
-    public void deactivateDataCall(int cid, int reason, Message result) {unimplemented(result);}
-
-    public void setPreferredNetworkType(int networkType , Message result) {
-        mNetworkType = networkType;
-        resultSuccess(result, null);
-    }
-
-    public void getPreferredNetworkType(Message result) {
-        int ret[] = new int[1];
-
-        ret[0] = mNetworkType;
-        resultSuccess(result, ret);
-    }
-
-    public void getNeighboringCids(Message result) {
-        int ret[] = new int[7];
-
-        ret[0] = 6;
-        for (int i = 1; i<7; i++) {
-            ret[i] = i;
-        }
-        resultSuccess(result, ret);
-    }
-
-    public void setLocationUpdates(boolean enable, Message response) {
-        unimplemented(response);
-    }
-
-    public void getSmscAddress(Message result) {
-        unimplemented(result);
-    }
-
-    public void setSmscAddress(String address, Message result) {
-        unimplemented(result);
-    }
-
-    public void reportSmsMemoryStatus(boolean available, Message result) {
-        unimplemented(result);
-    }
-
-    public void reportStkServiceIsRunning(Message result) {
-        resultSuccess(result, null);
-    }
-
-    @Override
-    public void getCdmaSubscriptionSource(Message result) {
-        unimplemented(result);
-    }
-
-    private boolean isSimLocked() {
-        if (mSimLockedState != SimLockState.NONE) {
-            return true;
-        }
-        return false;
-    }
-
-    public void setRadioPower(boolean on, Message result) {
-        if(on) {
-            setRadioState(RadioState.RADIO_ON);
-        } else {
-            setRadioState(RadioState.RADIO_OFF);
-        }
-    }
-
-
-    public void acknowledgeLastIncomingGsmSms(boolean success, int cause, Message result) {
-        unimplemented(result);
-    }
-
-    public void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result) {
-        unimplemented(result);
-    }
-
-    public void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu,
-            Message result) {
-        unimplemented(result);
-    }
-
-    public void iccIO(int command, int fileid, String path, int p1, int p2, int p3, String data,
-            String pin2, Message response) {
-        iccIOForApp(command, fileid, path, p1, p2, p3, data,pin2, null, response);
-    }
-
-    /**
-     * parameters equivalent to 27.007 AT+CRSM command
-     * response.obj will be an AsyncResult
-     * response.obj.userObj will be a SimIoResult on success
-     */
-    public void iccIOForApp (int command, int fileid, String path, int p1, int p2,
-                       int p3, String data, String pin2, String aid, Message result) {
-        unimplemented(result);
-    }
-
-    /**
-     * (AsyncResult)response.obj).result is an int[] with element [0] set to
-     * 1 for "CLIP is provisioned", and 0 for "CLIP is not provisioned".
-     *
-     * @param response is callback message
-     */
-    public void queryCLIP(Message response) { unimplemented(response); }
-
-
-    /**
-     * response.obj will be a an int[2]
-     *
-     * response.obj[0] will be TS 27.007 +CLIR parameter 'n'
-     *  0 presentation indicator is used according to the subscription of the CLIR service
-     *  1 CLIR invocation
-     *  2 CLIR suppression
-     *
-     * response.obj[1] will be TS 27.007 +CLIR parameter 'm'
-     *  0 CLIR not provisioned
-     *  1 CLIR provisioned in permanent mode
-     *  2 unknown (e.g. no network, etc.)
-     *  3 CLIR temporary mode presentation restricted
-     *  4 CLIR temporary mode presentation allowed
-     */
-
-    public void getCLIR(Message result) {unimplemented(result);}
-
-    /**
-     * clirMode is one of the CLIR_* constants above
-     *
-     * response.obj is null
-     */
-
-    public void setCLIR(int clirMode, Message result) {unimplemented(result);}
-
-    /**
-     * (AsyncResult)response.obj).result is an int[] with element [0] set to
-     * 0 for disabled, 1 for enabled.
-     *
-     * @param serviceClass is a sum of SERVICE_CLASS_*
-     * @param response is callback message
-     */
-
-    public void queryCallWaiting(int serviceClass, Message response) {
-        unimplemented(response);
-    }
-
-    /**
-     * @param enable is true to enable, false to disable
-     * @param serviceClass is a sum of SERVICE_CLASS_*
-     * @param response is callback message
-     */
-
-    public void setCallWaiting(boolean enable, int serviceClass,
-            Message response) {
-        unimplemented(response);
-    }
-
-    /**
-     * @param action is one of CF_ACTION_*
-     * @param cfReason is one of CF_REASON_*
-     * @param serviceClass is a sum of SERVICE_CLASSS_*
-     */
-    public void setCallForward(int action, int cfReason, int serviceClass,
-            String number, int timeSeconds, Message result) {unimplemented(result);}
-
-    /**
-     * cfReason is one of CF_REASON_*
-     *
-     * ((AsyncResult)response.obj).result will be an array of
-     * CallForwardInfo's
-     *
-     * An array of length 0 means "disabled for all codes"
-     */
-    public void queryCallForwardStatus(int cfReason, int serviceClass,
-            String number, Message result) {unimplemented(result);}
-
-    public void setNetworkSelectionModeAutomatic(Message result) {unimplemented(result);}
-    public void exitEmergencyCallbackMode(Message result) {unimplemented(result);}
-    public void setNetworkSelectionModeManual(
-            String operatorNumeric, Message result) {unimplemented(result);}
-
-    /**
-     * Queries whether the current network selection mode is automatic
-     * or manual
-     *
-     * ((AsyncResult)response.obj).result  is an int[] with element [0] being
-     * a 0 for automatic selection and a 1 for manual selection
-     */
-
-    public void getNetworkSelectionMode(Message result) {
-        int ret[] = new int[1];
-
-        ret[0] = 0;
-        resultSuccess(result, ret);
-    }
-
-    /**
-     * Queries the currently available networks
-     *
-     * ((AsyncResult)response.obj).result  is a List of NetworkInfo objects
-     */
-    public void getAvailableNetworks(Message result) {unimplemented(result);}
-
-    public void getBasebandVersion (Message result) {
-        resultSuccess(result, "SimulatedCommands");
-    }
-
-    /**
-     * Simulates an incoming USSD message
-     * @param statusCode  Status code string. See <code>setOnUSSD</code>
-     * in CommandsInterface.java
-     * @param message Message text to send or null if none
-     */
-    public void triggerIncomingUssd(String statusCode, String message) {
-        if (mUSSDRegistrant != null) {
-            String[] result = {statusCode, message};
-            mUSSDRegistrant.notifyResult(result);
-        }
-    }
-
-
-    public void sendUSSD (String ussdString, Message result) {
-
-        // We simulate this particular sequence
-        if (ussdString.equals("#646#")) {
-            resultSuccess(result, null);
-
-            // 0 == USSD-Notify
-            triggerIncomingUssd("0", "You have NNN minutes remaining.");
-        } else {
-            resultSuccess(result, null);
-
-            triggerIncomingUssd("0", "All Done");
-        }
-    }
-
-    // inherited javadoc suffices
-    public void cancelPendingUssd (Message response) {
-        resultSuccess(response, null);
-    }
-
-
-    public void resetRadio(Message result) {
-        unimplemented(result);
-    }
-
-    public void invokeOemRilRequestRaw(byte[] data, Message response) {
-        // Just echo back data
-        if (response != null) {
-            AsyncResult.forMessage(response).result = data;
-            response.sendToTarget();
-        }
-    }
-
-    public void invokeOemRilRequestStrings(String[] strings, Message response) {
-        // Just echo back data
-        if (response != null) {
-            AsyncResult.forMessage(response).result = strings;
-            response.sendToTarget();
-        }
-    }
-
-    //***** SimulatedRadioControl
-
-
-    /** Start the simulated phone ringing */
-    public void
-    triggerRing(String number) {
-        simulatedCallState.triggerRing(number);
-        mCallStateRegistrants.notifyRegistrants();
-    }
-
-    public void
-    progressConnectingCallState() {
-        simulatedCallState.progressConnectingCallState();
-        mCallStateRegistrants.notifyRegistrants();
-    }
-
-    /** If a call is DIALING or ALERTING, progress it all the way to ACTIVE */
-    public void
-    progressConnectingToActive() {
-        simulatedCallState.progressConnectingToActive();
-        mCallStateRegistrants.notifyRegistrants();
-    }
-
-    /** automatically progress mobile originated calls to ACTIVE.
-     *  default to true
-     */
-    public void
-    setAutoProgressConnectingCall(boolean b) {
-        simulatedCallState.setAutoProgressConnectingCall(b);
-    }
-
-    public void
-    setNextDialFailImmediately(boolean b) {
-        simulatedCallState.setNextDialFailImmediately(b);
-    }
-
-    public void
-    setNextCallFailCause(int gsmCause) {
-        nextCallFailCause = gsmCause;
-    }
-
-    public void
-    triggerHangupForeground() {
-        simulatedCallState.triggerHangupForeground();
-        mCallStateRegistrants.notifyRegistrants();
-    }
-
-    /** hangup holding calls */
-    public void
-    triggerHangupBackground() {
-        simulatedCallState.triggerHangupBackground();
-        mCallStateRegistrants.notifyRegistrants();
-    }
-
-    public void triggerSsn(int type, int code) {
-        SuppServiceNotification not = new SuppServiceNotification();
-        not.notificationType = type;
-        not.code = code;
-        mSsnRegistrant.notifyRegistrant(new AsyncResult(null, not, null));
-    }
-
-    public void
-    shutdown() {
-        setRadioState(RadioState.RADIO_UNAVAILABLE);
-        Looper looper = mHandlerThread.getLooper();
-        if (looper != null) {
-            looper.quit();
-        }
-    }
-
-    /** hangup all */
-
-    public void
-    triggerHangupAll() {
-        simulatedCallState.triggerHangupAll();
-        mCallStateRegistrants.notifyRegistrants();
-    }
-
-    public void
-    triggerIncomingSMS(String message) {
-        //TODO
-    }
-
-    public void
-    pauseResponses() {
-        pausedResponseCount++;
-    }
-
-    public void
-    resumeResponses() {
-        pausedResponseCount--;
-
-        if (pausedResponseCount == 0) {
-            for (int i = 0, s = pausedResponses.size(); i < s ; i++) {
-                pausedResponses.get(i).sendToTarget();
-            }
-            pausedResponses.clear();
-        } else {
-            Log.e("GSM", "SimulatedCommands.resumeResponses < 0");
-        }
-    }
-
-    //***** Private Methods
-
-    private void unimplemented(Message result) {
-        if (result != null) {
-            AsyncResult.forMessage(result).exception
-                = new RuntimeException("Unimplemented");
-
-            if (pausedResponseCount > 0) {
-                pausedResponses.add(result);
-            } else {
-                result.sendToTarget();
-            }
-        }
-    }
-
-    private void resultSuccess(Message result, Object ret) {
-        if (result != null) {
-            AsyncResult.forMessage(result).result = ret;
-            if (pausedResponseCount > 0) {
-                pausedResponses.add(result);
-            } else {
-                result.sendToTarget();
-            }
-        }
-    }
-
-    private void resultFail(Message result, Throwable tr) {
-        if (result != null) {
-            AsyncResult.forMessage(result).exception = tr;
-            if (pausedResponseCount > 0) {
-                pausedResponses.add(result);
-            } else {
-                result.sendToTarget();
-            }
-        }
-    }
-
-    // ***** Methods for CDMA support
-    public void
-    getDeviceIdentity(Message response) {
-        Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
-        unimplemented(response);
-    }
-
-    public void
-    getCDMASubscription(Message response) {
-        Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
-        unimplemented(response);
-    }
-
-    public void
-    setCdmaSubscriptionSource(int cdmaSubscriptionType, Message response) {
-        Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
-        unimplemented(response);
-    }
-
-    public void queryCdmaRoamingPreference(Message response) {
-        Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
-        unimplemented(response);
-    }
-
-    public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
-        Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
-        unimplemented(response);
-    }
-
-    public void
-    setPhoneType(int phoneType) {
-        Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
-    }
-
-    public void getPreferredVoicePrivacy(Message result) {
-        Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
-        unimplemented(result);
-    }
-
-    public void setPreferredVoicePrivacy(boolean enable, Message result) {
-        Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
-        unimplemented(result);
-    }
-
-    /**
-     *  Set the TTY mode
-     *
-     * @param ttyMode is one of the following:
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
-     * @param response is callback message
-     */
-    public void setTTYMode(int ttyMode, Message response) {
-        Log.w(LOG_TAG, "Not implemented in SimulatedCommands");
-        unimplemented(response);
-    }
-
-    /**
-     *  Query the TTY mode
-     * (AsyncResult)response.obj).result is an int[] with element [0] set to
-     * tty mode:
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
-     * @param response is callback message
-     */
-    public void queryTTYMode(Message response) {
-        Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
-        unimplemented(response);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void sendCDMAFeatureCode(String FeatureCode, Message response) {
-        Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
-        unimplemented(response);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void sendCdmaSms(byte[] pdu, Message response){
-       Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
-    }
-
-    public void setCdmaBroadcastActivation(boolean activate, Message response) {
-        unimplemented(response);
-
-    }
-
-    public void getCdmaBroadcastConfig(Message response) {
-        unimplemented(response);
-
-    }
-
-    public void setCdmaBroadcastConfig(int[] configValuesArray, Message response) {
-        unimplemented(response);
-
-    }
-
-    public void forceDataDormancy(Message response) {
-        unimplemented(response);
-    }
-
-
-    public void setGsmBroadcastActivation(boolean activate, Message response) {
-        unimplemented(response);
-    }
-
-
-    public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response) {
-        unimplemented(response);
-    }
-
-    public void getGsmBroadcastConfig(Message response) {
-        unimplemented(response);
-    }
-
-    @Override
-    public void supplyIccPinForApp(String pin, String aid, Message response) {
-        unimplemented(response);
-    }
-
-    @Override
-    public void supplyIccPukForApp(String puk, String newPin, String aid, Message response) {
-        unimplemented(response);
-    }
-
-    @Override
-    public void supplyIccPin2ForApp(String pin2, String aid, Message response) {
-        unimplemented(response);
-    }
-
-    @Override
-    public void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message response) {
-        unimplemented(response);
-    }
-
-    @Override
-    public void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message response) {
-        unimplemented(response);
-    }
-
-    @Override
-    public void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr,
-            Message response) {
-        unimplemented(response);
-    }
-
-    public void requestIsimAuthentication(String nonce, Message response) {
-        unimplemented(response);
-    }
-
-    public void getVoiceRadioTechnology(Message response) {
-        unimplemented(response);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedGsmCallState.java b/telephony/java/com/android/internal/telephony/test/SimulatedGsmCallState.java
deleted file mode 100644
index c6c301d..0000000
--- a/telephony/java/com/android/internal/telephony/test/SimulatedGsmCallState.java
+++ /dev/null
@@ -1,809 +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.internal.telephony.test;
-
-import android.os.Looper;
-import android.os.Message;
-import android.os.Handler;
-import android.telephony.PhoneNumberUtils;
-import com.android.internal.telephony.ATParseEx;
-import com.android.internal.telephony.DriverCall;
-import java.util.List;
-import java.util.ArrayList;
-
-import android.util.Log;
-
-class CallInfo {
-    enum State {
-        ACTIVE(0),
-        HOLDING(1),
-        DIALING(2),    // MO call only
-        ALERTING(3),   // MO call only
-        INCOMING(4),   // MT call only
-        WAITING(5);    // MT call only
-
-        State (int value) {this.value = value;}
-
-        private final int value;
-        public int value() {return value;};
-    };
-
-    boolean isMT;
-    State state;
-    boolean isMpty;
-    String number;
-    int TOA;
-
-    CallInfo (boolean isMT, State state, boolean isMpty, String number) {
-        this.isMT = isMT;
-        this.state = state;
-        this.isMpty = isMpty;
-        this.number = number;
-
-        if (number.length() > 0 && number.charAt(0) == '+') {
-            TOA = PhoneNumberUtils.TOA_International;
-        } else {
-            TOA = PhoneNumberUtils.TOA_Unknown;
-        }
-    }
-
-    static CallInfo
-    createOutgoingCall(String number) {
-        return new CallInfo (false, State.DIALING, false, number);
-    }
-
-    static CallInfo
-    createIncomingCall(String number) {
-        return new CallInfo (true, State.INCOMING, false, number);
-    }
-
-    String
-    toCLCCLine(int index) {
-        return
-            "+CLCC: "
-            + index + "," + (isMT ? "1" : "0") +","
-            + state.value() + ",0," + (isMpty ? "1" : "0")
-            + ",\"" + number + "\"," + TOA;
-    }
-
-    DriverCall
-    toDriverCall(int index) {
-        DriverCall ret;
-
-        ret = new DriverCall();
-
-        ret.index = index;
-        ret.isMT = isMT;
-
-        try {
-            ret.state = DriverCall.stateFromCLCC(state.value());
-        } catch (ATParseEx ex) {
-            throw new RuntimeException("should never happen", ex);
-        }
-
-        ret.isMpty = isMpty;
-        ret.number = number;
-        ret.TOA = TOA;
-        ret.isVoice = true;
-        ret.als = 0;
-
-        return ret;
-    }
-
-
-    boolean
-    isActiveOrHeld() {
-        return state == State.ACTIVE || state == State.HOLDING;
-    }
-
-    boolean
-    isConnecting() {
-        return state == State.DIALING || state == State.ALERTING;
-    }
-
-    boolean
-    isRinging() {
-        return state == State.INCOMING || state == State.WAITING;
-    }
-
-}
-
-class InvalidStateEx extends Exception {
-    InvalidStateEx() {
-
-    }
-}
-
-
-class SimulatedGsmCallState extends Handler {
-    //***** Instance Variables
-
-    CallInfo calls[] = new CallInfo[MAX_CALLS];
-
-    private boolean autoProgressConnecting = true;
-    private boolean nextDialFailImmediately;
-
-
-    //***** Event Constants
-
-    static final int EVENT_PROGRESS_CALL_STATE = 1;
-
-    //***** Constants
-
-    static final int MAX_CALLS = 7;
-    /** number of msec between dialing -> alerting and alerting->active */
-    static final int CONNECTING_PAUSE_MSEC = 5 * 100;
-
-
-    //***** Overridden from Handler
-
-    public SimulatedGsmCallState(Looper looper) {
-        super(looper);
-    }
-
-    public void
-    handleMessage(Message msg) {
-        synchronized(this) { switch (msg.what) {
-            // PLEASE REMEMBER
-            // calls may have hung up by the time delayed events happen
-
-            case EVENT_PROGRESS_CALL_STATE:
-                progressConnectingCallState();
-            break;
-        }}
-    }
-
-    //***** Public Methods
-
-    /**
-     * Start the simulated phone ringing
-     * true if succeeded, false if failed
-     */
-    public boolean
-    triggerRing(String number) {
-        synchronized (this) {
-            int empty = -1;
-            boolean isCallWaiting = false;
-
-            // ensure there aren't already calls INCOMING or WAITING
-            for (int i = 0 ; i < calls.length ; i++) {
-                CallInfo call = calls[i];
-
-                if (call == null && empty < 0) {
-                    empty = i;
-                } else if (call != null
-                    && (call.state == CallInfo.State.INCOMING
-                        || call.state == CallInfo.State.WAITING)
-                ) {
-                    Log.w("ModelInterpreter",
-                        "triggerRing failed; phone already ringing");
-                    return false;
-                } else if (call != null) {
-                    isCallWaiting = true;
-                }
-            }
-
-            if (empty < 0 ) {
-                Log.w("ModelInterpreter", "triggerRing failed; all full");
-                return false;
-            }
-
-            calls[empty] = CallInfo.createIncomingCall(
-                PhoneNumberUtils.extractNetworkPortion(number));
-
-            if (isCallWaiting) {
-                calls[empty].state = CallInfo.State.WAITING;
-            }
-
-        }
-        return true;
-    }
-
-    /** If a call is DIALING or ALERTING, progress it to the next state */
-    public void
-    progressConnectingCallState() {
-        synchronized (this)  {
-            for (int i = 0 ; i < calls.length ; i++) {
-                CallInfo call = calls[i];
-
-                if (call != null && call.state == CallInfo.State.DIALING) {
-                    call.state = CallInfo.State.ALERTING;
-
-                    if (autoProgressConnecting) {
-                        sendMessageDelayed(
-                                obtainMessage(EVENT_PROGRESS_CALL_STATE, call),
-                                CONNECTING_PAUSE_MSEC);
-                    }
-                    break;
-                } else if (call != null
-                        && call.state == CallInfo.State.ALERTING
-                ) {
-                    call.state = CallInfo.State.ACTIVE;
-                    break;
-                }
-            }
-        }
-    }
-
-    /** If a call is DIALING or ALERTING, progress it all the way to ACTIVE */
-    public void
-    progressConnectingToActive() {
-        synchronized (this)  {
-            for (int i = 0 ; i < calls.length ; i++) {
-                CallInfo call = calls[i];
-
-                if (call != null && (call.state == CallInfo.State.DIALING
-                    || call.state == CallInfo.State.ALERTING)
-                ) {
-                    call.state = CallInfo.State.ACTIVE;
-                    break;
-                }
-            }
-        }
-    }
-
-    /** automatically progress mobile originated calls to ACTIVE.
-     *  default to true
-     */
-    public void
-    setAutoProgressConnectingCall(boolean b) {
-        autoProgressConnecting = b;
-    }
-
-    public void
-    setNextDialFailImmediately(boolean b) {
-        nextDialFailImmediately = b;
-    }
-
-    /**
-     * hangup ringing, dialing, or active calls
-     * returns true if call was hung up, false if not
-     */
-    public boolean
-    triggerHangupForeground() {
-        synchronized (this) {
-            boolean found;
-
-            found = false;
-
-            for (int i = 0 ; i < calls.length ; i++) {
-                CallInfo call = calls[i];
-
-                if (call != null
-                    && (call.state == CallInfo.State.INCOMING
-                        || call.state == CallInfo.State.WAITING)
-                ) {
-                    calls[i] = null;
-                    found = true;
-                }
-            }
-
-            for (int i = 0 ; i < calls.length ; i++) {
-                CallInfo call = calls[i];
-
-                if (call != null
-                    && (call.state == CallInfo.State.DIALING
-                        || call.state == CallInfo.State.ACTIVE
-                        || call.state == CallInfo.State.ALERTING)
-                ) {
-                    calls[i] = null;
-                    found = true;
-                }
-            }
-            return found;
-        }
-    }
-
-    /**
-     * hangup holding calls
-     * returns true if call was hung up, false if not
-     */
-    public boolean
-    triggerHangupBackground() {
-        synchronized (this) {
-            boolean found = false;
-
-            for (int i = 0 ; i < calls.length ; i++) {
-                CallInfo call = calls[i];
-
-                if (call != null && call.state == CallInfo.State.HOLDING) {
-                    calls[i] = null;
-                    found = true;
-                }
-            }
-
-            return found;
-        }
-    }
-
-    /**
-     * hangup all
-     * returns true if call was hung up, false if not
-     */
-    public boolean
-    triggerHangupAll() {
-        synchronized(this) {
-            boolean found = false;
-
-            for (int i = 0 ; i < calls.length ; i++) {
-                CallInfo call = calls[i];
-
-                if (calls[i] != null) {
-                    found = true;
-                }
-
-                calls[i] = null;
-            }
-
-            return found;
-        }
-    }
-
-    public boolean
-    onAnswer() {
-        synchronized (this) {
-            for (int i = 0 ; i < calls.length ; i++) {
-                CallInfo call = calls[i];
-
-                if (call != null
-                    && (call.state == CallInfo.State.INCOMING
-                        || call.state == CallInfo.State.WAITING)
-                ) {
-                    return switchActiveAndHeldOrWaiting();
-                }
-            }
-        }
-
-        return false;
-    }
-
-    public boolean
-    onHangup() {
-        boolean found = false;
-
-        for (int i = 0 ; i < calls.length ; i++) {
-            CallInfo call = calls[i];
-
-            if (call != null && call.state != CallInfo.State.WAITING) {
-                calls[i] = null;
-                found = true;
-            }
-        }
-
-        return found;
-    }
-
-    public boolean
-    onChld(char c0, char c1) {
-        boolean ret;
-        int callIndex = 0;
-
-        if (c1 != 0) {
-            callIndex = c1 - '1';
-
-            if (callIndex < 0 || callIndex >= calls.length) {
-                return false;
-            }
-        }
-
-        switch (c0) {
-            case '0':
-                ret = releaseHeldOrUDUB();
-            break;
-            case '1':
-                if (c1 <= 0) {
-                    ret = releaseActiveAcceptHeldOrWaiting();
-                } else {
-                    if (calls[callIndex] == null) {
-                        ret = false;
-                    } else {
-                        calls[callIndex] = null;
-                        ret = true;
-                    }
-                }
-            break;
-            case '2':
-                if (c1 <= 0) {
-                    ret = switchActiveAndHeldOrWaiting();
-                } else {
-                    ret = separateCall(callIndex);
-                }
-            break;
-            case '3':
-                ret = conference();
-            break;
-            case '4':
-                ret = explicitCallTransfer();
-            break;
-            case '5':
-                if (true) { //just so javac doesnt complain about break
-                    //CCBS not impled
-                    ret = false;
-                }
-            break;
-            default:
-                ret = false;
-
-        }
-
-        return ret;
-    }
-
-    public boolean
-    releaseHeldOrUDUB() {
-        boolean found = false;
-
-        for (int i = 0 ; i < calls.length ; i++) {
-            CallInfo c = calls[i];
-
-            if (c != null && c.isRinging()) {
-                found = true;
-                calls[i] = null;
-                break;
-            }
-        }
-
-        if (!found) {
-            for (int i = 0 ; i < calls.length ; i++) {
-                CallInfo c = calls[i];
-
-                if (c != null && c.state == CallInfo.State.HOLDING) {
-                    found = true;
-                    calls[i] = null;
-                    // don't stop...there may be more than one
-                }
-            }
-        }
-
-        return true;
-    }
-
-
-    public boolean
-    releaseActiveAcceptHeldOrWaiting() {
-        boolean foundHeld = false;
-        boolean foundActive = false;
-
-        for (int i = 0 ; i < calls.length ; i++) {
-            CallInfo c = calls[i];
-
-            if (c != null && c.state == CallInfo.State.ACTIVE) {
-                calls[i] = null;
-                foundActive = true;
-            }
-        }
-
-        if (!foundActive) {
-            // FIXME this may not actually be how most basebands react
-            // CHLD=1 may not hang up dialing/alerting calls
-            for (int i = 0 ; i < calls.length ; i++) {
-                CallInfo c = calls[i];
-
-                if (c != null
-                        && (c.state == CallInfo.State.DIALING
-                            || c.state == CallInfo.State.ALERTING)
-                ) {
-                    calls[i] = null;
-                    foundActive = true;
-                }
-            }
-        }
-
-        for (int i = 0 ; i < calls.length ; i++) {
-            CallInfo c = calls[i];
-
-            if (c != null && c.state == CallInfo.State.HOLDING) {
-                c.state = CallInfo.State.ACTIVE;
-                foundHeld = true;
-            }
-        }
-
-        if (foundHeld) {
-            return true;
-        }
-
-        for (int i = 0 ; i < calls.length ; i++) {
-            CallInfo c = calls[i];
-
-            if (c != null && c.isRinging()) {
-                c.state = CallInfo.State.ACTIVE;
-                return true;
-            }
-        }
-
-        return true;
-    }
-
-    public boolean
-    switchActiveAndHeldOrWaiting() {
-        boolean hasHeld = false;
-
-        // first, are there held calls?
-        for (int i = 0 ; i < calls.length ; i++) {
-            CallInfo c = calls[i];
-
-            if (c != null && c.state == CallInfo.State.HOLDING) {
-                hasHeld = true;
-                break;
-            }
-        }
-
-        // Now, switch
-        for (int i = 0 ; i < calls.length ; i++) {
-            CallInfo c = calls[i];
-
-            if (c != null) {
-                if (c.state == CallInfo.State.ACTIVE) {
-                    c.state = CallInfo.State.HOLDING;
-                } else if (c.state == CallInfo.State.HOLDING) {
-                    c.state = CallInfo.State.ACTIVE;
-                } else if (!hasHeld && c.isRinging())  {
-                    c.state = CallInfo.State.ACTIVE;
-                }
-            }
-        }
-
-        return true;
-    }
-
-
-    public boolean
-    separateCall(int index) {
-        try {
-            CallInfo c;
-
-            c = calls[index];
-
-            if (c == null || c.isConnecting() || countActiveLines() != 1) {
-                return false;
-            }
-
-            c.state = CallInfo.State.ACTIVE;
-            c.isMpty = false;
-
-            for (int i = 0 ; i < calls.length ; i++) {
-                int countHeld=0, lastHeld=0;
-
-                if (i != index) {
-                    CallInfo cb = calls[i];
-
-                    if (cb != null && cb.state == CallInfo.State.ACTIVE) {
-                        cb.state = CallInfo.State.HOLDING;
-                        countHeld++;
-                        lastHeld = i;
-                    }
-                }
-
-                if (countHeld == 1) {
-                    // if there's only one left, clear the MPTY flag
-                    calls[lastHeld].isMpty = false;
-                }
-            }
-
-            return true;
-        } catch (InvalidStateEx ex) {
-            return false;
-        }
-    }
-
-
-
-    public boolean
-    conference() {
-        int countCalls = 0;
-
-        // if there's connecting calls, we can't do this yet
-        for (int i = 0 ; i < calls.length ; i++) {
-            CallInfo c = calls[i];
-
-            if (c != null) {
-                countCalls++;
-
-                if (c.isConnecting()) {
-                    return false;
-                }
-            }
-        }
-        for (int i = 0 ; i < calls.length ; i++) {
-            CallInfo c = calls[i];
-
-            if (c != null) {
-                c.state = CallInfo.State.ACTIVE;
-                if (countCalls > 0) {
-                    c.isMpty = true;
-                }
-            }
-        }
-
-        return true;
-    }
-
-    public boolean
-    explicitCallTransfer() {
-        int countCalls = 0;
-
-        // if there's connecting calls, we can't do this yet
-        for (int i = 0 ; i < calls.length ; i++) {
-            CallInfo c = calls[i];
-
-            if (c != null) {
-                countCalls++;
-
-                if (c.isConnecting()) {
-                    return false;
-                }
-            }
-        }
-
-        // disconnect the subscriber from both calls
-        return triggerHangupAll();
-    }
-
-    public boolean
-    onDial(String address) {
-        CallInfo call;
-        int freeSlot = -1;
-
-        Log.d("GSM", "SC> dial '" + address + "'");
-
-        if (nextDialFailImmediately) {
-            nextDialFailImmediately = false;
-
-            Log.d("GSM", "SC< dial fail (per request)");
-            return false;
-        }
-
-        String phNum = PhoneNumberUtils.extractNetworkPortion(address);
-
-        if (phNum.length() == 0) {
-            Log.d("GSM", "SC< dial fail (invalid ph num)");
-            return false;
-        }
-
-        // Ignore setting up GPRS
-        if (phNum.startsWith("*99") && phNum.endsWith("#")) {
-            Log.d("GSM", "SC< dial ignored (gprs)");
-            return true;
-        }
-
-        // There can be at most 1 active "line" when we initiate
-        // a new call
-        try {
-            if (countActiveLines() > 1) {
-                Log.d("GSM", "SC< dial fail (invalid call state)");
-                return false;
-            }
-        } catch (InvalidStateEx ex) {
-            Log.d("GSM", "SC< dial fail (invalid call state)");
-            return false;
-        }
-
-        for (int i = 0 ; i < calls.length ; i++) {
-            if (freeSlot < 0 && calls[i] == null) {
-                freeSlot = i;
-            }
-
-            if (calls[i] != null && !calls[i].isActiveOrHeld()) {
-                // Can't make outgoing calls when there is a ringing or
-                // connecting outgoing call
-                Log.d("GSM", "SC< dial fail (invalid call state)");
-                return false;
-            } else if (calls[i] != null && calls[i].state == CallInfo.State.ACTIVE) {
-                // All active calls behome held
-                calls[i].state = CallInfo.State.HOLDING;
-            }
-        }
-
-        if (freeSlot < 0) {
-            Log.d("GSM", "SC< dial fail (invalid call state)");
-            return false;
-        }
-
-        calls[freeSlot] = CallInfo.createOutgoingCall(phNum);
-
-        if (autoProgressConnecting) {
-            sendMessageDelayed(
-                    obtainMessage(EVENT_PROGRESS_CALL_STATE, calls[freeSlot]),
-                    CONNECTING_PAUSE_MSEC);
-        }
-
-        Log.d("GSM", "SC< dial (slot = " + freeSlot + ")");
-
-        return true;
-    }
-
-    public List<DriverCall>
-    getDriverCalls() {
-        ArrayList<DriverCall> ret = new ArrayList<DriverCall>(calls.length);
-
-        for (int i = 0 ; i < calls.length ; i++) {
-            CallInfo c = calls[i];
-
-            if (c != null) {
-                DriverCall dc;
-
-                dc = c.toDriverCall(i + 1);
-                ret.add(dc);
-            }
-        }
-
-        Log.d("GSM", "SC< getDriverCalls " + ret);
-
-        return ret;
-    }
-
-    public List<String>
-    getClccLines() {
-        ArrayList<String> ret = new ArrayList<String>(calls.length);
-
-        for (int i = 0 ; i < calls.length ; i++) {
-            CallInfo c = calls[i];
-
-            if (c != null) {
-                ret.add((c.toCLCCLine(i + 1)));
-            }
-        }
-
-        return ret;
-    }
-
-    private int
-    countActiveLines() throws InvalidStateEx {
-        boolean hasMpty = false;
-        boolean hasHeld = false;
-        boolean hasActive = false;
-        boolean hasConnecting = false;
-        boolean hasRinging = false;
-        boolean mptyIsHeld = false;
-
-        for (int i = 0 ; i < calls.length ; i++) {
-            CallInfo call = calls[i];
-
-            if (call != null) {
-                if (!hasMpty && call.isMpty) {
-                    mptyIsHeld = call.state == CallInfo.State.HOLDING;
-                } else if (call.isMpty && mptyIsHeld
-                    && call.state == CallInfo.State.ACTIVE
-                ) {
-                    Log.e("ModelInterpreter", "Invalid state");
-                    throw new InvalidStateEx();
-                } else if (!call.isMpty && hasMpty && mptyIsHeld
-                    && call.state == CallInfo.State.HOLDING
-                ) {
-                    Log.e("ModelInterpreter", "Invalid state");
-                    throw new InvalidStateEx();
-                }
-
-                hasMpty |= call.isMpty;
-                hasHeld |= call.state == CallInfo.State.HOLDING;
-                hasActive |= call.state == CallInfo.State.ACTIVE;
-                hasConnecting |= call.isConnecting();
-                hasRinging |= call.isRinging();
-            }
-        }
-
-        int ret = 0;
-
-        if (hasHeld) ret++;
-        if (hasActive) ret++;
-        if (hasConnecting) ret++;
-        if (hasRinging) ret++;
-
-        return ret;
-    }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedRadioControl.java b/telephony/java/com/android/internal/telephony/test/SimulatedRadioControl.java
deleted file mode 100644
index 054d370..0000000
--- a/telephony/java/com/android/internal/telephony/test/SimulatedRadioControl.java
+++ /dev/null
@@ -1,53 +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.internal.telephony.test;
-
-public interface SimulatedRadioControl
-{
-    public void triggerRing(String number);
-
-    public void progressConnectingCallState();
-
-    public void progressConnectingToActive();
-
-    public void setAutoProgressConnectingCall(boolean b);
-
-    public void setNextDialFailImmediately(boolean b);
-
-    public void setNextCallFailCause(int gsmCause);
-
-    public void triggerHangupForeground();
-
-    public void triggerHangupBackground();
-
-    public void triggerHangupAll();
-
-    public void triggerIncomingSMS(String message);
-
-    public void shutdown();
-
-    /** Pause responses to async requests until (ref-counted) resumeResponses() */
-    public void pauseResponses();
-
-    /** see pauseResponses */
-    public void resumeResponses();
-
-    public void triggerSsn(int type, int code);
-
-    /** Generates an incoming USSD message. */
-    public void triggerIncomingUssd(String statusCode, String message);
-}
diff --git a/telephony/java/com/android/internal/telephony/test/package.html b/telephony/java/com/android/internal/telephony/test/package.html
deleted file mode 100755
index c9f96a6..0000000
--- a/telephony/java/com/android/internal/telephony/test/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<body>
-
-{@hide}
-
-</body>
diff --git a/telephony/java/com/android/internal/telephony/uicc/UiccController.java b/telephony/java/com/android/internal/telephony/uicc/UiccController.java
deleted file mode 100644
index 5961efd..0000000
--- a/telephony/java/com/android/internal/telephony/uicc/UiccController.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2011 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.internal.telephony.uicc;
-
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.cdma.CDMALTEPhone;
-import com.android.internal.telephony.cdma.CDMAPhone;
-import com.android.internal.telephony.gsm.GSMPhone;
-
-import android.util.Log;
-
-/* This class is responsible for keeping all knowledge about
- * ICCs in the system. It is also used as API to get appropriate
- * applications to pass them to phone and service trackers.
- */
-public class UiccController {
-    private static final boolean DBG = true;
-    private static final String LOG_TAG = "RIL_UiccController";
-
-    private static UiccController mInstance;
-
-    private PhoneBase mCurrentPhone;
-    private boolean mIsCurrentCard3gpp;
-    private IccCard mIccCard;
-
-    public static synchronized UiccController getInstance(PhoneBase phone) {
-        if (mInstance == null) {
-            mInstance = new UiccController(phone);
-        } else {
-            mInstance.setNewPhone(phone);
-        }
-        return mInstance;
-    }
-
-    public IccCard getIccCard() {
-        return mIccCard;
-    }
-
-    private UiccController(PhoneBase phone) {
-        if (DBG) log("Creating UiccController");
-        setNewPhone(phone);
-    }
-
-    private void setNewPhone(PhoneBase phone) {
-        mCurrentPhone = phone;
-        if (phone instanceof GSMPhone) {
-            if (DBG) log("New phone is GSMPhone");
-            updateCurrentCard(IccCard.CARD_IS_3GPP);
-        } else if (phone instanceof CDMALTEPhone){
-            if (DBG) log("New phone type is CDMALTEPhone");
-            updateCurrentCard(IccCard.CARD_IS_3GPP);
-        } else if (phone instanceof CDMAPhone){
-            if (DBG) log("New phone type is CDMAPhone");
-            updateCurrentCard(IccCard.CARD_IS_NOT_3GPP);
-        } else {
-            Log.e(LOG_TAG, "Unhandled phone type. Critical error!");
-        }
-    }
-
-    private void updateCurrentCard(boolean isNewCard3gpp) {
-        if (mIsCurrentCard3gpp == isNewCard3gpp && mIccCard != null) {
-            return;
-        }
-
-        if (mIccCard != null) {
-            mIccCard.dispose();
-            mIccCard = null;
-        }
-
-        mIsCurrentCard3gpp = isNewCard3gpp;
-        mIccCard = new IccCard(mCurrentPhone, mCurrentPhone.getPhoneName(),
-                isNewCard3gpp, DBG);
-    }
-
-    private void log(String string) {
-        Log.d(LOG_TAG, string);
-    }
-}
\ No newline at end of file
diff --git a/telephony/mockril/Android.mk b/telephony/mockril/Android.mk
deleted file mode 100644
index 95ae84c..0000000
--- a/telephony/mockril/Android.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Copyright (C) 2010 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)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_JAVA_LIBRARIES := core framework
-
-LOCAL_STATIC_JAVA_LIBRARIES := librilproto-java
-
-LOCAL_MODULE := mockrilcontroller
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/telephony/mockril/src/com/android/internal/telephony/mockril/MockRilController.java b/telephony/mockril/src/com/android/internal/telephony/mockril/MockRilController.java
deleted file mode 100644
index 0e75c72..0000000
--- a/telephony/mockril/src/com/android/internal/telephony/mockril/MockRilController.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2010, 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.internal.telephony.mockril;
-
-import android.os.Bundle;
-import android.util.Log;
-
-import com.android.internal.communication.MsgHeader;
-import com.android.internal.communication.Msg;
-import com.android.internal.telephony.RilChannel;
-import com.android.internal.telephony.ril_proto.RilCtrlCmds;
-import com.android.internal.telephony.ril_proto.RilCmds;
-import com.google.protobuf.micro.MessageMicro;
-
-import java.io.IOException;
-
-/**
- * Contain a list of commands to control Mock RIL. Before using these commands the devices
- * needs to be set with Mock RIL. Refer to hardware/ril/mockril/README.txt for details.
- *
- */
-public class MockRilController {
-    private static final String TAG = "MockRILController";
-    private RilChannel mRilChannel = null;
-    private Msg mMessage = null;
-
-    public MockRilController() throws IOException {
-        mRilChannel = RilChannel.makeRilChannel();
-    }
-
-    /**
-     * Close the channel after the communication is done.
-     * This method has to be called after the test is finished.
-     */
-    public void closeChannel() {
-        mRilChannel.close();
-    }
-
-    /**
-     * Send commands and return true on success
-     * @param cmd for MsgHeader
-     * @param token for MsgHeader
-     * @param status for MsgHeader
-     * @param pbData for Msg data
-     * @return true if command is sent successfully, false if it fails
-     */
-    private boolean sendCtrlCommand(int cmd, long token, int status, MessageMicro pbData) {
-        try {
-            Msg.send(mRilChannel, cmd, token, status, pbData);
-        } catch (IOException e) {
-            Log.v(TAG, "send command : %d failed: " + e.getStackTrace());
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Get control response
-     * @return Msg if response is received, else return null.
-     */
-    private Msg getCtrlResponse() {
-        Msg response = null;
-        try {
-            response = Msg.recv(mRilChannel);
-        } catch (IOException e) {
-            Log.v(TAG, "receive response for getRadioState() error: " + e.getStackTrace());
-            return null;
-        }
-        return response;
-    }
-
-    /**
-     * @return the radio state if it is valid, otherwise return -1
-     */
-    public int getRadioState() {
-        if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_GET_RADIO_STATE, 0, 0, null)) {
-            return -1;
-        }
-        Msg response = getCtrlResponse();
-        if (response == null) {
-            Log.v(TAG, "failed to get response");
-            return -1;
-        }
-        response.printHeader(TAG);
-        RilCtrlCmds.CtrlRspRadioState resp =
-            response.getDataAs(RilCtrlCmds.CtrlRspRadioState.class);
-        int state = resp.getState();
-        if ((state >= RilCmds.RADIOSTATE_OFF) && (state <= RilCmds.RADIOSTATE_NV_READY))
-            return state;
-        else
-            return -1;
-    }
-
-    /**
-     * Set the radio state of mock ril to the given state
-     * @param state for given radio state
-     * @return true if the state is set successful, false if it fails
-     */
-    public boolean setRadioState(int state) {
-        RilCtrlCmds.CtrlReqRadioState req = new RilCtrlCmds.CtrlReqRadioState();
-        if (state < 0 || state > RilCmds.RADIOSTATE_NV_READY) {
-            Log.v(TAG, "the give radio state is not valid.");
-            return false;
-        }
-        req.setState(state);
-        if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_RADIO_STATE, 0, 0, req)) {
-            Log.v(TAG, "send set radio state request failed.");
-            return false;
-        }
-        Msg response = getCtrlResponse();
-        if (response == null) {
-            Log.v(TAG, "failed to get response for setRadioState");
-            return false;
-        }
-        response.printHeader(TAG);
-        RilCtrlCmds.CtrlRspRadioState resp =
-            response.getDataAs(RilCtrlCmds.CtrlRspRadioState.class);
-        int curstate = resp.getState();
-        return curstate == state;
-    }
-
-    /**
-     * Start an incoming call for the given phone number
-     *
-     * @param phoneNumber is the number to show as incoming call
-     * @return true if the incoming call is started successfully, false if it fails.
-     */
-    public boolean startIncomingCall(String phoneNumber) {
-        RilCtrlCmds.CtrlReqSetMTCall req = new RilCtrlCmds.CtrlReqSetMTCall();
-
-        req.setPhoneNumber(phoneNumber);
-        if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_MT_CALL, 0, 0, req)) {
-            Log.v(TAG, "send CMD_SET_MT_CALL request failed");
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Hang up a connection remotelly for the given call fail cause
-     *
-     * @param connectionID is the connection to be hung up
-     * @param failCause is the call fail cause defined in ril.h
-     * @return true if the hangup is successful, false if it fails
-     */
-    public boolean hangupRemote(int connectionId, int failCause) {
-        RilCtrlCmds.CtrlHangupConnRemote req = new RilCtrlCmds.CtrlHangupConnRemote();
-        req.setConnectionId(connectionId);
-        req.setCallFailCause(failCause);
-
-        if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_HANGUP_CONN_REMOTE, 0, 0, req)) {
-            Log.v(TAG, "send CTRL_CMD_HANGUP_CONN_REMOTE request failed");
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Set call transition flag to the Mock Ril
-     *
-     * @param flag is a boolean value for the call transiton flag
-     *             true: call transition: dialing->alert, alert->active is controlled
-     *             false: call transition is automatically handled by Mock Ril
-     * @return true if the request is successful, false if it failed to set the flag
-     */
-    public boolean setCallTransitionFlag(boolean flag) {
-        RilCtrlCmds.CtrlSetCallTransitionFlag req = new RilCtrlCmds.CtrlSetCallTransitionFlag();
-
-        req.setFlag(flag);
-
-        if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_CALL_TRANSITION_FLAG, 0, 0, req)) {
-            Log.v(TAG, "send CTRL_CMD_SET_CALL_TRANSITION_FLAG request failed");
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Set the dialing call to alert if the call transition flag is true
-     *
-     * @return true if the call transition is successful, false if it fails
-     */
-    public boolean setDialCallToAlert() {
-        if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_CALL_ALERT, 0, 0, null)) {
-            Log.v(TAG, "send CTRL_CMD_SET_CALL_ALERT request failed");
-            return false;
-        }
-        return true;
-   }
-
-   /**
-    * Set the alert call to active if the call transition flag is true
-    *
-    * @return true if the call transition is successful, false if it fails
-    */
-   public boolean setAlertCallToActive() {
-        if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_CALL_ACTIVE, 0, 0, null)) {
-            Log.v(TAG, "send CTRL_CMD_SET_CALL_ACTIVE request failed");
-            return false;
-        }
-        return true;
-   }
-}
diff --git a/telephony/tests/telephonymockriltests/Android.mk b/telephony/tests/telephonymockriltests/Android.mk
deleted file mode 100644
index 9731d0d..0000000
--- a/telephony/tests/telephonymockriltests/Android.mk
+++ /dev/null
@@ -1,14 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_STATIC_JAVA_LIBRARIES := mockrilcontroller
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-LOCAL_PACKAGE_NAME := TelephonyMockRilTests
-
-include $(BUILD_PACKAGE)
diff --git a/telephony/tests/telephonymockriltests/AndroidManifest.xml b/telephony/tests/telephonymockriltests/AndroidManifest.xml
deleted file mode 100644
index 63f44a2..0000000
--- a/telephony/tests/telephonymockriltests/AndroidManifest.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!-- 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.telephonymockriltests">
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-        <activity android:label="TelephonyMockRilTest"
-                android:name="TelephonyMockRilTest">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER"/>
-            </intent-filter>
-        </activity>
-    </application>
-
-    <instrumentation android:name=".TelephonyMockTestRunner"
-        android:targetPackage="com.android.telephonymockriltests"
-        android:label="Test runner for Telephony Tests Using Mock RIL"
-    />
-
-    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
-    <uses-permission android:name="android.permission.INTERNET" />
-
-</manifest>
diff --git a/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/TelephonyMockTestRunner.java b/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/TelephonyMockTestRunner.java
deleted file mode 100644
index 78ee738..0000000
--- a/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/TelephonyMockTestRunner.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2010, 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.telephonymockriltests;
-
-import android.os.Bundle;
-import android.test.InstrumentationTestRunner;
-import android.test.InstrumentationTestSuite;
-import com.android.internal.telephony.mockril.MockRilController;
-import android.util.Log;
-
-import com.android.telephonymockriltests.functional.SimpleTestUsingMockRil;
-
-import java.io.IOException;
-import junit.framework.TestSuite;
-import junit.framework.TestCase;
-
-/**
- * Test runner for telephony tests that using Mock RIL
- *
- */
-public class TelephonyMockTestRunner extends InstrumentationTestRunner {
-    private static final String TAG="TelephonyMockTestRunner";
-    public MockRilController mController;
-
-    @Override
-    public TestSuite getAllTests() {
-        TestSuite suite = new InstrumentationTestSuite(this);
-        suite.addTestSuite(SimpleTestUsingMockRil.class);
-        return suite;
-    }
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        try {
-            mController = new MockRilController();
-        } catch (IOException e) {
-            e.printStackTrace();
-            TestCase.assertTrue("Create Mock RIl Controller failed", false);
-        }
-        TestCase.assertNotNull(mController);
-        super.onCreate(icicle);
-    }
-
-    @Override
-    public void finish(int resultCode, Bundle results) {
-        if (mController != null)
-            mController.closeChannel();
-        super.finish(resultCode, results);
-    }
-}
diff --git a/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/functional/SimpleTestUsingMockRil.java b/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/functional/SimpleTestUsingMockRil.java
deleted file mode 100644
index 3ea1cf2..0000000
--- a/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/functional/SimpleTestUsingMockRil.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2010 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.telephonymockriltests.functional;
-
-import com.android.internal.telephony.mockril.MockRilController;
-import android.test.InstrumentationTestCase;
-import android.util.Log;
-
-import com.android.telephonymockriltests.TelephonyMockTestRunner;
-
-/**
- * A simple test that using Mock RIL Controller
- */
-public class SimpleTestUsingMockRil extends InstrumentationTestCase {
-    private static final String TAG = "SimpleTestUsingMockRil";
-    private MockRilController mMockRilCtrl = null;
-    private TelephonyMockTestRunner mRunner;
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        mRunner = (TelephonyMockTestRunner)getInstrumentation();
-        mMockRilCtrl = mRunner.mController;
-        assertNotNull(mMockRilCtrl);
-    }
-
-    /**
-     * Get the current radio state of RIL
-     */
-    public void testGetRadioState() {
-        int state = mMockRilCtrl.getRadioState();
-        Log.v(TAG, "testGetRadioState: " + state);
-        assertTrue(state >= 0 && state <= 9);
-    }
-
-    /**
-     * Set the current radio state of RIL
-     * and verify the radio state is set correctly
-     */
-    public void testSetRadioState() {
-        for (int state = 0; state <= 9; state++) {
-            Log.v(TAG, "set radio state to be " + state);
-            assertTrue("set radio state: " + state + " failed.",
-                       mMockRilCtrl.setRadioState(state));
-        }
-        assertFalse("use an invalid radio state", mMockRilCtrl.setRadioState(-1));
-        assertFalse("the radio state doesn't exist", mMockRilCtrl.setRadioState(10));
-    }
-}
diff --git a/telephony/tests/telephonytests/Android.mk b/telephony/tests/telephonytests/Android.mk
deleted file mode 100644
index 98e4403..0000000
--- a/telephony/tests/telephonytests/Android.mk
+++ /dev/null
@@ -1,14 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_STATIC_JAVA_LIBRARIES := librilproto-java
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-LOCAL_PACKAGE_NAME := FrameworksTelephonyTests
-
-include $(BUILD_PACKAGE)
diff --git a/telephony/tests/telephonytests/AndroidManifest.xml b/telephony/tests/telephonytests/AndroidManifest.xml
deleted file mode 100644
index ba1d957..0000000
--- a/telephony/tests/telephonytests/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!-- 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.frameworks.telephonytests">
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-        <activity android:label="TelephonyTest"
-                android:name="TelephonyTest">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER"/>
-            </intent-filter>
-        </activity>
-    </application>
-    <instrumentation android:name="android.test.InstrumentationTestRunner"
-        android:targetPackage="com.android.frameworks.telephonytests"
-        android:label="Frameworks Telephony Tests">
-    </instrumentation>
-
-    <instrumentation android:name=".TelephonyMockRilTestRunner"
-        android:targetPackage="com.android.frameworks.telephonytests"
-        android:label="Test Runner for Mock Ril Tests"
-    />
-
-    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
-    <uses-permission android:name="android.permission.INTERNET" />
-
-</manifest>
diff --git a/telephony/tests/telephonytests/src/com/android/frameworks/telephonytests/TelephonyMockRilTestRunner.java b/telephony/tests/telephonytests/src/com/android/frameworks/telephonytests/TelephonyMockRilTestRunner.java
deleted file mode 100644
index 9192f57..0000000
--- a/telephony/tests/telephonytests/src/com/android/frameworks/telephonytests/TelephonyMockRilTestRunner.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2010, 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.frameworks.telephonytests;
-
-import android.os.Bundle;
-
-import android.test.InstrumentationTestRunner;
-import android.test.InstrumentationTestSuite;
-import android.util.Log;
-
-import java.io.IOException;
-
-import com.android.internal.telephony.RilChannel;
-import com.android.internal.telephony.mockril.MockRilTest;
-
-import junit.framework.TestSuite;
-
-public class TelephonyMockRilTestRunner extends InstrumentationTestRunner {
-
-    public RilChannel mMockRilChannel;
-
-    @Override
-    public TestSuite getAllTests() {
-        log("getAllTests E");
-        TestSuite suite = new InstrumentationTestSuite(this);
-        suite.addTestSuite(MockRilTest.class);
-        log("getAllTests X");
-        return suite;
-    }
-
-    @Override
-    public ClassLoader getLoader() {
-        log("getLoader EX");
-        return TelephonyMockRilTestRunner.class.getClassLoader();
-    }
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        log("onCreate E");
-        try {
-            mMockRilChannel = RilChannel.makeRilChannel();
-        } catch (IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-        log("onCreate X");
-
-        super.onCreate(icicle);
-    }
-
-    @Override
-    public void onDestroy() {
-        // I've not seen this called
-        log("onDestroy EX");
-        super.onDestroy();
-    }
-
-    @Override
-    public void onStart() {
-        // Called when the instrumentation thread is started.
-        // At the moment we don't need the thread so return
-        // which will shut down this unused thread.
-        log("onStart EX");
-        super.onStart();
-    }
-
-    @Override
-    public void finish(int resultCode, Bundle results) {
-        // Called when complete so I ask the mMockRilChannel to quit.
-        log("finish E");
-        mMockRilChannel.close();
-        log("finish X");
-        super.finish(resultCode, results);
-    }
-
-    private void log(String s) {
-        Log.e("TelephonyMockRilTestRunner", s);
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/ATResponseParserTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/ATResponseParserTest.java
deleted file mode 100644
index 81727e4..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/ATResponseParserTest.java
+++ /dev/null
@@ -1,113 +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.internal.telephony;
-
-import junit.framework.TestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-public class ATResponseParserTest extends TestCase {
-    @SmallTest
-    public void testBasic() throws Exception {
-        ATResponseParser p = new ATResponseParser("+CREG: 0");
-
-        assertEquals(0, p.nextInt());
-
-        assertFalse(p.hasMore());
-
-        try {
-            p.nextInt();
-            fail("exception expected");
-        } catch (ATParseEx ex) {
-            //test pass
-        }
-
-        p = new ATResponseParser("+CREG: 0,1");
-        assertEquals(0, p.nextInt());
-        assertEquals(1, p.nextInt());
-        assertFalse(p.hasMore());
-
-        p = new ATResponseParser("+CREG: 0, 1");
-        assertEquals(0, p.nextInt());
-        assertEquals(1, p.nextInt());
-        assertFalse(p.hasMore());
-
-        p = new ATResponseParser("+CREG: 0, 1,");
-        assertEquals(0, p.nextInt());
-        assertEquals(1, p.nextInt());
-        // this seems odd but is probably OK
-        assertFalse(p.hasMore());
-        try {
-            p.nextInt();
-            fail("exception expected");
-        } catch (ATParseEx ex) {
-            //test pass
-        }
-
-        p = new ATResponseParser("+CREG: 0, 1 ");
-        assertEquals(0, p.nextInt());
-        assertEquals(1, p.nextInt());
-        assertFalse(p.hasMore());
-
-        p = new ATResponseParser("0, 1 ");
-        // no prefix -> exception
-        try {
-            p.nextInt();
-            fail("exception expected");
-        } catch (ATParseEx ex) {
-            //test pass
-        }
-
-        p = new ATResponseParser("+CREG: 0, 1, 5");
-        assertFalse(p.nextBoolean());
-        assertTrue(p.nextBoolean());
-        try {
-            // is this over-constraining?
-            p.nextBoolean();
-            fail("exception expected");
-        } catch (ATParseEx ex) {
-            //test pass
-        }
-
-        p = new ATResponseParser("+CLCC: 1,0,2,0,0,\"+18005551212\",145");
-
-        assertEquals(1, p.nextInt());
-        assertFalse(p.nextBoolean());
-        assertEquals(2, p.nextInt());
-        assertEquals(0, p.nextInt());
-        assertEquals(0, p.nextInt());
-        assertEquals("+18005551212", p.nextString());
-        assertEquals(145, p.nextInt());
-        assertFalse(p.hasMore());
-
-        p = new ATResponseParser("+CLCC: 1,0,2,0,0,\"+18005551212,145");
-
-        assertEquals(1, p.nextInt());
-        assertFalse(p.nextBoolean());
-        assertEquals(2, p.nextInt());
-        assertEquals(0, p.nextInt());
-        assertEquals(0, p.nextInt());
-        try {
-            p.nextString();
-            fail("expected ex");
-        } catch (ATParseEx ex) {
-            //test pass
-        }
-
-        p = new ATResponseParser("+FOO: \"\"");
-        assertEquals("", p.nextString());
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/AdnRecordTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/AdnRecordTest.java
deleted file mode 100644
index 8a4a285..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/AdnRecordTest.java
+++ /dev/null
@@ -1,176 +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.internal.telephony;
-
-import junit.framework.TestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-/**
- * {@hide}
- */
-public class AdnRecordTest extends TestCase {
-    
-    @SmallTest
-    public void testBasic() throws Exception {
-        AdnRecord adn;
-
-        //
-        // Typical record
-        // 
-        adn = new AdnRecord(
-                IccUtils.hexStringToBytes("566F696365204D61696C07918150367742F3FFFFFFFFFFFF"));
-
-        assertEquals("Voice Mail", adn.getAlphaTag());
-        assertEquals("+18056377243", adn.getNumber());
-        assertFalse(adn.isEmpty());
-
-        //
-        // Empty records, empty strings
-        // 
-        adn = new AdnRecord(
-                IccUtils.hexStringToBytes("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"));
-
-        assertEquals("", adn.getAlphaTag());
-        assertEquals("", adn.getNumber());
-        assertTrue(adn.isEmpty());
-
-        //
-        // Record too short
-        // 
-        adn = new AdnRecord(IccUtils.hexStringToBytes( "FF"));
-
-        assertEquals("", adn.getAlphaTag());
-        assertEquals("", adn.getNumber());
-        assertTrue(adn.isEmpty());
-
-        //
-        // TOA = 0xff ("control string")
-        // 
-        adn = new AdnRecord(
-                IccUtils.hexStringToBytes("566F696365204D61696C07FF8150367742F3FFFFFFFFFFFF"));
-
-        assertEquals("Voice Mail", adn.getAlphaTag());
-        assertEquals("18056377243", adn.getNumber());
-        assertFalse(adn.isEmpty());
-
-        //
-        // TOA = 0x81 (unknown)
-        // 
-        adn = new AdnRecord(
-                IccUtils.hexStringToBytes("566F696365204D61696C07818150367742F3FFFFFFFFFFFF"));
-
-        assertEquals("Voice Mail", adn.getAlphaTag());
-        assertEquals("18056377243", adn.getNumber());
-        assertFalse(adn.isEmpty());
-
-        //
-        // Number Length is too long
-        // 
-        adn = new AdnRecord(
-                IccUtils.hexStringToBytes("566F696365204D61696C0F918150367742F3FFFFFFFFFFFF"));
-
-        assertEquals("Voice Mail", adn.getAlphaTag());
-        assertEquals("", adn.getNumber());
-        assertFalse(adn.isEmpty());
-
-        //
-        // Number Length is zero (invalid)
-        // 
-        adn = new AdnRecord(
-                IccUtils.hexStringToBytes("566F696365204D61696C00918150367742F3FFFFFFFFFFFF"));
-
-        assertEquals("Voice Mail", adn.getAlphaTag());
-        assertEquals("", adn.getNumber());
-        assertFalse(adn.isEmpty());
-
-        //
-        // Number Length is 2, first number byte is FF, TOA is international
-        // 
-        adn = new AdnRecord(
-                IccUtils.hexStringToBytes("566F696365204D61696C0291FF50367742F3FFFFFFFFFFFF"));
-
-        assertEquals("Voice Mail", adn.getAlphaTag());
-        assertEquals("", adn.getNumber());
-        assertFalse(adn.isEmpty());
-
-        //
-        // Number Length is 2, first number digit is valid, TOA is international
-        // 
-        adn = new AdnRecord(
-                IccUtils.hexStringToBytes("566F696365204D61696C0291F150367742F3FFFFFFFFFFFF"));
-
-        assertEquals("Voice Mail", adn.getAlphaTag());
-        assertEquals("+1", adn.getNumber());
-        assertFalse(adn.isEmpty());
-
-        //
-        // An extended record
-        // 
-        adn = new AdnRecord(
-                IccUtils.hexStringToBytes(
-                        "4164676A6DFFFFFFFFFFFFFFFFFFFFFF0B918188551512C221436587FF01"));
-
-        assertEquals("Adgjm", adn.getAlphaTag());
-        assertEquals("+18885551212,12345678", adn.getNumber());
-        assertFalse(adn.isEmpty());
-        assertTrue(adn.hasExtendedRecord());
-
-        adn.appendExtRecord(IccUtils.hexStringToBytes("0206092143658709ffffffffff"));
-
-        assertEquals("Adgjm", adn.getAlphaTag());
-        assertEquals("+18885551212,12345678901234567890", adn.getNumber());
-        assertFalse(adn.isEmpty());
-
-        //
-        // An extended record with an invalid extension
-        // 
-        adn = new AdnRecord(
-                IccUtils.hexStringToBytes(
-                        "4164676A6DFFFFFFFFFFFFFFFFFFFFFF0B918188551512C221436587FF01"));
-
-        assertEquals("Adgjm", adn.getAlphaTag());
-        assertEquals("+18885551212,12345678", adn.getNumber());
-        assertFalse(adn.isEmpty());
-        assertTrue(adn.hasExtendedRecord());
-
-        adn.appendExtRecord(IccUtils.hexStringToBytes("0106092143658709ffffffffff"));
-
-        assertEquals("Adgjm", adn.getAlphaTag());
-        assertEquals("+18885551212,12345678", adn.getNumber());
-        assertFalse(adn.isEmpty());
-
-        //
-        // An extended record with an invalid extension
-        // 
-        adn = new AdnRecord(
-                IccUtils.hexStringToBytes(
-                        "4164676A6DFFFFFFFFFFFFFFFFFFFFFF0B918188551512C221436587FF01"));
-
-        assertEquals("Adgjm", adn.getAlphaTag());
-        assertEquals("+18885551212,12345678", adn.getNumber());
-        assertFalse(adn.isEmpty());
-        assertTrue(adn.hasExtendedRecord());
-
-        adn.appendExtRecord(IccUtils.hexStringToBytes("020B092143658709ffffffffff"));
-
-        assertEquals("Adgjm", adn.getAlphaTag());
-        assertEquals("+18885551212,12345678", adn.getNumber());
-        assertFalse(adn.isEmpty());
-    }
-}
-
-
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/ApnSettingTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/ApnSettingTest.java
deleted file mode 100755
index ac8c4c16..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/ApnSettingTest.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2010 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.internal.telephony;
-
-import junit.framework.TestCase;
-
-import android.test.suitebuilder.annotation.SmallTest;
-
-public class ApnSettingTest extends TestCase {
-
-    public static final String[] TYPES = {"default", "*"};
-
-    public static void assertApnSettingEqual(ApnSetting a1, ApnSetting a2) {
-        assertEquals(a1.carrier,  a2.carrier);
-        assertEquals(a1.apn,      a2.apn);
-        assertEquals(a1.proxy,    a2.proxy);
-        assertEquals(a1.port,     a2.port);
-        assertEquals(a1.mmsc,     a2.mmsc);
-        assertEquals(a1.mmsProxy, a2.mmsProxy);
-        assertEquals(a1.mmsPort,  a2.mmsPort);
-        assertEquals(a1.user,     a2.user);
-        assertEquals(a1.password, a2.password);
-        assertEquals(a1.authType, a2.authType);
-        assertEquals(a1.id,       a2.id);
-        assertEquals(a1.numeric,  a2.numeric);
-        assertEquals(a1.protocol, a2.protocol);
-        assertEquals(a1.roamingProtocol, a2.roamingProtocol);
-        assertEquals(a1.types.length, a2.types.length);
-        int i;
-        for (i = 0; i < a1.types.length; i++) {
-            assertEquals(a1.types[i], a2.types[i]);
-        }
-        assertEquals(a1.carrierEnabled, a2.carrierEnabled);
-        assertEquals(a1.bearer, a2.bearer);
-    }
-
-    @SmallTest
-    public void testFromString() throws Exception {
-        String[] dunTypes = {"DUN"};
-        String[] mmsTypes = {"mms", "*"};
-
-        ApnSetting expected_apn;
-        String testString;
-
-        // A real-world v1 example string.
-        testString = "Vodafone IT,web.omnitel.it,,,,,,,,,222,10,,DUN";
-        expected_apn =  new ApnSetting(
-                -1, "22210", "Vodafone IT", "web.omnitel.it", "", "",
-                "", "", "", "", "", 0, dunTypes, "IP", "IP",true,0);
-        assertApnSettingEqual(expected_apn, ApnSetting.fromString(testString));
-
-        // A v2 string.
-        testString = "[ApnSettingV2] Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,14";
-        expected_apn =  new ApnSetting(
-                -1, "12345", "Name", "apn", "", "",
-                "", "", "", "", "", 0, mmsTypes, "IPV6", "IP",true,14);
-        assertApnSettingEqual(expected_apn, ApnSetting.fromString(testString));
-
-        // A v2 string with spaces.
-        testString = "[ApnSettingV2] Name,apn, ,,,,,,,,123,45,,mms|*,IPV4V6, IP,true,14";
-        expected_apn =  new ApnSetting(
-                -1, "12345", "Name", "apn", "", "",
-                "", "", "", "", "", 0, mmsTypes, "IPV4V6", "IP",true,14);
-        assertApnSettingEqual(expected_apn, ApnSetting.fromString(testString));
-
-        // Return null if insufficient fields given.
-        testString = "[ApnSettingV2] Name,apn,,,,,,,,,123, 45,,mms|*";
-        assertEquals(null, ApnSetting.fromString(testString));
-
-        testString = "Name,apn,,,,,,,,,123, 45,";
-        assertEquals(null, ApnSetting.fromString(testString));
-
-        // Parse (incorrect) V2 format without the tag as V1.
-        testString = "Name,apn,,,,,,,,,123, 45,,mms|*,IPV6,true,14";
-        String[] incorrectTypes = {"mms|*", "IPV6"};
-        expected_apn =  new ApnSetting(
-                -1, "12345", "Name", "apn", "", "",
-                "", "", "", "", "", 0, incorrectTypes, "IP", "IP",true,14);
-        assertApnSettingEqual(expected_apn, ApnSetting.fromString(testString));
-    }
-
-
-    @SmallTest
-    public void testToString() throws Exception {
-        String[] types = {"default", "*"};
-        ApnSetting apn =  new ApnSetting(
-                99, "12345", "Name", "apn", "proxy", "port",
-                "mmsc", "mmsproxy", "mmsport", "user", "password", 0,
-                types, "IPV4V6", "IP", true, 14);
-        String expected = "[ApnSettingV2] Name, 99, 12345, apn, proxy, " +
-                "mmsc, mmsproxy, mmsport, port, 0, default | *, " +
-                "IPV4V6, IP, true, 14";
-        assertEquals(expected, apn.toString());
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/CallerInfoTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/CallerInfoTest.java
deleted file mode 100644
index 1e5dafb..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/CallerInfoTest.java
+++ /dev/null
@@ -1,241 +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.
- */
-
-package com.android.internal.telephony;
-
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.res.Resources;
-import com.android.internal.telephony.CallerInfo;
-import com.android.internal.telephony.CallerInfoAsyncQuery;
-import android.util.Log;
-import android.os.Looper;
-import android.test.ActivityInstrumentationTestCase;
-import android.util.StringBuilderPrinter;
-
-/*
- * Check the CallerInfo utility class works as expected.
- *
- */
-
-public class CallerInfoTest extends AndroidTestCase {
-    private CallerInfo mInfo;
-    private Context mContext;
-
-    private static final String kEmergencyNumber = "Emergency Number";
-    private static final int kToken = 0xdeadbeef;
-    private static final String TAG = "CallerInfoUnitTest";
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mContext = new MockContext();
-        mInfo = new CallerInfo();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    /**
-     * Checks the caller info instance is flagged as an emergency if
-     * the number is an emergency one. There is no test for the
-     * contact based constructors because emergency number are not in
-     * the contact DB.
-     */
-    @SmallTest
-    public void testEmergencyIsProperlySet() throws Exception {
-        assertFalse(mInfo.isEmergencyNumber());
-
-        mInfo = CallerInfo.getCallerInfo(mContext, "911");
-        assertIsValidEmergencyCallerInfo();
-
-        mInfo = CallerInfo.getCallerInfo(mContext, "tel:911");
-        assertIsValidEmergencyCallerInfo();
-
-
-        // This one hits the content resolver.
-        mInfo = CallerInfo.getCallerInfo(mContext, "18001234567");
-        assertFalse(mInfo.isEmergencyNumber());
-    }
-
-    /**
-     * Same as testEmergencyIsProperlySet but uses the async query api.
-     */
-    @SmallTest
-    public void testEmergencyIsProperlySetUsingAsyncQuery() throws Exception {
-        QueryRunner query;
-
-        query = new QueryRunner("911");
-        query.runAndCheckCompletion();
-        assertIsValidEmergencyCallerInfo();
-
-        query = new QueryRunner("tel:911");
-        query.runAndCheckCompletion();
-        assertIsValidEmergencyCallerInfo();
-
-        query = new QueryRunner("18001234567");
-        query.runAndCheckCompletion();
-        assertFalse(mInfo.isEmergencyNumber());
-    }
-
-    /**
-     * For emergency caller info, phoneNumber should be set to the
-     * string emergency_call_dialog_number_for_display and the
-     * photoResource should be set to the picture_emergency drawable.
-     */
-    @SmallTest
-    public void testEmergencyNumberAndPhotoAreSet() throws Exception {
-        mInfo = CallerInfo.getCallerInfo(mContext, "911");
-
-        assertIsValidEmergencyCallerInfo();
-    }
-
-    // TODO: Add more tests:
-    /**
-     * Check if the voice mail number cannot be retrieved that the
-     * original phone number is preserved.
-     */
-    /**
-     * Check the markAs* methods work.
-     */
-
-
-    //
-    // Helpers
-    //
-
-    // Partial implementation of MockResources.
-    public class MockResources extends android.test.mock.MockResources
-    {
-        @Override
-        public String getString(int resId) throws Resources.NotFoundException {
-            switch (resId) {
-                case com.android.internal.R.string.emergency_call_dialog_number_for_display:
-                    return kEmergencyNumber;
-                default:
-                    throw new UnsupportedOperationException("Missing handling for resid " + resId);
-            }
-        }
-    }
-
-    // Partial implementation of MockContext.
-    public class MockContext extends android.test.mock.MockContext {
-        private ContentResolver mResolver;
-        private Resources mResources;
-
-        public MockContext() {
-            mResolver = new android.test.mock.MockContentResolver();
-            mResources = new MockResources();
-        }
-
-        @Override
-        public ContentResolver getContentResolver() {
-            return mResolver;
-        }
-
-        @Override
-        public Resources getResources() {
-            return mResources;
-        }
-    }
-
-    /**
-     * Class to run a CallerInfoAsyncQuery in a separate thread, with
-     * its own Looper. We cannot use the main Looper because on the
-     * 1st quit the thread is maked dead, ie no further test can use
-     * it. Also there is not way to inject a Looper instance in the
-     * query, so we have to use a thread with its own looper.
-     */
-    private class QueryRunner extends Thread
-            implements CallerInfoAsyncQuery.OnQueryCompleteListener {
-        private Looper mLooper;
-        private String mNumber;
-        private boolean mAsyncCompleted;
-
-        public QueryRunner(String number) {
-            super();
-            mNumber = number;
-        }
-
-        // Run the query in the thread, wait for completion.
-        public void runAndCheckCompletion() throws InterruptedException {
-            start();
-            join();
-            assertTrue(mAsyncCompleted);
-        }
-
-        @Override
-        public void run() {
-            Looper.prepare();
-            mLooper = Looper.myLooper();
-            mAsyncCompleted = false;
-            // The query will pick the thread local looper we've just prepared.
-            CallerInfoAsyncQuery.startQuery(kToken, mContext, mNumber, this, null);
-            mLooper.loop();
-        }
-
-        // Quit the Looper on the 1st callback
-        // (EVENT_EMERGENCY_NUMBER). There is another message
-        // (EVENT_END_OF_QUEUE) that will never be delivered because
-        // the test has exited. The corresponding stack trace
-        // "Handler{xxxxx} sending message to a Handler on a dead
-        // thread" can be ignored.
-        public void onQueryComplete(int token, Object cookie, CallerInfo info) {
-            mAsyncCompleted = true;
-            mInfo = info;
-            mLooper.quit();
-        }
-    }
-
-    /**
-     * Fail if mInfo does not contain a valid emergency CallerInfo instance.
-     */
-    private void assertIsValidEmergencyCallerInfo() throws Exception {
-        assertTrue(mInfo.isEmergencyNumber());
-
-        // For emergency caller info, phoneNumber should be set to the
-        // string emergency_call_dialog_number_for_display and the
-        // photoResource should be set to the picture_emergency drawable.
-        assertEquals(kEmergencyNumber, mInfo.phoneNumber);
-        assertEquals(com.android.internal.R.drawable.picture_emergency, mInfo.photoResource);
-
-        // The name should be null
-        assertNull(mInfo.name);
-        assertEquals(0, mInfo.namePresentation);
-        assertNull(mInfo.cnapName);
-        assertEquals(0, mInfo.numberPresentation);
-
-        assertFalse(mInfo.contactExists);
-        assertEquals(0, mInfo.person_id);
-        assertFalse(mInfo.needUpdate);
-        assertNull(mInfo.contactRefUri);
-
-        assertNull(mInfo.phoneLabel);
-        assertEquals(0, mInfo.numberType);
-        assertNull(mInfo.numberLabel);
-
-        assertNull(mInfo.contactRingtoneUri);
-        assertFalse(mInfo.shouldSendToVoicemail);
-
-        assertNull(mInfo.cachedPhoto);
-        assertFalse(mInfo.isCachedPhotoCurrent);
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmAlphabetTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmAlphabetTest.java
deleted file mode 100644
index f9dc3a9..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmAlphabetTest.java
+++ /dev/null
@@ -1,361 +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.internal.telephony;
-
-import com.android.internal.telephony.GsmAlphabet;
-
-import junit.framework.TestCase;
-
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.SmallTest;
-
-public class GsmAlphabetTest extends TestCase {
-
-    private static final String sGsmExtendedChars = "{|}\\[~]\f\u20ac";
-
-    @SmallTest
-    public void test7bitWithHeader() throws Exception {
-        SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
-        concatRef.refNumber = 1;
-        concatRef.seqNumber = 2;
-        concatRef.msgCount = 2;
-        concatRef.isEightBits = true;
-        SmsHeader header = new SmsHeader();
-        header.concatRef = concatRef;
-
-        String message = "aaaaaaaaaabbbbbbbbbbcccccccccc";
-        byte[] userData = GsmAlphabet.stringToGsm7BitPackedWithHeader(message,
-                SmsHeader.toByteArray(header), 0, 0);
-        int septetCount = GsmAlphabet.countGsmSeptetsUsingTables(message, true, 0, 0);
-        String parsedMessage = GsmAlphabet.gsm7BitPackedToString(
-                userData, SmsHeader.toByteArray(header).length+2, septetCount, 1, 0, 0);
-        assertEquals(message, parsedMessage);
-    }
-
-    // TODO: This method should *really* be a series of individual test methods.
-    // However, it's a SmallTest because it executes quickly.
-    @SmallTest
-    public void testBasic() throws Exception {
-        // '@' maps to char 0
-        assertEquals(0, GsmAlphabet.charToGsm('@'));
-
-        // `a (a with grave accent) maps to last GSM character
-        assertEquals(0x7f, GsmAlphabet.charToGsm('\u00e0'));
-
-        //
-        // These are the extended chars
-        // They should all return GsmAlphabet.GSM_EXTENDED_ESCAPE
-        //
-
-        for (int i = 0, s = sGsmExtendedChars.length(); i < s; i++) {
-            assertEquals(GsmAlphabet.GSM_EXTENDED_ESCAPE,
-                    GsmAlphabet.charToGsm(sGsmExtendedChars.charAt(i)));
-
-        }
-
-        // euro symbol
-        assertEquals(GsmAlphabet.GSM_EXTENDED_ESCAPE,
-                GsmAlphabet.charToGsm('\u20ac'));
-
-        // An unmappable char (the 'cent' char) maps to a space
-        assertEquals(GsmAlphabet.charToGsm(' '),
-                GsmAlphabet.charToGsm('\u00a2'));
-
-        // unmappable = space = 1 septet
-        assertEquals(1, GsmAlphabet.countGsmSeptets('\u00a2'));
-
-        //
-        // Test extended table
-        //
-
-        for (int i = 0, s = sGsmExtendedChars.length(); i < s; i++) {
-            assertEquals(sGsmExtendedChars.charAt(i),
-                    GsmAlphabet.gsmExtendedToChar(
-                            GsmAlphabet.charToGsmExtended(sGsmExtendedChars.charAt(i))));
-
-        }
-
-        // Unmappable extended char
-        assertEquals(GsmAlphabet.charToGsm(' '),
-                GsmAlphabet.charToGsmExtended('@'));
-
-        //
-        // gsmToChar()
-        //
-
-        assertEquals('@', GsmAlphabet.gsmToChar(0));
-
-        // `a (a with grave accent) maps to last GSM character
-        assertEquals('\u00e0', GsmAlphabet.gsmToChar(0x7f));
-
-        assertEquals('\uffff',
-                GsmAlphabet.gsmToChar(GsmAlphabet.GSM_EXTENDED_ESCAPE));
-
-        // Out-of-range/unmappable value
-        assertEquals(' ', GsmAlphabet.gsmToChar(0x80));
-
-        //
-        // gsmExtendedToChar()
-        //
-
-        assertEquals('{', GsmAlphabet.gsmExtendedToChar(0x28));
-
-        // No double-escapes
-        assertEquals(' ', GsmAlphabet.gsmExtendedToChar(
-                GsmAlphabet.GSM_EXTENDED_ESCAPE));
-
-        // Reserved for extension to extension table (mapped to space)
-        assertEquals(' ', GsmAlphabet.gsmExtendedToChar(GsmAlphabet.GSM_EXTENDED_ESCAPE));
-
-        // Unmappable (mapped to character in default or national locking shift table)
-        assertEquals('@', GsmAlphabet.gsmExtendedToChar(0));
-        assertEquals('\u00e0', GsmAlphabet.gsmExtendedToChar(0x7f));
-
-        //
-        // stringTo7BitPacked, gsm7BitPackedToString
-        //
-
-        byte[] packed;
-        StringBuilder testString = new StringBuilder(300);
-
-        // Check all alignment cases
-        for (int i = 0; i < 9; i++, testString.append('@')) {
-            packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0);
-            assertEquals(testString.toString(),
-                    GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0]));
-        }
-
-        // Check full non-extended alphabet
-        for (int i = 0; i < 0x80; i++) {
-            char c;
-
-            if (i == GsmAlphabet.GSM_EXTENDED_ESCAPE) {
-                continue;
-            }
-
-            c = GsmAlphabet.gsmToChar(i);
-            testString.append(c);
-
-            // These are all non-extended chars, so it should be
-            // one septet per char
-            assertEquals(1, GsmAlphabet.countGsmSeptets(c));
-        }
-
-        packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0);
-        assertEquals(testString.toString(),
-                GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0]));
-
-        // Test extended chars too
-
-        testString.append(sGsmExtendedChars);
-
-        for (int i = 0, s = sGsmExtendedChars.length(); i < s; i++) {
-            // These are all extended chars, so it should be
-            // two septets per char
-            assertEquals(2, GsmAlphabet.countGsmSeptets(sGsmExtendedChars.charAt(i)));
-
-        }
-
-        packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0);
-        assertEquals(testString.toString(),
-                GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0]));
-
-        // stringTo7BitPacked handles up to 255 septets
-
-        testString.setLength(0);
-        for (int i = 0; i < 255; i++) {
-            testString.append('@');
-        }
-
-        packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0);
-        assertEquals(testString.toString(),
-                GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0]));
-
-        // > 255 septets throws runtime exception
-        testString.append('@');
-
-        try {
-            GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0);
-            fail("expected exception");
-        } catch (EncodeException ex) {
-            // exception expected
-        }
-
-        // Try 254 septets with 127 extended chars
-
-        testString.setLength(0);
-        for (int i = 0; i < (255 / 2); i++) {
-            testString.append('{');
-        }
-
-        packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0);
-        assertEquals(testString.toString(),
-                GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0]));
-
-        // > 255 septets throws runtime exception
-        testString.append('{');
-
-        try {
-            GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0);
-            fail("expected exception");
-        } catch (EncodeException ex) {
-            // exception expected
-        }
-
-        // Reserved for extension to extension table (mapped to space)
-        packed = new byte[]{(byte)(0x1b | 0x80), 0x1b >> 1};
-        assertEquals(" ", GsmAlphabet.gsm7BitPackedToString(packed, 0, 2));
-
-        // Unmappable (mapped to character in default alphabet table)
-        packed[0] = 0x1b;
-        packed[1] = 0x00;
-        assertEquals("@", GsmAlphabet.gsm7BitPackedToString(packed, 0, 2));
-        packed[0] = (byte)(0x1b | 0x80);
-        packed[1] = (byte)(0x7f >> 1);
-        assertEquals("\u00e0", GsmAlphabet.gsm7BitPackedToString(packed, 0, 2));
-
-        //
-        // 8 bit unpacked format
-        //
-        // Note: we compare hex strings here
-        // because Assert doesn't have array comparisons
-
-        byte unpacked[];
-
-        unpacked = IccUtils.hexStringToBytes("566F696365204D61696C");
-        assertEquals("Voice Mail",
-                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length));
-
-        assertEquals(IccUtils.bytesToHexString(unpacked),
-                IccUtils.bytesToHexString(
-                        GsmAlphabet.stringToGsm8BitPacked("Voice Mail")));
-
-        unpacked = GsmAlphabet.stringToGsm8BitPacked(sGsmExtendedChars);
-        // two bytes for every extended char
-        assertEquals(2 * sGsmExtendedChars.length(), unpacked.length);
-        assertEquals(sGsmExtendedChars,
-                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length));
-
-        // should be two bytes per extended char
-        assertEquals(2 * sGsmExtendedChars.length(), unpacked.length);
-
-        // Test truncation of unaligned extended chars
-        unpacked = new byte[3];
-        GsmAlphabet.stringToGsm8BitUnpackedField(sGsmExtendedChars, unpacked,
-                0, unpacked.length);
-
-        // Should be one extended char and an 0xff at the end
-
-        assertEquals(0xff, 0xff & unpacked[2]);
-        assertEquals(sGsmExtendedChars.substring(0, 1),
-                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length));
-
-        // Test truncation of normal chars
-        unpacked = new byte[3];
-        GsmAlphabet.stringToGsm8BitUnpackedField("abcd", unpacked,
-                0, unpacked.length);
-
-        assertEquals("abc",
-                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length));
-
-        // Test truncation of mixed normal and extended chars
-        unpacked = new byte[3];
-        GsmAlphabet.stringToGsm8BitUnpackedField("a{cd", unpacked,
-                0, unpacked.length);
-
-        assertEquals("a{",
-                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length));
-
-        // Test padding after normal char
-        unpacked = new byte[3];
-        GsmAlphabet.stringToGsm8BitUnpackedField("a", unpacked,
-                0, unpacked.length);
-
-        assertEquals("a",
-                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length));
-
-        assertEquals(0xff, 0xff & unpacked[1]);
-        assertEquals(0xff, 0xff & unpacked[2]);
-
-        // Test malformed input -- escape char followed by end of field
-        unpacked[0] = 0;
-        unpacked[1] = 0;
-        unpacked[2] = GsmAlphabet.GSM_EXTENDED_ESCAPE;
-
-        assertEquals("@@",
-                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length));
-
-        // non-zero offset
-        assertEquals("@",
-                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 1, unpacked.length - 1));
-
-        // test non-zero offset
-        unpacked[0] = 0;
-        GsmAlphabet.stringToGsm8BitUnpackedField("abcd", unpacked,
-                1, unpacked.length - 1);
-
-
-        assertEquals(0, unpacked[0]);
-
-        assertEquals("ab",
-                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 1, unpacked.length - 1));
-
-        // test non-zero offset with truncated extended char
-        unpacked[0] = 0;
-
-        GsmAlphabet.stringToGsm8BitUnpackedField("a{", unpacked,
-                1, unpacked.length - 1);
-
-        assertEquals(0, unpacked[0]);
-
-        assertEquals("a",
-                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 1, unpacked.length - 1));
-
-        // Reserved for extension to extension table (mapped to space)
-        unpacked[0] = 0x1b;
-        unpacked[1] = 0x1b;
-        assertEquals(" ", GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, 2));
-
-        // Unmappable (mapped to character in default or national locking shift table)
-        unpacked[1] = 0x00;
-        assertEquals("@", GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, 2));
-        unpacked[1] = 0x7f;
-        assertEquals("\u00e0", GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, 2));
-    }
-
-    @SmallTest
-    public void testGsm8BitUpackedWithEuckr() throws Exception {
-        // Some feature phones in Korea store contacts as euc-kr.
-        // Test this situations.
-        byte unpacked[];
-
-        // Test general alphabet strings.
-        unpacked = IccUtils.hexStringToBytes("61626320646566FF");
-        assertEquals("abc def",
-                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length, "euc-kr"));
-
-        // Test korean strings.
-        unpacked = IccUtils.hexStringToBytes("C5D7BDBAC6AEFF");
-        assertEquals("\uD14C\uC2A4\uD2B8",
-                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length, "euc-kr"));
-
-        // Test gsm Extented Characters.
-        unpacked = GsmAlphabet.stringToGsm8BitPacked(sGsmExtendedChars);
-        assertEquals(sGsmExtendedChars,
-                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length, "euc-kr"));
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java
deleted file mode 100644
index 5950669..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java
+++ /dev/null
@@ -1,538 +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.internal.telephony;
-
-import android.telephony.TelephonyManager;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.internal.telephony.gsm.SmsMessage;
-import com.android.internal.util.HexDump;
-
-import java.util.ArrayList;
-
-public class GsmSmsTest extends AndroidTestCase {
-
-    @SmallTest
-    public void testAddressing() throws Exception {
-        String pdu = "07914151551512f2040B916105551511f100006060605130308A04D4F29C0E";
-        SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-        assertEquals("+14155551212", sms.getServiceCenterAddress());
-        assertEquals("+16505551111", sms.getOriginatingAddress());
-        assertEquals("Test", sms.getMessageBody());
-
-        pdu = "07914151551512f2040B916105551511f100036060924180008A0DA"
-                + "8695DAC2E8FE9296A794E07";
-        sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-        assertEquals("+14155551212", sms.getServiceCenterAddress());
-        assertEquals("+16505551111", sms.getOriginatingAddress());
-        assertEquals("(Subject)Test", sms.getMessageBody());
-    }
-
-    @SmallTest
-    public void testUdh() throws Exception {
-        String pdu = "07914140279510F6440A8111110301003BF56080207130138A8C0B05040B8423F"
-                + "000032A02010106276170706C69636174696F6E2F766E642E7761702E6D6D732D"
-                + "6D65737361676500AF848D0185B4848C8298524E453955304A6D7135514141426"
-                + "66C414141414D7741414236514141414141008D908918802B3135313232393737"
-                + "3638332F545950453D504C4D4E008A808E022B918805810306977F83687474703"
-                + "A2F2F36";
-        SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-        SmsHeader header = sms.getUserDataHeader();
-        assertNotNull(header);
-        assertNotNull(header.concatRef);
-        assertEquals(header.concatRef.refNumber, 42);
-        assertEquals(header.concatRef.msgCount, 2);
-        assertEquals(header.concatRef.seqNumber, 1);
-        assertEquals(header.concatRef.isEightBits, true);
-        assertNotNull(header.portAddrs);
-        assertEquals(header.portAddrs.destPort, 2948);
-        assertEquals(header.portAddrs.origPort, 9200);
-        assertEquals(header.portAddrs.areEightBits, false);
-
-        pdu = "07914140279510F6440A8111110301003BF56080207130238A3B0B05040B8423F"
-                + "000032A0202362E3130322E3137312E3135302F524E453955304A6D7135514141"
-                + "42666C414141414D774141423651414141414100";
-        sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-        header = sms.getUserDataHeader();
-        assertNotNull(header);
-        assertNotNull(header.concatRef);
-        assertEquals(header.concatRef.refNumber, 42);
-        assertEquals(header.concatRef.msgCount, 2);
-        assertEquals(header.concatRef.seqNumber, 2);
-        assertEquals(header.concatRef.isEightBits, true);
-        assertNotNull(header.portAddrs);
-        assertEquals(header.portAddrs.destPort, 2948);
-        assertEquals(header.portAddrs.origPort, 9200);
-        assertEquals(header.portAddrs.areEightBits, false);
-    }
-
-    @SmallTest
-    public void testUcs2() throws Exception {
-        String pdu = "07912160130300F4040B914151245584F600087010807121352B1021220"
-                + "0A900AE00680065006C006C006F";
-        SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-        assertEquals("\u2122\u00a9\u00aehello", sms.getMessageBody());
-    }
-
-    @SmallTest
-    public void testMultipart() throws Exception {
-        /*
-         * Multi-part text SMS with septet data.
-         */
-        String pdu = "07916163838408F6440B816105224431F700007060217175830AA0050003"
-                + "00020162B1582C168BC562B1582C168BC562B1582C168BC562B1582C"
-                + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562B1582C"
-                + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562B1582C"
-                + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562B1582C"
-                + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562";
-        SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-        assertEquals(sms.getMessageBody(),
-                "1111111111111111111111111111111111111111"
-                + "1111111111111111111111111111111111111111"
-                + "1111111111111111111111111111111111111111"
-                + "111111111111111111111111111111111");
-
-        pdu = "07916163838408F6440B816105224431F700007060217185000A23050003"
-                + "00020262B1582C168BC96432994C2693C96432994C2693C96432990C";
-        sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-        assertEquals("1111111222222222222222222222", sms.getMessageBody());
-    }
-
-    @SmallTest
-    public void testCPHSVoiceMail() throws Exception {
-        // "set MWI flag"
-
-        String pdu = "07912160130310F20404D0110041006060627171118A0120";
-
-        SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-
-        assertTrue(sms.isReplace());
-        assertEquals("_@", sms.getOriginatingAddress());
-        assertEquals(" ", sms.getMessageBody());
-        assertTrue(sms.isMWISetMessage());
-
-        // "clear mwi flag"
-
-        pdu = "07912160130310F20404D0100041006021924193352B0120";
-
-        sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-
-        assertTrue(sms.isMWIClearMessage());
-
-        // "clear MWI flag"
-
-        pdu = "07912160130310F20404D0100041006060627161058A0120";
-
-        sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-
-        assertTrue(sms.isReplace());
-        assertEquals("\u0394@", sms.getOriginatingAddress());
-        assertEquals(" ", sms.getMessageBody());
-        assertTrue(sms.isMWIClearMessage());
-    }
-
-    @SmallTest
-    public void testCingularVoiceMail() throws Exception {
-        // "set MWI flag"
-
-        String pdu = "07912180958750F84401800500C87020026195702B06040102000200";
-        SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-
-        assertTrue(sms.isMWISetMessage());
-        assertTrue(sms.isMwiDontStore());
-
-        // "clear mwi flag"
-
-        pdu = "07912180958750F84401800500C07020027160112B06040102000000";
-        sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-
-        assertTrue(sms.isMWIClearMessage());
-        assertTrue(sms.isMwiDontStore());
-    }
-
-    @SmallTest
-    public void testEmailGateway() throws Exception {
-        String pdu = "07914151551512f204038105f300007011103164638a28e6f71b50c687db" +
-                "7076d9357eb7412f7a794e07cdeb6275794c07bde8e5391d247e93f3";
-
-        SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-
-        assertEquals("+14155551212", sms.getServiceCenterAddress());
-        assertTrue(sms.isEmail());
-        assertEquals("foo@example.com", sms.getEmailFrom());
-        assertEquals("foo@example.com", sms.getDisplayOriginatingAddress());
-        // As of https://android-git.corp.google.com/g/#change,9324
-        // getPseudoSubject will always be empty, and any subject is not extracted.
-        assertEquals("", sms.getPseudoSubject());
-        assertEquals("test subject /test body", sms.getDisplayMessageBody());
-        assertEquals("test subject /test body", sms.getEmailBody());
-
-        // email gateway sms test, including gsm extended character set.
-        pdu = "07914151551512f204038105f400007011103105458a29e6f71b50c687db" +
-                "7076d9357eb741af0d0a442fcfe9c23739bfe16d289bdee6b5f1813629";
-
-        sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-
-        assertEquals("+14155551212", sms.getServiceCenterAddress());
-        assertTrue(sms.isEmail());
-        assertEquals("foo@example.com", sms.getDisplayOriginatingAddress());
-        assertEquals("foo@example.com", sms.getEmailFrom());
-        assertEquals("{ testBody[^~\\] }", sms.getDisplayMessageBody());
-        assertEquals("{ testBody[^~\\] }", sms.getEmailBody());
-    }
-
-    @SmallTest
-    public void testExtendedCharacterTable() throws Exception {
-        String pdu = "07914151551512f2040B916105551511f100006080615131728A44D4F29C0E2" +
-                "AE3E96537B94C068DD16179784C2FCB41F4B0985D06B958ADD00FB0E94536AF9749" +
-                "74DA6D281BA00E95E26D509B946FC3DBF87A25D56A04";
-
-        SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-
-        assertEquals("+14155551212", sms.getServiceCenterAddress());
-        assertEquals("+16505551111", sms.getOriginatingAddress());
-        assertEquals("Test extended character table .,-!?@~_\\/&\"';^|:()<{}>[]=%*+#",
-                sms.getMessageBody());
-    }
-
-    // GSM 7 bit tables in String form, Escape (0x1B) replaced with '@'
-    private static final String[] sBasicTables = {
-        // GSM 7 bit default alphabet
-        "@\u00a3$\u00a5\u00e8\u00e9\u00f9\u00ec\u00f2\u00c7\n\u00d8\u00f8\r\u00c5\u00e5\u0394_"
-            + "\u03a6\u0393\u039b\u03a9\u03a0\u03a8\u03a3\u0398\u039e@\u00c6\u00e6\u00df\u00c9"
-            + " !\"#\u00a4%&'()*+,-./0123456789:;<=>?\u00a1ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c4\u00d6"
-            + "\u00d1\u00dc\u00a7\u00bfabcdefghijklmnopqrstuvwxyz\u00e4\u00f6\u00f1\u00fc\u00e0",
-
-        // Turkish locking shift table
-        "@\u00a3$\u00a5\u20ac\u00e9\u00f9\u0131\u00f2\u00c7\n\u011e\u011f\r\u00c5\u00e5\u0394_"
-            + "\u03a6\u0393\u039b\u03a9\u03a0\u03a8\u03a3\u0398\u039e@\u015e\u015f\u00df\u00c9"
-            + " !\"#\u00a4%&'()*+,-./0123456789:;<=>?\u0130ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c4\u00d6"
-            + "\u00d1\u00dc\u00a7\u00e7abcdefghijklmnopqrstuvwxyz\u00e4\u00f6\u00f1\u00fc\u00e0",
-
-        // no locking shift table defined for Spanish
-        "",
-
-        // Portuguese locking shift table
-        "@\u00a3$\u00a5\u00ea\u00e9\u00fa\u00ed\u00f3\u00e7\n\u00d4\u00f4\r\u00c1\u00e1\u0394_"
-            + "\u00aa\u00c7\u00c0\u221e^\\\u20ac\u00d3|@\u00c2\u00e2\u00ca\u00c9 !\"#\u00ba%&'()"
-            + "*+,-./0123456789:;<=>?\u00cdABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c3\u00d5\u00da\u00dc"
-            + "\u00a7~abcdefghijklmnopqrstuvwxyz\u00e3\u00f5`\u00fc\u00e0"
-    };
-
-    @SmallTest
-    public void testFragmentText() throws Exception {
-        boolean isGsmPhone = (TelephonyManager.getDefault().getPhoneType() ==
-                TelephonyManager.PHONE_TYPE_GSM);
-
-        // Valid 160 character 7-bit text.
-        String text = "123456789012345678901234567890123456789012345678901234567890" +
-                "1234567890123456789012345678901234567890123456789012345678901234567890" +
-                "123456789012345678901234567890";
-        SmsMessageBase.TextEncodingDetails ted = SmsMessage.calculateLength(text, false);
-        assertEquals(1, ted.msgCount);
-        assertEquals(160, ted.codeUnitCount);
-        assertEquals(1, ted.codeUnitSize);
-        assertEquals(0, ted.languageTable);
-        assertEquals(0, ted.languageShiftTable);
-        if (isGsmPhone) {
-            ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text);
-            assertEquals(1, fragments.size());
-        }
-
-        // Valid 161 character 7-bit text.
-        text = "123456789012345678901234567890123456789012345678901234567890" +
-                "1234567890123456789012345678901234567890123456789012345678901234567890" +
-                "1234567890123456789012345678901";
-        ted = SmsMessage.calculateLength(text, false);
-        assertEquals(2, ted.msgCount);
-        assertEquals(161, ted.codeUnitCount);
-        assertEquals(1, ted.codeUnitSize);
-        assertEquals(0, ted.languageTable);
-        assertEquals(0, ted.languageShiftTable);
-        if (isGsmPhone) {
-            ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text);
-            assertEquals(2, fragments.size());
-            assertEquals(text, fragments.get(0) + fragments.get(1));
-            assertEquals(153, fragments.get(0).length());
-            assertEquals(8, fragments.get(1).length());
-        }
-    }
-
-    @SmallTest
-    public void testFragmentTurkishText() throws Exception {
-        boolean isGsmPhone = (TelephonyManager.getDefault().getPhoneType() ==
-                TelephonyManager.PHONE_TYPE_GSM);
-
-        int[] oldTables = GsmAlphabet.getEnabledSingleShiftTables();
-        int[] turkishTable = { 1 };
-        GsmAlphabet.setEnabledSingleShiftTables(turkishTable);
-
-        // Valid 77 character text with Turkish characters.
-        String text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" +
-                "ĞŞİğşıĞŞİğşıĞŞİğş";
-        SmsMessageBase.TextEncodingDetails ted = SmsMessage.calculateLength(text, false);
-        assertEquals(1, ted.msgCount);
-        assertEquals(154, ted.codeUnitCount);
-        assertEquals(1, ted.codeUnitSize);
-        assertEquals(0, ted.languageTable);
-        assertEquals(1, ted.languageShiftTable);
-        if (isGsmPhone) {
-            ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text);
-            assertEquals(1, fragments.size());
-            assertEquals(text, fragments.get(0));
-            assertEquals(77, fragments.get(0).length());
-        }
-
-        // Valid 78 character text with Turkish characters.
-        text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" +
-                "ĞŞİğşıĞŞİğşıĞŞİğşı";
-        ted = SmsMessage.calculateLength(text, false);
-        assertEquals(2, ted.msgCount);
-        assertEquals(156, ted.codeUnitCount);
-        assertEquals(1, ted.codeUnitSize);
-        assertEquals(0, ted.languageTable);
-        assertEquals(1, ted.languageShiftTable);
-        if (isGsmPhone) {
-            ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text);
-            assertEquals(2, fragments.size());
-            assertEquals(text, fragments.get(0) + fragments.get(1));
-            assertEquals(74, fragments.get(0).length());
-            assertEquals(4, fragments.get(1).length());
-        }
-
-        // Valid 160 character text with Turkish characters.
-        text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" +
-                "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğ" +
-                "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı";
-        ted = SmsMessage.calculateLength(text, false);
-        assertEquals(3, ted.msgCount);
-        assertEquals(320, ted.codeUnitCount);
-        assertEquals(1, ted.codeUnitSize);
-        assertEquals(0, ted.languageTable);
-        assertEquals(1, ted.languageShiftTable);
-        if (isGsmPhone) {
-            ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text);
-            assertEquals(3, fragments.size());
-            assertEquals(text, fragments.get(0) + fragments.get(1) + fragments.get(2));
-            assertEquals(74, fragments.get(0).length());
-            assertEquals(74, fragments.get(1).length());
-            assertEquals(12, fragments.get(2).length());
-        }
-
-        GsmAlphabet.setEnabledSingleShiftTables(oldTables);
-    }
-
-
-    @SmallTest
-    public void testDecode() throws Exception {
-        decodeSingle(0);    // default table
-        decodeSingle(1);    // Turkish locking shift table
-        decodeSingle(3);    // Portuguese locking shift table
-    }
-
-    private void decodeSingle(int language) throws Exception {
-        byte[] septets = new byte[(7 * 128 + 7) / 8];
-
-        int bitOffset = 0;
-
-        for (int i = 0; i < 128; i++) {
-            int v;
-            if (i == 0x1b) {
-                // extended escape char
-                v = 0;
-            } else {
-                v = i;
-            }
-
-            int byteOffset = bitOffset / 8;
-            int shift = bitOffset % 8;
-
-            septets[byteOffset] |= v << shift;
-
-            if (shift > 1) {
-                septets[byteOffset + 1] = (byte) (v >> (8 - shift));
-            }
-
-            bitOffset += 7;
-        }
-
-        String decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, 128, 0, language, 0);
-        byte[] reEncoded = GsmAlphabet.stringToGsm7BitPacked(decoded, language, 0);
-
-        assertEquals(sBasicTables[language], decoded);
-
-        // reEncoded has the count septets byte at the front
-        assertEquals(septets.length + 1, reEncoded.length);
-
-        for (int i = 0; i < septets.length; i++) {
-            assertEquals(septets[i], reEncoded[i + 1]);
-        }
-    }
-
-    private static final int GSM_ESCAPE_CHARACTER = 0x1b;
-
-    private static final String[] sExtendedTables = {
-        // GSM 7 bit default alphabet extension table
-        "\f^{}\\[~]|\u20ac",
-
-        // Turkish single shift extension table
-        "\f^{}\\[~]|\u011e\u0130\u015e\u00e7\u20ac\u011f\u0131\u015f",
-
-        // Spanish single shift extension table
-        "\u00e7\f^{}\\[~]|\u00c1\u00cd\u00d3\u00da\u00e1\u20ac\u00ed\u00f3\u00fa",
-
-        // Portuguese single shift extension table
-        "\u00ea\u00e7\f\u00d4\u00f4\u00c1\u00e1\u03a6\u0393^\u03a9\u03a0\u03a8\u03a3\u0398\u00ca"
-            + "{}\\[~]|\u00c0\u00cd\u00d3\u00da\u00c3\u00d5\u00c2\u20ac\u00ed\u00f3\u00fa\u00e3"
-            + "\u00f5\u00e2"
-    };
-
-    private static final int[][] sExtendedTableIndexes = {
-        {0x0a, 0x14, 0x28, 0x29, 0x2f, 0x3c, 0x3d, 0x3e, 0x40, 0x65},
-        {0x0a, 0x14, 0x28, 0x29, 0x2f, 0x3c, 0x3d, 0x3e, 0x40, 0x47, 0x49, 0x53, 0x63,
-                0x65, 0x67, 0x69, 0x73},
-        {0x09, 0x0a, 0x14, 0x28, 0x29, 0x2f, 0x3c, 0x3d, 0x3e, 0x40, 0x41, 0x49, 0x4f,
-                0x55, 0x61, 0x65, 0x69, 0x6f, 0x75},
-        {0x05, 0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x0f, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-                0x18, 0x19, 0x1f, 0x28, 0x29, 0x2f, 0x3c, 0x3d, 0x3e, 0x40, 0x41, 0x49,
-                0x4f, 0x55, 0x5b, 0x5c, 0x61, 0x65, 0x69, 0x6f, 0x75, 0x7b, 0x7c, 0x7f}
-    };
-
-    @SmallTest
-    public void testDecodeExtended() throws Exception {
-        for (int language = 0; language < 3; language++) {
-            int[] tableIndex = sExtendedTableIndexes[language];
-            int numSeptets = tableIndex.length * 2;  // two septets per extended char
-            byte[] septets = new byte[(7 * numSeptets + 7) / 8];
-
-            int bitOffset = 0;
-
-            for (int v : tableIndex) {
-                // escape character
-                int byteOffset = bitOffset / 8;
-                int shift = bitOffset % 8;
-
-                septets[byteOffset] |= GSM_ESCAPE_CHARACTER << shift;
-
-                if (shift > 1) {
-                    septets[byteOffset + 1] = (byte) (GSM_ESCAPE_CHARACTER >> (8 - shift));
-                }
-
-                bitOffset += 7;
-
-                // extended table index
-                byteOffset = bitOffset / 8;
-                shift = bitOffset % 8;
-
-                septets[byteOffset] |= v << shift;
-
-                if (shift > 1) {
-                    septets[byteOffset + 1] = (byte) (v >> (8 - shift));
-                }
-
-                bitOffset += 7;
-            }
-
-            String decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, numSeptets, 0,
-                    0, language);
-            byte[] reEncoded = GsmAlphabet.stringToGsm7BitPacked(decoded, 0, language);
-
-            assertEquals(sExtendedTables[language], decoded);
-
-            // reEncoded has the count septets byte at the front
-            assertEquals(septets.length + 1, reEncoded.length);
-
-            for (int i = 0; i < septets.length; i++) {
-                assertEquals(septets[i], reEncoded[i + 1]);
-            }
-        }
-    }
-
-    @SmallTest
-    public void testDecodeExtendedFallback() throws Exception {
-        // verify that unmapped characters in extension table fall back to locking shift table
-        for (int language = 0; language < 3; language++) {
-            int[] tableIndex = sExtendedTableIndexes[language];
-            int numChars = 128 - tableIndex.length;
-            int numSeptets = numChars * 2;  // two septets per extended char
-            byte[] septets = new byte[(7 * numSeptets + 7) / 8];
-
-            int tableOffset = 0;
-            int bitOffset = 0;
-
-            StringBuilder defaultTable = new StringBuilder(128);
-            StringBuilder turkishTable = new StringBuilder(128);
-            StringBuilder portugueseTable = new StringBuilder(128);
-
-            for (char c = 0; c < 128; c++) {
-                // skip characters that are present in the current extension table
-                if (tableOffset < tableIndex.length && tableIndex[tableOffset] == c) {
-                    tableOffset++;
-                    continue;
-                }
-
-                // escape character
-                int byteOffset = bitOffset / 8;
-                int shift = bitOffset % 8;
-
-                septets[byteOffset] |= GSM_ESCAPE_CHARACTER << shift;
-
-                if (shift > 1) {
-                    septets[byteOffset + 1] = (byte) (GSM_ESCAPE_CHARACTER >> (8 - shift));
-                }
-
-                bitOffset += 7;
-
-                // extended table index
-                byteOffset = bitOffset / 8;
-                shift = bitOffset % 8;
-
-                septets[byteOffset] |= c << shift;
-
-                if (shift > 1) {
-                    septets[byteOffset + 1] = (byte) (c >> (8 - shift));
-                }
-
-                bitOffset += 7;
-
-                if (c == GsmAlphabet.GSM_EXTENDED_ESCAPE) {
-                    // double Escape maps to space character
-                    defaultTable.append(' ');
-                    turkishTable.append(' ');
-                    portugueseTable.append(' ');
-                } else {
-                    // other unmapped chars map to the default or locking shift table
-                    defaultTable.append(sBasicTables[0].charAt(c));
-                    turkishTable.append(sBasicTables[1].charAt(c));
-                    portugueseTable.append(sBasicTables[3].charAt(c));
-                }
-            }
-
-            String decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, numSeptets, 0,
-                    0, language);
-
-            assertEquals(defaultTable.toString(), decoded);
-
-            decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, numSeptets, 0, 1, language);
-            assertEquals(turkishTable.toString(), decoded);
-
-            decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, numSeptets, 0, 3, language);
-            assertEquals(portugueseTable.toString(), decoded);
-        }
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/IccServiceTableTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/IccServiceTableTest.java
deleted file mode 100644
index c89f33a..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/IccServiceTableTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2011 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.internal.telephony;
-
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-/**
- * Test IccServiceTable class.
- */
-public class IccServiceTableTest extends AndroidTestCase {
-
-    static class TestIccServiceTable extends IccServiceTable {
-        public enum TestIccService {
-            SERVICE1,
-            SERVICE2,
-            SERVICE3,
-            SERVICE4
-        }
-
-        public TestIccServiceTable(byte[] table) {
-            super(table);
-        }
-
-        public boolean isAvailable(TestIccService service) {
-            return super.isAvailable(service.ordinal());
-        }
-
-        @Override
-        protected String getTag() {
-            return "TestIccServiceTable";
-        }
-
-        @Override
-        protected Object[] getValues() {
-            return TestIccService.values();
-        }
-    }
-
-    @SmallTest
-    public void testIccServiceTable() {
-        byte[] noServices = {0x00};
-        byte[] service1 = {0x01};
-        byte[] service4 = {0x08};
-        byte[] allServices = {0x0f};
-
-        TestIccServiceTable testTable1 = new TestIccServiceTable(noServices);
-        assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE1));
-        assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE2));
-        assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE3));
-        assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE4));
-
-        TestIccServiceTable testTable2 = new TestIccServiceTable(service1);
-        assertTrue(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE1));
-        assertFalse(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE2));
-        assertFalse(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE3));
-        assertFalse(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE4));
-
-        TestIccServiceTable testTable3 = new TestIccServiceTable(service4);
-        assertFalse(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE1));
-        assertFalse(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE2));
-        assertFalse(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE3));
-        assertTrue(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE4));
-
-        TestIccServiceTable testTable4 = new TestIccServiceTable(allServices);
-        assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE1));
-        assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE2));
-        assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE3));
-        assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE4));
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/IntRangeManagerTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/IntRangeManagerTest.java
deleted file mode 100644
index 79dca39..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/IntRangeManagerTest.java
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * Copyright (C) 2011 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.internal.telephony;
-
-import android.test.AndroidTestCase;
-
-import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
-
-import java.util.ArrayList;
-
-/**
- * Test cases for the IntRangeManager class.
- */
-public class IntRangeManagerTest extends AndroidTestCase {
-
-    private static final int SMS_CB_CODE_SCHEME_MIN = 0;
-    private static final int SMS_CB_CODE_SCHEME_MAX = 255;
-
-    private static final int FLAG_START_UPDATE_CALLED   = 0x01;
-    private static final int FLAG_ADD_RANGE_CALLED      = 0x02;
-    private static final int FLAG_FINISH_UPDATE_CALLED  = 0x04;
-
-    private static final int ALL_FLAGS_SET = FLAG_START_UPDATE_CALLED | FLAG_ADD_RANGE_CALLED |
-            FLAG_FINISH_UPDATE_CALLED;
-
-    /** Dummy IntRangeManager for testing. */
-    class TestIntRangeManager extends IntRangeManager {
-        ArrayList<SmsBroadcastConfigInfo> mConfigList =
-                new ArrayList<SmsBroadcastConfigInfo>();
-
-        int flags;
-        boolean finishUpdateReturnValue = true;
-
-        /**
-         * Called when the list of enabled ranges has changed. This will be
-         * followed by zero or more calls to {@link #addRange} followed by
-         * a call to {@link #finishUpdate}.
-         */
-        protected void startUpdate() {
-            mConfigList.clear();
-            flags |= FLAG_START_UPDATE_CALLED;
-        }
-
-        /**
-         * Called after {@link #startUpdate} to indicate a range of enabled
-         * values.
-         * @param startId the first id included in the range
-         * @param endId the last id included in the range
-         */
-        protected void addRange(int startId, int endId, boolean selected) {
-            mConfigList.add(new SmsBroadcastConfigInfo(startId, endId,
-                        SMS_CB_CODE_SCHEME_MIN, SMS_CB_CODE_SCHEME_MAX, selected));
-            flags |= FLAG_ADD_RANGE_CALLED;
-        }
-
-        /**
-         * Called to indicate the end of a range update started by the
-         * previous call to {@link #startUpdate}.
-         */
-        protected boolean finishUpdate() {
-            flags |= FLAG_FINISH_UPDATE_CALLED;
-            return finishUpdateReturnValue;
-        }
-
-        /** Reset the object for the next test case. */
-        void reset() {
-            flags = 0;
-            mConfigList.clear();
-        }
-    }
-
-    public void testEmptyRangeManager() {
-        TestIntRangeManager testManager = new TestIntRangeManager();
-        assertEquals("expecting empty configlist", 0, testManager.mConfigList.size());
-    }
-
-    private void checkConfigInfo(SmsBroadcastConfigInfo info, int fromServiceId,
-            int toServiceId, int fromCodeScheme, int toCodeScheme, boolean selected) {
-        assertEquals("fromServiceId", fromServiceId, info.getFromServiceId());
-        assertEquals("toServiceId", toServiceId, info.getToServiceId());
-        assertEquals("fromCodeScheme", fromCodeScheme, info.getFromCodeScheme());
-        assertEquals("toCodeScheme", toCodeScheme, info.getToCodeScheme());
-        assertEquals("selected", selected, info.isSelected());
-    }
-
-    public void testAddSingleChannel() {
-        TestIntRangeManager testManager = new TestIntRangeManager();
-        assertEquals("flags before test", 0, testManager.flags);
-        assertTrue("enabling range", testManager.enableRange(123, 123, "client1"));
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 123, 123, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        testManager.reset();
-        assertTrue("updating ranges", testManager.updateRanges());
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 123, 123, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-    }
-
-    public void testRemoveSingleChannel() {
-        TestIntRangeManager testManager = new TestIntRangeManager();
-        assertTrue("enabling range", testManager.enableRange(123, 123, "client1"));
-        assertEquals("flags after enable", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        testManager.reset();
-        assertTrue("disabling range", testManager.disableRange(123, 123, "client1"));
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 123, 123, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, false);
-        testManager.reset();
-        assertTrue("updating ranges", testManager.updateRanges());
-        assertEquals("flags after test", FLAG_START_UPDATE_CALLED | FLAG_FINISH_UPDATE_CALLED,
-                testManager.flags);
-        assertEquals("configlist size", 0, testManager.mConfigList.size());
-    }
-
-    public void testRemoveBadChannel() {
-        TestIntRangeManager testManager = new TestIntRangeManager();
-        assertFalse("disabling missing range", testManager.disableRange(123, 123, "client1"));
-        assertEquals("flags after test", 0, testManager.flags);
-        assertEquals("configlist size", 0, testManager.mConfigList.size());
-    }
-
-    public void testAddTwoChannels() {
-        TestIntRangeManager testManager = new TestIntRangeManager();
-        assertEquals("flags before test", 0, testManager.flags);
-        assertTrue("enabling range 1", testManager.enableRange(100, 120, "client1"));
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 100, 120, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        testManager.reset();
-        assertTrue("enabling range 2", testManager.enableRange(200, 250, "client2"));
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 200, 250, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        testManager.reset();
-        assertTrue("updating ranges", testManager.updateRanges());
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 2, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 100, 120, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        checkConfigInfo(testManager.mConfigList.get(1), 200, 250, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-    }
-
-    public void testOverlappingChannels() {
-        TestIntRangeManager testManager = new TestIntRangeManager();
-        assertEquals("flags before test", 0, testManager.flags);
-        assertTrue("enabling range 1", testManager.enableRange(100, 200, "client1"));
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 100, 200, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        testManager.reset();
-        assertTrue("enabling range 2", testManager.enableRange(150, 250, "client2"));
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 201, 250, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        testManager.reset();
-        assertTrue("updating ranges", testManager.updateRanges());
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 100, 250, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        testManager.reset();
-        assertTrue("disabling range 1", testManager.disableRange(100, 200, "client1"));
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 100, 149, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, false);
-        testManager.reset();
-        assertTrue("disabling range 2", testManager.disableRange(150, 250, "client2"));
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 150, 250, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, false);
-        testManager.reset();
-        assertTrue("updating ranges", testManager.updateRanges());
-        assertEquals("flags after test", FLAG_START_UPDATE_CALLED | FLAG_FINISH_UPDATE_CALLED,
-                testManager.flags);
-        assertEquals("configlist size", 0, testManager.mConfigList.size());
-    }
-
-    public void testOverlappingChannels2() {
-        TestIntRangeManager testManager = new TestIntRangeManager();
-        assertEquals("flags before test", 0, testManager.flags);
-        assertTrue("enabling range 1", testManager.enableRange(100, 200, "client1"));
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 100, 200, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        testManager.reset();
-        assertTrue("enabling range 2", testManager.enableRange(150, 250, "client2"));
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 201, 250, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        testManager.reset();
-        assertTrue("disabling range 2", testManager.disableRange(150, 250, "client2"));
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 201, 250, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, false);
-        testManager.reset();
-        assertTrue("updating ranges", testManager.updateRanges());
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 100, 200, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        testManager.reset();
-        assertTrue("disabling range 1", testManager.disableRange(100, 200, "client1"));
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 100, 200, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, false);
-    }
-
-    public void testMultipleOverlappingChannels() {
-        TestIntRangeManager testManager = new TestIntRangeManager();
-        assertEquals("flags before test", 0, testManager.flags);
-        assertTrue("enabling range 1", testManager.enableRange(67, 9999, "client1"));
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 67, 9999, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        testManager.reset();
-        assertTrue("enabling range 2", testManager.enableRange(150, 250, "client2"));
-        assertEquals("flags after test", 0, testManager.flags);
-        assertEquals("configlist size", 0, testManager.mConfigList.size());
-        testManager.reset();
-        assertTrue("enabling range 3", testManager.enableRange(25, 75, "client3"));
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 25, 66, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        testManager.reset();
-        assertTrue("enabling range 4", testManager.enableRange(12, 500, "client4"));
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 12, 24, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        testManager.reset();
-        assertTrue("enabling range 5", testManager.enableRange(8000, 9998, "client5"));
-        assertEquals("flags after test", 0, testManager.flags);
-        assertEquals("configlist size", 0, testManager.mConfigList.size());
-        testManager.reset();
-        assertTrue("enabling range 6", testManager.enableRange(50000, 65535, "client6"));
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 50000, 65535, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        testManager.reset();
-        assertTrue("updating ranges", testManager.updateRanges());
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 2, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 12, 9999, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        checkConfigInfo(testManager.mConfigList.get(1), 50000, 65535, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        testManager.reset();
-        assertTrue("disabling range 1", testManager.disableRange(67, 9999, "client1"));
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 2, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 501, 7999, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, false);
-        checkConfigInfo(testManager.mConfigList.get(1), 9999, 9999, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, false);
-        testManager.reset();
-        assertTrue("updating ranges", testManager.updateRanges());
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 3, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 12, 500, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        checkConfigInfo(testManager.mConfigList.get(1), 8000, 9998, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        checkConfigInfo(testManager.mConfigList.get(2), 50000, 65535, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        testManager.reset();
-        assertTrue("disabling range 4", testManager.disableRange(12, 500, "client4"));
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 3, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 12, 24, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, false);
-        checkConfigInfo(testManager.mConfigList.get(1), 76, 149, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, false);
-        checkConfigInfo(testManager.mConfigList.get(2), 251, 500, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, false);
-        testManager.reset();
-        assertTrue("updating ranges", testManager.updateRanges());
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 4, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 25, 75, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        checkConfigInfo(testManager.mConfigList.get(1), 150, 250, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        checkConfigInfo(testManager.mConfigList.get(2), 8000, 9998, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        checkConfigInfo(testManager.mConfigList.get(3), 50000, 65535, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        testManager.reset();
-        assertTrue("disabling range 5", testManager.disableRange(8000, 9998, "client5"));
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 8000, 9998, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, false);
-        testManager.reset();
-        assertTrue("updating ranges", testManager.updateRanges());
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 3, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 25, 75, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        checkConfigInfo(testManager.mConfigList.get(1), 150, 250, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        checkConfigInfo(testManager.mConfigList.get(2), 50000, 65535, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        testManager.reset();
-        assertTrue("disabling range 6", testManager.disableRange(50000, 65535, "client6"));
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 50000, 65535, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, false);
-        testManager.reset();
-        assertTrue("updating ranges", testManager.updateRanges());
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 2, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 25, 75, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        checkConfigInfo(testManager.mConfigList.get(1), 150, 250, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        testManager.reset();
-        assertTrue("disabling range 2", testManager.disableRange(150, 250, "client2"));
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 150, 250, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, false);
-        testManager.reset();
-        assertTrue("updating ranges", testManager.updateRanges());
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 25, 75, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, true);
-        testManager.reset();
-        assertTrue("disabling range 3", testManager.disableRange(25, 75, "client3"));
-        assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
-        assertEquals("configlist size", 1, testManager.mConfigList.size());
-        checkConfigInfo(testManager.mConfigList.get(0), 25, 75, SMS_CB_CODE_SCHEME_MIN,
-                SMS_CB_CODE_SCHEME_MAX, false);
-        testManager.reset();
-        assertTrue("updating ranges", testManager.updateRanges());
-        assertEquals("flags after test", FLAG_START_UPDATE_CALLED | FLAG_FINISH_UPDATE_CALLED,
-                testManager.flags);
-        assertEquals("configlist size", 0, testManager.mConfigList.size());
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java
deleted file mode 100644
index 868c76d..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java
+++ /dev/null
@@ -1,75 +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.internal.telephony;
-
-import com.android.internal.telephony.MccTable;
-
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import android.util.Log;
-
-public class MccTableTest extends AndroidTestCase {
-    private final static String LOG_TAG = "GSM";
-
-    @SmallTest
-    public void testTimeZone() throws Exception {
-        assertEquals(MccTable.defaultTimeZoneForMcc(208), "ECT");
-        assertEquals(MccTable.defaultTimeZoneForMcc(232), "Europe/Vienna");
-        assertEquals(MccTable.defaultTimeZoneForMcc(655), "Africa/Johannesburg");
-        assertEquals(MccTable.defaultTimeZoneForMcc(440), "Asia/Tokyo");
-        assertEquals(MccTable.defaultTimeZoneForMcc(441), "Asia/Tokyo");
-        assertEquals(MccTable.defaultTimeZoneForMcc(525), "Asia/Singapore");
-        assertEquals(MccTable.defaultTimeZoneForMcc(240), null);  // tz not defined, hence default
-        assertEquals(MccTable.defaultTimeZoneForMcc(0), null);    // mcc not defined, hence default
-        assertEquals(MccTable.defaultTimeZoneForMcc(2000), null); // mcc not defined, hence default
-    }
-
-    @SmallTest
-    public void testCountryCode() throws Exception {
-        assertEquals(MccTable.countryCodeForMcc(270), "lu");
-        assertEquals(MccTable.countryCodeForMcc(202), "gr");
-        assertEquals(MccTable.countryCodeForMcc(750), "fk");
-        assertEquals(MccTable.countryCodeForMcc(646), "mg");
-        assertEquals(MccTable.countryCodeForMcc(314), "us");
-        assertEquals(MccTable.countryCodeForMcc(300), "");  // mcc not defined, hence default
-        assertEquals(MccTable.countryCodeForMcc(0), "");    // mcc not defined, hence default
-        assertEquals(MccTable.countryCodeForMcc(2000), ""); // mcc not defined, hence default
-    }
-
-    @SmallTest
-    public void testLang() throws Exception {
-        assertEquals(MccTable.defaultLanguageForMcc(311), "en");
-        assertEquals(MccTable.defaultLanguageForMcc(232), "de");
-        assertEquals(MccTable.defaultLanguageForMcc(230), "cs");
-        assertEquals(MccTable.defaultLanguageForMcc(204), "nl");
-        assertEquals(MccTable.defaultLanguageForMcc(274), null);  // lang not defined, hence default
-        assertEquals(MccTable.defaultLanguageForMcc(0), null);    // mcc not defined, hence default
-        assertEquals(MccTable.defaultLanguageForMcc(2000), null); // mcc not defined, hence default
-    }
-
-    @SmallTest
-    public void testSmDigits() throws Exception {
-        assertEquals(MccTable.smallestDigitsMccForMnc(312), 3);
-        assertEquals(MccTable.smallestDigitsMccForMnc(430), 2);
-        assertEquals(MccTable.smallestDigitsMccForMnc(365), 3);
-        assertEquals(MccTable.smallestDigitsMccForMnc(536), 2);
-        assertEquals(MccTable.smallestDigitsMccForMnc(352), 2);  // sd not defined, hence default
-        assertEquals(MccTable.smallestDigitsMccForMnc(0), 2);    // mcc not defined, hence default
-        assertEquals(MccTable.smallestDigitsMccForMnc(2000), 2); // mcc not defined, hence default
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/NeighboringCellInfoTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/NeighboringCellInfoTest.java
deleted file mode 100644
index b63dc71..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/NeighboringCellInfoTest.java
+++ /dev/null
@@ -1,79 +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.
- */
-package com.android.internal.telephony;
-
-import android.os.Parcel;
-import android.test.AndroidTestCase;
-import android.telephony.NeighboringCellInfo;
-import android.test. suitebuilder.annotation.SmallTest;
-
-import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_EDGE;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_GPRS;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_UMTS;
-
-public class NeighboringCellInfoTest extends AndroidTestCase {
-    @SmallTest
-    public void testConstructor() {
-        int rssi = 31;
-        NeighboringCellInfo nc;
-
-        nc = new NeighboringCellInfo(rssi, "FFFFFFF", NETWORK_TYPE_EDGE);
-        assertEquals(NETWORK_TYPE_EDGE, nc.getNetworkType());
-        assertEquals(rssi, nc.getRssi());
-        assertEquals(0xfff, nc.getLac());
-        assertEquals(0xffff, nc.getCid());
-        assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getPsc());
-
-        nc = new NeighboringCellInfo(rssi, "1FF", NETWORK_TYPE_UMTS);
-        assertEquals(NETWORK_TYPE_UMTS, nc.getNetworkType());
-        assertEquals(rssi, nc.getRssi());
-        assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getCid());
-        assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getLac());
-        assertEquals(0x1ff, nc.getPsc());
-
-        nc = new NeighboringCellInfo(rssi, "1FF", NETWORK_TYPE_UNKNOWN);
-        assertEquals(NETWORK_TYPE_UNKNOWN, nc.getNetworkType());
-        assertEquals(rssi, nc.getRssi());
-        assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getCid());
-        assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getLac());
-        assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getPsc());
-    }
-
-    @SmallTest
-    public void testParcel() {
-        int rssi = 20;
-
-        NeighboringCellInfo nc = new NeighboringCellInfo(rssi, "12345678", NETWORK_TYPE_GPRS);
-        assertEquals(NETWORK_TYPE_GPRS, nc.getNetworkType());
-        assertEquals(rssi, nc.getRssi());
-        assertEquals(0x1234, nc.getLac());
-        assertEquals(0x5678, nc.getCid());
-        assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getPsc());
-
-        Parcel p = Parcel.obtain();
-        p.setDataPosition(0);
-        nc.writeToParcel(p, 0);
-
-        p.setDataPosition(0);
-        NeighboringCellInfo nw = new NeighboringCellInfo(p);
-        assertEquals(NETWORK_TYPE_GPRS, nw.getNetworkType());
-        assertEquals(rssi, nw.getRssi());
-        assertEquals(0x1234, nw.getLac());
-        assertEquals(0x5678, nw.getCid());
-        assertEquals(NeighboringCellInfo.UNKNOWN_CID, nw.getPsc());
-     }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
deleted file mode 100644
index db670f8..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
+++ /dev/null
@@ -1,657 +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.internal.telephony;
-
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.text.SpannableStringBuilder;
-import android.telephony.PhoneNumberUtils;
-
-public class PhoneNumberUtilsTest extends AndroidTestCase {
-
-    @SmallTest
-    public void testExtractNetworkPortion() throws Exception {
-        assertEquals(
-                "+17005554141",
-                PhoneNumberUtils.extractNetworkPortion("+17005554141")
-        );
-
-        assertEquals(
-                "+17005554141",
-                PhoneNumberUtils.extractNetworkPortion("+1 (700).555-4141")
-        );
-
-        assertEquals(
-                "17005554141",
-                PhoneNumberUtils.extractNetworkPortion("1 (700).555-4141")
-        );
-
-        // This may seem wrong, but it's probably ok
-        assertEquals(
-                "17005554141*#",
-                PhoneNumberUtils.extractNetworkPortion("1 (700).555-4141*#")
-        );
-
-        assertEquals(
-                "170055541NN",
-                PhoneNumberUtils.extractNetworkPortion("1 (700).555-41NN")
-        );
-
-        assertEquals(
-                "170055541NN",
-                PhoneNumberUtils.extractNetworkPortion("1 (700).555-41NN,1234")
-        );
-
-        assertEquals(
-                "170055541NN",
-                PhoneNumberUtils.extractNetworkPortion("1 (700).555-41NN;1234")
-        );
-
-        // An MMI string is unperterbed, even though it contains a
-        // (valid in this case) embedded +
-        assertEquals(
-                "**21**17005554141#",
-                PhoneNumberUtils.extractNetworkPortion("**21**+17005554141#")
-                //TODO this is the correct result, although the above
-                //result has been returned since change 31776
-                //"**21**+17005554141#"
-        );
-
-        assertEquals("", PhoneNumberUtils.extractNetworkPortion(""));
-
-        assertEquals("", PhoneNumberUtils.extractNetworkPortion(",1234"));
-
-        byte [] b = new byte[20];
-        b[0] = (byte) 0x81; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55;
-        b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0;
-        assertEquals("17005550020",
-            PhoneNumberUtils.calledPartyBCDToString(b, 0, 7));
-
-        b[0] = (byte) 0x80; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55;
-        b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0;
-        assertEquals("17005550020",
-            PhoneNumberUtils.calledPartyBCDToString(b, 0, 7));
-
-        b[0] = (byte) 0x90; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55;
-        b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0;
-        assertEquals("+17005550020",
-            PhoneNumberUtils.calledPartyBCDToString(b, 0, 7));
-
-        b[0] = (byte) 0x91; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55;
-        b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0;
-        assertEquals("+17005550020",
-                PhoneNumberUtils.calledPartyBCDToString(b, 0, 7));
-
-        byte[] bRet = PhoneNumberUtils.networkPortionToCalledPartyBCD("+17005550020");
-        assertEquals(7, bRet.length);
-        for (int i = 0; i < 7; i++) {
-            assertEquals(b[i], bRet[i]);
-        }
-
-        bRet = PhoneNumberUtils.networkPortionToCalledPartyBCDWithLength("+17005550020");
-        assertEquals(8, bRet.length);
-        assertEquals(bRet[0], 7);
-        for (int i = 1; i < 8; i++) {
-            assertEquals(b[i - 1], bRet[i]);
-        }
-
-        bRet = PhoneNumberUtils.networkPortionToCalledPartyBCD("7005550020");
-        assertEquals("7005550020",
-            PhoneNumberUtils.calledPartyBCDToString(bRet, 0, bRet.length));
-
-        b[0] = (byte) 0x81; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55;
-        b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xB0;
-        assertEquals("17005550020#",
-            PhoneNumberUtils.calledPartyBCDToString(b, 0, 7));
-
-        b[0] = (byte) 0x91; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55;
-        b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xB0;
-        assertEquals("+17005550020#",
-            PhoneNumberUtils.calledPartyBCDToString(b, 0, 7));
-
-        b[0] = (byte) 0x81; b[1] = (byte) 0x2A; b[2] = (byte) 0xB1;
-        assertEquals("*21#",
-            PhoneNumberUtils.calledPartyBCDToString(b, 0, 3));
-
-        b[0] = (byte) 0x81; b[1] = (byte) 0x2B; b[2] = (byte) 0xB1;
-        assertEquals("#21#",
-            PhoneNumberUtils.calledPartyBCDToString(b, 0, 3));
-
-        b[0] = (byte) 0x91; b[1] = (byte) 0x2A; b[2] = (byte) 0xB1;
-        assertEquals("*21#+",
-            PhoneNumberUtils.calledPartyBCDToString(b, 0, 3));
-
-        b[0] = (byte) 0x81; b[1] = (byte) 0xAA; b[2] = (byte) 0x12; b[3] = (byte) 0xFB;
-        assertEquals("**21#",
-            PhoneNumberUtils.calledPartyBCDToString(b, 0, 4));
-
-        b[0] = (byte) 0x91; b[1] = (byte) 0xAA; b[2] = (byte) 0x12; b[3] = (byte) 0xFB;
-        assertEquals("**21#+",
-            PhoneNumberUtils.calledPartyBCDToString(b, 0, 4));
-
-        b[0] = (byte) 0x81; b[1] = (byte) 0x9A; b[2] = (byte) 0xA9; b[3] = (byte) 0x71;
-        b[4] = (byte) 0x00; b[5] = (byte) 0x55; b[6] = (byte) 0x05; b[7] = (byte) 0x20;
-        b[8] = (byte) 0xB0;
-        assertEquals("*99*17005550020#",
-            PhoneNumberUtils.calledPartyBCDToString(b, 0, 9));
-
-        b[0] = (byte) 0x91; b[1] = (byte) 0x9A; b[2] = (byte) 0xA9; b[3] = (byte) 0x71;
-        b[4] = (byte) 0x00; b[5] = (byte) 0x55; b[6] = (byte) 0x05; b[7] = (byte) 0x20;
-        b[8] = (byte) 0xB0;
-        assertEquals("*99*+17005550020#",
-            PhoneNumberUtils.calledPartyBCDToString(b, 0, 9));
-
-        b[0] = (byte) 0x81; b[1] = (byte) 0xAA; b[2] = (byte) 0x12; b[3] = (byte) 0x1A;
-        b[4] = (byte) 0x07; b[5] = (byte) 0x50; b[6] = (byte) 0x55; b[7] = (byte) 0x00;
-        b[8] = (byte) 0x02; b[9] = (byte) 0xFB;
-        assertEquals("**21*17005550020#",
-            PhoneNumberUtils.calledPartyBCDToString(b, 0, 10));
-
-        b[0] = (byte) 0x91; b[1] = (byte) 0xAA; b[2] = (byte) 0x12; b[3] = (byte) 0x1A;
-        b[4] = (byte) 0x07; b[5] = (byte) 0x50; b[6] = (byte) 0x55; b[7] = (byte) 0x00;
-        b[8] = (byte) 0x02; b[9] = (byte) 0xFB;
-        assertEquals("**21*+17005550020#",
-            PhoneNumberUtils.calledPartyBCDToString(b, 0, 10));
-
-        b[0] = (byte) 0x81; b[1] = (byte) 0x2A; b[2] = (byte) 0xA1; b[3] = (byte) 0x71;
-        b[4] = (byte) 0x00; b[5] = (byte) 0x55; b[6] = (byte) 0x05; b[7] = (byte) 0x20;
-        b[8] = (byte) 0xF0;
-        assertEquals("*21*17005550020",
-            PhoneNumberUtils.calledPartyBCDToString(b, 0, 9));
-
-        b[0] = (byte) 0x91; b[1] = (byte) 0x2A; b[2] = (byte) 0xB1; b[3] = (byte) 0x71;
-        b[4] = (byte) 0x00; b[5] = (byte) 0x55; b[6] = (byte) 0x05; b[7] = (byte) 0x20;
-        b[8] = (byte) 0xF0;
-        assertEquals("*21#+17005550020",
-            PhoneNumberUtils.calledPartyBCDToString(b, 0, 9));
-
-        assertNull(PhoneNumberUtils.extractNetworkPortion(null));
-        assertNull(PhoneNumberUtils.extractPostDialPortion(null));
-        assertTrue(PhoneNumberUtils.compare(null, null));
-        assertFalse(PhoneNumberUtils.compare(null, "123"));
-        assertFalse(PhoneNumberUtils.compare("123", null));
-        assertNull(PhoneNumberUtils.toCallerIDMinMatch(null));
-        assertNull(PhoneNumberUtils.getStrippedReversed(null));
-        assertNull(PhoneNumberUtils.stringFromStringAndTOA(null, 1));
-    }
-
-    @SmallTest
-    public void testExtractNetworkPortionAlt() throws Exception {
-        assertEquals(
-                "+17005554141",
-                PhoneNumberUtils.extractNetworkPortionAlt("+17005554141")
-        );
-
-        assertEquals(
-                "+17005554141",
-                PhoneNumberUtils.extractNetworkPortionAlt("+1 (700).555-4141")
-        );
-
-        assertEquals(
-                "17005554141",
-                PhoneNumberUtils.extractNetworkPortionAlt("1 (700).555-4141")
-        );
-
-        // This may seem wrong, but it's probably ok
-        assertEquals(
-                "17005554141*#",
-                PhoneNumberUtils.extractNetworkPortionAlt("1 (700).555-4141*#")
-        );
-
-        assertEquals(
-                "170055541NN",
-                PhoneNumberUtils.extractNetworkPortionAlt("1 (700).555-41NN")
-        );
-
-        assertEquals(
-                "170055541NN",
-                PhoneNumberUtils.extractNetworkPortionAlt("1 (700).555-41NN,1234")
-        );
-
-        assertEquals(
-                "170055541NN",
-                PhoneNumberUtils.extractNetworkPortionAlt("1 (700).555-41NN;1234")
-        );
-
-        // An MMI string is unperterbed, even though it contains a
-        // (valid in this case) embedded +
-        assertEquals(
-                "**21**+17005554141#",
-                PhoneNumberUtils.extractNetworkPortionAlt("**21**+17005554141#")
-        );
-
-        assertEquals(
-                "*31#+447966164208",
-                PhoneNumberUtils.extractNetworkPortionAlt("*31#+447966164208")
-        );
-
-        assertEquals(
-                "*31#+447966164208",
-                PhoneNumberUtils.extractNetworkPortionAlt("*31# (+44) 79 6616 4208")
-        );
-
-        assertEquals("", PhoneNumberUtils.extractNetworkPortionAlt(""));
-
-        assertEquals("", PhoneNumberUtils.extractNetworkPortionAlt(",1234"));
-
-        assertNull(PhoneNumberUtils.extractNetworkPortionAlt(null));
-    }
-
-    @SmallTest
-    public void testB() throws Exception {
-        assertEquals("", PhoneNumberUtils.extractPostDialPortion("+17005554141"));
-        assertEquals("", PhoneNumberUtils.extractPostDialPortion("+1 (700).555-4141"));
-        assertEquals("", PhoneNumberUtils.extractPostDialPortion("+1 (700).555-41NN"));
-        assertEquals(",1234", PhoneNumberUtils.extractPostDialPortion("+1 (700).555-41NN,1234"));
-        assertEquals(";1234", PhoneNumberUtils.extractPostDialPortion("+1 (700).555-41NN;1234"));
-        assertEquals(";1234,;N",
-                PhoneNumberUtils.extractPostDialPortion("+1 (700).555-41NN;1-2.34 ,;N"));
-    }
-
-    @SmallTest
-    public void testCompare() throws Exception {
-        // this is odd
-        assertFalse(PhoneNumberUtils.compare("", ""));
-
-        assertTrue(PhoneNumberUtils.compare("911", "911"));
-        assertFalse(PhoneNumberUtils.compare("911", "18005550911"));
-        assertTrue(PhoneNumberUtils.compare("5555", "5555"));
-        assertFalse(PhoneNumberUtils.compare("5555", "180055555555"));
-
-        assertTrue(PhoneNumberUtils.compare("+17005554141", "+17005554141"));
-        assertTrue(PhoneNumberUtils.compare("+17005554141", "+1 (700).555-4141"));
-        assertTrue(PhoneNumberUtils.compare("+17005554141", "+1 (700).555-4141,1234"));
-        assertTrue(PhoneNumberUtils.compare("+17005554141", "17005554141"));
-        assertTrue(PhoneNumberUtils.compare("+17005554141", "7005554141"));
-        assertTrue(PhoneNumberUtils.compare("+17005554141", "5554141"));
-        assertTrue(PhoneNumberUtils.compare("17005554141", "5554141"));
-        assertTrue(PhoneNumberUtils.compare("+17005554141", "01117005554141"));
-        assertTrue(PhoneNumberUtils.compare("+17005554141", "0017005554141"));
-        assertTrue(PhoneNumberUtils.compare("17005554141", "0017005554141"));
-
-
-        assertTrue(PhoneNumberUtils.compare("+17005554141", "**31#+17005554141"));
-
-        assertFalse(PhoneNumberUtils.compare("+1 999 7005554141", "+1 7005554141"));
-        assertTrue(PhoneNumberUtils.compare("011 1 7005554141", "7005554141"));
-
-        assertFalse(PhoneNumberUtils.compare("011 11 7005554141", "+17005554141"));
-
-        assertFalse(PhoneNumberUtils.compare("+17005554141", "7085882300"));
-
-        assertTrue(PhoneNumberUtils.compare("+44 207 792 3490", "0 207 792 3490"));
-
-        assertFalse(PhoneNumberUtils.compare("+44 207 792 3490", "00 207 792 3490"));
-        assertFalse(PhoneNumberUtils.compare("+44 207 792 3490", "011 207 792 3490"));
-
-        /***** FIXME's ******/
-        //
-        // MMI header should be ignored
-        assertFalse(PhoneNumberUtils.compare("+17005554141", "**31#17005554141"));
-
-        // It's too bad this is false
-        // +44 (0) 207 792 3490 is not a dialable number
-        // but it is commonly how European phone numbers are written
-        assertFalse(PhoneNumberUtils.compare("+44 207 792 3490", "+44 (0) 207 792 3490"));
-
-        // The japanese international prefix, for example, messes us up
-        // But who uses a GSM phone in Japan?
-        assertFalse(PhoneNumberUtils.compare("+44 207 792 3490", "010 44 207 792 3490"));
-
-        // The Australian one messes us up too
-        assertFalse(PhoneNumberUtils.compare("+44 207 792 3490", "0011 44 207 792 3490"));
-
-        // The Russian trunk prefix messes us up, as does current
-        // Russian area codes (which bein with 0)
-
-        assertFalse(PhoneNumberUtils.compare("+7(095)9100766", "8(095)9100766"));
-
-        // 444 is not a valid country code, but
-        // matchIntlPrefixAndCC doesnt know this
-        assertTrue(PhoneNumberUtils.compare("+444 207 792 3490", "0 207 792 3490"));
-
-        // compare SMS short code
-        assertTrue(PhoneNumberUtils.compare("404-04", "40404"));
-    }
-
-
-    @SmallTest
-    public void testToCallerIDIndexable() throws Exception {
-        assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("17005554141"));
-        assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141"));
-        assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141,1234"));
-        assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141;1234"));
-
-        //this seems wrong, or at least useless
-        assertEquals("NN14555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-41NN"));
-
-        //<shrug> -- these are all not useful, but not terribly wrong
-        assertEquals("", PhoneNumberUtils.toCallerIDMinMatch(""));
-        assertEquals("0032", PhoneNumberUtils.toCallerIDMinMatch("2300"));
-        assertEquals("0032+", PhoneNumberUtils.toCallerIDMinMatch("+2300"));
-        assertEquals("#130#*", PhoneNumberUtils.toCallerIDMinMatch("*#031#"));
-    }
-
-    @SmallTest
-    public void testGetIndexable() throws Exception {
-        assertEquals("14145550071", PhoneNumberUtils.getStrippedReversed("1-700-555-4141"));
-        assertEquals("14145550071", PhoneNumberUtils.getStrippedReversed("1-700-555-4141,1234"));
-        assertEquals("14145550071", PhoneNumberUtils.getStrippedReversed("1-700-555-4141;1234"));
-
-        //this seems wrong, or at least useless
-        assertEquals("NN145550071", PhoneNumberUtils.getStrippedReversed("1-700-555-41NN"));
-
-        //<shrug> -- these are all not useful, but not terribly wrong
-        assertEquals("", PhoneNumberUtils.getStrippedReversed(""));
-        assertEquals("0032", PhoneNumberUtils.getStrippedReversed("2300"));
-        assertEquals("0032+", PhoneNumberUtils.getStrippedReversed("+2300"));
-        assertEquals("#130#*", PhoneNumberUtils.getStrippedReversed("*#031#"));
-    }
-
-    @SmallTest
-    public void testNanpFormatting() {
-        SpannableStringBuilder number = new SpannableStringBuilder();
-        number.append("8005551212");
-        PhoneNumberUtils.formatNanpNumber(number);
-        assertEquals("800-555-1212", number.toString());
-
-        number.clear();
-        number.append("800555121");
-        PhoneNumberUtils.formatNanpNumber(number);
-        assertEquals("800-555-121", number.toString());
-
-        number.clear();
-        number.append("555-1212");
-        PhoneNumberUtils.formatNanpNumber(number);
-        assertEquals("555-1212", number.toString());
-
-        number.clear();
-        number.append("800-55512");
-        PhoneNumberUtils.formatNanpNumber(number);
-        assertEquals("800-555-12", number.toString());
-
-        number.clear();
-        number.append("46645");
-        PhoneNumberUtils.formatNanpNumber(number);
-        assertEquals("46645", number.toString());
-    }
-
-    @SmallTest
-    public void testConvertKeypadLettersToDigits() {
-        assertEquals("1-800-4664-411",
-                     PhoneNumberUtils.convertKeypadLettersToDigits("1-800-GOOG-411"));
-        assertEquals("18004664411",
-                     PhoneNumberUtils.convertKeypadLettersToDigits("1800GOOG411"));
-        assertEquals("1-800-466-4411",
-                     PhoneNumberUtils.convertKeypadLettersToDigits("1-800-466-4411"));
-        assertEquals("18004664411",
-                     PhoneNumberUtils.convertKeypadLettersToDigits("18004664411"));
-        assertEquals("222-333-444-555-666-7777-888-9999",
-                     PhoneNumberUtils.convertKeypadLettersToDigits(
-                             "ABC-DEF-GHI-JKL-MNO-PQRS-TUV-WXYZ"));
-        assertEquals("222-333-444-555-666-7777-888-9999",
-                     PhoneNumberUtils.convertKeypadLettersToDigits(
-                             "abc-def-ghi-jkl-mno-pqrs-tuv-wxyz"));
-        assertEquals("(800) 222-3334",
-                     PhoneNumberUtils.convertKeypadLettersToDigits("(800) ABC-DEFG"));
-    }
-
-    // To run this test, the device has to be registered with network
-    public void testCheckAndProcessPlusCode() {
-        assertEquals("0118475797000",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+8475797000"));
-        assertEquals("18475797000",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+18475797000"));
-        assertEquals("0111234567",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+1234567"));
-        assertEquals("01123456700000",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+23456700000"));
-        assertEquals("01111875767800",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+11875767800"));
-        assertEquals("8475797000,18475231753",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,+18475231753"));
-        assertEquals("0118475797000,18475231753",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+8475797000,+18475231753"));
-        assertEquals("8475797000;0118469312345",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000;+8469312345"));
-        assertEquals("8475797000,0111234567",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,+1234567"));
-        assertEquals("847597000;01111875767000",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("847597000;+11875767000"));
-        assertEquals("8475797000,,0118469312345",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,,+8469312345"));
-        assertEquals("8475797000;,0118469312345",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000;,+8469312345"));
-        assertEquals("8475797000,;18475231753",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,;+18475231753"));
-        assertEquals("8475797000;,01111875767000",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000;,+11875767000"));
-        assertEquals("8475797000,;01111875767000",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,;+11875767000"));
-        assertEquals("8475797000,,,01111875767000",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,,,+11875767000"));
-        assertEquals("8475797000;,,01111875767000",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000;,,+11875767000"));
-        assertEquals("+;,8475797000",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+;,8475797000"));
-        assertEquals("8475797000,",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,"));
-        assertEquals("847+579-7000",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("847+579-7000"));
-        assertEquals(",8475797000",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode(",8475797000"));
-        assertEquals(";;8475797000,,",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode(";;8475797000,,"));
-        assertEquals("+this+is$weird;,+",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+this+is$weird;,+"));
-        assertEquals("",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCode(""));
-        assertNull(PhoneNumberUtils.cdmaCheckAndProcessPlusCode(null));
-    }
-
-    @SmallTest
-    public void testCheckAndProcessPlusCodeByNumberFormat() {
-        assertEquals("18475797000",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCodeByNumberFormat("+18475797000",
-                PhoneNumberUtils.FORMAT_NANP,PhoneNumberUtils.FORMAT_NANP));
-        assertEquals("+18475797000",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCodeByNumberFormat("+18475797000",
-                PhoneNumberUtils.FORMAT_NANP,PhoneNumberUtils.FORMAT_JAPAN));
-        assertEquals("+18475797000",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCodeByNumberFormat("+18475797000",
-                PhoneNumberUtils.FORMAT_NANP,PhoneNumberUtils.FORMAT_UNKNOWN));
-        assertEquals("+18475797000",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCodeByNumberFormat("+18475797000",
-                PhoneNumberUtils.FORMAT_JAPAN,PhoneNumberUtils.FORMAT_JAPAN));
-        assertEquals("+18475797000",
-                PhoneNumberUtils.cdmaCheckAndProcessPlusCodeByNumberFormat("+18475797000",
-                PhoneNumberUtils.FORMAT_UNKNOWN,PhoneNumberUtils.FORMAT_UNKNOWN));
-    }
-
-    /**
-     * Basic checks for the VoiceMail number.
-     */
-    @SmallTest
-    public void testWithNumberNotEqualToVoiceMail() throws Exception {
-        assertFalse(PhoneNumberUtils.isVoiceMailNumber("911"));
-        assertFalse(PhoneNumberUtils.isVoiceMailNumber("tel:911"));
-        assertFalse(PhoneNumberUtils.isVoiceMailNumber("+18001234567"));
-        assertFalse(PhoneNumberUtils.isVoiceMailNumber(""));
-        assertFalse(PhoneNumberUtils.isVoiceMailNumber(null));
-        // This test fails on a device without a sim card
-        /*TelephonyManager mTelephonyManager =
-            (TelephonyManager)getContext().getSystemService(Context.TELEPHONY_SERVICE);
-        String mVoiceMailNumber = mTelephonyManager.getDefault().getVoiceMailNumber();
-        assertTrue(PhoneNumberUtils.isVoiceMailNumber(mVoiceMailNumber));
-        */
-    }
-
-    @SmallTest
-    public void testFormatNumberToE164() {
-        // Note: ISO 3166-1 only allows upper case country codes.
-        assertEquals("+16502910000", PhoneNumberUtils.formatNumberToE164("650 2910000", "US"));
-        assertNull(PhoneNumberUtils.formatNumberToE164("1234567", "US"));
-        assertEquals("+18004664114", PhoneNumberUtils.formatNumberToE164("800-GOOG-114", "US"));
-    }
-
-    @SmallTest
-    public void testFormatNumber() {
-        assertEquals("(650) 291-0000", PhoneNumberUtils.formatNumber("650 2910000", "US"));
-        assertEquals("223-4567", PhoneNumberUtils.formatNumber("2234567", "US"));
-        assertEquals("011 86 10 8888 0000",
-                     PhoneNumberUtils.formatNumber("011861088880000", "US"));
-        assertEquals("010 8888 0000", PhoneNumberUtils.formatNumber("01088880000", "CN"));
-        // formatNumber doesn't format alpha numbers, but keep them as they are.
-        assertEquals("800-GOOG-114", PhoneNumberUtils.formatNumber("800-GOOG-114", "US"));
-    }
-
-    @SmallTest
-    public void testFormatNumber_LeadingStarAndHash() {
-        // Numbers with a leading '*' or '#' should be left unchanged.
-        assertEquals("*650 2910000", PhoneNumberUtils.formatNumber("*650 2910000", "US"));
-        assertEquals("#650 2910000", PhoneNumberUtils.formatNumber("#650 2910000", "US"));
-        assertEquals("*#650 2910000", PhoneNumberUtils.formatNumber("*#650 2910000", "US"));
-        assertEquals("#*650 2910000", PhoneNumberUtils.formatNumber("#*650 2910000", "US"));
-        assertEquals("#650*2910000", PhoneNumberUtils.formatNumber("#650*2910000", "US"));
-        assertEquals("#650*2910000", PhoneNumberUtils.formatNumber("#650*2910000", "US"));
-        assertEquals("##650 2910000", PhoneNumberUtils.formatNumber("##650 2910000", "US"));
-        assertEquals("**650 2910000", PhoneNumberUtils.formatNumber("**650 2910000", "US"));
-    }
-
-    @SmallTest
-    public void testNormalizeNumber() {
-        assertEquals("6502910000", PhoneNumberUtils.normalizeNumber("650 2910000"));
-        assertEquals("1234567", PhoneNumberUtils.normalizeNumber("12,3#4*567"));
-        assertEquals("8004664114", PhoneNumberUtils.normalizeNumber("800-GOOG-114"));
-        assertEquals("+16502910000", PhoneNumberUtils.normalizeNumber("+1 650 2910000"));
-    }
-
-    @SmallTest
-    public void testFormatDailabeNumber() {
-        // Using the phoneNumberE164's country code
-        assertEquals("(650) 291-0000",
-                PhoneNumberUtils.formatNumber("6502910000", "+16502910000", "CN"));
-        // Using the default country code for a phone number containing the IDD
-        assertEquals("011 86 10 8888 0000",
-                PhoneNumberUtils.formatNumber("011861088880000", "+861088880000", "US"));
-        assertEquals("00 86 10 8888 0000",
-                PhoneNumberUtils.formatNumber("00861088880000", "+861088880000", "GB"));
-        assertEquals("+86 10 8888 0000",
-                PhoneNumberUtils.formatNumber("+861088880000", "+861088880000", "GB"));
-        // Wrong default country, so no formatting is done
-        assertEquals("011861088880000",
-                PhoneNumberUtils.formatNumber("011861088880000", "+861088880000", "GB"));
-        // The phoneNumberE164 is null
-        assertEquals("(650) 291-0000", PhoneNumberUtils.formatNumber("6502910000", null, "US"));
-        // The given number has a country code.
-        assertEquals("+1 650-291-0000", PhoneNumberUtils.formatNumber("+16502910000", null, "CN"));
-        // The given number was formatted.
-        assertEquals("650-291-0000", PhoneNumberUtils.formatNumber("650-291-0000", null, "US"));
-        // A valid Polish number should be formatted.
-        assertEquals("506 128 687", PhoneNumberUtils.formatNumber("506128687", null, "PL"));
-        // An invalid Polish number should be left as it is. Note Poland doesn't use '0' as a
-        // national prefix; therefore, the leading '0' makes the number invalid.
-        assertEquals("0506128687", PhoneNumberUtils.formatNumber("0506128687", null, "PL"));
-        // Wrong default country, so no formatting is done
-        assertEquals("011861088880000",
-                PhoneNumberUtils.formatNumber("011861088880000", "", "GB"));
-    }
-
-    @SmallTest
-    public void testIsEmergencyNumber() {
-        // There are two parallel sets of tests here: one for the
-        // regular isEmergencyNumber() method, and the other for
-        // isPotentialEmergencyNumber().
-        //
-        // (The difference is that isEmergencyNumber() will return true
-        // only if the specified number exactly matches an actual
-        // emergency number, but isPotentialEmergencyNumber() will
-        // return true if the specified number simply starts with the
-        // same digits as any actual emergency number.)
-
-        // Tests for isEmergencyNumber():
-        assertTrue(PhoneNumberUtils.isEmergencyNumber("911", "US"));
-        assertTrue(PhoneNumberUtils.isEmergencyNumber("112", "US"));
-        // The next two numbers are not valid phone numbers in the US,
-        // so do not count as emergency numbers (but they *are* "potential"
-        // emergency numbers; see below.)
-        assertFalse(PhoneNumberUtils.isEmergencyNumber("91112345", "US"));
-        assertFalse(PhoneNumberUtils.isEmergencyNumber("11212345", "US"));
-        // A valid mobile phone number from Singapore shouldn't be classified as an emergency number
-        // in Singapore, as 911 is not an emergency number there.
-        assertFalse(PhoneNumberUtils.isEmergencyNumber("91121234", "SG"));
-        // A valid fixed-line phone number from Brazil shouldn't be classified as an emergency number
-        // in Brazil, as 112 is not an emergency number there.
-        assertFalse(PhoneNumberUtils.isEmergencyNumber("1121234567", "BR"));
-        // A valid local phone number from Brazil shouldn't be classified as an emergency number in
-        // Brazil.
-        assertFalse(PhoneNumberUtils.isEmergencyNumber("91112345", "BR"));
-
-        // Tests for isPotentialEmergencyNumber():
-        // These first two are obviously emergency numbers:
-        assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("911", "US"));
-        assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("112", "US"));
-        // The next two numbers are not valid phone numbers in the US, but can be used to trick the
-        // system to dial 911 and 112, which are emergency numbers in the US. For the purpose of
-        // addressing that, they are also classified as "potential" emergency numbers in the US.
-        assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("91112345", "US"));
-        assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("11212345", "US"));
-
-        // A valid mobile phone number from Singapore shouldn't be classified as an emergency number
-        // in Singapore, as 911 is not an emergency number there.
-        // This test fails on devices that have ecclist property preloaded with 911.
-        // assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("91121234", "SG"));
-
-        // A valid fixed-line phone number from Brazil shouldn't be classified as an emergency number
-        // in Brazil, as 112 is not an emergency number there.
-        assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("1121234567", "BR"));
-        // A valid local phone number from Brazil shouldn't be classified as an emergency number in
-        // Brazil.
-        assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("91112345", "BR"));
-    }
-
-    @SmallTest
-    public void testStripSeparators() {
-        // Smoke tests which should never fail.
-        assertEquals("1234567890", PhoneNumberUtils.stripSeparators("1234567890"));
-        assertEquals("911", PhoneNumberUtils.stripSeparators("911"));
-        assertEquals("112", PhoneNumberUtils.stripSeparators("112"));
-
-        // Separators should be removed, while '+' or any other digits should not.
-        assertEquals("+16502910000", PhoneNumberUtils.stripSeparators("+1 (650) 291-0000"));
-
-        // WAIT, PAUSE should *not* be stripped
-        assertEquals("+16502910000,300;",
-                PhoneNumberUtils.stripSeparators("+1 (650) 291-0000, 300;"));
-    }
-
-    @SmallTest
-    public void testConvertAndStrip() {
-        // Smoke tests which should never fail.
-        assertEquals("1234567890", PhoneNumberUtils.convertAndStrip("1234567890"));
-        assertEquals("911", PhoneNumberUtils.convertAndStrip("911"));
-        assertEquals("112", PhoneNumberUtils.convertAndStrip("112"));
-
-        // It should convert keypad characters into digits, and strip separators
-        assertEquals("22233344455566677778889999",
-                PhoneNumberUtils.convertAndStrip("ABC DEF GHI JKL MNO PQR STUV WXYZ"));
-
-        // Test real cases.
-        assertEquals("18004664411", PhoneNumberUtils.convertAndStrip("1-800-GOOG-411"));
-        assertEquals("8002223334", PhoneNumberUtils.convertAndStrip("(800) ABC-DEFG"));
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java
deleted file mode 100644
index a6a0fce..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * 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.internal.telephony;
-
-import android.telephony.PhoneNumberFormattingTextWatcher;
-import android.test.AndroidTestCase;
-import android.text.Editable;
-import android.text.Selection;
-import android.text.SpannableStringBuilder;
-import android.text.TextWatcher;
-
-public class PhoneNumberWatcherTest extends AndroidTestCase {
-    public void testAppendChars() {
-        final String multiChars = "65012345";
-        final String formatted1 = "(650) 123-45";
-        TextWatcher textWatcher = getTextWatcher();
-        SpannableStringBuilder number = new SpannableStringBuilder();
-        // Append more than one chars
-        textWatcher.beforeTextChanged(number, 0, 0, multiChars.length());
-        number.append(multiChars);
-        Selection.setSelection(number, number.length());
-        textWatcher.onTextChanged(number, 0, 0, number.length());
-        textWatcher.afterTextChanged(number);
-        assertEquals(formatted1, number.toString());
-        assertEquals(formatted1.length(), Selection.getSelectionEnd(number));
-        // Append one chars
-        final char appendChar = '6';
-        final String formatted2 = "(650) 123-456";
-        int len = number.length();
-        textWatcher.beforeTextChanged(number, number.length(), 0, 1);
-        number.append(appendChar);
-        Selection.setSelection(number, number.length());
-        textWatcher.onTextChanged(number, len, 0, 1);
-        textWatcher.afterTextChanged(number);
-        assertEquals(formatted2, number.toString());
-        assertEquals(formatted2.length(), Selection.getSelectionEnd(number));
-    }
-
-    public void testRemoveLastChars() {
-        final String init = "65012345678";
-        final String result1 = "(650) 123-4567";
-        TextWatcher textWatcher = getTextWatcher();
-        // Remove the last char.
-        SpannableStringBuilder number = new SpannableStringBuilder(init);
-        int len = number.length();
-        textWatcher.beforeTextChanged(number, len - 1, 1, 0);
-        number.delete(len - 1, len);
-        Selection.setSelection(number, number.length());
-        textWatcher.onTextChanged(number, number.length() - 1, 1, 0);
-        textWatcher.afterTextChanged(number);
-        assertEquals(result1, number.toString());
-        assertEquals(result1.length(), Selection.getSelectionEnd(number));
-        // Remove last 5 chars
-        final String result2 = "650-123";
-        textWatcher.beforeTextChanged(number, number.length() - 4, 4, 0);
-        number.delete(number.length() - 5, number.length());
-        Selection.setSelection(number, number.length());
-        textWatcher.onTextChanged(number, number.length(), 4, 0);
-        textWatcher.afterTextChanged(number);
-        assertEquals(result2, number.toString());
-        assertEquals(result2.length(), Selection.getSelectionEnd(number));
-    }
-
-    public void testInsertChars() {
-        final String init = "650-23";
-        final String expected1 = "650-123";
-        TextWatcher textWatcher = getTextWatcher();
-
-        // Insert one char
-        SpannableStringBuilder number = new SpannableStringBuilder(init);
-        textWatcher.beforeTextChanged(number, 3, 0, 1);
-        number.insert(3, "1"); // 6501-23
-        Selection.setSelection(number, 4); // make the cursor at right of 1
-        textWatcher.onTextChanged(number, 3, 0, 1);
-        textWatcher.afterTextChanged(number);
-        assertEquals(expected1, number.toString());
-        // the cursor should still at the right of '1'
-        assertEquals(5, Selection.getSelectionEnd(number));
-
-        // Insert multiple chars
-        final String expected2 = "(650) 145-6723";
-        textWatcher.beforeTextChanged(number, 5, 0, 4);
-        number.insert(5, "4567"); // change to 650-1456723
-        Selection.setSelection(number, 9); // the cursor is at the right of '7'.
-        textWatcher.onTextChanged(number, 7, 0, 4);
-        textWatcher.afterTextChanged(number);
-        assertEquals(expected2, number.toString());
-        // the cursor should be still at the right of '7'
-        assertEquals(12, Selection.getSelectionEnd(number));
-    }
-
-    public void testStopFormatting() {
-        final String init = "(650) 123";
-        final String expected1 = "(650) 123 4";
-        TextWatcher textWatcher = getTextWatcher();
-
-        // Append space
-        SpannableStringBuilder number = new SpannableStringBuilder(init);
-        textWatcher.beforeTextChanged(number, 9, 0, 2);
-        number.insert(9, " 4"); // (6501) 23 4
-        Selection.setSelection(number, number.length()); // make the cursor at right of 4
-        textWatcher.onTextChanged(number, 9, 0, 2);
-        textWatcher.afterTextChanged(number);
-        assertEquals(expected1, number.toString());
-        // the cursor should still at the right of '1'
-        assertEquals(expected1.length(), Selection.getSelectionEnd(number));
-
-        // Delete a ')'
-        final String expected2 ="(650 123";
-        textWatcher = getTextWatcher();
-        number = new SpannableStringBuilder(init);
-        textWatcher.beforeTextChanged(number, 4, 1, 0);
-        number.delete(4, 5); // (6501 23 4
-        Selection.setSelection(number, 5); // make the cursor at right of 1
-        textWatcher.onTextChanged(number, 4, 1, 0);
-        textWatcher.afterTextChanged(number);
-        assertEquals(expected2, number.toString());
-        // the cursor should still at the right of '1'
-        assertEquals(5, Selection.getSelectionEnd(number));
-
-        // Insert a hyphen
-        final String expected3 ="(650) 12-3";
-        textWatcher = getTextWatcher();
-        number = new SpannableStringBuilder(init);
-        textWatcher.beforeTextChanged(number, 8, 0, 1);
-        number.insert(8, "-"); // (650) 12-3
-        Selection.setSelection(number, 9); // make the cursor at right of -
-        textWatcher.onTextChanged(number, 8, 0, 1);
-        textWatcher.afterTextChanged(number);
-        assertEquals(expected3, number.toString());
-        // the cursor should still at the right of '-'
-        assertEquals(9, Selection.getSelectionEnd(number));
-    }
-
-    public void testRestartFormatting() {
-        final String init = "(650) 123";
-        final String expected1 = "(650) 123 4";
-        TextWatcher textWatcher = getTextWatcher();
-
-        // Append space
-        SpannableStringBuilder number = new SpannableStringBuilder(init);
-        textWatcher.beforeTextChanged(number, 9, 0, 2);
-        number.insert(9, " 4"); // (650) 123 4
-        Selection.setSelection(number, number.length()); // make the cursor at right of 4
-        textWatcher.onTextChanged(number, 9, 0, 2);
-        textWatcher.afterTextChanged(number);
-        assertEquals(expected1, number.toString());
-        // the cursor should still at the right of '4'
-        assertEquals(expected1.length(), Selection.getSelectionEnd(number));
-
-        // Clear the current string, and start formatting again.
-        int len = number.length();
-        textWatcher.beforeTextChanged(number, 0, len, 0);
-        number.delete(0, len);
-        textWatcher.onTextChanged(number, 0, len, 0);
-        textWatcher.afterTextChanged(number);
-
-        final String expected2 = "650-1234";
-        number = new SpannableStringBuilder(init);
-        textWatcher.beforeTextChanged(number, 9, 0, 1);
-        number.insert(9, "4"); // (650) 1234
-        Selection.setSelection(number, number.length()); // make the cursor at right of 4
-        textWatcher.onTextChanged(number, 9, 0, 1);
-        textWatcher.afterTextChanged(number);
-        assertEquals(expected2, number.toString());
-        // the cursor should still at the right of '4'
-        assertEquals(expected2.length(), Selection.getSelectionEnd(number));
-    }
-
-    public void testTextChangedByOtherTextWatcher() {
-        final TextWatcher cleanupTextWatcher = new TextWatcher() {
-            @Override
-            public void afterTextChanged(Editable s) {
-                s.clear();
-            }
-
-            @Override
-            public void beforeTextChanged(CharSequence s, int start, int count,
-                    int after) {
-            }
-
-            @Override
-            public void onTextChanged(CharSequence s, int start, int before,
-                    int count) {
-            }
-        };
-        final String init = "(650) 123";
-        final String expected1 = "";
-        TextWatcher textWatcher = getTextWatcher();
-
-        SpannableStringBuilder number = new SpannableStringBuilder(init);
-        textWatcher.beforeTextChanged(number, 5, 0, 1);
-        number.insert(5, "4"); // (6504) 123
-        Selection.setSelection(number, 5); // make the cursor at right of 4
-        textWatcher.onTextChanged(number, 5, 0, 1);
-        number.setSpan(cleanupTextWatcher, 0, number.length(), 0);
-        textWatcher.afterTextChanged(number);
-        assertEquals(expected1, number.toString());
-    }
-
-    /**
-     * Test the case where some other component is auto-completing what the user is typing
-     */
-    public void testAutoCompleteWithFormattedNumber() {
-        String init = "650-1";
-        String expected = "+1-650-123-4567"; // Different formatting than ours
-        testReplacement(init, expected, expected);
-    }
-
-    /**
-     * Test the case where some other component is auto-completing what the user is typing
-     */
-    public void testAutoCompleteWithFormattedNameAndNumber() {
-        String init = "650-1";
-        String expected = "Test User <650-123-4567>";
-        testReplacement(init, expected, expected);
-    }
-
-    /**
-     * Test the case where some other component is auto-completing what the user is typing
-     */
-    public void testAutoCompleteWithNumericNameAndNumber() {
-        String init = "650";
-        String expected = "2nd Test User <650-123-4567>";
-        testReplacement(init, expected, expected);
-    }
-
-    /**
-     * Test the case where some other component is auto-completing what the user is typing
-     */
-    public void testAutoCompleteWithUnformattedNumber() {
-        String init = "650-1";
-        String expected = "6501234567";
-        testReplacement(init, expected, expected);
-    }
-
-    /**
-     * Test the case where some other component is auto-completing what the user is typing, where
-     * the deleted text doesn't have any formatting and neither does the replacement text: in this
-     * case the replacement text should be formatted by the PhoneNumberFormattingTextWatcher.
-     */
-    public void testAutoCompleteUnformattedWithUnformattedNumber() {
-        String init = "650";
-        String replacement = "6501234567";
-        String expected = "(650) 123-4567";
-        testReplacement(init, replacement, expected);
-
-        String init2 = "650";
-        String replacement2 = "16501234567";
-        String expected2 = "1 650-123-4567";
-        testReplacement(init2, replacement2, expected2);
-    }
-
-    /**
-     * Helper method for testing replacing the entire string with another string
-     * @param init The initial string
-     * @param expected
-     */
-    private void testReplacement(String init, String replacement, String expected) {
-        TextWatcher textWatcher = getTextWatcher();
-
-        SpannableStringBuilder number = new SpannableStringBuilder(init);
-
-        // Replace entire text with the given values
-        textWatcher.beforeTextChanged(number, 0, init.length(), replacement.length());
-        number.replace(0, init.length(), replacement, 0, replacement.length());
-        Selection.setSelection(number, replacement.length()); // move the cursor to the end
-        textWatcher.onTextChanged(number, 0, init.length(), replacement.length());
-        textWatcher.afterTextChanged(number);
-
-        assertEquals(expected, number.toString());
-        // the cursor should be still at the end
-        assertEquals(expected.length(), Selection.getSelectionEnd(number));
-    }
-
-    private TextWatcher getTextWatcher() {
-        return new PhoneNumberFormattingTextWatcher("US");
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/SMSDispatcherTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/SMSDispatcherTest.java
deleted file mode 100644
index 8a66614..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/SMSDispatcherTest.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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.internal.telephony;
-
-import android.test.suitebuilder.annotation.MediumTest;
-import com.android.internal.telephony.TestPhoneNotifier;
-import com.android.internal.telephony.gsm.SmsMessage;
-import com.android.internal.telephony.test.SimulatedCommands;
-import com.android.internal.telephony.test.SimulatedRadioControl;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.Suppress;
-
-import java.util.Iterator;
-
-/**
- * {@hide}
- */
-public class SMSDispatcherTest extends AndroidTestCase {
-    @MediumTest
-    public void testCMT1() throws Exception {
-        SmsMessage sms;
-        SmsHeader header;
-
-        String[] lines = new String[2];
-
-        lines[0] = "+CMT: ,158";
-        lines[1] = "07914140279510F6440A8111110301003BF56080426101748A8C0B05040B"
-                 + "8423F000035502010106276170706C69636174696F6E2F766E642E776170"
-                 + "2E6D6D732D6D65737361676500AF848D0185B4848C8298524F347839776F"
-                 + "7547514D4141424C3641414141536741415A4B554141414141008D908918"
-                 + "802B31363530323438363137392F545950453D504C4D4E008A808E028000"
-                 + "88058103093A8083687474703A2F2F36";
-
-        sms = SmsMessage.newFromCMT(lines);
-        header = sms.getUserDataHeader();
-        assertNotNull(header);
-        assertNotNull(sms.getUserData());
-        assertNotNull(header.concatRef);
-        assertEquals(header.concatRef.refNumber, 85);
-        assertEquals(header.concatRef.msgCount, 2);
-        assertEquals(header.concatRef.seqNumber, 1);
-        assertEquals(header.concatRef.isEightBits, true);
-        assertNotNull(header.portAddrs);
-        assertEquals(header.portAddrs.destPort, 2948);
-        assertEquals(header.portAddrs.origPort, 9200);
-        assertEquals(header.portAddrs.areEightBits, false);
-    }
-
-    @MediumTest
-    public void testCMT2() throws Exception {
-        SmsMessage sms;
-        SmsHeader header;
-
-        String[] lines = new String[2];
-
-        lines[0] = "+CMT: ,77";
-        lines[1] = "07914140279510F6440A8111110301003BF56080426101848A3B0B05040B8423F"
-                 + "00003550202362E3130322E3137312E3135302F524F347839776F7547514D4141"
-                 + "424C3641414141536741415A4B55414141414100";
-
-        sms = SmsMessage.newFromCMT(lines);
-        header = sms.getUserDataHeader();
-        assertNotNull(header);
-        assertNotNull(sms.getUserData());
-        assertNotNull(header.concatRef);
-        assertEquals(header.concatRef.refNumber, 85);
-        assertEquals(header.concatRef.msgCount, 2);
-        assertEquals(header.concatRef.seqNumber, 2);
-        assertEquals(header.concatRef.isEightBits, true);
-        assertNotNull(header.portAddrs);
-        assertEquals(header.portAddrs.destPort, 2948);
-        assertEquals(header.portAddrs.origPort, 9200);
-        assertEquals(header.portAddrs.areEightBits, false);
-    }
-
-    @MediumTest
-    public void testEfRecord() throws Exception {
-        SmsMessage sms;
-
-        String s = "03029111000c9194981492631000f269206190022000a053e4534a05358bd3"
-                 + "69f05804259da0219418a40641536a110a0aea408080604028180e888462c1"
-                 + "50341c0f484432a1542c174c46b3e1743c9f9068442a994ea8946ac56ab95e"
-                 + "b0986c46abd96eb89c6ec7ebf97ec0a070482c1a8fc8a472c96c3a9fd0a874"
-                 + "4aad5aafd8ac76cbed7abfe0b0784c2e9bcfe8b47acd6ebbdff0b87c4eafdb"
-                 + "eff8bc7ecfeffbffffffffffffffffffffffffffff";
-       byte[] data = IccUtils.hexStringToBytes(s);
-
-       sms = SmsMessage.createFromEfRecord(1, data);
-       assertNotNull(sms.getMessageBody());
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/SimPhoneBookTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/SimPhoneBookTest.java
deleted file mode 100644
index 609e768..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/SimPhoneBookTest.java
+++ /dev/null
@@ -1,106 +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.internal.telephony;
-
-import android.os.ServiceManager;
-import android.test.suitebuilder.annotation.Suppress;
-
-import java.util.List;
-
-import junit.framework.TestCase;
-
-@Suppress
-public class SimPhoneBookTest extends TestCase {
-
-    public void testBasic() throws Exception {
-        IIccPhoneBook simPhoneBook =
-                IIccPhoneBook.Stub.asInterface(ServiceManager.getService("simphonebook"));
-        assertNotNull(simPhoneBook);
-
-        int size[] = simPhoneBook.getAdnRecordsSize(IccConstants.EF_ADN);
-        assertNotNull(size);
-        assertEquals(3, size.length);
-        assertEquals(size[0] * size[2], size[1]);
-        assertTrue(size[2] >= 100);
-
-        List<AdnRecord> adnRecordList = simPhoneBook.getAdnRecordsInEf(IccConstants.EF_ADN);
-        // do it twice cause the second time shall read from cache only
-        adnRecordList = simPhoneBook.getAdnRecordsInEf(IccConstants.EF_ADN);
-        assertNotNull(adnRecordList);
-
-        // Test for phone book update
-        int adnIndex, listIndex = 0;
-        AdnRecord originalAdn = null;
-        // We need to maintain the state of the SIM before and after the test.
-        // Since this test doesn't mock the SIM we try to get a valid ADN record,
-        // for 3 tries and if this fails, we bail out. 
-        for (adnIndex = 3 ; adnIndex >= 1; adnIndex--) {
-            listIndex = adnIndex - 1; // listIndex is zero based.
-            originalAdn = adnRecordList.get(listIndex);
-            assertNotNull("Original Adn is Null.", originalAdn);
-            assertNotNull("Original Adn alpha tag is null.", originalAdn.getAlphaTag());
-            assertNotNull("Original Adn number is null.", originalAdn.getNumber());
-            
-            if (originalAdn.getNumber().length() > 0 &&  
-                originalAdn.getAlphaTag().length() > 0) {   
-                break;
-            }
-        }
-        if (adnIndex == 0) return;
-        
-        AdnRecord emptyAdn = new AdnRecord("", "");
-        AdnRecord firstAdn = new AdnRecord("John", "4085550101");
-        AdnRecord secondAdn = new AdnRecord("Andy", "6505550102");
-        String pin2 = null;
-
-        // udpate by index
-        boolean success = simPhoneBook.updateAdnRecordsInEfByIndex(IccConstants.EF_ADN,
-                firstAdn.getAlphaTag(), firstAdn.getNumber(), adnIndex, pin2);
-        adnRecordList = simPhoneBook.getAdnRecordsInEf(IccConstants.EF_ADN);
-         AdnRecord tmpAdn = adnRecordList.get(listIndex);
-        assertTrue(success);
-        assertTrue(firstAdn.isEqual(tmpAdn));
-
-        // replace by search
-        success = simPhoneBook.updateAdnRecordsInEfBySearch(IccConstants.EF_ADN,
-                firstAdn.getAlphaTag(), firstAdn.getNumber(),
-                secondAdn.getAlphaTag(), secondAdn.getNumber(), pin2);
-        adnRecordList = simPhoneBook.getAdnRecordsInEf(IccConstants.EF_ADN);
-        tmpAdn = adnRecordList.get(listIndex);
-        assertTrue(success);
-        assertFalse(firstAdn.isEqual(tmpAdn));
-        assertTrue(secondAdn.isEqual(tmpAdn));
-
-        // erase be search
-        success = simPhoneBook.updateAdnRecordsInEfBySearch(IccConstants.EF_ADN,
-                secondAdn.getAlphaTag(), secondAdn.getNumber(),
-                emptyAdn.getAlphaTag(), emptyAdn.getNumber(), pin2);
-        adnRecordList = simPhoneBook.getAdnRecordsInEf(IccConstants.EF_ADN);
-        tmpAdn = adnRecordList.get(listIndex);
-        assertTrue(success);
-        assertTrue(tmpAdn.isEmpty());
-
-        // restore the orginial adn
-        success = simPhoneBook.updateAdnRecordsInEfByIndex(IccConstants.EF_ADN,
-                originalAdn.getAlphaTag(), originalAdn.getNumber(), adnIndex,
-                pin2);
-        adnRecordList = simPhoneBook.getAdnRecordsInEf(IccConstants.EF_ADN);
-        tmpAdn = adnRecordList.get(listIndex);
-        assertTrue(success);
-        assertTrue(originalAdn.isEqual(tmpAdn));
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/SimSmsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/SimSmsTest.java
deleted file mode 100644
index 1609680..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/SimSmsTest.java
+++ /dev/null
@@ -1,60 +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.internal.telephony;
-
-import android.os.ServiceManager;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
-
-import java.util.List;
-
-import junit.framework.TestCase;
-
-public class SimSmsTest extends TestCase {
-
-    @MediumTest
-    @Suppress // TODO: suppress this test for now since it doesn't work on the emulator
-    public void testBasic() throws Exception {
-
-        ISms sms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
-        assertNotNull(sms);
-
-        List<SmsRawData> records = sms.getAllMessagesFromIccEf();
-        assertNotNull(records);
-        assertTrue(records.size() >= 0);
-
-        int firstNullIndex = -1;
-        int firstValidIndex = -1;
-        byte[] pdu = null;
-        for (int i = 0; i < records.size(); i++) {
-            SmsRawData data = records.get(i);
-            if (data != null && firstValidIndex == -1) {
-                firstValidIndex = i;
-                pdu = data.getBytes();
-            }
-            if (data == null && firstNullIndex == -1) {
-                firstNullIndex = i;
-            }
-            if (firstNullIndex != -1 && firstValidIndex != -1) {
-                break;
-            }
-        }
-        if (firstNullIndex == -1 || firstValidIndex == -1)
-            return;
-        assertNotNull(pdu);
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/SimUtilsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/SimUtilsTest.java
deleted file mode 100644
index ef62d85..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/SimUtilsTest.java
+++ /dev/null
@@ -1,91 +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.internal.telephony;
-
-import com.android.internal.telephony.gsm.SimTlv;
-import com.android.internal.telephony.IccUtils;
-import junit.framework.TestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-
-public class SimUtilsTest extends TestCase {
-
-    @SmallTest
-    public void testBasic() throws Exception {
-        byte[] data, data2;
-
-        /*
-         * bcdToString()
-         */
-
-        // An EF[ICCID] record
-        data = IccUtils.hexStringToBytes("981062400510444868f2");
-        assertEquals("8901260450014484862", IccUtils.bcdToString(data, 0, data.length));
-
-        // skip the first and last bytes
-        assertEquals("0126045001448486", IccUtils.bcdToString(data, 1, data.length - 2));
-
-        // Stops on invalid BCD value
-        data = IccUtils.hexStringToBytes("98E062400510444868f2");
-        assertEquals("890", IccUtils.bcdToString(data, 0, data.length));
-
-        // skip the high nibble 'F' since some PLMNs have it
-        data = IccUtils.hexStringToBytes("98F062400510444868f2");
-        assertEquals("890260450014484862", IccUtils.bcdToString(data, 0, data.length));
-
-        /*
-         * gsmBcdByteToInt()
-         */
-
-        assertEquals(98, IccUtils.gsmBcdByteToInt((byte) 0x89));
-
-        // Out of range is treated as 0
-        assertEquals(8, IccUtils.gsmBcdByteToInt((byte) 0x8c));
-
-        /*
-         * cdmaBcdByteToInt()
-         */
-
-        assertEquals(89, IccUtils.cdmaBcdByteToInt((byte) 0x89));
-
-        // Out of range is treated as 0
-        assertEquals(80, IccUtils.cdmaBcdByteToInt((byte) 0x8c));
-
-        /*
-         * adnStringFieldToString()
-         */
-
-
-        data = IccUtils.hexStringToBytes("00566f696365204d61696c07918150367742f3ffffffffffff");
-        // Again, skip prepended 0
-        // (this is an EF[ADN] record)
-        assertEquals("Voice Mail", IccUtils.adnStringFieldToString(data, 1, data.length - 15));
-
-        data = IccUtils.hexStringToBytes("809673539A5764002F004DFFFFFFFFFF");
-        // (this is from an EF[ADN] record)
-        assertEquals("\u9673\u539A\u5764/M", IccUtils.adnStringFieldToString(data, 0, data.length));
-
-        data = IccUtils.hexStringToBytes("810A01566fec6365204de0696cFFFFFF");
-        // (this is made up to test since I don't have a real one)
-        assertEquals("Vo\u00ECce M\u00E0il", IccUtils.adnStringFieldToString(data, 0, data.length));
-
-        data = IccUtils.hexStringToBytes("820505302D82d32d31");
-        // Example from 3GPP TS 11.11 V18.1.3.0 annex B
-        assertEquals("-\u0532\u0583-1", IccUtils.adnStringFieldToString(data, 0, data.length));
-    }
-
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/SmsMessageBodyTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/SmsMessageBodyTest.java
deleted file mode 100644
index 170bd9b..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/SmsMessageBodyTest.java
+++ /dev/null
@@ -1,606 +0,0 @@
-/*
- * Copyright (C) 2010 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.internal.telephony;
-
-import android.telephony.SmsMessage;
-import android.telephony.TelephonyManager;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
-
-import java.util.Random;
-
-import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES;
-import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER;
-import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS;
-import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS_WITH_HEADER;
-
-/**
- * Test cases to verify selection of the optimal 7 bit encoding tables
- * (for all combinations of enabled national language tables) for messages
- * containing Turkish, Spanish, Portuguese, Greek, and other symbols
- * present in the GSM default and national language tables defined in
- * 3GPP TS 23.038. Also verifies correct SMS encoding for CDMA, which only
- * supports the GSM 7 bit default alphabet, ASCII 8 bit, and UCS-2.
- * Tests both encoding variations: unsupported characters mapped to space,
- * and unsupported characters force entire message to UCS-2.
- */
-public class SmsMessageBodyTest extends AndroidTestCase {
-    private static final String TAG = "SmsMessageBodyTest";
-
-    // ASCII chars in the GSM 7 bit default alphabet
-    private static final String sAsciiChars = "@$_ !\"#%&'()*+,-./0123456789" +
-            ":;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\n\r";
-
-    // Unicode chars in the GSM 7 bit default alphabet and both locking shift tables
-    private static final String sGsmDefaultChars = "\u00a3\u00a5\u00e9\u00c7\u0394\u00c9" +
-            "\u00dc\u00a7\u00fc\u00e0";
-
-    // Unicode chars in the GSM 7 bit default table and Turkish locking shift tables
-    private static final String sGsmDefaultAndTurkishTables = "\u00f9\u00f2\u00c5\u00e5\u00df" +
-            "\u00a4\u00c4\u00d6\u00d1\u00e4\u00f6\u00f1";
-
-    // Unicode chars in the GSM 7 bit default table but not the locking shift tables
-    private static final String sGsmDefaultTableOnly = "\u00e8\u00ec\u00d8\u00f8\u00c6\u00e6" +
-            "\u00a1\u00bf";
-
-    // ASCII chars in the GSM default extension table
-    private static final String sGsmExtendedAsciiChars = "{}[]\f";
-
-    // chars in GSM default extension table and Portuguese locking shift table
-    private static final String sGsmExtendedPortugueseLocking = "^\\|~";
-
-    // Euro currency symbol
-    private static final String sGsmExtendedEuroSymbol = "\u20ac";
-
-    // CJK ideographs, Hiragana, Katakana, full width letters, Cyrillic, etc.
-    private static final String sUnicodeChars = "\u4e00\u4e01\u4e02\u4e03" +
-            "\u4e04\u4e05\u4e06\u4e07\u4e08\u4e09\u4e0a\u4e0b\u4e0c\u4e0d" +
-            "\u4e0e\u4e0f\u3041\u3042\u3043\u3044\u3045\u3046\u3047\u3048" +
-            "\u30a1\u30a2\u30a3\u30a4\u30a5\u30a6\u30a7\u30a8" +
-            "\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18" +
-            "\uff70\uff71\uff72\uff73\uff74\uff75\uff76\uff77\uff78" +
-            "\u0400\u0401\u0402\u0403\u0404\u0405\u0406\u0407\u0408" +
-            "\u00a2\u00a9\u00ae\u2122";
-
-    // chars in Turkish single shift and locking shift tables
-    private static final String sTurkishChars = "\u0131\u011e\u011f\u015e\u015f\u0130";
-
-    // chars in Spanish single shift table and Portuguese single and locking shift tables
-    private static final String sPortugueseAndSpanishChars = "\u00c1\u00e1\u00cd\u00ed"
-            + "\u00d3\u00f3\u00da\u00fa";
-
-    // chars in all national language tables but not in the standard GSM alphabets
-    private static final String sNationalLanguageTablesOnly = "\u00e7";
-
-    // chars in Portuguese single shift and locking shift tables
-    private static final String sPortugueseChars = "\u00ea\u00d4\u00f4\u00c0\u00c2\u00e2"
-            + "\u00ca\u00c3\u00d5\u00e3\u00f5";
-
-    // chars in Portuguese locking shift table only
-    private static final String sPortugueseLockingShiftChars = "\u00aa\u221e\u00ba`";
-
-    // Greek letters in GSM alphabet missing from Portuguese locking and single shift tables
-    private static final String sGreekLettersNotInPortugueseTables = "\u039b\u039e";
-
-    // Greek letters in GSM alphabet and Portuguese single shift (but not locking shift) table
-    private static final String sGreekLettersInPortugueseShiftTable =
-            "\u03a6\u0393\u03a9\u03a0\u03a8\u03a3\u0398";
-
-    // List of classes of characters in SMS tables
-    private static final String[] sCharacterClasses = {
-            sGsmExtendedAsciiChars,
-            sGsmExtendedPortugueseLocking,
-            sGsmDefaultChars,
-            sGsmDefaultAndTurkishTables,
-            sGsmDefaultTableOnly,
-            sGsmExtendedEuroSymbol,
-            sUnicodeChars,
-            sTurkishChars,
-            sPortugueseChars,
-            sPortugueseLockingShiftChars,
-            sPortugueseAndSpanishChars,
-            sGreekLettersNotInPortugueseTables,
-            sGreekLettersInPortugueseShiftTable,
-            sNationalLanguageTablesOnly,
-            sAsciiChars
-    };
-
-    private static final int sNumCharacterClasses = sCharacterClasses.length;
-
-    // For each character class, whether it is present in a particular char table.
-    // First three entries are locking shift tables, followed by four single shift tables
-    private static final boolean[][] sCharClassPresenceInTables = {
-            // ASCII chars in all GSM extension tables
-            {false, false, false, true, true, true, true},
-            // ASCII chars in all GSM extension tables and Portuguese locking shift table
-            {false, false, true, true, true, true, true},
-            // non-ASCII chars in GSM default alphabet and all locking tables
-            {true, true, true, false, false, false, false},
-            // non-ASCII chars in GSM default alphabet and Turkish locking shift table
-            {true, true, false, false, false, false, false},
-            // non-ASCII chars in GSM default alphabet table only
-            {true, false, false, false, false, false, false},
-            // Euro symbol is present in several tables
-            {false, true, true, true, true, true, true},
-            // Unicode characters not present in any 7 bit tables
-            {false, false, false, false, false, false, false},
-            // Characters specific to Turkish language
-            {false, true, false, false, true, false, false},
-            // Characters in Portuguese single shift and locking shift tables
-            {false, false, true, false, false, false, true},
-            // Characters in Portuguese locking shift table only
-            {false, false, true, false, false, false, false},
-            // Chars in Spanish single shift and Portuguese single and locking shift tables
-            {false, false, true, false, false, true, true},
-            // Greek letters in GSM default alphabet missing from Portuguese tables
-            {true, true, false, false, false, false, false},
-            // Greek letters in GSM alphabet and Portuguese single shift table
-            {true, true, false, false, false, false, true},
-            // Chars in all national language tables but not the standard GSM tables
-            {false, true, true, false, true, true, true},
-            // ASCII chars in GSM default alphabet
-            {true, true, true, false, false, false, false}
-    };
-
-    private static final int sTestLengthCount = 12;
-
-    private static final int[] sSeptetTestLengths =
-            {  0,   1,   2, 80, 159, 160, 161, 240, 305, 306, 307, 320};
-
-    private static final int[] sUnicodeTestLengths =
-            {  0,   1,   2, 35,  69,  70,  71, 100, 133, 134, 135, 160};
-
-    private static final int[] sTestMsgCounts =
-            {  1,   1,   1,  1,   1,   1,   2,   2,   2,   2,   3,   3};
-
-    private static final int[] sSeptetUnitsRemaining =
-            {160, 159, 158, 80,   1,   0, 145,  66,   1,   0, 152, 139};
-
-    private static final int[] sUnicodeUnitsRemaining =
-            { 70,  69,  68, 35,   1,   0,  63,  34,   1,   0,  66,  41};
-
-    // Combinations of enabled GSM national language single shift tables
-    private static final int[][] sEnabledSingleShiftTables = {
-            {},         // GSM default alphabet only
-            {1},        // Turkish (single shift only)
-            {1},        // Turkish (single and locking shift)
-            {2},        // Spanish
-            {3},        // Portuguese (single shift only)
-            {3},        // Portuguese (single and locking shift)
-            {1, 2},     // Turkish + Spanish (single shift only)
-            {1, 2},     // Turkish + Spanish (single and locking shift)
-            {1, 3},     // Turkish + Portuguese (single shift only)
-            {1, 3},     // Turkish + Portuguese (single and locking shift)
-            {2, 3},     // Spanish + Portuguese (single shift only)
-            {2, 3},     // Spanish + Portuguese (single and locking shift)
-            {1, 2, 3},  // Turkish, Spanish, Portuguese (single shift only)
-            {1, 2, 3},  // Turkish, Spanish, Portuguese (single and locking shift)
-            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} // all language tables
-    };
-
-    // Combinations of enabled GSM national language locking shift tables
-    private static final int[][] sEnabledLockingShiftTables = {
-            {},         // GSM default alphabet only
-            {},         // Turkish (single shift only)
-            {1},        // Turkish (single and locking shift)
-            {},         // Spanish (no locking shift table)
-            {},         // Portuguese (single shift only)
-            {3},        // Portuguese (single and locking shift)
-            {},         // Turkish + Spanish (single shift only)
-            {1},        // Turkish + Spanish (single and locking shift)
-            {},         // Turkish + Portuguese (single shift only)
-            {1, 3},     // Turkish + Portuguese (single and locking shift)
-            {},         // Spanish + Portuguese (single shift only)
-            {3},        // Spanish + Portuguese (single and locking shift)
-            {},         // Turkish, Spanish, Portuguese (single shift only)
-            {1, 3},     // Turkish, Spanish, Portuguese (single and locking shift)
-            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} // all language tables
-    };
-
-    // LanguagePair counter indexes to check for each entry above
-    private static final int[][] sLanguagePairIndexesByEnabledIndex = {
-            {0},                            // default tables only
-            {0, 1},                         // Turkish (single shift only)
-            {0, 1, 4, 5},                   // Turkish (single and locking shift)
-            {0, 2},                         // Spanish
-            {0, 3},                         // Portuguese (single shift only)
-            {0, 3, 8, 11},                  // Portuguese (single and locking shift)
-            {0, 1, 2},                      // Turkish + Spanish (single shift only)
-            {0, 1, 2, 4, 5, 6},             // Turkish + Spanish (single and locking shift)
-            {0, 1, 3},                      // Turkish + Portuguese (single shift only)
-            {0, 1, 3, 4, 5, 7, 8, 9, 11},   // Turkish + Portuguese (single and locking shift)
-            {0, 2, 3},                      // Spanish + Portuguese (single shift only)
-            {0, 2, 3, 8, 10, 11},           // Spanish + Portuguese (single and locking shift)
-            {0, 1, 2, 3},                   // all languages (single shift only)
-            {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, // all languages (single and locking shift)
-            {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}  // all languages (no Indic chars in test)
-    };
-
-    /**
-     * User data header requires one octet for length. Count as one septet, because
-     * all combinations of header elements below will have at least one free bit
-     * when padding to the nearest septet boundary.
-     */
-    private static final int UDH_SEPTET_COST_LENGTH = 1;
-
-    /**
-     * Using a non-default language locking shift table OR single shift table
-     * requires a user data header of 3 octets, or 4 septets, plus UDH length.
-     */
-    private static final int UDH_SEPTET_COST_ONE_SHIFT_TABLE = 4;
-
-    /**
-     * Using a non-default language locking shift table AND single shift table
-     * requires a user data header of 6 octets, or 7 septets, plus UDH length.
-     */
-    private static final int UDH_SEPTET_COST_TWO_SHIFT_TABLES = 7;
-
-    /**
-     * Multi-part messages require a user data header of 5 octets, or 6 septets,
-     * plus UDH length.
-     */
-    private static final int UDH_SEPTET_COST_CONCATENATED_MESSAGE = 6;
-
-    @SmallTest
-    public void testCalcLengthAscii() throws Exception {
-        StringBuilder sb = new StringBuilder(320);
-        int[] values = {0, 0, 0, SmsMessage.ENCODING_7BIT, 0, 0};
-        int startPos = 0;
-        int asciiCharsLen = sAsciiChars.length();
-
-        for (int i = 0; i < sTestLengthCount; i++) {
-            int len = sSeptetTestLengths[i];
-            assertTrue(sb.length() <= len);
-
-            while (sb.length() < len) {
-                int addCount = len - sb.length();
-                int endPos = (asciiCharsLen - startPos > addCount) ?
-                        (startPos + addCount) : asciiCharsLen;
-                sb.append(sAsciiChars, startPos, endPos);
-                startPos = (endPos == asciiCharsLen) ? 0 : endPos;
-            }
-            assertEquals(len, sb.length());
-
-            String testStr = sb.toString();
-            values[0] = sTestMsgCounts[i];
-            values[1] = len;
-            values[2] = sSeptetUnitsRemaining[i];
-
-            callGsmLengthMethods(testStr, false, values);
-            callGsmLengthMethods(testStr, true, values);
-            callCdmaLengthMethods(testStr, false, values);
-            callCdmaLengthMethods(testStr, true, values);
-        }
-    }
-
-    @SmallTest
-    public void testCalcLengthUnicode() throws Exception {
-        StringBuilder sb = new StringBuilder(160);
-        int[] values = {0, 0, 0, SmsMessage.ENCODING_16BIT, 0, 0};
-        int[] values7bit = {1, 0, 0, SmsMessage.ENCODING_7BIT, 0, 0};
-        int startPos = 0;
-        int unicodeCharsLen = sUnicodeChars.length();
-
-        // start with length 1: empty string uses ENCODING_7BIT
-        for (int i = 1; i < sTestLengthCount; i++) {
-            int len = sUnicodeTestLengths[i];
-            assertTrue(sb.length() <= len);
-
-            while (sb.length() < len) {
-                int addCount = len - sb.length();
-                int endPos = (unicodeCharsLen - startPos > addCount) ?
-                        (startPos + addCount) : unicodeCharsLen;
-                sb.append(sUnicodeChars, startPos, endPos);
-                startPos = (endPos == unicodeCharsLen) ? 0 : endPos;
-            }
-            assertEquals(len, sb.length());
-
-            String testStr = sb.toString();
-            values[0] = sTestMsgCounts[i];
-            values[1] = len;
-            values[2] = sUnicodeUnitsRemaining[i];
-            values7bit[1] = len;
-            values7bit[2] = MAX_USER_DATA_SEPTETS - len;
-
-            callGsmLengthMethods(testStr, false, values);
-            callCdmaLengthMethods(testStr, false, values);
-            callGsmLengthMethods(testStr, true, values7bit);
-            callCdmaLengthMethods(testStr, true, values7bit);
-        }
-    }
-
-    private static class LanguagePair {
-        // index is 2 for Portuguese locking shift because there is no Spanish locking shift table
-        private final int langTableIndex;
-        private final int langShiftTableIndex;
-        int length;
-        int missingChars7bit;
-
-        LanguagePair(int langTable, int langShiftTable) {
-            langTableIndex = langTable;
-            langShiftTableIndex = langShiftTable;
-        }
-
-        void clear() {
-            length = 0;
-            missingChars7bit = 0;
-        }
-
-        void addChar(boolean[] charClassTableRow) {
-            if (charClassTableRow[langTableIndex]) {
-                length++;
-            } else if (charClassTableRow[3 + langShiftTableIndex]) {
-                length += 2;
-            } else {
-                length++;    // use ' ' for unmapped char in 7 bit only mode
-                missingChars7bit++;
-            }
-        }
-    }
-
-    private static class CounterHelper {
-        LanguagePair[] mCounters;
-        int[] mStatsCounters;
-        int mUnicodeCounter;
-
-        CounterHelper() {
-            mCounters = new LanguagePair[12];
-            mStatsCounters = new int[12];
-            for (int i = 0; i < 12; i++) {
-                mCounters[i] = new LanguagePair(i/4, i%4);
-            }
-        }
-
-        void clear() {
-            // Note: don't clear stats counters
-            for (int i = 0; i < 12; i++) {
-                mCounters[i].clear();
-            }
-        }
-
-        void addChar(int charClass) {
-            boolean[] charClassTableRow = sCharClassPresenceInTables[charClass];
-            for (int i = 0; i < 12; i++) {
-                mCounters[i].addChar(charClassTableRow);
-            }
-        }
-
-        void fillData(int enabledLangsIndex, boolean use7bitOnly, int[] values, int length) {
-            int[] languagePairs = sLanguagePairIndexesByEnabledIndex[enabledLangsIndex];
-            int minNumSeptets = Integer.MAX_VALUE;
-            int minNumSeptetsWithHeader = Integer.MAX_VALUE;
-            int minNumMissingChars = Integer.MAX_VALUE;
-            int langIndex = -1;
-            int langShiftIndex = -1;
-            for (int i : languagePairs) {
-                LanguagePair pair = mCounters[i];
-                int udhLength = 0;
-                if (i != 0) {
-                    udhLength = UDH_SEPTET_COST_LENGTH;
-                    if (i < 4 || i % 4 == 0) {
-                        udhLength += UDH_SEPTET_COST_ONE_SHIFT_TABLE;
-                    } else {
-                        udhLength += UDH_SEPTET_COST_TWO_SHIFT_TABLES;
-                    }
-                }
-                int numSeptetsWithHeader;
-                if (pair.length > (MAX_USER_DATA_SEPTETS - udhLength)) {
-                    if (udhLength == 0) {
-                        udhLength = UDH_SEPTET_COST_LENGTH;
-                    }
-                    udhLength += UDH_SEPTET_COST_CONCATENATED_MESSAGE;
-                    int septetsPerPart = MAX_USER_DATA_SEPTETS - udhLength;
-                    int msgCount = (pair.length + septetsPerPart - 1) / septetsPerPart;
-                    numSeptetsWithHeader = udhLength * msgCount + pair.length;
-                } else {
-                    numSeptetsWithHeader = udhLength + pair.length;
-                }
-
-                if (use7bitOnly) {
-                    if (pair.missingChars7bit < minNumMissingChars || (pair.missingChars7bit ==
-                            minNumMissingChars && numSeptetsWithHeader < minNumSeptetsWithHeader)) {
-                        minNumSeptets = pair.length;
-                        minNumSeptetsWithHeader = numSeptetsWithHeader;
-                        minNumMissingChars = pair.missingChars7bit;
-                        langIndex = pair.langTableIndex;
-                        langShiftIndex = pair.langShiftTableIndex;
-                    }
-                } else {
-                    if (pair.missingChars7bit == 0 && numSeptetsWithHeader < minNumSeptetsWithHeader) {
-                        minNumSeptets = pair.length;
-                        minNumSeptetsWithHeader = numSeptetsWithHeader;
-                        langIndex = pair.langTableIndex;
-                        langShiftIndex = pair.langShiftTableIndex;
-                    }
-                }
-            }
-            if (langIndex == -1) {
-                // nothing matches, use values for Unicode
-                int byteCount = length * 2;
-                if (byteCount > MAX_USER_DATA_BYTES) {
-                    values[0] = (byteCount + MAX_USER_DATA_BYTES_WITH_HEADER - 1) /
-                            MAX_USER_DATA_BYTES_WITH_HEADER;
-                    values[2] = ((values[0] * MAX_USER_DATA_BYTES_WITH_HEADER) - byteCount) / 2;
-                } else {
-                    values[0] = 1;
-                    values[2] = (MAX_USER_DATA_BYTES - byteCount) / 2;
-                }
-                values[1] = length;
-                values[3] = SmsMessage.ENCODING_16BIT;
-                values[4] = 0;
-                values[5] = 0;
-                mUnicodeCounter++;
-            } else {
-                int udhLength = 0;
-                if (langIndex != 0 || langShiftIndex != 0) {
-                    udhLength = UDH_SEPTET_COST_LENGTH;
-                    if (langIndex == 0 || langShiftIndex == 0) {
-                        udhLength += UDH_SEPTET_COST_ONE_SHIFT_TABLE;
-                    } else {
-                        udhLength += UDH_SEPTET_COST_TWO_SHIFT_TABLES;
-                    }
-                }
-                int msgCount;
-                if (minNumSeptets > (MAX_USER_DATA_SEPTETS - udhLength)) {
-                    if (udhLength == 0) {
-                        udhLength = UDH_SEPTET_COST_LENGTH;
-                    }
-                    udhLength += UDH_SEPTET_COST_CONCATENATED_MESSAGE;
-                    int septetsPerPart = MAX_USER_DATA_SEPTETS - udhLength;
-                    msgCount = (minNumSeptets + septetsPerPart - 1) / septetsPerPart;
-                } else {
-                    msgCount = 1;
-                }
-                values[0] = msgCount;
-                values[1] = minNumSeptets;
-                values[2] = (values[0] * (MAX_USER_DATA_SEPTETS - udhLength)) - minNumSeptets;
-                values[3] = SmsMessage.ENCODING_7BIT;
-                values[4] = (langIndex == 2 ? 3 : langIndex); // Portuguese is code 3, index 2
-                values[5] = langShiftIndex;
-                assertEquals("minNumSeptetsWithHeader", minNumSeptetsWithHeader,
-                        udhLength * msgCount + minNumSeptets);
-                mStatsCounters[langIndex * 4 + langShiftIndex]++;
-            }
-        }
-
-        void printStats() {
-            Log.d(TAG, "Unicode selection count: " + mUnicodeCounter);
-            for (int i = 0; i < 12; i++) {
-                Log.d(TAG, "Language pair index " + i + " count: " + mStatsCounters[i]);
-            }
-        }
-    }
-
-    @LargeTest
-    public void testCalcLengthMixed7bit() throws Exception {
-        StringBuilder sb = new StringBuilder(320);
-        CounterHelper ch = new CounterHelper();
-        Random r = new Random(0x4321);  // use the same seed for reproducibility
-        int[] expectedValues = new int[6];
-        int[] origLockingShiftTables = GsmAlphabet.getEnabledLockingShiftTables();
-        int[] origSingleShiftTables = GsmAlphabet.getEnabledSingleShiftTables();
-        int enabledLanguagesTestCases = sEnabledSingleShiftTables.length;
-        long startTime = System.currentTimeMillis();
-
-        // Repeat for 10 test runs
-        for (int run = 0; run < 10; run++) {
-            sb.setLength(0);
-            ch.clear();
-            int unicodeOnlyCount = 0;
-
-            // Test incrementally from 1 to 320 character random messages
-            for (int i = 1; i < 320; i++) {
-                // 1% chance to add from each special character class, else add an ASCII char
-                int charClass = r.nextInt(100);
-                if (charClass >= sNumCharacterClasses) {
-                    charClass = sNumCharacterClasses - 1;   // last class is ASCII
-                }
-                int classLength = sCharacterClasses[charClass].length();
-                char nextChar = sCharacterClasses[charClass].charAt(r.nextInt(classLength));
-                sb.append(nextChar);
-                ch.addChar(charClass);
-
-//                if (i % 20 == 0) {
-//                    Log.d(TAG, "test string: " + sb);
-//                }
-
-                // Test string against all combinations of enabled languages
-                boolean unicodeOnly = true;
-                for (int j = 0; j < enabledLanguagesTestCases; j++) {
-                    GsmAlphabet.setEnabledSingleShiftTables(sEnabledSingleShiftTables[j]);
-                    GsmAlphabet.setEnabledLockingShiftTables(sEnabledLockingShiftTables[j]);
-                    ch.fillData(j, false, expectedValues, i);
-                    if (expectedValues[3] == SmsMessage.ENCODING_7BIT) {
-                        unicodeOnly = false;
-                    }
-                    callGsmLengthMethods(sb, false, expectedValues);
-                    // test 7 bit only mode
-                    ch.fillData(j, true, expectedValues, i);
-                    callGsmLengthMethods(sb, true, expectedValues);
-                }
-                // after 10 iterations with a Unicode-only string, skip to next test string
-                // so we can spend more time testing strings that do encode into 7 bits.
-                if (unicodeOnly && ++unicodeOnlyCount == 10) {
-//                    Log.d(TAG, "Unicode only: skipping to next test string");
-                    break;
-                }
-            }
-        }
-        ch.printStats();
-        Log.d(TAG, "Completed in " + (System.currentTimeMillis() - startTime) + " ms");
-        GsmAlphabet.setEnabledLockingShiftTables(origLockingShiftTables);
-        GsmAlphabet.setEnabledSingleShiftTables(origSingleShiftTables);
-    }
-
-    private void callGsmLengthMethods(CharSequence msgBody, boolean use7bitOnly,
-            int[] expectedValues)
-    {
-        // deprecated GSM-specific method
-        int[] values = android.telephony.gsm.SmsMessage.calculateLength(msgBody, use7bitOnly);
-        assertEquals("msgCount",           expectedValues[0], values[0]);
-        assertEquals("codeUnitCount",      expectedValues[1], values[1]);
-        assertEquals("codeUnitsRemaining", expectedValues[2], values[2]);
-        assertEquals("codeUnitSize",       expectedValues[3], values[3]);
-
-        int activePhone = TelephonyManager.getDefault().getPhoneType();
-        if (TelephonyManager.PHONE_TYPE_GSM == activePhone) {
-            values = android.telephony.SmsMessage.calculateLength(msgBody, use7bitOnly);
-            assertEquals("msgCount",           expectedValues[0], values[0]);
-            assertEquals("codeUnitCount",      expectedValues[1], values[1]);
-            assertEquals("codeUnitsRemaining", expectedValues[2], values[2]);
-            assertEquals("codeUnitSize",       expectedValues[3], values[3]);
-        }
-
-        SmsMessageBase.TextEncodingDetails ted =
-                com.android.internal.telephony.gsm.SmsMessage.calculateLength(msgBody, use7bitOnly);
-        assertEquals("msgCount",           expectedValues[0], ted.msgCount);
-        assertEquals("codeUnitCount",      expectedValues[1], ted.codeUnitCount);
-        assertEquals("codeUnitsRemaining", expectedValues[2], ted.codeUnitsRemaining);
-        assertEquals("codeUnitSize",       expectedValues[3], ted.codeUnitSize);
-        assertEquals("languageTable",      expectedValues[4], ted.languageTable);
-        assertEquals("languageShiftTable", expectedValues[5], ted.languageShiftTable);
-    }
-
-    private void callCdmaLengthMethods(CharSequence msgBody, boolean use7bitOnly,
-            int[] expectedValues)
-    {
-        int activePhone = TelephonyManager.getDefault().getPhoneType();
-        if (TelephonyManager.PHONE_TYPE_CDMA == activePhone) {
-            int[] values = android.telephony.SmsMessage.calculateLength(msgBody, use7bitOnly);
-            assertEquals("msgCount",           expectedValues[0], values[0]);
-            assertEquals("codeUnitCount",      expectedValues[1], values[1]);
-            assertEquals("codeUnitsRemaining", expectedValues[2], values[2]);
-            assertEquals("codeUnitSize",       expectedValues[3], values[3]);
-        }
-
-        SmsMessageBase.TextEncodingDetails ted =
-                com.android.internal.telephony.cdma.SmsMessage.calculateLength(msgBody, use7bitOnly);
-        assertEquals("msgCount",           expectedValues[0], ted.msgCount);
-        assertEquals("codeUnitCount",      expectedValues[1], ted.codeUnitCount);
-        assertEquals("codeUnitsRemaining", expectedValues[2], ted.codeUnitsRemaining);
-        assertEquals("codeUnitSize",       expectedValues[3], ted.codeUnitSize);
-
-        ted = com.android.internal.telephony.cdma.sms.BearerData.calcTextEncodingDetails(msgBody, use7bitOnly);
-        assertEquals("msgCount",           expectedValues[0], ted.msgCount);
-        assertEquals("codeUnitCount",      expectedValues[1], ted.codeUnitCount);
-        assertEquals("codeUnitsRemaining", expectedValues[2], ted.codeUnitsRemaining);
-        assertEquals("codeUnitSize",       expectedValues[3], ted.codeUnitSize);
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/TelephonyUtilsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/TelephonyUtilsTest.java
deleted file mode 100644
index 3757017..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/TelephonyUtilsTest.java
+++ /dev/null
@@ -1,219 +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.
- */
-
-package com.android.internal.telephony;
-
-import com.android.internal.telephony.RetryManager;
-import junit.framework.TestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-public class TelephonyUtilsTest extends TestCase {
-
-    /**
-     * After first creating the RetryManager
-     * isRetryNeeded should be false and the time 0
-     */
-    @SmallTest
-    public void testRetryManagerEmpty() throws Exception {
-        RetryManager rm = new RetryManager();
-
-        assertEquals(0, rm.getRetryCount());
-        assertFalse(rm.isRetryForever());
-        assertFalse(rm.isRetryNeeded());
-        assertEquals(0, rm.getRetryCount());
-        assertEquals(0, rm.getRetryTimer());
-
-        rm.increaseRetryCount();
-        assertFalse(rm.isRetryForever());
-        assertFalse(rm.isRetryNeeded());
-        assertEquals(0, rm.getRetryCount());
-        assertEquals(0, rm.getRetryTimer());
-
-        rm.setRetryCount(123);
-        assertFalse(rm.isRetryForever());
-        assertFalse(rm.isRetryNeeded());
-        assertEquals(0, rm.getRetryCount());
-        assertEquals(0, rm.getRetryTimer());
-
-        rm.retryForeverUsingLastTimeout();
-        assertTrue(rm.isRetryForever());
-        assertTrue(rm.isRetryNeeded());
-        assertEquals(0, rm.getRetryCount());
-        assertEquals(0, rm.getRetryTimer());
-
-        rm.setRetryCount(2);
-        assertFalse(rm.isRetryForever());
-        assertFalse(rm.isRetryNeeded());
-        assertEquals(0, rm.getRetryCount());
-        assertEquals(0, rm.getRetryTimer());
-    }
-
-    /**
-     * A simple test and that randomization is doing something.
-     */
-    @SmallTest
-    public void testRetryManagerSimplest() throws Exception {
-        RetryManager rm = new RetryManager();
-
-        assertTrue(rm.configure(1, 500, 10));
-        int loops = 10;
-        int count = 0;
-        for (int i = 0; i < loops; i++) {
-            assertTrue(rm.isRetryNeeded());
-            int time = rm.getRetryTimer();
-            assertTrue((time >= 500) && (time < 600));
-            if (time == 500) {
-                count++;
-            }
-        }
-        assertFalse(count == loops);
-        rm.increaseRetryCount();
-        assertFalse(rm.isRetryNeeded());
-        rm.setRetryCount(0);
-        assertTrue(rm.isRetryNeeded());
-    }
-
-    /**
-     * Test multiple values using simple configuration.
-     */
-    @SmallTest
-    public void testRetryManagerSimple() throws Exception {
-        RetryManager rm = new RetryManager();
-
-        assertTrue(rm.configure(3, 1000, 0));
-        assertTrue(rm.isRetryNeeded());
-        assertEquals(1000, rm.getRetryTimer());
-        assertEquals(rm.getRetryTimer(), 1000);
-        rm.increaseRetryCount();
-        assertTrue(rm.isRetryNeeded());
-        assertEquals(1000, rm.getRetryTimer());
-        rm.increaseRetryCount();
-        assertTrue(rm.isRetryNeeded());
-        assertEquals(1000, rm.getRetryTimer());
-        rm.increaseRetryCount();
-        assertFalse(rm.isRetryNeeded());
-        assertEquals(1000, rm.getRetryTimer());
-    }
-
-    /**
-     * Test string configuration, simplest
-     */
-    @SmallTest
-    public void testRetryManageSimpleString() throws Exception {
-        RetryManager rm = new RetryManager();
-
-        assertTrue(rm.configure("101"));
-        assertTrue(rm.isRetryNeeded());
-        assertEquals(101, rm.getRetryTimer());
-        rm.increaseRetryCount();
-        assertFalse(rm.isRetryNeeded());
-    }
-
-    /**
-     * Test infinite retires
-     */
-    @SmallTest
-    public void testRetryManageInfinite() throws Exception {
-        RetryManager rm = new RetryManager();
-
-        assertTrue(rm.configure("1000,2000,3000,max_retries=infinite"));
-        assertTrue(rm.isRetryNeeded());
-        assertEquals(1000, rm.getRetryTimer());
-        rm.increaseRetryCount();
-        assertTrue(rm.isRetryNeeded());
-        assertEquals(2000, rm.getRetryTimer());
-        rm.increaseRetryCount();
-        assertTrue(rm.isRetryNeeded());
-        // All others are 3000 and isRetryNeeded is always true
-        for (int i=0; i < 100; i++) {
-            assertEquals(3000, rm.getRetryTimer());
-            rm.increaseRetryCount();
-            assertTrue(rm.isRetryNeeded());
-        }
-    }
-
-    /**
-     * Test string configuration using all options and with quotes.
-     */
-    @SmallTest
-    public void testRetryManageString() throws Exception {
-        RetryManager rm = new RetryManager();
-        int time;
-
-        assertTrue(rm.configure(
-                "\"max_retries=4, default_randomization=100,1000, 2000 :200 , 3000\""));
-        assertTrue(rm.isRetryNeeded());
-        time = rm.getRetryTimer();
-        assertTrue((time >= 1000) && (time < 1100));
-
-        rm.increaseRetryCount();
-        assertTrue(rm.isRetryNeeded());
-        time = rm.getRetryTimer();
-        assertTrue((time >= 2000) && (time < 2200));
-
-        rm.increaseRetryCount();
-        assertTrue(rm.isRetryNeeded());
-        time = rm.getRetryTimer();
-        assertTrue((time >= 3000) && (time < 3100));
-
-        rm.increaseRetryCount();
-        assertTrue(rm.isRetryNeeded());
-        time = rm.getRetryTimer();
-        assertTrue((time >= 3000) && (time < 3100));
-
-        rm.increaseRetryCount();
-        assertFalse(rm.isRetryNeeded());
-    }
-
-    /**
-     * Test string configuration using all options.
-     */
-    @SmallTest
-    public void testRetryManageForever() throws Exception {
-        RetryManager rm = new RetryManager();
-        int time;
-
-        assertTrue(rm.configure("1000, 2000, 3000"));
-        assertTrue(rm.isRetryNeeded());
-        assertFalse(rm.isRetryForever());
-        assertEquals(0, rm.getRetryCount());
-        assertEquals(1000, rm.getRetryTimer());
-
-        rm.retryForeverUsingLastTimeout();
-        rm.increaseRetryCount();
-        rm.increaseRetryCount();
-        rm.increaseRetryCount();
-        assertTrue(rm.isRetryNeeded());
-        assertTrue(rm.isRetryForever());
-        assertEquals(3, rm.getRetryCount());
-        assertEquals(3000, rm.getRetryTimer());
-
-        rm.setRetryCount(1);
-        assertTrue(rm.isRetryNeeded());
-        assertFalse(rm.isRetryForever());
-        assertEquals(1, rm.getRetryCount());
-        assertEquals(2000, rm.getRetryTimer());
-
-        rm.retryForeverUsingLastTimeout();
-        assertTrue(rm.isRetryNeeded());
-        assertTrue(rm.isRetryForever());
-        rm.resetRetryCount();
-        assertTrue(rm.isRetryNeeded());
-        assertFalse(rm.isRetryForever());
-        assertEquals(0, rm.getRetryCount());
-        assertEquals(1000, rm.getRetryTimer());
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java
deleted file mode 100644
index cb67a93..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java
+++ /dev/null
@@ -1,66 +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.internal.telephony;
-
-import com.android.internal.telephony.Phone;
-import android.telephony.CellInfo;
-
-/**
- * Stub class used for unit tests
- */
-
-public class TestPhoneNotifier implements PhoneNotifier {
-    public TestPhoneNotifier() {
-    }
-
-    public void notifyPhoneState(Phone sender) {
-    }
-
-    public void notifyServiceState(Phone sender) {
-    }
-
-    public void notifyCellLocation(Phone sender) {
-    }
-
-    public void notifySignalStrength(Phone sender) {
-    }
-
-    public void notifyMessageWaitingChanged(Phone sender) {
-    }
-
-    public void notifyCallForwardingChanged(Phone sender) {
-    }
-
-    public void notifyDataConnection(Phone sender, String reason, String apnType) {
-    }
-
-    public void notifyDataConnection(Phone sender, String reason, String apnType,
-            Phone.DataState state) {
-    }
-
-    public void notifyDataConnectionFailed(Phone sender, String reason, String apnType) {
-    }
-
-    public void notifyDataActivity(Phone sender) {
-    }
-
-    public void notifyOtaspChanged(Phone sender, int otaspMode) {
-    }
-
-    public void notifyCellInfo(Phone sender, CellInfo cellInfo) {
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/Wap230WspContentTypeTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/Wap230WspContentTypeTest.java
deleted file mode 100644
index d31b294..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/Wap230WspContentTypeTest.java
+++ /dev/null
@@ -1,853 +0,0 @@
-/*
- * Copyright (C) 2010 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.internal.telephony;
-
-import com.android.internal.telephony.WspTypeDecoder;
-import com.android.internal.util.HexDump;
-
-import java.io.ByteArrayOutputStream;
-import java.util.HashMap;
-import java.util.Map;
-
-import junit.framework.TestCase;
-
-public class Wap230WspContentTypeTest extends TestCase {
-
-    public static final Map<Integer, String> WELL_KNOWN_SHORT_MIME_TYPES
-            = new HashMap<Integer, String>();
-    public static final Map<Integer, String> WELL_KNOWN_LONG_MIME_TYPES
-            = new HashMap<Integer, String>();
-    public static final Map<Integer, String> WELL_KNOWN_PARAMETERS
-            = new HashMap<Integer, String>();
-
-    static {
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x00, "*/*");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x01, "text/*");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x02, "text/html");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x03, "text/plain");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x04, "text/x-hdml");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x05, "text/x-ttml");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x06, "text/x-vCalendar");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x07, "text/x-vCard");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x08, "text/vnd.wap.wml");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x09, "text/vnd.wap.wmlscript");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x0A, "text/vnd.wap.wta-event");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x0B, "multipart/*");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x0C, "multipart/mixed");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x0D, "multipart/form-data");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x0E, "multipart/byterantes");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x0F, "multipart/alternative");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x10, "application/*");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x11, "application/java-vm");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x12, "application/x-www-form-urlencoded");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x13, "application/x-hdmlc");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x14, "application/vnd.wap.wmlc");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x15, "application/vnd.wap.wmlscriptc");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x16, "application/vnd.wap.wta-eventc");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x17, "application/vnd.wap.uaprof");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x18, "application/vnd.wap.wtls-ca-certificate");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x19, "application/vnd.wap.wtls-user-certificate");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x1A, "application/x-x509-ca-cert");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x1B, "application/x-x509-user-cert");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x1C, "image/*");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x1D, "image/gif");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x1E, "image/jpeg");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x1F, "image/tiff");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x20, "image/png");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x21, "image/vnd.wap.wbmp");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x22, "application/vnd.wap.multipart.*");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x23, "application/vnd.wap.multipart.mixed");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x24, "application/vnd.wap.multipart.form-data");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x25, "application/vnd.wap.multipart.byteranges");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x26, "application/vnd.wap.multipart.alternative");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x27, "application/xml");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x28, "text/xml");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x29, "application/vnd.wap.wbxml");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x2A, "application/x-x968-cross-cert");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x2B, "application/x-x968-ca-cert");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x2C, "application/x-x968-user-cert");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x2D, "text/vnd.wap.si");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x2E, "application/vnd.wap.sic");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x2F, "text/vnd.wap.sl");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x30, "application/vnd.wap.slc");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x31, "text/vnd.wap.co");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x32, "application/vnd.wap.coc");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x33, "application/vnd.wap.multipart.related");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x34, "application/vnd.wap.sia");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x35, "text/vnd.wap.connectivity-xml");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x36, "application/vnd.wap.connectivity-wbxml");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x37, "application/pkcs7-mime");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x38, "application/vnd.wap.hashed-certificate");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x39, "application/vnd.wap.signed-certificate");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x3A, "application/vnd.wap.cert-response");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x3B, "application/xhtml+xml");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x3C, "application/wml+xml");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x3D, "text/css");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x3E, "application/vnd.wap.mms-message");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x3F, "application/vnd.wap.rollover-certificate");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x40, "application/vnd.wap.locc+wbxml");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x41, "application/vnd.wap.loc+xml");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x42, "application/vnd.syncml.dm+wbxml");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x43, "application/vnd.syncml.dm+xml");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x44, "application/vnd.syncml.notification");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x45, "application/vnd.wap.xhtml+xml");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x46, "application/vnd.wv.csp.cir");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x47, "application/vnd.oma.dd+xml");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x48, "application/vnd.oma.drm.message");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x49, "application/vnd.oma.drm.content");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x4A, "application/vnd.oma.drm.rights+xml");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x4B, "application/vnd.oma.drm.rights+wbxml");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x4C, "application/vnd.wv.csp+xml");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x4D, "application/vnd.wv.csp+wbxml");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x4E, "application/vnd.syncml.ds.notification");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x4F, "audio/*");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x50, "video/*");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x51, "application/vnd.oma.dd2+xml");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x52, "application/mikey");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x53, "application/vnd.oma.dcd");
-        WELL_KNOWN_SHORT_MIME_TYPES.put(0x54, "application/vnd.oma.dcdc");
-
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0201, "application/vnd.uplanet.cacheop-wbxml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0202, "application/vnd.uplanet.signal");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0203, "application/vnd.uplanet.alert-wbxml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0204, "application/vnd.uplanet.list-wbxml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0205, "application/vnd.uplanet.listcmd-wbxml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0206, "application/vnd.uplanet.channel-wbxml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0207, "application/vnd.uplanet.provisioning-status-uri");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0208, "x-wap.multipart/vnd.uplanet.header-set");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0209, "application/vnd.uplanet.bearer-choice-wbxml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x020A, "application/vnd.phonecom.mmc-wbxml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x020B, "application/vnd.nokia.syncset+wbxml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x020C, "image/x-up-wpng");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0300, "application/iota.mmc-wbxml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0301, "application/iota.mmc-xml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0302, "application/vnd.syncml+xml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0303, "application/vnd.syncml+wbxml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0304, "text/vnd.wap.emn+xml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0305, "text/calendar");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0306, "application/vnd.omads-email+xml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0307, "application/vnd.omads-file+xml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0308, "application/vnd.omads-folder+xml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0309, "text/directory;profile=vCard");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x030A, "application/vnd.wap.emn+wbxml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x030B, "application/vnd.nokia.ipdc-purchase-response");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x030C, "application/vnd.motorola.screen3+xml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x030D, "application/vnd.motorola.screen3+gzip");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x030E, "application/vnd.cmcc.setting+wbxml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x030F, "application/vnd.cmcc.bombing+wbxml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0310, "application/vnd.docomo.pf");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0311, "application/vnd.docomo.ub");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0312, "application/vnd.omaloc-supl-init");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0313, "application/vnd.oma.group-usage-list+xml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0314, "application/oma-directory+xml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0315, "application/vnd.docomo.pf2");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0316, "application/vnd.oma.drm.roap-trigger+wbxml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0317, "application/vnd.sbm.mid2");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0318, "application/vnd.wmf.bootstrap");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x0319, "application/vnc.cmcc.dcd+xml");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x031A, "application/vnd.sbm.cid");
-        WELL_KNOWN_LONG_MIME_TYPES.put(0x031B, "application/vnd.oma.bcast.provisioningtrigger");
-
-        WELL_KNOWN_PARAMETERS.put(0x00, "Q");
-        WELL_KNOWN_PARAMETERS.put(0x01, "Charset");
-        WELL_KNOWN_PARAMETERS.put(0x02, "Level");
-        WELL_KNOWN_PARAMETERS.put(0x03, "Type");
-        WELL_KNOWN_PARAMETERS.put(0x07, "Differences");
-        WELL_KNOWN_PARAMETERS.put(0x08, "Padding");
-        WELL_KNOWN_PARAMETERS.put(0x09, "Type");
-        WELL_KNOWN_PARAMETERS.put(0x0E, "Max-Age");
-        WELL_KNOWN_PARAMETERS.put(0x10, "Secure");
-        WELL_KNOWN_PARAMETERS.put(0x11, "SEC");
-        WELL_KNOWN_PARAMETERS.put(0x12, "MAC");
-        WELL_KNOWN_PARAMETERS.put(0x13, "Creation-date");
-        WELL_KNOWN_PARAMETERS.put(0x14, "Modification-date");
-        WELL_KNOWN_PARAMETERS.put(0x15, "Read-date");
-        WELL_KNOWN_PARAMETERS.put(0x16, "Size");
-        WELL_KNOWN_PARAMETERS.put(0x17, "Name");
-        WELL_KNOWN_PARAMETERS.put(0x18, "Filename");
-        WELL_KNOWN_PARAMETERS.put(0x19, "Start");
-        WELL_KNOWN_PARAMETERS.put(0x1A, "Start-info");
-        WELL_KNOWN_PARAMETERS.put(0x1B, "Comment");
-        WELL_KNOWN_PARAMETERS.put(0x1C, "Domain");
-        WELL_KNOWN_PARAMETERS.put(0x1D, "Path");
-
-    }
-
-    final int WSP_DEFINED_SHORT_MIME_TYPE_COUNT = 85;
-    final int WSP_DEFINED_LONG_MIME_TYPE_COUNT = 85;
-
-    private static final byte WSP_STRING_TERMINATOR = 0x00;
-    private static final byte WSP_SHORT_INTEGER_MASK = (byte) 0x80;
-    private static final byte WSP_LENGTH_QUOTE = 0x1F;
-    private static final byte WSP_QUOTE = 0x22;
-
-    private static final short LONG_MIME_TYPE_OMA_DIRECTORY_XML = 0x0314;
-    private static final short LONG_MIME_TYPE_UNASSIGNED = 0x052C;
-
-    private static final byte SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE = 0x3F;
-    private static final byte SHORT_MIME_TYPE_UNASSIGNED = 0x60;
-
-    private static final String STRING_MIME_TYPE_ROLLOVER_CERTIFICATE
-            = "application/vnd.wap.rollover-certificate";
-
-    private static final byte TYPED_PARAM_Q = 0x00;
-    private static final byte TYPED_PARAM_DOMAIN = 0x1C;
-    private static final byte PARAM_UNASSIGNED = 0x42;
-    private static final byte PARAM_NO_VALUE = 0x00;
-    private static final byte TYPED_PARAM_SEC = 0x11;
-    private static final byte TYPED_PARAM_MAC = 0x12;
-
-    public void testHasExpectedNumberOfShortMimeTypes() {
-        assertEquals(WSP_DEFINED_SHORT_MIME_TYPE_COUNT, WELL_KNOWN_SHORT_MIME_TYPES.size());
-    }
-
-    public void testHasExpectedNumberOfLongMimeTypes() {
-        assertEquals(WSP_DEFINED_LONG_MIME_TYPE_COUNT, WELL_KNOWN_LONG_MIME_TYPES.size());
-    }
-
-    public void testWellKnownShortIntegerMimeTypeValues() {
-
-        for (int value : Wap230WspContentTypeTest.WELL_KNOWN_SHORT_MIME_TYPES.keySet()) {
-            WspTypeDecoder unit = new WspTypeDecoder(
-                    HexDump.toByteArray((byte) (value | WSP_SHORT_INTEGER_MASK)));
-            assertTrue(unit.decodeContentType(0));
-            String mimeType = unit.getValueString();
-            int wellKnownValue = (int) unit.getValue32();
-            assertEquals(Wap230WspContentTypeTest.WELL_KNOWN_SHORT_MIME_TYPES.get(value), mimeType);
-            assertEquals(value, wellKnownValue);
-            assertEquals(1, unit.getDecodedDataLength());
-        }
-    }
-
-    public void testWellKnownLongIntegerMimeTypeValues() {
-        byte headerLength = 3;
-        byte typeLength = 2;
-        for (int value : Wap230WspContentTypeTest.WELL_KNOWN_SHORT_MIME_TYPES.keySet()) {
-            byte[] data = new byte[10];
-            data[0] = headerLength;
-            data[1] = typeLength;
-            data[2] = (byte) (value >> 8);
-            data[3] = (byte) (value & 0xFF);
-            WspTypeDecoder unit = new WspTypeDecoder(data);
-            assertTrue(unit.decodeContentType(0));
-            String mimeType = unit.getValueString();
-            int wellKnownValue = (int) unit.getValue32();
-            assertEquals(Wap230WspContentTypeTest.WELL_KNOWN_SHORT_MIME_TYPES.get(value), mimeType);
-            assertEquals(value, wellKnownValue);
-            assertEquals(4, unit.getDecodedDataLength());
-        }
-    }
-
-    public void testDecodeReturnsFalse_WhenOnlyAZeroBytePresent() {
-
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write(0x00);
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertFalse(unit.decodeContentType(0));
-    }
-
-    public void testConstrainedMediaExtensionMedia() throws Exception {
-
-        String testType = "application/wibble";
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write(testType.getBytes("US-ASCII"));
-        out.write(WSP_STRING_TERMINATOR);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-        String mimeType = unit.getValueString();
-        assertEquals(testType, mimeType);
-        assertEquals(-1, unit.getValue32());
-        assertEquals(19, unit.getDecodedDataLength());
-    }
-
-    public void testGeneralFormShortLengthExtensionMedia() throws Exception {
-
-        String testType = "12345678901234567890123456789";
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write(testType.length() + 1);
-        out.write(testType.getBytes("US-ASCII"));
-        out.write(WSP_STRING_TERMINATOR);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-
-        String mimeType = unit.getValueString();
-        assertEquals(testType, mimeType);
-        assertEquals(-1, unit.getValue32());
-        assertEquals(31, unit.getDecodedDataLength());
-    }
-
-    public void testGeneralFormShortLengthWellKnownShortInteger()  {
-
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write(0x01);
-        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-
-        String mimeType = unit.getValueString();
-        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
-        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
-        assertEquals(2, unit.getDecodedDataLength());
-
-    }
-
-    public void testGeneralFormShortLengthWellKnownShortIntegerWithUnknownValue()  {
-
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write(0x01);
-        out.write(SHORT_MIME_TYPE_UNASSIGNED | WSP_SHORT_INTEGER_MASK);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-
-        String mimeType = unit.getValueString();
-        assertNull(mimeType);
-        assertEquals(SHORT_MIME_TYPE_UNASSIGNED, unit.getValue32());
-        assertEquals(2, unit.getDecodedDataLength());
-
-    }
-
-    public void testGeneralFormShortLengthWellKnownLongInteger()  {
-
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-
-        out.write(0x03); // header length
-        out.write(0x02); // type length (2 octets)
-        out.write(LONG_MIME_TYPE_OMA_DIRECTORY_XML >> 8);
-        out.write(LONG_MIME_TYPE_OMA_DIRECTORY_XML & 0xFF);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-
-        String mimeType = unit.getValueString();
-
-        assertEquals("application/oma-directory+xml", mimeType);
-        assertEquals(LONG_MIME_TYPE_OMA_DIRECTORY_XML, unit.getValue32());
-        assertEquals(4, unit.getDecodedDataLength());
-    }
-
-    public void testGeneralFormShortLengthWellKnownLongIntegerWithUnknownValue()  {
-
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-
-        out.write(0x03); // Value-length, short-length
-        out.write(0x02); // long-integer length (2 octets)
-        out.write(LONG_MIME_TYPE_UNASSIGNED >> 8);
-        out.write(LONG_MIME_TYPE_UNASSIGNED & 0xFF);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-
-        String mimeType = unit.getValueString();
-
-        assertNull(mimeType);
-        assertEquals(LONG_MIME_TYPE_UNASSIGNED, unit.getValue32());
-        assertEquals(4, unit.getDecodedDataLength());
-
-    }
-
-    public void testGeneralFormLengthQuoteWellKnownShortInteger()  {
-
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-
-        out.write(WSP_LENGTH_QUOTE);
-        out.write(0x01); // Length as UINTVAR
-        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-
-        String mimeType = unit.getValueString();
-        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
-        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
-        assertEquals(3, unit.getDecodedDataLength());
-
-    }
-
-    public void testGeneralFormLengthQuoteWellKnownShortIntegerWithUnknownValue()  {
-
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-
-        out.write(WSP_LENGTH_QUOTE);
-        out.write(0x01); // Length as UINTVAR
-        out.write(SHORT_MIME_TYPE_UNASSIGNED | WSP_SHORT_INTEGER_MASK);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-
-        String mimeType = unit.getValueString();
-        assertNull(mimeType);
-        assertEquals(SHORT_MIME_TYPE_UNASSIGNED, unit.getValue32());
-        assertEquals(3, unit.getDecodedDataLength());
-    }
-
-    public void testGeneralFormLengthQuoteWellKnownLongInteger()  {
-
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-
-        out.write(WSP_LENGTH_QUOTE);
-        out.write(0x03); // Length as UINTVAR
-        out.write(0x02); // long-integer length (2 octets)
-        out.write(LONG_MIME_TYPE_OMA_DIRECTORY_XML >> 8);
-        out.write(LONG_MIME_TYPE_OMA_DIRECTORY_XML & 0xFF);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-
-        String mimeType = unit.getValueString();
-
-        assertEquals("application/oma-directory+xml", mimeType);
-        assertEquals(LONG_MIME_TYPE_OMA_DIRECTORY_XML, unit.getValue32());
-        assertEquals(5, unit.getDecodedDataLength());
-
-    }
-
-    public void testGeneralFormLengthQuoteWellKnownLongIntegerWithUnknownValue()  {
-
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-
-        out.write(WSP_LENGTH_QUOTE);
-        out.write(0x03); // Length as UINTVAR
-        out.write(0x02); // long-integer length (2 octets)
-        out.write(LONG_MIME_TYPE_UNASSIGNED >> 8);
-        out.write(LONG_MIME_TYPE_UNASSIGNED & 0xFF);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-
-        String mimeType = unit.getValueString();
-
-        assertNull(mimeType);
-        assertEquals(LONG_MIME_TYPE_UNASSIGNED, unit.getValue32());
-        assertEquals(5, unit.getDecodedDataLength());
-
-    }
-
-    public void testGeneralFormLengthQuoteExtensionMedia() throws Exception {
-
-        String testType = "application/wibble";
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-
-        out.write(WSP_LENGTH_QUOTE);
-        out.write(testType.length() + 1); // Length as UINTVAR
-
-        out.write(testType.getBytes("US-ASCII"));
-        out.write(WSP_STRING_TERMINATOR);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-
-        String mimeType = unit.getValueString();
-
-        assertEquals(testType, mimeType);
-        assertEquals(-1, unit.getValue32());
-        assertEquals(21, unit.getDecodedDataLength());
-
-    }
-
-    public void testGeneralFormLengthQuoteExtensionMediaWithNiceLongMimeType() throws Exception {
-
-        String testType =
-                "01234567890123456789012345678901234567890123456789012345678901234567890123456789"
-                +"01234567890123456789012345678901234567890123456789012345678901234567890123456789";
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-
-        out.write(WSP_LENGTH_QUOTE);
-        out.write(0x81); // Length as UINTVAR (161 decimal, 0xA1), 2 bytes
-        out.write(0x21);
-
-        out.write(testType.getBytes("US-ASCII"));
-        out.write(WSP_STRING_TERMINATOR);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-
-        String mimeType = unit.getValueString();
-
-        assertEquals(testType, mimeType);
-        assertEquals(-1, unit.getValue32());
-        assertEquals(164, unit.getDecodedDataLength());
-
-    }
-
-    public void testConstrainedMediaExtensionMediaWithSpace() throws Exception {
-
-        String testType = " application/wibble";
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write(testType.getBytes("US-ASCII"));
-        out.write(WSP_STRING_TERMINATOR);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-
-        String mimeType = unit.getValueString();
-
-        assertEquals(testType, mimeType);
-        assertEquals(-1, unit.getValue32());
-        assertEquals(20, unit.getDecodedDataLength());
-
-    }
-
-    public void testTypedParamWellKnownShortIntegerNoValue()  {
-
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write(0x03); // Value-length, short-length
-        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
-        out.write(TYPED_PARAM_DOMAIN | WSP_SHORT_INTEGER_MASK);
-        out.write(PARAM_NO_VALUE);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-
-        String mimeType = unit.getValueString();
-
-        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
-        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
-
-        assertEquals(4, unit.getDecodedDataLength());
-
-        Map<String, String> params = unit.getContentParameters();
-        assertEquals(null, params.get("Domain"));
-
-    }
-
-    public void testTypedParamWellKnownShortIntegerTokenText() throws Exception {
-
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write(0x14); // Value-length, short-length
-        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
-        out.write(TYPED_PARAM_DOMAIN | WSP_SHORT_INTEGER_MASK);
-        out.write("wdstechnology.com".getBytes("US-ASCII"));
-        out.write(WSP_STRING_TERMINATOR);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-
-        String mimeType = unit.getValueString();
-
-        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
-        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
-
-        assertEquals(out.toByteArray().length, unit.getDecodedDataLength());
-
-        Map<String, String> params = unit.getContentParameters();
-        assertEquals("wdstechnology.com", params.get("Domain"));
-
-    }
-
-    public void testTypedParamWellKnownLongIntegerTokenText() throws Exception {
-
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write(0x15);
-        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
-        out.write(0x01);
-        out.write(TYPED_PARAM_DOMAIN);
-        out.write("wdstechnology.com".getBytes("US-ASCII"));
-        out.write(WSP_STRING_TERMINATOR);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-
-        String mimeType = unit.getValueString();
-
-        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
-        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
-
-        assertEquals(22, unit.getDecodedDataLength());
-
-        Map<String, String> params = unit.getContentParameters();
-        assertEquals("wdstechnology.com", params.get("Domain"));
-
-    }
-
-    public void testTypedParamWellKnownShortIntegerQuotedText() throws Exception {
-
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write(0x15);
-        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
-        out.write(TYPED_PARAM_DOMAIN | WSP_SHORT_INTEGER_MASK);
-        out.write(WSP_QUOTE);
-        out.write("wdstechnology.com".getBytes("US-ASCII"));
-        out.write(WSP_STRING_TERMINATOR);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-
-        String mimeType = unit.getValueString();
-
-        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
-        assertEquals(0x3F, unit.getValue32());
-        assertEquals(22, unit.getDecodedDataLength());
-
-        Map<String, String> params = unit.getContentParameters();
-        assertEquals("wdstechnology.com", params.get("Domain"));
-
-    }
-
-    public void testTypedParamWellKnownShortIntegerCompactIntegerValue()  {
-
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write(0x3);
-        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
-        out.write(TYPED_PARAM_SEC | WSP_SHORT_INTEGER_MASK);
-        out.write(0x01 | WSP_SHORT_INTEGER_MASK);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-
-        String mimeType = unit.getValueString();
-
-        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
-        assertEquals(0x3F, unit.getValue32());
-        assertEquals(4, unit.getDecodedDataLength());
-
-        Map<String, String> params = unit.getContentParameters();
-        assertEquals("1", params.get("SEC"));
-
-    }
-
-    public void testTypedParamWellKnownShortIntegerMultipleParameters() throws Exception {
-
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write(0x0B);
-        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
-        out.write(TYPED_PARAM_SEC | WSP_SHORT_INTEGER_MASK);
-        out.write(0x01 | WSP_SHORT_INTEGER_MASK);
-        out.write(TYPED_PARAM_MAC | WSP_SHORT_INTEGER_MASK);
-        out.write(WSP_QUOTE);
-        out.write("imapc".getBytes("US-ASCII"));
-        out.write(WSP_STRING_TERMINATOR);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-
-        String mimeType = unit.getValueString();
-
-        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
-        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
-        assertEquals(12, unit.getDecodedDataLength());
-
-        Map<String, String> params = unit.getContentParameters();
-        assertEquals("1", params.get("SEC"));
-        assertEquals("imapc", params.get("MAC"));
-    }
-
-    public void testUntypedParamIntegerValueShortInteger() throws Exception {
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write(0x0A);
-        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
-        out.write("MYPARAM".getBytes("US-ASCII"));
-        out.write(WSP_STRING_TERMINATOR); // EOS
-        out.write(0x45 | WSP_SHORT_INTEGER_MASK);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-
-        String mimeType = unit.getValueString();
-
-        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
-        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
-        assertEquals(11, unit.getDecodedDataLength());
-
-        Map<String, String> params = unit.getContentParameters();
-        assertEquals("69", params.get("MYPARAM"));
-    }
-
-    public void testUntypedParamIntegerValueLongInteger() throws Exception {
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write(0x0C);
-        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
-        out.write("MYPARAM".getBytes("US-ASCII"));
-        out.write(WSP_STRING_TERMINATOR);
-        out.write(0x02); // Short Length
-        out.write(0x42); // Long Integer byte 1
-        out.write(0x69); // Long Integer byte 2
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-
-        String mimeType = unit.getValueString();
-
-        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
-        assertEquals(0x3F, unit.getValue32());
-        assertEquals(13, unit.getDecodedDataLength());
-
-        Map<String, String> params = unit.getContentParameters();
-        assertEquals("17001", params.get("MYPARAM"));
-    }
-
-    public void testUntypedParamTextNoValue() throws Exception {
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write(0x0A);
-        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
-        out.write("MYPARAM".getBytes("US-ASCII"));
-        out.write(WSP_STRING_TERMINATOR);
-        out.write(PARAM_NO_VALUE);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-        String mimeType = unit.getValueString();
-
-        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
-        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
-        assertEquals(11, unit.getDecodedDataLength());
-
-        Map<String, String> params = unit.getContentParameters();
-        assertEquals(null, params.get("MYPARAM"));
-
-    }
-
-    public void testUntypedParamTextTokenText() throws Exception {
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write(0x11);
-        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
-        out.write("MYPARAM".getBytes("US-ASCII"));
-        out.write(WSP_STRING_TERMINATOR);
-        out.write("myvalue".getBytes("US-ASCII"));
-        out.write(WSP_STRING_TERMINATOR);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-        String mimeType = unit.getValueString();
-
-        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
-        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
-        assertEquals(18, unit.getDecodedDataLength());
-
-        Map<String, String> params = unit.getContentParameters();
-        assertEquals("myvalue", params.get("MYPARAM"));
-    }
-
-    public void testUntypedParamTextQuotedString() throws Exception {
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write(0x11);
-        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
-        out.write("MYPARAM".getBytes("US-ASCII"));
-        out.write(WSP_STRING_TERMINATOR);
-        out.write(WSP_QUOTE);
-        out.write("myvalue".getBytes("US-ASCII"));
-        out.write(WSP_STRING_TERMINATOR);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-        String mimeType = unit.getValueString();
-
-        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
-        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
-        assertEquals(19, unit.getDecodedDataLength());
-
-        Map<String, String> params = unit.getContentParameters();
-        assertEquals("myvalue", params.get("MYPARAM"));
-
-    }
-
-    public void testDecodesReturnsFalse_ForParamWithMissingValue() throws Exception {
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write(0x09);
-        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
-        out.write("MYPARAM".getBytes("US-ASCII"));
-        out.write(WSP_STRING_TERMINATOR);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertFalse(unit.decodeContentType(0));
-    }
-
-    public void testTypedParamTextQValue()  {
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write(0x04);
-        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
-        out.write(TYPED_PARAM_Q);
-        out.write(0x83); // Q value byte 1
-        out.write(0x31); // Q value byte 2
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-        String mimeType = unit.getValueString();
-
-        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
-        assertEquals(0x3F, unit.getValue32());
-        assertEquals(5, unit.getDecodedDataLength());
-
-        Map<String, String> params = unit.getContentParameters();
-        assertEquals("433", params.get("Q"));
-
-    }
-
-    public void testTypedParamUnassignedWellKnownShortIntegerTokenText() throws Exception {
-
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write(0x14);
-        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
-        out.write(PARAM_UNASSIGNED | WSP_SHORT_INTEGER_MASK);
-        out.write("wdstechnology.com".getBytes("US-ASCII"));
-        out.write(WSP_STRING_TERMINATOR);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-
-        String mimeType = unit.getValueString();
-
-        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
-        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
-
-        assertEquals(21, unit.getDecodedDataLength());
-
-        Map<String, String> params = unit.getContentParameters();
-        assertEquals("wdstechnology.com", params.get("unassigned/0x42"));
-
-    }
-
-    public void testTypedParamUnassignedWellKnownLongIntegerTokenText() throws Exception {
-
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write(0x15);
-        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
-        out.write(0x01); // Short-length of well-known parameter token
-        out.write(PARAM_UNASSIGNED);
-        out.write("wdstechnology.com".getBytes("US-ASCII"));
-        out.write(WSP_STRING_TERMINATOR);
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertTrue(unit.decodeContentType(0));
-
-        String mimeType = unit.getValueString();
-
-        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
-        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
-
-        assertEquals(22, unit.getDecodedDataLength());
-
-        Map<String, String> params = unit.getContentParameters();
-        assertEquals("wdstechnology.com", params.get("unassigned/0x42"));
-    }
-
-    public void testDecodesReturnsFalse_WhenParamValueNotTerminated() throws Exception {
-
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write(0x15);
-        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
-        out.write(0x01);
-        out.write(PARAM_UNASSIGNED);
-        out.write("wdstechnology.com".getBytes("US-ASCII"));
-
-        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
-        assertFalse(unit.decodeContentType(0));
-    }
-}
\ No newline at end of file
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java
deleted file mode 100644
index a95f60c..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java
+++ /dev/null
@@ -1,746 +0,0 @@
-/*
- * Copyright (C) 2012 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.internal.telephony.cdma;
-
-import android.os.Parcel;
-import android.telephony.SmsCbCmasInfo;
-import android.telephony.SmsCbMessage;
-import android.telephony.cdma.CdmaSmsCbProgramData;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.cdma.sms.BearerData;
-import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
-import com.android.internal.telephony.cdma.sms.SmsEnvelope;
-import com.android.internal.telephony.cdma.sms.UserData;
-import com.android.internal.util.BitwiseOutputStream;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Random;
-
-/**
- * Test cases for basic SmsCbMessage operation for CDMA.
- */
-public class CdmaSmsCbTest extends AndroidTestCase {
-
-    /* Copy of private subparameter identifier constants from BearerData class. */
-    private static final byte SUBPARAM_MESSAGE_IDENTIFIER   = (byte) 0x00;
-    private static final byte SUBPARAM_USER_DATA            = (byte) 0x01;
-    private static final byte SUBPARAM_PRIORITY_INDICATOR   = (byte) 0x08;
-    private static final byte SUBPARAM_LANGUAGE_INDICATOR   = (byte) 0x0D;
-    private static final byte SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA    = 0x12;
-
-    /**
-     * Initialize a Parcel for an incoming CDMA cell broadcast. The caller will write the
-     * bearer data and then convert it to an SmsMessage.
-     * @param serviceCategory the CDMA service category
-     * @return the initialized Parcel
-     */
-    private static Parcel createBroadcastParcel(int serviceCategory) {
-        Parcel p = Parcel.obtain();
-
-        p.writeInt(SmsEnvelope.TELESERVICE_NOT_SET);
-        p.writeByte((byte) 1);  // non-zero for MESSAGE_TYPE_BROADCAST
-        p.writeInt(serviceCategory);
-
-        // dummy address (RIL may generate a different dummy address for broadcasts)
-        p.writeInt(CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF);            // sAddress.digit_mode
-        p.writeInt(CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK);    // sAddress.number_mode
-        p.writeInt(CdmaSmsAddress.TON_UNKNOWN);                     // sAddress.number_type
-        p.writeInt(CdmaSmsAddress.NUMBERING_PLAN_ISDN_TELEPHONY);   // sAddress.number_plan
-        p.writeByte((byte) 0);      // sAddress.number_of_digits
-        p.writeInt((byte) 0);       // sSubAddress.subaddressType
-        p.writeByte((byte) 0);      // sSubAddress.odd
-        p.writeByte((byte) 0);      // sSubAddress.number_of_digits
-        return p;
-    }
-
-    /**
-     * Initialize a BitwiseOutputStream with the CDMA bearer data subparameters except for
-     * user data. The caller will append the user data and add it to the parcel.
-     * @param messageId the 16-bit message identifier
-     * @param priority message priority
-     * @param language message language code
-     * @return the initialized BitwiseOutputStream
-     */
-    private static BitwiseOutputStream createBearerDataStream(int messageId, int priority,
-            int language) throws BitwiseOutputStream.AccessException {
-        BitwiseOutputStream bos = new BitwiseOutputStream(10);
-        bos.write(8, SUBPARAM_MESSAGE_IDENTIFIER);
-        bos.write(8, 3);    // length: 3 bytes
-        bos.write(4, BearerData.MESSAGE_TYPE_DELIVER);
-        bos.write(8, ((messageId >>> 8) & 0xff));
-        bos.write(8, (messageId & 0xff));
-        bos.write(1, 0);    // no User Data Header
-        bos.write(3, 0);    // reserved
-
-        if (priority != -1) {
-            bos.write(8, SUBPARAM_PRIORITY_INDICATOR);
-            bos.write(8, 1);    // length: 1 byte
-            bos.write(2, (priority & 0x03));
-            bos.write(6, 0);    // reserved
-        }
-
-        if (language != -1) {
-            bos.write(8, SUBPARAM_LANGUAGE_INDICATOR);
-            bos.write(8, 1);    // length: 1 byte
-            bos.write(8, (language & 0xff));
-        }
-
-        return bos;
-    }
-
-    /**
-     * Write the bearer data array to the parcel, then return a new SmsMessage from the parcel.
-     * @param p the parcel containing the CDMA SMS headers
-     * @param bearerData the bearer data byte array to append to the parcel
-     * @return the new SmsMessage created from the parcel
-     */
-    private static SmsMessage createMessageFromParcel(Parcel p, byte[] bearerData) {
-        p.writeInt(bearerData.length);
-        for (byte b : bearerData) {
-            p.writeByte(b);
-        }
-        p.setDataPosition(0);   // reset position for reading
-        SmsMessage message = SmsMessage.newFromParcel(p);
-        p.recycle();
-        return message;
-    }
-
-    /**
-     * Create a parcel for an incoming CMAS broadcast, then return a new SmsMessage created
-     * from the parcel.
-     * @param serviceCategory the CDMA service category
-     * @param messageId the 16-bit message identifier
-     * @param priority message priority
-     * @param language message language code
-     * @param body message body
-     * @param cmasCategory CMAS category (or -1 to skip adding CMAS type 1 elements record)
-     * @param responseType CMAS response type
-     * @param severity CMAS severity
-     * @param urgency CMAS urgency
-     * @param certainty CMAS certainty
-     * @return the newly created SmsMessage object
-     */
-    private static SmsMessage createCmasSmsMessage(int serviceCategory, int messageId, int priority,
-            int language, int encoding, String body, int cmasCategory, int responseType,
-            int severity, int urgency, int certainty) throws Exception {
-        BitwiseOutputStream cmasBos = new BitwiseOutputStream(10);
-        cmasBos.write(8, 0);    // CMAE protocol version 0
-
-        if (body != null) {
-            cmasBos.write(8, 0);        // Type 0 elements (alert text)
-            encodeBody(encoding, body, true, cmasBos);
-        }
-
-        if (cmasCategory != SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN) {
-            cmasBos.write(8, 1);    // Type 1 elements
-            cmasBos.write(8, 4);    // length: 4 bytes
-            cmasBos.write(8, (cmasCategory & 0xff));
-            cmasBos.write(8, (responseType & 0xff));
-            cmasBos.write(4, (severity & 0x0f));
-            cmasBos.write(4, (urgency & 0x0f));
-            cmasBos.write(4, (certainty & 0x0f));
-            cmasBos.write(4, 0);    // pad to octet boundary
-        }
-
-        byte[] cmasUserData = cmasBos.toByteArray();
-
-        Parcel p = createBroadcastParcel(serviceCategory);
-        BitwiseOutputStream bos = createBearerDataStream(messageId, priority, language);
-
-        bos.write(8, SUBPARAM_USER_DATA);
-        bos.write(8, cmasUserData.length + 2);  // add 2 bytes for msg_encoding and num_fields
-        bos.write(5, UserData.ENCODING_OCTET);
-        bos.write(8, cmasUserData.length);
-        bos.writeByteArray(cmasUserData.length * 8, cmasUserData);
-        bos.write(3, 0);    // pad to byte boundary
-
-        return createMessageFromParcel(p, bos.toByteArray());
-    }
-
-    /**
-     * Create a parcel for an incoming CDMA cell broadcast, then return a new SmsMessage created
-     * from the parcel.
-     * @param serviceCategory the CDMA service category
-     * @param messageId the 16-bit message identifier
-     * @param priority message priority
-     * @param language message language code
-     * @param encoding user data encoding method
-     * @param body the message body
-     * @return the newly created SmsMessage object
-     */
-    private static SmsMessage createBroadcastSmsMessage(int serviceCategory, int messageId,
-            int priority, int language, int encoding, String body) throws Exception {
-        Parcel p = createBroadcastParcel(serviceCategory);
-        BitwiseOutputStream bos = createBearerDataStream(messageId, priority, language);
-
-        bos.write(8, SUBPARAM_USER_DATA);
-        encodeBody(encoding, body, false, bos);
-
-        return createMessageFromParcel(p, bos.toByteArray());
-    }
-
-    /**
-     * Append the message length, encoding, and body to the BearerData output stream.
-     * This is used for writing the User Data subparameter for non-CMAS broadcasts and for
-     * writing the alert text for CMAS broadcasts.
-     * @param encoding one of the CDMA UserData encoding values
-     * @param body the message body
-     * @param isCmasRecord true if this is a CMAS type 0 elements record; false for user data
-     * @param bos the BitwiseOutputStream to write to
-     * @throws Exception on any encoding error
-     */
-    private static void encodeBody(int encoding, String body, boolean isCmasRecord,
-            BitwiseOutputStream bos) throws Exception {
-        if (encoding == UserData.ENCODING_7BIT_ASCII || encoding == UserData.ENCODING_IA5) {
-            int charCount = body.length();
-            int recordBits = (charCount * 7) + 5;       // add 5 bits for char set field
-            int recordOctets = (recordBits + 7) / 8;    // round up to octet boundary
-            int padBits = (recordOctets * 8) - recordBits;
-
-            if (!isCmasRecord) {
-                recordOctets++;                         // add 8 bits for num_fields
-            }
-
-            bos.write(8, recordOctets);
-            bos.write(5, (encoding & 0x1f));
-
-            if (!isCmasRecord) {
-                bos.write(8, charCount);
-            }
-
-            for (int i = 0; i < charCount; i++) {
-                bos.write(7, body.charAt(i));
-            }
-
-            bos.write(padBits, 0);      // pad to octet boundary
-        } else if (encoding == UserData.ENCODING_GSM_7BIT_ALPHABET
-                || encoding == UserData.ENCODING_GSM_DCS) {
-            // convert to 7-bit packed encoding with septet count in index 0 of byte array
-            byte[] encodedBody = GsmAlphabet.stringToGsm7BitPacked(body);
-
-            int charCount = encodedBody[0];             // septet count
-            int recordBits = (charCount * 7) + 5;       // add 5 bits for char set field
-            int recordOctets = (recordBits + 7) / 8;    // round up to octet boundary
-            int padBits = (recordOctets * 8) - recordBits;
-
-            if (!isCmasRecord) {
-                recordOctets++;                         // add 8 bits for num_fields
-                if (encoding == UserData.ENCODING_GSM_DCS) {
-                    recordOctets++;                     // add 8 bits for DCS (message type)
-                }
-            }
-
-            bos.write(8, recordOctets);
-            bos.write(5, (encoding & 0x1f));
-
-            if (!isCmasRecord && encoding == UserData.ENCODING_GSM_DCS) {
-                bos.write(8, 0);        // GSM DCS: 7 bit default alphabet, no msg class
-            }
-
-            if (!isCmasRecord) {
-                bos.write(8, charCount);
-            }
-            byte[] bodySeptets = Arrays.copyOfRange(encodedBody, 1, encodedBody.length);
-            bos.writeByteArray(charCount * 7, bodySeptets);
-            bos.write(padBits, 0);      // pad to octet boundary
-        } else if (encoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) {
-            // 6 bit packed encoding with 0x20 offset (ASCII 0x20 - 0x60)
-            int charCount = body.length();
-            int recordBits = (charCount * 6) + 21;      // add 21 bits for header fields
-            int recordOctets = (recordBits + 7) / 8;    // round up to octet boundary
-            int padBits = (recordOctets * 8) - recordBits;
-
-            bos.write(8, recordOctets);
-
-            bos.write(5, (encoding & 0x1f));
-            bos.write(8, UserData.IS91_MSG_TYPE_SHORT_MESSAGE);
-            bos.write(8, charCount);
-
-            for (int i = 0; i < charCount; i++) {
-                bos.write(6, ((int) body.charAt(i) - 0x20));
-            }
-
-            bos.write(padBits, 0);      // pad to octet boundary
-        } else {
-            byte[] encodedBody;
-            switch (encoding) {
-                case UserData.ENCODING_UNICODE_16:
-                    encodedBody = body.getBytes("UTF-16BE");
-                    break;
-
-                case UserData.ENCODING_SHIFT_JIS:
-                    encodedBody = body.getBytes("Shift_JIS");
-                    break;
-
-                case UserData.ENCODING_KOREAN:
-                    encodedBody = body.getBytes("KSC5601");
-                    break;
-
-                case UserData.ENCODING_LATIN_HEBREW:
-                    encodedBody = body.getBytes("ISO-8859-8");
-                    break;
-
-                case UserData.ENCODING_LATIN:
-                default:
-                    encodedBody = body.getBytes("ISO-8859-1");
-                    break;
-            }
-            int charCount = body.length();              // use actual char count for num fields
-            int recordOctets = encodedBody.length + 1;  // add 1 byte for encoding and pad bits
-            if (!isCmasRecord) {
-                recordOctets++;                         // add 8 bits for num_fields
-            }
-            bos.write(8, recordOctets);
-            bos.write(5, (encoding & 0x1f));
-            if (!isCmasRecord) {
-                bos.write(8, charCount);
-            }
-            bos.writeByteArray(encodedBody.length * 8, encodedBody);
-            bos.write(3, 0);            // pad to octet boundary
-        }
-    }
-
-    private static final String TEST_TEXT = "This is a test CDMA cell broadcast message..."
-            + "678901234567890123456789012345678901234567890";
-
-    private static final String PRES_ALERT =
-            "THE PRESIDENT HAS ISSUED AN EMERGENCY ALERT. CHECK LOCAL MEDIA FOR MORE DETAILS";
-
-    private static final String EXTREME_ALERT = "FLASH FLOOD WARNING FOR SOUTH COCONINO COUNTY"
-            + " - NORTH CENTRAL ARIZONA UNTIL 415 PM MST";
-
-    private static final String SEVERE_ALERT = "SEVERE WEATHER WARNING FOR SOMERSET COUNTY"
-            + " - NEW JERSEY UNTIL 415 PM MST";
-
-    private static final String AMBER_ALERT =
-            "AMBER ALERT:Mountain View,CA VEH'07 Blue Honda Civic CA LIC 5ABC123";
-
-    private static final String MONTHLY_TEST_ALERT = "This is a test of the emergency alert system."
-            + " This is only a test. 89012345678901234567890";
-
-    private static final String IS91_TEXT = "IS91 SHORT MSG";   // max length 14 chars
-
-    /**
-     * Verify that the SmsCbMessage has the correct values for CDMA.
-     * @param cbMessage the message to test
-     */
-    private static void verifyCbValues(SmsCbMessage cbMessage) {
-        assertEquals(SmsCbMessage.MESSAGE_FORMAT_3GPP2, cbMessage.getMessageFormat());
-        assertEquals(SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE, cbMessage.getGeographicalScope());
-        assertEquals(false, cbMessage.isEtwsMessage()); // ETWS on CDMA not currently supported
-    }
-
-    private static void doTestNonEmergencyBroadcast(int encoding) throws Exception {
-        SmsMessage msg = createBroadcastSmsMessage(123, 456, BearerData.PRIORITY_NORMAL,
-                BearerData.LANGUAGE_ENGLISH, encoding, TEST_TEXT);
-
-        SmsCbMessage cbMessage = msg.parseBroadcastSms();
-        verifyCbValues(cbMessage);
-        assertEquals(123, cbMessage.getServiceCategory());
-        assertEquals(456, cbMessage.getSerialNumber());
-        assertEquals(SmsCbMessage.MESSAGE_PRIORITY_NORMAL, cbMessage.getMessagePriority());
-        assertEquals("en", cbMessage.getLanguageCode());
-        assertEquals(TEST_TEXT, cbMessage.getMessageBody());
-        assertEquals(false, cbMessage.isEmergencyMessage());
-        assertEquals(false, cbMessage.isCmasMessage());
-    }
-
-    public void testNonEmergencyBroadcast7bitAscii() throws Exception {
-        doTestNonEmergencyBroadcast(UserData.ENCODING_7BIT_ASCII);
-    }
-
-    public void testNonEmergencyBroadcast7bitGsm() throws Exception {
-        doTestNonEmergencyBroadcast(UserData.ENCODING_GSM_7BIT_ALPHABET);
-    }
-
-    public void testNonEmergencyBroadcast16bitUnicode() throws Exception {
-        doTestNonEmergencyBroadcast(UserData.ENCODING_UNICODE_16);
-    }
-
-    public void testNonEmergencyBroadcastIs91Extended() throws Exception {
-        // IS-91 doesn't support language or priority subparameters, max 14 chars text
-        SmsMessage msg = createBroadcastSmsMessage(987, 654, -1, -1,
-                UserData.ENCODING_IS91_EXTENDED_PROTOCOL, IS91_TEXT);
-
-        SmsCbMessage cbMessage = msg.parseBroadcastSms();
-        verifyCbValues(cbMessage);
-        assertEquals(987, cbMessage.getServiceCategory());
-        assertEquals(654, cbMessage.getSerialNumber());
-        assertEquals(SmsCbMessage.MESSAGE_PRIORITY_NORMAL, cbMessage.getMessagePriority());
-        assertEquals(null, cbMessage.getLanguageCode());
-        assertEquals(IS91_TEXT, cbMessage.getMessageBody());
-        assertEquals(false, cbMessage.isEmergencyMessage());
-        assertEquals(false, cbMessage.isCmasMessage());
-    }
-
-    private static void doTestCmasBroadcast(int serviceCategory, int messageClass, String body)
-            throws Exception {
-        SmsMessage msg = createCmasSmsMessage(
-                serviceCategory, 1234, BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH,
-                UserData.ENCODING_7BIT_ASCII, body, -1, -1, -1, -1, -1);
-
-        SmsCbMessage cbMessage = msg.parseBroadcastSms();
-        verifyCbValues(cbMessage);
-        assertEquals(serviceCategory, cbMessage.getServiceCategory());
-        assertEquals(1234, cbMessage.getSerialNumber());
-        assertEquals(SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, cbMessage.getMessagePriority());
-        assertEquals("en", cbMessage.getLanguageCode());
-        assertEquals(body, cbMessage.getMessageBody());
-        assertEquals(true, cbMessage.isEmergencyMessage());
-        assertEquals(true, cbMessage.isCmasMessage());
-        SmsCbCmasInfo cmasInfo = cbMessage.getCmasWarningInfo();
-        assertEquals(messageClass, cmasInfo.getMessageClass());
-        assertEquals(SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN, cmasInfo.getCategory());
-        assertEquals(SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN, cmasInfo.getResponseType());
-        assertEquals(SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN, cmasInfo.getSeverity());
-        assertEquals(SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN, cmasInfo.getUrgency());
-        assertEquals(SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN, cmasInfo.getCertainty());
-    }
-
-    public void testCmasPresidentialAlert() throws Exception {
-        doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT,
-                SmsCbCmasInfo.CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT, PRES_ALERT);
-    }
-
-    public void testCmasExtremeAlert() throws Exception {
-        doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
-                SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT, EXTREME_ALERT);
-    }
-
-    public void testCmasSevereAlert() throws Exception {
-        doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT,
-                SmsCbCmasInfo.CMAS_CLASS_SEVERE_THREAT, SEVERE_ALERT);
-    }
-
-    public void testCmasAmberAlert() throws Exception {
-        doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY,
-                SmsCbCmasInfo.CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY, AMBER_ALERT);
-    }
-
-    public void testCmasTestMessage() throws Exception {
-        doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE,
-                SmsCbCmasInfo.CMAS_CLASS_REQUIRED_MONTHLY_TEST, MONTHLY_TEST_ALERT);
-    }
-
-    public void testCmasExtremeAlertType1Elements() throws Exception {
-        SmsMessage msg = createCmasSmsMessage(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
-                5678, BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH,
-                UserData.ENCODING_7BIT_ASCII, EXTREME_ALERT, SmsCbCmasInfo.CMAS_CATEGORY_ENV,
-                SmsCbCmasInfo.CMAS_RESPONSE_TYPE_MONITOR, SmsCbCmasInfo.CMAS_SEVERITY_SEVERE,
-                SmsCbCmasInfo.CMAS_URGENCY_EXPECTED, SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY);
-
-        SmsCbMessage cbMessage = msg.parseBroadcastSms();
-        verifyCbValues(cbMessage);
-        assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
-                cbMessage.getServiceCategory());
-        assertEquals(5678, cbMessage.getSerialNumber());
-        assertEquals(SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, cbMessage.getMessagePriority());
-        assertEquals("en", cbMessage.getLanguageCode());
-        assertEquals(EXTREME_ALERT, cbMessage.getMessageBody());
-        assertEquals(true, cbMessage.isEmergencyMessage());
-        assertEquals(true, cbMessage.isCmasMessage());
-        SmsCbCmasInfo cmasInfo = cbMessage.getCmasWarningInfo();
-        assertEquals(SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT, cmasInfo.getMessageClass());
-        assertEquals(SmsCbCmasInfo.CMAS_CATEGORY_ENV, cmasInfo.getCategory());
-        assertEquals(SmsCbCmasInfo.CMAS_RESPONSE_TYPE_MONITOR, cmasInfo.getResponseType());
-        assertEquals(SmsCbCmasInfo.CMAS_SEVERITY_SEVERE, cmasInfo.getSeverity());
-        assertEquals(SmsCbCmasInfo.CMAS_URGENCY_EXPECTED, cmasInfo.getUrgency());
-        assertEquals(SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY, cmasInfo.getCertainty());
-    }
-
-    // VZW requirement is to discard message with unsupported charset. Verify that we return null
-    // for this unsupported character set.
-    public void testCmasUnsupportedCharSet() throws Exception {
-        SmsMessage msg = createCmasSmsMessage(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
-                12345, BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH,
-                UserData.ENCODING_GSM_DCS, EXTREME_ALERT, -1, -1, -1, -1, -1);
-
-        SmsCbMessage cbMessage = msg.parseBroadcastSms();
-        assertNull("expected null for unsupported charset", cbMessage);
-    }
-
-    // VZW requirement is to discard message with unsupported charset. Verify that we return null
-    // for this unsupported character set.
-    public void testCmasUnsupportedCharSet2() throws Exception {
-        SmsMessage msg = createCmasSmsMessage(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
-                67890, BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH,
-                UserData.ENCODING_KOREAN, EXTREME_ALERT, -1, -1, -1, -1, -1);
-
-        SmsCbMessage cbMessage = msg.parseBroadcastSms();
-        assertNull("expected null for unsupported charset", cbMessage);
-    }
-
-    // VZW requirement is to discard message without record type 0. The framework will decode it
-    // and the app will discard it.
-    public void testCmasNoRecordType0() throws Exception {
-        SmsMessage msg = createCmasSmsMessage(
-                SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT, 1234,
-                BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH,
-                UserData.ENCODING_7BIT_ASCII, null, -1, -1, -1, -1, -1);
-
-        SmsCbMessage cbMessage = msg.parseBroadcastSms();
-        verifyCbValues(cbMessage);
-        assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT,
-                cbMessage.getServiceCategory());
-        assertEquals(1234, cbMessage.getSerialNumber());
-        assertEquals(SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, cbMessage.getMessagePriority());
-        assertEquals("en", cbMessage.getLanguageCode());
-        assertEquals(null, cbMessage.getMessageBody());
-        assertEquals(true, cbMessage.isEmergencyMessage());
-        assertEquals(true, cbMessage.isCmasMessage());
-        SmsCbCmasInfo cmasInfo = cbMessage.getCmasWarningInfo();
-        assertEquals(SmsCbCmasInfo.CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT, cmasInfo.getMessageClass());
-        assertEquals(SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN, cmasInfo.getCategory());
-        assertEquals(SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN, cmasInfo.getResponseType());
-        assertEquals(SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN, cmasInfo.getSeverity());
-        assertEquals(SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN, cmasInfo.getUrgency());
-        assertEquals(SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN, cmasInfo.getCertainty());
-    }
-
-    // Make sure we don't throw an exception if we feed completely random data to BearerStream.
-    public void testRandomBearerStreamData() {
-        Random r = new Random(54321);
-        for (int run = 0; run < 1000; run++) {
-            int len = r.nextInt(140);
-            byte[] data = new byte[len];
-            for (int i = 0; i < len; i++) {
-                data[i] = (byte) r.nextInt(256);
-            }
-            // Log.d("CdmaSmsCbTest", "trying random bearer data run " + run + " length " + len);
-            try {
-                int category = 0x0ff0 + r.nextInt(32);  // half CMAS, half non-CMAS
-                Parcel p = createBroadcastParcel(category);
-                SmsMessage msg = createMessageFromParcel(p, data);
-                SmsCbMessage cbMessage = msg.parseBroadcastSms();
-                // with random input, cbMessage will almost always be null (log when it isn't)
-                if (cbMessage != null) {
-                    Log.d("CdmaSmsCbTest", "success: " + cbMessage);
-                }
-            } catch (Exception e) {
-                Log.d("CdmaSmsCbTest", "exception thrown", e);
-                fail("Exception in decoder at run " + run + " length " + len + ": " + e);
-            }
-        }
-    }
-
-    // Make sure we don't throw an exception if we put random data in the UserData subparam.
-    public void testRandomUserData() {
-        Random r = new Random(94040);
-        for (int run = 0; run < 1000; run++) {
-            int category = 0x0ff0 + r.nextInt(32);  // half CMAS, half non-CMAS
-            Parcel p = createBroadcastParcel(category);
-            int len = r.nextInt(140);
-            // Log.d("CdmaSmsCbTest", "trying random user data run " + run + " length " + len);
-
-            try {
-                BitwiseOutputStream bos = createBearerDataStream(r.nextInt(65536), r.nextInt(4),
-                        r.nextInt(256));
-
-                bos.write(8, SUBPARAM_USER_DATA);
-                bos.write(8, len);
-
-                for (int i = 0; i < len; i++) {
-                    bos.write(8, r.nextInt(256));
-                }
-
-                SmsMessage msg = createMessageFromParcel(p, bos.toByteArray());
-                SmsCbMessage cbMessage = msg.parseBroadcastSms();
-            } catch (Exception e) {
-                Log.d("CdmaSmsCbTest", "exception thrown", e);
-                fail("Exception in decoder at run " + run + " length " + len + ": " + e);
-            }
-        }
-    }
-
-    /**
-     * Initialize a Parcel for incoming Service Category Program Data teleservice. The caller will
-     * write the bearer data and then convert it to an SmsMessage.
-     * @return the initialized Parcel
-     */
-    private static Parcel createServiceCategoryProgramDataParcel() {
-        Parcel p = Parcel.obtain();
-
-        p.writeInt(SmsEnvelope.TELESERVICE_SCPT);
-        p.writeByte((byte) 0);  // non-zero for MESSAGE_TYPE_BROADCAST
-        p.writeInt(0);
-
-        // dummy address (RIL may generate a different dummy address for broadcasts)
-        p.writeInt(CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF);            // sAddress.digit_mode
-        p.writeInt(CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK);    // sAddress.number_mode
-        p.writeInt(CdmaSmsAddress.TON_UNKNOWN);                     // sAddress.number_type
-        p.writeInt(CdmaSmsAddress.NUMBERING_PLAN_ISDN_TELEPHONY);   // sAddress.number_plan
-        p.writeByte((byte) 0);      // sAddress.number_of_digits
-        p.writeInt((byte) 0);       // sSubAddress.subaddressType
-        p.writeByte((byte) 0);      // sSubAddress.odd
-        p.writeByte((byte) 0);      // sSubAddress.number_of_digits
-        return p;
-    }
-
-    private static final String CAT_EXTREME_THREAT = "Extreme Threat to Life and Property";
-    private static final String CAT_SEVERE_THREAT = "Severe Threat to Life and Property";
-    private static final String CAT_AMBER_ALERTS = "AMBER Alerts";
-
-    public void testServiceCategoryProgramDataAddCategory() throws Exception {
-        Parcel p = createServiceCategoryProgramDataParcel();
-        BitwiseOutputStream bos = createBearerDataStream(123, -1, -1);
-
-        int categoryNameLength = CAT_EXTREME_THREAT.length();
-        int subparamLengthBits = (53 + (categoryNameLength * 7));
-        int subparamLengthBytes = (subparamLengthBits + 7) / 8;
-        int subparamPadBits = (subparamLengthBytes * 8) - subparamLengthBits;
-
-        bos.write(8, SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA);
-        bos.write(8, subparamLengthBytes);
-        bos.write(5, UserData.ENCODING_7BIT_ASCII);
-
-        bos.write(4, CdmaSmsCbProgramData.OPERATION_ADD_CATEGORY);
-        bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT >>> 8));
-        bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT & 0xff));
-        bos.write(8, BearerData.LANGUAGE_ENGLISH);
-        bos.write(8, 100);  // max messages
-        bos.write(4, CdmaSmsCbProgramData.ALERT_OPTION_DEFAULT_ALERT);
-
-        bos.write(8, categoryNameLength);
-        for (int i = 0; i < categoryNameLength; i++) {
-            bos.write(7, CAT_EXTREME_THREAT.charAt(i));
-        }
-        bos.write(subparamPadBits, 0);
-
-        SmsMessage msg = createMessageFromParcel(p, bos.toByteArray());
-        assertNotNull(msg);
-        msg.parseSms();
-        List<CdmaSmsCbProgramData> programDataList = msg.getSmsCbProgramData();
-        assertNotNull(programDataList);
-        assertEquals(1, programDataList.size());
-        CdmaSmsCbProgramData programData = programDataList.get(0);
-        assertEquals(CdmaSmsCbProgramData.OPERATION_ADD_CATEGORY, programData.getOperation());
-        assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT, programData.getCategory());
-        assertEquals(CAT_EXTREME_THREAT, programData.getCategoryName());
-        assertEquals(BearerData.LANGUAGE_ENGLISH, programData.getLanguage());
-        assertEquals(100, programData.getMaxMessages());
-        assertEquals(CdmaSmsCbProgramData.ALERT_OPTION_DEFAULT_ALERT, programData.getAlertOption());
-    }
-
-    public void testServiceCategoryProgramDataDeleteTwoCategories() throws Exception {
-        Parcel p = createServiceCategoryProgramDataParcel();
-        BitwiseOutputStream bos = createBearerDataStream(456, -1, -1);
-
-        int category1NameLength = CAT_SEVERE_THREAT.length();
-        int category2NameLength = CAT_AMBER_ALERTS.length();
-
-        int subparamLengthBits = (101 + (category1NameLength * 7) + (category2NameLength * 7));
-        int subparamLengthBytes = (subparamLengthBits + 7) / 8;
-        int subparamPadBits = (subparamLengthBytes * 8) - subparamLengthBits;
-
-        bos.write(8, SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA);
-        bos.write(8, subparamLengthBytes);
-        bos.write(5, UserData.ENCODING_7BIT_ASCII);
-
-        bos.write(4, CdmaSmsCbProgramData.OPERATION_DELETE_CATEGORY);
-        bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT >>> 8));
-        bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT & 0xff));
-        bos.write(8, BearerData.LANGUAGE_ENGLISH);
-        bos.write(8, 0);  // max messages
-        bos.write(4, CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT);
-
-        bos.write(8, category1NameLength);
-        for (int i = 0; i < category1NameLength; i++) {
-            bos.write(7, CAT_SEVERE_THREAT.charAt(i));
-        }
-
-        bos.write(4, CdmaSmsCbProgramData.OPERATION_DELETE_CATEGORY);
-        bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY >>> 8));
-        bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY & 0xff));
-        bos.write(8, BearerData.LANGUAGE_ENGLISH);
-        bos.write(8, 0);  // max messages
-        bos.write(4, CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT);
-
-        bos.write(8, category2NameLength);
-        for (int i = 0; i < category2NameLength; i++) {
-            bos.write(7, CAT_AMBER_ALERTS.charAt(i));
-        }
-
-        bos.write(subparamPadBits, 0);
-
-        SmsMessage msg = createMessageFromParcel(p, bos.toByteArray());
-        assertNotNull(msg);
-        msg.parseSms();
-        List<CdmaSmsCbProgramData> programDataList = msg.getSmsCbProgramData();
-        assertNotNull(programDataList);
-        assertEquals(2, programDataList.size());
-
-        CdmaSmsCbProgramData programData = programDataList.get(0);
-        assertEquals(CdmaSmsCbProgramData.OPERATION_DELETE_CATEGORY, programData.getOperation());
-        assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT, programData.getCategory());
-        assertEquals(CAT_SEVERE_THREAT, programData.getCategoryName());
-        assertEquals(BearerData.LANGUAGE_ENGLISH, programData.getLanguage());
-        assertEquals(0, programData.getMaxMessages());
-        assertEquals(CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT, programData.getAlertOption());
-
-        programData = programDataList.get(1);
-        assertEquals(CdmaSmsCbProgramData.OPERATION_DELETE_CATEGORY, programData.getOperation());
-        assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY,
-                programData.getCategory());
-        assertEquals(CAT_AMBER_ALERTS, programData.getCategoryName());
-        assertEquals(BearerData.LANGUAGE_ENGLISH, programData.getLanguage());
-        assertEquals(0, programData.getMaxMessages());
-        assertEquals(CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT, programData.getAlertOption());
-    }
-
-    private static final byte[] CMAS_TEST_BEARER_DATA = {
-        0x00, 0x03, 0x1C, 0x78, 0x00, 0x01, 0x59, 0x02, (byte) 0xB8, 0x00, 0x02, 0x10, (byte) 0xAA,
-        0x68, (byte) 0xD3, (byte) 0xCD, 0x06, (byte) 0x9E, 0x68, 0x30, (byte) 0xA0, (byte) 0xE9,
-        (byte) 0x97, (byte) 0x9F, 0x44, 0x1B, (byte) 0xF3, 0x20, (byte) 0xE9, (byte) 0xA3,
-        0x2A, 0x08, 0x7B, (byte) 0xF6, (byte) 0xED, (byte) 0xCB, (byte) 0xCB, 0x1E, (byte) 0x9C,
-        0x3B, 0x10, 0x4D, (byte) 0xDF, (byte) 0x8B, 0x4E,
-        (byte) 0xCC, (byte) 0xA8, 0x20, (byte) 0xEC, (byte) 0xCB, (byte) 0xCB, (byte) 0xA2, 0x0A,
-        0x7E, 0x79, (byte) 0xF4, (byte) 0xCB, (byte) 0xB5, 0x72, 0x0A, (byte) 0x9A, 0x34,
-        (byte) 0xF3, 0x41, (byte) 0xA7, (byte) 0x9A, 0x0D, (byte) 0xFB, (byte) 0xB6, 0x79, 0x41,
-        (byte) 0x85, 0x07, 0x4C, (byte) 0xBC, (byte) 0xFA, 0x2E, 0x00, 0x08, 0x20, 0x58, 0x38,
-        (byte) 0x88, (byte) 0x80, 0x10, 0x54, 0x06, 0x38, 0x20, 0x60,
-        0x30, (byte) 0xA8, (byte) 0x81, (byte) 0x90, 0x20, 0x08
-    };
-
-    // Test case for CMAS test message received on the Sprint network.
-    public void testDecodeRawBearerData() throws Exception {
-        Parcel p = createBroadcastParcel(SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE);
-        SmsMessage msg = createMessageFromParcel(p, CMAS_TEST_BEARER_DATA);
-
-        SmsCbMessage cbMessage = msg.parseBroadcastSms();
-        assertNotNull("expected non-null for bearer data", cbMessage);
-        assertEquals("geoScope", cbMessage.getGeographicalScope(), 1);
-        assertEquals("serialNumber", cbMessage.getSerialNumber(), 51072);
-        assertEquals("serviceCategory", cbMessage.getServiceCategory(),
-                SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE);
-        assertEquals("payload", cbMessage.getMessageBody(),
-                "This is a test of the Commercial Mobile Alert System. This is only a test.");
-
-        SmsCbCmasInfo cmasInfo = cbMessage.getCmasWarningInfo();
-        assertNotNull("expected non-null for CMAS info", cmasInfo);
-        assertEquals("category", cmasInfo.getCategory(), SmsCbCmasInfo.CMAS_CATEGORY_OTHER);
-        assertEquals("responseType", cmasInfo.getResponseType(),
-                SmsCbCmasInfo.CMAS_RESPONSE_TYPE_NONE);
-        assertEquals("severity", cmasInfo.getSeverity(), SmsCbCmasInfo.CMAS_SEVERITY_SEVERE);
-        assertEquals("urgency", cmasInfo.getUrgency(), SmsCbCmasInfo.CMAS_URGENCY_EXPECTED);
-        assertEquals("certainty", cmasInfo.getCertainty(), SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY);
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/sms/CdmaSmsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/sms/CdmaSmsTest.java
deleted file mode 100644
index f1bc268..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/sms/CdmaSmsTest.java
+++ /dev/null
@@ -1,946 +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.internal.telephony.cdma.sms;
-
-import android.telephony.TelephonyManager;
-
-import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.SmsHeader;
-import com.android.internal.telephony.cdma.SmsMessage;
-import com.android.internal.telephony.cdma.sms.BearerData;
-import com.android.internal.telephony.cdma.sms.UserData;
-import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
-import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails;
-import com.android.internal.util.BitwiseInputStream;
-import com.android.internal.util.BitwiseOutputStream;
-import com.android.internal.util.HexDump;
-
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-public class CdmaSmsTest extends AndroidTestCase {
-    private final static String LOG_TAG = "XXX CdmaSmsTest XXX";
-
-    // CJK ideographs, Hiragana, Katakana, full width letters, Cyrillic, etc.
-    private static final String sUnicodeChars = "\u4e00\u4e01\u4e02\u4e03" +
-            "\u4e04\u4e05\u4e06\u4e07\u4e08\u4e09\u4e0a\u4e0b\u4e0c\u4e0d" +
-            "\u4e0e\u4e0f\u3041\u3042\u3043\u3044\u3045\u3046\u3047\u3048" +
-            "\u30a1\u30a2\u30a3\u30a4\u30a5\u30a6\u30a7\u30a8" +
-            "\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18" +
-            "\uff70\uff71\uff72\uff73\uff74\uff75\uff76\uff77\uff78" +
-            "\u0400\u0401\u0402\u0403\u0404\u0405\u0406\u0407\u0408" +
-            "\u00a2\u00a9\u00ae\u2122";
-
-    @SmallTest
-    public void testCdmaSmsAddrParsing() throws Exception {
-        CdmaSmsAddress addr = CdmaSmsAddress.parse("6502531000");
-        assertEquals(addr.ton, CdmaSmsAddress.TON_UNKNOWN);
-        assertEquals(addr.digitMode, CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF);
-        assertEquals(addr.numberMode, CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK);
-        assertEquals(addr.numberOfDigits, 10);
-        assertEquals(addr.origBytes.length, 10);
-        byte[] data = {6, 5, 10, 2, 5, 3, 1, 10, 10, 10};
-        for (int i = 0; i < data.length; i++) {
-            assertEquals(addr.origBytes[i], data[i]);
-        }
-        addr = CdmaSmsAddress.parse("(650) 253-1000");
-        assertEquals(addr.ton, CdmaSmsAddress.TON_UNKNOWN);
-        assertEquals(addr.digitMode, CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF);
-        assertEquals(addr.numberMode, CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK);
-        assertEquals(addr.numberOfDigits, 10);
-        assertEquals(addr.origBytes.length, 10);
-        byte[] data2 = {6, 5, 10, 2, 5, 3, 1, 10, 10, 10};
-        for (int i = 0; i < data2.length; i++) {
-            assertEquals(addr.origBytes[i], data2[i]);
-        }
-        addr = CdmaSmsAddress.parse("650.253.1000");
-        assertEquals(addr.ton, CdmaSmsAddress.TON_UNKNOWN);
-        assertEquals(addr.digitMode, CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF);
-        assertEquals(addr.numberMode, CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK);
-        assertEquals(addr.numberOfDigits, 10);
-        assertEquals(addr.origBytes.length, 10);
-        byte[] data5 = {6, 5, 10, 2, 5, 3, 1, 10, 10, 10};
-        for (int i = 0; i < data2.length; i++) {
-            assertEquals(addr.origBytes[i], data5[i]);
-        }
-        addr = CdmaSmsAddress.parse("(+886) 917 222 555");
-        assertEquals(addr.ton, CdmaSmsAddress.TON_INTERNATIONAL_OR_IP);
-        assertEquals(addr.digitMode, CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF);
-        assertEquals(addr.numberMode, CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK);
-        assertEquals(addr.numberOfDigits, 12);
-        assertEquals(addr.origBytes.length, 12);
-        byte[] data3 = {8, 8, 6, 9, 1, 7, 2, 2, 2, 5, 5, 5};
-        for (int i = 0; i < data3.length; i++) {
-            assertEquals(addr.origBytes[i], data3[i]);
-        }
-        addr = CdmaSmsAddress.parse("(650) *253-1000 #600");
-        byte[] data4 = {6, 5, 10, 11, 2, 5, 3, 1, 10, 10, 10, 12, 6, 10, 10};
-        for (int i = 0; i < data4.length; i++) {
-            assertEquals(addr.origBytes[i], data4[i]);
-        }
-        String input = "x@y.com,a@b.com";
-        addr = CdmaSmsAddress.parse(input);
-        assertEquals(addr.ton, CdmaSmsAddress.TON_NATIONAL_OR_EMAIL);
-        assertEquals(addr.digitMode, CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR);
-        assertEquals(addr.numberMode, CdmaSmsAddress.NUMBER_MODE_DATA_NETWORK);
-        assertEquals(addr.numberOfDigits, 15);
-        assertEquals(addr.origBytes.length, 15);
-        assertEquals(new String(addr.origBytes), input);
-        addr = CdmaSmsAddress.parse("foo bar");
-        assertEquals(addr.ton, CdmaSmsAddress.TON_UNKNOWN);
-        assertEquals(addr.digitMode, CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR);
-        assertEquals(addr.numberMode, CdmaSmsAddress.NUMBER_MODE_DATA_NETWORK);
-        assertEquals(addr.numberOfDigits, 6);
-        assertEquals(addr.origBytes.length, 6);
-        assertEquals(new String(addr.origBytes), "foobar");
-        addr = CdmaSmsAddress.parse("f\noo\tb   a\rr");
-        assertEquals(new String(addr.origBytes), "foobar");
-        assertEquals(CdmaSmsAddress.parse("f\u0000oo bar"), null);
-        assertEquals(CdmaSmsAddress.parse("f\u0007oo bar"), null);
-        assertEquals(CdmaSmsAddress.parse("f\u0080oo bar"), null);
-        assertEquals(CdmaSmsAddress.parse("f\u1ECFboo\u001fbar"), null);
-        assertEquals(CdmaSmsAddress.parse("f\u0080oo bar"), null);
-    }
-
-    @SmallTest
-    public void testUserData7bitGsm() throws Exception {
-        String pdu = "00031040900112488ea794e074d69e1b7392c270326cde9e98";
-        BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu));
-        assertEquals("Test standard SMS", bearerData.userData.payloadStr);
-    }
-
-    @SmallTest
-    public void testUserData7bitAscii() throws Exception {
-        String pdu = "0003100160010610262d5ab500";
-        BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu));
-        assertEquals("bjjj", bearerData.userData.payloadStr);
-    }
-
-    @SmallTest
-    public void testUserData7bitAsciiTwo() throws Exception {
-        String pdu = "00031001d00109104539b4d052ebb3d0";
-        BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu));
-        assertEquals("SMS Rulz", bearerData.userData.payloadStr);
-    }
-
-    @SmallTest
-    public void testUserDataIa5() throws Exception {
-        String pdu = "00031002100109184539b4d052ebb3d0";
-        BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu));
-        assertEquals("SMS Rulz", bearerData.userData.payloadStr);
-    }
-
-    @SmallTest
-    public void testUserData7bitAsciiFeedback() throws Exception {
-        BearerData bearerData = new BearerData();
-        bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
-        bearerData.messageId = 0;
-        bearerData.hasUserDataHeader = false;
-        UserData userData = new UserData();
-        userData.payloadStr = "Test standard SMS";
-        userData.msgEncoding = UserData.ENCODING_7BIT_ASCII;
-        userData.msgEncodingSet = true;
-        bearerData.userData = userData;
-        byte []encodedSms = BearerData.encode(bearerData);
-        BearerData revBearerData = BearerData.decode(encodedSms);
-        assertEquals(BearerData.MESSAGE_TYPE_DELIVER, revBearerData.messageType);
-        assertEquals(0, revBearerData.messageId);
-        assertEquals(false, revBearerData.hasUserDataHeader);
-        assertEquals(userData.msgEncoding, revBearerData.userData.msgEncoding);
-        assertEquals(userData.payloadStr.length(), revBearerData.userData.numFields);
-        assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
-        userData.payloadStr = "Test \u007f standard \u0000 SMS";
-        revBearerData = BearerData.decode(BearerData.encode(bearerData));
-        assertEquals("Test   standard   SMS", revBearerData.userData.payloadStr);
-        userData.payloadStr = "Test \n standard \r SMS";
-        revBearerData = BearerData.decode(BearerData.encode(bearerData));
-        assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
-        userData.payloadStr = "";
-        revBearerData = BearerData.decode(BearerData.encode(bearerData));
-        assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
-    }
-
-    @SmallTest
-    public void testUserData7bitGsmFeedback() throws Exception {
-        BearerData bearerData = new BearerData();
-        bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
-        bearerData.messageId = 0;
-        bearerData.hasUserDataHeader = false;
-        UserData userData = new UserData();
-        userData.payloadStr = "Test standard SMS";
-        userData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET;
-        userData.msgEncodingSet = true;
-        bearerData.userData = userData;
-        byte []encodedSms = BearerData.encode(bearerData);
-        BearerData revBearerData = BearerData.decode(encodedSms);
-        assertEquals(BearerData.MESSAGE_TYPE_DELIVER, revBearerData.messageType);
-        assertEquals(0, revBearerData.messageId);
-        assertEquals(false, revBearerData.hasUserDataHeader);
-        assertEquals(userData.msgEncoding, revBearerData.userData.msgEncoding);
-        assertEquals(userData.payloadStr.length(), revBearerData.userData.numFields);
-        assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
-        userData.payloadStr = "1234567";
-        revBearerData = BearerData.decode(BearerData.encode(bearerData));
-        assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
-        userData.payloadStr = "";
-        revBearerData = BearerData.decode(BearerData.encode(bearerData));
-        assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
-        userData.payloadStr = "12345678901234567890123456789012345678901234567890" +
-                "12345678901234567890123456789012345678901234567890" +
-                "12345678901234567890123456789012345678901234567890" +
-                "1234567890";
-        revBearerData = BearerData.decode(BearerData.encode(bearerData));
-        assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
-        userData.payloadStr = "Test \u007f illegal \u0000 SMS chars";
-        revBearerData = BearerData.decode(BearerData.encode(bearerData));
-        assertEquals("Test   illegal   SMS chars", revBearerData.userData.payloadStr);
-        userData.payloadStr = "More @ testing\nis great^|^~woohoo";
-        revBearerData = BearerData.decode(BearerData.encode(bearerData));
-        assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
-        SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
-        concatRef.refNumber = 0xEE;
-        concatRef.msgCount = 2;
-        concatRef.seqNumber = 2;
-        concatRef.isEightBits = true;
-        SmsHeader smsHeader = new SmsHeader();
-        smsHeader.concatRef = concatRef;
-        byte[] encodedHeader = SmsHeader.toByteArray(smsHeader);
-        userData.userDataHeader = smsHeader;
-        revBearerData = BearerData.decode(BearerData.encode(bearerData));
-        assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
-        SmsHeader decodedHeader = revBearerData.userData.userDataHeader;
-        assertEquals(decodedHeader.concatRef.refNumber, concatRef.refNumber);
-        assertEquals(decodedHeader.concatRef.msgCount, concatRef.msgCount);
-        assertEquals(decodedHeader.concatRef.seqNumber, concatRef.seqNumber);
-    }
-
-    @SmallTest
-    public void testUserDataUtf16Feedback() throws Exception {
-        BearerData bearerData = new BearerData();
-        bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
-        bearerData.messageId = 0;
-        bearerData.hasUserDataHeader = false;
-        UserData userData = new UserData();
-        userData.payloadStr = "\u0160u\u1E5B\u0301r\u1ECFg\uD835\uDC1At\u00E9\u4E002\u3042";
-        userData.msgEncoding = UserData.ENCODING_UNICODE_16;
-        userData.msgEncodingSet = true;
-        bearerData.userData = userData;
-        byte []encodedSms = BearerData.encode(bearerData);
-        BearerData revBearerData = BearerData.decode(encodedSms);
-        assertEquals(BearerData.MESSAGE_TYPE_DELIVER, revBearerData.messageType);
-        assertEquals(0, revBearerData.messageId);
-        assertEquals(false, revBearerData.hasUserDataHeader);
-        assertEquals(userData.msgEncoding, revBearerData.userData.msgEncoding);
-        assertEquals(userData.payloadStr.length(), revBearerData.userData.numFields);
-        assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
-        userData.msgEncoding = UserData.ENCODING_OCTET;
-        userData.msgEncodingSet = false;
-        revBearerData = BearerData.decode(BearerData.encode(bearerData));
-        assertEquals(BearerData.MESSAGE_TYPE_DELIVER, revBearerData.messageType);
-        assertEquals(0, revBearerData.messageId);
-        assertEquals(false, revBearerData.hasUserDataHeader);
-        assertEquals(userData.msgEncoding, revBearerData.userData.msgEncoding);
-        assertEquals(userData.payloadStr.length(), revBearerData.userData.numFields);
-        assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
-        userData.payloadStr = "1234567";
-        revBearerData = BearerData.decode(BearerData.encode(bearerData));
-        assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
-        userData.payloadStr = "";
-        revBearerData = BearerData.decode(BearerData.encode(bearerData));
-        assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
-    }
-
-    @SmallTest
-    public void testMonolithicOne() throws Exception {
-        String pdu = "0003200010010410168d2002010503060812011101590501c706069706180000000701c108" +
-                "01c00901800a01e00b01030c01c00d01070e05039acc13880f018011020566";
-        BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu));
-        assertEquals(bearerData.messageType, BearerData.MESSAGE_TYPE_SUBMIT);
-        assertEquals(bearerData.messageId, 1);
-        assertEquals(bearerData.priority, BearerData.PRIORITY_EMERGENCY);
-        assertEquals(bearerData.privacy, BearerData.PRIVACY_CONFIDENTIAL);
-        assertEquals(bearerData.userAckReq, true);
-        assertEquals(bearerData.readAckReq, true);
-        assertEquals(bearerData.deliveryAckReq, true);
-        assertEquals(bearerData.reportReq, false);
-        assertEquals(bearerData.numberOfMessages, 3);
-        assertEquals(bearerData.alert, BearerData.ALERT_HIGH_PRIO);
-        assertEquals(bearerData.language, BearerData.LANGUAGE_HEBREW);
-        assertEquals(bearerData.callbackNumber.digitMode, CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF);
-        assertEquals(bearerData.callbackNumber.numberMode,
-                     CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK);
-        assertEquals(bearerData.callbackNumber.ton, CdmaSmsAddress.TON_UNKNOWN);
-        assertEquals(bearerData.callbackNumber.numberPlan, CdmaSmsAddress.NUMBERING_PLAN_UNKNOWN);
-        assertEquals(bearerData.callbackNumber.numberOfDigits, 7);
-        assertEquals(bearerData.callbackNumber.address, "3598271");
-        assertEquals(bearerData.displayMode, BearerData.DISPLAY_MODE_USER);
-        assertEquals(bearerData.depositIndex, 1382);
-        assertEquals(bearerData.userResponseCode, 5);
-        assertEquals(bearerData.msgCenterTimeStamp.year, 2008);
-        assertEquals(bearerData.msgCenterTimeStamp.month, 11);
-        assertEquals(bearerData.msgCenterTimeStamp.monthDay, 1);
-        assertEquals(bearerData.msgCenterTimeStamp.hour, 11);
-        assertEquals(bearerData.msgCenterTimeStamp.minute, 1);
-        assertEquals(bearerData.msgCenterTimeStamp.second, 59);
-        assertEquals(bearerData.validityPeriodAbsolute, null);
-        assertEquals(bearerData.validityPeriodRelative, 193);
-        assertEquals(bearerData.deferredDeliveryTimeAbsolute.year, 1997);
-        assertEquals(bearerData.deferredDeliveryTimeAbsolute.month, 5);
-        assertEquals(bearerData.deferredDeliveryTimeAbsolute.monthDay, 18);
-        assertEquals(bearerData.deferredDeliveryTimeAbsolute.hour, 0);
-        assertEquals(bearerData.deferredDeliveryTimeAbsolute.minute, 0);
-        assertEquals(bearerData.deferredDeliveryTimeAbsolute.second, 0);
-        assertEquals(bearerData.deferredDeliveryTimeRelative, 199);
-        assertEquals(bearerData.hasUserDataHeader, false);
-        assertEquals(bearerData.userData.msgEncoding, UserData.ENCODING_7BIT_ASCII);
-        assertEquals(bearerData.userData.numFields, 2);
-        assertEquals(bearerData.userData.payloadStr, "hi");
-    }
-
-    @SmallTest
-    public void testMonolithicTwo() throws Exception {
-        String pdu = "0003200010010410168d200201050306081201110159050192060697061800000007013d0" +
-                "801c00901800a01e00b01030c01c00d01070e05039acc13880f018011020566";
-        BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu));
-        assertEquals(bearerData.messageType, BearerData.MESSAGE_TYPE_SUBMIT);
-        assertEquals(bearerData.messageId, 1);
-        assertEquals(bearerData.priority, BearerData.PRIORITY_EMERGENCY);
-        assertEquals(bearerData.privacy, BearerData.PRIVACY_CONFIDENTIAL);
-        assertEquals(bearerData.userAckReq, true);
-        assertEquals(bearerData.readAckReq, true);
-        assertEquals(bearerData.deliveryAckReq, true);
-        assertEquals(bearerData.reportReq, false);
-        assertEquals(bearerData.numberOfMessages, 3);
-        assertEquals(bearerData.alert, BearerData.ALERT_HIGH_PRIO);
-        assertEquals(bearerData.language, BearerData.LANGUAGE_HEBREW);
-        assertEquals(bearerData.callbackNumber.digitMode, CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF);
-        assertEquals(bearerData.callbackNumber.numberMode,
-                     CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK);
-        assertEquals(bearerData.callbackNumber.ton, CdmaSmsAddress.TON_UNKNOWN);
-        assertEquals(bearerData.callbackNumber.numberPlan, CdmaSmsAddress.NUMBERING_PLAN_UNKNOWN);
-        assertEquals(bearerData.callbackNumber.numberOfDigits, 7);
-        assertEquals(bearerData.callbackNumber.address, "3598271");
-        assertEquals(bearerData.displayMode, BearerData.DISPLAY_MODE_USER);
-        assertEquals(bearerData.depositIndex, 1382);
-        assertEquals(bearerData.userResponseCode, 5);
-        assertEquals(bearerData.msgCenterTimeStamp.year, 2008);
-        assertEquals(bearerData.msgCenterTimeStamp.month, 11);
-        assertEquals(bearerData.msgCenterTimeStamp.monthDay, 1);
-        assertEquals(bearerData.msgCenterTimeStamp.hour, 11);
-        assertEquals(bearerData.msgCenterTimeStamp.minute, 1);
-        assertEquals(bearerData.msgCenterTimeStamp.second, 59);
-        assertEquals(bearerData.validityPeriodAbsolute, null);
-        assertEquals(bearerData.validityPeriodRelative, 61);
-        assertEquals(bearerData.deferredDeliveryTimeAbsolute.year, 1997);
-        assertEquals(bearerData.deferredDeliveryTimeAbsolute.month, 5);
-        assertEquals(bearerData.deferredDeliveryTimeAbsolute.monthDay, 18);
-        assertEquals(bearerData.deferredDeliveryTimeAbsolute.hour, 0);
-        assertEquals(bearerData.deferredDeliveryTimeAbsolute.minute, 0);
-        assertEquals(bearerData.deferredDeliveryTimeAbsolute.second, 0);
-        assertEquals(bearerData.deferredDeliveryTimeRelative, 146);
-        assertEquals(bearerData.hasUserDataHeader, false);
-        assertEquals(bearerData.userData.msgEncoding, UserData.ENCODING_7BIT_ASCII);
-        assertEquals(bearerData.userData.numFields, 2);
-        assertEquals(bearerData.userData.payloadStr, "hi");
-    }
-
-    @SmallTest
-    public void testUserDataHeaderConcatRefFeedback() throws Exception {
-        BearerData bearerData = new BearerData();
-        bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
-        bearerData.messageId = 55;
-        SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
-        concatRef.refNumber = 0xEE;
-        concatRef.msgCount = 2;
-        concatRef.seqNumber = 2;
-        concatRef.isEightBits = true;
-        SmsHeader smsHeader = new SmsHeader();
-        smsHeader.concatRef = concatRef;
-        byte[] encodedHeader = SmsHeader.toByteArray(smsHeader);
-        SmsHeader decodedHeader = SmsHeader.fromByteArray(encodedHeader);
-        assertEquals(decodedHeader.concatRef.refNumber, concatRef.refNumber);
-        assertEquals(decodedHeader.concatRef.msgCount, concatRef.msgCount);
-        assertEquals(decodedHeader.concatRef.seqNumber, concatRef.seqNumber);
-        assertEquals(decodedHeader.concatRef.isEightBits, concatRef.isEightBits);
-        assertEquals(decodedHeader.portAddrs, null);
-        UserData userData = new UserData();
-        userData.payloadStr = "User Data Header (UDH) feedback test";
-        userData.userDataHeader = smsHeader;
-        bearerData.userData = userData;
-        byte[] encodedSms = BearerData.encode(bearerData);
-        BearerData revBearerData = BearerData.decode(encodedSms);
-        decodedHeader = revBearerData.userData.userDataHeader;
-        assertEquals(decodedHeader.concatRef.refNumber, concatRef.refNumber);
-        assertEquals(decodedHeader.concatRef.msgCount, concatRef.msgCount);
-        assertEquals(decodedHeader.concatRef.seqNumber, concatRef.seqNumber);
-        assertEquals(decodedHeader.concatRef.isEightBits, concatRef.isEightBits);
-        assertEquals(decodedHeader.portAddrs, null);
-    }
-
-    @SmallTest
-    public void testUserDataHeaderIllegalConcatRef() throws Exception {
-        BearerData bearerData = new BearerData();
-        bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
-        bearerData.messageId = 55;
-        SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
-        concatRef.refNumber = 0x10;
-        concatRef.msgCount = 0;
-        concatRef.seqNumber = 2;
-        concatRef.isEightBits = true;
-        SmsHeader smsHeader = new SmsHeader();
-        smsHeader.concatRef = concatRef;
-        byte[] encodedHeader = SmsHeader.toByteArray(smsHeader);
-        SmsHeader decodedHeader = SmsHeader.fromByteArray(encodedHeader);
-        assertEquals(decodedHeader.concatRef, null);
-        concatRef.isEightBits = false;
-        encodedHeader = SmsHeader.toByteArray(smsHeader);
-        decodedHeader = SmsHeader.fromByteArray(encodedHeader);
-        assertEquals(decodedHeader.concatRef, null);
-        concatRef.msgCount = 1;
-        concatRef.seqNumber = 2;
-        encodedHeader = SmsHeader.toByteArray(smsHeader);
-        decodedHeader = SmsHeader.fromByteArray(encodedHeader);
-        assertEquals(decodedHeader.concatRef, null);
-        concatRef.msgCount = 1;
-        concatRef.seqNumber = 0;
-        encodedHeader = SmsHeader.toByteArray(smsHeader);
-        decodedHeader = SmsHeader.fromByteArray(encodedHeader);
-        assertEquals(decodedHeader.concatRef, null);
-        concatRef.msgCount = 2;
-        concatRef.seqNumber = 1;
-        encodedHeader = SmsHeader.toByteArray(smsHeader);
-        decodedHeader = SmsHeader.fromByteArray(encodedHeader);
-        assertEquals(decodedHeader.concatRef.msgCount, 2);
-        assertEquals(decodedHeader.concatRef.seqNumber, 1);
-    }
-
-    @SmallTest
-    public void testUserDataHeaderMixedFeedback() throws Exception {
-        BearerData bearerData = new BearerData();
-        bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
-        bearerData.messageId = 42;
-        SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
-        concatRef.refNumber = 0x34;
-        concatRef.msgCount = 5;
-        concatRef.seqNumber = 2;
-        concatRef.isEightBits = false;
-        SmsHeader.PortAddrs portAddrs = new SmsHeader.PortAddrs();
-        portAddrs.destPort = 88;
-        portAddrs.origPort = 66;
-        portAddrs.areEightBits = false;
-        SmsHeader smsHeader = new SmsHeader();
-        smsHeader.concatRef = concatRef;
-        smsHeader.portAddrs = portAddrs;
-        byte[] encodedHeader = SmsHeader.toByteArray(smsHeader);
-        SmsHeader decodedHeader = SmsHeader.fromByteArray(encodedHeader);
-        assertEquals(decodedHeader.concatRef.refNumber, concatRef.refNumber);
-        assertEquals(decodedHeader.concatRef.msgCount, concatRef.msgCount);
-        assertEquals(decodedHeader.concatRef.seqNumber, concatRef.seqNumber);
-        assertEquals(decodedHeader.concatRef.isEightBits, concatRef.isEightBits);
-        assertEquals(decodedHeader.portAddrs.destPort, portAddrs.destPort);
-        assertEquals(decodedHeader.portAddrs.origPort, portAddrs.origPort);
-        assertEquals(decodedHeader.portAddrs.areEightBits, portAddrs.areEightBits);
-        UserData userData = new UserData();
-        userData.payloadStr = "User Data Header (UDH) feedback test";
-        userData.userDataHeader = smsHeader;
-        bearerData.userData = userData;
-        byte[] encodedSms = BearerData.encode(bearerData);
-        BearerData revBearerData = BearerData.decode(encodedSms);
-        decodedHeader = revBearerData.userData.userDataHeader;
-        assertEquals(decodedHeader.concatRef.refNumber, concatRef.refNumber);
-        assertEquals(decodedHeader.concatRef.msgCount, concatRef.msgCount);
-        assertEquals(decodedHeader.concatRef.seqNumber, concatRef.seqNumber);
-        assertEquals(decodedHeader.concatRef.isEightBits, concatRef.isEightBits);
-        assertEquals(decodedHeader.portAddrs.destPort, portAddrs.destPort);
-        assertEquals(decodedHeader.portAddrs.origPort, portAddrs.origPort);
-        assertEquals(decodedHeader.portAddrs.areEightBits, portAddrs.areEightBits);
-    }
-
-    @SmallTest
-    public void testReplyOption() throws Exception {
-        String pdu1 = "0003104090011648b6a794e0705476bf77bceae934fe5f6d94d87450080a0180";
-        BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
-        assertEquals("Test Acknowledgement 1", bd1.userData.payloadStr);
-        assertEquals(true, bd1.userAckReq);
-        assertEquals(false, bd1.deliveryAckReq);
-        assertEquals(false, bd1.readAckReq);
-        assertEquals(false, bd1.reportReq);
-        String pdu2 = "0003104090011648b6a794e0705476bf77bceae934fe5f6d94d87490080a0140";
-        BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2));
-        assertEquals("Test Acknowledgement 2", bd2.userData.payloadStr);
-        assertEquals(false, bd2.userAckReq);
-        assertEquals(true, bd2.deliveryAckReq);
-        assertEquals(false, bd2.readAckReq);
-        assertEquals(false, bd2.reportReq);
-        String pdu3 = "0003104090011648b6a794e0705476bf77bceae934fe5f6d94d874d0080a0120";
-        BearerData bd3 = BearerData.decode(HexDump.hexStringToByteArray(pdu3));
-        assertEquals("Test Acknowledgement 3", bd3.userData.payloadStr);
-        assertEquals(false, bd3.userAckReq);
-        assertEquals(false, bd3.deliveryAckReq);
-        assertEquals(true, bd3.readAckReq);
-        assertEquals(false, bd3.reportReq);
-        String pdu4 = "0003104090011648b6a794e0705476bf77bceae934fe5f6d94d87510080a0110";
-        BearerData bd4 = BearerData.decode(HexDump.hexStringToByteArray(pdu4));
-        assertEquals("Test Acknowledgement 4", bd4.userData.payloadStr);
-        assertEquals(false, bd4.userAckReq);
-        assertEquals(false, bd4.deliveryAckReq);
-        assertEquals(false, bd4.readAckReq);
-        assertEquals(true, bd4.reportReq);
-    }
-
-    @SmallTest
-    public void testReplyOptionFeedback() throws Exception {
-        BearerData bearerData = new BearerData();
-        bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
-        bearerData.messageId = 0;
-        bearerData.hasUserDataHeader = false;
-        UserData userData = new UserData();
-        userData.payloadStr = "test reply option";
-        bearerData.userData = userData;
-        bearerData.userAckReq = true;
-        byte []encodedSms = BearerData.encode(bearerData);
-        BearerData revBearerData = BearerData.decode(encodedSms);
-        assertEquals(true, revBearerData.userAckReq);
-        assertEquals(false, revBearerData.deliveryAckReq);
-        assertEquals(false, revBearerData.readAckReq);
-        assertEquals(false, revBearerData.reportReq);
-        bearerData.userAckReq = false;
-        bearerData.deliveryAckReq = true;
-        encodedSms = BearerData.encode(bearerData);
-        revBearerData = BearerData.decode(encodedSms);
-        assertEquals(false, revBearerData.userAckReq);
-        assertEquals(true, revBearerData.deliveryAckReq);
-        assertEquals(false, revBearerData.readAckReq);
-        assertEquals(false, revBearerData.reportReq);
-        bearerData.deliveryAckReq = false;
-        bearerData.readAckReq = true;
-        encodedSms = BearerData.encode(bearerData);
-        revBearerData = BearerData.decode(encodedSms);
-        assertEquals(false, revBearerData.userAckReq);
-        assertEquals(false, revBearerData.deliveryAckReq);
-        assertEquals(true, revBearerData.readAckReq);
-        assertEquals(false, revBearerData.reportReq);
-        bearerData.readAckReq = false;
-        bearerData.reportReq = true;
-        encodedSms = BearerData.encode(bearerData);
-        revBearerData = BearerData.decode(encodedSms);
-        assertEquals(false, revBearerData.userAckReq);
-        assertEquals(false, revBearerData.deliveryAckReq);
-        assertEquals(false, revBearerData.readAckReq);
-        assertEquals(true, revBearerData.reportReq);
-    }
-
-    @SmallTest
-    public void testNumberOfMessages() throws Exception {
-        // Note that the message text below does not properly reflect
-        // the message count.  The author of these messages was
-        // apparently unaware that the values are bcd encoded, and the
-        // values being tested against (not the ones in the message
-        // text) are actually correct.
-        String pdu1 = "000310409001124896a794e07595f69f199540ea759a0dc8e00b0163";
-        BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
-        assertEquals("Test Voice mail 99", bd1.userData.payloadStr);
-        assertEquals(63, bd1.numberOfMessages);
-        String pdu2 = "00031040900113489ea794e07595f69f199540ea759a0988c0600b0164";
-        BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2));
-        assertEquals("Test Voice mail 100", bd2.userData.payloadStr);
-        assertEquals(64, bd2.numberOfMessages);
-    }
-
-    @SmallTest
-    public void testCallbackNum() throws Exception {
-        String pdu1 = "00031040900112488ea794e070d436cb638bc5e035ce2f97900e06910431323334";
-        BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
-        assertEquals("Test Callback nbr", bd1.userData.payloadStr);
-        assertEquals(CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR, bd1.callbackNumber.digitMode);
-        assertEquals(CdmaSmsAddress.TON_INTERNATIONAL_OR_IP, bd1.callbackNumber.ton);
-        assertEquals(CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK, bd1.callbackNumber.numberMode);
-        assertEquals(CdmaSmsAddress.NUMBERING_PLAN_ISDN_TELEPHONY, bd1.callbackNumber.numberPlan);
-        assertEquals("1234", bd1.callbackNumber.address);
-    }
-
-    @SmallTest
-    public void testCallbackNumDtmf() throws Exception {
-        String pdu1 = "00031002300109104539b4d052ebb3d00e07052d4c90a55080";
-        BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
-        assertEquals("SMS Rulz", bd1.userData.payloadStr);
-        assertEquals(CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF, bd1.callbackNumber.digitMode);
-        assertEquals(CdmaSmsAddress.TON_UNKNOWN, bd1.callbackNumber.ton);
-        assertEquals(CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK, bd1.callbackNumber.numberMode);
-        assertEquals(CdmaSmsAddress.NUMBERING_PLAN_UNKNOWN, bd1.callbackNumber.numberPlan);
-        assertEquals("5099214001", bd1.callbackNumber.address);
-    }
-
-    @SmallTest
-    public void testCallbackNumFeedback() throws Exception {
-        BearerData bearerData = new BearerData();
-        bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
-        bearerData.messageId = 0;
-        bearerData.hasUserDataHeader = false;
-        UserData userData = new UserData();
-        userData.payloadStr = "test callback number";
-        bearerData.userData = userData;
-        CdmaSmsAddress addr = new CdmaSmsAddress();
-        addr.digitMode = CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR;
-        addr.ton = CdmaSmsAddress.TON_NATIONAL_OR_EMAIL;
-        addr.numberMode = CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK;
-        addr.numberPlan = CdmaSmsAddress.NUMBERING_PLAN_UNKNOWN;
-        addr.address = "8005551212";
-        addr.numberOfDigits = (byte)addr.address.length();
-        bearerData.callbackNumber = addr;
-        byte []encodedSms = BearerData.encode(bearerData);
-        BearerData revBearerData = BearerData.decode(encodedSms);
-        CdmaSmsAddress revAddr = revBearerData.callbackNumber;
-        assertEquals(addr.digitMode, revAddr.digitMode);
-        assertEquals(addr.ton, revAddr.ton);
-        assertEquals(addr.numberMode, revAddr.numberMode);
-        assertEquals(addr.numberPlan, revAddr.numberPlan);
-        assertEquals(addr.numberOfDigits, revAddr.numberOfDigits);
-        assertEquals(addr.address, revAddr.address);
-        addr.address = "8*55#1012";
-        addr.numberOfDigits = (byte)addr.address.length();
-        addr.digitMode = CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF;
-        encodedSms = BearerData.encode(bearerData);
-        revBearerData = BearerData.decode(encodedSms);
-        revAddr = revBearerData.callbackNumber;
-        assertEquals(addr.digitMode, revAddr.digitMode);
-        assertEquals(addr.numberOfDigits, revAddr.numberOfDigits);
-        assertEquals(addr.address, revAddr.address);
-    }
-
-    @SmallTest
-    public void testPrivacyIndicator() throws Exception {
-        String pdu1 = "0003104090010c485f4194dfea34becf61b840090140";
-        BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
-        assertEquals(bd1.privacy, BearerData.PRIVACY_RESTRICTED);
-        String pdu2 = "0003104090010c485f4194dfea34becf61b840090180";
-        BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2));
-        assertEquals(bd2.privacy, BearerData.PRIVACY_CONFIDENTIAL);
-        String pdu3 = "0003104090010c485f4194dfea34becf61b8400901c0";
-        BearerData bd3 = BearerData.decode(HexDump.hexStringToByteArray(pdu3));
-        assertEquals(bd3.privacy, BearerData.PRIVACY_SECRET);
-    }
-
-    @SmallTest
-    public void testPrivacyIndicatorFeedback() throws Exception {
-        BearerData bearerData = new BearerData();
-        bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
-        bearerData.messageId = 0;
-        bearerData.hasUserDataHeader = false;
-        UserData userData = new UserData();
-        userData.payloadStr = "test privacy indicator";
-        bearerData.userData = userData;
-        bearerData.privacy = BearerData.PRIVACY_SECRET;
-        bearerData.privacyIndicatorSet = true;
-        byte []encodedSms = BearerData.encode(bearerData);
-        BearerData revBearerData = BearerData.decode(encodedSms);
-        assertEquals(revBearerData.userData.payloadStr, userData.payloadStr);
-        assertEquals(revBearerData.privacyIndicatorSet, true);
-        assertEquals(revBearerData.privacy, BearerData.PRIVACY_SECRET);
-        bearerData.privacy = BearerData.PRIVACY_RESTRICTED;
-        encodedSms = BearerData.encode(bearerData);
-        revBearerData = BearerData.decode(encodedSms);
-        assertEquals(revBearerData.privacy, BearerData.PRIVACY_RESTRICTED);
-    }
-
-    @SmallTest
-    public void testMsgDeliveryAlert() throws Exception {
-        String pdu1 = "0003104090010d4866a794e07055965b91d040300c0100";
-        BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
-        assertEquals(bd1.alert, 0);
-        assertEquals(bd1.userData.payloadStr, "Test Alert 0");
-        String pdu2 = "0003104090010d4866a794e07055965b91d140300c0140";
-        BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2));
-        assertEquals(bd2.alert, 1);
-        assertEquals(bd2.userData.payloadStr, "Test Alert 1");
-        String pdu3 = "0003104090010d4866a794e07055965b91d240300c0180";
-        BearerData bd3 = BearerData.decode(HexDump.hexStringToByteArray(pdu3));
-        assertEquals(bd3.alert, 2);
-        assertEquals(bd3.userData.payloadStr, "Test Alert 2");
-        String pdu4 = "0003104090010d4866a794e07055965b91d340300c01c0";
-        BearerData bd4 = BearerData.decode(HexDump.hexStringToByteArray(pdu4));
-        assertEquals(bd4.alert, 3);
-        assertEquals(bd4.userData.payloadStr, "Test Alert 3");
-        String pdu5 = "00031000000126114F4CBCFA20DB979F3C39F2A0C9976" +
-            "69ED979794187665E5D1028EFA7A6840E1062D3D39A900C028000";
-        BearerData bd5 = BearerData.decode(HexDump.hexStringToByteArray(pdu5));
-        assertEquals(bd5.alert, BearerData.ALERT_MEDIUM_PRIO);
-        assertEquals(bd5.userData.payloadStr, "test message delivery alert (with 8 bits)");
-        String pdu6 = "00031000000126114F4CBCFA20DB979F3C39F2A0C9976" +
-            "69ED979794187665E5D1028EFA7A6840C1062D3D39A900C00";
-        BearerData bd6 = BearerData.decode(HexDump.hexStringToByteArray(pdu6));
-        assertEquals(bd6.userData.payloadStr, "test message delivery alert (with 0 bits)");
-        assertEquals(bd6.alertIndicatorSet, false);
-    }
-
-    @SmallTest
-    public void testMiscParams() throws Exception {
-        String pdu1 = "00031002400109104539b4d052ebb3d00c0180";
-        BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
-        assertEquals(bd1.alert, BearerData.ALERT_MEDIUM_PRIO);
-        assertEquals(bd1.userData.payloadStr, "SMS Rulz");
-        String pdu2 = "00031002500109104539b4d052ebb3d00801800901c0";
-        BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2));
-        assertEquals(bd2.priority, BearerData.PRIORITY_URGENT);
-        assertEquals(bd2.privacy, BearerData.PRIVACY_SECRET);
-        assertEquals(bd2.userData.payloadStr, "SMS Rulz");
-        String pdu3 = "00031002600109104539b4d052ebb3d00901400c01c0";
-        BearerData bd3 = BearerData.decode(HexDump.hexStringToByteArray(pdu3));
-        assertEquals(bd3.privacy, BearerData.PRIVACY_RESTRICTED);
-        assertEquals(bd3.alert, BearerData.ALERT_HIGH_PRIO);
-        assertEquals(bd3.userData.payloadStr, "SMS Rulz");
-        String pdu4 = "00031002700109104539b4d052ebb3d00f0105";
-        BearerData bd4 = BearerData.decode(HexDump.hexStringToByteArray(pdu4));
-        assertEquals(bd4.displayMode, BearerData.DISPLAY_MODE_IMMEDIATE);
-        assertEquals(bd4.userData.payloadStr, "SMS Rulz");
-    }
-   @SmallTest
-    public void testMsgDeliveryAlertFeedback() throws Exception {
-        BearerData bearerData = new BearerData();
-        bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
-        bearerData.messageId = 0;
-        bearerData.hasUserDataHeader = false;
-        UserData userData = new UserData();
-        userData.payloadStr = "test message delivery alert";
-        bearerData.userData = userData;
-        bearerData.alert = BearerData.ALERT_MEDIUM_PRIO;
-        bearerData.alertIndicatorSet = true;
-        byte []encodedSms = BearerData.encode(bearerData);
-        BearerData revBearerData = BearerData.decode(encodedSms);
-        assertEquals(revBearerData.userData.payloadStr, userData.payloadStr);
-        assertEquals(revBearerData.alertIndicatorSet, true);
-        assertEquals(revBearerData.alert, bearerData.alert);
-        bearerData.alert = BearerData.ALERT_HIGH_PRIO;
-        encodedSms = BearerData.encode(bearerData);
-        revBearerData = BearerData.decode(encodedSms);
-        assertEquals(revBearerData.userData.payloadStr, userData.payloadStr);
-        assertEquals(revBearerData.alertIndicatorSet, true);
-        assertEquals(revBearerData.alert, bearerData.alert);
-    }
-
-    @SmallTest
-    public void testLanguageIndicator() throws Exception {
-        String pdu1 = "0003104090011748bea794e0731436ef3bd7c2e0352eef27a1c263fe58080d0101";
-        BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
-        assertEquals(bd1.userData.payloadStr, "Test Language indicator");
-        assertEquals(bd1.language, BearerData.LANGUAGE_ENGLISH);
-        String pdu2 = "0003104090011748bea794e0731436ef3bd7c2e0352eef27a1c263fe58080d0106";
-        BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2));
-        assertEquals(bd2.userData.payloadStr, "Test Language indicator");
-        assertEquals(bd2.language, BearerData.LANGUAGE_CHINESE);
-    }
-
-    @SmallTest
-    public void testLanguageIndicatorFeedback() throws Exception {
-        BearerData bearerData = new BearerData();
-        bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
-        bearerData.messageId = 0;
-        bearerData.hasUserDataHeader = false;
-        UserData userData = new UserData();
-        userData.payloadStr = "test language indicator";
-        bearerData.userData = userData;
-        bearerData.language = BearerData.LANGUAGE_ENGLISH;
-        bearerData.languageIndicatorSet = true;
-        byte []encodedSms = BearerData.encode(bearerData);
-        BearerData revBearerData = BearerData.decode(encodedSms);
-        assertEquals(revBearerData.userData.payloadStr, userData.payloadStr);
-        assertEquals(revBearerData.languageIndicatorSet, true);
-        assertEquals(revBearerData.language, bearerData.language);
-        bearerData.language = BearerData.LANGUAGE_KOREAN;
-        encodedSms = BearerData.encode(bearerData);
-        revBearerData = BearerData.decode(encodedSms);
-        assertEquals(revBearerData.userData.payloadStr, userData.payloadStr);
-        assertEquals(revBearerData.languageIndicatorSet, true);
-        assertEquals(revBearerData.language, bearerData.language);
-    }
-
-    @SmallTest
-    public void testDisplayMode() throws Exception {
-        String pdu1 = "0003104090010c485f4194dfea34becf61b8400f0100";
-        BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
-        assertEquals(bd1.displayMode, BearerData.DISPLAY_MODE_IMMEDIATE);
-        String pdu2 = "0003104090010c485f4194dfea34becf61b8400f0140";
-        BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2));
-        assertEquals(bd2.displayMode, BearerData.DISPLAY_MODE_DEFAULT);
-        String pdu3 = "0003104090010c485f4194dfea34becf61b8400f0180";
-        BearerData bd3 = BearerData.decode(HexDump.hexStringToByteArray(pdu3));
-        assertEquals(bd3.displayMode, BearerData.DISPLAY_MODE_USER);
-    }
-
-    @SmallTest
-    public void testDisplayModeFeedback() throws Exception {
-        BearerData bearerData = new BearerData();
-        bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
-        bearerData.messageId = 0;
-        bearerData.hasUserDataHeader = false;
-        UserData userData = new UserData();
-        userData.payloadStr = "test display mode";
-        bearerData.userData = userData;
-        bearerData.displayMode = BearerData.DISPLAY_MODE_IMMEDIATE;
-        bearerData.displayModeSet = true;
-        byte []encodedSms = BearerData.encode(bearerData);
-        BearerData revBearerData = BearerData.decode(encodedSms);
-        assertEquals(revBearerData.userData.payloadStr, userData.payloadStr);
-        assertEquals(revBearerData.displayModeSet, true);
-        assertEquals(revBearerData.displayMode, bearerData.displayMode);
-        bearerData.displayMode = BearerData.DISPLAY_MODE_USER;
-        encodedSms = BearerData.encode(bearerData);
-        revBearerData = BearerData.decode(encodedSms);
-        assertEquals(revBearerData.userData.payloadStr, userData.payloadStr);
-        assertEquals(revBearerData.displayModeSet, true);
-        assertEquals(revBearerData.displayMode, bearerData.displayMode);
-    }
-
-    @SmallTest
-    public void testIs91() throws Exception {
-        String pdu1 = "000320001001070c2039acc13880";
-        BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
-        assertEquals(bd1.callbackNumber.address, "3598271");
-        String pdu4 = "000320001001080c283c314724b34e";
-        BearerData bd4 = BearerData.decode(HexDump.hexStringToByteArray(pdu4));
-        assertEquals(bd4.userData.payloadStr, "ABCDEFG");
-    }
-
-    @SmallTest
-    public void testUserDataHeaderWithEightCharMsg() throws Exception {
-        encodeDecodeAssertEquals("01234567", 2, 2, false);
-    }
-
-    private void encodeDecodeAssertEquals(String payload, int index, int total,
-            boolean oddLengthHeader) throws Exception {
-        BearerData bearerData = new BearerData();
-        bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
-        bearerData.messageId = 55;
-        SmsHeader smsHeader = new SmsHeader();
-        if (oddLengthHeader) {
-            // Odd length header to verify correct UTF-16 header padding
-            SmsHeader.MiscElt miscElt = new SmsHeader.MiscElt();
-            miscElt.id = 0x27;  // reserved for future use; ignored on decode
-            miscElt.data = new byte[]{0x12, 0x34};
-            smsHeader.miscEltList.add(miscElt);
-        } else {
-            // Even length header normally generated for concatenated SMS.
-            SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
-            concatRef.refNumber = 0xEE;
-            concatRef.msgCount = total;
-            concatRef.seqNumber = index;
-            concatRef.isEightBits = true;
-            smsHeader.concatRef = concatRef;
-        }
-        byte[] encodeHeader = SmsHeader.toByteArray(smsHeader);
-        if (oddLengthHeader) {
-            assertEquals(4, encodeHeader.length);     // 5 bytes with UDH length
-        } else {
-            assertEquals(5, encodeHeader.length);     // 6 bytes with UDH length
-        }
-        UserData userData = new UserData();
-        userData.payloadStr = payload;
-        userData.userDataHeader = smsHeader;
-        bearerData.userData = userData;
-        byte[] encodedSms = BearerData.encode(bearerData);
-        BearerData revBearerData = BearerData.decode(encodedSms);
-        assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
-        assertTrue(revBearerData.hasUserDataHeader);
-        byte[] header = SmsHeader.toByteArray(revBearerData.userData.userDataHeader);
-        if (oddLengthHeader) {
-            assertEquals(4, header.length);     // 5 bytes with UDH length
-        } else {
-            assertEquals(5, header.length);     // 6 bytes with UDH length
-        }
-        assertTrue(Arrays.equals(encodeHeader, header));
-    }
-
-    @SmallTest
-    public void testFragmentText() throws Exception {
-        boolean isCdmaPhone = (TelephonyManager.getDefault().getPhoneType() ==
-                TelephonyManager.PHONE_TYPE_CDMA);
-        // Valid 160 character ASCII text.
-        String text1 = "123456789012345678901234567890123456789012345678901234567890" +
-                "1234567890123456789012345678901234567890123456789012345678901234567890" +
-                "12345678901234567890123456789[";
-        TextEncodingDetails ted = SmsMessage.calculateLength(text1, false);
-        assertEquals(ted.msgCount, 1);
-        assertEquals(ted.codeUnitCount, 160);
-        assertEquals(ted.codeUnitSize, 1);
-        if (isCdmaPhone) {
-            ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text1);
-            assertEquals(fragments.size(), 1);
-        }
-
-        /*
-           This is not a valid test: we will never encode a single-segment
-           EMS message.  Leaving this here, since we may try to support
-           this in the future.
-
-        // Valid 160 character GSM text -- the last character is
-        // non-ASCII, and so this will currently generate a singleton
-        // EMS message, which is not necessarily supported by Verizon.
-        String text2 = "123456789012345678901234567890123456789012345678901234567890" +
-                "1234567890123456789012345678901234567890123456789012345678901234567890" +
-                "12345678901234567890123456789\u00a3";  // Trailing pound-currency sign.
-        ted = SmsMessage.calculateLength(text2, false);
-        assertEquals(ted.msgCount, 1);
-        assertEquals(ted.codeUnitCount, 160);
-        assertEquals(ted.codeUnitSize, 1);
-        if (isCdmaPhone) {
-            ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text2);
-            assertEquals(fragments.size(), 1);
-        }
-        */
-
-        // *IF* we supported single-segment EMS, this text would result in a
-        // single fragment with 7-bit encoding. But we don't, so this text
-        // results in three fragments of 16-bit encoding.
-        String text2 = "123456789012345678901234567890123456789012345678901234567890" +
-                "1234567890123456789012345678901234567890123456789012345678901234567890" +
-                "12345678901234567890123456789\u00a3";  // Trailing pound-currency sign.
-        ted = SmsMessage.calculateLength(text2, false);
-        assertEquals(3, ted.msgCount);
-        assertEquals(160, ted.codeUnitCount);
-        assertEquals(3, ted.codeUnitSize);
-        if (isCdmaPhone) {
-            ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text2);
-            assertEquals(3, fragments.size());
-
-            for (int i = 0; i < 3; i++) {
-                encodeDecodeAssertEquals(fragments.get(i), i + 1, 3, false);
-                encodeDecodeAssertEquals(fragments.get(i), i + 1, 3, true);
-            }
-        }
-
-        // Test case for multi-part UTF-16 message.
-        String text3 = sUnicodeChars + sUnicodeChars + sUnicodeChars;
-        ted = SmsMessage.calculateLength(text3, false);
-        assertEquals(3, ted.msgCount);
-        assertEquals(189, ted.codeUnitCount);
-        assertEquals(3, ted.codeUnitSize);
-        if (isCdmaPhone) {
-            ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text3);
-            assertEquals(3, fragments.size());
-
-            for (int i = 0; i < 3; i++) {
-                encodeDecodeAssertEquals(fragments.get(i), i + 1, 3, false);
-                encodeDecodeAssertEquals(fragments.get(i), i + 1, 3, true);
-            }
-        }
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMPhoneTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMPhoneTest.java
deleted file mode 100644
index 485542b..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMPhoneTest.java
+++ /dev/null
@@ -1,1932 +0,0 @@
-/*
- * 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 GSMTestHandler.ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.gsm;
-
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.telephony.ServiceState;
-import android.test.AndroidTestCase;
-import android.test.PerformanceTestCase;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallStateException;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.MmiCode;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.gsm.CallFailCause;
-import com.android.internal.telephony.gsm.GSMPhone;
-import com.android.internal.telephony.gsm.GSMTestHandler;
-import com.android.internal.telephony.gsm.GsmMmiCode;
-import com.android.internal.telephony.gsm.SuppServiceNotification;
-import com.android.internal.telephony.test.SimulatedRadioControl;
-
-import java.util.List;
-
-
-public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase {
-    private SimulatedRadioControl mRadioControl;
-    private GSMPhone mGSMPhone;
-    private GSMTestHandler mGSMTestHandler;
-    private Handler mHandler;
-
-    private static final int EVENT_PHONE_STATE_CHANGED = 1;
-    private static final int EVENT_DISCONNECT = 2;
-    private static final int EVENT_RINGING = 3;
-    private static final int EVENT_CHANNEL_OPENED = 4;
-    private static final int EVENT_POST_DIAL = 5;
-    private static final int EVENT_DONE = 6;
-    private static final int EVENT_SSN = 7;
-    private static final int EVENT_MMI_INITIATE = 8;
-    private static final int EVENT_MMI_COMPLETE = 9;
-    private static final int EVENT_IN_SERVICE = 10;
-    private static final int SUPP_SERVICE_FAILED = 11;
-    private static final int SERVICE_STATE_CHANGED = 12;
-    private static final int EVENT_OEM_RIL_MESSAGE = 13;
-    public static final int ANY_MESSAGE = -1;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mGSMTestHandler = new GSMTestHandler(mContext);
-
-        mGSMTestHandler.start();
-        synchronized (mGSMTestHandler) {
-            do {
-                mGSMTestHandler.wait();
-            } while (mGSMTestHandler.getGSMPhone() == null);
-        }
-
-        mGSMPhone = mGSMTestHandler.getGSMPhone();
-        mRadioControl = mGSMTestHandler.getSimulatedCommands();
-
-        mHandler = mGSMTestHandler.getHandler();
-        mGSMPhone.registerForPreciseCallStateChanged(mHandler, EVENT_PHONE_STATE_CHANGED, null);
-        mGSMPhone.registerForNewRingingConnection(mHandler, EVENT_RINGING, null);
-        mGSMPhone.registerForDisconnect(mHandler, EVENT_DISCONNECT, null);
-
-        mGSMPhone.setOnPostDialCharacter(mHandler, EVENT_POST_DIAL, null);
-
-        mGSMPhone.registerForSuppServiceNotification(mHandler, EVENT_SSN, null);
-        mGSMPhone.registerForMmiInitiate(mHandler, EVENT_MMI_INITIATE, null);
-        mGSMPhone.registerForMmiComplete(mHandler, EVENT_MMI_COMPLETE, null);
-        mGSMPhone.registerForSuppServiceFailed(mHandler, SUPP_SERVICE_FAILED, null);
-
-        mGSMPhone.registerForServiceStateChanged(mHandler, SERVICE_STATE_CHANGED, null);
-
-        // wait until we get phone in both voice and data service
-        Message msg;
-        ServiceState state;
-
-        do {
-            msg = mGSMTestHandler.waitForMessage(SERVICE_STATE_CHANGED);
-            assertNotNull("Message Time Out", msg);
-            state = (ServiceState) ((AsyncResult) msg.obj).result;
-        } while (state.getState() != ServiceState.STATE_IN_SERVICE);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mRadioControl.shutdown();
-
-        mGSMPhone.unregisterForPreciseCallStateChanged(mHandler);
-        mGSMPhone.unregisterForNewRingingConnection(mHandler);
-        mGSMPhone.unregisterForDisconnect(mHandler);
-        mGSMPhone.setOnPostDialCharacter(mHandler, 0, null);
-        mGSMPhone.unregisterForSuppServiceNotification(mHandler);
-        mGSMPhone.unregisterForMmiInitiate(mHandler);
-        mGSMPhone.unregisterForMmiComplete(mHandler);
-
-        mGSMPhone = null;
-        mRadioControl = null;
-        mHandler = null;
-        mGSMTestHandler.cleanup();
-
-        super.tearDown();
-    }
-
-    // These test can only be run once.
-    public int startPerformance(Intermediates intermediates) {
-        return 1;
-    }
-
-    public boolean isPerformanceOnly() {
-        return false;
-    }
-
-
-    //This test is causing the emulator screen to turn off. I don't understand
-    //why, but I'm removing it until we can figure it out.
-    public void brokenTestGeneral() throws Exception {
-        Connection cn;
-        Message msg;
-        AsyncResult ar;
-
-        // IDLE state
-
-        assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-        assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
-        assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime());
-        assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-        assertFalse(mGSMPhone.canConference());
-
-        // One DIALING connection
-
-        mRadioControl.setAutoProgressConnectingCall(false);
-
-        mGSMPhone.dial("+13125551212");
-
-        assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_PHONE_STATE_CHANGED);
-        assertNotNull("Message Time Out", msg);
-
-        assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
-        assertEquals(Call.State.DIALING, mGSMPhone.getForegroundCall().getState());
-        assertTrue(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
-        /*do {
-            mGSMTestHandler.waitForMessage(ANY_MESSAGE);
-        } while (mGSMPhone.getForegroundCall().getConnections().size() == 0);*/
-
-        assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
-        assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
-        assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.DIALING,
-                mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
-        assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
-        cn = mGSMPhone.getForegroundCall().getConnections().get(0);
-        assertTrue(!cn.isIncoming());
-        assertEquals(Connection.PostDialState.NOT_STARTED, cn.getPostDialState());
-
-        assertEquals(Connection.DisconnectCause.NOT_DISCONNECTED, cn.getDisconnectCause());
-
-        assertFalse(mGSMPhone.canConference());
-
-        // One ALERTING connection
-
-        mRadioControl.progressConnectingCallState();
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        }
-        while (mGSMPhone.getForegroundCall().getState() != Call.State.ALERTING);
-
-        assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
-        assertTrue(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
-        assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
-        assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
-        assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.ALERTING, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
-        assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
-        cn = mGSMPhone.getForegroundCall().getConnections().get(0);
-        assertTrue(!cn.isIncoming());
-        assertEquals(Connection.PostDialState.NOT_STARTED, cn.getPostDialState());
-        assertFalse(mGSMPhone.canConference());
-
-        // One ACTIVE connection
-
-        mRadioControl.progressConnectingCallState();
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
-        assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
-        assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
-        assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
-        assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
-        assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
-        assertTrue(mGSMPhone.getForegroundCall().getEarliestConnectTime() > 0);
-
-        cn = mGSMPhone.getForegroundCall().getConnections().get(0);
-        assertTrue(!cn.isIncoming());
-        assertEquals(Connection.PostDialState.COMPLETE, cn.getPostDialState());
-        assertFalse(mGSMPhone.canConference());
-
-        // One disconnected connection
-        mGSMPhone.getForegroundCall().hangup();
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
-        assertNotNull("Message Time Out", msg);
-
-        assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-        assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
-        assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
-        assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
-        assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
-        assertTrue(mGSMPhone.getForegroundCall().getEarliestConnectTime() > 0);
-
-        assertFalse(mGSMPhone.canConference());
-
-        cn = mGSMPhone.getForegroundCall().getEarliestConnection();
-
-        assertEquals(Call.State.DISCONNECTED, cn.getState());
-
-        // Back to idle state
-
-        mGSMPhone.clearDisconnected();
-
-        assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-        assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
-        assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
-        assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime());
-        assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
-        assertFalse(mGSMPhone.canConference());
-
-        // cn left over from before phone.clearDisconnected();
-
-        assertEquals(Call.State.DISCONNECTED, cn.getState());
-
-        // One ringing (INCOMING) call
-
-        mRadioControl.triggerRing("18005551212");
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_RINGING);
-        assertNotNull("Message Time Out", msg);
-
-        assertEquals(Phone.State.RINGING, mGSMPhone.getState());
-        assertTrue(mGSMPhone.getRingingCall().isRinging());
-
-        ar = (AsyncResult) msg.obj;
-        cn = (Connection) ar.result;
-        assertTrue(cn.isRinging());
-        assertEquals(mGSMPhone.getRingingCall(), cn.getCall());
-
-        assertEquals(1, mGSMPhone.getRingingCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
-        assertEquals(Call.State.INCOMING, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        assertTrue(mGSMPhone.getRingingCall().getEarliestCreateTime() > 0);
-        assertEquals(0, mGSMPhone.getRingingCall().getEarliestConnectTime());
-
-        assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime());
-        assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
-        cn = mGSMPhone.getRingingCall().getConnections().get(0);
-        assertTrue(cn.isIncoming());
-        assertEquals(Connection.PostDialState.NOT_STARTED, cn.getPostDialState());
-
-        assertFalse(mGSMPhone.canConference());
-
-        // One mobile terminated active call
-        mGSMPhone.acceptCall();
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getRingingCall().getConnections().size() == 1);
-
-        assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
-        assertFalse(mGSMPhone.getRingingCall().isRinging());
-
-        assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
-        assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
-        assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.ACTIVE,
-                mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
-        assertTrue(mGSMPhone.getForegroundCall().getEarliestConnectTime() > 0);
-
-        cn = mGSMPhone.getForegroundCall().getConnections().get(0);
-        assertTrue(cn.isIncoming());
-        assertEquals(Connection.PostDialState.NOT_STARTED, cn.getPostDialState());
-
-        assertFalse(mGSMPhone.canConference());
-
-        // One disconnected (local hangup) call
-
-        try {
-            Connection conn;
-            conn = mGSMPhone.getForegroundCall().getConnections().get(0);
-            conn.hangup();
-        } catch (CallStateException ex) {
-            ex.printStackTrace();
-            fail("unexpected ex");
-        }
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
-        assertNotNull("Message Time Out", msg);
-
-        assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-        assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-        assertFalse(mGSMPhone.getRingingCall().isRinging());
-
-        assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
-        assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
-        assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.DISCONNECTED,
-                mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
-        assertTrue(mGSMPhone.getForegroundCall().getEarliestConnectTime() > 0);
-
-        cn = mGSMPhone.getForegroundCall().getEarliestConnection();
-
-        assertEquals(Call.State.DISCONNECTED, cn.getState());
-
-        assertEquals(Connection.DisconnectCause.LOCAL, cn.getDisconnectCause());
-
-        assertFalse(mGSMPhone.canConference());
-
-        // Back to idle state
-
-        mGSMPhone.clearDisconnected();
-
-        assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-        assertFalse(mGSMPhone.getRingingCall().isRinging());
-
-        assertEquals(Connection.DisconnectCause.LOCAL, cn.getDisconnectCause());
-        assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
-        assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-
-        assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
-        assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime());
-        assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
-        assertFalse(mGSMPhone.canConference());
-
-        // cn left over from before phone.clearDisconnected();
-
-        assertEquals(Call.State.DISCONNECTED, cn.getState());
-
-        // One ringing call
-
-        mRadioControl.triggerRing("18005551212");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getRingingCall().getConnections().isEmpty());
-
-        assertEquals(Phone.State.RINGING, mGSMPhone.getState());
-        assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-        assertTrue(mGSMPhone.getRingingCall().isRinging());
-
-        assertEquals(1, mGSMPhone.getRingingCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
-        assertEquals(Call.State.INCOMING, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        assertTrue(mGSMPhone.getRingingCall().getEarliestCreateTime() > 0);
-        assertEquals(0, mGSMPhone.getRingingCall().getEarliestConnectTime());
-
-        assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime());
-        assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
-        assertFalse(mGSMPhone.canConference());
-
-        // One rejected call
-        mGSMPhone.rejectCall();
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getState() != Phone.State.IDLE);
-
-        assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-        assertFalse(mGSMPhone.getRingingCall().isRinging());
-
-        assertEquals(1, mGSMPhone.getRingingCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
-        assertEquals(Call.State.DISCONNECTED, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        assertTrue(mGSMPhone.getRingingCall().getEarliestCreateTime() > 0);
-        assertEquals(0, mGSMPhone.getRingingCall().getEarliestConnectTime());
-
-        assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime());
-        assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
-        cn = mGSMPhone.getRingingCall().getEarliestConnection();
-        assertEquals(Call.State.DISCONNECTED, cn.getState());
-
-        assertEquals(Connection.DisconnectCause.INCOMING_MISSED, cn.getDisconnectCause());
-
-        assertFalse(mGSMPhone.canConference());
-
-        // Back to idle state
-
-        mGSMPhone.clearDisconnected();
-
-        assertEquals(Connection.DisconnectCause.INCOMING_MISSED, cn.getDisconnectCause());
-        assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
-        assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-
-        assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
-        assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime());
-        assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
-        assertFalse(mGSMPhone.canConference());
-        assertEquals(Call.State.DISCONNECTED, cn.getState());
-
-        // One ringing call
-
-        mRadioControl.triggerRing("18005551212");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getRingingCall().getConnections().isEmpty());
-
-        assertEquals(Phone.State.RINGING, mGSMPhone.getState());
-        assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-        assertTrue(mGSMPhone.getRingingCall().isRinging());
-
-        cn = mGSMPhone.getRingingCall().getEarliestConnection();
-
-        // Ringing call disconnects
-
-        mRadioControl.triggerHangupForeground();
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getState() != Phone.State.IDLE);
-
-        assertEquals(Connection.DisconnectCause.INCOMING_MISSED, cn.getDisconnectCause());
-
-        // One Ringing Call
-
-        mRadioControl.triggerRing("18005551212");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getState() != Phone.State.RINGING);
-
-
-        cn = mGSMPhone.getRingingCall().getEarliestConnection();
-
-        // One answered call
-        mGSMPhone.acceptCall();
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getState() != Phone.State.OFFHOOK);
-
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        // one holding call
-        mGSMPhone.switchHoldingAndActive();
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getBackgroundCall().getState() == Call.State.IDLE);
-
-
-        assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
-        // one active call
-        mGSMPhone.switchHoldingAndActive();
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        }
-        while (mGSMPhone.getBackgroundCall().getState() == Call.State.HOLDING);
-
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        // One disconnected call in the foreground slot
-
-        mRadioControl.triggerHangupAll();
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getState() != Phone.State.IDLE);
-
-        assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Connection.DisconnectCause.NORMAL, cn.getDisconnectCause());
-
-        // Test missed calls
-
-        mRadioControl.triggerRing("18005551212");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getState() != Phone.State.RINGING);
-
-        mGSMPhone.rejectCall();
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (msg.what != EVENT_DISCONNECT);
-
-        ar = (AsyncResult) msg.obj;
-        cn = (Connection) ar.result;
-
-        assertEquals(Connection.DisconnectCause.INCOMING_MISSED, cn.getDisconnectCause());
-        assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-        assertEquals(Call.State.DISCONNECTED, mGSMPhone.getRingingCall().getState());
-
-        // Test incoming not missed calls
-
-        mRadioControl.triggerRing("18005551212");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getState() != Phone.State.RINGING);
-
-        cn = mGSMPhone.getRingingCall().getEarliestConnection();
-
-        mGSMPhone.acceptCall();
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getState() != Phone.State.OFFHOOK);
-
-        assertEquals(Connection.DisconnectCause.NOT_DISCONNECTED, cn.getDisconnectCause());
-        assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-
-        try {
-            mGSMPhone.getForegroundCall().hangup();
-        } catch (CallStateException ex) {
-            ex.printStackTrace();
-            fail("unexpected ex");
-        }
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getForegroundCall().getState()
-                != Call.State.DISCONNECTED);
-
-        assertEquals(Connection.DisconnectCause.LOCAL, cn.getDisconnectCause());
-
-        //
-        // Test held and hangup held calls
-        //
-
-        // One ALERTING call
-        mGSMPhone.dial("+13125551212");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getState() != Phone.State.OFFHOOK);
-
-        assertTrue(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
-        mRadioControl.progressConnectingCallState();
-        mRadioControl.progressConnectingCallState();
-
-        // One ACTIVE call
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
-        assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
-        // One ACTIVE call, one ringing call
-
-        mRadioControl.triggerRing("18005551212");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getState() != Phone.State.RINGING);
-
-        assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-        assertTrue(mGSMPhone.getRingingCall().isRinging());
-
-        // One HOLDING call, one ACTIVE call
-        mGSMPhone.acceptCall();
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getState() != Phone.State.OFFHOOK);
-
-        assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
-        assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-        assertTrue(mGSMPhone.canConference());
-
-        // Conference the two
-        mGSMPhone.conference();
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
-
-        assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
-        assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertTrue(mGSMPhone.getForegroundCall().isMultiparty());
-        assertFalse(mGSMPhone.canConference());
-
-        // Hold the multiparty call
-        mGSMPhone.switchHoldingAndActive();
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        }
-        while (mGSMPhone.getBackgroundCall().getState() != Call.State.HOLDING);
-
-        assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
-        assertTrue(mGSMPhone.getBackgroundCall().isMultiparty());
-        assertFalse(mGSMPhone.canConference());
-
-        // Multiparty call on hold, call waiting added
-
-        mRadioControl.triggerRing("18005558355");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getState() != Phone.State.RINGING);
-
-        assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-        assertTrue(mGSMPhone.getRingingCall().isRinging());
-
-        assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-        assertTrue(mGSMPhone.getBackgroundCall().isMultiparty());
-        assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState());
-        assertFalse(mGSMPhone.canConference());
-
-        // Hangup conference call, ringing call still around
-        mGSMPhone.getBackgroundCall().hangup();
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getBackgroundCall().getState() != Call.State.DISCONNECTED);
-
-        assertEquals(Phone.State.RINGING, mGSMPhone.getState());
-        assertEquals(Call.State.DISCONNECTED, mGSMPhone.getBackgroundCall().getState());
-
-        assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-        assertTrue(mGSMPhone.getRingingCall().isRinging());
-
-        // Reject waiting call
-        mGSMPhone.rejectCall();
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getState() != Phone.State.IDLE);
-
-        assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-        assertFalse(mGSMPhone.getRingingCall().isRinging());
-    }
-
-    public void testOutgoingCallFailImmediately() throws Exception {
-        Message msg;
-
-        // Test outgoing call fail-immediately edge case
-        // This happens when a call terminated before ever appearing in a
-        // call list
-        // This should land the immediately-failing call in the
-        // ForegroundCall list as an IDLE call
-        mRadioControl.setNextDialFailImmediately(true);
-
-        Connection cn = mGSMPhone.dial("+13125551212");
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
-        assertNotNull("Message Time Out", msg);
-        assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-
-        assertEquals(Connection.DisconnectCause.NORMAL, cn.getDisconnectCause());
-
-        assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
-        assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
-        assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
-        assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-    }
-
-    public void testHangupOnOutgoing() throws Exception {
-        Connection cn;
-        Message msg;
-
-        mRadioControl.setAutoProgressConnectingCall(false);
-
-        // Test 1: local hangup in "DIALING" state
-        mGSMPhone.dial("+13125551212");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        }
-        while (mGSMPhone.getForegroundCall().getState() != Call.State.DIALING);
-
-        cn = mGSMPhone.getForegroundCall().getEarliestConnection();
-
-        mGSMPhone.getForegroundCall().hangup();
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
-        assertNotNull("Message Time Out", msg);
-        assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-
-        assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Connection.DisconnectCause.LOCAL, cn.getDisconnectCause());
-
-        // Test 2: local hangup in "ALERTING" state
-        mGSMPhone.dial("+13125551212");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getState() != Phone.State.OFFHOOK);
-
-        mRadioControl.progressConnectingCallState();
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        }
-        while (mGSMPhone.getForegroundCall().getState() != Call.State.ALERTING);
-
-        cn = mGSMPhone.getForegroundCall().getEarliestConnection();
-
-        mGSMPhone.getForegroundCall().hangup();
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
-        assertNotNull("Message Time Out", msg);
-
-        assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-
-        assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Connection.DisconnectCause.LOCAL, cn.getDisconnectCause());
-
-        // Test 3: local immediate hangup before GSM index is
-        // assigned (CallTracker.hangupPendingMO case)
-
-        mRadioControl.pauseResponses();
-
-        cn = mGSMPhone.dial("+13125551212");
-
-        cn.hangup();
-
-        mRadioControl.resumeResponses();
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
-        assertNotNull("Message Time Out", msg);
-        assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-
-        assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
-
-        assertEquals(Connection.DisconnectCause.LOCAL,
-                mGSMPhone.getForegroundCall().getEarliestConnection().getDisconnectCause());
-    }
-
-    public void testHangupOnChannelClose() throws Exception {
-        mGSMPhone.dial("+13125551212");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getForegroundCall().getConnections().isEmpty());
-
-        mRadioControl.shutdown();
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-            mGSMPhone.clearDisconnected();
-        } while (!mGSMPhone.getForegroundCall().getConnections().isEmpty());
-    }
-
-    public void testIncallMmiCallDeflection() throws Exception {
-        Message msg;
-
-        // establish an active call
-        mGSMPhone.dial("+13125551212");
-
-        do {
-            mRadioControl.progressConnectingCallState();
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        // establish a ringing (WAITING) call
-
-        mRadioControl.triggerRing("18005551212");
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_RINGING);
-        assertNotNull("Message Time Out", msg);
-
-        assertEquals(Phone.State.RINGING, mGSMPhone.getState());
-        assertTrue(mGSMPhone.getRingingCall().isRinging());
-        assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        // Simulate entering 0 followed by SEND: release all held calls
-        // or sets UDUB for a waiting call.
-        mGSMPhone.handleInCallMmiCommands("0");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getRingingCall().getState() == Call.State.WAITING);
-
-        assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
-        assertFalse(mGSMPhone.getRingingCall().isRinging());
-        assertEquals(Call.State.DISCONNECTED, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        // change the active call to holding call
-        mGSMPhone.switchHoldingAndActive();
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getBackgroundCall().getState() == Call.State.IDLE);
-
-
-        assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
-        // Simulate entering 0 followed by SEND: release all held calls
-        // or sets UDUB for a waiting call.
-        mGSMPhone.handleInCallMmiCommands("0");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getBackgroundCall().getState() == Call.State.HOLDING);
-
-        assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.DISCONNECTED, mGSMPhone.getBackgroundCall().getState());
-    }
-
-    public void testIncallMmiCallWaiting() throws Exception {
-        Message msg;
-
-        // establish an active call
-        mGSMPhone.dial("+13125551212");
-
-        do {
-            mRadioControl.progressConnectingCallState();
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        // establish a ringing (WAITING) call
-
-        mRadioControl.triggerRing("18005551212");
-
-        do {
-            msg = mGSMTestHandler.waitForMessage(ANY_MESSAGE);
-            assertNotNull("Message Time Out", msg);
-        } while (msg.what != EVENT_RINGING);
-
-        assertEquals(Phone.State.RINGING, mGSMPhone.getState());
-        assertTrue(mGSMPhone.getRingingCall().isRinging());
-        assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        // Simulate entering 1 followed by SEND: release all active calls
-        // (if any exist) and accepts the other (held or waiting) call.
-
-        mGSMPhone.handleInCallMmiCommands("1");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getRingingCall().getState() == Call.State.WAITING);
-
-        assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
-        assertFalse(mGSMPhone.getRingingCall().isRinging());
-        assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals("18005551212",
-                mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
-
-        // change the active call to holding call
-        mGSMPhone.switchHoldingAndActive();
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getBackgroundCall().getState() == Call.State.IDLE);
-
-        assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
-        // Simulate entering 1 followed by SEND: release all active calls
-        // (if any exist) and accepts the other (held or waiting) call.
-        mGSMPhone.handleInCallMmiCommands("1");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
-
-        assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-        assertEquals("18005551212",
-                mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
-
-        // at this point, the active call with number==18005551212 should
-        // have the gsm index of 2
-
-        mRadioControl.triggerRing("16505550100");
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_RINGING);
-        assertNotNull("Message Time Out", msg);
-
-        assertEquals(Phone.State.RINGING, mGSMPhone.getState());
-        assertTrue(mGSMPhone.getRingingCall().isRinging());
-        assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        // Simulate entering "12" followed by SEND: release the call with
-        // gsm index equals to 2.
-        mGSMPhone.handleInCallMmiCommands("12");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE);
-
-        assertEquals(Phone.State.RINGING, mGSMPhone.getState());
-        assertTrue(mGSMPhone.getRingingCall().isRinging());
-        assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        mGSMPhone.acceptCall();
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getState() != Phone.State.OFFHOOK);
-
-        assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
-        assertFalse(mGSMPhone.getRingingCall().isRinging());
-        assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        // at this point, the call with number==16505550100 should
-        // have the gsm index of 1
-        mGSMPhone.dial("+13125551212");
-
-        do {
-            mRadioControl.progressConnectingCallState();
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE ||
-                mGSMPhone.getBackgroundCall().getState() != Call.State.HOLDING);
-
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
-        // at this point, the active call with number==13125551212 should
-        // have the gsm index of 2
-
-        // Simulate entering "11" followed by SEND: release the call with
-        // gsm index equals to 1. This should not be allowed, and a
-        // Supplementary Service notification must be received.
-        mGSMPhone.handleInCallMmiCommands("11");
-
-        msg = mGSMTestHandler.waitForMessage(SUPP_SERVICE_FAILED);
-        assertNotNull("Message Time Out", msg);
-        assertFalse("IncallMmiCallWaiting: command should not work on holding call", msg == null);
-
-        // Simulate entering "12" followed by SEND: release the call with
-        // gsm index equals to 2.
-        mGSMPhone.handleInCallMmiCommands("12");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE);
-
-        assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
-        // Simulate entering 1 followed by SEND: release all active calls
-        // (if any exist) and accepts the other (held or waiting) call.
-        mGSMPhone.handleInCallMmiCommands("1");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
-
-        assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-        assertEquals("16505550100",
-                mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
-
-        // Simulate entering "11" followed by SEND: release the call with
-        // gsm index equals to 1.
-        mGSMPhone.handleInCallMmiCommands("11");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE);
-
-        assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-    }
-
-    public void testIncallMmiCallHold() throws Exception {
-        Message msg;
-
-        // establish an active call
-        mGSMPhone.dial("13125551212");
-
-        do {
-            mRadioControl.progressConnectingCallState();
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        // establish a ringing (WAITING) call
-
-        mRadioControl.triggerRing("18005551212");
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_RINGING);
-        assertNotNull("Message Time Out", msg);
-
-        assertEquals(Phone.State.RINGING, mGSMPhone.getState());
-        assertTrue(mGSMPhone.getRingingCall().isRinging());
-        assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        // simulate entering 2 followed by SEND: place all active calls
-        // (if any exist) on hold and accepts the other (held or waiting)
-        // call
-
-        mGSMPhone.handleInCallMmiCommands("2");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getRingingCall().getState() == Call.State.WAITING);
-
-
-        assertFalse(mGSMPhone.getRingingCall().isRinging());
-        assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.ACTIVE,
-                mGSMPhone.getForegroundCall().getState());
-        assertEquals("18005551212",
-                mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
-        assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-        assertEquals("13125551212",
-                mGSMPhone.getBackgroundCall().getConnections().get(0).getAddress());
-
-        // swap the active and holding calls
-        mGSMPhone.handleInCallMmiCommands("2");
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_PHONE_STATE_CHANGED);
-        assertNotNull("Message Time Out", msg);
-
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals("13125551212",
-                mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
-        assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-        assertEquals("18005551212",
-                mGSMPhone.getBackgroundCall().getConnections().get(0).getAddress());
-
-        // merge the calls
-        mGSMPhone.conference();
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
-
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-        assertEquals(2, mGSMPhone.getForegroundCall().getConnections().size());
-
-        // at this point, we have an active conference call, with
-        // call(1) = 13125551212 and call(2) = 18005551212
-
-        // Simulate entering "23" followed by SEND: places all active call
-        // on hold except call 3. This should fail and a supplementary service
-        // failed notification should be received.
-
-        mGSMPhone.handleInCallMmiCommands("23");
-
-        msg = mGSMTestHandler.waitForMessage(SUPP_SERVICE_FAILED);
-        assertNotNull("Message Time Out", msg);
-        assertFalse("IncallMmiCallHold: separate should have failed!", msg == null);
-
-        // Simulate entering "21" followed by SEND: places all active call
-        // on hold except call 1.
-        mGSMPhone.handleInCallMmiCommands("21");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getBackgroundCall().getState() == Call.State.IDLE);
-
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals("13125551212",
-                mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
-        assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-        assertEquals("18005551212",
-                mGSMPhone.getBackgroundCall().getConnections().get(0).getAddress());
-    }
-
-    public void testIncallMmiMultipartyServices() throws Exception {
-        // establish an active call
-        mGSMPhone.dial("13125551212");
-
-        do {
-            mRadioControl.progressConnectingCallState();
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        // dial another call
-        mGSMPhone.dial("18005551212");
-
-        do {
-            mRadioControl.progressConnectingCallState();
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
-        mGSMPhone.handleInCallMmiCommands("3");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
-
-        assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals("18005551212",
-                mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
-        assertEquals("13125551212",
-                mGSMPhone.getForegroundCall().getConnections().get(1).getAddress());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-    }
-
-    public void testCallIndex() throws Exception {
-        Message msg;
-
-        // establish the first call
-        mGSMPhone.dial("16505550100");
-
-        do {
-            mRadioControl.progressConnectingCallState();
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        String baseNumber = "1650555010";
-
-        for (int i = 1; i < 6; i++) {
-            String number = baseNumber + i;
-
-            mGSMPhone.dial(number);
-
-            do {
-                mRadioControl.progressConnectingCallState();
-                assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-            } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
-            assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-            assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
-            if (mGSMPhone.getBackgroundCall().getConnections().size() >= 5) {
-                break;
-            }
-
-            mGSMPhone.conference();
-
-            do {
-                assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-            } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
-
-            assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-            assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-        }
-
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals("16505550105",
-                mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
-        assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
-        // create an incoming call, this call should have the call index
-        // of 7
-        mRadioControl.triggerRing("18005551212");
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_RINGING);
-        assertNotNull("Message Time Out", msg);
-
-        assertEquals(Phone.State.RINGING, mGSMPhone.getState());
-        assertTrue(mGSMPhone.getRingingCall().isRinging());
-        assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
-        // hangup the background call and accept the ringing call
-        mGSMPhone.getBackgroundCall().hangup();
-        mGSMPhone.acceptCall();
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getRingingCall().getState() != Call.State.IDLE);
-
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals("18005551212",
-                mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
-        assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-        assertEquals("16505550105",
-                mGSMPhone.getBackgroundCall().getConnections().get(0).getAddress());
-
-        mGSMPhone.handleInCallMmiCommands("17");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE);
-
-        assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-        assertEquals("16505550105",
-                mGSMPhone.getBackgroundCall().getConnections().get(0).
-                        getAddress());
-
-        mGSMPhone.handleInCallMmiCommands("1");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
-        assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        mGSMPhone.handleInCallMmiCommands("16");
-
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE);
-
-        assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-    }
-
-    public void testPostDialSequences() throws Exception {
-        Message msg;
-        AsyncResult ar;
-        Connection cn;
-
-        mGSMPhone.dial("+13125551212,1234;5N8xx");
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
-        assertNotNull("Message Time Out", msg);
-        ar = (AsyncResult) (msg.obj);
-        cn = (Connection) (ar.result);
-        assertEquals(',', msg.arg1);
-        assertEquals("1234;5N8", cn.getRemainingPostDialString());
-
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
-        assertNotNull("Message Time Out", msg);
-        assertEquals('1', msg.arg1);
-        ar = (AsyncResult) (msg.obj);
-        assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
-        assertNotNull("Message Time Out", msg);
-        assertEquals('2', msg.arg1);
-        ar = (AsyncResult) (msg.obj);
-        assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
-        assertNotNull("Message Time Out", msg);
-        assertEquals('3', msg.arg1);
-        ar = (AsyncResult) (msg.obj);
-        assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
-        assertNotNull("Message Time Out", msg);
-        assertEquals('4', msg.arg1);
-        ar = (AsyncResult) (msg.obj);
-        assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
-        assertNotNull("Message Time Out", msg);
-        assertEquals(';', msg.arg1);
-        ar = (AsyncResult) (msg.obj);
-        cn = (Connection) (ar.result);
-        assertEquals(Connection.PostDialState.WAIT, cn.getPostDialState());
-        assertEquals(Connection.PostDialState.WAIT, ar.userObj);
-        cn.proceedAfterWaitChar();
-
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
-        assertNotNull("Message Time Out", msg);
-        assertEquals('5', msg.arg1);
-        ar = (AsyncResult) (msg.obj);
-        assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
-        assertEquals('N', msg.arg1);
-        ar = (AsyncResult) (msg.obj);
-        cn = (Connection) (ar.result);
-        assertEquals(Connection.PostDialState.WILD, cn.getPostDialState());
-        assertEquals(Connection.PostDialState.WILD, ar.userObj);
-        cn.proceedAfterWildChar(",6;7");
-
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
-        assertNotNull("Message Time Out", msg);
-        ar = (AsyncResult) (msg.obj);
-        cn = (Connection) (ar.result);
-        assertEquals(',', msg.arg1);
-        assertEquals("6;78", cn.getRemainingPostDialString());
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
-        assertNotNull("Message Time Out", msg);
-        assertEquals('6', msg.arg1);
-        ar = (AsyncResult) (msg.obj);
-        assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
-        assertNotNull("Message Time Out", msg);
-        assertEquals(';', msg.arg1);
-        ar = (AsyncResult) (msg.obj);
-        cn = (Connection) (ar.result);
-        assertEquals(Connection.PostDialState.WAIT, cn.getPostDialState());
-        assertEquals(Connection.PostDialState.WAIT, ar.userObj);
-        cn.proceedAfterWaitChar();
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
-        assertNotNull("Message Time Out", msg);
-        assertEquals('7', msg.arg1);
-        ar = (AsyncResult) (msg.obj);
-        assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
-        assertNotNull("Message Time Out", msg);
-        assertEquals('8', msg.arg1);
-        ar = (AsyncResult) (msg.obj);
-        assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
-        // Bogus chars at end should be ignored
-        msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
-        assertNotNull("Message Time Out", msg);
-        assertEquals(0, msg.arg1);
-        ar = (AsyncResult) (msg.obj);
-        cn = (Connection) (ar.result);
-        assertEquals(Connection.PostDialState.COMPLETE,
-                cn.getPostDialState());
-        assertEquals(Connection.PostDialState.COMPLETE, ar.userObj);
-    }
-
-    public void testPostDialCancel() throws Exception {
-        Message msg;
-        AsyncResult ar;
-        Connection cn;
-
-        mGSMPhone.dial("+13125551212,N");
-        mRadioControl.progressConnectingToActive();
-
-        mRadioControl.progressConnectingToActive();
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
-        assertNotNull("Message Time Out", msg);
-        assertEquals(',', msg.arg1);
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
-        assertEquals('N', msg.arg1);
-        ar = (AsyncResult) (msg.obj);
-        cn = (Connection) (ar.result);
-        assertEquals(Connection.PostDialState.WILD, cn.getPostDialState());
-        cn.cancelPostDial();
-
-        assertEquals(Connection.PostDialState.CANCELLED, cn.getPostDialState());
-    }
-
-    public void testOutgoingCallFail() throws Exception {
-        Message msg;
-        /*
-        * normal clearing
-        */
-
-        mRadioControl.setNextCallFailCause(CallFailCause.NORMAL_CLEARING);
-        mRadioControl.setAutoProgressConnectingCall(false);
-
-        Connection cn = mGSMPhone.dial("+13125551212");
-
-        mRadioControl.progressConnectingCallState();
-
-        // I'm just progressing the call state to
-        // ensure getCurrentCalls() gets processed...
-        // Normally these failure conditions would happen in DIALING
-        // not ALERTING
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (cn.getState() == Call.State.DIALING);
-
-
-        mRadioControl.triggerHangupAll();
-        msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
-        assertNotNull("Message Time Out", msg);
-        assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-
-        assertEquals(Connection.DisconnectCause.NORMAL, cn.getDisconnectCause());
-
-        assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
-        assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
-        assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
-        assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
-        /*
-        * busy
-        */
-
-        mRadioControl.setNextCallFailCause(CallFailCause.USER_BUSY);
-        mRadioControl.setAutoProgressConnectingCall(false);
-
-        cn = mGSMPhone.dial("+13125551212");
-
-        mRadioControl.progressConnectingCallState();
-
-        // I'm just progressing the call state to
-        // ensure getCurrentCalls() gets processed...
-        // Normally these failure conditions would happen in DIALING
-        // not ALERTING
-        do {
-            assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
-        } while (cn.getState() == Call.State.DIALING);
-
-
-        mRadioControl.triggerHangupAll();
-        msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
-        assertNotNull("Message Time Out", msg);
-        assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-
-        assertEquals(Connection.DisconnectCause.BUSY, cn.getDisconnectCause());
-
-        assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
-        assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
-        assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.DISCONNECTED,
-                mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
-        assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
-        /*
-        * congestion
-        */
-
-        mRadioControl.setNextCallFailCause(CallFailCause.NO_CIRCUIT_AVAIL);
-        mRadioControl.setAutoProgressConnectingCall(false);
-
-        cn = mGSMPhone.dial("+13125551212");
-
-        mRadioControl.progressConnectingCallState();
-
-        // I'm just progressing the call state to
-        // ensure getCurrentCalls() gets processed...
-        // Normally these failure conditions would happen in DIALING
-        // not ALERTING
-        do {
-            msg = mGSMTestHandler.waitForMessage(ANY_MESSAGE);
-            assertNotNull("Message Time Out", msg);
-        } while (cn.getState() == Call.State.DIALING);
-
-
-        mRadioControl.triggerHangupAll();
-
-        // Unlike the while loops above, this one waits
-        // for a "phone state changed" message back to "idle"
-        do {
-            msg = mGSMTestHandler.waitForMessage(ANY_MESSAGE);
-            assertNotNull("Message Time Out", msg);
-        } while (!(msg.what == EVENT_PHONE_STATE_CHANGED
-                && mGSMPhone.getState() == Phone.State.IDLE));
-
-        assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-
-        assertEquals(Connection.DisconnectCause.CONGESTION, cn.getDisconnectCause());
-
-        assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
-        assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
-        assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
-        assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
-        assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
-        assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
-        assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
-        assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-    }
-
-    public void testSSNotification() throws Exception {
-        // MO
-        runTest(0, SuppServiceNotification.MO_CODE_UNCONDITIONAL_CF_ACTIVE);
-        runTest(0, SuppServiceNotification.MO_CODE_CALL_IS_WAITING);
-        runTest(0, SuppServiceNotification.MO_CODE_CALL_DEFLECTED);
-
-        // MT
-        runTest(1, SuppServiceNotification.MT_CODE_FORWARDED_CALL);
-        runTest(1, SuppServiceNotification.MT_CODE_CALL_CONNECTED_ECT);
-        runTest(1, SuppServiceNotification.MT_CODE_ADDITIONAL_CALL_FORWARDED);
-    }
-
-    private void runTest(int type, int code) {
-        Message msg;
-
-        mRadioControl.triggerSsn(type, code);
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_SSN);
-        assertNotNull("Message Time Out", msg);
-        AsyncResult ar = (AsyncResult) msg.obj;
-
-        assertNull(ar.exception);
-
-        SuppServiceNotification notification =
-                (SuppServiceNotification) ar.result;
-
-        assertEquals(type, notification.notificationType);
-        assertEquals(code, notification.code);
-    }
-
-    public void testUssd() throws Exception {
-        // Quick hack to work around a race condition in this test:
-        // We may initiate a USSD MMI before GSMPhone receives its initial
-        // GSMTestHandler.EVENT_RADIO_OFF_OR_NOT_AVAILABLE event.  When the phone sees this
-        // event, it will cancel the just issued USSD MMI, which we don't
-        // want.  So sleep a little first.
-        try {
-            Thread.sleep(1000);
-        } catch (InterruptedException ex) {
-            // do nothing
-        }
-
-        verifyNormal();
-        verifyCancel();
-        varifyNetworkInitiated();
-    }
-
-    private void varifyNetworkInitiated() {
-        Message msg;
-        AsyncResult ar;
-        MmiCode mmi;
-
-        // Receive an incoming NOTIFY
-        mRadioControl.triggerIncomingUssd("0", "NOTIFY message");
-        msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
-        assertNotNull("Message Time Out", msg);
-        ar = (AsyncResult) msg.obj;
-        mmi = (MmiCode) ar.result;
-
-        assertFalse(mmi.isUssdRequest());
-
-        // Receive a REQUEST and send response
-        mRadioControl.triggerIncomingUssd("1", "REQUEST Message");
-        msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
-        assertNotNull("Message Time Out", msg);
-        ar = (AsyncResult) msg.obj;
-        mmi = (MmiCode) ar.result;
-
-        assertTrue(mmi.isUssdRequest());
-
-        mGSMPhone.sendUssdResponse("## TEST: TEST_GSMPhone responding...");
-        msg = mGSMTestHandler.waitForMessage(EVENT_MMI_INITIATE);
-        assertNotNull("Message Time Out", msg);
-        ar = (AsyncResult) msg.obj;
-        mmi = (MmiCode) ar.result;
-
-        GsmMmiCode gsmMmi = (GsmMmiCode) mmi;
-        assertTrue(gsmMmi.isPendingUSSD());
-        msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
-        assertNotNull("Message Time Out", msg);
-        ar = (AsyncResult) msg.obj;
-        mmi = (MmiCode) ar.result;
-
-        assertNull(ar.exception);
-        assertFalse(mmi.isUssdRequest());
-
-        // Receive a REQUEST and cancel
-        mRadioControl.triggerIncomingUssd("1", "REQUEST Message");
-        msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
-        assertNotNull("Message Time Out", msg);
-        ar = (AsyncResult) msg.obj;
-        mmi = (MmiCode) ar.result;
-
-        assertTrue(mmi.isUssdRequest());
-
-        mmi.cancel();
-        msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
-        assertNotNull("Message Time Out", msg);
-
-        ar = (AsyncResult) msg.obj;
-        mmi = (MmiCode) ar.result;
-
-        assertNull(ar.exception);
-        assertEquals(MmiCode.State.CANCELLED, mmi.getState());
-
-        List mmiList = mGSMPhone.getPendingMmiCodes();
-        assertEquals(0, mmiList.size());
-    }
-
-    private void verifyNormal() throws CallStateException {
-        Message msg;
-        AsyncResult ar;
-        MmiCode mmi;
-
-        mGSMPhone.dial("#646#");
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_MMI_INITIATE);
-        assertNotNull("Message Time Out", msg);
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
-        assertNotNull("Message Time Out", msg);
-
-        ar = (AsyncResult) msg.obj;
-        mmi = (MmiCode) ar.result;
-        assertEquals(MmiCode.State.COMPLETE, mmi.getState());
-    }
-
-
-    private void verifyCancel() throws CallStateException {
-        /**
-         * This case makes an assumption that dial() will add the USSD
-         * to the "pending MMI codes" list before it returns.  This seems
-         * like reasonable semantics. It also assumes that the USSD
-         * request in question won't complete until we get back to the
-         * event loop, thus cancel() is safe.
-         */
-        Message msg;
-
-        mGSMPhone.dial("#646#");
-
-        List<? extends MmiCode> pendingMmis = mGSMPhone.getPendingMmiCodes();
-
-        assertEquals(1, pendingMmis.size());
-
-        MmiCode mmi = pendingMmis.get(0);
-        assertTrue(mmi.isCancelable());
-        mmi.cancel();
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_MMI_INITIATE);
-        assertNotNull("Message Time Out", msg);
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
-        assertNotNull("Message Time Out", msg);
-
-        AsyncResult ar = (AsyncResult) msg.obj;
-        mmi = (MmiCode) ar.result;
-
-        assertEquals(MmiCode.State.CANCELLED, mmi.getState());
-    }
-
-    public void testRilHooks() throws Exception {
-        //
-        // These test cases all assume the RIL OEM hooks
-        // just echo back their input
-        //
-
-        Message msg;
-        AsyncResult ar;
-
-        // null byte array
-
-        mGSMPhone.invokeOemRilRequestRaw(null, mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
-        assertNotNull("Message Time Out", msg);
-
-        ar = ((AsyncResult) msg.obj);
-
-        assertNull(ar.result);
-        assertNull(ar.exception);
-
-        // empty byte array
-
-        mGSMPhone.invokeOemRilRequestRaw(new byte[0], mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
-        assertNotNull("Message Time Out", msg);
-
-        ar = ((AsyncResult) msg.obj);
-
-        assertEquals(0, ((byte[]) (ar.result)).length);
-        assertNull(ar.exception);
-
-        // byte array with data
-
-        mGSMPhone.invokeOemRilRequestRaw("Hello".getBytes("utf-8"),
-                mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
-        assertNotNull("Message Time Out", msg);
-
-        ar = ((AsyncResult) msg.obj);
-
-        assertEquals("Hello", new String(((byte[]) (ar.result)), "utf-8"));
-        assertNull(ar.exception);
-
-        // null strings
-
-        mGSMPhone.invokeOemRilRequestStrings(null, mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
-        assertNotNull("Message Time Out", msg);
-
-        ar = ((AsyncResult) msg.obj);
-
-        assertNull(ar.result);
-        assertNull(ar.exception);
-
-        // empty byte array
-
-        mGSMPhone.invokeOemRilRequestStrings(new String[0],
-                mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
-        assertNotNull("Message Time Out", msg);
-
-        ar = ((AsyncResult) msg.obj);
-
-        assertEquals(0, ((String[]) (ar.result)).length);
-        assertNull(ar.exception);
-
-        // Strings with data
-
-        String s[] = new String[1];
-
-        s[0] = "Hello";
-
-        mGSMPhone.invokeOemRilRequestStrings(s, mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
-        assertNotNull("Message Time Out", msg);
-
-        ar = ((AsyncResult) msg.obj);
-
-        assertEquals("Hello", ((String[]) (ar.result))[0]);
-        assertEquals(1, ((String[]) (ar.result)).length);
-        assertNull(ar.exception);
-    }
-
-    public void testMmi() throws Exception {
-        mRadioControl.setAutoProgressConnectingCall(false);
-
-        // "valid" MMI sequences
-        runValidMmi("*#67#", false);
-        runValidMmi("##43*11#", false);
-        runValidMmi("#33*1234*11#", false);
-        runValidMmi("*21*6505551234**5#", false);
-        runValidMmi("**03**1234*4321*4321#", false);
-        // pound string
-        runValidMmi("5308234092307540923#", true);
-        // short code
-        runValidMmi("22", true);
-        // as part of call setup
-        runValidMmiWithConnect("*31#6505551234");
-
-        // invalid MMI sequences
-        runNotMmi("6505551234");
-        runNotMmi("1234#*12#34566654");
-        runNotMmi("*#*#12#*");
-    }
-
-    private void runValidMmi(String dialString, boolean cancelable) throws CallStateException {
-        Connection c = mGSMPhone.dial(dialString);
-        assertNull(c);
-        Message msg = mGSMTestHandler.waitForMessage(EVENT_MMI_INITIATE);
-        assertNotNull("Message Time Out", msg);
-        // Should not be cancelable.
-        AsyncResult ar = (AsyncResult) msg.obj;
-        MmiCode mmi = (MmiCode) ar.result;
-        assertEquals(cancelable, mmi.isCancelable());
-
-        msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
-        assertNotNull("Message Time Out", msg);
-    }
-
-    private void runValidMmiWithConnect(String dialString) throws CallStateException {
-        mRadioControl.pauseResponses();
-
-        Connection c = mGSMPhone.dial(dialString);
-        assertNotNull(c);
-
-        hangup(c);
-    }
-
-    private void hangup(Connection cn) throws CallStateException {
-        cn.hangup();
-
-        mRadioControl.resumeResponses();
-        assertNotNull(mGSMTestHandler.waitForMessage(EVENT_DISCONNECT));
-
-    }
-
-    private void runNotMmi(String dialString) throws CallStateException {
-        mRadioControl.pauseResponses();
-
-        Connection c = mGSMPhone.dial(dialString);
-        assertNotNull(c);
-
-        hangup(c);
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMTestHandler.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMTestHandler.java
deleted file mode 100644
index fb8a5d9..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMTestHandler.java
+++ /dev/null
@@ -1,118 +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.
- */
-
-package com.android.internal.telephony.gsm;
-
-import android.content.Context;
-
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-import com.android.internal.telephony.gsm.GSMPhone;
-import com.android.internal.telephony.test.SimulatedCommands;
-import com.android.internal.telephony.TestPhoneNotifier;
-
-/**
- * This class creates a HandlerThread which waits for the various messages.
- */
-public class GSMTestHandler extends HandlerThread implements Handler.Callback {
-
-    private Handler mHandler;
-    private Message mCurrentMessage;
-
-    private Boolean mMsgConsumed;
-    private SimulatedCommands sc;
-    private GSMPhone mGSMPhone;
-    private Context mContext;
-
-    private static final int FAIL_TIMEOUT_MILLIS = 5 * 1000;
-
-    public GSMTestHandler(Context context) {
-        super("GSMPhoneTest");
-        mMsgConsumed = false;
-        mContext = context;
-   }
-
-    @Override
-    protected void onLooperPrepared() {
-        sc = new SimulatedCommands();
-        mGSMPhone = new GSMPhone(mContext, sc, new TestPhoneNotifier(), true);
-        mHandler = new Handler(getLooper(), this);
-        synchronized (this) {
-            notifyAll();
-        }
-    }
-
-    public boolean handleMessage(Message msg) {
-        synchronized (this) {
-            mCurrentMessage = msg;
-            this.notifyAll();
-            while(!mMsgConsumed) {
-                try {
-                    this.wait();
-                } catch (InterruptedException e) {}
-            }
-            mMsgConsumed = false;
-        }
-        return true;
-    }
-
-
-    public void cleanup() {
-        Looper looper = getLooper();
-        if (looper != null) looper.quit();
-        mHandler = null;
-    }
-
-    public Handler getHandler() {
-        return mHandler;
-    }
-
-    public SimulatedCommands getSimulatedCommands() {
-        return sc;
-    }
-
-    public GSMPhone getGSMPhone() {
-        return mGSMPhone;
-    }
-
-    public Message waitForMessage(int code) {
-        Message msg;
-        while(true) {
-            msg = null;
-            synchronized (this) {
-                try {
-                    this.wait(FAIL_TIMEOUT_MILLIS);
-                } catch (InterruptedException e) {
-                }
-
-                // Check if timeout has occurred.
-                if (mCurrentMessage != null) {
-                    // Consume the message
-                    msg = Message.obtain();
-                    msg.copyFrom(mCurrentMessage);
-                    mCurrentMessage = null;
-                    mMsgConsumed = true;
-                    this.notifyAll();
-                }
-            }
-            if (msg == null || code == GSMPhoneTest.ANY_MESSAGE || msg.what == code) return msg;
-       }
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsCbTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsCbTest.java
deleted file mode 100644
index 82c6944..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsCbTest.java
+++ /dev/null
@@ -1,758 +0,0 @@
-/*
- * Copyright (C) 2010 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.internal.telephony.gsm;
-
-import android.telephony.SmsCbEtwsInfo;
-import android.telephony.SmsCbLocation;
-import android.telephony.SmsCbMessage;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-import com.android.internal.telephony.IccUtils;
-
-import java.util.Random;
-
-/**
- * Test cases for basic SmsCbMessage operations
- */
-public class GsmSmsCbTest extends AndroidTestCase {
-
-    private static final String TAG = "GsmSmsCbTest";
-
-    private static final SmsCbLocation sTestLocation = new SmsCbLocation("94040", 1234, 5678);
-
-    private static SmsCbMessage createFromPdu(byte[] pdu) {
-        try {
-            SmsCbHeader header = new SmsCbHeader(pdu);
-            byte[][] pdus = new byte[1][];
-            pdus[0] = pdu;
-            return GsmSmsCbMessage.createSmsCbMessage(header, sTestLocation, pdus);
-        } catch (IllegalArgumentException e) {
-            return null;
-        }
-    }
-
-    private static void doTestGeographicalScopeValue(byte[] pdu, byte b, int expectedGs) {
-        pdu[0] = b;
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected geographical scope decoded", expectedGs, msg
-                .getGeographicalScope());
-    }
-
-    public void testCreateNullPdu() {
-        SmsCbMessage msg = createFromPdu(null);
-        assertNull("createFromPdu(byte[] with null pdu should return null", msg);
-    }
-
-    public void testCreateTooShortPdu() {
-        byte[] pdu = new byte[4];
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertNull("createFromPdu(byte[] with too short pdu should return null", msg);
-    }
-
-    public void testGetGeographicalScope() {
-        byte[] pdu = {
-                (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x40, (byte)0x11, (byte)0x41,
-                (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6,
-                (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70,
-                (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5,
-                (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69,
-                (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
-                (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75,
-                (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69,
-                (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00
-        };
-
-        doTestGeographicalScopeValue(pdu, (byte)0x00,
-                SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE);
-        doTestGeographicalScopeValue(pdu, (byte)0x40, SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE);
-        doTestGeographicalScopeValue(pdu, (byte)0x80, SmsCbMessage.GEOGRAPHICAL_SCOPE_LA_WIDE);
-        doTestGeographicalScopeValue(pdu, (byte)0xC0, SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE);
-    }
-
-    public void testGetGeographicalScopeUmts() {
-        byte[] pdu = {
-                (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x40,
-
-                (byte)0x01,
-
-                (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91,
-                (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07,
-                (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C,
-                (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C,
-                (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, (byte)0x3A,
-                (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
-                (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9,
-                (byte)0x75, (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93,
-                (byte)0xC9, (byte)0x69, (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68,
-                (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
-                (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
-                (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
-                (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
-                (byte)0x34
-        };
-
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected geographical scope decoded",
-                SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE, msg.getGeographicalScope());
-    }
-
-    public void testGetMessageBody7Bit() {
-        byte[] pdu = {
-                (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x40, (byte)0x11, (byte)0x41,
-                (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6,
-                (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70,
-                (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5,
-                (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69,
-                (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
-                (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75,
-                (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69,
-                (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected 7-bit string decoded",
-                "A GSM default alphabet message with carriage return padding",
-                msg.getMessageBody());
-    }
-
-    public void testGetMessageBody7BitUmts() {
-        byte[] pdu = {
-                (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x40,
-
-                (byte)0x01,
-
-                (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91,
-                (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07,
-                (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C,
-                (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C,
-                (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, (byte)0x3A,
-                (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
-                (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9,
-                (byte)0x75, (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93,
-                (byte)0xC9, (byte)0x69, (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68,
-                (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
-                (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
-                (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
-                (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
-                (byte)0x34
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected 7-bit string decoded",
-                "A GSM default alphabet message with carriage return padding",
-                msg.getMessageBody());
-    }
-
-    public void testGetMessageBody7BitMultipageUmts() {
-        byte[] pdu = {
-                (byte)0x01, (byte)0x00, (byte)0x01, (byte)0xC0, (byte)0x00, (byte)0x40,
-
-                (byte)0x02,
-
-                (byte)0xC6, (byte)0xB4, (byte)0x7C, (byte)0x4E, (byte)0x07, (byte)0xC1,
-                (byte)0xC3, (byte)0xE7, (byte)0xF2, (byte)0xAA, (byte)0xD1, (byte)0x68,
-                (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
-                (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
-                (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
-                (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A,
-                (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34,
-                (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68,
-                (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
-                (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
-                (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
-                (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
-                (byte)0x0A,
-
-                (byte)0xD3, (byte)0xF2, (byte)0xF8, (byte)0xED, (byte)0x26, (byte)0x83,
-                (byte)0xE0, (byte)0xE1, (byte)0x73, (byte)0xB9, (byte)0xD1, (byte)0x68,
-                (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
-                (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
-                (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
-                (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A,
-                (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34,
-                (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68,
-                (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
-                (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
-                (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
-                (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
-                (byte)0x0A
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected multipage 7-bit string decoded",
-                "First page+Second page",
-                msg.getMessageBody());
-    }
-
-    public void testGetMessageBody7BitFull() {
-        byte[] pdu = {
-                (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x40, (byte)0x11, (byte)0x41,
-                (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6,
-                (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70,
-                (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5,
-                (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xC4, (byte)0xE5,
-                (byte)0xB4, (byte)0xFB, (byte)0x0C, (byte)0x2A, (byte)0xE3, (byte)0xC3, (byte)0x63,
-                (byte)0x3A, (byte)0x3B, (byte)0x0F, (byte)0xCA, (byte)0xCD, (byte)0x40, (byte)0x63,
-                (byte)0x74, (byte)0x58, (byte)0x1E, (byte)0x1E, (byte)0xD3, (byte)0xCB, (byte)0xF2,
-                (byte)0x39, (byte)0x88, (byte)0xFD, (byte)0x76, (byte)0x9F, (byte)0x59, (byte)0xA0,
-                (byte)0x76, (byte)0x39, (byte)0xEC, (byte)0x4E, (byte)0xBB, (byte)0xCF, (byte)0x20,
-                (byte)0x3A, (byte)0xBA, (byte)0x2C, (byte)0x2F, (byte)0x83, (byte)0xD2, (byte)0x73,
-                (byte)0x90, (byte)0xFB, (byte)0x0D, (byte)0x82, (byte)0x87, (byte)0xC9, (byte)0xE4,
-                (byte)0xB4, (byte)0xFB, (byte)0x1C, (byte)0x02
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals(
-                "Unexpected 7-bit string decoded",
-                "A GSM default alphabet message being exactly 93 characters long, " +
-                "meaning there is no padding!",
-                msg.getMessageBody());
-    }
-
-    public void testGetMessageBody7BitFullUmts() {
-        byte[] pdu = {
-                (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x40,
-
-                (byte)0x01,
-
-                (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91,
-                (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07,
-                (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C,
-                (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C,
-                (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xC4, (byte)0xE5, (byte)0xB4,
-                (byte)0xFB, (byte)0x0C, (byte)0x2A, (byte)0xE3, (byte)0xC3, (byte)0x63,
-                (byte)0x3A, (byte)0x3B, (byte)0x0F, (byte)0xCA, (byte)0xCD, (byte)0x40,
-                (byte)0x63, (byte)0x74, (byte)0x58, (byte)0x1E, (byte)0x1E, (byte)0xD3,
-                (byte)0xCB, (byte)0xF2, (byte)0x39, (byte)0x88, (byte)0xFD, (byte)0x76,
-                (byte)0x9F, (byte)0x59, (byte)0xA0, (byte)0x76, (byte)0x39, (byte)0xEC,
-                (byte)0x4E, (byte)0xBB, (byte)0xCF, (byte)0x20, (byte)0x3A, (byte)0xBA,
-                (byte)0x2C, (byte)0x2F, (byte)0x83, (byte)0xD2, (byte)0x73, (byte)0x90,
-                (byte)0xFB, (byte)0x0D, (byte)0x82, (byte)0x87, (byte)0xC9, (byte)0xE4,
-                (byte)0xB4, (byte)0xFB, (byte)0x1C, (byte)0x02,
-
-                (byte)0x52
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals(
-                "Unexpected 7-bit string decoded",
-                "A GSM default alphabet message being exactly 93 characters long, " +
-                "meaning there is no padding!",
-                msg.getMessageBody());
-    }
-
-    public void testGetMessageBody7BitWithLanguage() {
-        byte[] pdu = {
-                (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x04, (byte)0x11, (byte)0x41,
-                (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6,
-                (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70,
-                (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5,
-                (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69,
-                (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
-                (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75,
-                (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69,
-                (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected 7-bit string decoded",
-                "A GSM default alphabet message with carriage return padding",
-                msg.getMessageBody());
-
-        assertEquals("Unexpected language indicator decoded", "es", msg.getLanguageCode());
-    }
-
-    public void testGetMessageBody7BitWithLanguageInBody() {
-        byte[] pdu = {
-                (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x10, (byte)0x11, (byte)0x73,
-                (byte)0x7B, (byte)0x23, (byte)0x08, (byte)0x3A, (byte)0x4E, (byte)0x9B, (byte)0x20,
-                (byte)0x72, (byte)0xD9, (byte)0x1C, (byte)0xAE, (byte)0xB3, (byte)0xE9, (byte)0xA0,
-                (byte)0x30, (byte)0x1B, (byte)0x8E, (byte)0x0E, (byte)0x8B, (byte)0xCB, (byte)0x74,
-                (byte)0x50, (byte)0xBB, (byte)0x3C, (byte)0x9F, (byte)0x87, (byte)0xCF, (byte)0x65,
-                (byte)0xD0, (byte)0x3D, (byte)0x4D, (byte)0x47, (byte)0x83, (byte)0xC6, (byte)0x61,
-                (byte)0xB9, (byte)0x3C, (byte)0x1D, (byte)0x3E, (byte)0x97, (byte)0x41, (byte)0xF2,
-                (byte)0x32, (byte)0xBD, (byte)0x2E, (byte)0x77, (byte)0x83, (byte)0xE0, (byte)0x61,
-                (byte)0x32, (byte)0x39, (byte)0xED, (byte)0x3E, (byte)0x37, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected 7-bit string decoded",
-                "A GSM default alphabet message with carriage return padding",
-                msg.getMessageBody());
-
-        assertEquals("Unexpected language indicator decoded", "sv", msg.getLanguageCode());
-    }
-
-    public void testGetMessageBody7BitWithLanguageInBodyUmts() {
-        byte[] pdu = {
-                (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x10,
-
-                (byte)0x01,
-
-                (byte)0x73, (byte)0x7B, (byte)0x23, (byte)0x08, (byte)0x3A, (byte)0x4E,
-                (byte)0x9B, (byte)0x20, (byte)0x72, (byte)0xD9, (byte)0x1C, (byte)0xAE,
-                (byte)0xB3, (byte)0xE9, (byte)0xA0, (byte)0x30, (byte)0x1B, (byte)0x8E,
-                (byte)0x0E, (byte)0x8B, (byte)0xCB, (byte)0x74, (byte)0x50, (byte)0xBB,
-                (byte)0x3C, (byte)0x9F, (byte)0x87, (byte)0xCF, (byte)0x65, (byte)0xD0,
-                (byte)0x3D, (byte)0x4D, (byte)0x47, (byte)0x83, (byte)0xC6, (byte)0x61,
-                (byte)0xB9, (byte)0x3C, (byte)0x1D, (byte)0x3E, (byte)0x97, (byte)0x41,
-                (byte)0xF2, (byte)0x32, (byte)0xBD, (byte)0x2E, (byte)0x77, (byte)0x83,
-                (byte)0xE0, (byte)0x61, (byte)0x32, (byte)0x39, (byte)0xED, (byte)0x3E,
-                (byte)0x37, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
-                (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
-                (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
-                (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
-                (byte)0x37
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected 7-bit string decoded",
-                "A GSM default alphabet message with carriage return padding",
-                msg.getMessageBody());
-
-        assertEquals("Unexpected language indicator decoded", "sv", msg.getLanguageCode());
-    }
-
-    public void testGetMessageBody8Bit() {
-        byte[] pdu = {
-                (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x44, (byte)0x11, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("8-bit message body should be empty", "", msg.getMessageBody());
-    }
-
-    public void testGetMessageBodyUcs2() {
-        byte[] pdu = {
-                (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x48, (byte)0x11, (byte)0x00,
-                (byte)0x41, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x55, (byte)0x00, (byte)0x43,
-                (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x20, (byte)0x00,
-                (byte)0x6D, (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x73, (byte)0x00, (byte)0x73,
-                (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x65, (byte)0x00,
-                (byte)0x20, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x6F, (byte)0x00, (byte)0x6E,
-                (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x69, (byte)0x00,
-                (byte)0x6E, (byte)0x00, (byte)0x69, (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x67,
-                (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x20, (byte)0x04,
-                (byte)0x34, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x68,
-                (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x61, (byte)0x00,
-                (byte)0x63, (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x72,
-                (byte)0x00, (byte)0x0D, (byte)0x00, (byte)0x0D
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected 7-bit string decoded",
-                "A UCS2 message containing a \u0434 character", msg.getMessageBody());
-    }
-
-    public void testGetMessageBodyUcs2Umts() {
-        byte[] pdu = {
-                (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x48,
-
-                (byte)0x01,
-
-                (byte)0x00, (byte)0x41, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x55,
-                (byte)0x00, (byte)0x43, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x32,
-                (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x6D, (byte)0x00, (byte)0x65,
-                (byte)0x00, (byte)0x73, (byte)0x00, (byte)0x73, (byte)0x00, (byte)0x61,
-                (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x20,
-                (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x6F, (byte)0x00, (byte)0x6E,
-                (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x69,
-                (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x69, (byte)0x00, (byte)0x6E,
-                (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x61,
-                (byte)0x00, (byte)0x20, (byte)0x04, (byte)0x34, (byte)0x00, (byte)0x20,
-                (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x68, (byte)0x00, (byte)0x61,
-                (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x63,
-                (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x72,
-                (byte)0x00, (byte)0x0D, (byte)0x00, (byte)0x0D,
-
-                (byte)0x4E
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected 7-bit string decoded",
-                "A UCS2 message containing a \u0434 character", msg.getMessageBody());
-    }
-
-    public void testGetMessageBodyUcs2MultipageUmts() {
-        byte[] pdu = {
-                (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x48,
-
-                (byte)0x02,
-
-                (byte)0x00, (byte)0x41, (byte)0x00, (byte)0x41, (byte)0x00, (byte)0x41,
-                (byte)0x00, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-
-                (byte)0x06,
-
-                (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x42,
-                (byte)0x00, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-
-                (byte)0x06
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected multipage UCS2 string decoded",
-                "AAABBB", msg.getMessageBody());
-    }
-
-    public void testGetMessageBodyUcs2WithLanguageInBody() {
-        byte[] pdu = {
-                (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x11, (byte)0x11, (byte)0x78,
-                (byte)0x3C, (byte)0x00, (byte)0x41, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x55,
-                (byte)0x00, (byte)0x43, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x32, (byte)0x00,
-                (byte)0x20, (byte)0x00, (byte)0x6D, (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x73,
-                (byte)0x00, (byte)0x73, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x67, (byte)0x00,
-                (byte)0x65, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x6F,
-                (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x61, (byte)0x00,
-                (byte)0x69, (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x69, (byte)0x00, (byte)0x6E,
-                (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x61, (byte)0x00,
-                (byte)0x20, (byte)0x04, (byte)0x34, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x63,
-                (byte)0x00, (byte)0x68, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x72, (byte)0x00,
-                (byte)0x61, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x65,
-                (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x0D
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected 7-bit string decoded",
-                "A UCS2 message containing a \u0434 character", msg.getMessageBody());
-
-        assertEquals("Unexpected language indicator decoded", "xx", msg.getLanguageCode());
-    }
-
-    public void testGetMessageBodyUcs2WithLanguageInBodyUmts() {
-        byte[] pdu = {
-                (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x11,
-
-                (byte)0x01,
-
-                (byte)0x78, (byte)0x3C, (byte)0x00, (byte)0x41, (byte)0x00, (byte)0x20,
-                (byte)0x00, (byte)0x55, (byte)0x00, (byte)0x43, (byte)0x00, (byte)0x53,
-                (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x6D,
-                (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x73, (byte)0x00, (byte)0x73,
-                (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x65,
-                (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x6F,
-                (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x61,
-                (byte)0x00, (byte)0x69, (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x69,
-                (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x20,
-                (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x20, (byte)0x04, (byte)0x34,
-                (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x68,
-                (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x61,
-                (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x65,
-                (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x0D,
-
-                (byte)0x50
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected 7-bit string decoded",
-                "A UCS2 message containing a \u0434 character", msg.getMessageBody());
-
-        assertEquals("Unexpected language indicator decoded", "xx", msg.getLanguageCode());
-    }
-
-    public void testGetMessageIdentifier() {
-        byte[] pdu = {
-                (byte)0xC0, (byte)0x00, (byte)0x30, (byte)0x39, (byte)0x40, (byte)0x11, (byte)0x41,
-                (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6,
-                (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70,
-                (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5,
-                (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69,
-                (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
-                (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75,
-                (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69,
-                (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00
-        };
-
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected message identifier decoded", 12345, msg.getServiceCategory());
-    }
-
-    public void testGetMessageIdentifierUmts() {
-        byte[] pdu = {
-                (byte)0x01, (byte)0x30, (byte)0x39, (byte)0x2A, (byte)0xA5, (byte)0x40,
-
-                (byte)0x01,
-
-                (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91,
-                (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07,
-                (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C,
-                (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C,
-                (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, (byte)0x3A,
-                (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
-                (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9,
-                (byte)0x75, (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93,
-                (byte)0xC9, (byte)0x69, (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68,
-                (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
-                (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
-                (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
-                (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
-                (byte)0x34
-        };
-
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected message identifier decoded", 12345, msg.getServiceCategory());
-    }
-
-    public void testGetMessageCode() {
-        byte[] pdu = {
-                (byte)0x2A, (byte)0xA5, (byte)0x30, (byte)0x39, (byte)0x40, (byte)0x11, (byte)0x41,
-                (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6,
-                (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70,
-                (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5,
-                (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69,
-                (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
-                (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75,
-                (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69,
-                (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00
-        };
-
-        SmsCbMessage msg = createFromPdu(pdu);
-        int messageCode = (msg.getSerialNumber() & 0x3ff0) >> 4;
-
-        assertEquals("Unexpected message code decoded", 682, messageCode);
-    }
-
-    public void testGetMessageCodeUmts() {
-        byte[] pdu = {
-                (byte)0x01, (byte)0x30, (byte)0x39, (byte)0x2A, (byte)0xA5, (byte)0x40,
-
-                (byte)0x01,
-
-                (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91,
-                (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07,
-                (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C,
-                (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C,
-                (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, (byte)0x3A,
-                (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
-                (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9,
-                (byte)0x75, (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93,
-                (byte)0xC9, (byte)0x69, (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68,
-                (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
-                (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
-                (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
-                (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
-                (byte)0x34
-        };
-
-        SmsCbMessage msg = createFromPdu(pdu);
-        int messageCode = (msg.getSerialNumber() & 0x3ff0) >> 4;
-
-        assertEquals("Unexpected message code decoded", 682, messageCode);
-    }
-
-    public void testGetUpdateNumber() {
-        byte[] pdu = {
-                (byte)0x2A, (byte)0xA5, (byte)0x30, (byte)0x39, (byte)0x40, (byte)0x11, (byte)0x41,
-                (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6,
-                (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70,
-                (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5,
-                (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69,
-                (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
-                (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75,
-                (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69,
-                (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00
-        };
-
-        SmsCbMessage msg = createFromPdu(pdu);
-        int updateNumber = msg.getSerialNumber() & 0x000f;
-
-        assertEquals("Unexpected update number decoded", 5, updateNumber);
-    }
-
-    public void testGetUpdateNumberUmts() {
-        byte[] pdu = {
-                (byte)0x01, (byte)0x30, (byte)0x39, (byte)0x2A, (byte)0xA5, (byte)0x40,
-
-                (byte)0x01,
-
-                (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91,
-                (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07,
-                (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C,
-                (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C,
-                (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, (byte)0x3A,
-                (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
-                (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9,
-                (byte)0x75, (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93,
-                (byte)0xC9, (byte)0x69, (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68,
-                (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
-                (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
-                (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
-                (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
-                (byte)0x34
-        };
-
-        SmsCbMessage msg = createFromPdu(pdu);
-        int updateNumber = msg.getSerialNumber() & 0x000f;
-
-        assertEquals("Unexpected update number decoded", 5, updateNumber);
-    }
-
-    /* ETWS Test message including header */
-    private static final byte[] etwsMessageNormal = IccUtils.hexStringToBytes("000011001101" +
-            "0D0A5BAE57CE770C531790E85C716CBF3044573065B930675730" +
-            "9707767A751F30025F37304463FA308C306B5099304830664E0B30553044FF086C178C615E81FF09" +
-            "0000000000000000000000000000");
-
-    private static final byte[] etwsMessageCancel = IccUtils.hexStringToBytes("000011001101" +
-            "0D0A5148307B3069002800310030003A0035" +
-            "00320029306E7DCA602557309707901F5831309253D66D883057307E3059FF086C178C615E81FF09" +
-            "00000000000000000000000000000000000000000000");
-
-    private static final byte[] etwsMessageTest = IccUtils.hexStringToBytes("000011031101" +
-            "0D0A5BAE57CE770C531790E85C716CBF3044" +
-            "573065B9306757309707300263FA308C306B5099304830664E0B30553044FF086C178C615E81FF09" +
-            "00000000000000000000000000000000000000000000");
-
-    // FIXME: add example of ETWS primary notification PDU
-
-    public void testEtwsMessageNormal() {
-        SmsCbMessage msg = createFromPdu(etwsMessageNormal);
-        Log.d(TAG, msg.toString());
-        assertEquals("GS mismatch", 0, msg.getGeographicalScope());
-        assertEquals("serial number mismatch", 0, msg.getSerialNumber());
-        assertEquals("message ID mismatch", 0x1100, msg.getServiceCategory());
-        assertEquals("warning type mismatch", SmsCbEtwsInfo.ETWS_WARNING_TYPE_EARTHQUAKE,
-                msg.getEtwsWarningInfo().getWarningType());
-    }
-
-    public void testEtwsMessageCancel() {
-        SmsCbMessage msg = createFromPdu(etwsMessageCancel);
-        Log.d(TAG, msg.toString());
-        assertEquals("GS mismatch", 0, msg.getGeographicalScope());
-        assertEquals("serial number mismatch", 0, msg.getSerialNumber());
-        assertEquals("message ID mismatch", 0x1100, msg.getServiceCategory());
-        assertEquals("warning type mismatch", SmsCbEtwsInfo.ETWS_WARNING_TYPE_EARTHQUAKE,
-                msg.getEtwsWarningInfo().getWarningType());
-    }
-
-    public void testEtwsMessageTest() {
-        SmsCbMessage msg = createFromPdu(etwsMessageTest);
-        Log.d(TAG, msg.toString());
-        assertEquals("GS mismatch", 0, msg.getGeographicalScope());
-        assertEquals("serial number mismatch", 0, msg.getSerialNumber());
-        assertEquals("message ID mismatch", 0x1103, msg.getServiceCategory());
-        assertEquals("warning type mismatch", SmsCbEtwsInfo.ETWS_WARNING_TYPE_TEST_MESSAGE,
-                msg.getEtwsWarningInfo().getWarningType());
-    }
-
-    // Make sure we don't throw an exception if we feed random data to the PDU parser.
-    public void testRandomPdus() {
-        Random r = new Random(94040);
-        for (int run = 0; run < 10000; run++) {
-            int len = r.nextInt(140);
-            byte[] data = new byte[len];
-            for (int i = 0; i < len; i++) {
-                data[i] = (byte) r.nextInt(256);
-            }
-            try {
-                // this should return a SmsCbMessage object or null for invalid data
-                SmsCbMessage msg = createFromPdu(data);
-            } catch (Exception e) {
-                Log.d(TAG, "exception thrown", e);
-                fail("Exception in decoder at run " + run + " length " + len + ": " + e);
-            }
-        }
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadCommands.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadCommands.java
deleted file mode 100644
index ea6836d..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadCommands.java
+++ /dev/null
@@ -1,624 +0,0 @@
-/*
- * Copyright (C) 2011 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.internal.telephony.gsm;
-
-import android.content.Context;
-import android.os.AsyncResult;
-import android.os.Message;
-import android.os.SystemClock;
-import android.util.Log;
-
-import com.android.internal.telephony.BaseCommands;
-import com.android.internal.telephony.IccIoResult;
-import com.android.internal.telephony.UUSInfo;
-
-import junit.framework.Assert;
-
-/**
- * Dummy BaseCommands for UsimDataDownloadTest. Only implements UICC envelope and
- * SMS acknowledgement commands.
- */
-class UsimDataDownloadCommands extends BaseCommands {
-    private static final String TAG = "UsimDataDownloadCommands";
-
-    private boolean mExpectingAcknowledgeGsmSms;        // true if expecting ack GSM SMS
-    private boolean mExpectingAcknowledgeGsmSmsSuccess; // true if expecting ack SMS success
-    private int mExpectingAcknowledgeGsmSmsFailureCause;    // expecting ack SMS failure cause
-    private String mExpectingAcknowledgeGsmSmsPdu;          // expecting ack SMS PDU
-
-    private boolean mExpectingSendEnvelope;         // true to expect a send envelope command
-    private String mExpectingSendEnvelopeContents;  // expected string for send envelope
-    private int mExpectingSendEnvelopeResponseSw1;  // SW1/SW2 response status
-    private int mExpectingSendEnvelopeResponseSw2;  // SW1/SW2 response status
-    private String mExpectingSendEnvelopeResponse;  // Response string for Send Envelope
-
-    UsimDataDownloadCommands(Context context) {
-        super(context);
-    }
-
-    /**
-     * Expect a call to acknowledgeLastIncomingGsmSms with success flag and failure cause.
-     * @param success true if expecting success; false if expecting failure
-     * @param cause the failure cause, if success is false
-     */
-    synchronized void expectAcknowledgeGsmSms(boolean success, int cause) {
-        Assert.assertFalse("expectAcknowledgeGsmSms called twice", mExpectingAcknowledgeGsmSms);
-        mExpectingAcknowledgeGsmSms = true;
-        mExpectingAcknowledgeGsmSmsSuccess = success;
-        mExpectingAcknowledgeGsmSmsFailureCause = cause;
-    }
-
-    /**
-     * Expect a call to acknowledgeLastIncomingGsmSmsWithPdu with success flag and PDU.
-     * @param success true if expecting success; false if expecting failure
-     * @param ackPdu the acknowledgement PDU to expect
-     */
-    synchronized void expectAcknowledgeGsmSmsWithPdu(boolean success, String ackPdu) {
-        Assert.assertFalse("expectAcknowledgeGsmSms called twice", mExpectingAcknowledgeGsmSms);
-        mExpectingAcknowledgeGsmSms = true;
-        mExpectingAcknowledgeGsmSmsSuccess = success;
-        mExpectingAcknowledgeGsmSmsPdu = ackPdu;
-    }
-
-    /**
-     * Expect a call to sendEnvelopeWithStatus().
-     * @param contents expected envelope contents to send
-     * @param sw1 simulated SW1 status to return
-     * @param sw2 simulated SW2 status to return
-     * @param response simulated envelope response to return
-     */
-    synchronized void expectSendEnvelope(String contents, int sw1, int sw2, String response) {
-        Assert.assertFalse("expectSendEnvelope called twice", mExpectingSendEnvelope);
-        mExpectingSendEnvelope = true;
-        mExpectingSendEnvelopeContents = contents;
-        mExpectingSendEnvelopeResponseSw1 = sw1;
-        mExpectingSendEnvelopeResponseSw2 = sw2;
-        mExpectingSendEnvelopeResponse = response;
-    }
-
-    synchronized void assertExpectedMethodsCalled() {
-        long stopTime = SystemClock.elapsedRealtime() + 5000;
-        while ((mExpectingAcknowledgeGsmSms || mExpectingSendEnvelope)
-                && SystemClock.elapsedRealtime() < stopTime) {
-            try {
-                wait();
-            } catch (InterruptedException ignored) {}
-        }
-        Assert.assertFalse("expecting SMS acknowledge call", mExpectingAcknowledgeGsmSms);
-        Assert.assertFalse("expecting send envelope call", mExpectingSendEnvelope);
-    }
-
-    @Override
-    public synchronized void acknowledgeLastIncomingGsmSms(boolean success, int cause,
-            Message response) {
-        Log.d(TAG, "acknowledgeLastIncomingGsmSms: success=" + success + ", cause=" + cause);
-        Assert.assertTrue("unexpected call to acknowledge SMS", mExpectingAcknowledgeGsmSms);
-        Assert.assertEquals(mExpectingAcknowledgeGsmSmsSuccess, success);
-        Assert.assertEquals(mExpectingAcknowledgeGsmSmsFailureCause, cause);
-        mExpectingAcknowledgeGsmSms = false;
-        if (response != null) {
-            AsyncResult.forMessage(response);
-            response.sendToTarget();
-        }
-        notifyAll();    // wake up assertExpectedMethodsCalled()
-    }
-
-    @Override
-    public synchronized void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu,
-            Message response) {
-        Log.d(TAG, "acknowledgeLastIncomingGsmSmsWithPdu: success=" + success
-                + ", ackPDU= " + ackPdu);
-        Assert.assertTrue("unexpected call to acknowledge SMS", mExpectingAcknowledgeGsmSms);
-        Assert.assertEquals(mExpectingAcknowledgeGsmSmsSuccess, success);
-        Assert.assertEquals(mExpectingAcknowledgeGsmSmsPdu, ackPdu);
-        mExpectingAcknowledgeGsmSms = false;
-        if (response != null) {
-            AsyncResult.forMessage(response);
-            response.sendToTarget();
-        }
-        notifyAll();    // wake up assertExpectedMethodsCalled()
-    }
-
-    @Override
-    public synchronized void sendEnvelopeWithStatus(String contents, Message response) {
-        // Add spaces between hex bytes for readability
-        StringBuilder builder = new StringBuilder();
-        for (int i = 0; i < contents.length(); i += 2) {
-            builder.append(contents.charAt(i)).append(contents.charAt(i+1)).append(' ');
-        }
-        Log.d(TAG, "sendEnvelopeWithStatus: " + builder.toString());
-
-        Assert.assertTrue("unexpected call to send envelope", mExpectingSendEnvelope);
-        Assert.assertEquals(mExpectingSendEnvelopeContents, contents);
-        mExpectingSendEnvelope = false;
-
-        IccIoResult result = new IccIoResult(mExpectingSendEnvelopeResponseSw1,
-                mExpectingSendEnvelopeResponseSw2, mExpectingSendEnvelopeResponse);
-
-        if (response != null) {
-            AsyncResult.forMessage(response, result, null);
-            response.sendToTarget();
-        }
-        notifyAll();    // wake up assertExpectedMethodsCalled()
-    }
-
-    @Override
-    public void setSuppServiceNotifications(boolean enable, Message result) {
-    }
-
-    @Override
-    public void supplyIccPin(String pin, Message result) {
-    }
-
-    @Override
-    public void supplyIccPinForApp(String pin, String aid, Message result) {
-    }
-
-    @Override
-    public void supplyIccPuk(String puk, String newPin, Message result) {
-    }
-
-    @Override
-    public void supplyIccPukForApp(String puk, String newPin, String aid, Message result) {
-    }
-
-    @Override
-    public void supplyIccPin2(String pin2, Message result) {
-    }
-
-    @Override
-    public void supplyIccPin2ForApp(String pin2, String aid, Message result) {
-    }
-
-    @Override
-    public void supplyIccPuk2(String puk2, String newPin2, Message result) {
-    }
-
-    @Override
-    public void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message result) {
-    }
-
-    @Override
-    public void changeIccPin(String oldPin, String newPin, Message result) {
-    }
-
-    @Override
-    public void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message result) {
-    }
-
-    @Override
-    public void changeIccPin2(String oldPin2, String newPin2, Message result) {
-    }
-
-    @Override
-    public void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr, Message result) {
-    }
-
-    @Override
-    public void changeBarringPassword(String facility, String oldPwd, String newPwd,
-            Message result) {
-    }
-
-    @Override
-    public void supplyNetworkDepersonalization(String netpin, Message result) {
-    }
-
-    @Override
-    public void getCurrentCalls(Message result) {
-    }
-
-    @Override
-    public void getPDPContextList(Message result) {
-    }
-
-    @Override
-    public void getDataCallList(Message result) {
-    }
-
-    @Override
-    public void dial(String address, int clirMode, Message result) {
-    }
-
-    @Override
-    public void dial(String address, int clirMode, UUSInfo uusInfo, Message result) {
-    }
-
-    @Override
-    public void getIMSI(Message result) {
-    }
-
-    @Override
-    public void getIMEI(Message result) {
-    }
-
-    @Override
-    public void getIMEISV(Message result) {
-    }
-
-    @Override
-    public void hangupConnection(int gsmIndex, Message result) {
-    }
-
-    @Override
-    public void hangupWaitingOrBackground(Message result) {
-    }
-
-    @Override
-    public void hangupForegroundResumeBackground(Message result) {
-    }
-
-    @Override
-    public void switchWaitingOrHoldingAndActive(Message result) {
-    }
-
-    @Override
-    public void conference(Message result) {
-    }
-
-    @Override
-    public void setPreferredVoicePrivacy(boolean enable, Message result) {
-    }
-
-    @Override
-    public void getPreferredVoicePrivacy(Message result) {
-    }
-
-    @Override
-    public void separateConnection(int gsmIndex, Message result) {
-    }
-
-    @Override
-    public void acceptCall(Message result) {
-    }
-
-    @Override
-    public void rejectCall(Message result) {
-    }
-
-    @Override
-    public void explicitCallTransfer(Message result) {
-    }
-
-    @Override
-    public void getLastCallFailCause(Message result) {
-    }
-
-    @Override
-    public void getLastPdpFailCause(Message result) {
-    }
-
-    @Override
-    public void getLastDataCallFailCause(Message result) {
-    }
-
-    @Override
-    public void setMute(boolean enableMute, Message response) {
-    }
-
-    @Override
-    public void getMute(Message response) {
-    }
-
-    @Override
-    public void getSignalStrength(Message response) {
-    }
-
-    @Override
-    public void getVoiceRegistrationState(Message response) {
-    }
-
-    @Override
-    public void getDataRegistrationState(Message response) {
-    }
-
-    @Override
-    public void getOperator(Message response) {
-    }
-
-    @Override
-    public void sendDtmf(char c, Message result) {
-    }
-
-    @Override
-    public void startDtmf(char c, Message result) {
-    }
-
-    @Override
-    public void stopDtmf(Message result) {
-    }
-
-    @Override
-    public void sendBurstDtmf(String dtmfString, int on, int off, Message result) {
-    }
-
-    @Override
-    public void sendSMS(String smscPDU, String pdu, Message response) {
-    }
-
-    @Override
-    public void sendCdmaSms(byte[] pdu, Message response) {
-    }
-
-    @Override
-    public void deleteSmsOnSim(int index, Message response) {
-    }
-
-    @Override
-    public void deleteSmsOnRuim(int index, Message response) {
-    }
-
-    @Override
-    public void writeSmsToSim(int status, String smsc, String pdu, Message response) {
-    }
-
-    @Override
-    public void writeSmsToRuim(int status, String pdu, Message response) {
-    }
-
-    @Override
-    public void setRadioPower(boolean on, Message response) {
-    }
-
-    @Override
-    public void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message response) {
-    }
-
-    @Override
-    public void iccIO(int command, int fileid, String path, int p1, int p2, int p3, String data,
-            String pin2, Message response) {
-    }
-
-    @Override
-    public void queryCLIP(Message response) {
-    }
-
-    @Override
-    public void getCLIR(Message response) {
-    }
-
-    @Override
-    public void setCLIR(int clirMode, Message response) {
-    }
-
-    @Override
-    public void queryCallWaiting(int serviceClass, Message response) {
-    }
-
-    @Override
-    public void setCallWaiting(boolean enable, int serviceClass, Message response) {
-    }
-
-    @Override
-    public void setCallForward(int action, int cfReason, int serviceClass, String number,
-            int timeSeconds, Message response) {
-    }
-
-    @Override
-    public void queryCallForwardStatus(int cfReason, int serviceClass, String number,
-            Message response) {
-    }
-
-    @Override
-    public void setNetworkSelectionModeAutomatic(Message response) {
-    }
-
-    @Override
-    public void setNetworkSelectionModeManual(String operatorNumeric, Message response) {
-    }
-
-    @Override
-    public void getNetworkSelectionMode(Message response) {
-    }
-
-    @Override
-    public void getAvailableNetworks(Message response) {
-    }
-
-    @Override
-    public void getBasebandVersion(Message response) {
-    }
-
-    @Override
-    public void queryFacilityLock(String facility, String password, int serviceClass,
-            Message response) {
-    }
-
-    @Override
-    public void queryFacilityLockForApp(String facility, String password, int serviceClass,
-            String appId, Message response) {
-    }
-
-    @Override
-    public void setFacilityLock(String facility, boolean lockState, String password,
-            int serviceClass, Message response) {
-    }
-
-    @Override
-    public void setFacilityLockForApp(String facility, boolean lockState, String password,
-            int serviceClass, String appId, Message response) {
-    }
-
-    @Override
-    public void sendUSSD(String ussdString, Message response) {
-    }
-
-    @Override
-    public void cancelPendingUssd(Message response) {
-    }
-
-    @Override
-    public void resetRadio(Message result) {
-    }
-
-    @Override
-    public void setBandMode(int bandMode, Message response) {
-    }
-
-    @Override
-    public void queryAvailableBandMode(Message response) {
-    }
-
-    @Override
-    public void setPreferredNetworkType(int networkType, Message response) {
-    }
-
-    @Override
-    public void getPreferredNetworkType(Message response) {
-    }
-
-    @Override
-    public void getNeighboringCids(Message response) {
-    }
-
-    @Override
-    public void setLocationUpdates(boolean enable, Message response) {
-    }
-
-    @Override
-    public void getSmscAddress(Message result) {
-    }
-
-    @Override
-    public void setSmscAddress(String address, Message result) {
-    }
-
-    @Override
-    public void reportSmsMemoryStatus(boolean available, Message result) {
-    }
-
-    @Override
-    public void reportStkServiceIsRunning(Message result) {
-    }
-
-    @Override
-    public void invokeOemRilRequestRaw(byte[] data, Message response) {
-    }
-
-    @Override
-    public void invokeOemRilRequestStrings(String[] strings, Message response) {
-    }
-
-    @Override
-    public void sendTerminalResponse(String contents, Message response) {
-    }
-
-    @Override
-    public void sendEnvelope(String contents, Message response) {
-    }
-
-    @Override
-    public void handleCallSetupRequestFromSim(boolean accept, Message response) {
-    }
-
-    @Override
-    public void setGsmBroadcastActivation(boolean activate, Message result) {
-    }
-
-    @Override
-    public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response) {
-    }
-
-    @Override
-    public void getGsmBroadcastConfig(Message response) {
-    }
-
-    @Override
-    public void getDeviceIdentity(Message response) {
-    }
-
-    @Override
-    public void getCDMASubscription(Message response) {
-    }
-
-    @Override
-    public void sendCDMAFeatureCode(String FeatureCode, Message response) {
-    }
-
-    @Override
-    public void setPhoneType(int phoneType) {
-    }
-
-    @Override
-    public void queryCdmaRoamingPreference(Message response) {
-    }
-
-    @Override
-    public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
-    }
-
-    @Override
-    public void setCdmaSubscriptionSource(int cdmaSubscriptionType, Message response) {
-    }
-
-    @Override
-    public void getCdmaSubscriptionSource(Message response) {
-    }
-
-    @Override
-    public void setTTYMode(int ttyMode, Message response) {
-    }
-
-    @Override
-    public void queryTTYMode(Message response) {
-    }
-
-    @Override
-    public void setupDataCall(String radioTechnology, String profile, String apn, String user,
-            String password, String authType, String protocol, Message result) {
-    }
-
-    @Override
-    public void deactivateDataCall(int cid, int reason, Message result) {
-    }
-
-    @Override
-    public void setCdmaBroadcastActivation(boolean activate, Message result) {
-    }
-
-    @Override
-    public void setCdmaBroadcastConfig(int[] configValuesArray, Message result) {
-    }
-
-    @Override
-    public void getCdmaBroadcastConfig(Message result) {
-    }
-
-    @Override
-    public void exitEmergencyCallbackMode(Message response) {
-    }
-
-    @Override
-    public void getIccCardStatus(Message result) {
-    }
-
-    @Override
-    public void requestIsimAuthentication(String nonce, Message response) {
-    }
-
-    @Override
-    public void getVoiceRadioTechnology(Message response) {
-    }
-
-    @Override
-    public void getIMSIForApp(String aid, Message result) {
-    }
-
-    @Override
-    public void iccIOForApp(int command, int fileid, String path, int p1, int p2, int p3,
-            String data, String pin2, String aid, Message response) {
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadTest.java
deleted file mode 100644
index 6c8ba5e..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadTest.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2011 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.internal.telephony.gsm;
-
-import android.os.HandlerThread;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-import java.nio.charset.Charset;
-
-/**
- * Test SMS-PP data download to UICC.
- * Uses test messages from 3GPP TS 31.124 section 27.22.5.
- */
-public class UsimDataDownloadTest extends AndroidTestCase {
-    private static final String TAG = "UsimDataDownloadTest";
-
-    class TestHandlerThread extends HandlerThread {
-        private UsimDataDownloadHandler mHandler;
-
-        TestHandlerThread() {
-            super("TestHandlerThread");
-        }
-
-        @Override
-        protected void onLooperPrepared() {
-            synchronized (this) {
-                mHandler = new UsimDataDownloadHandler(mCm);
-                notifyAll();
-            }
-        }
-
-        UsimDataDownloadHandler getHandler() {
-            synchronized (this) {
-                while (mHandler == null) {
-                    try {
-                        wait();
-                    } catch (InterruptedException ignored) {}
-                }
-                return mHandler;
-            }
-        }
-    }
-
-    private UsimDataDownloadCommands mCm;
-    private TestHandlerThread mHandlerThread;
-    UsimDataDownloadHandler mHandler;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mCm = new UsimDataDownloadCommands(mContext);
-        mHandlerThread = new TestHandlerThread();
-        mHandlerThread.start();
-        mHandler = mHandlerThread.getHandler();
-        Log.d(TAG, "mHandler is constructed");
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mHandlerThread.quit();
-        super.tearDown();
-    }
-
-    // SMS-PP Message 3.1.1
-    private static final byte[] SMS_PP_MESSAGE_3_1_1 = {
-            // Service center address
-            0x09, (byte) 0x91, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, (byte) 0xf8,
-
-            0x04, 0x04, (byte) 0x91, 0x21, 0x43, 0x7f, 0x16, (byte) 0x89, 0x10, 0x10, 0x00, 0x00,
-            0x00, 0x00, 0x0d, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61,
-            0x67, 0x65, 0x20, 0x31
-    };
-
-    // SMS-PP Download Envelope 3.1.1
-    private static final String SMS_PP_ENVELOPE_3_1_1 = "d12d8202838106099111223344556677f88b1c04"
-            + "049121437f16891010000000000d546573744d6573736167652031";
-
-    // SMS-PP Message 3.1.5
-    private static final byte[] SMS_PP_MESSAGE_3_1_5 = {
-            // Service center address
-            0x09, (byte) 0x91, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, (byte) 0xf8,
-
-            0x44, 0x04, (byte) 0x91, 0x21, 0x43, 0x7f, (byte) 0xf6, (byte) 0x89, 0x10, 0x10, 0x00,
-            0x00, 0x00, 0x00, 0x1e, 0x02, 0x70, 0x00, 0x00, 0x19, 0x00, 0x0d, 0x00, 0x00,
-            0x00, 0x00, (byte) 0xbf, (byte) 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
-            (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, (byte) 0xdc,
-            (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, (byte) 0xdc
-    };
-
-    // SMS-PP Download Envelope 3.1.5
-    private static final String SMS_PP_ENVELOPE_3_1_5 = "d13e8202838106099111223344556677f88b2d44"
-            + "049121437ff6891010000000001e0270000019000d00000000bfff00000000000100"
-            + "dcdcdcdcdcdcdcdcdcdc";
-
-    public void testDataDownloadMessage1() {
-        SmsMessage message = SmsMessage.createFromPdu(SMS_PP_MESSAGE_3_1_1);
-        assertTrue("message is SMS-PP data download", message.isUsimDataDownload());
-
-        mCm.expectSendEnvelope(SMS_PP_ENVELOPE_3_1_1, 0x90, 0x00, "");
-        mCm.expectAcknowledgeGsmSms(true, 0);
-        mHandler.startDataDownload(message);
-        mCm.assertExpectedMethodsCalled();
-
-        mCm.expectSendEnvelope(SMS_PP_ENVELOPE_3_1_1, 0x90, 0x00, "0123456789");
-        mCm.expectAcknowledgeGsmSmsWithPdu(true, "00077f16050123456789");
-        mHandler.startDataDownload(message);
-        mCm.assertExpectedMethodsCalled();
-
-        mCm.expectSendEnvelope(SMS_PP_ENVELOPE_3_1_1, 0x62, 0xff, "0123456789abcdef");
-        mCm.expectAcknowledgeGsmSmsWithPdu(false, "00d5077f16080123456789abcdef");
-        mHandler.startDataDownload(message);
-        mCm.assertExpectedMethodsCalled();
-    }
-
-    public void testDataDownloadMessage5() {
-        SmsMessage message = SmsMessage.createFromPdu(SMS_PP_MESSAGE_3_1_5);
-        assertTrue("message is SMS-PP data download", message.isUsimDataDownload());
-
-        mCm.expectSendEnvelope(SMS_PP_ENVELOPE_3_1_5, 0x90, 0x00, "9876543210");
-        mCm.expectAcknowledgeGsmSmsWithPdu(true, "00077ff6059876543210");
-        mHandler.startDataDownload(message);
-        mCm.assertExpectedMethodsCalled();
-
-        mCm.expectSendEnvelope(SMS_PP_ENVELOPE_3_1_5, 0x93, 0x00, "");
-        mCm.expectAcknowledgeGsmSms(false, 0xd4);   // SIM toolkit busy
-        mHandler.startDataDownload(message);
-        mCm.assertExpectedMethodsCalled();
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimServiceTableTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimServiceTableTest.java
deleted file mode 100644
index 56854ed..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimServiceTableTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2011 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.internal.telephony.gsm;
-
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-/**
- * Test UsimServiceTable class.
- */
-public class UsimServiceTableTest extends AndroidTestCase {
-
-    @SmallTest
-    public void testUsimServiceTable() {
-        byte[] noServices = {0x00};
-        byte[] service1 = {0x01, 0x00};
-        byte[] service8 = {(byte) 0x80, 0x00, 0x00};
-        byte[] service8And9 = {(byte) 0x80, 0x01};
-        byte[] service28 = {0x00, 0x00, 0x00, 0x08};
-        byte[] service89To96 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                0x00, (byte) 0xff};
-
-        UsimServiceTable testTable1 = new UsimServiceTable(noServices);
-        assertFalse(testTable1.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
-        assertFalse(testTable1.isAvailable(UsimServiceTable.UsimService.FDN));
-        assertFalse(testTable1.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
-
-        UsimServiceTable testTable2 = new UsimServiceTable(service1);
-        assertTrue(testTable2.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
-        assertFalse(testTable2.isAvailable(UsimServiceTable.UsimService.FDN));
-        assertFalse(testTable2.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
-
-        UsimServiceTable testTable3 = new UsimServiceTable(service8);
-        assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
-        assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.BDN_EXTENSION));
-        assertTrue(testTable3.isAvailable(UsimServiceTable.UsimService.OUTGOING_CALL_INFO));
-        assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.INCOMING_CALL_INFO));
-        assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
-
-        UsimServiceTable testTable4 = new UsimServiceTable(service8And9);
-        assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
-        assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.BDN_EXTENSION));
-        assertTrue(testTable4.isAvailable(UsimServiceTable.UsimService.OUTGOING_CALL_INFO));
-        assertTrue(testTable4.isAvailable(UsimServiceTable.UsimService.INCOMING_CALL_INFO));
-        assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.SM_STORAGE));
-        assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
-
-        UsimServiceTable testTable5 = new UsimServiceTable(service28);
-        assertFalse(testTable5.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
-        assertTrue(testTable5.isAvailable(UsimServiceTable.UsimService.DATA_DL_VIA_SMS_PP));
-        assertFalse(testTable5.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
-
-        UsimServiceTable testTable6 = new UsimServiceTable(service89To96);
-        assertFalse(testTable6.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
-        assertFalse(testTable6.isAvailable(UsimServiceTable.UsimService.HPLMN_DIRECT_ACCESS));
-        assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.ECALL_DATA));
-        assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.SM_OVER_IP));
-        assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.UICC_ACCESS_TO_IMS));
-        assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
-    }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/mockril/MockRilTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/mockril/MockRilTest.java
deleted file mode 100644
index 3149ee1..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/mockril/MockRilTest.java
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Copyright (C) 2010 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.internal.telephony.mockril;
-
-import android.util.Log;
-import android.test.InstrumentationTestCase;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-import com.android.internal.communication.MsgHeader;
-import com.android.internal.communication.Msg;
-import com.android.internal.telephony.RilChannel;
-import com.android.internal.telephony.ril_proto.RilCtrlCmds;
-import com.android.internal.telephony.ril_proto.RilCmds;
-
-import com.android.frameworks.telephonytests.TelephonyMockRilTestRunner;
-import com.google.protobuf.micro.InvalidProtocolBufferMicroException;
-
-// Test suite for test ril
-public class MockRilTest extends InstrumentationTestCase {
-    private static final String TAG = "MockRilTest";
-
-    RilChannel mMockRilChannel;
-    TelephonyMockRilTestRunner mRunner;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mRunner = (TelephonyMockRilTestRunner)getInstrumentation();
-        mMockRilChannel = mRunner.mMockRilChannel;
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    static void log(String s) {
-        Log.v(TAG, s);
-    }
-
-    /**
-     * Test Case 1: Test protobuf serialization and deserialization
-     * @throws InvalidProtocolBufferMicroException
-     */
-    public void testProtobufSerDes() throws InvalidProtocolBufferMicroException {
-        log("testProtobufSerdes E");
-
-        RilCtrlCmds.CtrlRspRadioState rs = new RilCtrlCmds.CtrlRspRadioState();
-        assertTrue(String.format("expected rs.state == 0 was %d", rs.getState()),
-                rs.getState() == 0);
-        rs.setState(1);
-        assertTrue(String.format("expected rs.state == 1 was %d", rs.getState()),
-                rs.getState() == 1);
-
-        byte[] rs_ser = rs.toByteArray();
-        RilCtrlCmds.CtrlRspRadioState rsNew = RilCtrlCmds.CtrlRspRadioState.parseFrom(rs_ser);
-        assertTrue(String.format("expected rsNew.state == 1 was %d", rs.getState()),
-                rs.getState() == 1);
-
-        log("testProtobufSerdes X");
-    }
-
-    /**
-     * Test case 2: Test echo command works using writeMsg & readMsg
-     */
-    public void testEchoMsg() throws IOException {
-        log("testEchoMsg E");
-
-        MsgHeader mh = new MsgHeader();
-        mh.setCmd(0);
-        mh.setToken(1);
-        mh.setStatus(2);
-        ByteBuffer data = ByteBuffer.allocate(3);
-        data.put((byte)3);
-        data.put((byte)4);
-        data.put((byte)5);
-        Msg.send(mMockRilChannel, mh, data);
-
-        Msg respMsg = Msg.recv(mMockRilChannel);
-        assertTrue(String.format("expected mhd.header.cmd == 0 was %d",respMsg.getCmd()),
-                respMsg.getCmd() == 0);
-        assertTrue(String.format("expected mhd.header.token == 1 was %d",respMsg.getToken()),
-                respMsg.getToken() == 1);
-        assertTrue(String.format("expected mhd.header.status == 2 was %d", respMsg.getStatus()),
-                respMsg.getStatus() == 2);
-        assertTrue(String.format("expected mhd.data[0] == 3 was %d", respMsg.getData(0)),
-                respMsg.getData(0) == 3);
-        assertTrue(String.format("expected mhd.data[1] == 4 was %d", respMsg.getData(1)),
-                respMsg.getData(1) == 4);
-        assertTrue(String.format("expected mhd.data[2] == 5 was %d", respMsg.getData(2)),
-                respMsg.getData(2) == 5);
-
-        log("testEchoMsg X");
-    }
-
-    /**
-     * Test case 3: Test get as
-     */
-    public void testGetAs() {
-        log("testGetAs E");
-
-        // Use a message header as the protobuf data content
-        MsgHeader mh = new MsgHeader();
-        mh.setCmd(12345);
-        mh.setToken(9876);
-        mh.setStatus(7654);
-        mh.setLengthData(4321);
-        byte[] data = mh.toByteArray();
-        MsgHeader mhResult = Msg.getAs(MsgHeader.class, data);
-
-        assertTrue(String.format("expected cmd == 12345 was %d", mhResult.getCmd()),
-                mhResult.getCmd() == 12345);
-        assertTrue(String.format("expected token == 9876 was %d", mhResult.getToken()),
-                mhResult.getToken() == 9876);
-        assertTrue(String.format("expected status == 7654 was %d", mhResult.getStatus()),
-                mhResult.getStatus() == 7654);
-        assertTrue(String.format("expected lengthData == 4321 was %d", mhResult.getLengthData()),
-                mhResult.getLengthData() == 4321);
-
-        Msg msg = Msg.obtain();
-        msg.setData(ByteBuffer.wrap(data));
-
-        mhResult = msg.getDataAs(MsgHeader.class);
-
-        assertTrue(String.format("expected cmd == 12345 was %d", mhResult.getCmd()),
-                mhResult.getCmd() == 12345);
-        assertTrue(String.format("expected token == 9876 was %d", mhResult.getToken()),
-                mhResult.getToken() == 9876);
-        assertTrue(String.format("expected status == 7654 was %d", mhResult.getStatus()),
-                mhResult.getStatus() == 7654);
-        assertTrue(String.format("expected lengthData == 4321 was %d", mhResult.getLengthData()),
-                mhResult.getLengthData() == 4321);
-
-        log("testGetAs X");
-    }
-
-    /**
-     * Test case 3: test get radio state
-     */
-    public void testGetRadioState() throws IOException {
-        log("testGetRadioState E");
-
-        Msg.send(mMockRilChannel, 1, 9876, 0, null);
-
-        Msg resp = Msg.recv(mMockRilChannel);
-        //resp.printHeader("testGetRadioState");
-
-        assertTrue(String.format("expected cmd == 1 was %d", resp.getCmd()),
-                resp.getCmd() == 1);
-        assertTrue(String.format("expected token == 9876 was %d", resp.getToken()),
-                resp.getToken() == 9876);
-        assertTrue(String.format("expected status == 0 was %d", resp.getStatus()),
-                resp.getStatus() == 0);
-
-        RilCtrlCmds.CtrlRspRadioState rsp = resp.getDataAs(RilCtrlCmds.CtrlRspRadioState.class);
-
-        int state = rsp.getState();
-        log("testGetRadioState state=" + state);
-        assertTrue(String.format("expected RadioState >= 0 && RadioState <= 9 was %d", state),
-                ((state >= 0) && (state <= 9)));
-
-        log("testGetRadioState X");
-    }
-
-    /**
-     * Test case 5: test set radio state
-     */
-    public void testSetRadioState() throws IOException {
-        log("testSetRadioState E");
-
-        RilCtrlCmds.CtrlReqRadioState cmdrs = new RilCtrlCmds.CtrlReqRadioState();
-        assertEquals(0, cmdrs.getState());
-
-        cmdrs.setState(RilCmds.RADIOSTATE_SIM_NOT_READY);
-        assertEquals(2, cmdrs.getState());
-
-        Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_RADIO_STATE, 0, 0, cmdrs);
-
-        Msg resp = Msg.recv(mMockRilChannel);
-        log("get response status :" + resp.getStatus());
-        log("get response for command: " + resp.getCmd());
-        log("get command token: " + resp.getToken());
-
-        RilCtrlCmds.CtrlRspRadioState rsp = resp.getDataAs(RilCtrlCmds.CtrlRspRadioState.class);
-
-        int state = rsp.getState();
-        log("get response for testSetRadioState: " + state);
-        assertTrue(RilCmds.RADIOSTATE_SIM_NOT_READY == state);
-    }
-
-    /**
-     * Test case 6: test start incoming call and hangup it.
-     */
-    public void testStartIncomingCallAndHangup() throws IOException {
-        log("testStartIncomingCallAndHangup");
-        RilCtrlCmds.CtrlReqSetMTCall cmd = new RilCtrlCmds.CtrlReqSetMTCall();
-        String incomingCall = "6502889108";
-        // set the MT call
-        cmd.setPhoneNumber(incomingCall);
-        Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_MT_CALL, 0, 0, cmd);
-        // get response
-        Msg resp = Msg.recv(mMockRilChannel);
-        log("Get response status: " + resp.getStatus());
-        assertTrue("The ril is not in a proper state to set MT calls.",
-                   resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
-
-        // allow the incoming call alerting for some time
-        try {
-            Thread.sleep(5000);
-        } catch (InterruptedException e) {}
-
-        // we are playing a trick to assume the current is 1
-        RilCtrlCmds.CtrlHangupConnRemote hangupCmd = new RilCtrlCmds.CtrlHangupConnRemote();
-        hangupCmd.setConnectionId(1);
-        hangupCmd.setCallFailCause(16);   // normal hangup
-        Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_HANGUP_CONN_REMOTE, 0, 0, hangupCmd);
-
-        // get response
-        resp = Msg.recv(mMockRilChannel);
-        log("Get response for hangup connection: " + resp.getStatus());
-        assertTrue("CTRL_CMD_HANGUP_CONN_REMOTE failed",
-                   resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
-    }
-
-    /**
-     * Test case 7: test set call transition flag
-     */
-    public void testSetCallTransitionFlag() throws IOException {
-        log("testSetCallTransitionFlag");
-        // Set flag to true:
-        RilCtrlCmds.CtrlSetCallTransitionFlag cmd = new RilCtrlCmds.CtrlSetCallTransitionFlag();
-        cmd.setFlag(true);
-        Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_CALL_TRANSITION_FLAG, 0, 0, cmd);
-
-        Msg resp = Msg.recv(mMockRilChannel);
-        log("Get response status: " + resp.getStatus());
-        assertTrue("Set call transition flag failed",
-                   resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
-
-        // add a dialing call
-        RilCtrlCmds.CtrlReqAddDialingCall cmdDialCall = new RilCtrlCmds.CtrlReqAddDialingCall();
-        String phoneNumber = "5102345678";
-        cmdDialCall.setPhoneNumber(phoneNumber);
-        Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_ADD_DIALING_CALL, 0, 0, cmdDialCall);
-        resp = Msg.recv(mMockRilChannel);
-        log("Get response status for adding a dialing call: " + resp.getStatus());
-        assertTrue("add dialing call failed",
-                   resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
-        try {
-            Thread.sleep(5000);
-        } catch (InterruptedException e) {}
-
-        // send command to force call state change
-        Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_CALL_ALERT, 0, 0, null);
-        resp = Msg.recv(mMockRilChannel);
-        log("Get response status: " + resp.getStatus());
-        assertTrue("Set call alert failed",
-                   resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
-
-        try {
-            Thread.sleep(2000);
-        } catch (InterruptedException e) {}
-
-        // send command to force call state change
-        Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_CALL_ACTIVE, 0, 0, null);
-        resp = Msg.recv(mMockRilChannel);
-        log("Get response status: " + resp.getStatus());
-        assertTrue("Set call active failed",
-                   resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
-
-        // hangup the active all remotely
-        RilCtrlCmds.CtrlHangupConnRemote hangupCmd = new RilCtrlCmds.CtrlHangupConnRemote();
-        hangupCmd.setConnectionId(1);
-        hangupCmd.setCallFailCause(16);   // normal hangup
-        Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_HANGUP_CONN_REMOTE, 0, 0, hangupCmd);
-        resp = Msg.recv(mMockRilChannel);
-        log("Get response for hangup connection: " + resp.getStatus());
-        assertTrue("CTRL_CMD_HANGUP_CONN_REMOTE failed",
-                   resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
-
-        // set the flag to false
-        cmd.setFlag(false);
-        Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_CALL_TRANSITION_FLAG, 0, 0, cmd);
-        resp = Msg.recv(mMockRilChannel);
-        assertTrue("Set call transition flag failed",
-                   resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
-    }
-}
diff --git a/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/BallsView.java b/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/BallsView.java
index b3b3756..041782d 100644
--- a/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/BallsView.java
+++ b/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/BallsView.java
@@ -105,7 +105,7 @@
     }
 
     void setAccel(float x, float y, float z) {
-        if (mRender == null) {
+        if ((mRender == null) || (mRS == null)) {
             return;
         }
         mRender.setAccel(x, -y);
diff --git a/tests/permission/Android.mk b/tests/permission/Android.mk
index a6df98e..31a0daf 100644
--- a/tests/permission/Android.mk
+++ b/tests/permission/Android.mk
@@ -7,7 +7,7 @@
 # Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common
 LOCAL_PACKAGE_NAME := FrameworkPermissionTests
 
 include $(BUILD_PACKAGE)
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index f2fa3f5..46b8a27 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -58,7 +58,7 @@
 
 // The default to use if no other ignore pattern is defined.
 const char * const gDefaultIgnoreAssets =
-    "!.svn:!.git:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*.scc:*~";
+    "!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~";
 // The ignore pattern that can be passed via --ignore-assets in Main.cpp
 const char * gUserIgnoreAssets = NULL;
 
diff --git a/tools/aapt/Android.mk b/tools/aapt/Android.mk
index d0a81dc..d9b0681 100644
--- a/tools/aapt/Android.mk
+++ b/tools/aapt/Android.mk
@@ -29,8 +29,11 @@
 
 
 LOCAL_CFLAGS += -Wno-format-y2k
+ifeq (darwin,$(HOST_OS))
+LOCAL_CFLAGS += -D_DARWIN_UNLIMITED_STREAMS
+endif
 
-LOCAL_C_INCLUDES += external/expat/lib
+
 LOCAL_C_INCLUDES += external/libpng
 LOCAL_C_INCLUDES += external/zlib
 LOCAL_C_INCLUDES += build/libs/host/include
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 8e0be1c..fde3bd6 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -51,9 +51,8 @@
           mUpdate(false), mExtending(false),
           mRequireLocalization(false), mPseudolocalize(false),
           mWantUTF16(false), mValues(false),
-          mCompressionMethod(0), mOutputAPKFile(NULL),
+          mCompressionMethod(0), mJunkPath(false), mOutputAPKFile(NULL),
           mManifestPackageNameOverride(NULL), mInstrumentationPackageNameOverride(NULL),
-          mIsOverlayPackage(false),
           mAutoAddOverlay(false), mGenDependencies(false),
           mAssetSourceDir(NULL), 
           mCrunchedOutputDir(NULL), mProguardFile(NULL),
@@ -108,8 +107,6 @@
     void setManifestPackageNameOverride(const char * val) { mManifestPackageNameOverride = val; }
     const char* getInstrumentationPackageNameOverride() const { return mInstrumentationPackageNameOverride; }
     void setInstrumentationPackageNameOverride(const char * val) { mInstrumentationPackageNameOverride = val; }
-    bool getIsOverlayPackage() const { return mIsOverlayPackage; }
-    void setIsOverlayPackage(bool val) { mIsOverlayPackage = val; }
     bool getAutoAddOverlay() { return mAutoAddOverlay; }
     void setAutoAddOverlay(bool val) { mAutoAddOverlay = val; }
     bool getGenDependencies() { return mGenDependencies; }
@@ -255,7 +252,6 @@
     const char* mOutputAPKFile;
     const char* mManifestPackageNameOverride;
     const char* mInstrumentationPackageNameOverride;
-    bool        mIsOverlayPackage;
     bool        mAutoAddOverlay;
     bool        mGenDependencies;
     const char* mAssetSourceDir;
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index d48394a..f398de0 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -69,7 +69,6 @@
         "        [-F apk-file] [-J R-file-dir] \\\n"
         "        [--product product1,product2,...] \\\n"
         "        [-c CONFIGS] [--preferred-configurations CONFIGS] \\\n"
-        "        [-o] \\\n"
         "        [raw-files-dir [raw-files-dir] ...] \\\n"
         "        [--output-text-symbols DIR]\n"
         "\n"
@@ -111,7 +110,6 @@
         "   -j  specify a jar or zip file containing classes to include\n"
         "   -k  junk path of file(s) added\n"
         "   -m  make package directories under location specified by -J\n"
-        "   -o  create overlay package (ie only resources; expects <overlay-package> in manifest)\n"
 #if 0
         "   -p  pseudolocalize the default configuration\n"
 #endif
@@ -305,9 +303,6 @@
             case 'm':
                 bundle.setMakePackageDirs(true);
                 break;
-            case 'o':
-                bundle.setIsOverlayPackage(true);
-                break;
 #if 0
             case 'p':
                 bundle.setPseudolocalize(true);
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 0195727..d98fe65 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -2749,6 +2749,12 @@
             const bool filterable = (typeName != mipmap16);
 
             const size_t N = t != NULL ? t->getOrderedConfigs().size() : 0;
+
+            // Until a non-NO_ENTRY value has been written for a resource,
+            // that resource is invalid; validResources[i] represents
+            // the item at t->getOrderedConfigs().itemAt(i).
+            Vector<bool> validResources;
+            validResources.insertAt(false, 0, N);
             
             // First write the typeSpec chunk, containing information about
             // each resource entry in this type.
@@ -2885,6 +2891,7 @@
                         if (amt < 0) {
                             return amt;
                         }
+                        validResources.editItemAt(ei) = true;
                     } else {
                         index[ei] = htodl(ResTable_type::NO_ENTRY);
                     }
@@ -2895,6 +2902,14 @@
                     (((uint8_t*)data->editData()) + typeStart);
                 tHeader->header.size = htodl(data->getSize()-typeStart);
             }
+
+            for (size_t i = 0; i < N; ++i) {
+                if (!validResources[i]) {
+                    sp<ConfigList> c = t->getOrderedConfigs().itemAt(i);
+                    fprintf(stderr, "warning: no entries written for %s/%s\n",
+                            String8(typeName).string(), String8(c->getName()).string());
+                }
+            }
         }
 
         // Fill in the rest of the package information.
@@ -3723,9 +3738,7 @@
 {
     sp<Package> p = mPackages.valueFor(package);
     if (p == NULL) {
-        if (mBundle->getIsOverlayPackage()) {
-            p = new Package(package, 0x00);
-        } else if (mIsAppPackage) {
+        if (mIsAppPackage) {
             if (mHaveAppPackage) {
                 fprintf(stderr, "Adding multiple application package resources; only one is allowed.\n"
                                 "Use -x to create extended resources.\n");
diff --git a/tools/aapt/StringPool.h b/tools/aapt/StringPool.h
index d501008..16050b2 100644
--- a/tools/aapt/StringPool.h
+++ b/tools/aapt/StringPool.h
@@ -21,7 +21,7 @@
 #include <ctype.h>
 #include <errno.h>
 
-#include <expat.h>
+#include <libexpat/expat.h>
 
 using namespace android;
 
diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp
index 0dba950..dcbe7db 100644
--- a/tools/aapt/XMLNode.cpp
+++ b/tools/aapt/XMLNode.cpp
@@ -511,7 +511,8 @@
             namespaces.pop();
         } else if (code == ResXMLTree::TEXT) {
             size_t len;
-            printf("%sC: \"%s\"\n", prefix.string(), String8(block->getText(&len)).string());
+            printf("%sC: \"%s\"\n", prefix.string(),
+                    ResTable::normalizeForOutput(String8(block->getText(&len)).string()).string());
         }
     }
 
diff --git a/tools/aidl/generate_java_binder.cpp b/tools/aidl/generate_java_binder.cpp
index 2e459a8..f80a388 100644
--- a/tools/aidl/generate_java_binder.cpp
+++ b/tools/aidl/generate_java_binder.cpp
@@ -54,7 +54,7 @@
 
     // asBinder
     Method* asBinder = new Method;
-        asBinder->modifiers = PUBLIC;
+        asBinder->modifiers = PUBLIC | OVERRIDE;
         asBinder->returnType = IBINDER_TYPE;
         asBinder->name = "asBinder";
         asBinder->statements = new StatementBlock;
@@ -117,7 +117,7 @@
     queryLocalInterface->arguments.push_back(new LiteralExpression("DESCRIPTOR"));
     IInterfaceType* iinType = new IInterfaceType();
     Variable *iin = new Variable(iinType, "iin");
-    VariableDeclaration* iinVd = new VariableDeclaration(iin, queryLocalInterface, iinType);
+    VariableDeclaration* iinVd = new VariableDeclaration(iin, queryLocalInterface, NULL);
     m->statements->Add(iinVd);
 
     // Ensure the instance type of the local object is as expected.
@@ -181,7 +181,7 @@
 
     // IBinder asBinder()
     Method* asBinder = new Method;
-        asBinder->modifiers = PUBLIC;
+        asBinder->modifiers = PUBLIC | OVERRIDE;
         asBinder->returnType = IBINDER_TYPE;
         asBinder->name = "asBinder";
         asBinder->statements = new StatementBlock;
@@ -384,7 +384,7 @@
     // == the proxy method ===================================================
     Method* proxy = new Method;
         proxy->comment = gather_comments(method->comments_token->extra);
-        proxy->modifiers = PUBLIC;
+        proxy->modifiers = PUBLIC | OVERRIDE;
         proxy->returnType = NAMES.Search(method->type.type.data);
         proxy->returnTypeDimension = method->type.dimension;
         proxy->name = method->name.data;
diff --git a/tools/layoutlib/bridge/.classpath b/tools/layoutlib/bridge/.classpath
index 9fb000e..a5db7b1 100644
--- a/tools/layoutlib/bridge/.classpath
+++ b/tools/layoutlib/bridge/.classpath
@@ -3,7 +3,7 @@
 	<classpathentry excluding="org/kxml2/io/" kind="src" path="src"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/layoutlib_api/layoutlib_api-prebuilt.jar"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
+	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/ninepatch/ninepatch-prebuilt.jar"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/tools-common/tools-common-prebuilt.jar"/>
diff --git a/tools/layoutlib/bridge/tests/.classpath b/tools/layoutlib/bridge/tests/.classpath
index 027bc67..2b32e09 100644
--- a/tools/layoutlib/bridge/tests/.classpath
+++ b/tools/layoutlib/bridge/tests/.classpath
@@ -4,7 +4,7 @@
 	<classpathentry kind="src" path="res"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/layoutlib_bridge"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
+	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
 	<classpathentry kind="output" path="bin"/>
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java
new file mode 100755
index 0000000..c988c70
--- /dev/null
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java
@@ -0,0 +1,787 @@
+/*
+ * Copyright (C) 2012 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.tools.layoutlib.create;
+
+import com.android.tools.layoutlib.annotations.VisibleForTesting;
+import com.android.tools.layoutlib.annotations.VisibleForTesting.Visibility;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.signature.SignatureReader;
+import org.objectweb.asm.signature.SignatureVisitor;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+/**
+ * Analyzes the input JAR using the ASM java bytecode manipulation library
+ * to list the classes and their dependencies. A "dependency" is a class
+ * used by another class.
+ */
+public class DependencyFinder {
+
+    // Note: a bunch of stuff has package-level access for unit tests. Consider it private.
+
+    /** Output logger. */
+    private final Log mLog;
+
+    /**
+     * Creates a new analyzer.
+     *
+     * @param log The log output.
+     */
+    public DependencyFinder(Log log) {
+        mLog = log;
+    }
+
+    /**
+     * Starts the analysis using parameters from the constructor.
+     *
+     * @param osJarPath The input source JARs to parse.
+     * @return A pair: [0]: map { class FQCN => set of FQCN class dependencies }.
+     *                 [1]: map { missing class FQCN => set of FQCN class that uses it. }
+     */
+    public List<Map<String, Set<String>>> findDeps(List<String> osJarPath) throws IOException {
+
+        Map<String, ClassReader> zipClasses = parseZip(osJarPath);
+        mLog.info("Found %d classes in input JAR%s.",
+                zipClasses.size(),
+                osJarPath.size() > 1 ? "s" : "");
+
+        Map<String, Set<String>> deps = findClassesDeps(zipClasses);
+
+        Map<String, Set<String>> missing = findMissingClasses(deps, zipClasses.keySet());
+
+        List<Map<String, Set<String>>> result = new ArrayList<Map<String,Set<String>>>(2);
+        result.add(deps);
+        result.add(missing);
+        return result;
+    }
+
+    /**
+     * Prints dependencies to the current logger, found stuff and missing stuff.
+     */
+    public void printAllDeps(List<Map<String, Set<String>>> result) {
+        assert result.size() == 2;
+        Map<String, Set<String>> deps = result.get(0);
+        Map<String, Set<String>> missing = result.get(1);
+
+        // Print all dependences found in the format:
+        // +Found: <FQCN from zip>
+        //     uses: FQCN
+
+        mLog.info("++++++ %d Entries found in source JARs", deps.size());
+        mLog.info("");
+
+        for (Entry<String, Set<String>> entry : deps.entrySet()) {
+            mLog.info(    "+Found  : %s", entry.getKey());
+            for (String dep : entry.getValue()) {
+                mLog.info("    uses: %s", dep);
+            }
+
+            mLog.info("");
+        }
+
+
+        // Now print all missing dependences in the format:
+        // -Missing <FQCN>:
+        //     used by: <FQCN>
+
+        mLog.info("");
+        mLog.info("------ %d Entries missing from source JARs", missing.size());
+        mLog.info("");
+
+        for (Entry<String, Set<String>> entry : missing.entrySet()) {
+            mLog.info(    "-Missing  : %s", entry.getKey());
+            for (String dep : entry.getValue()) {
+                mLog.info("   used by: %s", dep);
+            }
+
+            mLog.info("");
+        }
+    }
+
+    /**
+     * Prints only a summary of the missing dependencies to the current logger.
+     */
+    public void printMissingDeps(List<Map<String, Set<String>>> result) {
+        assert result.size() == 2;
+        @SuppressWarnings("unused") Map<String, Set<String>> deps = result.get(0);
+        Map<String, Set<String>> missing = result.get(1);
+
+        for (String fqcn : missing.keySet()) {
+            mLog.info("%s", fqcn);
+        }
+    }
+
+    // ----------------
+
+    /**
+     * Parses a JAR file and returns a list of all classes founds using a map
+     * class name => ASM ClassReader. Class names are in the form "android.view.View".
+     */
+    Map<String,ClassReader> parseZip(List<String> jarPathList) throws IOException {
+        TreeMap<String, ClassReader> classes = new TreeMap<String, ClassReader>();
+
+        for (String jarPath : jarPathList) {
+            ZipFile zip = new ZipFile(jarPath);
+            Enumeration<? extends ZipEntry> entries = zip.entries();
+            ZipEntry entry;
+            while (entries.hasMoreElements()) {
+                entry = entries.nextElement();
+                if (entry.getName().endsWith(".class")) {
+                    ClassReader cr = new ClassReader(zip.getInputStream(entry));
+                    String className = classReaderToClassName(cr);
+                    classes.put(className, cr);
+                }
+            }
+        }
+
+        return classes;
+    }
+
+    /**
+     * Utility that returns the fully qualified binary class name for a ClassReader.
+     * E.g. it returns something like android.view.View.
+     */
+    static String classReaderToClassName(ClassReader classReader) {
+        if (classReader == null) {
+            return null;
+        } else {
+            return classReader.getClassName().replace('/', '.');
+        }
+    }
+
+    /**
+     * Utility that returns the fully qualified binary class name from a path-like FQCN.
+     * E.g. it returns android.view.View from android/view/View.
+     */
+    static String internalToBinaryClassName(String className) {
+        if (className == null) {
+            return null;
+        } else {
+            return className.replace('/', '.');
+        }
+    }
+
+    /**
+     * Finds all dependencies for all classes in keepClasses which are also
+     * listed in zipClasses. Returns a map of all the dependencies found.
+     */
+    Map<String, Set<String>> findClassesDeps(Map<String, ClassReader> zipClasses) {
+
+        // The dependencies that we'll collect.
+        // It's a map Class name => uses class names.
+        Map<String, Set<String>> dependencyMap = new TreeMap<String, Set<String>>();
+
+        DependencyVisitor visitor = getVisitor();
+
+        int count = 0;
+        try {
+            for (Entry<String, ClassReader> entry : zipClasses.entrySet()) {
+                String name = entry.getKey();
+
+                TreeSet<String> set = new TreeSet<String>();
+                dependencyMap.put(name, set);
+                visitor.setDependencySet(set);
+
+                ClassReader cr = entry.getValue();
+                cr.accept(visitor, 0 /* flags */);
+
+                visitor.setDependencySet(null);
+
+                mLog.debugNoln("Visited %d classes\r", ++count);
+            }
+        } finally {
+            mLog.debugNoln("\n");
+        }
+
+        return dependencyMap;
+    }
+
+    /**
+     * Computes which classes FQCN were found as dependencies that are NOT listed
+     * in the original JAR classes.
+     *
+     * @param deps The map { FQCN => dependencies[] } returned by {@link #findClassesDeps(Map)}.
+     * @param zipClasses The set of all classes FQCN found in the JAR files.
+     * @return A map { FQCN not found in the zipClasses => classes using it }
+     */
+    private Map<String, Set<String>> findMissingClasses(
+            Map<String, Set<String>> deps,
+            Set<String> zipClasses) {
+        Map<String, Set<String>> missing = new TreeMap<String, Set<String>>();
+
+        for (Entry<String, Set<String>> entry : deps.entrySet()) {
+            String name = entry.getKey();
+
+            for (String dep : entry.getValue()) {
+                if (!zipClasses.contains(dep)) {
+                    // This dependency doesn't exist in the zip classes.
+                    Set<String> set = missing.get(dep);
+                    if (set == null) {
+                        set = new TreeSet<String>();
+                        missing.put(dep, set);
+                    }
+                    set.add(name);
+                }
+            }
+
+        }
+
+        return missing;
+    }
+
+
+    // ----------------------------------
+
+    /**
+     * Instantiates a new DependencyVisitor. Useful for unit tests.
+     */
+    @VisibleForTesting(visibility=Visibility.PRIVATE)
+    DependencyVisitor getVisitor() {
+        return new DependencyVisitor();
+    }
+
+    /**
+     * Visitor to collect all the type dependencies from a class.
+     */
+    public class DependencyVisitor extends ClassVisitor {
+
+        private Set<String> mCurrentDepSet;
+
+        /**
+         * Creates a new visitor that will find all the dependencies for the visited class.
+         */
+        public DependencyVisitor() {
+            super(Opcodes.ASM4);
+        }
+
+        /**
+         * Sets the {@link Set} where to record direct dependencies for this class.
+         * This will change before each {@link ClassReader#accept(ClassVisitor, int)} call.
+         */
+        public void setDependencySet(Set<String> set) {
+            mCurrentDepSet = set;
+        }
+
+        /**
+         * Considers the given class name as a dependency.
+         */
+        public void considerName(String className) {
+            if (className == null) {
+                return;
+            }
+
+            className = internalToBinaryClassName(className);
+
+            try {
+                // exclude classes that are part of the default JRE (the one executing this program)
+                if (getClass().getClassLoader().loadClass(className) != null) {
+                    return;
+                }
+            } catch (ClassNotFoundException e) {
+                // ignore
+            }
+
+            // Add it to the dependency set for the currently visited class, as needed.
+            assert mCurrentDepSet != null;
+            if (mCurrentDepSet != null) {
+                mCurrentDepSet.add(className);
+            }
+        }
+
+        /**
+         * Considers this array of names using considerName().
+         */
+        public void considerNames(String[] classNames) {
+            if (classNames != null) {
+                for (String className : classNames) {
+                    considerName(className);
+                }
+            }
+        }
+
+        /**
+         * Considers this signature or type signature by invoking the {@link SignatureVisitor}
+         * on it.
+         */
+        public void considerSignature(String signature) {
+            if (signature != null) {
+                SignatureReader sr = new SignatureReader(signature);
+                // SignatureReader.accept will call accessType so we don't really have
+                // to differentiate where the signature comes from.
+                sr.accept(new MySignatureVisitor());
+            }
+        }
+
+        /**
+         * Considers this {@link Type}. For arrays, the element type is considered.
+         * If the type is an object, it's internal name is considered.
+         */
+        public void considerType(Type t) {
+            if (t != null) {
+                if (t.getSort() == Type.ARRAY) {
+                    t = t.getElementType();
+                }
+                if (t.getSort() == Type.OBJECT) {
+                    considerName(t.getInternalName());
+                }
+            }
+        }
+
+        /**
+         * Considers a descriptor string. The descriptor is converted to a {@link Type}
+         * and then considerType() is invoked.
+         */
+        public boolean considerDesc(String desc) {
+            if (desc != null) {
+                try {
+                    if (desc.length() > 0 && desc.charAt(0) == '(') {
+                        // This is a method descriptor with arguments and a return type.
+                        Type t = Type.getReturnType(desc);
+                        considerType(t);
+
+                        for (Type arg : Type.getArgumentTypes(desc)) {
+                            considerType(arg);
+                        }
+
+                    } else {
+                        Type t = Type.getType(desc);
+                        considerType(t);
+                    }
+                    return true;
+                } catch (ArrayIndexOutOfBoundsException e) {
+                    // ignore, not a valid type.
+                }
+            }
+            return false;
+        }
+
+
+        // ---------------------------------------------------
+        // --- ClassVisitor, FieldVisitor
+        // ---------------------------------------------------
+
+        // Visits a class header
+        @Override
+        public void visit(int version, int access, String name,
+                String signature, String superName, String[] interfaces) {
+            // signature is the signature of this class. May be null if the class is not a generic
+            // one, and does not extend or implement generic classes or interfaces.
+
+            if (signature != null) {
+                considerSignature(signature);
+            }
+
+            // superName is the internal of name of the super class (see getInternalName).
+            // For interfaces, the super class is Object. May be null but only for the Object class.
+            considerName(superName);
+
+            // interfaces is the internal names of the class's interfaces (see getInternalName).
+            // May be null.
+            considerNames(interfaces);
+        }
+
+
+        @Override
+        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+            // desc is the class descriptor of the annotation class.
+            considerDesc(desc);
+            return new MyAnnotationVisitor();
+        }
+
+        @Override
+        public void visitAttribute(Attribute attr) {
+            // pass
+        }
+
+        // Visits the end of a class
+        @Override
+        public void visitEnd() {
+            // pass
+        }
+
+        private class MyFieldVisitor extends FieldVisitor {
+
+            public MyFieldVisitor() {
+                super(Opcodes.ASM4);
+            }
+
+            @Override
+            public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+                // desc is the class descriptor of the annotation class.
+                considerDesc(desc);
+                return new MyAnnotationVisitor();
+            }
+
+            @Override
+            public void visitAttribute(Attribute attr) {
+                // pass
+            }
+
+            // Visits the end of a class
+            @Override
+            public void visitEnd() {
+                // pass
+            }
+        }
+
+        @Override
+        public FieldVisitor visitField(int access, String name, String desc,
+                String signature, Object value) {
+            // desc is the field's descriptor (see Type).
+            considerDesc(desc);
+
+            // signature is the field's signature. May be null if the field's type does not use
+            // generic types.
+            considerSignature(signature);
+
+            return new MyFieldVisitor();
+        }
+
+        @Override
+        public void visitInnerClass(String name, String outerName, String innerName, int access) {
+            // name is the internal name of an inner class (see getInternalName).
+            // Note: outerName/innerName seems to be null when we're reading the
+            // _Original_ClassName classes generated by layoutlib_create.
+            if (outerName != null) {
+                considerName(name);
+            }
+        }
+
+        @Override
+        public MethodVisitor visitMethod(int access, String name, String desc,
+                String signature, String[] exceptions) {
+            // desc is the method's descriptor (see Type).
+            considerDesc(desc);
+            // signature is the method's signature. May be null if the method parameters, return
+            // type and exceptions do not use generic types.
+            considerSignature(signature);
+
+            return new MyMethodVisitor();
+        }
+
+        @Override
+        public void visitOuterClass(String owner, String name, String desc) {
+            // pass
+        }
+
+        @Override
+        public void visitSource(String source, String debug) {
+            // pass
+        }
+
+
+        // ---------------------------------------------------
+        // --- MethodVisitor
+        // ---------------------------------------------------
+
+        private class MyMethodVisitor extends MethodVisitor {
+
+            public MyMethodVisitor() {
+                super(Opcodes.ASM4);
+            }
+
+
+            @Override
+            public AnnotationVisitor visitAnnotationDefault() {
+                return new MyAnnotationVisitor();
+            }
+
+            @Override
+            public void visitCode() {
+                // pass
+            }
+
+            // field instruction
+            @Override
+            public void visitFieldInsn(int opcode, String owner, String name, String desc) {
+                // name is the field's name.
+                // desc is the field's descriptor (see Type).
+                considerDesc(desc);
+            }
+
+            @Override
+            public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) {
+                // pass
+            }
+
+            @Override
+            public void visitIincInsn(int var, int increment) {
+                // pass -- an IINC instruction
+            }
+
+            @Override
+            public void visitInsn(int opcode) {
+                // pass -- a zero operand instruction
+            }
+
+            @Override
+            public void visitIntInsn(int opcode, int operand) {
+                // pass -- a single int operand instruction
+            }
+
+            @Override
+            public void visitJumpInsn(int opcode, Label label) {
+                // pass -- a jump instruction
+            }
+
+            @Override
+            public void visitLabel(Label label) {
+                // pass -- a label target
+            }
+
+            // instruction to load a constant from the stack
+            @Override
+            public void visitLdcInsn(Object cst) {
+                if (cst instanceof Type) {
+                    considerType((Type) cst);
+                }
+            }
+
+            @Override
+            public void visitLineNumber(int line, Label start) {
+                // pass
+            }
+
+            @Override
+            public void visitLocalVariable(String name, String desc,
+                    String signature, Label start, Label end, int index) {
+                // desc is the type descriptor of this local variable.
+                considerDesc(desc);
+                // signature is the type signature of this local variable. May be null if the local
+                // variable type does not use generic types.
+                considerSignature(signature);
+            }
+
+            @Override
+            public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
+                // pass -- a lookup switch instruction
+            }
+
+            @Override
+            public void visitMaxs(int maxStack, int maxLocals) {
+                // pass
+            }
+
+            // instruction that invokes a method
+            @Override
+            public void visitMethodInsn(int opcode, String owner, String name, String desc) {
+
+                // owner is the internal name of the method's owner class
+                if (!considerDesc(owner) && owner.indexOf('/') != -1) {
+                    considerName(owner);
+                }
+                // desc is the method's descriptor (see Type).
+                considerDesc(desc);
+            }
+
+            // instruction multianewarray, whatever that is
+            @Override
+            public void visitMultiANewArrayInsn(String desc, int dims) {
+
+                // desc an array type descriptor.
+                considerDesc(desc);
+            }
+
+            @Override
+            public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
+                    boolean visible) {
+                // desc is the class descriptor of the annotation class.
+                considerDesc(desc);
+                return new MyAnnotationVisitor();
+            }
+
+            @Override
+            public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
+                // pass -- table switch instruction
+
+            }
+
+            @Override
+            public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
+                // type is the internal name of the type of exceptions handled by the handler,
+                // or null to catch any exceptions (for "finally" blocks).
+                considerName(type);
+            }
+
+            // type instruction
+            @Override
+            public void visitTypeInsn(int opcode, String type) {
+                // type is the operand of the instruction to be visited. This operand must be the
+                // internal name of an object or array class.
+                considerName(type);
+            }
+
+            @Override
+            public void visitVarInsn(int opcode, int var) {
+                // pass -- local variable instruction
+            }
+        }
+
+        private class MySignatureVisitor extends SignatureVisitor {
+
+            public MySignatureVisitor() {
+                super(Opcodes.ASM4);
+            }
+
+            // ---------------------------------------------------
+            // --- SignatureVisitor
+            // ---------------------------------------------------
+
+            private String mCurrentSignatureClass = null;
+
+            // Starts the visit of a signature corresponding to a class or interface type
+            @Override
+            public void visitClassType(String name) {
+                mCurrentSignatureClass = name;
+                considerName(name);
+            }
+
+            // Visits an inner class
+            @Override
+            public void visitInnerClassType(String name) {
+                if (mCurrentSignatureClass != null) {
+                    mCurrentSignatureClass += "$" + name;
+                    considerName(mCurrentSignatureClass);
+                }
+            }
+
+            @Override
+            public SignatureVisitor visitArrayType() {
+                return new MySignatureVisitor();
+            }
+
+            @Override
+            public void visitBaseType(char descriptor) {
+                // pass -- a primitive type, ignored
+            }
+
+            @Override
+            public SignatureVisitor visitClassBound() {
+                return new MySignatureVisitor();
+            }
+
+            @Override
+            public SignatureVisitor visitExceptionType() {
+                return new MySignatureVisitor();
+            }
+
+            @Override
+            public void visitFormalTypeParameter(String name) {
+                // pass
+            }
+
+            @Override
+            public SignatureVisitor visitInterface() {
+                return new MySignatureVisitor();
+            }
+
+            @Override
+            public SignatureVisitor visitInterfaceBound() {
+                return new MySignatureVisitor();
+            }
+
+            @Override
+            public SignatureVisitor visitParameterType() {
+                return new MySignatureVisitor();
+            }
+
+            @Override
+            public SignatureVisitor visitReturnType() {
+                return new MySignatureVisitor();
+            }
+
+            @Override
+            public SignatureVisitor visitSuperclass() {
+                return new MySignatureVisitor();
+            }
+
+            @Override
+            public SignatureVisitor visitTypeArgument(char wildcard) {
+                return new MySignatureVisitor();
+            }
+
+            @Override
+            public void visitTypeVariable(String name) {
+                // pass
+            }
+
+            @Override
+            public void visitTypeArgument() {
+                // pass
+            }
+        }
+
+
+        // ---------------------------------------------------
+        // --- AnnotationVisitor
+        // ---------------------------------------------------
+
+        private class MyAnnotationVisitor extends AnnotationVisitor {
+
+            public MyAnnotationVisitor() {
+                super(Opcodes.ASM4);
+            }
+
+            // Visits a primitive value of an annotation
+            @Override
+            public void visit(String name, Object value) {
+                // value is the actual value, whose type must be Byte, Boolean, Character, Short,
+                // Integer, Long, Float, Double, String or Type
+                if (value instanceof Type) {
+                    considerType((Type) value);
+                }
+            }
+
+            @Override
+            public AnnotationVisitor visitAnnotation(String name, String desc) {
+                // desc is the class descriptor of the nested annotation class.
+                considerDesc(desc);
+                return new MyAnnotationVisitor();
+            }
+
+            @Override
+            public AnnotationVisitor visitArray(String name) {
+                return new MyAnnotationVisitor();
+            }
+
+            @Override
+            public void visitEnum(String name, String desc, String value) {
+                // desc is the class descriptor of the enumeration class.
+                considerDesc(desc);
+            }
+        }
+    }
+}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java
index 8efd871..c3ba591 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java
@@ -33,11 +33,19 @@
         }
     }
 
+    /** Similar to debug() but doesn't do a \n automatically. */
+    public void debugNoln(String format, Object... args) {
+        if (mVerbose) {
+            String s = String.format(format, args);
+            System.out.print(s);
+        }
+    }
+
     public void info(String format, Object... args) {
         String s = String.format(format, args);
         outPrintln(s);
     }
-    
+
     public void error(String format, Object... args) {
         String s = String.format(format, args);
         errPrintln(s);
@@ -50,15 +58,15 @@
         pw.flush();
         error(format + "\n" + sw.toString(), args);
     }
-    
+
     /** for unit testing */
     protected void errPrintln(String msg) {
         System.err.println(msg);
     }
-    
+
     /** for unit testing */
     protected void outPrintln(String msg) {
         System.out.println(msg);
     }
-    
+
 }
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
index 4b7a348..9cd74db 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
@@ -18,6 +18,8 @@
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 
@@ -47,6 +49,8 @@
 
     public static class Options {
         public boolean generatePublicAccess = true;
+        public boolean listAllDeps = false;
+        public boolean listOnlyMissingDeps = false;
     }
 
     public static final Options sOptions = new Options();
@@ -60,16 +64,29 @@
 
         if (!processArgs(log, args, osJarPath, osDestJar)) {
             log.error("Usage: layoutlib_create [-v] [-p] output.jar input.jar ...");
+            log.error("Usage: layoutlib_create [-v] [--list-deps|--missing-deps] input.jar ...");
             System.exit(1);
         }
 
-        log.info("Output: %1$s", osDestJar[0]);
+        if (sOptions.listAllDeps || sOptions.listOnlyMissingDeps) {
+            System.exit(listDeps(osJarPath, log));
+
+        } else {
+            System.exit(createLayoutLib(osDestJar[0], osJarPath, log));
+        }
+
+
+        System.exit(1);
+    }
+
+    private static int createLayoutLib(String osDestJar, ArrayList<String> osJarPath, Log log) {
+        log.info("Output: %1$s", osDestJar);
         for (String path : osJarPath) {
             log.info("Input :      %1$s", path);
         }
 
         try {
-            AsmGenerator agen = new AsmGenerator(log, osDestJar[0], new CreateInfo());
+            AsmGenerator agen = new AsmGenerator(log, osDestJar, new CreateInfo());
 
             AsmAnalyzer aa = new AsmAnalyzer(log, osJarPath, agen,
                     new String[] {                          // derived from
@@ -116,17 +133,33 @@
                 for (String path : osJarPath) {
                     log.info("- Input JAR : %1$s", path);
                 }
-                System.exit(1);
+                return 1;
             }
 
-            System.exit(0);
+            return 0;
         } catch (IOException e) {
             log.exception(e, "Failed to load jar");
         } catch (LogAbortException e) {
             e.error(log);
         }
 
-        System.exit(1);
+        return 1;
+    }
+
+    private static int listDeps(ArrayList<String> osJarPath, Log log) {
+        DependencyFinder df = new DependencyFinder(log);
+        try {
+            List<Map<String, Set<String>>> result = df.findDeps(osJarPath);
+            if (sOptions.listAllDeps) {
+                df.printAllDeps(result);
+            } else if (sOptions.listOnlyMissingDeps) {
+                df.printMissingDeps(result);
+            }
+        } catch (IOException e) {
+            log.exception(e, "Failed to load jar");
+        }
+
+        return 0;
     }
 
     /**
@@ -138,14 +171,21 @@
      */
     private static boolean processArgs(Log log, String[] args,
             ArrayList<String> osJarPath, String[] osDestJar) {
+        boolean needs_dest = true;
         for (int i = 0; i < args.length; i++) {
             String s = args[i];
             if (s.equals("-v")) {
                 log.setVerbose(true);
             } else if (s.equals("-p")) {
                 sOptions.generatePublicAccess = false;
+            } else if (s.equals("--list-deps")) {
+                sOptions.listAllDeps = true;
+                needs_dest = false;
+            } else if (s.equals("--missing-deps")) {
+                sOptions.listOnlyMissingDeps = true;
+                needs_dest = false;
             } else if (!s.startsWith("-")) {
-                if (osDestJar[0] == null) {
+                if (needs_dest && osDestJar[0] == null) {
                     osDestJar[0] = s;
                 } else {
                     osJarPath.add(s);
@@ -160,7 +200,7 @@
             log.error("Missing parameter: path to input jar");
             return false;
         }
-        if (osDestJar[0] == null) {
+        if (needs_dest && osDestJar[0] == null) {
             log.error("Missing parameter: path to output jar");
             return false;
         }
diff --git a/voip/java/android/net/sip/SimpleSessionDescription.java b/voip/java/android/net/sip/SimpleSessionDescription.java
index 29166dc..9fcd21d 100644
--- a/voip/java/android/net/sip/SimpleSessionDescription.java
+++ b/voip/java/android/net/sip/SimpleSessionDescription.java
@@ -18,6 +18,7 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Locale;
 
 /**
  * An object used to manipulate messages of Session Description Protocol (SDP).
@@ -66,7 +67,7 @@
     public SimpleSessionDescription(long sessionId, String address) {
         address = (address.indexOf(':') < 0 ? "IN IP4 " : "IN IP6 ") + address;
         mFields.parse("v=0");
-        mFields.parse(String.format("o=- %d %d %s", sessionId,
+        mFields.parse(String.format(Locale.US, "o=- %d %d %s", sessionId,
                 System.currentTimeMillis(), address));
         mFields.parse("s=-");
         mFields.parse("t=0 0");
diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java
index a447c86..17c930b 100644
--- a/wifi/java/android/net/wifi/WifiMonitor.java
+++ b/wifi/java/android/net/wifi/WifiMonitor.java
@@ -20,6 +20,8 @@
 import android.net.wifi.p2p.WifiP2pConfig;
 import android.net.wifi.p2p.WifiP2pDevice;
 import android.net.wifi.p2p.WifiP2pGroup;
+import android.net.wifi.p2p.WifiP2pService;
+import android.net.wifi.p2p.WifiP2pService.P2pStatus;
 import android.net.wifi.p2p.WifiP2pProvDiscEvent;
 import android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
 import android.net.wifi.StateChangeResult;
@@ -186,7 +188,7 @@
 
     /* P2P-GROUP-STARTED p2p-wlan0-0 [client|GO] ssid="DIRECT-W8" freq=2437
        [psk=2182b2e50e53f260d04f3c7b25ef33c965a3291b9b36b455a82d77fd82ca15bc|passphrase="fKG4jMe3"]
-       go_dev_addr=fa:7b:7a:42:02:13 */
+       go_dev_addr=fa:7b:7a:42:02:13 [PERSISTENT] */
     private static final String P2P_GROUP_STARTED_STR = "P2P-GROUP-STARTED";
 
     /* P2P-GROUP-REMOVED p2p-wlan0-0 [client|GO] reason=REQUESTED */
@@ -594,7 +596,13 @@
                 if (tokens.length != 2) return;
                 String[] nameValue = tokens[1].split("=");
                 if (nameValue.length != 2) return;
-                mStateMachine.sendMessage(P2P_INVITATION_RESULT_EVENT, nameValue[1]);
+                P2pStatus err = P2pStatus.UNKNOWN;
+                try {
+                    err = P2pStatus.valueOf(Integer.parseInt(nameValue[1]));
+                } catch (NumberFormatException e) {
+                    e.printStackTrace();
+                }
+                mStateMachine.sendMessage(P2P_INVITATION_RESULT_EVENT, err);
             } else if (dataString.startsWith(P2P_PROV_DISC_PBC_REQ_STR)) {
                 mStateMachine.sendMessage(P2P_PROV_DISC_PBC_REQ_EVENT,
                         new WifiP2pProvDiscEvent(dataString));
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 4bf1ca3..e520185 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -547,10 +547,9 @@
                 break;
         }
 
-        //TODO: Add persist behavior once the supplicant interaction is fixed for both
-        // group and client scenarios
-        /* Persist unless there is an explicit request to not do so*/
-        //if (config.persist != WifiP2pConfig.Persist.NO) args.add("persistent");
+        if (config.netId == WifiP2pGroup.PERSISTENT_NET_ID) {
+            args.add("persistent");
+        }
 
         if (joinExistingGroup) {
             args.add("join");
@@ -592,10 +591,17 @@
         return false;
     }
 
-    public boolean p2pGroupAdd() {
+    public boolean p2pGroupAdd(boolean persistent) {
+        if (persistent) {
+            return doBooleanCommand("P2P_GROUP_ADD persistent");
+        }
         return doBooleanCommand("P2P_GROUP_ADD");
     }
 
+    public boolean p2pGroupAdd(int netId) {
+        return doBooleanCommand("P2P_GROUP_ADD persistent=" + netId);
+    }
+
     public boolean p2pGroupRemove(String iface) {
         if (TextUtils.isEmpty(iface)) return false;
         return doBooleanCommand("P2P_GROUP_REMOVE " + iface);
@@ -624,6 +630,9 @@
         return doBooleanCommand("P2P_INVITE persistent=" + netId + " peer=" + deviceAddress);
     }
 
+    public String p2pGetSsid(String deviceAddress) {
+        return p2pGetParam(deviceAddress, "oper_ssid");
+    }
 
     public String p2pGetDeviceAddress() {
         String status = status();
@@ -665,6 +674,24 @@
         return doStringCommand("P2P_PEER " + deviceAddress);
     }
 
+    private String p2pGetParam(String deviceAddress, String key) {
+        if (deviceAddress == null) return null;
+
+        String peerInfo = p2pPeer(deviceAddress);
+        if (peerInfo == null) return null;
+        String[] tokens= peerInfo.split("\n");
+
+        key += "=";
+        for (String token : tokens) {
+            if (token.startsWith(key)) {
+                String[] nameValue = token.split("=");
+                if (nameValue.length != 2) break;
+                return nameValue[1];
+            }
+        }
+        return null;
+    }
+
     public boolean p2pServiceAdd(WifiP2pServiceInfo servInfo) {
         /*
          * P2P_SERVICE_ADD bonjour <query hexdump> <RDATA hexdump>
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 7e47c99..15eb9b9 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -697,7 +697,7 @@
 
         setInitialState(mInitialState);
 
-        setProcessedMessagesSize(100);
+        setLogRecSize(100);
         if (DBG) setDbg(true);
 
         //start the state machine
@@ -1151,7 +1151,7 @@
     }
 
     @Override
-    protected boolean recordProcessedMessage(Message msg) {
+    protected boolean recordLogRec(Message msg) {
         //Ignore screen on/off & common messages when driver has started
         if (getCurrentState() == mConnectedState || getCurrentState() == mDisconnectedState) {
             switch (msg.what) {
@@ -1240,14 +1240,14 @@
            ip settings */
         InterfaceConfiguration ifcg = null;
         try {
-            ifcg = mNwService.getInterfaceConfig(mInterfaceName);
+            ifcg = mNwService.getInterfaceConfig(mTetherInterfaceName);
             if (ifcg != null) {
                 ifcg.setLinkAddress(
                         new LinkAddress(NetworkUtils.numericToInetAddress("0.0.0.0"), 0));
-                mNwService.setInterfaceConfig(mInterfaceName, ifcg);
+                mNwService.setInterfaceConfig(mTetherInterfaceName, ifcg);
             }
         } catch (Exception e) {
-            loge("Error resetting interface " + mInterfaceName + ", :" + e);
+            loge("Error resetting interface " + mTetherInterfaceName + ", :" + e);
         }
 
         if (mCm.untether(mTetherInterfaceName) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
@@ -1651,7 +1651,7 @@
             handlePostDhcpSetup();
 
             mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
-            mDhcpStateMachine.quit();
+            mDhcpStateMachine.doQuit();
             mDhcpStateMachine = null;
         }
 
@@ -3535,6 +3535,13 @@
                     if (DBG) log("Network connection lost");
                     handleNetworkDisconnect();
                     break;
+                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
+                    // Disregard auth failure events during WPS connection. The
+                    // EAP sequence is retried several times, and there might be
+                    // failures (especially for wps pin). We will get a WPS_XXX
+                    // event at the end of the sequence anyway.
+                    if (DBG) log("Ignore auth failure during WPS connection");
+                    break;
                 case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
                     //Throw away supplicant state changes when WPS is running.
                     //We will start getting supplicant state changes once we get
diff --git a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
index 45efe3e..c6d3eae 100644
--- a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
@@ -881,8 +881,8 @@
             //test to avoid any wifi connectivity issues
             loge("ARP test initiation failure: " + se);
             success = true;
-        } catch (IllegalArgumentException e) {
-            // ArpPeer throws exception for IPv6 address
+        } catch (IllegalArgumentException ae) {
+            log("ARP test initiation failure: " + ae);
             success = true;
         }
 
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
index 6aea090..100e062 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
@@ -46,18 +46,8 @@
      */
     public int groupOwnerIntent = -1;
 
-    /**
-     * Indicates whether the configuration is saved
-     * @hide
-     */
-    public enum Persist {
-        SYSTEM_DEFAULT,
-        YES,
-        NO
-    }
-
     /** @hide */
-    public Persist persist = Persist.SYSTEM_DEFAULT;
+    public int netId = WifiP2pGroup.PERSISTENT_NET_ID;
 
     public WifiP2pConfig() {
         //set defaults
@@ -110,7 +100,7 @@
         sbuf.append("\n address: ").append(deviceAddress);
         sbuf.append("\n wps: ").append(wps);
         sbuf.append("\n groupOwnerIntent: ").append(groupOwnerIntent);
-        sbuf.append("\n persist: ").append(persist.toString());
+        sbuf.append("\n persist: ").append(netId);
         return sbuf.toString();
     }
 
@@ -125,7 +115,7 @@
             deviceAddress = source.deviceAddress;
             wps = new WpsInfo(source.wps);
             groupOwnerIntent = source.groupOwnerIntent;
-            persist = source.persist;
+            netId = source.netId;
         }
     }
 
@@ -134,7 +124,7 @@
         dest.writeString(deviceAddress);
         dest.writeParcelable(wps, flags);
         dest.writeInt(groupOwnerIntent);
-        dest.writeString(persist.name());
+        dest.writeInt(netId);
     }
 
     /** Implement the Parcelable interface */
@@ -145,7 +135,7 @@
                 config.deviceAddress = in.readString();
                 config.wps = (WpsInfo) in.readParcelable(null);
                 config.groupOwnerIntent = in.readInt();
-                config.persist = Persist.valueOf(in.readString());
+                config.netId = in.readInt();
                 return config;
             }
 
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
index afdc9be..c86ec8b 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
@@ -231,11 +231,26 @@
         return (deviceCapability & DEVICE_CAPAB_SERVICE_DISCOVERY) != 0;
     }
 
+    /** Returns true if the device is capable of invitation {@hide}*/
+    public boolean isInvitationCapable() {
+        return (deviceCapability & DEVICE_CAPAB_INVITATION_PROCEDURE) != 0;
+    }
+
+    /** Returns true if the device reaches the limit. {@hide}*/
+    public boolean isDeviceLimit() {
+        return (deviceCapability & DEVICE_CAPAB_DEVICE_LIMIT) != 0;
+    }
+
     /** Returns true if the device is a group owner */
     public boolean isGroupOwner() {
         return (groupCapability & GROUP_CAPAB_GROUP_OWNER) != 0;
     }
 
+    /** Returns true if the group reaches the limit. {@hide}*/
+    public boolean isGroupLimit() {
+        return (groupCapability & GROUP_CAPAB_GROUP_LIMIT) != 0;
+    }
+
     @Override
     public boolean equals(Object obj) {
         if (this == obj) return true;
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
index c30cc73..bc492b3 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
@@ -33,6 +33,16 @@
  */
 public class WifiP2pGroup implements Parcelable {
 
+    /** The temporary network id.
+     * {@hide} */
+    public static final int TEMPORARY_NET_ID = -1;
+
+    /** The persistent network id.
+     * If a matching persistent profile is found, use it.
+     * Otherwise, create a new persistent profile.
+     * {@hide} */
+    public static final int PERSISTENT_NET_ID = -2;
+
     /** The network name */
     private String mNetworkName;
 
@@ -50,13 +60,17 @@
 
     private String mInterface;
 
+    /** The network id in the wpa_supplicant */
+    private int mNetId;
+
     /** P2P group started string pattern */
     private static final Pattern groupStartedPattern = Pattern.compile(
         "ssid=\"(.+)\" " +
         "freq=(\\d+) " +
         "(?:psk=)?([0-9a-fA-F]{64})?" +
         "(?:passphrase=)?(?:\"(.{8,63})\")? " +
-        "go_dev_addr=((?:[0-9a-f]{2}:){5}[0-9a-f]{2})"
+        "go_dev_addr=((?:[0-9a-f]{2}:){5}[0-9a-f]{2})" +
+        " ?(\\[PERSISTENT\\])?"
     );
 
     public WifiP2pGroup() {
@@ -67,13 +81,15 @@
      *
      *  P2P-GROUP-STARTED p2p-wlan0-0 [client|GO] ssid="DIRECT-W8" freq=2437
      *  [psk=2182b2e50e53f260d04f3c7b25ef33c965a3291b9b36b455a82d77fd82ca15bc|
-     *  passphrase="fKG4jMe3"] go_dev_addr=fa:7b:7a:42:02:13
+     *  passphrase="fKG4jMe3"] go_dev_addr=fa:7b:7a:42:02:13 [PERSISTENT]
      *
      *  P2P-GROUP-REMOVED p2p-wlan0-0 [client|GO] reason=REQUESTED
      *
      *  P2P-INVITATION-RECEIVED sa=fa:7b:7a:42:02:13 go_dev_addr=f8:7b:7a:42:02:13
      *  bssid=fa:7b:7a:42:82:13 unknown-network
      *
+     *  P2P-INVITATION-RECEIVED sa=b8:f9:34:2a:c7:9d persistent=0
+     *
      *  Note: The events formats can be looked up in the wpa_supplicant code
      *  @hide
      */
@@ -100,16 +116,38 @@
             //String psk = match.group(3);
             mPassphrase = match.group(4);
             mOwner = new WifiP2pDevice(match.group(5));
-
+            if (match.group(6) != null) {
+                mNetId = PERSISTENT_NET_ID;
+            } else {
+                mNetId = TEMPORARY_NET_ID;
+            }
         } else if (tokens[0].equals("P2P-INVITATION-RECEIVED")) {
+            String sa = null;
+            mNetId = PERSISTENT_NET_ID;
             for (String token : tokens) {
                 String[] nameValue = token.split("=");
                 if (nameValue.length != 2) continue;
 
+                if (nameValue[0].equals("sa")) {
+                    sa = nameValue[1];
+
+                    // set source address into the client list.
+                    WifiP2pDevice dev = new WifiP2pDevice();
+                    dev.deviceAddress = nameValue[1];
+                    mClients.add(dev);
+                    continue;
+                }
+
                 if (nameValue[0].equals("go_dev_addr")) {
                     mOwner = new WifiP2pDevice(nameValue[1]);
                     continue;
                 }
+
+                if (nameValue[0].equals("persistent")) {
+                    mOwner = new WifiP2pDevice(sa);
+                    mNetId = Integer.parseInt(nameValue[1]);
+                    continue;
+                }
             }
         } else {
             throw new IllegalArgumentException("Malformed supplicant event");
@@ -212,6 +250,16 @@
         return mInterface;
     }
 
+    /** @hide */
+    public int getNetworkId() {
+        return mNetId;
+    }
+
+    /** @hide */
+    public void setNetworkId(int netId) {
+        this.mNetId = netId;
+    }
+
     public String toString() {
         StringBuffer sbuf = new StringBuffer();
         sbuf.append("network: ").append(mNetworkName);
@@ -221,6 +269,7 @@
             sbuf.append("\n Client: ").append(client);
         }
         sbuf.append("\n interface: ").append(mInterface);
+        sbuf.append("\n networkId: ").append(mNetId);
         return sbuf.toString();
     }
 
@@ -238,6 +287,7 @@
             for (WifiP2pDevice d : source.getClientList()) mClients.add(d);
             mPassphrase = source.getPassphrase();
             mInterface = source.getInterface();
+            mNetId = source.getNetworkId();
         }
     }
 
@@ -252,6 +302,7 @@
         }
         dest.writeString(mPassphrase);
         dest.writeString(mInterface);
+        dest.writeInt(mNetId);
     }
 
     /** Implement the Parcelable interface */
@@ -268,6 +319,7 @@
                 }
                 group.setPassphrase(in.readString());
                 group.setInterface(in.readString());
+                group.setNetworkId(in.readInt());
                 return group;
             }
 
diff --git a/telephony/java/com/android/internal/telephony/IccException.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.aidl
similarity index 62%
copy from telephony/java/com/android/internal/telephony/IccException.java
copy to wifi/java/android/net/wifi/p2p/WifiP2pGroupList.aidl
index 1659a4e..3d8a476 100644
--- a/telephony/java/com/android/internal/telephony/IccException.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
+/**
+ * Copyright (c) 2012, 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
+ *     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,
@@ -14,17 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony;
+package android.net.wifi.p2p;
 
-/**
- * {@hide}
- */
-public class IccException extends Exception {
-    public IccException() {
-
-    }
-
-    public IccException(String s) {
-        super(s);
-    }
-}
+parcelable WifiP2pGroupList;
\ No newline at end of file
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java
new file mode 100644
index 0000000..3459a5a
--- /dev/null
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.net.wifi.p2p;
+
+import java.util.Collection;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.LruCache;
+
+
+/**
+ * A class representing a Wi-Fi P2p group list
+ *
+ * {@see WifiP2pManager}
+ * @hide
+ */
+public class WifiP2pGroupList implements Parcelable {
+
+    private static final int CREDENTIAL_MAX_NUM             =   32;
+
+    private LruCache<Integer, WifiP2pGroup> mGroups;
+    private GroupDeleteListener mListener;
+    private boolean isClearCalled = false;
+
+    public interface GroupDeleteListener {
+        public void onDeleteGroup(int netId);
+    }
+
+    WifiP2pGroupList() {
+        this(null);
+    }
+
+    WifiP2pGroupList(GroupDeleteListener listener) {
+        mListener = listener;
+        mGroups = new LruCache<Integer, WifiP2pGroup>(CREDENTIAL_MAX_NUM) {
+            @Override
+            protected void entryRemoved(boolean evicted, Integer netId,
+                    WifiP2pGroup oldValue, WifiP2pGroup newValue) {
+                if (mListener != null && !isClearCalled) {
+                    mListener.onDeleteGroup(oldValue.getNetworkId());
+                }
+            }
+        };
+    }
+
+    /**
+     * Return the list of p2p group.
+     *
+     * @return the list of p2p group.
+     */
+    public Collection<WifiP2pGroup> getGroupList() {
+        return mGroups.snapshot().values();
+    }
+
+    /**
+     * Add the specified group to this group list.
+     *
+     * @param group
+     */
+    void add(WifiP2pGroup group) {
+        mGroups.put(group.getNetworkId(), group);
+    }
+
+    /**
+     * Remove the group with the specified network id from this group list.
+     *
+     * @param netId
+     */
+    void remove(int netId) {
+        mGroups.remove(netId);
+    }
+
+    /**
+     * Remove the group with the specified device address from this group list.
+     *
+     * @param deviceAddress
+     */
+    void remove(String deviceAddress) {
+        remove(getNetworkId(deviceAddress));
+    }
+
+    /**
+     * Clear the group.
+     */
+    boolean clear() {
+        if (mGroups.size() == 0) return false;
+        isClearCalled = true;
+        mGroups.evictAll();
+        isClearCalled = false;
+        return true;
+    }
+
+    /**
+     * Return the network id of the group owner profile with the specified p2p device
+     * address.
+     * If more than one persistent group of the same address is present in the list,
+     * return the first one.
+     *
+     * @param deviceAddress p2p device address.
+     * @return the network id. if not found, return -1.
+     */
+    int getNetworkId(String deviceAddress) {
+        if (deviceAddress == null) return -1;
+
+        final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
+        for (WifiP2pGroup grp: groups) {
+            if (deviceAddress.equalsIgnoreCase(grp.getOwner().deviceAddress)) {
+                // update cache ordered.
+                mGroups.get(grp.getNetworkId());
+                return grp.getNetworkId();
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Return the network id of the group with the specified p2p device address
+     * and the ssid.
+     *
+     * @param deviceAddress p2p device address.
+     * @param ssid ssid.
+     * @return the network id. if not found, return -1.
+     */
+    int getNetworkId(String deviceAddress, String ssid) {
+        if (deviceAddress == null || ssid == null) {
+            return -1;
+        }
+
+        final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
+        for (WifiP2pGroup grp: groups) {
+            if (deviceAddress.equalsIgnoreCase(grp.getOwner().deviceAddress) &&
+                    ssid.equals(grp.getNetworkName())) {
+                // update cache ordered.
+                mGroups.get(grp.getNetworkId());
+                return grp.getNetworkId();
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Return the group owner address of the group with the specified network id
+     *
+     * @param netId network id.
+     * @return the address. if not found, return null.
+     */
+    String getOwnerAddr(int netId) {
+        WifiP2pGroup grp = mGroups.get(netId);
+        if (grp != null) {
+            return grp.getOwner().deviceAddress;
+        }
+        return null;
+    }
+
+    /**
+     * Return true if this group list contains the specified network id.
+     * This function does NOT update LRU information.
+     * It means the internal queue is NOT reordered.
+     *
+     * @param netId network id.
+     * @return true if the specified network id is present in this group list.
+     */
+    boolean contains(int netId) {
+        final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
+        for (WifiP2pGroup grp: groups) {
+            if (netId == grp.getNetworkId()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public String toString() {
+        StringBuffer sbuf = new StringBuffer();
+
+        final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
+        for (WifiP2pGroup grp: groups) {
+            sbuf.append(grp).append("\n");
+        }
+        return sbuf.toString();
+    }
+
+    /** Implement the Parcelable interface */
+    public int describeContents() {
+        return 0;
+    }
+
+    /** Implement the Parcelable interface */
+    public void writeToParcel(Parcel dest, int flags) {
+        final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
+        dest.writeInt(groups.size());
+        for(WifiP2pGroup group : groups) {
+            dest.writeParcelable(group, flags);
+        }
+    }
+
+    /** Implement the Parcelable interface */
+    public static final Creator<WifiP2pGroupList> CREATOR =
+        new Creator<WifiP2pGroupList>() {
+            public WifiP2pGroupList createFromParcel(Parcel in) {
+                WifiP2pGroupList grpList = new WifiP2pGroupList();
+
+                int deviceCount = in.readInt();
+                for (int i = 0; i < deviceCount; i++) {
+                    grpList.add((WifiP2pGroup)in.readParcelable(null));
+                }
+                return grpList;
+            }
+
+            public WifiP2pGroupList[] newArray(int size) {
+                return new WifiP2pGroupList[size];
+            }
+        };
+}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index 2c25e9d..96d3a7f 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -34,10 +34,10 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.Messenger;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.WorkSource;
-import android.os.Messenger;
 import android.util.Log;
 
 import com.android.internal.util.AsyncChannel;
@@ -267,6 +267,13 @@
     public static final String EXTRA_WIFI_P2P_DEVICE = "wifiP2pDevice";
 
     /**
+     * Broadcast intent action indicating that remembered persistent groups have changed.
+     * @hide
+     */
+    public static final String WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION =
+        "android.net.wifi.p2p.PERSISTENT_GROUPS_CHANGED";
+
+    /**
      * The lookup key for a {@link #String} object.
      * Retrieve with {@link android.os.Bundle#getString(String)}.
      * @hide
@@ -436,6 +443,18 @@
     /** @hide */
     public static final int SHOW_PIN_REQUESTED                      = BASE + 58;
 
+    /** @hide */
+    public static final int DELETE_PERSISTENT_GROUP                 = BASE + 59;
+    /** @hide */
+    public static final int DELETE_PERSISTENT_GROUP_FAILED          = BASE + 60;
+    /** @hide */
+    public static final int DELETE_PERSISTENT_GROUP_SUCCEEDED       = BASE + 61;
+
+    /** @hide */
+    public static final int REQUEST_PERSISTENT_GROUP_INFO           = BASE + 62;
+    /** @hide */
+    public static final int RESPONSE_PERSISTENT_GROUP_INFO          = BASE + 63;
+
     /**
      * Create a new WifiP2pManager instance. Applications use
      * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
@@ -657,6 +676,15 @@
         public void onDetached(int reason);
     }
 
+    /** Interface for callback invocation when stored group info list is available {@hide}*/
+    public interface PersistentGroupInfoListener {
+        /**
+         * The requested stored p2p group info list is available
+         * @param groups Wi-Fi p2p group info list
+         */
+        public void onPersistentGroupInfoAvailable(WifiP2pGroupList groups);
+    }
+
     /**
      * A channel that connects the application to the Wifi p2p framework.
      * Most p2p operations require a Channel as an argument. An instance of Channel is obtained
@@ -713,6 +741,7 @@
                     case WifiP2pManager.REMOVE_SERVICE_REQUEST_FAILED:
                     case WifiP2pManager.CLEAR_SERVICE_REQUESTS_FAILED:
                     case WifiP2pManager.SET_DEVICE_NAME_FAILED:
+                    case WifiP2pManager.DELETE_PERSISTENT_GROUP_FAILED:
                         if (listener != null) {
                             ((ActionListener) listener).onFailure(message.arg1);
                         }
@@ -732,6 +761,7 @@
                     case WifiP2pManager.REMOVE_SERVICE_REQUEST_SUCCEEDED:
                     case WifiP2pManager.CLEAR_SERVICE_REQUESTS_SUCCEEDED:
                     case WifiP2pManager.SET_DEVICE_NAME_SUCCEEDED:
+                    case WifiP2pManager.DELETE_PERSISTENT_GROUP_SUCCEEDED:
                         if (listener != null) {
                             ((ActionListener) listener).onSuccess();
                         }
@@ -786,6 +816,13 @@
                             mDialogListener = null;
                         }
                         break;
+                    case WifiP2pManager.RESPONSE_PERSISTENT_GROUP_INFO:
+                        WifiP2pGroupList groups = (WifiP2pGroupList) message.obj;
+                        if (listener != null) {
+                            ((PersistentGroupInfoListener) listener).
+                                onPersistentGroupInfoAvailable(groups);
+                        }
+                        break;
                    default:
                         Log.d(TAG, "Ignored " + message);
                         break;
@@ -995,7 +1032,8 @@
      */
     public void createGroup(Channel c, ActionListener listener) {
         checkChannel(c);
-        c.mAsyncChannel.sendMessage(CREATE_GROUP, 0, c.putListener(listener));
+        c.mAsyncChannel.sendMessage(CREATE_GROUP, WifiP2pGroup.PERSISTENT_NET_ID,
+                c.putListener(listener));
     }
 
     /**
@@ -1297,6 +1335,40 @@
     }
 
     /**
+     * Delete a stored persistent group from the system settings.
+     *
+     * <p> The function call immediately returns after sending a persistent group removal request
+     * to the framework. The application is notified of a success or failure to initiate
+     * group removal through listener callbacks {@link ActionListener#onSuccess} or
+     * {@link ActionListener#onFailure}.
+     *
+     * <p>The persistent p2p group list stored in the system can be obtained by
+     * {@link #requestPersistentGroupInfo(Channel, PersistentGroupInfoListener)} and
+     *  a network id can be obtained by {@link WifiP2pGroup#getNetworkId()}.
+     *
+     * @param c is the channel created at {@link #initialize}
+     * @param netId he network id of the p2p group.
+     * @param listener for callbacks on success or failure. Can be null.
+     * @hide
+     */
+    public void deletePersistentGroup(Channel c, int netId, ActionListener listener) {
+        checkChannel(c);
+        c.mAsyncChannel.sendMessage(DELETE_PERSISTENT_GROUP, netId, c.putListener(listener));
+    }
+
+    /**
+     * Request a list of all the persistent p2p groups stored in system.
+     *
+     * @param c is the channel created at {@link #initialize}
+     * @param listener for callback when persistent group info list is available. Can be null.
+     * @hide
+     */
+    public void requestPersistentGroupInfo(Channel c, PersistentGroupInfoListener listener) {
+        checkChannel(c);
+        c.mAsyncChannel.sendMessage(REQUEST_PERSISTENT_GROUP_INFO, 0, c.putListener(listener));
+    }
+
+    /**
      * Get a reference to WifiP2pService handler. This is used to establish
      * an AsyncChannel communication with WifiService
      *
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 9e004d0..0be2b27 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -45,6 +45,7 @@
 import android.net.wifi.WifiNative;
 import android.net.wifi.WifiStateMachine;
 import android.net.wifi.WpsInfo;
+import android.net.wifi.p2p.WifiP2pGroupList.GroupDeleteListener;
 import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
 import android.net.wifi.p2p.nsd.WifiP2pServiceRequest;
 import android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
@@ -118,6 +119,13 @@
     private static final Boolean JOIN_GROUP = true;
     private static final Boolean FORM_GROUP = false;
 
+    private static final Boolean TRY_REINVOCATION = true;;
+    private static final Boolean NO_REINVOCATION = false;
+
+    private static final int CONNECT_FAILURE = -1;
+    private static final int CONNECT_SUCCESS = 0;
+    private static final int NEEDS_PROVISION_REQ = 1;
+
     /* Two minutes comes from the wpa_supplicant setting */
     private static final int GROUP_CREATING_WAIT_TIME_MS = 120 * 1000;
     private static int mGroupCreatingTimeoutIndex = 0;
@@ -191,6 +199,84 @@
     private static final String[] DHCP_RANGE = {"192.168.49.2", "192.168.49.254"};
     private static final String SERVER_ADDRESS = "192.168.49.1";
 
+    /**
+     * Error code definition.
+     * see the Table.8 in the WiFi Direct specification for the detail.
+     */
+    public static enum P2pStatus {
+        /* Success. */
+        SUCCESS,
+
+        /* The target device is currently unavailable. */
+        INFORMATION_IS_CURRENTLY_UNAVAILABLE,
+
+        /* Protocol error. */
+        INCOMPATIBLE_PARAMETERS,
+
+        /* The target device reached the limit of the number of the connectable device.
+         * For example, device limit or group limit is set. */
+        LIMIT_REACHED,
+
+        /* Protocol error. */
+        INVALID_PARAMETER,
+
+        /* Unable to accommodate request. */
+        UNABLE_TO_ACCOMMODATE_REQUEST,
+
+        /* Previous protocol error, or disruptive behavior. */
+        PREVIOUS_PROTOCOL_ERROR,
+
+        /* There is no common channels the both devices can use. */
+        NO_COMMON_CHANNE,
+
+        /* Unknown p2p group. For example, Device A tries to invoke the previous persistent group,
+         *  but device B has removed the specified credential already. */
+        UNKNOWN_P2P_GROUP,
+
+        /* Both p2p devices indicated an intent of 15 in group owner negotiation. */
+        BOTH_GO_INTENT_15,
+
+        /* Incompatible provisioning method. */
+        INCOMPATIBLE_PROVISIONING_METHOD,
+
+        /* Rejected by user */
+        REJECTED_BY_USER,
+
+        /* Unknown error */
+        UNKNOWN;
+
+        public static P2pStatus valueOf(int error) {
+            switch(error) {
+            case 0 :
+                return SUCCESS;
+            case 1:
+                return INFORMATION_IS_CURRENTLY_UNAVAILABLE;
+            case 2:
+                return INCOMPATIBLE_PARAMETERS;
+            case 3:
+                return LIMIT_REACHED;
+            case 4:
+                return INVALID_PARAMETER;
+            case 5:
+                return UNABLE_TO_ACCOMMODATE_REQUEST;
+            case 6:
+                return PREVIOUS_PROTOCOL_ERROR;
+            case 7:
+                return NO_COMMON_CHANNE;
+            case 8:
+                return UNKNOWN_P2P_GROUP;
+            case 9:
+                return BOTH_GO_INTENT_15;
+            case 10:
+                return INCOMPATIBLE_PROVISIONING_METHOD;
+            case 11:
+                return REJECTED_BY_USER;
+            default:
+                return UNKNOWN;
+            }
+        }
+    }
+
     public WifiP2pService(Context context) {
         mContext = context;
 
@@ -273,6 +359,16 @@
         private WifiMonitor mWifiMonitor = new WifiMonitor(this, mWifiNative);
 
         private WifiP2pDeviceList mPeers = new WifiP2pDeviceList();
+        private WifiP2pGroupList mGroups = new WifiP2pGroupList(
+                new GroupDeleteListener() {
+            @Override
+            public void onDeleteGroup(int netId) {
+                if (DBG) logd("called onDeleteGroup() netId=" + netId);
+                mWifiNative.removeNetwork(netId);
+                mWifiNative.saveConfig();
+                sendP2pPersistentGroupsChangedBroadcast();
+            }
+        });
         private WifiP2pInfo mWifiP2pInfo = new WifiP2pInfo();
         private WifiP2pGroup mGroup;
 
@@ -395,6 +491,10 @@
                     replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
                             WifiP2pManager.BUSY);
                     break;
+                case WifiP2pManager.DELETE_PERSISTENT_GROUP:
+                    replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP,
+                            WifiP2pManager.BUSY);
+                    break;
                 case WifiP2pManager.REQUEST_PEERS:
                     replyToMessage(message, WifiP2pManager.RESPONSE_PEERS, mPeers);
                     break;
@@ -404,6 +504,10 @@
                 case WifiP2pManager.REQUEST_GROUP_INFO:
                     replyToMessage(message, WifiP2pManager.RESPONSE_GROUP_INFO, mGroup);
                     break;
+                case WifiP2pManager.REQUEST_PERSISTENT_GROUP_INFO:
+                    replyToMessage(message, WifiP2pManager.RESPONSE_PERSISTENT_GROUP_INFO,
+                            mGroups);
+                    break;
                 case WifiP2pManager.SET_DIALOG_LISTENER:
                     String appPkgName = (String)message.getData().getString(
                             WifiP2pManager.APP_PKG_BUNDLE_KEY);
@@ -520,6 +624,10 @@
                     replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
                             WifiP2pManager.P2P_UNSUPPORTED);
                     break;
+                case WifiP2pManager.DELETE_PERSISTENT_GROUP:
+                    replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP,
+                            WifiP2pManager.P2P_UNSUPPORTED);
+                    break;
                default:
                     return NOT_HANDLED;
             }
@@ -626,6 +734,8 @@
                     break;
                 case WifiStateMachine.CMD_DISABLE_P2P:
                     if (mPeers.clear()) sendP2pPeersChangedBroadcast();
+                    if (mGroups.clear()) sendP2pPersistentGroupsChangedBroadcast();
+
                     mWifiNative.closeSupplicantConnection();
                     transitionTo(mP2pDisablingState);
                     break;
@@ -734,6 +844,11 @@
                         sendServiceResponse(resp);
                     }
                     break;
+               case WifiP2pManager.DELETE_PERSISTENT_GROUP:
+                   if (DBG) logd(getName() + " delete persistent group");
+                   mGroups.remove(message.arg1);
+                   replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP_SUCCEEDED);
+                   break;
                 default:
                     return NOT_HANDLED;
             }
@@ -768,47 +883,35 @@
                     /* Update group capability before connect */
                     int gc = mWifiNative.getGroupCapability(config.deviceAddress);
                     mPeers.updateGroupCapability(config.deviceAddress, gc);
-
-                    if (mSavedPeerConfig != null && config.deviceAddress.equals(
-                                    mSavedPeerConfig.deviceAddress)) {
-                        mSavedPeerConfig = config;
-
-                        //Stop discovery before issuing connect
-                        mWifiNative.p2pStopFind();
-                        if (mPeers.isGroupOwner(mSavedPeerConfig.deviceAddress)) {
-                            p2pConnectWithPinDisplay(mSavedPeerConfig, JOIN_GROUP);
-                        } else {
-                            p2pConnectWithPinDisplay(mSavedPeerConfig, FORM_GROUP);
-                        }
-                        transitionTo(mGroupNegotiationState);
-                    } else {
-                        mSavedPeerConfig = config;
-                        int netId = configuredNetworkId(mSavedPeerConfig.deviceAddress);
-                        if (netId >= 0) {
-                            //TODO: if failure, remove config and do a regular p2pConnect()
-                            mWifiNative.p2pReinvoke(netId, mSavedPeerConfig.deviceAddress);
-                        } else {
-                            //Stop discovery before issuing connect
-                            mWifiNative.p2pStopFind();
-                            //If peer is a GO, we do not need to send provisional discovery,
-                            //the supplicant takes care of it.
-                            if (mPeers.isGroupOwner(mSavedPeerConfig.deviceAddress)) {
-                                if (DBG) logd("Sending join to GO");
-                                p2pConnectWithPinDisplay(mSavedPeerConfig, JOIN_GROUP);
-                                transitionTo(mGroupNegotiationState);
-                            } else {
-                                if (DBG) logd("Sending prov disc");
-                                transitionTo(mProvisionDiscoveryState);
-                            }
-                        }
+                    int connectRet = connect(config, TRY_REINVOCATION);
+                    if (connectRet == CONNECT_FAILURE) {
+                        replyToMessage(message, WifiP2pManager.CONNECT_FAILED);
+                        break;
                     }
                     mPeers.updateStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
                     sendP2pPeersChangedBroadcast();
                     replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
+                    if (connectRet == NEEDS_PROVISION_REQ) {
+                        if (DBG) logd("Sending prov disc");
+                        transitionTo(mProvisionDiscoveryState);
+                        break;
+                    }
+                    transitionTo(mGroupNegotiationState);
+                    break;
+                case WifiP2pManager.STOP_DISCOVERY:
+                    if (mWifiNative.p2pStopFind()) {
+                        // When discovery stops in inactive state, flush to clear
+                        // state peer data
+                        mWifiNative.p2pFlush();
+                        mServiceDiscReqId = null;
+                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_SUCCEEDED);
+                    } else {
+                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
+                                WifiP2pManager.ERROR);
+                    }
                     break;
                 case WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT:
                     mSavedPeerConfig = (WifiP2pConfig) message.obj;
-
                     mAutonomousGroup = false;
                     mJoinExistingGroup = false;
                     if (!sendConnectNoticeToApp(mPeers.get(mSavedPeerConfig.deviceAddress),
@@ -848,13 +951,6 @@
                         transitionTo(mUserAuthorizingInvitationState);
                     }
                     break;
-                case WifiMonitor.P2P_FIND_STOPPED_EVENT:
-                    // When discovery stops in inactive state, flush to clear
-                    // state peer data
-                    mWifiNative.p2pFlush();
-                    mServiceDiscReqId = null;
-                    sendP2pDiscoveryChangedBroadcast(false);
-                    break;
                 case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
                 case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
                 case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
@@ -865,16 +961,44 @@
                    break;
                 case WifiP2pManager.CREATE_GROUP:
                    mAutonomousGroup = true;
-                   if (mWifiNative.p2pGroupAdd()) {
-                        replyToMessage(message, WifiP2pManager.CREATE_GROUP_SUCCEEDED);
+                   int netId = message.arg1;
+                   boolean ret = false;
+                   if (netId == WifiP2pGroup.PERSISTENT_NET_ID) {
+                       // check if the go persistent group is present.
+                       netId = mGroups.getNetworkId(mThisDevice.deviceAddress);
+                       if (netId != -1) {
+                           ret = mWifiNative.p2pGroupAdd(netId);
+                       } else {
+                           ret = mWifiNative.p2pGroupAdd(true);
+                       }
+                   } else {
+                       ret = mWifiNative.p2pGroupAdd(false);
+                   }
+
+                   if (ret) {
+                       replyToMessage(message, WifiP2pManager.CREATE_GROUP_SUCCEEDED);
+                       transitionTo(mGroupNegotiationState);
+                   } else {
+                       replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
+                               WifiP2pManager.ERROR);
+                       // remain at this state.
+                   }
+                   break;
+                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
+                    mGroup = (WifiP2pGroup) message.obj;
+                    if (DBG) logd(getName() + " group started");
+
+                    if (mGroup.getNetworkId() == WifiP2pGroup.PERSISTENT_NET_ID) {
+                        // This is an invocation case.
+                        mAutonomousGroup = false;
+                        deferMessage(message);
+                        transitionTo(mGroupNegotiationState);
                     } else {
-                        replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
-                                WifiP2pManager.ERROR);
+                        return NOT_HANDLED;
                     }
-                    transitionTo(mGroupNegotiationState);
                     break;
                default:
-                    return NOT_HANDLED;
+                   return NOT_HANDLED;
             }
             return HANDLED;
         }
@@ -941,10 +1065,7 @@
         @Override
         public void enter() {
             if (DBG) logd(getName());
-            if (!sendConnectNoticeToApp(mPeers.get(mSavedPeerConfig.deviceAddress),
-                    mSavedPeerConfig)) {
-                notifyInvitationReceived();
-            }
+            notifyInvitationReceived();
         }
 
         @Override
@@ -953,11 +1074,10 @@
             boolean ret = HANDLED;
             switch (message.what) {
                 case PEER_CONNECTION_USER_ACCEPT:
-                    //TODO: handle persistence
-                    if (mJoinExistingGroup) {
-                        p2pConnectWithPinDisplay(mSavedPeerConfig, JOIN_GROUP);
-                    } else {
-                        p2pConnectWithPinDisplay(mSavedPeerConfig, FORM_GROUP);
+                    if (connect(mSavedPeerConfig, TRY_REINVOCATION) == CONNECT_FAILURE) {
+                        handleGroupCreationFailure();
+                        transitionTo(mInactiveState);
+                        break;
                     }
                     mPeers.updateStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
                     sendP2pPeersChangedBroadcast();
@@ -1000,7 +1120,7 @@
 
                     if (mSavedPeerConfig.wps.setup == WpsInfo.PBC) {
                         if (DBG) logd("Found a match " + mSavedPeerConfig);
-                        mWifiNative.p2pConnect(mSavedPeerConfig, FORM_GROUP);
+                        p2pConnectWithPinDisplay(mSavedPeerConfig);
                         transitionTo(mGroupNegotiationState);
                     }
                     break;
@@ -1013,11 +1133,14 @@
                         if (DBG) logd("Found a match " + mSavedPeerConfig);
                         /* we already have the pin */
                         if (!TextUtils.isEmpty(mSavedPeerConfig.wps.pin)) {
-                            mWifiNative.p2pConnect(mSavedPeerConfig, FORM_GROUP);
+                            p2pConnectWithPinDisplay(mSavedPeerConfig);
                             transitionTo(mGroupNegotiationState);
                         } else {
                             mJoinExistingGroup = false;
-                            transitionTo(mUserAuthorizingInvitationState);
+                            if (!sendConnectNoticeToApp(mPeers.get(mSavedPeerConfig.deviceAddress),
+                                    mSavedPeerConfig)) {
+                                transitionTo(mUserAuthorizingInvitationState);
+                            }
                         }
                     }
                     break;
@@ -1029,7 +1152,7 @@
                     if (mSavedPeerConfig.wps.setup == WpsInfo.DISPLAY) {
                         if (DBG) logd("Found a match " + mSavedPeerConfig);
                         mSavedPeerConfig.wps.pin = provDisc.pin;
-                        mWifiNative.p2pConnect(mSavedPeerConfig, FORM_GROUP);
+                        p2pConnectWithPinDisplay(mSavedPeerConfig);
                         if (!sendShowPinReqToFrontApp(provDisc.pin)) {
                             notifyInvitationSent(provDisc.pin, device.deviceAddress);
                         }
@@ -1062,6 +1185,17 @@
                 case WifiMonitor.P2P_GROUP_STARTED_EVENT:
                     mGroup = (WifiP2pGroup) message.obj;
                     if (DBG) logd(getName() + " group started");
+
+                    if (mGroup.getNetworkId() == WifiP2pGroup.PERSISTENT_NET_ID) {
+                        /*
+                         * update cache information and set network id to mGroup.
+                         */
+                        updatePersistentNetworks();
+                        String devAddr = mGroup.getOwner().deviceAddress;
+                        mGroup.setNetworkId(mGroups.getNetworkId(devAddr,
+                                mGroup.getNetworkName()));
+                    }
+
                     if (mGroup.isGroupOwner()) {
                         startDhcpServer(mGroup.getInterface());
                     } else {
@@ -1090,6 +1224,29 @@
                 // failure causes supplicant issues. Ignore right now.
                 case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
                     break;
+                case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
+                    P2pStatus status = (P2pStatus)message.obj;
+                    if (status == P2pStatus.SUCCESS) {
+                        // invocation was succeeded.
+                        // wait P2P_GROUP_STARTED_EVENT.
+                        break;
+                    } else if (status == P2pStatus.UNKNOWN_P2P_GROUP) {
+                        // target device has already removed the credential.
+                        // So, remove this credential accordingly.
+                        int netId = mSavedPeerConfig.netId;
+                        if (netId >= 0) {
+                            if (DBG) logd("Remove unknown client from the list");
+                            removeClientFromList(netId, mSavedPeerConfig.deviceAddress, true);
+                        }
+                    }
+
+                    // invocation is failed or deferred. Try another way to connect.
+                    mSavedPeerConfig.netId = WifiP2pGroup.PERSISTENT_NET_ID;
+                    if (connect(mSavedPeerConfig, NO_REINVOCATION) == CONNECT_FAILURE) {
+                        handleGroupCreationFailure();
+                        transitionTo(mInactiveState);
+                    }
+                    break;
                 default:
                     return NOT_HANDLED;
             }
@@ -1152,7 +1309,7 @@
                             }
                         }
                         sendP2pPeersChangedBroadcast();
-                        if (DBG) loge(getName() + " ap sta disconnected");
+                        if (DBG) logd(getName() + " ap sta disconnected");
                     } else {
                         loge("Disconnect on unknown device: " + device);
                     }
@@ -1172,7 +1329,7 @@
                     }
                     break;
                 case WifiP2pManager.REMOVE_GROUP:
-                    if (DBG) loge(getName() + " remove group");
+                    if (DBG) logd(getName() + " remove group");
                     if (mWifiNative.p2pGroupRemove(mGroup.getInterface())) {
                         replyToMessage(message, WifiP2pManager.REMOVE_GROUP_SUCCEEDED);
                     } else {
@@ -1181,7 +1338,7 @@
                     }
                     break;
                 case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
-                    if (DBG) loge(getName() + " group removed");
+                    if (DBG) logd(getName() + " group removed");
                     Collection <WifiP2pDevice> devices = mGroup.getClientList();
                     boolean changed = false;
                     for (WifiP2pDevice d : mPeers.getDeviceList()) {
@@ -1196,7 +1353,7 @@
                     } else {
                         if (DBG) logd("stop DHCP client");
                         mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
-                        mDhcpStateMachine.quit();
+                        mDhcpStateMachine.doQuit();
                         mDhcpStateMachine = null;
                     }
 
@@ -1252,6 +1409,7 @@
                         replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
                     } else {
                         logd("Inviting device : " + config.deviceAddress);
+                        mSavedPeerConfig = config;
                         if (mWifiNative.p2pInvite(mGroup, config.deviceAddress)) {
                             mPeers.updateStatus(config.deviceAddress, WifiP2pDevice.INVITED);
                             sendP2pPeersChangedBroadcast();
@@ -1263,6 +1421,29 @@
                     }
                     // TODO: figure out updating the status to declined when invitation is rejected
                     break;
+                case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
+                    P2pStatus status = (P2pStatus)message.obj;
+                    logd("===> INVITATION RESULT EVENT : " + status);
+                    if (status == P2pStatus.SUCCESS) {
+                        // invocation was succeeded.
+                        break;
+                    } else if (status == P2pStatus.UNKNOWN_P2P_GROUP) {
+                        // target device has already removed the credential.
+                        // So, remove this credential accordingly.
+                        int netId = mGroup.getNetworkId();
+                        if (netId >= 0) {
+                            if (DBG) logd("Remove unknown client from the list");
+                            if (!removeClientFromList(netId,
+                                    mSavedPeerConfig.deviceAddress, false)) {
+                                // not found the client on the list
+                                Slog.e(TAG, "Already removed the client, ignore");
+                                break;
+                            }
+                            // try invitation.
+                            sendMessage(WifiP2pManager.CONNECT, mSavedPeerConfig);
+                        }
+                    }
+                    break;
                 case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
                 case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
                 case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
@@ -1304,7 +1485,6 @@
         @Override
         public void enter() {
             if (DBG) logd(getName());
-
             notifyInvitationReceived();
         }
 
@@ -1394,6 +1574,13 @@
         mContext.sendStickyBroadcast(intent);
     }
 
+    private void sendP2pPersistentGroupsChangedBroadcast() {
+        if (DBG) logd("sending p2p persistent groups changed broadcast");
+        Intent intent = new Intent(WifiP2pManager.WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION);
+        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+        mContext.sendStickyBroadcast(intent);   
+    }
+
     private void startDhcpServer(String intf) {
         InterfaceConfiguration ifcg = null;
         try {
@@ -1520,11 +1707,246 @@
         dialog.show();
     }
 
-    //TODO: implement when wpa_supplicant is fixed
-    private int configuredNetworkId(String deviceAddress) {
+    /**
+     * Synchronize the persistent group list between
+     * wpa_supplicant and mGroups.
+     */
+    private void updatePersistentNetworks() {
+        String listStr = mWifiNative.listNetworks();
+
+        boolean isSaveRequired = false;
+        String[] lines = listStr.split("\n");
+        // Skip the first line, which is a header
+        for (int i = 1; i < lines.length; i++) {
+            String[] result = lines[i].split("\t");
+            if (result == null || result.length < 4) {
+                continue;
+            }
+            // network-id | ssid | bssid | flags
+            int netId = -1;
+            String ssid = result[1];
+            String bssid = result[2];
+            String flags = result[3];
+            try {
+                netId = Integer.parseInt(result[0]);
+            } catch(NumberFormatException e) {
+                e.printStackTrace();
+                continue;
+            }
+
+            if (flags.indexOf("[CURRENT]") != -1) {
+                continue;
+            }
+            if (flags.indexOf("[P2P-PERSISTENT]") == -1) {
+                /*
+                 * The unused profile is sometimes remained when the p2p group formation is failed.
+                 * So, we clean up the p2p group here.
+                 */
+                if (DBG) logd("clean up the unused persistent group. netId=" + netId);
+                mWifiNative.removeNetwork(netId);
+                isSaveRequired = true;
+                continue;
+            }
+
+            if (mGroups.contains(netId)) {
+                continue;
+            }
+
+            WifiP2pGroup group = new WifiP2pGroup();
+            group.setNetworkId(netId);
+            group.setNetworkName(ssid);
+            String mode = mWifiNative.getNetworkVariable(netId, "mode");
+            if (mode != null && mode.equals("3")) {
+                group.setIsGroupOwner(true);
+            }
+            if (bssid.equalsIgnoreCase(mThisDevice.deviceAddress)) {
+                group.setOwner(mThisDevice);
+            } else {
+                WifiP2pDevice device = new WifiP2pDevice();
+                device.deviceAddress = bssid;
+                group.setOwner(device);
+            }
+            mGroups.add(group);
+            isSaveRequired = true;
+        }
+
+        if (isSaveRequired) {
+            sendP2pPersistentGroupsChangedBroadcast();
+            mWifiNative.saveConfig();
+        }
+    }
+
+    /**
+     * Try to connect to the target device.
+     *
+     * Use the persistent credential if it has been stored.
+     *
+     * @param config
+     * @param tryInvocation if true, try to invoke. Otherwise, never try to invoke.
+     * @return
+     */
+    private int connect(WifiP2pConfig config, boolean tryInvocation) {
+
+        if (config == null) {
+            loge("invalid argument.");
+            return CONNECT_FAILURE;
+        }
+
+        boolean isResp = (mSavedPeerConfig != null &&
+                config.deviceAddress.equals(mSavedPeerConfig.deviceAddress));
+        mSavedPeerConfig = config;
+
+        WifiP2pDevice dev = mPeers.get(config.deviceAddress);
+        if (dev == null) {
+            loge("target device is not found.");
+            return CONNECT_FAILURE;
+        }
+
+        boolean join = dev.isGroupOwner();
+        String ssid = mWifiNative.p2pGetSsid(dev.deviceAddress);
+        if (DBG) logd("target ssid is " + ssid + " join:" + join);
+
+        if (join && dev.isGroupLimit()) {
+            if (DBG) logd("target device reaches group limit.");
+
+            // if the target group has reached the limit,
+            // try group formation.
+            join = false;
+        } else if (join) {
+            int netId = mGroups.getNetworkId(dev.deviceAddress, ssid);
+            if (netId >= 0) {
+                // Skip WPS and start 4way handshake immediately.
+                if (!mWifiNative.p2pGroupAdd(netId)) {
+                    return CONNECT_FAILURE;
+                }
+                return CONNECT_SUCCESS;
+            }
+        }
+
+        if (!join && dev.isDeviceLimit()) {
+            loge("target device reaches the device limit.");
+            return CONNECT_FAILURE;
+        }
+
+        if (!join && tryInvocation && dev.isInvitationCapable()) {
+            int netId = WifiP2pGroup.PERSISTENT_NET_ID;
+            if (config.netId >= 0) {
+                if (config.deviceAddress.equals(mGroups.getOwnerAddr(config.netId))) {
+                    netId = config.netId;
+                }
+            } else {
+                netId = mGroups.getNetworkId(dev.deviceAddress);
+            }
+            if (netId < 0) {
+                netId = getNetworkIdFromClientList(dev.deviceAddress);
+            }
+            if (DBG) logd("netId related with " + dev.deviceAddress + " = " + netId);
+            if (netId >= 0) {
+
+                // Invoke the persistent group.
+                if (!mWifiNative.p2pReinvoke(netId, dev.deviceAddress)) {
+                    loge("p2pReinvoke() failed");
+                    return CONNECT_FAILURE;
+                }
+                // Save network id. It'll be used when an invitation result event is received.
+                mSavedPeerConfig.netId = netId;
+                return CONNECT_SUCCESS;
+            }
+        }
+
+        //Stop discovery before issuing connect
+        mWifiNative.p2pStopFind();
+
+        if (!isResp) {
+            return NEEDS_PROVISION_REQ;
+        }
+
+        p2pConnectWithPinDisplay(config);
+        return CONNECT_SUCCESS;
+    }
+
+    /**
+     * Return the network id of the group owner profile which has the p2p client with
+     * the specified device address in it's client list.
+     * If more than one persistent group of the same address is present in its client
+     * lists, return the first one.
+     *
+     * @param deviceAddress p2p device address.
+     * @return the network id. if not found, return -1.
+     */
+    private int getNetworkIdFromClientList(String deviceAddress) {
+        if (deviceAddress == null) return -1;
+
+        Collection<WifiP2pGroup> groups = mGroups.getGroupList();
+        for (WifiP2pGroup group : groups) {
+            int netId = group.getNetworkId();
+            String[] p2pClientList = getClientList(netId);
+            if (p2pClientList == null) continue;
+            for (String client : p2pClientList) {
+                if (deviceAddress.equalsIgnoreCase(client)) {
+                    return netId;
+                }
+            }
+        }
         return -1;
     }
 
+    /**
+     * Return p2p client list associated with the specified network id.
+     * @param netId network id.
+     * @return p2p client list. if not found, return null.
+     */
+    private String[] getClientList(int netId) {
+        String p2pClients = mWifiNative.getNetworkVariable(netId, "p2p_client_list");
+        if (p2pClients == null) {
+            return null;
+        }
+        return p2pClients.split(" ");
+    }
+
+    /**
+     * Remove the specified p2p client from the specified profile.
+     * @param netId network id of the profile.
+     * @param addr p2p client address to be removed.
+     * @param isRemovable if true, remove the specified profile if its client list becomes empty.
+     * @return whether removing the specified p2p client is successful or not.
+     */
+    private boolean removeClientFromList(int netId, String addr, boolean isRemovable) {
+        StringBuilder modifiedClientList =  new StringBuilder();
+        String[] currentClientList = getClientList(netId);
+        boolean isClientRemoved = false;
+        if (currentClientList != null) {
+            for (String client : currentClientList) {
+                if (!client.equalsIgnoreCase(addr)) {
+                    modifiedClientList.append(" ");
+                    modifiedClientList.append(client);
+                } else {
+                    isClientRemoved = true;
+                }
+            }
+        }
+        if (modifiedClientList.length() == 0 && isRemovable) {
+            // the client list is empty. so remove it.
+            if (DBG) logd("Remove unknown network");
+            mGroups.remove(netId);
+            return true;
+        }
+
+        if (!isClientRemoved) {
+            // specified p2p client is not found. already removed.
+            return false;
+        }
+
+        if (DBG) logd("Modified client list: " + modifiedClientList);
+        if (modifiedClientList.length() == 0) {
+            modifiedClientList.append("\"\"");
+        }
+        mWifiNative.setNetworkVariable(netId,
+                "p2p_client_list", modifiedClientList.toString());
+        mWifiNative.saveConfig();
+        return true;
+    }
+
     private void setWifiP2pInfoOnGroupFormation(String serverAddress) {
         mWifiP2pInfo.groupFormed = true;
         mWifiP2pInfo.isGroupOwner = mGroup.isGroupOwner();
@@ -1546,8 +1968,14 @@
         return deviceAddress;
     }
 
-    private void p2pConnectWithPinDisplay(WifiP2pConfig config, boolean join) {
-        String pin = mWifiNative.p2pConnect(config, join);
+    private void p2pConnectWithPinDisplay(WifiP2pConfig config) {
+        WifiP2pDevice dev = mPeers.get(config.deviceAddress);
+        if (dev == null) {
+            loge("target device is not found " + config.deviceAddress);
+            return;
+        }
+
+        String pin = mWifiNative.p2pConnect(config, dev.isGroupOwner());
         try {
             Integer.parseInt(pin);
             if (!sendShowPinReqToFrontApp(pin)) {
@@ -1610,6 +2038,8 @@
         mWifiNative.p2pServiceFlush();
         mServiceTransactionId = 0;
         mServiceDiscReqId = null;
+
+        updatePersistentNetworks();
     }
 
     private void updateThisDevice(int status) {
@@ -1738,7 +2168,7 @@
         //Application does not have transaction id information
         //go through stored requests to remove
         boolean removed = false;
-        for (int i=0; i < clientInfo.mReqList.size(); i++) {
+        for (int i=0; i<clientInfo.mReqList.size(); i++) {
             if (req.equals(clientInfo.mReqList.valueAt(i))) {
                 removed = true;
                 clientInfo.mReqList.removeAt(i);
@@ -2077,5 +2507,4 @@
             mServList = new ArrayList<WifiP2pServiceInfo>();
         }
     }
-
 }
