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..b7e0683 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 8f68ae3..315f2d5 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -751,7 +751,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 35cdf9b..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 0dd43c1..964e2f3 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
@@ -19,6 +19,8 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 
@@ -48,6 +50,8 @@
 
     public static class Options {
         public boolean generatePublicAccess = true;
+        public boolean listAllDeps = false;
+        public boolean listOnlyMissingDeps = false;
     }
 
     public static final Options sOptions = new Options();
@@ -61,10 +65,23 @@
 
         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);
         }
@@ -121,17 +138,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;
     }
 
     private static Set<String> getExcludedClasses(CreateInfo info) {
@@ -153,14 +186,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);
@@ -175,7 +215,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 54f47be..a5cb855 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) {
@@ -1653,7 +1653,7 @@
             handlePostDhcpSetup();
 
             mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
-            mDhcpStateMachine.quit();
+            mDhcpStateMachine.doQuit();
             mDhcpStateMachine = null;
         }
 
@@ -3538,6 +3538,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>();
         }
     }
-
 }
