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/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index 54a89ad..5612943 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,
@@ -191,18 +186,18 @@
                 }
                 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));
+                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 +227,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 +243,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 +260,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 +269,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 {
@@ -369,7 +366,7 @@
      */
     public boolean teardown() {
         setTeardownRequested(true);
-        return (setEnableApn(mApnType, false) != Phone.APN_REQUEST_FAILED);
+        return (setEnableApn(mApnType, false) != PhoneConstants.APN_REQUEST_FAILED);
     }
 
     /**
@@ -418,17 +415,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 +467,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 +479,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 +490,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 +545,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/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/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/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/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/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/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 2b2b818..71c8c83 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;
@@ -1590,7 +1592,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/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 1068267..4d22f33 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;
@@ -220,7 +221,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);
@@ -335,11 +336,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)) {
@@ -422,26 +423,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;
         }
     }
 
@@ -638,7 +640,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:
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/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 4b2066f..73edbd3 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;
@@ -621,10 +621,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 +727,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/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/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..230f07b 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();
             }
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/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index 00832ee..5aa3a29 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;
@@ -1195,7 +1196,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 {
@@ -1204,14 +1205,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/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/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/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.java b/telephony/java/com/android/internal/telephony/AdnRecord.java
deleted file mode 100644
index 1bf2d3c..0000000
--- a/telephony/java/com/android/internal/telephony/AdnRecord.java
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.telephony.PhoneNumberUtils;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.util.Arrays;
-
-
-/**
- *
- * Used to load or store ADNs (Abbreviated Dialing Numbers).
- *
- * {@hide}
- *
- */
-public class AdnRecord implements Parcelable {
-    static final String LOG_TAG = "GSM";
-
-    //***** Instance Variables
-
-    String alphaTag = null;
-    String number = null;
-    String[] emails;
-    int extRecord = 0xff;
-    int efid;                   // or 0 if none
-    int recordNumber;           // or 0 if none
-
-
-    //***** Constants
-
-    // In an ADN record, everything but the alpha identifier
-    // is in a footer that's 14 bytes
-    static final int FOOTER_SIZE_BYTES = 14;
-
-    // Maximum size of the un-extended number field
-    static final int MAX_NUMBER_SIZE_BYTES = 11;
-
-    static final int EXT_RECORD_LENGTH_BYTES = 13;
-    static final int EXT_RECORD_TYPE_ADDITIONAL_DATA = 2;
-    static final int EXT_RECORD_TYPE_MASK = 3;
-    static final int MAX_EXT_CALLED_PARTY_LENGTH = 0xa;
-
-    // ADN offset
-    static final int ADN_BCD_NUMBER_LENGTH = 0;
-    static final int ADN_TON_AND_NPI = 1;
-    static final int ADN_DIALING_NUMBER_START = 2;
-    static final int ADN_DIALING_NUMBER_END = 11;
-    static final int ADN_CAPABILITY_ID = 12;
-    static final int ADN_EXTENSION_ID = 13;
-
-    //***** Static Methods
-
-    public static final Parcelable.Creator<AdnRecord> CREATOR
-            = new Parcelable.Creator<AdnRecord>() {
-        public AdnRecord createFromParcel(Parcel source) {
-            int efid;
-            int recordNumber;
-            String alphaTag;
-            String number;
-            String[] emails;
-
-            efid = source.readInt();
-            recordNumber = source.readInt();
-            alphaTag = source.readString();
-            number = source.readString();
-            emails = source.readStringArray();
-
-            return new AdnRecord(efid, recordNumber, alphaTag, number, emails);
-        }
-
-        public AdnRecord[] newArray(int size) {
-            return new AdnRecord[size];
-        }
-    };
-
-
-    //***** Constructor
-    public AdnRecord (byte[] record) {
-        this(0, 0, record);
-    }
-
-    public AdnRecord (int efid, int recordNumber, byte[] record) {
-        this.efid = efid;
-        this.recordNumber = recordNumber;
-        parseRecord(record);
-    }
-
-    public AdnRecord (String alphaTag, String number) {
-        this(0, 0, alphaTag, number);
-    }
-
-    public AdnRecord (String alphaTag, String number, String[] emails) {
-        this(0, 0, alphaTag, number, emails);
-    }
-
-    public AdnRecord (int efid, int recordNumber, String alphaTag, String number, String[] emails) {
-        this.efid = efid;
-        this.recordNumber = recordNumber;
-        this.alphaTag = alphaTag;
-        this.number = number;
-        this.emails = emails;
-    }
-
-    public AdnRecord(int efid, int recordNumber, String alphaTag, String number) {
-        this.efid = efid;
-        this.recordNumber = recordNumber;
-        this.alphaTag = alphaTag;
-        this.number = number;
-        this.emails = null;
-    }
-
-    //***** Instance Methods
-
-    public String getAlphaTag() {
-        return alphaTag;
-    }
-
-    public String getNumber() {
-        return number;
-    }
-
-    public String[] getEmails() {
-        return emails;
-    }
-
-    public void setEmails(String[] emails) {
-        this.emails = emails;
-    }
-
-    public String toString() {
-        return "ADN Record '" + alphaTag + "' '" + number + " " + emails + "'";
-    }
-
-    public boolean isEmpty() {
-        return TextUtils.isEmpty(alphaTag) && TextUtils.isEmpty(number) && emails == null;
-    }
-
-    public boolean hasExtendedRecord() {
-        return extRecord != 0 && extRecord != 0xff;
-    }
-
-    /** Helper function for {@link #isEqual}. */
-    private static boolean stringCompareNullEqualsEmpty(String s1, String s2) {
-        if (s1 == s2) {
-            return true;
-        }
-        if (s1 == null) {
-            s1 = "";
-        }
-        if (s2 == null) {
-            s2 = "";
-        }
-        return (s1.equals(s2));
-    }
-
-    public boolean isEqual(AdnRecord adn) {
-        return ( stringCompareNullEqualsEmpty(alphaTag, adn.alphaTag) &&
-                stringCompareNullEqualsEmpty(number, adn.number) &&
-                Arrays.equals(emails, adn.emails));
-    }
-    //***** Parcelable Implementation
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(efid);
-        dest.writeInt(recordNumber);
-        dest.writeString(alphaTag);
-        dest.writeString(number);
-        dest.writeStringArray(emails);
-    }
-
-    /**
-     * Build adn hex byte array based on record size
-     * The format of byte array is defined in 51.011 10.5.1
-     *
-     * @param recordSize is the size X of EF record
-     * @return hex byte[recordSize] to be written to EF record
-     *          return null for wrong format of dialing number or tag
-     */
-    public byte[] buildAdnString(int recordSize) {
-        byte[] bcdNumber;
-        byte[] byteTag;
-        byte[] adnString;
-        int footerOffset = recordSize - FOOTER_SIZE_BYTES;
-
-        // create an empty record
-        adnString = new byte[recordSize];
-        for (int i = 0; i < recordSize; i++) {
-            adnString[i] = (byte) 0xFF;
-        }
-
-        if (TextUtils.isEmpty(number)) {
-            Log.w(LOG_TAG, "[buildAdnString] Empty dialing number");
-            return adnString;   // return the empty record (for delete)
-        } else if (number.length()
-                > (ADN_DIALING_NUMBER_END - ADN_DIALING_NUMBER_START + 1) * 2) {
-            Log.w(LOG_TAG,
-                    "[buildAdnString] Max length of dialing number is 20");
-            return null;
-        } else if (alphaTag != null && alphaTag.length() > footerOffset) {
-            Log.w(LOG_TAG,
-                    "[buildAdnString] Max length of tag is " + footerOffset);
-            return null;
-        } else {
-            bcdNumber = PhoneNumberUtils.numberToCalledPartyBCD(number);
-
-            System.arraycopy(bcdNumber, 0, adnString,
-                    footerOffset + ADN_TON_AND_NPI, bcdNumber.length);
-
-            adnString[footerOffset + ADN_BCD_NUMBER_LENGTH]
-                    = (byte) (bcdNumber.length);
-            adnString[footerOffset + ADN_CAPABILITY_ID]
-                    = (byte) 0xFF; // Capability Id
-            adnString[footerOffset + ADN_EXTENSION_ID]
-                    = (byte) 0xFF; // Extension Record Id
-
-            if (!TextUtils.isEmpty(alphaTag)) {
-                byteTag = GsmAlphabet.stringToGsm8BitPacked(alphaTag);
-                System.arraycopy(byteTag, 0, adnString, 0, byteTag.length);
-            }
-
-            return adnString;
-        }
-    }
-
-    /**
-     * See TS 51.011 10.5.10
-     */
-    public void
-    appendExtRecord (byte[] extRecord) {
-        try {
-            if (extRecord.length != EXT_RECORD_LENGTH_BYTES) {
-                return;
-            }
-
-            if ((extRecord[0] & EXT_RECORD_TYPE_MASK)
-                    != EXT_RECORD_TYPE_ADDITIONAL_DATA) {
-                return;
-            }
-
-            if ((0xff & extRecord[1]) > MAX_EXT_CALLED_PARTY_LENGTH) {
-                // invalid or empty record
-                return;
-            }
-
-            number += PhoneNumberUtils.calledPartyBCDFragmentToString(
-                                        extRecord, 2, 0xff & extRecord[1]);
-
-            // We don't support ext record chaining.
-
-        } catch (RuntimeException ex) {
-            Log.w(LOG_TAG, "Error parsing AdnRecord ext record", ex);
-        }
-    }
-
-    //***** Private Methods
-
-    /**
-     * alphaTag and number are set to null on invalid format
-     */
-    private void
-    parseRecord(byte[] record) {
-        try {
-            alphaTag = IccUtils.adnStringFieldToString(
-                            record, 0, record.length - FOOTER_SIZE_BYTES);
-
-            int footerOffset = record.length - FOOTER_SIZE_BYTES;
-
-            int numberLength = 0xff & record[footerOffset];
-
-            if (numberLength > MAX_NUMBER_SIZE_BYTES) {
-                // Invalid number length
-                number = "";
-                return;
-            }
-
-            // Please note 51.011 10.5.1:
-            //
-            // "If the Dialling Number/SSC String does not contain
-            // a dialling number, e.g. a control string deactivating
-            // a service, the TON/NPI byte shall be set to 'FF' by
-            // the ME (see note 2)."
-
-            number = PhoneNumberUtils.calledPartyBCDToString(
-                            record, footerOffset + 1, numberLength);
-
-
-            extRecord = 0xff & record[record.length - 1];
-
-            emails = null;
-
-        } catch (RuntimeException ex) {
-            Log.w(LOG_TAG, "Error parsing AdnRecord", ex);
-            number = "";
-            alphaTag = "";
-            emails = null;
-        }
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/AdnRecordCache.java b/telephony/java/com/android/internal/telephony/AdnRecordCache.java
deleted file mode 100644
index db5f4da..0000000
--- a/telephony/java/com/android/internal/telephony/AdnRecordCache.java
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-import android.util.SparseArray;
-
-import com.android.internal.telephony.gsm.UsimPhoneBookManager;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-/**
- * {@hide}
- */
-public final class AdnRecordCache extends Handler implements IccConstants {
-    //***** Instance Variables
-
-    private IccFileHandler mFh;
-    private UsimPhoneBookManager mUsimPhoneBookManager;
-
-    // Indexed by EF ID
-    SparseArray<ArrayList<AdnRecord>> adnLikeFiles
-        = new SparseArray<ArrayList<AdnRecord>>();
-
-    // People waiting for ADN-like files to be loaded
-    SparseArray<ArrayList<Message>> adnLikeWaiters
-        = new SparseArray<ArrayList<Message>>();
-
-    // People waiting for adn record to be updated
-    SparseArray<Message> userWriteResponse = new SparseArray<Message>();
-
-    //***** Event Constants
-
-    static final int EVENT_LOAD_ALL_ADN_LIKE_DONE = 1;
-    static final int EVENT_UPDATE_ADN_DONE = 2;
-
-    //***** Constructor
-
-
-
-    public AdnRecordCache(IccFileHandler fh) {
-        mFh = fh;
-        mUsimPhoneBookManager = new UsimPhoneBookManager(mFh, this);
-    }
-
-    //***** Called from SIMRecords
-
-    /**
-     * Called from SIMRecords.onRadioNotAvailable and SIMRecords.handleSimRefresh.
-     */
-    public void reset() {
-        adnLikeFiles.clear();
-        mUsimPhoneBookManager.reset();
-
-        clearWaiters();
-        clearUserWriters();
-
-    }
-
-    private void clearWaiters() {
-        int size = adnLikeWaiters.size();
-        for (int i = 0; i < size; i++) {
-            ArrayList<Message> waiters = adnLikeWaiters.valueAt(i);
-            AsyncResult ar = new AsyncResult(null, null, new RuntimeException("AdnCache reset"));
-            notifyWaiters(waiters, ar);
-        }
-        adnLikeWaiters.clear();
-    }
-
-    private void clearUserWriters() {
-        int size = userWriteResponse.size();
-        for (int i = 0; i < size; i++) {
-            sendErrorResponse(userWriteResponse.valueAt(i), "AdnCace reset");
-        }
-        userWriteResponse.clear();
-    }
-
-    /**
-     * @return List of AdnRecords for efid if we've already loaded them this
-     * radio session, or null if we haven't
-     */
-    public ArrayList<AdnRecord>
-    getRecordsIfLoaded(int efid) {
-        return adnLikeFiles.get(efid);
-    }
-
-    /**
-     * Returns extension ef associated with ADN-like EF or -1 if
-     * we don't know.
-     *
-     * See 3GPP TS 51.011 for this mapping
-     */
-    int extensionEfForEf(int efid) {
-        switch (efid) {
-            case EF_MBDN: return EF_EXT6;
-            case EF_ADN: return EF_EXT1;
-            case EF_SDN: return EF_EXT3;
-            case EF_FDN: return EF_EXT2;
-            case EF_MSISDN: return EF_EXT1;
-            case EF_PBR: return 0; // The EF PBR doesn't have an extension record
-            default: return -1;
-        }
-    }
-
-    private void sendErrorResponse(Message response, String errString) {
-        if (response != null) {
-            Exception e = new RuntimeException(errString);
-            AsyncResult.forMessage(response).exception = e;
-            response.sendToTarget();
-        }
-    }
-
-    /**
-     * Update an ADN-like record in EF by record index
-     *
-     * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN
-     * @param adn is the new adn to be stored
-     * @param recordIndex is the 1-based adn record index
-     * @param pin2 is required to update EF_FDN, otherwise must be null
-     * @param response message to be posted when done
-     *        response.exception hold the exception in error
-     */
-    public void updateAdnByIndex(int efid, AdnRecord adn, int recordIndex, String pin2,
-            Message response) {
-
-        int extensionEF = extensionEfForEf(efid);
-        if (extensionEF < 0) {
-            sendErrorResponse(response, "EF is not known ADN-like EF:" + efid);
-            return;
-        }
-
-        Message pendingResponse = userWriteResponse.get(efid);
-        if (pendingResponse != null) {
-            sendErrorResponse(response, "Have pending update for EF:" + efid);
-            return;
-        }
-
-        userWriteResponse.put(efid, response);
-
-        new AdnRecordLoader(mFh).updateEF(adn, efid, extensionEF,
-                recordIndex, pin2,
-                obtainMessage(EVENT_UPDATE_ADN_DONE, efid, recordIndex, adn));
-    }
-
-    /**
-     * Replace oldAdn with newAdn in ADN-like record in EF
-     *
-     * The ADN-like records must be read through requestLoadAllAdnLike() before
-     *
-     * @param efid must be one of EF_ADN, EF_FDN, and EF_SDN
-     * @param oldAdn is the adn to be replaced
-     *        If oldAdn.isEmpty() is ture, it insert the newAdn
-     * @param newAdn is the adn to be stored
-     *        If newAdn.isEmpty() is true, it delete the oldAdn
-     * @param pin2 is required to update EF_FDN, otherwise must be null
-     * @param response message to be posted when done
-     *        response.exception hold the exception in error
-     */
-    public void updateAdnBySearch(int efid, AdnRecord oldAdn, AdnRecord newAdn,
-            String pin2, Message response) {
-
-        int extensionEF;
-        extensionEF = extensionEfForEf(efid);
-
-        if (extensionEF < 0) {
-            sendErrorResponse(response, "EF is not known ADN-like EF:" + efid);
-            return;
-        }
-
-        ArrayList<AdnRecord>  oldAdnList;
-
-        if (efid == EF_PBR) {
-            oldAdnList = mUsimPhoneBookManager.loadEfFilesFromUsim();
-        } else {
-            oldAdnList = getRecordsIfLoaded(efid);
-        }
-
-        if (oldAdnList == null) {
-            sendErrorResponse(response, "Adn list not exist for EF:" + efid);
-            return;
-        }
-
-        int index = -1;
-        int count = 1;
-        for (Iterator<AdnRecord> it = oldAdnList.iterator(); it.hasNext(); ) {
-            if (oldAdn.isEqual(it.next())) {
-                index = count;
-                break;
-            }
-            count++;
-        }
-
-        if (index == -1) {
-            sendErrorResponse(response, "Adn record don't exist for " + oldAdn);
-            return;
-        }
-
-        if (efid == EF_PBR) {
-            AdnRecord foundAdn = oldAdnList.get(index-1);
-            efid = foundAdn.efid;
-            extensionEF = foundAdn.extRecord;
-            index = foundAdn.recordNumber;
-
-            newAdn.efid = efid;
-            newAdn.extRecord = extensionEF;
-            newAdn.recordNumber = index;
-        }
-
-        Message pendingResponse = userWriteResponse.get(efid);
-
-        if (pendingResponse != null) {
-            sendErrorResponse(response, "Have pending update for EF:" + efid);
-            return;
-        }
-
-        userWriteResponse.put(efid, response);
-
-        new AdnRecordLoader(mFh).updateEF(newAdn, efid, extensionEF,
-                index, pin2,
-                obtainMessage(EVENT_UPDATE_ADN_DONE, efid, index, newAdn));
-    }
-
-
-    /**
-     * Responds with exception (in response) if efid is not a known ADN-like
-     * record
-     */
-    public void
-    requestLoadAllAdnLike (int efid, int extensionEf, Message response) {
-        ArrayList<Message> waiters;
-        ArrayList<AdnRecord> result;
-
-        if (efid == EF_PBR) {
-            result = mUsimPhoneBookManager.loadEfFilesFromUsim();
-        } else {
-            result = getRecordsIfLoaded(efid);
-        }
-
-        // Have we already loaded this efid?
-        if (result != null) {
-            if (response != null) {
-                AsyncResult.forMessage(response).result = result;
-                response.sendToTarget();
-            }
-
-            return;
-        }
-
-        // Have we already *started* loading this efid?
-
-        waiters = adnLikeWaiters.get(efid);
-
-        if (waiters != null) {
-            // There's a pending request for this EF already
-            // just add ourselves to it
-
-            waiters.add(response);
-            return;
-        }
-
-        // Start loading efid
-
-        waiters = new ArrayList<Message>();
-        waiters.add(response);
-
-        adnLikeWaiters.put(efid, waiters);
-
-
-        if (extensionEf < 0) {
-            // respond with error if not known ADN-like record
-
-            if (response != null) {
-                AsyncResult.forMessage(response).exception
-                    = new RuntimeException("EF is not known ADN-like EF:" + efid);
-                response.sendToTarget();
-            }
-
-            return;
-        }
-
-        new AdnRecordLoader(mFh).loadAllFromEF(efid, extensionEf,
-            obtainMessage(EVENT_LOAD_ALL_ADN_LIKE_DONE, efid, 0));
-    }
-
-    //***** Private methods
-
-    private void
-    notifyWaiters(ArrayList<Message> waiters, AsyncResult ar) {
-
-        if (waiters == null) {
-            return;
-        }
-
-        for (int i = 0, s = waiters.size() ; i < s ; i++) {
-            Message waiter = waiters.get(i);
-
-            AsyncResult.forMessage(waiter, ar.result, ar.exception);
-            waiter.sendToTarget();
-        }
-    }
-
-    //***** Overridden from Handler
-
-    public void
-    handleMessage(Message msg) {
-        AsyncResult ar;
-        int efid;
-
-        switch(msg.what) {
-            case EVENT_LOAD_ALL_ADN_LIKE_DONE:
-                /* arg1 is efid, obj.result is ArrayList<AdnRecord>*/
-                ar = (AsyncResult) msg.obj;
-                efid = msg.arg1;
-                ArrayList<Message> waiters;
-
-                waiters = adnLikeWaiters.get(efid);
-                adnLikeWaiters.delete(efid);
-
-                if (ar.exception == null) {
-                    adnLikeFiles.put(efid, (ArrayList<AdnRecord>) ar.result);
-                }
-                notifyWaiters(waiters, ar);
-                break;
-            case EVENT_UPDATE_ADN_DONE:
-                ar = (AsyncResult)msg.obj;
-                efid = msg.arg1;
-                int index = msg.arg2;
-                AdnRecord adn = (AdnRecord) (ar.userObj);
-
-                if (ar.exception == null) {
-                    adnLikeFiles.get(efid).set(index - 1, adn);
-                    mUsimPhoneBookManager.invalidateCache();
-                }
-
-                Message response = userWriteResponse.get(efid);
-                userWriteResponse.delete(efid);
-
-                AsyncResult.forMessage(response, null, ar.exception);
-                response.sendToTarget();
-                break;
-        }
-
-    }
-
-
-}
diff --git a/telephony/java/com/android/internal/telephony/AdnRecordLoader.java b/telephony/java/com/android/internal/telephony/AdnRecordLoader.java
deleted file mode 100644
index 084fae6..0000000
--- a/telephony/java/com/android/internal/telephony/AdnRecordLoader.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import java.util.ArrayList;
-
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-
-public class AdnRecordLoader extends Handler {
-    final static String LOG_TAG = "RIL_AdnRecordLoader";
-
-    //***** Instance Variables
-
-    private IccFileHandler mFh;
-    int ef;
-    int extensionEF;
-    int pendingExtLoads;
-    Message userResponse;
-    String pin2;
-
-    // For "load one"
-    int recordNumber;
-
-    // for "load all"
-    ArrayList<AdnRecord> adns; // only valid after EVENT_ADN_LOAD_ALL_DONE
-
-    // Either an AdnRecord or a reference to adns depending
-    // if this is a load one or load all operation
-    Object result;
-
-    //***** Event Constants
-
-    static final int EVENT_ADN_LOAD_DONE = 1;
-    static final int EVENT_EXT_RECORD_LOAD_DONE = 2;
-    static final int EVENT_ADN_LOAD_ALL_DONE = 3;
-    static final int EVENT_EF_LINEAR_RECORD_SIZE_DONE = 4;
-    static final int EVENT_UPDATE_RECORD_DONE = 5;
-
-    //***** Constructor
-
-    public AdnRecordLoader(IccFileHandler fh) {
-        // The telephony unit-test cases may create AdnRecords
-        // in secondary threads
-        super(Looper.getMainLooper());
-        mFh = fh;
-    }
-
-    /**
-     * Resulting AdnRecord is placed in response.obj.result
-     * or response.obj.exception is set
-     */
-    public void
-    loadFromEF(int ef, int extensionEF, int recordNumber,
-                Message response) {
-        this.ef = ef;
-        this.extensionEF = extensionEF;
-        this.recordNumber = recordNumber;
-        this.userResponse = response;
-
-        mFh.loadEFLinearFixed(
-                    ef, recordNumber,
-                    obtainMessage(EVENT_ADN_LOAD_DONE));
-
-    }
-
-
-    /**
-     * Resulting ArrayList&lt;adnRecord> is placed in response.obj.result
-     * or response.obj.exception is set
-     */
-    public void
-    loadAllFromEF(int ef, int extensionEF,
-                Message response) {
-        this.ef = ef;
-        this.extensionEF = extensionEF;
-        this.userResponse = response;
-
-        mFh.loadEFLinearFixedAll(
-                    ef,
-                    obtainMessage(EVENT_ADN_LOAD_ALL_DONE));
-
-    }
-
-    /**
-     * Write adn to a EF SIM record
-     * It will get the record size of EF record and compose hex adn array
-     * then write the hex array to EF record
-     *
-     * @param adn is set with alphaTag and phone number
-     * @param ef EF fileid
-     * @param extensionEF extension EF fileid
-     * @param recordNumber 1-based record index
-     * @param pin2 for CHV2 operations, must be null if pin2 is not needed
-     * @param response will be sent to its handler when completed
-     */
-    public void
-    updateEF(AdnRecord adn, int ef, int extensionEF, int recordNumber,
-            String pin2, Message response) {
-        this.ef = ef;
-        this.extensionEF = extensionEF;
-        this.recordNumber = recordNumber;
-        this.userResponse = response;
-        this.pin2 = pin2;
-
-        mFh.getEFLinearRecordSize( ef,
-            obtainMessage(EVENT_EF_LINEAR_RECORD_SIZE_DONE, adn));
-    }
-
-    //***** Overridden from Handler
-
-    public void
-    handleMessage(Message msg) {
-        AsyncResult ar;
-        byte data[];
-        AdnRecord adn;
-
-        try {
-            switch (msg.what) {
-                case EVENT_EF_LINEAR_RECORD_SIZE_DONE:
-                    ar = (AsyncResult)(msg.obj);
-                    adn = (AdnRecord)(ar.userObj);
-
-                    if (ar.exception != null) {
-                        throw new RuntimeException("get EF record size failed",
-                                ar.exception);
-                    }
-
-                    int[] recordSize = (int[])ar.result;
-                    // recordSize is int[3] array
-                    // int[0]  is the record length
-                    // int[1]  is the total length of the EF file
-                    // int[2]  is the number of records in the EF file
-                    // So int[0] * int[2] = int[1]
-                   if (recordSize.length != 3 || recordNumber > recordSize[2]) {
-                        throw new RuntimeException("get wrong EF record size format",
-                                ar.exception);
-                    }
-
-                    data = adn.buildAdnString(recordSize[0]);
-
-                    if(data == null) {
-                        throw new RuntimeException("wrong ADN format",
-                                ar.exception);
-                    }
-
-                    mFh.updateEFLinearFixed(ef, recordNumber,
-                            data, pin2, obtainMessage(EVENT_UPDATE_RECORD_DONE));
-
-                    pendingExtLoads = 1;
-
-                    break;
-                case EVENT_UPDATE_RECORD_DONE:
-                    ar = (AsyncResult)(msg.obj);
-                    if (ar.exception != null) {
-                        throw new RuntimeException("update EF adn record failed",
-                                ar.exception);
-                    }
-                    pendingExtLoads = 0;
-                    result = null;
-                    break;
-                case EVENT_ADN_LOAD_DONE:
-                    ar = (AsyncResult)(msg.obj);
-                    data = (byte[])(ar.result);
-
-                    if (ar.exception != null) {
-                        throw new RuntimeException("load failed", ar.exception);
-                    }
-
-                    if (false) {
-                        Log.d(LOG_TAG,"ADN EF: 0x"
-                            + Integer.toHexString(ef)
-                            + ":" + recordNumber
-                            + "\n" + IccUtils.bytesToHexString(data));
-                    }
-
-                    adn = new AdnRecord(ef, recordNumber, data);
-                    result = adn;
-
-                    if (adn.hasExtendedRecord()) {
-                        // If we have a valid value in the ext record field,
-                        // we're not done yet: we need to read the corresponding
-                        // ext record and append it
-
-                        pendingExtLoads = 1;
-
-                        mFh.loadEFLinearFixed(
-                            extensionEF, adn.extRecord,
-                            obtainMessage(EVENT_EXT_RECORD_LOAD_DONE, adn));
-                    }
-                break;
-
-                case EVENT_EXT_RECORD_LOAD_DONE:
-                    ar = (AsyncResult)(msg.obj);
-                    data = (byte[])(ar.result);
-                    adn = (AdnRecord)(ar.userObj);
-
-                    if (ar.exception != null) {
-                        throw new RuntimeException("load failed", ar.exception);
-                    }
-
-                    Log.d(LOG_TAG,"ADN extension EF: 0x"
-                        + Integer.toHexString(extensionEF)
-                        + ":" + adn.extRecord
-                        + "\n" + IccUtils.bytesToHexString(data));
-
-                    adn.appendExtRecord(data);
-
-                    pendingExtLoads--;
-                    // result should have been set in
-                    // EVENT_ADN_LOAD_DONE or EVENT_ADN_LOAD_ALL_DONE
-                break;
-
-                case EVENT_ADN_LOAD_ALL_DONE:
-                    ar = (AsyncResult)(msg.obj);
-                    ArrayList<byte[]> datas = (ArrayList<byte[]>)(ar.result);
-
-                    if (ar.exception != null) {
-                        throw new RuntimeException("load failed", ar.exception);
-                    }
-
-                    adns = new ArrayList<AdnRecord>(datas.size());
-                    result = adns;
-                    pendingExtLoads = 0;
-
-                    for(int i = 0, s = datas.size() ; i < s ; i++) {
-                        adn = new AdnRecord(ef, 1 + i, datas.get(i));
-                        adns.add(adn);
-
-                        if (adn.hasExtendedRecord()) {
-                            // If we have a valid value in the ext record field,
-                            // we're not done yet: we need to read the corresponding
-                            // ext record and append it
-
-                            pendingExtLoads++;
-
-                            mFh.loadEFLinearFixed(
-                                extensionEF, adn.extRecord,
-                                obtainMessage(EVENT_EXT_RECORD_LOAD_DONE, adn));
-                        }
-                    }
-                break;
-            }
-        } catch (RuntimeException exc) {
-            if (userResponse != null) {
-                AsyncResult.forMessage(userResponse)
-                                .exception = exc;
-                userResponse.sendToTarget();
-                // Loading is all or nothing--either every load succeeds
-                // or we fail the whole thing.
-                userResponse = null;
-            }
-            return;
-        }
-
-        if (userResponse != null && pendingExtLoads == 0) {
-            AsyncResult.forMessage(userResponse).result
-                = result;
-
-            userResponse.sendToTarget();
-            userResponse = null;
-        }
-    }
-
-
-}
diff --git a/telephony/java/com/android/internal/telephony/ApnContext.java b/telephony/java/com/android/internal/telephony/ApnContext.java
deleted file mode 100644
index 9746398..0000000
--- a/telephony/java/com/android/internal/telephony/ApnContext.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Maintain the Apn context
- */
-public class ApnContext {
-
-    public final String LOG_TAG;
-
-    protected static final boolean DBG = true;
-
-    private final String mApnType;
-
-    private DataConnectionTracker.State mState;
-
-    private ArrayList<ApnSetting> mWaitingApns = null;
-
-    /** A zero indicates that all waiting APNs had a permanent error */
-    private AtomicInteger mWaitingApnsPermanentFailureCountDown;
-
-    private ApnSetting mApnSetting;
-
-    DataConnection mDataConnection;
-
-    DataConnectionAc mDataConnectionAc;
-
-    String mReason;
-
-    int mRetryCount;
-
-    /**
-     * user/app requested connection on this APN
-     */
-    AtomicBoolean mDataEnabled;
-
-    /**
-     * carrier requirements met
-     */
-    AtomicBoolean mDependencyMet;
-
-    public ApnContext(String apnType, String logTag) {
-        mApnType = apnType;
-        mState = DataConnectionTracker.State.IDLE;
-        setReason(Phone.REASON_DATA_ENABLED);
-        setRetryCount(0);
-        mDataEnabled = new AtomicBoolean(false);
-        mDependencyMet = new AtomicBoolean(true);
-        mWaitingApnsPermanentFailureCountDown = new AtomicInteger(0);
-        LOG_TAG = logTag;
-    }
-
-    public String getApnType() {
-        return mApnType;
-    }
-
-    public synchronized DataConnection getDataConnection() {
-        return mDataConnection;
-    }
-
-    public synchronized void setDataConnection(DataConnection dc) {
-        if (DBG) {
-            log("setDataConnection: old dc=" + mDataConnection + " new dc=" + dc + " this=" + this);
-        }
-        mDataConnection = dc;
-    }
-
-
-    public synchronized DataConnectionAc getDataConnectionAc() {
-        return mDataConnectionAc;
-    }
-
-    public synchronized void setDataConnectionAc(DataConnectionAc dcac) {
-        if (DBG) {
-            log("setDataConnectionAc: old dcac=" + mDataConnectionAc + " new dcac=" + dcac);
-        }
-        if (dcac != null) {
-            dcac.addApnContextSync(this);
-        } else {
-            if (mDataConnectionAc != null) {
-                mDataConnectionAc.removeApnContextSync(this);
-            }
-        }
-        mDataConnectionAc = dcac;
-    }
-
-    public synchronized ApnSetting getApnSetting() {
-        return mApnSetting;
-    }
-
-    public synchronized void setApnSetting(ApnSetting apnSetting) {
-        mApnSetting = apnSetting;
-    }
-
-    public synchronized void setWaitingApns(ArrayList<ApnSetting> waitingApns) {
-        mWaitingApns = waitingApns;
-        mWaitingApnsPermanentFailureCountDown.set(mWaitingApns.size());
-    }
-
-    public int getWaitingApnsPermFailCount() {
-        return mWaitingApnsPermanentFailureCountDown.get();
-    }
-
-    public void decWaitingApnsPermFailCount() {
-        mWaitingApnsPermanentFailureCountDown.decrementAndGet();
-    }
-
-    public synchronized ApnSetting getNextWaitingApn() {
-        ArrayList<ApnSetting> list = mWaitingApns;
-        ApnSetting apn = null;
-
-        if (list != null) {
-            if (!list.isEmpty()) {
-                apn = list.get(0);
-            }
-        }
-        return apn;
-    }
-
-    public synchronized void removeWaitingApn(ApnSetting apn) {
-        if (mWaitingApns != null) {
-            mWaitingApns.remove(apn);
-        }
-    }
-
-    public synchronized ArrayList<ApnSetting> getWaitingApns() {
-        return mWaitingApns;
-    }
-
-    public synchronized void setState(DataConnectionTracker.State s) {
-        if (DBG) {
-            log("setState: " + s + ", previous state:" + mState);
-        }
-
-        mState = s;
-
-        if (mState == DataConnectionTracker.State.FAILED) {
-            if (mWaitingApns != null) {
-                mWaitingApns.clear(); // when teardown the connection and set to IDLE
-            }
-        }
-    }
-
-    public synchronized DataConnectionTracker.State getState() {
-        return mState;
-    }
-
-    public boolean isDisconnected() {
-        DataConnectionTracker.State currentState = getState();
-        return ((currentState == DataConnectionTracker.State.IDLE) ||
-                    currentState == DataConnectionTracker.State.FAILED);
-    }
-
-    public synchronized void setReason(String reason) {
-        if (DBG) {
-            log("set reason as " + reason + ",current state " + mState);
-        }
-        mReason = reason;
-    }
-
-    public synchronized String getReason() {
-        return mReason;
-    }
-
-    public synchronized void setRetryCount(int retryCount) {
-        if (DBG) {
-            log("setRetryCount: " + retryCount);
-        }
-        mRetryCount = retryCount;
-        DataConnection dc = mDataConnection;
-        if (dc != null) {
-            dc.setRetryCount(retryCount);
-        }
-    }
-
-    public synchronized int getRetryCount() {
-        return mRetryCount;
-    }
-
-    public boolean isReady() {
-        return mDataEnabled.get() && mDependencyMet.get();
-    }
-
-    public void setEnabled(boolean enabled) {
-        if (DBG) {
-            log("set enabled as " + enabled + ", current state is " + mDataEnabled.get());
-        }
-        mDataEnabled.set(enabled);
-    }
-
-    public boolean isEnabled() {
-        return mDataEnabled.get();
-    }
-
-    public void setDependencyMet(boolean met) {
-        if (DBG) {
-            log("set mDependencyMet as " + met + " current state is " + mDependencyMet.get());
-        }
-        mDependencyMet.set(met);
-    }
-
-    public boolean getDependencyMet() {
-       return mDependencyMet.get();
-    }
-
-    @Override
-    public String toString() {
-        // We don't print mDataConnection because its recursive.
-        return "{mApnType=" + mApnType + " mState=" + getState() + " mWaitingApns=" + mWaitingApns +
-                " mWaitingApnsPermanentFailureCountDown=" + mWaitingApnsPermanentFailureCountDown +
-                " mApnSetting=" + mApnSetting + " mDataConnectionAc=" + mDataConnectionAc +
-                " mReason=" + mReason + " mRetryCount=" + mRetryCount +
-                " mDataEnabled=" + mDataEnabled + " mDependencyMet=" + mDependencyMet + "}";
-    }
-
-    protected void log(String s) {
-        Log.d(LOG_TAG, "[ApnContext:" + mApnType + "] " + s);
-    }
-
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("ApnContext: " + this.toString());
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/ApnSetting.java b/telephony/java/com/android/internal/telephony/ApnSetting.java
deleted file mode 100755
index ad69fdb..0000000
--- a/telephony/java/com/android/internal/telephony/ApnSetting.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-/**
- * This class represents a apn setting for create PDP link
- */
-public class ApnSetting {
-
-    static final String V2_FORMAT_REGEX = "^\\[ApnSettingV2\\]\\s*";
-
-    public final String carrier;
-    public final String apn;
-    public final String proxy;
-    public final String port;
-    public final String mmsc;
-    public final String mmsProxy;
-    public final String mmsPort;
-    public final String user;
-    public final String password;
-    public final int authType;
-    public final String[] types;
-    public final int id;
-    public final String numeric;
-    public final String protocol;
-    public final String roamingProtocol;
-    /**
-      * Current status of APN
-      * true : enabled APN, false : disabled APN.
-      */
-    public final boolean carrierEnabled;
-    /**
-      * Radio Access Technology info
-      * To check what values can hold, refer to ServiceState.java.
-      * This should be spread to other technologies,
-      * but currently only used for LTE(14) and EHRPD(13).
-      */
-    public final int bearer;
-
-    public ApnSetting(int id, String numeric, String carrier, String apn,
-            String proxy, String port,
-            String mmsc, String mmsProxy, String mmsPort,
-            String user, String password, int authType, String[] types,
-            String protocol, String roamingProtocol, boolean carrierEnabled, int bearer) {
-        this.id = id;
-        this.numeric = numeric;
-        this.carrier = carrier;
-        this.apn = apn;
-        this.proxy = proxy;
-        this.port = port;
-        this.mmsc = mmsc;
-        this.mmsProxy = mmsProxy;
-        this.mmsPort = mmsPort;
-        this.user = user;
-        this.password = password;
-        this.authType = authType;
-        this.types = types;
-        this.protocol = protocol;
-        this.roamingProtocol = roamingProtocol;
-        this.carrierEnabled = carrierEnabled;
-        this.bearer = bearer;
-    }
-
-    /**
-     * Creates an ApnSetting object from a string.
-     *
-     * @param data the string to read.
-     *
-     * The string must be in one of two formats (newlines added for clarity,
-     * spaces are optional):
-     *
-     * v1 format:
-     *   <carrier>, <apn>, <proxy>, <port>, <mmsc>, <mmsproxy>,
-     *   <mmsport>, <user>, <password>, <authtype>, <mcc>,<mnc>,
-     *   <type>[, <type>...]
-     *
-     * v2 format:
-     *   [ApnSettingV2] <carrier>, <apn>, <proxy>, <port>, <mmsc>, <mmsproxy>,
-     *   <mmsport>, <user>, <password>, <authtype>, <mcc>, <mnc>,
-     *   <type>[| <type>...], <protocol>, <roaming_protocol>, <carrierEnabled>, <bearer>
-     *
-     * Note that the strings generated by toString() do not contain the username
-     * and password and thus cannot be read by this method.
-     *
-     * @see ApnSettingTest
-     */
-    public static ApnSetting fromString(String data) {
-        if (data == null) return null;
-
-        int version;
-        // matches() operates on the whole string, so append .* to the regex.
-        if (data.matches(V2_FORMAT_REGEX + ".*")) {
-            version = 2;
-            data = data.replaceFirst(V2_FORMAT_REGEX, "");
-        } else {
-            version = 1;
-        }
-
-        String[] a = data.split("\\s*,\\s*");
-        if (a.length < 14) {
-            return null;
-        }
-
-        int authType;
-        try {
-            authType = Integer.parseInt(a[12]);
-        } catch (Exception e) {
-            authType = 0;
-        }
-
-        String[] typeArray;
-        String protocol, roamingProtocol;
-        boolean carrierEnabled;
-        int bearer;
-        if (version == 1) {
-            typeArray = new String[a.length - 13];
-            System.arraycopy(a, 13, typeArray, 0, a.length - 13);
-            protocol = RILConstants.SETUP_DATA_PROTOCOL_IP;
-            roamingProtocol = RILConstants.SETUP_DATA_PROTOCOL_IP;
-            carrierEnabled = true;
-            bearer = 0;
-        } else {
-            if (a.length < 18) {
-                return null;
-            }
-            typeArray = a[13].split("\\s*\\|\\s*");
-            protocol = a[14];
-            roamingProtocol = a[15];
-            try {
-                carrierEnabled = Boolean.parseBoolean(a[16]);
-            } catch (Exception e) {
-                carrierEnabled = true;
-            }
-            bearer = Integer.parseInt(a[17]);
-        }
-
-        return new ApnSetting(-1,a[10]+a[11],a[0],a[1],a[2],a[3],a[7],a[8],
-                a[9],a[4],a[5],authType,typeArray,protocol,roamingProtocol,carrierEnabled,bearer);
-    }
-
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("[ApnSettingV2] ")
-        .append(carrier)
-        .append(", ").append(id)
-        .append(", ").append(numeric)
-        .append(", ").append(apn)
-        .append(", ").append(proxy)
-        .append(", ").append(mmsc)
-        .append(", ").append(mmsProxy)
-        .append(", ").append(mmsPort)
-        .append(", ").append(port)
-        .append(", ").append(authType).append(", ");
-        for (int i = 0; i < types.length; i++) {
-            sb.append(types[i]);
-            if (i < types.length - 1) {
-                sb.append(" | ");
-            }
-        }
-        sb.append(", ").append(protocol);
-        sb.append(", ").append(roamingProtocol);
-        sb.append(", ").append(carrierEnabled);
-        sb.append(", ").append(bearer);
-        return sb.toString();
-    }
-
-    public boolean canHandleType(String type) {
-        for (String t : types) {
-            // DEFAULT handles all, and HIPRI is handled by DEFAULT
-            if (t.equalsIgnoreCase(type) ||
-                    t.equalsIgnoreCase(Phone.APN_TYPE_ALL) ||
-                    (t.equalsIgnoreCase(Phone.APN_TYPE_DEFAULT) &&
-                    type.equalsIgnoreCase(Phone.APN_TYPE_HIPRI))) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    // TODO - if we have this function we should also have hashCode.
-    // Also should handle changes in type order and perhaps case-insensitivity
-    public boolean equals(Object o) {
-        if (o instanceof ApnSetting == false) return false;
-        return (this.toString().equals(o.toString()));
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java
deleted file mode 100644
index 35cdf9bd..0000000
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ /dev/null
@@ -1,721 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-
-import android.content.Context;
-import android.os.RegistrantList;
-import android.os.Registrant;
-import android.os.Handler;
-import android.os.AsyncResult;
-import android.os.SystemProperties;
-import android.util.Log;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * {@hide}
- */
-public abstract class BaseCommands implements CommandsInterface {
-    static final String LOG_TAG = "RILB";
-
-    //***** Instance Variables
-    protected Context mContext;
-    protected RadioState mState = RadioState.RADIO_UNAVAILABLE;
-    protected Object mStateMonitor = new Object();
-
-    protected RegistrantList mRadioStateChangedRegistrants = new RegistrantList();
-    protected RegistrantList mOnRegistrants = new RegistrantList();
-    protected RegistrantList mAvailRegistrants = new RegistrantList();
-    protected RegistrantList mOffOrNotAvailRegistrants = new RegistrantList();
-    protected RegistrantList mNotAvailRegistrants = new RegistrantList();
-    protected RegistrantList mCallStateRegistrants = new RegistrantList();
-    protected RegistrantList mVoiceNetworkStateRegistrants = new RegistrantList();
-    protected RegistrantList mDataNetworkStateRegistrants = new RegistrantList();
-    protected RegistrantList mVoiceRadioTechChangedRegistrants = new RegistrantList();
-    protected RegistrantList mIccStatusChangedRegistrants = new RegistrantList();
-    protected RegistrantList mVoicePrivacyOnRegistrants = new RegistrantList();
-    protected RegistrantList mVoicePrivacyOffRegistrants = new RegistrantList();
-    protected Registrant mUnsolOemHookRawRegistrant;
-    protected RegistrantList mOtaProvisionRegistrants = new RegistrantList();
-    protected RegistrantList mCallWaitingInfoRegistrants = new RegistrantList();
-    protected RegistrantList mDisplayInfoRegistrants = new RegistrantList();
-    protected RegistrantList mSignalInfoRegistrants = new RegistrantList();
-    protected RegistrantList mNumberInfoRegistrants = new RegistrantList();
-    protected RegistrantList mRedirNumInfoRegistrants = new RegistrantList();
-    protected RegistrantList mLineControlInfoRegistrants = new RegistrantList();
-    protected RegistrantList mT53ClirInfoRegistrants = new RegistrantList();
-    protected RegistrantList mT53AudCntrlInfoRegistrants = new RegistrantList();
-    protected RegistrantList mRingbackToneRegistrants = new RegistrantList();
-    protected RegistrantList mResendIncallMuteRegistrants = new RegistrantList();
-    protected RegistrantList mCdmaSubscriptionChangedRegistrants = new RegistrantList();
-    protected RegistrantList mCdmaPrlChangedRegistrants = new RegistrantList();
-    protected RegistrantList mExitEmergencyCallbackModeRegistrants = new RegistrantList();
-    protected RegistrantList mRilConnectedRegistrants = new RegistrantList();
-    protected RegistrantList mIccRefreshRegistrants = new RegistrantList();
-
-    protected Registrant mGsmSmsRegistrant;
-    protected Registrant mCdmaSmsRegistrant;
-    protected Registrant mNITZTimeRegistrant;
-    protected Registrant mSignalStrengthRegistrant;
-    protected Registrant mUSSDRegistrant;
-    protected Registrant mSmsOnSimRegistrant;
-    protected Registrant mSmsStatusRegistrant;
-    protected Registrant mSsnRegistrant;
-    protected Registrant mCatSessionEndRegistrant;
-    protected Registrant mCatProCmdRegistrant;
-    protected Registrant mCatEventRegistrant;
-    protected Registrant mCatCallSetUpRegistrant;
-    protected Registrant mIccSmsFullRegistrant;
-    protected Registrant mEmergencyCallbackModeRegistrant;
-    protected Registrant mRingRegistrant;
-    protected Registrant mRestrictedStateRegistrant;
-    protected Registrant mGsmBroadcastSmsRegistrant;
-
-    // Preferred network type received from PhoneFactory.
-    // This is used when establishing a connection to the
-    // vendor ril so it starts up in the correct mode.
-    protected int mPreferredNetworkType;
-    // CDMA subscription received from PhoneFactory
-    protected int mCdmaSubscription;
-    // Type of Phone, GSM or CDMA. Set by CDMAPhone or GSMPhone.
-    protected int mPhoneType;
-    // RIL Version
-    protected int mRilVersion = -1;
-
-    public BaseCommands(Context context) {
-        mContext = context;  // May be null (if so we won't log statistics)
-    }
-
-    //***** CommandsInterface implementation
-
-    public RadioState getRadioState() {
-        return mState;
-    }
-
-    public void registerForRadioStateChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        synchronized (mStateMonitor) {
-            mRadioStateChangedRegistrants.add(r);
-            r.notifyRegistrant();
-        }
-    }
-
-    public void unregisterForRadioStateChanged(Handler h) {
-        synchronized (mStateMonitor) {
-            mRadioStateChangedRegistrants.remove(h);
-        }
-    }
-
-    public void registerForOn(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        synchronized (mStateMonitor) {
-            mOnRegistrants.add(r);
-
-            if (mState.isOn()) {
-                r.notifyRegistrant(new AsyncResult(null, null, null));
-            }
-        }
-    }
-    public void unregisterForOn(Handler h) {
-        synchronized (mStateMonitor) {
-            mOnRegistrants.remove(h);
-        }
-    }
-
-
-    public void registerForAvailable(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        synchronized (mStateMonitor) {
-            mAvailRegistrants.add(r);
-
-            if (mState.isAvailable()) {
-                r.notifyRegistrant(new AsyncResult(null, null, null));
-            }
-        }
-    }
-
-    public void unregisterForAvailable(Handler h) {
-        synchronized(mStateMonitor) {
-            mAvailRegistrants.remove(h);
-        }
-    }
-
-    public void registerForNotAvailable(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        synchronized (mStateMonitor) {
-            mNotAvailRegistrants.add(r);
-
-            if (!mState.isAvailable()) {
-                r.notifyRegistrant(new AsyncResult(null, null, null));
-            }
-        }
-    }
-
-    public void unregisterForNotAvailable(Handler h) {
-        synchronized (mStateMonitor) {
-            mNotAvailRegistrants.remove(h);
-        }
-    }
-
-    public void registerForOffOrNotAvailable(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        synchronized (mStateMonitor) {
-            mOffOrNotAvailRegistrants.add(r);
-
-            if (mState == RadioState.RADIO_OFF || !mState.isAvailable()) {
-                r.notifyRegistrant(new AsyncResult(null, null, null));
-            }
-        }
-    }
-    public void unregisterForOffOrNotAvailable(Handler h) {
-        synchronized(mStateMonitor) {
-            mOffOrNotAvailRegistrants.remove(h);
-        }
-    }
-
-    public void registerForCallStateChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        mCallStateRegistrants.add(r);
-    }
-
-    public void unregisterForCallStateChanged(Handler h) {
-        mCallStateRegistrants.remove(h);
-    }
-
-    public void registerForVoiceNetworkStateChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        mVoiceNetworkStateRegistrants.add(r);
-    }
-
-    public void unregisterForVoiceNetworkStateChanged(Handler h) {
-        mVoiceNetworkStateRegistrants.remove(h);
-    }
-
-    public void registerForDataNetworkStateChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        mDataNetworkStateRegistrants.add(r);
-    }
-
-    public void unregisterForDataNetworkStateChanged(Handler h) {
-        mDataNetworkStateRegistrants.remove(h);
-    }
-
-    public void registerForVoiceRadioTechChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mVoiceRadioTechChangedRegistrants.add(r);
-    }
-
-    public void unregisterForVoiceRadioTechChanged(Handler h) {
-        mVoiceRadioTechChangedRegistrants.remove(h);
-    }
-
-    public void registerForIccStatusChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mIccStatusChangedRegistrants.add(r);
-    }
-
-    public void unregisterForIccStatusChanged(Handler h) {
-        mIccStatusChangedRegistrants.remove(h);
-    }
-
-    public void setOnNewGsmSms(Handler h, int what, Object obj) {
-        mGsmSmsRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnNewGsmSms(Handler h) {
-        mGsmSmsRegistrant.clear();
-    }
-
-    public void setOnNewCdmaSms(Handler h, int what, Object obj) {
-        mCdmaSmsRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnNewCdmaSms(Handler h) {
-        mCdmaSmsRegistrant.clear();
-    }
-
-    public void setOnNewGsmBroadcastSms(Handler h, int what, Object obj) {
-        mGsmBroadcastSmsRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnNewGsmBroadcastSms(Handler h) {
-        mGsmBroadcastSmsRegistrant.clear();
-    }
-
-    public void setOnSmsOnSim(Handler h, int what, Object obj) {
-        mSmsOnSimRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnSmsOnSim(Handler h) {
-        mSmsOnSimRegistrant.clear();
-    }
-
-    public void setOnSmsStatus(Handler h, int what, Object obj) {
-        mSmsStatusRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnSmsStatus(Handler h) {
-        mSmsStatusRegistrant.clear();
-    }
-
-    public void setOnSignalStrengthUpdate(Handler h, int what, Object obj) {
-        mSignalStrengthRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnSignalStrengthUpdate(Handler h) {
-        mSignalStrengthRegistrant.clear();
-    }
-
-    public void setOnNITZTime(Handler h, int what, Object obj) {
-        mNITZTimeRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnNITZTime(Handler h) {
-        mNITZTimeRegistrant.clear();
-    }
-
-    public void setOnUSSD(Handler h, int what, Object obj) {
-        mUSSDRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnUSSD(Handler h) {
-        mUSSDRegistrant.clear();
-    }
-
-    public void setOnSuppServiceNotification(Handler h, int what, Object obj) {
-        mSsnRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnSuppServiceNotification(Handler h) {
-        mSsnRegistrant.clear();
-    }
-
-    public void setOnCatSessionEnd(Handler h, int what, Object obj) {
-        mCatSessionEndRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnCatSessionEnd(Handler h) {
-        mCatSessionEndRegistrant.clear();
-    }
-
-    public void setOnCatProactiveCmd(Handler h, int what, Object obj) {
-        mCatProCmdRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnCatProactiveCmd(Handler h) {
-        mCatProCmdRegistrant.clear();
-    }
-
-    public void setOnCatEvent(Handler h, int what, Object obj) {
-        mCatEventRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnCatEvent(Handler h) {
-        mCatEventRegistrant.clear();
-    }
-
-    public void setOnCatCallSetUp(Handler h, int what, Object obj) {
-        mCatCallSetUpRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnCatCallSetUp(Handler h) {
-        mCatCallSetUpRegistrant.clear();
-    }
-
-    public void setOnIccSmsFull(Handler h, int what, Object obj) {
-        mIccSmsFullRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnIccSmsFull(Handler h) {
-        mIccSmsFullRegistrant.clear();
-    }
-
-    public void registerForIccRefresh(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mIccRefreshRegistrants.add(r);
-    }
-    public void setOnIccRefresh(Handler h, int what, Object obj) {
-        registerForIccRefresh(h, what, obj);
-    }
-
-    public void setEmergencyCallbackMode(Handler h, int what, Object obj) {
-        mEmergencyCallbackModeRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unregisterForIccRefresh(Handler h) {
-        mIccRefreshRegistrants.remove(h);
-    }
-    public void unsetOnIccRefresh(Handler h) {
-        unregisterForIccRefresh(h);
-    }
-
-    public void setOnCallRing(Handler h, int what, Object obj) {
-        mRingRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnCallRing(Handler h) {
-        mRingRegistrant.clear();
-    }
-
-    public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mVoicePrivacyOnRegistrants.add(r);
-    }
-
-    public void unregisterForInCallVoicePrivacyOn(Handler h){
-        mVoicePrivacyOnRegistrants.remove(h);
-    }
-
-    public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mVoicePrivacyOffRegistrants.add(r);
-    }
-
-    public void unregisterForInCallVoicePrivacyOff(Handler h){
-        mVoicePrivacyOffRegistrants.remove(h);
-    }
-
-    public void setOnRestrictedStateChanged(Handler h, int what, Object obj) {
-        mRestrictedStateRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnRestrictedStateChanged(Handler h) {
-        mRestrictedStateRegistrant.clear();
-    }
-
-    public void registerForDisplayInfo(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mDisplayInfoRegistrants.add(r);
-    }
-
-    public void unregisterForDisplayInfo(Handler h) {
-        mDisplayInfoRegistrants.remove(h);
-    }
-
-    public void registerForCallWaitingInfo(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mCallWaitingInfoRegistrants.add(r);
-    }
-
-    public void unregisterForCallWaitingInfo(Handler h) {
-        mCallWaitingInfoRegistrants.remove(h);
-    }
-
-    public void registerForSignalInfo(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mSignalInfoRegistrants.add(r);
-    }
-
-    public void setOnUnsolOemHookRaw(Handler h, int what, Object obj) {
-        mUnsolOemHookRawRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnUnsolOemHookRaw(Handler h) {
-        mUnsolOemHookRawRegistrant.clear();
-    }
-
-    public void unregisterForSignalInfo(Handler h) {
-        mSignalInfoRegistrants.remove(h);
-    }
-
-    public void registerForCdmaOtaProvision(Handler h,int what, Object obj){
-        Registrant r = new Registrant (h, what, obj);
-        mOtaProvisionRegistrants.add(r);
-    }
-
-    public void unregisterForCdmaOtaProvision(Handler h){
-        mOtaProvisionRegistrants.remove(h);
-    }
-
-    public void registerForNumberInfo(Handler h,int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mNumberInfoRegistrants.add(r);
-    }
-
-    public void unregisterForNumberInfo(Handler h){
-        mNumberInfoRegistrants.remove(h);
-    }
-
-     public void registerForRedirectedNumberInfo(Handler h,int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mRedirNumInfoRegistrants.add(r);
-    }
-
-    public void unregisterForRedirectedNumberInfo(Handler h) {
-        mRedirNumInfoRegistrants.remove(h);
-    }
-
-    public void registerForLineControlInfo(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mLineControlInfoRegistrants.add(r);
-    }
-
-    public void unregisterForLineControlInfo(Handler h) {
-        mLineControlInfoRegistrants.remove(h);
-    }
-
-    public void registerFoT53ClirlInfo(Handler h,int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mT53ClirInfoRegistrants.add(r);
-    }
-
-    public void unregisterForT53ClirInfo(Handler h) {
-        mT53ClirInfoRegistrants.remove(h);
-    }
-
-    public void registerForT53AudioControlInfo(Handler h,int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mT53AudCntrlInfoRegistrants.add(r);
-    }
-
-    public void unregisterForT53AudioControlInfo(Handler h) {
-        mT53AudCntrlInfoRegistrants.remove(h);
-    }
-
-    public void registerForRingbackTone(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mRingbackToneRegistrants.add(r);
-    }
-
-    public void unregisterForRingbackTone(Handler h) {
-        mRingbackToneRegistrants.remove(h);
-    }
-
-    public void registerForResendIncallMute(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mResendIncallMuteRegistrants.add(r);
-    }
-
-    public void unregisterForResendIncallMute(Handler h) {
-        mResendIncallMuteRegistrants.remove(h);
-    }
-
-    @Override
-    public void registerForCdmaSubscriptionChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mCdmaSubscriptionChangedRegistrants.add(r);
-    }
-
-    @Override
-    public void unregisterForCdmaSubscriptionChanged(Handler h) {
-        mCdmaSubscriptionChangedRegistrants.remove(h);
-    }
-
-    @Override
-    public void registerForCdmaPrlChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mCdmaPrlChangedRegistrants.add(r);
-    }
-
-    @Override
-    public void unregisterForCdmaPrlChanged(Handler h) {
-        mCdmaPrlChangedRegistrants.remove(h);
-    }
-
-    @Override
-    public void registerForExitEmergencyCallbackMode(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mExitEmergencyCallbackModeRegistrants.add(r);
-    }
-
-    @Override
-    public void unregisterForExitEmergencyCallbackMode(Handler h) {
-        mExitEmergencyCallbackModeRegistrants.remove(h);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void registerForRilConnected(Handler h, int what, Object obj) {
-        Log.d(LOG_TAG, "registerForRilConnected h=" + h + " w=" + what);
-        Registrant r = new Registrant (h, what, obj);
-        mRilConnectedRegistrants.add(r);
-        if (mRilVersion != -1) {
-            Log.d(LOG_TAG, "Notifying: ril connected mRilVersion=" + mRilVersion);
-            r.notifyRegistrant(new AsyncResult(null, new Integer(mRilVersion), null));
-        }
-    }
-
-    @Override
-    public void unregisterForRilConnected(Handler h) {
-        mRilConnectedRegistrants.remove(h);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setCurrentPreferredNetworkType() {
-    }
-
-    //***** Protected Methods
-    /**
-     * Store new RadioState and send notification based on the changes
-     *
-     * This function is called only by RIL.java when receiving unsolicited
-     * RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED
-     *
-     * RadioState has 3 values : RADIO_OFF, RADIO_UNAVAILABLE, RADIO_ON.
-     *
-     * @param newState new RadioState decoded from RIL_UNSOL_RADIO_STATE_CHANGED
-     */
-    protected void setRadioState(RadioState newState) {
-        RadioState oldState;
-
-        synchronized (mStateMonitor) {
-            if (false) {
-                Log.v(LOG_TAG, "setRadioState old: " + mState
-                    + " new " + newState);
-            }
-
-            oldState = mState;
-            mState = newState;
-
-            if (oldState == mState) {
-                // no state transition
-                return;
-            }
-
-            mRadioStateChangedRegistrants.notifyRegistrants();
-
-            if (mState.isAvailable() && !oldState.isAvailable()) {
-                Log.d(LOG_TAG,"Notifying: radio available");
-                mAvailRegistrants.notifyRegistrants();
-                onRadioAvailable();
-            }
-
-            if (!mState.isAvailable() && oldState.isAvailable()) {
-                Log.d(LOG_TAG,"Notifying: radio not available");
-                mNotAvailRegistrants.notifyRegistrants();
-            }
-
-            if (mState.isOn() && !oldState.isOn()) {
-                Log.d(LOG_TAG,"Notifying: Radio On");
-                mOnRegistrants.notifyRegistrants();
-            }
-
-            if ((!mState.isOn() || !mState.isAvailable())
-                && !((!oldState.isOn() || !oldState.isAvailable()))
-            ) {
-                Log.d(LOG_TAG,"Notifying: radio off or not available");
-                mOffOrNotAvailRegistrants.notifyRegistrants();
-            }
-        }
-    }
-
-    protected void onRadioAvailable() {
-    }
-
-    /**
-     * The contents of the /proc/cmdline file
-     */
-    private static String getProcCmdLine()
-    {
-        String cmdline = "";
-        FileInputStream is = null;
-        try {
-            is = new FileInputStream("/proc/cmdline");
-            byte [] buffer = new byte[2048];
-            int count = is.read(buffer);
-            if (count > 0) {
-                cmdline = new String(buffer, 0, count);
-            }
-        } catch (IOException e) {
-            Log.d(LOG_TAG, "No /proc/cmdline exception=" + e);
-        } finally {
-            if (is != null) {
-                try {
-                    is.close();
-                } catch (IOException e) {
-                }
-            }
-        }
-        Log.d(LOG_TAG, "/proc/cmdline=" + cmdline);
-        return cmdline;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public int getLteOnCdmaMode() {
-        return getLteOnCdmaModeStatic();
-    }
-
-    /** Kernel command line */
-    private static final String sKernelCmdLine = getProcCmdLine();
-
-    /** Pattern for selecting the product type from the kernel command line */
-    private static final Pattern sProductTypePattern =
-        Pattern.compile("\\sproduct_type\\s*=\\s*(\\w+)");
-
-    /** The ProductType used for LTE on CDMA devices */
-    private static final String sLteOnCdmaProductType =
-        SystemProperties.get(TelephonyProperties.PROPERTY_LTE_ON_CDMA_PRODUCT_TYPE, "");
-
-    /**
-     * Return if the current radio is LTE on CDMA. This
-     * is a tri-state return value as for a period of time
-     * the mode may be unknown.
-     *
-     * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
-     * or {@link Phone#LTE_ON_CDMA_TRUE}
-     */
-    public static int getLteOnCdmaModeStatic() {
-        int retVal;
-        int curVal;
-        String productType = "";
-
-        curVal = SystemProperties.getInt(TelephonyProperties.PROPERTY_LTE_ON_CDMA_DEVICE,
-                    Phone.LTE_ON_CDMA_UNKNOWN);
-        retVal = curVal;
-        if (retVal == Phone.LTE_ON_CDMA_UNKNOWN) {
-            Matcher matcher = sProductTypePattern.matcher(sKernelCmdLine);
-            if (matcher.find()) {
-                productType = matcher.group(1);
-                if (sLteOnCdmaProductType.equals(productType)) {
-                    retVal = Phone.LTE_ON_CDMA_TRUE;
-                } else {
-                    retVal = Phone.LTE_ON_CDMA_FALSE;
-                }
-            } else {
-                retVal = Phone.LTE_ON_CDMA_FALSE;
-            }
-        }
-
-        Log.d(LOG_TAG, "getLteOnCdmaMode=" + retVal + " curVal=" + curVal +
-                " product_type='" + productType +
-                "' lteOnCdmaProductType='" + sLteOnCdmaProductType + "'");
-        return retVal;
-    }
-
-    @Override
-    public void testingEmergencyCall() {}
-}
diff --git a/telephony/java/com/android/internal/telephony/Call.java b/telephony/java/com/android/internal/telephony/Call.java
deleted file mode 100644
index 4967ab8..0000000
--- a/telephony/java/com/android/internal/telephony/Call.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import java.util.List;
-
-import android.util.Log;
-
-/**
- * {@hide}
- */
-public abstract class Call {
-    /* Enums */
-
-    public enum State {
-        IDLE, ACTIVE, HOLDING, DIALING, ALERTING, INCOMING, WAITING, DISCONNECTED, DISCONNECTING;
-
-        public boolean isAlive() {
-            return !(this == IDLE || this == DISCONNECTED || this == DISCONNECTING);
-        }
-
-        public boolean isRinging() {
-            return this == INCOMING || this == WAITING;
-        }
-
-        public boolean isDialing() {
-            return this == DIALING || this == ALERTING;
-        }
-    }
-
-
-    /* Instance Variables */
-
-    public State state = State.IDLE;
-
-
-    // Flag to indicate if the current calling/caller information
-    // is accurate. If false the information is known to be accurate.
-    //
-    // For CDMA, during call waiting/3 way, there is no network response
-    // if call waiting is answered, network timed out, dropped, 3 way
-    // merged, etc.
-    protected boolean isGeneric = false;
-
-    protected final String LOG_TAG = "Call";
-
-    /* Instance Methods */
-
-    /** Do not modify the List result!!! This list is not yours to keep
-     *  It will change across event loop iterations            top
-     */
-
-    public abstract List<Connection> getConnections();
-    public abstract Phone getPhone();
-    public abstract boolean isMultiparty();
-    public abstract void hangup() throws CallStateException;
-
-
-    /**
-     * hasConnection
-     *
-     * @param c a Connection object
-     * @return true if the call contains the connection object passed in
-     */
-    public boolean hasConnection(Connection c) {
-        return c.getCall() == this;
-    }
-
-    /**
-     * hasConnections
-     * @return true if the call contains one or more connections
-     */
-    public boolean hasConnections() {
-        List connections = getConnections();
-
-        if (connections == null) {
-            return false;
-        }
-
-        return connections.size() > 0;
-    }
-
-    /**
-     * getState
-     * @return state of class call
-     */
-    public State getState() {
-        return state;
-    }
-
-    /**
-     * isIdle
-     *
-     * FIXME rename
-     * @return true if the call contains only disconnected connections (if any)
-     */
-    public boolean isIdle() {
-        return !getState().isAlive();
-    }
-
-    /**
-     * Returns the Connection associated with this Call that was created
-     * first, or null if there are no Connections in this Call
-     */
-    public Connection
-    getEarliestConnection() {
-        List l;
-        long time = Long.MAX_VALUE;
-        Connection c;
-        Connection earliest = null;
-
-        l = getConnections();
-
-        if (l.size() == 0) {
-            return null;
-        }
-
-        for (int i = 0, s = l.size() ; i < s ; i++) {
-            c = (Connection) l.get(i);
-            long t;
-
-            t = c.getCreateTime();
-
-            if (t < time) {
-                earliest = c;
-                time = t;
-            }
-        }
-
-        return earliest;
-    }
-
-    public long
-    getEarliestCreateTime() {
-        List l;
-        long time = Long.MAX_VALUE;
-
-        l = getConnections();
-
-        if (l.size() == 0) {
-            return 0;
-        }
-
-        for (int i = 0, s = l.size() ; i < s ; i++) {
-            Connection c = (Connection) l.get(i);
-            long t;
-
-            t = c.getCreateTime();
-
-            time = t < time ? t : time;
-        }
-
-        return time;
-    }
-
-    public long
-    getEarliestConnectTime() {
-        long time = Long.MAX_VALUE;
-        List l = getConnections();
-
-        if (l.size() == 0) {
-            return 0;
-        }
-
-        for (int i = 0, s = l.size() ; i < s ; i++) {
-            Connection c = (Connection) l.get(i);
-            long t;
-
-            t = c.getConnectTime();
-
-            time = t < time ? t : time;
-        }
-
-        return time;
-    }
-
-
-    public boolean
-    isDialingOrAlerting() {
-        return getState().isDialing();
-    }
-
-    public boolean
-    isRinging() {
-        return getState().isRinging();
-    }
-
-    /**
-     * Returns the Connection associated with this Call that was created
-     * last, or null if there are no Connections in this Call
-     */
-    public Connection
-    getLatestConnection() {
-        List l = getConnections();
-        if (l.size() == 0) {
-            return null;
-        }
-
-        long time = 0;
-        Connection latest = null;
-        for (int i = 0, s = l.size() ; i < s ; i++) {
-            Connection c = (Connection) l.get(i);
-            long t = c.getCreateTime();
-
-            if (t > time) {
-                latest = c;
-                time = t;
-            }
-        }
-
-        return latest;
-    }
-
-    /**
-     * To indicate if the connection information is accurate
-     * or not. false means accurate. Only used for CDMA.
-     */
-    public boolean isGeneric() {
-        return isGeneric;
-    }
-
-    /**
-     * Set the generic instance variable
-     */
-    public void setGeneric(boolean generic) {
-        isGeneric = generic;
-    }
-
-    /**
-     * Hangup call if it is alive
-     */
-    public void hangupIfAlive() {
-        if (getState().isAlive()) {
-            try {
-                hangup();
-            } catch (CallStateException ex) {
-                Log.w(LOG_TAG, " hangupIfActive: caught " + ex);
-            }
-        }
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/CallForwardInfo.java b/telephony/java/com/android/internal/telephony/CallForwardInfo.java
deleted file mode 100644
index 8b853b0..0000000
--- a/telephony/java/com/android/internal/telephony/CallForwardInfo.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.telephony.PhoneNumberUtils;
-
-/**
- * See also RIL_CallForwardInfo in include/telephony/ril.h
- *
- * {@hide}
- */
-public class CallForwardInfo {
-    public int             status;      /*1 = active, 0 = not active */
-    public int             reason;      /* from TS 27.007 7.11 "reason" */
-    public int             serviceClass; /* Sum of CommandsInterface.SERVICE_CLASS */
-    public int             toa;         /* "type" from TS 27.007 7.11 */
-    public String          number;      /* "number" from TS 27.007 7.11 */
-    public int             timeSeconds; /* for CF no reply only */
-
-    public String toString() {
-        return super.toString() + (status == 0 ? " not active " : " active ")
-            + " reason: " + reason
-            + " serviceClass: " + serviceClass
-            + " \"" + PhoneNumberUtils.stringFromStringAndTOA(number, toa) + "\" "
-            + timeSeconds + " seconds";
-
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java
deleted file mode 100644
index f825f31..0000000
--- a/telephony/java/com/android/internal/telephony/CallManager.java
+++ /dev/null
@@ -1,1855 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import com.android.internal.telephony.sip.SipPhone;
-
-import android.content.Context;
-import android.media.AudioManager;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.RegistrantList;
-import android.os.Registrant;
-import android.telephony.PhoneStateListener;
-import android.telephony.ServiceState;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-
-
-/**
- * @hide
- *
- * CallManager class provides an abstract layer for PhoneApp to access
- * and control calls. It implements Phone interface.
- *
- * CallManager provides call and connection control as well as
- * channel capability.
- *
- * There are three categories of APIs CallManager provided
- *
- *  1. Call control and operation, such as dial() and hangup()
- *  2. Channel capabilities, such as CanConference()
- *  3. Register notification
- *
- *
- */
-public final class CallManager {
-
-    private static final String LOG_TAG ="CallManager";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    private static final int EVENT_DISCONNECT = 100;
-    private static final int EVENT_PRECISE_CALL_STATE_CHANGED = 101;
-    private static final int EVENT_NEW_RINGING_CONNECTION = 102;
-    private static final int EVENT_UNKNOWN_CONNECTION = 103;
-    private static final int EVENT_INCOMING_RING = 104;
-    private static final int EVENT_RINGBACK_TONE = 105;
-    private static final int EVENT_IN_CALL_VOICE_PRIVACY_ON = 106;
-    private static final int EVENT_IN_CALL_VOICE_PRIVACY_OFF = 107;
-    private static final int EVENT_CALL_WAITING = 108;
-    private static final int EVENT_DISPLAY_INFO = 109;
-    private static final int EVENT_SIGNAL_INFO = 110;
-    private static final int EVENT_CDMA_OTA_STATUS_CHANGE = 111;
-    private static final int EVENT_RESEND_INCALL_MUTE = 112;
-    private static final int EVENT_MMI_INITIATE = 113;
-    private static final int EVENT_MMI_COMPLETE = 114;
-    private static final int EVENT_ECM_TIMER_RESET = 115;
-    private static final int EVENT_SUBSCRIPTION_INFO_READY = 116;
-    private static final int EVENT_SUPP_SERVICE_FAILED = 117;
-    private static final int EVENT_SERVICE_STATE_CHANGED = 118;
-    private static final int EVENT_POST_DIAL_CHARACTER = 119;
-
-    // Singleton instance
-    private static final CallManager INSTANCE = new CallManager();
-
-    // list of registered phones, which are PhoneBase objs
-    private final ArrayList<Phone> mPhones;
-
-    // list of supported ringing calls
-    private final ArrayList<Call> mRingingCalls;
-
-    // list of supported background calls
-    private final ArrayList<Call> mBackgroundCalls;
-
-    // list of supported foreground calls
-    private final ArrayList<Call> mForegroundCalls;
-
-    // empty connection list
-    private final ArrayList<Connection> emptyConnections = new ArrayList<Connection>();
-
-    // default phone as the first phone registered, which is PhoneBase obj
-    private Phone mDefaultPhone;
-
-    // state registrants
-    protected final RegistrantList mPreciseCallStateRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mNewRingingConnectionRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mIncomingRingRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mDisconnectRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mMmiRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mUnknownConnectionRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mRingbackToneRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mInCallVoicePrivacyOnRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mInCallVoicePrivacyOffRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mCallWaitingRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mDisplayInfoRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mSignalInfoRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mCdmaOtaStatusChangeRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mResendIncallMuteRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mMmiInitiateRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mMmiCompleteRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mEcmTimerResetRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mSubscriptionInfoReadyRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mSuppServiceFailedRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mServiceStateChangedRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mPostDialCharacterRegistrants
-    = new RegistrantList();
-
-    private CallManager() {
-        mPhones = new ArrayList<Phone>();
-        mRingingCalls = new ArrayList<Call>();
-        mBackgroundCalls = new ArrayList<Call>();
-        mForegroundCalls = new ArrayList<Call>();
-        mDefaultPhone = null;
-    }
-
-    /**
-     * get singleton instance of CallManager
-     * @return CallManager
-     */
-    public static CallManager getInstance() {
-        return INSTANCE;
-    }
-
-    /**
-     * Get the corresponding PhoneBase obj
-     *
-     * @param phone a Phone object
-     * @return the corresponding PhoneBase obj in Phone if Phone
-     * is a PhoneProxy obj
-     * or the Phone itself if Phone is not a PhoneProxy obj
-     */
-    private static Phone getPhoneBase(Phone phone) {
-        if (phone instanceof PhoneProxy) {
-            return phone.getForegroundCall().getPhone();
-        }
-        return phone;
-    }
-
-    /**
-     * Check if two phones refer to the same PhoneBase obj
-     *
-     * Note: PhoneBase, not PhoneProxy, is to be used inside of CallManager
-     *
-     * Both PhoneBase and PhoneProxy implement Phone interface, so
-     * they have same phone APIs, such as dial(). The real implementation, for
-     * example in GSM,  is in GSMPhone as extend from PhoneBase, so that
-     * foregroundCall.getPhone() returns GSMPhone obj. On the other hand,
-     * PhoneFactory.getDefaultPhone() returns PhoneProxy obj, which has a class
-     * member of GSMPhone.
-     *
-     * So for phone returned by PhoneFacotry, which is used by PhoneApp,
-     *        phone.getForegroundCall().getPhone() != phone
-     * but
-     *        isSamePhone(phone, phone.getForegroundCall().getPhone()) == true
-     *
-     * @param p1 is the first Phone obj
-     * @param p2 is the second Phone obj
-     * @return true if p1 and p2 refer to the same phone
-     */
-    public static boolean isSamePhone(Phone p1, Phone p2) {
-        return (getPhoneBase(p1) == getPhoneBase(p2));
-    }
-
-    /**
-     * Returns all the registered phone objects.
-     * @return all the registered phone objects.
-     */
-    public List<Phone> getAllPhones() {
-        return Collections.unmodifiableList(mPhones);
-    }
-
-    /**
-     * Get current coarse-grained voice call state.
-     * If the Call Manager has an active call and call waiting occurs,
-     * then the phone state is RINGING not OFFHOOK
-     *
-     */
-    public Phone.State getState() {
-        Phone.State s = Phone.State.IDLE;
-
-        for (Phone phone : mPhones) {
-            if (phone.getState() == Phone.State.RINGING) {
-                s = Phone.State.RINGING;
-            } else if (phone.getState() == Phone.State.OFFHOOK) {
-                if (s == Phone.State.IDLE) s = Phone.State.OFFHOOK;
-            }
-        }
-        return s;
-    }
-
-    /**
-     * @return the service state of CallManager, which represents the
-     * highest priority state of all the service states of phones
-     *
-     * The priority is defined as
-     *
-     * STATE_IN_SERIVCE > STATE_OUT_OF_SERIVCE > STATE_EMERGENCY > STATE_POWER_OFF
-     *
-     */
-
-    public int getServiceState() {
-        int resultState = ServiceState.STATE_OUT_OF_SERVICE;
-
-        for (Phone phone : mPhones) {
-            int serviceState = phone.getServiceState().getState();
-            if (serviceState == ServiceState.STATE_IN_SERVICE) {
-                // IN_SERVICE has the highest priority
-                resultState = serviceState;
-                break;
-            } else if (serviceState == ServiceState.STATE_OUT_OF_SERVICE) {
-                // OUT_OF_SERVICE replaces EMERGENCY_ONLY and POWER_OFF
-                // Note: EMERGENCY_ONLY is not in use at this moment
-                if ( resultState == ServiceState.STATE_EMERGENCY_ONLY ||
-                        resultState == ServiceState.STATE_POWER_OFF) {
-                    resultState = serviceState;
-                }
-            } else if (serviceState == ServiceState.STATE_EMERGENCY_ONLY) {
-                if (resultState == ServiceState.STATE_POWER_OFF) {
-                    resultState = serviceState;
-                }
-            }
-        }
-        return resultState;
-    }
-
-    /**
-     * Register phone to CallManager
-     * @param phone to be registered
-     * @return true if register successfully
-     */
-    public boolean registerPhone(Phone phone) {
-        Phone basePhone = getPhoneBase(phone);
-
-        if (basePhone != null && !mPhones.contains(basePhone)) {
-
-            if (DBG) {
-                Log.d(LOG_TAG, "registerPhone(" +
-                        phone.getPhoneName() + " " + phone + ")");
-            }
-
-            if (mPhones.isEmpty()) {
-                mDefaultPhone = basePhone;
-            }
-            mPhones.add(basePhone);
-            mRingingCalls.add(basePhone.getRingingCall());
-            mBackgroundCalls.add(basePhone.getBackgroundCall());
-            mForegroundCalls.add(basePhone.getForegroundCall());
-            registerForPhoneStates(basePhone);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * unregister phone from CallManager
-     * @param phone to be unregistered
-     */
-    public void unregisterPhone(Phone phone) {
-        Phone basePhone = getPhoneBase(phone);
-
-        if (basePhone != null && mPhones.contains(basePhone)) {
-
-            if (DBG) {
-                Log.d(LOG_TAG, "unregisterPhone(" +
-                        phone.getPhoneName() + " " + phone + ")");
-            }
-
-            mPhones.remove(basePhone);
-            mRingingCalls.remove(basePhone.getRingingCall());
-            mBackgroundCalls.remove(basePhone.getBackgroundCall());
-            mForegroundCalls.remove(basePhone.getForegroundCall());
-            unregisterForPhoneStates(basePhone);
-            if (basePhone == mDefaultPhone) {
-                if (mPhones.isEmpty()) {
-                    mDefaultPhone = null;
-                } else {
-                    mDefaultPhone = mPhones.get(0);
-                }
-            }
-        }
-    }
-
-    /**
-     * return the default phone or null if no phone available
-     */
-    public Phone getDefaultPhone() {
-        return mDefaultPhone;
-    }
-
-    /**
-     * @return the phone associated with the foreground call
-     */
-    public Phone getFgPhone() {
-        return getActiveFgCall().getPhone();
-    }
-
-    /**
-     * @return the phone associated with the background call
-     */
-    public Phone getBgPhone() {
-        return getFirstActiveBgCall().getPhone();
-    }
-
-    /**
-     * @return the phone associated with the ringing call
-     */
-    public Phone getRingingPhone() {
-        return getFirstActiveRingingCall().getPhone();
-    }
-
-    public void setAudioMode() {
-        Context context = getContext();
-        if (context == null) return;
-        AudioManager audioManager = (AudioManager)
-                context.getSystemService(Context.AUDIO_SERVICE);
-
-        // change the audio mode and request/abandon audio focus according to phone state,
-        // but only on audio mode transitions
-        switch (getState()) {
-            case RINGING:
-                if (audioManager.getMode() != AudioManager.MODE_RINGTONE) {
-                    // only request audio focus if the ringtone is going to be heard
-                    if (audioManager.getStreamVolume(AudioManager.STREAM_RING) > 0) {
-                        if (VDBG) Log.d(LOG_TAG, "requestAudioFocus on STREAM_RING");
-                        audioManager.requestAudioFocusForCall(AudioManager.STREAM_RING,
-                                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
-                    }
-                    audioManager.setMode(AudioManager.MODE_RINGTONE);
-                }
-                break;
-            case OFFHOOK:
-                Phone offhookPhone = getFgPhone();
-                if (getActiveFgCallState() == Call.State.IDLE) {
-                    // There is no active Fg calls, the OFFHOOK state
-                    // is set by the Bg call. So set the phone to bgPhone.
-                    offhookPhone = getBgPhone();
-                }
-
-                int newAudioMode = AudioManager.MODE_IN_CALL;
-                if (offhookPhone instanceof SipPhone) {
-                    // enable IN_COMMUNICATION audio mode instead for sipPhone
-                    newAudioMode = AudioManager.MODE_IN_COMMUNICATION;
-                }
-                if (audioManager.getMode() != newAudioMode) {
-                    // request audio focus before setting the new mode
-                    if (VDBG) Log.d(LOG_TAG, "requestAudioFocus on STREAM_VOICE_CALL");
-                    audioManager.requestAudioFocusForCall(AudioManager.STREAM_VOICE_CALL,
-                            AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
-                    audioManager.setMode(newAudioMode);
-                }
-                break;
-            case IDLE:
-                if (audioManager.getMode() != AudioManager.MODE_NORMAL) {
-                    audioManager.setMode(AudioManager.MODE_NORMAL);
-                    if (VDBG) Log.d(LOG_TAG, "abandonAudioFocus");
-                    // abandon audio focus after the mode has been set back to normal
-                    audioManager.abandonAudioFocusForCall();
-                }
-                break;
-        }
-    }
-
-    private Context getContext() {
-        Phone defaultPhone = getDefaultPhone();
-        return ((defaultPhone == null) ? null : defaultPhone.getContext());
-    }
-
-    private void registerForPhoneStates(Phone phone) {
-        // for common events supported by all phones
-        phone.registerForPreciseCallStateChanged(mHandler, EVENT_PRECISE_CALL_STATE_CHANGED, null);
-        phone.registerForDisconnect(mHandler, EVENT_DISCONNECT, null);
-        phone.registerForNewRingingConnection(mHandler, EVENT_NEW_RINGING_CONNECTION, null);
-        phone.registerForUnknownConnection(mHandler, EVENT_UNKNOWN_CONNECTION, null);
-        phone.registerForIncomingRing(mHandler, EVENT_INCOMING_RING, null);
-        phone.registerForRingbackTone(mHandler, EVENT_RINGBACK_TONE, null);
-        phone.registerForInCallVoicePrivacyOn(mHandler, EVENT_IN_CALL_VOICE_PRIVACY_ON, null);
-        phone.registerForInCallVoicePrivacyOff(mHandler, EVENT_IN_CALL_VOICE_PRIVACY_OFF, null);
-        phone.registerForDisplayInfo(mHandler, EVENT_DISPLAY_INFO, null);
-        phone.registerForSignalInfo(mHandler, EVENT_SIGNAL_INFO, null);
-        phone.registerForResendIncallMute(mHandler, EVENT_RESEND_INCALL_MUTE, null);
-        phone.registerForMmiInitiate(mHandler, EVENT_MMI_INITIATE, null);
-        phone.registerForMmiComplete(mHandler, EVENT_MMI_COMPLETE, null);
-        phone.registerForSuppServiceFailed(mHandler, EVENT_SUPP_SERVICE_FAILED, null);
-        phone.registerForServiceStateChanged(mHandler, EVENT_SERVICE_STATE_CHANGED, null);
-
-        // for events supported only by GSM and CDMA phone
-        if (phone.getPhoneType() == Phone.PHONE_TYPE_GSM ||
-                phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) {
-            phone.setOnPostDialCharacter(mHandler, EVENT_POST_DIAL_CHARACTER, null);
-        }
-
-        // for events supported only by CDMA phone
-        if (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA ){
-            phone.registerForCdmaOtaStatusChange(mHandler, EVENT_CDMA_OTA_STATUS_CHANGE, null);
-            phone.registerForSubscriptionInfoReady(mHandler, EVENT_SUBSCRIPTION_INFO_READY, null);
-            phone.registerForCallWaiting(mHandler, EVENT_CALL_WAITING, null);
-            phone.registerForEcmTimerReset(mHandler, EVENT_ECM_TIMER_RESET, null);
-        }
-    }
-
-    private void unregisterForPhoneStates(Phone phone) {
-        //  for common events supported by all phones
-        phone.unregisterForPreciseCallStateChanged(mHandler);
-        phone.unregisterForDisconnect(mHandler);
-        phone.unregisterForNewRingingConnection(mHandler);
-        phone.unregisterForUnknownConnection(mHandler);
-        phone.unregisterForIncomingRing(mHandler);
-        phone.unregisterForRingbackTone(mHandler);
-        phone.unregisterForInCallVoicePrivacyOn(mHandler);
-        phone.unregisterForInCallVoicePrivacyOff(mHandler);
-        phone.unregisterForDisplayInfo(mHandler);
-        phone.unregisterForSignalInfo(mHandler);
-        phone.unregisterForResendIncallMute(mHandler);
-        phone.unregisterForMmiInitiate(mHandler);
-        phone.unregisterForMmiComplete(mHandler);
-        phone.unregisterForSuppServiceFailed(mHandler);
-        phone.unregisterForServiceStateChanged(mHandler);
-
-        // for events supported only by GSM and CDMA phone
-        if (phone.getPhoneType() == Phone.PHONE_TYPE_GSM ||
-                phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) {
-            phone.setOnPostDialCharacter(null, EVENT_POST_DIAL_CHARACTER, null);
-        }
-
-        // for events supported only by CDMA phone
-        if (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA ){
-            phone.unregisterForCdmaOtaStatusChange(mHandler);
-            phone.unregisterForSubscriptionInfoReady(mHandler);
-            phone.unregisterForCallWaiting(mHandler);
-            phone.unregisterForEcmTimerReset(mHandler);
-        }
-    }
-
-    /**
-     * Answers a ringing or waiting call.
-     *
-     * Active call, if any, go on hold.
-     * If active call can't be held, i.e., a background call of the same channel exists,
-     * the active call will be hang up.
-     *
-     * Answering occurs asynchronously, and final notification occurs via
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}.
-     *
-     * @exception CallStateException when call is not ringing or waiting
-     */
-    public void acceptCall(Call ringingCall) throws CallStateException {
-        Phone ringingPhone = ringingCall.getPhone();
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "acceptCall(" +ringingCall + " from " + ringingCall.getPhone() + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if ( hasActiveFgCall() ) {
-            Phone activePhone = getActiveFgCall().getPhone();
-            boolean hasBgCall = ! (activePhone.getBackgroundCall().isIdle());
-            boolean sameChannel = (activePhone == ringingPhone);
-
-            if (VDBG) {
-                Log.d(LOG_TAG, "hasBgCall: "+ hasBgCall + "sameChannel:" + sameChannel);
-            }
-
-            if (sameChannel && hasBgCall) {
-                getActiveFgCall().hangup();
-            } else if (!sameChannel && !hasBgCall) {
-                activePhone.switchHoldingAndActive();
-            } else if (!sameChannel && hasBgCall) {
-                getActiveFgCall().hangup();
-            }
-        }
-
-        ringingPhone.acceptCall();
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End acceptCall(" +ringingCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-    }
-
-    /**
-     * Reject (ignore) a ringing call. In GSM, this means UDUB
-     * (User Determined User Busy). Reject occurs asynchronously,
-     * and final notification occurs via
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}.
-     *
-     * @exception CallStateException when no call is ringing or waiting
-     */
-    public void rejectCall(Call ringingCall) throws CallStateException {
-        if (VDBG) {
-            Log.d(LOG_TAG, "rejectCall(" +ringingCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        Phone ringingPhone = ringingCall.getPhone();
-
-        ringingPhone.rejectCall();
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End rejectCall(" +ringingCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-    }
-
-    /**
-     * Places active call on hold, and makes held call active.
-     * Switch occurs asynchronously and may fail.
-     *
-     * There are 4 scenarios
-     * 1. only active call but no held call, aka, hold
-     * 2. no active call but only held call, aka, unhold
-     * 3. both active and held calls from same phone, aka, swap
-     * 4. active and held calls from different phones, aka, phone swap
-     *
-     * Final notification occurs via
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}.
-     *
-     * @exception CallStateException if active call is ringing, waiting, or
-     * dialing/alerting, or heldCall can't be active.
-     * In these cases, this operation may not be performed.
-     */
-    public void switchHoldingAndActive(Call heldCall) throws CallStateException {
-        Phone activePhone = null;
-        Phone heldPhone = null;
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "switchHoldingAndActive(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (hasActiveFgCall()) {
-            activePhone = getActiveFgCall().getPhone();
-        }
-
-        if (heldCall != null) {
-            heldPhone = heldCall.getPhone();
-        }
-
-        if (activePhone != null) {
-            activePhone.switchHoldingAndActive();
-        }
-
-        if (heldPhone != null && heldPhone != activePhone) {
-            heldPhone.switchHoldingAndActive();
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End switchHoldingAndActive(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-    }
-
-    /**
-     * Hangup foreground call and resume the specific background call
-     *
-     * Note: this is noop if there is no foreground call or the heldCall is null
-     *
-     * @param heldCall to become foreground
-     * @throws CallStateException
-     */
-    public void hangupForegroundResumeBackground(Call heldCall) throws CallStateException {
-        Phone foregroundPhone = null;
-        Phone backgroundPhone = null;
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "hangupForegroundResumeBackground(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (hasActiveFgCall()) {
-            foregroundPhone = getFgPhone();
-            if (heldCall != null) {
-                backgroundPhone = heldCall.getPhone();
-                if (foregroundPhone == backgroundPhone) {
-                    getActiveFgCall().hangup();
-                } else {
-                // the call to be hangup and resumed belongs to different phones
-                    getActiveFgCall().hangup();
-                    switchHoldingAndActive(heldCall);
-                }
-            }
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End hangupForegroundResumeBackground(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-    }
-
-    /**
-     * Whether or not the phone can conference in the current phone
-     * state--that is, one call holding and one call active.
-     * @return true if the phone can conference; false otherwise.
-     */
-    public boolean canConference(Call heldCall) {
-        Phone activePhone = null;
-        Phone heldPhone = null;
-
-        if (hasActiveFgCall()) {
-            activePhone = getActiveFgCall().getPhone();
-        }
-
-        if (heldCall != null) {
-            heldPhone = heldCall.getPhone();
-        }
-
-        return heldPhone.getClass().equals(activePhone.getClass());
-    }
-
-    /**
-     * Conferences holding and active. Conference occurs asynchronously
-     * and may fail. Final notification occurs via
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}.
-     *
-     * @exception CallStateException if canConference() would return false.
-     * In these cases, this operation may not be performed.
-     */
-    public void conference(Call heldCall) throws CallStateException {
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "conference(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-
-        Phone fgPhone = getFgPhone();
-        if (fgPhone instanceof SipPhone) {
-            ((SipPhone) fgPhone).conference(heldCall);
-        } else if (canConference(heldCall)) {
-            fgPhone.conference();
-        } else {
-            throw(new CallStateException("Can't conference foreground and selected background call"));
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End conference(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-    }
-
-    /**
-     * Initiate a new voice connection. This happens asynchronously, so you
-     * cannot assume the audio path is connected (or a call index has been
-     * assigned) until PhoneStateChanged notification has occurred.
-     *
-     * @exception CallStateException if a new outgoing call is not currently
-     * possible because no more call slots exist or a call exists that is
-     * dialing, alerting, ringing, or waiting.  Other errors are
-     * handled asynchronously.
-     */
-    public Connection dial(Phone phone, String dialString) throws CallStateException {
-        Phone basePhone = getPhoneBase(phone);
-        Connection result;
-
-        if (VDBG) {
-            Log.d(LOG_TAG, " dial(" + basePhone + ", "+ dialString + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (!canDial(phone)) {
-            throw new CallStateException("cannot dial in current state");
-        }
-
-        if ( hasActiveFgCall() ) {
-            Phone activePhone = getActiveFgCall().getPhone();
-            boolean hasBgCall = !(activePhone.getBackgroundCall().isIdle());
-
-            if (DBG) {
-                Log.d(LOG_TAG, "hasBgCall: "+ hasBgCall + " sameChannel:" + (activePhone == basePhone));
-            }
-
-            if (activePhone != basePhone) {
-                if (hasBgCall) {
-                    Log.d(LOG_TAG, "Hangup");
-                    getActiveFgCall().hangup();
-                } else {
-                    Log.d(LOG_TAG, "Switch");
-                    activePhone.switchHoldingAndActive();
-                }
-            }
-        }
-
-        result = basePhone.dial(dialString);
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End dial(" + basePhone + ", "+ dialString + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        return result;
-    }
-
-    /**
-     * Initiate a new voice connection. This happens asynchronously, so you
-     * cannot assume the audio path is connected (or a call index has been
-     * assigned) until PhoneStateChanged notification has occurred.
-     *
-     * @exception CallStateException if a new outgoing call is not currently
-     * possible because no more call slots exist or a call exists that is
-     * dialing, alerting, ringing, or waiting.  Other errors are
-     * handled asynchronously.
-     */
-    public Connection dial(Phone phone, String dialString, UUSInfo uusInfo) throws CallStateException {
-        return phone.dial(dialString, uusInfo);
-    }
-
-    /**
-     * clear disconnect connection for each phone
-     */
-    public void clearDisconnected() {
-        for(Phone phone : mPhones) {
-            phone.clearDisconnected();
-        }
-    }
-
-    /**
-     * Phone can make a call only if ALL of the following are true:
-     *        - Phone is not powered off
-     *        - There's no incoming or waiting call
-     *        - There's available call slot in either foreground or background
-     *        - The foreground call is ACTIVE or IDLE or DISCONNECTED.
-     *          (We mainly need to make sure it *isn't* DIALING or ALERTING.)
-     * @param phone
-     * @return true if the phone can make a new call
-     */
-    private boolean canDial(Phone phone) {
-        int serviceState = phone.getServiceState().getState();
-        boolean hasRingingCall = hasActiveRingingCall();
-        boolean hasActiveCall = hasActiveFgCall();
-        boolean hasHoldingCall = hasActiveBgCall();
-        boolean allLinesTaken = hasActiveCall && hasHoldingCall;
-        Call.State fgCallState = getActiveFgCallState();
-
-        boolean result = (serviceState != ServiceState.STATE_POWER_OFF
-                && !hasRingingCall
-                && !allLinesTaken
-                && ((fgCallState == Call.State.ACTIVE)
-                    || (fgCallState == Call.State.IDLE)
-                    || (fgCallState == Call.State.DISCONNECTED)));
-
-        if (result == false) {
-            Log.d(LOG_TAG, "canDial serviceState=" + serviceState
-                            + " hasRingingCall=" + hasRingingCall
-                            + " hasActiveCall=" + hasActiveCall
-                            + " hasHoldingCall=" + hasHoldingCall
-                            + " allLinesTaken=" + allLinesTaken
-                            + " fgCallState=" + fgCallState);
-        }
-        return result;
-    }
-
-    /**
-     * Whether or not the phone can do explicit call transfer in the current
-     * phone state--that is, one call holding and one call active.
-     * @return true if the phone can do explicit call transfer; false otherwise.
-     */
-    public boolean canTransfer(Call heldCall) {
-        Phone activePhone = null;
-        Phone heldPhone = null;
-
-        if (hasActiveFgCall()) {
-            activePhone = getActiveFgCall().getPhone();
-        }
-
-        if (heldCall != null) {
-            heldPhone = heldCall.getPhone();
-        }
-
-        return (heldPhone == activePhone && activePhone.canTransfer());
-    }
-
-    /**
-     * Connects the held call and active call
-     * Disconnects the subscriber from both calls
-     *
-     * Explicit Call Transfer occurs asynchronously
-     * and may fail. Final notification occurs via
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}.
-     *
-     * @exception CallStateException if canTransfer() would return false.
-     * In these cases, this operation may not be performed.
-     */
-    public void explicitCallTransfer(Call heldCall) throws CallStateException {
-        if (VDBG) {
-            Log.d(LOG_TAG, " explicitCallTransfer(" + heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (canTransfer(heldCall)) {
-            heldCall.getPhone().explicitCallTransfer();
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End explicitCallTransfer(" + heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-    }
-
-    /**
-     * Returns a list of MMI codes that are pending for a phone. (They have initiated
-     * but have not yet completed).
-     * Presently there is only ever one.
-     *
-     * Use <code>registerForMmiInitiate</code>
-     * and <code>registerForMmiComplete</code> for change notification.
-     * @return null if phone doesn't have or support mmi code
-     */
-    public List<? extends MmiCode> getPendingMmiCodes(Phone phone) {
-        Log.e(LOG_TAG, "getPendingMmiCodes not implemented");
-        return null;
-    }
-
-    /**
-     * Sends user response to a USSD REQUEST message.  An MmiCode instance
-     * representing this response is sent to handlers registered with
-     * registerForMmiInitiate.
-     *
-     * @param ussdMessge    Message to send in the response.
-     * @return false if phone doesn't support ussd service
-     */
-    public boolean sendUssdResponse(Phone phone, String ussdMessge) {
-        Log.e(LOG_TAG, "sendUssdResponse not implemented");
-        return false;
-    }
-
-    /**
-     * Mutes or unmutes the microphone for the active call. The microphone
-     * is automatically unmuted if a call is answered, dialed, or resumed
-     * from a holding state.
-     *
-     * @param muted true to mute the microphone,
-     * false to activate the microphone.
-     */
-
-    public void setMute(boolean muted) {
-        if (VDBG) {
-            Log.d(LOG_TAG, " setMute(" + muted + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (hasActiveFgCall()) {
-            getActiveFgCall().getPhone().setMute(muted);
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End setMute(" + muted + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-    }
-
-    /**
-     * Gets current mute status. Use
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}
-     * as a change notifcation, although presently phone state changed is not
-     * fired when setMute() is called.
-     *
-     * @return true is muting, false is unmuting
-     */
-    public boolean getMute() {
-        if (hasActiveFgCall()) {
-            return getActiveFgCall().getPhone().getMute();
-        } else if (hasActiveBgCall()) {
-            return getFirstActiveBgCall().getPhone().getMute();
-        }
-        return false;
-    }
-
-    /**
-     * Enables or disables echo suppression.
-     */
-    public void setEchoSuppressionEnabled(boolean enabled) {
-        if (VDBG) {
-            Log.d(LOG_TAG, " setEchoSuppression(" + enabled + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (hasActiveFgCall()) {
-            getActiveFgCall().getPhone().setEchoSuppressionEnabled(enabled);
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End setEchoSuppression(" + enabled + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-    }
-
-    /**
-     * Play a DTMF tone on the active call.
-     *
-     * @param c should be one of 0-9, '*' or '#'. Other values will be
-     * silently ignored.
-     * @return false if no active call or the active call doesn't support
-     *         dtmf tone
-     */
-    public boolean sendDtmf(char c) {
-        boolean result = false;
-
-        if (VDBG) {
-            Log.d(LOG_TAG, " sendDtmf(" + c + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (hasActiveFgCall()) {
-            getActiveFgCall().getPhone().sendDtmf(c);
-            result = true;
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End sendDtmf(" + c + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-        return result;
-    }
-
-    /**
-     * Start to paly a DTMF tone on the active call.
-     * or there is a playing DTMF tone.
-     * @param c should be one of 0-9, '*' or '#'. Other values will be
-     * silently ignored.
-     *
-     * @return false if no active call or the active call doesn't support
-     *         dtmf tone
-     */
-    public boolean startDtmf(char c) {
-        boolean result = false;
-
-        if (VDBG) {
-            Log.d(LOG_TAG, " startDtmf(" + c + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (hasActiveFgCall()) {
-            getActiveFgCall().getPhone().startDtmf(c);
-            result = true;
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End startDtmf(" + c + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        return result;
-    }
-
-    /**
-     * Stop the playing DTMF tone. Ignored if there is no playing DTMF
-     * tone or no active call.
-     */
-    public void stopDtmf() {
-        if (VDBG) {
-            Log.d(LOG_TAG, " stopDtmf()" );
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (hasActiveFgCall()) getFgPhone().stopDtmf();
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End stopDtmf()");
-            Log.d(LOG_TAG, this.toString());
-        }
-    }
-
-    /**
-     * send burst DTMF tone, it can send the string as single character or multiple character
-     * ignore if there is no active call or not valid digits string.
-     * Valid digit means only includes characters ISO-LATIN characters 0-9, *, #
-     * The difference between sendDtmf and sendBurstDtmf is sendDtmf only sends one character,
-     * this api can send single character and multiple character, also, this api has response
-     * back to caller.
-     *
-     * @param dtmfString is string representing the dialing digit(s) in the active call
-     * @param on the DTMF ON length in milliseconds, or 0 for default
-     * @param off the DTMF OFF length in milliseconds, or 0 for default
-     * @param onComplete is the callback message when the action is processed by BP
-     *
-     */
-    public boolean sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) {
-        if (hasActiveFgCall()) {
-            getActiveFgCall().getPhone().sendBurstDtmf(dtmfString, on, off, onComplete);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Notifies when a voice connection has disconnected, either due to local
-     * or remote hangup or error.
-     *
-     *  Messages received from this will have the following members:<p>
-     *  <ul><li>Message.obj will be an AsyncResult</li>
-     *  <li>AsyncResult.userObj = obj</li>
-     *  <li>AsyncResult.result = a Connection object that is
-     *  no longer connected.</li></ul>
-     */
-    public void registerForDisconnect(Handler h, int what, Object obj) {
-        mDisconnectRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for voice disconnection notification.
-     * Extraneous calls are tolerated silently
-     */
-    public void unregisterForDisconnect(Handler h){
-        mDisconnectRegistrants.remove(h);
-    }
-
-    /**
-     * Register for getting notifications for change in the Call State {@link Call.State}
-     * This is called PreciseCallState because the call state is more precise than the
-     * {@link Phone.State} which can be obtained using the {@link PhoneStateListener}
-     *
-     * Resulting events will have an AsyncResult in <code>Message.obj</code>.
-     * AsyncResult.userData will be set to the obj argument here.
-     * The <em>h</em> parameter is held only by a weak reference.
-     */
-    public void registerForPreciseCallStateChanged(Handler h, int what, Object obj){
-        mPreciseCallStateRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for voice call state change notifications.
-     * Extraneous calls are tolerated silently.
-     */
-    public void unregisterForPreciseCallStateChanged(Handler h){
-        mPreciseCallStateRegistrants.remove(h);
-    }
-
-    /**
-     * Notifies when a previously untracked non-ringing/waiting connection has appeared.
-     * This is likely due to some other entity (eg, SIM card application) initiating a call.
-     */
-    public void registerForUnknownConnection(Handler h, int what, Object obj){
-        mUnknownConnectionRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for unknown connection notifications.
-     */
-    public void unregisterForUnknownConnection(Handler h){
-        mUnknownConnectionRegistrants.remove(h);
-    }
-
-
-    /**
-     * Notifies when a new ringing or waiting connection has appeared.<p>
-     *
-     *  Messages received from this:
-     *  Message.obj will be an AsyncResult
-     *  AsyncResult.userObj = obj
-     *  AsyncResult.result = a Connection. <p>
-     *  Please check Connection.isRinging() to make sure the Connection
-     *  has not dropped since this message was posted.
-     *  If Connection.isRinging() is true, then
-     *   Connection.getCall() == Phone.getRingingCall()
-     */
-    public void registerForNewRingingConnection(Handler h, int what, Object obj){
-        mNewRingingConnectionRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for new ringing connection notification.
-     * Extraneous calls are tolerated silently
-     */
-
-    public void unregisterForNewRingingConnection(Handler h){
-        mNewRingingConnectionRegistrants.remove(h);
-    }
-
-    /**
-     * Notifies when an incoming call rings.<p>
-     *
-     *  Messages received from this:
-     *  Message.obj will be an AsyncResult
-     *  AsyncResult.userObj = obj
-     *  AsyncResult.result = a Connection. <p>
-     */
-    public void registerForIncomingRing(Handler h, int what, Object obj){
-        mIncomingRingRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for ring notification.
-     * Extraneous calls are tolerated silently
-     */
-
-    public void unregisterForIncomingRing(Handler h){
-        mIncomingRingRegistrants.remove(h);
-    }
-
-    /**
-     * Notifies when out-band ringback tone is needed.<p>
-     *
-     *  Messages received from this:
-     *  Message.obj will be an AsyncResult
-     *  AsyncResult.userObj = obj
-     *  AsyncResult.result = boolean, true to start play ringback tone
-     *                       and false to stop. <p>
-     */
-    public void registerForRingbackTone(Handler h, int what, Object obj){
-        mRingbackToneRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for ringback tone notification.
-     */
-
-    public void unregisterForRingbackTone(Handler h){
-        mRingbackToneRegistrants.remove(h);
-    }
-
-    /**
-     * Registers the handler to reset the uplink mute state to get
-     * uplink audio.
-     */
-    public void registerForResendIncallMute(Handler h, int what, Object obj){
-        mResendIncallMuteRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for resend incall mute notifications.
-     */
-    public void unregisterForResendIncallMute(Handler h){
-        mResendIncallMuteRegistrants.remove(h);
-    }
-
-    /**
-     * Register for notifications of initiation of a new MMI code request.
-     * MMI codes for GSM are discussed in 3GPP TS 22.030.<p>
-     *
-     * Example: If Phone.dial is called with "*#31#", then the app will
-     * be notified here.<p>
-     *
-     * The returned <code>Message.obj</code> will contain an AsyncResult.
-     *
-     * <code>obj.result</code> will be an "MmiCode" object.
-     */
-    public void registerForMmiInitiate(Handler h, int what, Object obj){
-        mMmiInitiateRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for new MMI initiate notification.
-     * Extraneous calls are tolerated silently
-     */
-    public void unregisterForMmiInitiate(Handler h){
-        mMmiInitiateRegistrants.remove(h);
-    }
-
-    /**
-     * Register for notifications that an MMI request has completed
-     * its network activity and is in its final state. This may mean a state
-     * of COMPLETE, FAILED, or CANCELLED.
-     *
-     * <code>Message.obj</code> will contain an AsyncResult.
-     * <code>obj.result</code> will be an "MmiCode" object
-     */
-    public void registerForMmiComplete(Handler h, int what, Object obj){
-        mMmiCompleteRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for MMI complete notification.
-     * Extraneous calls are tolerated silently
-     */
-    public void unregisterForMmiComplete(Handler h){
-        mMmiCompleteRegistrants.remove(h);
-    }
-
-    /**
-     * Registration point for Ecm timer reset
-     * @param h handler to notify
-     * @param what user-defined message code
-     * @param obj placed in Message.obj
-     */
-    public void registerForEcmTimerReset(Handler h, int what, Object obj){
-        mEcmTimerResetRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregister for notification for Ecm timer reset
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForEcmTimerReset(Handler h){
-        mEcmTimerResetRegistrants.remove(h);
-    }
-
-    /**
-     * Register for ServiceState changed.
-     * Message.obj will contain an AsyncResult.
-     * AsyncResult.result will be a ServiceState instance
-     */
-    public void registerForServiceStateChanged(Handler h, int what, Object obj){
-        mServiceStateChangedRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for ServiceStateChange notification.
-     * Extraneous calls are tolerated silently
-     */
-    public void unregisterForServiceStateChanged(Handler h){
-        mServiceStateChangedRegistrants.remove(h);
-    }
-
-    /**
-     * Register for notifications when a supplementary service attempt fails.
-     * Message.obj will contain an AsyncResult.
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    public void registerForSuppServiceFailed(Handler h, int what, Object obj){
-        mSuppServiceFailedRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregister for notifications when a supplementary service attempt fails.
-     * Extraneous calls are tolerated silently
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForSuppServiceFailed(Handler h){
-        mSuppServiceFailedRegistrants.remove(h);
-    }
-
-    /**
-     * Register for notifications when a sInCall VoicePrivacy is enabled
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){
-        mInCallVoicePrivacyOnRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregister for notifications when a sInCall VoicePrivacy is enabled
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForInCallVoicePrivacyOn(Handler h){
-        mInCallVoicePrivacyOnRegistrants.remove(h);
-    }
-
-    /**
-     * Register for notifications when a sInCall VoicePrivacy is disabled
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){
-        mInCallVoicePrivacyOffRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregister for notifications when a sInCall VoicePrivacy is disabled
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForInCallVoicePrivacyOff(Handler h){
-        mInCallVoicePrivacyOffRegistrants.remove(h);
-    }
-
-    /**
-     * Register for notifications when CDMA call waiting comes
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    public void registerForCallWaiting(Handler h, int what, Object obj){
-        mCallWaitingRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregister for notifications when CDMA Call waiting comes
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForCallWaiting(Handler h){
-        mCallWaitingRegistrants.remove(h);
-    }
-
-
-    /**
-     * Register for signal information notifications from the network.
-     * Message.obj will contain an AsyncResult.
-     * AsyncResult.result will be a SuppServiceNotification instance.
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-
-    public void registerForSignalInfo(Handler h, int what, Object obj){
-        mSignalInfoRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for signal information notifications.
-     * Extraneous calls are tolerated silently
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForSignalInfo(Handler h){
-        mSignalInfoRegistrants.remove(h);
-    }
-
-    /**
-     * Register for display information notifications from the network.
-     * Message.obj will contain an AsyncResult.
-     * AsyncResult.result will be a SuppServiceNotification instance.
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    public void registerForDisplayInfo(Handler h, int what, Object obj){
-        mDisplayInfoRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for display information notifications.
-     * Extraneous calls are tolerated silently
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForDisplayInfo(Handler h) {
-        mDisplayInfoRegistrants.remove(h);
-    }
-
-    /**
-     * Register for notifications when CDMA OTA Provision status change
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj){
-        mCdmaOtaStatusChangeRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregister for notifications when CDMA OTA Provision status change
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForCdmaOtaStatusChange(Handler h){
-        mCdmaOtaStatusChangeRegistrants.remove(h);
-    }
-
-    /**
-     * Registration point for subscription info ready
-     * @param h handler to notify
-     * @param what what code of message when delivered
-     * @param obj placed in Message.obj
-     */
-    public void registerForSubscriptionInfoReady(Handler h, int what, Object obj){
-        mSubscriptionInfoReadyRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregister for notifications for subscription info
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForSubscriptionInfoReady(Handler h){
-        mSubscriptionInfoReadyRegistrants.remove(h);
-    }
-
-    /**
-     * Sets an event to be fired when the telephony system processes
-     * a post-dial character on an outgoing call.<p>
-     *
-     * Messages of type <code>what</code> will be sent to <code>h</code>.
-     * The <code>obj</code> field of these Message's will be instances of
-     * <code>AsyncResult</code>. <code>Message.obj.result</code> will be
-     * a Connection object.<p>
-     *
-     * Message.arg1 will be the post dial character being processed,
-     * or 0 ('\0') if end of string.<p>
-     *
-     * If Connection.getPostDialState() == WAIT,
-     * the application must call
-     * {@link com.android.internal.telephony.Connection#proceedAfterWaitChar()
-     * Connection.proceedAfterWaitChar()} or
-     * {@link com.android.internal.telephony.Connection#cancelPostDial()
-     * Connection.cancelPostDial()}
-     * for the telephony system to continue playing the post-dial
-     * DTMF sequence.<p>
-     *
-     * If Connection.getPostDialState() == WILD,
-     * the application must call
-     * {@link com.android.internal.telephony.Connection#proceedAfterWildChar
-     * Connection.proceedAfterWildChar()}
-     * or
-     * {@link com.android.internal.telephony.Connection#cancelPostDial()
-     * Connection.cancelPostDial()}
-     * for the telephony system to continue playing the
-     * post-dial DTMF sequence.<p>
-     *
-     */
-    public void registerForPostDialCharacter(Handler h, int what, Object obj){
-        mPostDialCharacterRegistrants.addUnique(h, what, obj);
-    }
-
-    public void unregisterForPostDialCharacter(Handler h){
-        mPostDialCharacterRegistrants.remove(h);
-    }
-
-    /* APIs to access foregroudCalls, backgroudCalls, and ringingCalls
-     * 1. APIs to access list of calls
-     * 2. APIs to check if any active call, which has connection other than
-     * disconnected ones, pleaser refer to Call.isIdle()
-     * 3. APIs to return first active call
-     * 4. APIs to return the connections of first active call
-     * 5. APIs to return other property of first active call
-     */
-
-    /**
-     * @return list of all ringing calls
-     */
-    public List<Call> getRingingCalls() {
-        return Collections.unmodifiableList(mRingingCalls);
-    }
-
-    /**
-     * @return list of all foreground calls
-     */
-    public List<Call> getForegroundCalls() {
-        return Collections.unmodifiableList(mForegroundCalls);
-    }
-
-    /**
-     * @return list of all background calls
-     */
-    public List<Call> getBackgroundCalls() {
-        return Collections.unmodifiableList(mBackgroundCalls);
-    }
-
-    /**
-     * Return true if there is at least one active foreground call
-     */
-    public boolean hasActiveFgCall() {
-        return (getFirstActiveCall(mForegroundCalls) != null);
-    }
-
-    /**
-     * Return true if there is at least one active background call
-     */
-    public boolean hasActiveBgCall() {
-        // TODO since hasActiveBgCall may get called often
-        // better to cache it to improve performance
-        return (getFirstActiveCall(mBackgroundCalls) != null);
-    }
-
-    /**
-     * Return true if there is at least one active ringing call
-     *
-     */
-    public boolean hasActiveRingingCall() {
-        return (getFirstActiveCall(mRingingCalls) != null);
-    }
-
-    /**
-     * return the active foreground call from foreground calls
-     *
-     * Active call means the call is NOT in Call.State.IDLE
-     *
-     * 1. If there is active foreground call, return it
-     * 2. If there is no active foreground call, return the
-     *    foreground call associated with default phone, which state is IDLE.
-     * 3. If there is no phone registered at all, return null.
-     *
-     */
-    public Call getActiveFgCall() {
-        Call call = getFirstNonIdleCall(mForegroundCalls);
-        if (call == null) {
-            call = (mDefaultPhone == null)
-                    ? null
-                    : mDefaultPhone.getForegroundCall();
-        }
-        return call;
-    }
-
-    // Returns the first call that is not in IDLE state. If both active calls
-    // and disconnecting/disconnected calls exist, return the first active call.
-    private Call getFirstNonIdleCall(List<Call> calls) {
-        Call result = null;
-        for (Call call : calls) {
-            if (!call.isIdle()) {
-                return call;
-            } else if (call.getState() != Call.State.IDLE) {
-                if (result == null) result = call;
-            }
-        }
-        return result;
-    }
-
-    /**
-     * return one active background call from background calls
-     *
-     * Active call means the call is NOT idle defined by Call.isIdle()
-     *
-     * 1. If there is only one active background call, return it
-     * 2. If there is more than one active background call, return the first one
-     * 3. If there is no active background call, return the background call
-     *    associated with default phone, which state is IDLE.
-     * 4. If there is no background call at all, return null.
-     *
-     * Complete background calls list can be get by getBackgroundCalls()
-     */
-    public Call getFirstActiveBgCall() {
-        Call call = getFirstNonIdleCall(mBackgroundCalls);
-        if (call == null) {
-            call = (mDefaultPhone == null)
-                    ? null
-                    : mDefaultPhone.getBackgroundCall();
-        }
-        return call;
-    }
-
-    /**
-     * return one active ringing call from ringing calls
-     *
-     * Active call means the call is NOT idle defined by Call.isIdle()
-     *
-     * 1. If there is only one active ringing call, return it
-     * 2. If there is more than one active ringing call, return the first one
-     * 3. If there is no active ringing call, return the ringing call
-     *    associated with default phone, which state is IDLE.
-     * 4. If there is no ringing call at all, return null.
-     *
-     * Complete ringing calls list can be get by getRingingCalls()
-     */
-    public Call getFirstActiveRingingCall() {
-        Call call = getFirstNonIdleCall(mRingingCalls);
-        if (call == null) {
-            call = (mDefaultPhone == null)
-                    ? null
-                    : mDefaultPhone.getRingingCall();
-        }
-        return call;
-    }
-
-    /**
-     * @return the state of active foreground call
-     * return IDLE if there is no active foreground call
-     */
-    public Call.State getActiveFgCallState() {
-        Call fgCall = getActiveFgCall();
-
-        if (fgCall != null) {
-            return fgCall.getState();
-        }
-
-        return Call.State.IDLE;
-    }
-
-    /**
-     * @return the connections of active foreground call
-     * return empty list if there is no active foreground call
-     */
-    public List<Connection> getFgCallConnections() {
-        Call fgCall = getActiveFgCall();
-        if ( fgCall != null) {
-            return fgCall.getConnections();
-        }
-        return emptyConnections;
-    }
-
-    /**
-     * @return the connections of active background call
-     * return empty list if there is no active background call
-     */
-    public List<Connection> getBgCallConnections() {
-        Call bgCall = getFirstActiveBgCall();
-        if ( bgCall != null) {
-            return bgCall.getConnections();
-        }
-        return emptyConnections;
-    }
-
-    /**
-     * @return the latest connection of active foreground call
-     * return null if there is no active foreground call
-     */
-    public Connection getFgCallLatestConnection() {
-        Call fgCall = getActiveFgCall();
-        if ( fgCall != null) {
-            return fgCall.getLatestConnection();
-        }
-        return null;
-    }
-
-    /**
-     * @return true if there is at least one Foreground call in disconnected state
-     */
-    public boolean hasDisconnectedFgCall() {
-        return (getFirstCallOfState(mForegroundCalls, Call.State.DISCONNECTED) != null);
-    }
-
-    /**
-     * @return true if there is at least one background call in disconnected state
-     */
-    public boolean hasDisconnectedBgCall() {
-        return (getFirstCallOfState(mBackgroundCalls, Call.State.DISCONNECTED) != null);
-    }
-
-    /**
-     * @return the first active call from a call list
-     */
-    private  Call getFirstActiveCall(ArrayList<Call> calls) {
-        for (Call call : calls) {
-            if (!call.isIdle()) {
-                return call;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * @return the first call in a the Call.state from a call list
-     */
-    private Call getFirstCallOfState(ArrayList<Call> calls, Call.State state) {
-        for (Call call : calls) {
-            if (call.getState() == state) {
-                return call;
-            }
-        }
-        return null;
-    }
-
-
-    private boolean hasMoreThanOneRingingCall() {
-        int count = 0;
-        for (Call call : mRingingCalls) {
-            if (call.getState().isRinging()) {
-                if (++count > 1) return true;
-            }
-        }
-        return false;
-    }
-
-    private Handler mHandler = new Handler() {
-
-        @Override
-        public void handleMessage(Message msg) {
-
-            switch (msg.what) {
-                case EVENT_DISCONNECT:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_DISCONNECT)");
-                    mDisconnectRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_PRECISE_CALL_STATE_CHANGED:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_PRECISE_CALL_STATE_CHANGED)");
-                    mPreciseCallStateRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_NEW_RINGING_CONNECTION:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_NEW_RINGING_CONNECTION)");
-                    if (getActiveFgCallState().isDialing() || hasMoreThanOneRingingCall()) {
-                        Connection c = (Connection) ((AsyncResult) msg.obj).result;
-                        try {
-                            Log.d(LOG_TAG, "silently drop incoming call: " + c.getCall());
-                            c.getCall().hangup();
-                        } catch (CallStateException e) {
-                            Log.w(LOG_TAG, "new ringing connection", e);
-                        }
-                    } else {
-                        mNewRingingConnectionRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    }
-                    break;
-                case EVENT_UNKNOWN_CONNECTION:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_UNKNOWN_CONNECTION)");
-                    mUnknownConnectionRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_INCOMING_RING:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_INCOMING_RING)");
-                    // The event may come from RIL who's not aware of an ongoing fg call
-                    if (!hasActiveFgCall()) {
-                        mIncomingRingRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    }
-                    break;
-                case EVENT_RINGBACK_TONE:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_RINGBACK_TONE)");
-                    mRingbackToneRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_IN_CALL_VOICE_PRIVACY_ON:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_IN_CALL_VOICE_PRIVACY_ON)");
-                    mInCallVoicePrivacyOnRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_IN_CALL_VOICE_PRIVACY_OFF:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_IN_CALL_VOICE_PRIVACY_OFF)");
-                    mInCallVoicePrivacyOffRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_CALL_WAITING:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_CALL_WAITING)");
-                    mCallWaitingRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_DISPLAY_INFO:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_DISPLAY_INFO)");
-                    mDisplayInfoRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_SIGNAL_INFO:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SIGNAL_INFO)");
-                    mSignalInfoRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_CDMA_OTA_STATUS_CHANGE:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_CDMA_OTA_STATUS_CHANGE)");
-                    mCdmaOtaStatusChangeRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_RESEND_INCALL_MUTE:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_RESEND_INCALL_MUTE)");
-                    mResendIncallMuteRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_MMI_INITIATE:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_MMI_INITIATE)");
-                    mMmiInitiateRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_MMI_COMPLETE:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_MMI_COMPLETE)");
-                    mMmiCompleteRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_ECM_TIMER_RESET:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_ECM_TIMER_RESET)");
-                    mEcmTimerResetRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_SUBSCRIPTION_INFO_READY:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SUBSCRIPTION_INFO_READY)");
-                    mSubscriptionInfoReadyRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_SUPP_SERVICE_FAILED:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SUPP_SERVICE_FAILED)");
-                    mSuppServiceFailedRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_SERVICE_STATE_CHANGED:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SERVICE_STATE_CHANGED)");
-                    mServiceStateChangedRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_POST_DIAL_CHARACTER:
-                    // we need send the character that is being processed in msg.arg1
-                    // so can't use notifyRegistrants()
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_POST_DIAL_CHARACTER)");
-                    for(int i=0; i < mPostDialCharacterRegistrants.size(); i++) {
-                        Message notifyMsg;
-                        notifyMsg = ((Registrant)mPostDialCharacterRegistrants.get(i)).messageForRegistrant();
-                        notifyMsg.obj = msg.obj;
-                        notifyMsg.arg1 = msg.arg1;
-                        notifyMsg.sendToTarget();
-                    }
-                    break;
-            }
-        }
-    };
-
-    @Override
-    public String toString() {
-        Call call;
-        StringBuilder b = new StringBuilder();
-
-        b.append("CallManager {");
-        b.append("\nstate = " + getState());
-        call = getActiveFgCall();
-        b.append("\n- Foreground: " + getActiveFgCallState());
-        b.append(" from " + call.getPhone());
-        b.append("\n  Conn: ").append(getFgCallConnections());
-        call = getFirstActiveBgCall();
-        b.append("\n- Background: " + call.getState());
-        b.append(" from " + call.getPhone());
-        b.append("\n  Conn: ").append(getBgCallConnections());
-        call = getFirstActiveRingingCall();
-        b.append("\n- Ringing: " +call.getState());
-        b.append(" from " + call.getPhone());
-
-        for (Phone phone : getAllPhones()) {
-            if (phone != null) {
-                b.append("\nPhone: " + phone + ", name = " + phone.getPhoneName()
-                        + ", state = " + phone.getState());
-                call = phone.getForegroundCall();
-                b.append("\n- Foreground: ").append(call);
-                call = phone.getBackgroundCall();
-                b.append(" Background: ").append(call);
-                call = phone.getRingingCall();
-                b.append(" Ringing: ").append(call);
-            }
-        }
-        b.append("\n}");
-        return b.toString();
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/CallStateException.java b/telephony/java/com/android/internal/telephony/CallStateException.java
deleted file mode 100644
index 6087124..0000000
--- a/telephony/java/com/android/internal/telephony/CallStateException.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-/**
- * {@hide}
- */
-public class CallStateException extends Exception
-{
-    public
-    CallStateException()
-    {
-    }
-
-    public
-    CallStateException(String string)
-    {
-        super(string);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/CallTracker.java b/telephony/java/com/android/internal/telephony/CallTracker.java
deleted file mode 100644
index 62caf01..0000000
--- a/telephony/java/com/android/internal/telephony/CallTracker.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.telephony.CommandException;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-
-/**
- * {@hide}
- */
-public abstract class CallTracker extends Handler {
-
-    private static final boolean DBG_POLL = false;
-
-    //***** Constants
-
-    static final int POLL_DELAY_MSEC = 250;
-
-    protected int pendingOperations;
-    protected boolean needsPoll;
-    protected Message lastRelevantPoll;
-
-    public CommandsInterface cm;
-
-
-    //***** Events
-
-    protected static final int EVENT_POLL_CALLS_RESULT             = 1;
-    protected static final int EVENT_CALL_STATE_CHANGE             = 2;
-    protected static final int EVENT_REPOLL_AFTER_DELAY            = 3;
-    protected static final int EVENT_OPERATION_COMPLETE            = 4;
-    protected static final int EVENT_GET_LAST_CALL_FAIL_CAUSE      = 5;
-
-    protected static final int EVENT_SWITCH_RESULT                 = 8;
-    protected static final int EVENT_RADIO_AVAILABLE               = 9;
-    protected static final int EVENT_RADIO_NOT_AVAILABLE           = 10;
-    protected static final int EVENT_CONFERENCE_RESULT             = 11;
-    protected static final int EVENT_SEPARATE_RESULT               = 12;
-    protected static final int EVENT_ECT_RESULT                    = 13;
-    protected static final int EVENT_EXIT_ECM_RESPONSE_CDMA        = 14;
-    protected static final int EVENT_CALL_WAITING_INFO_CDMA        = 15;
-    protected static final int EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA = 16;
-
-    protected void pollCallsWhenSafe() {
-        needsPoll = true;
-
-        if (checkNoOperationsPending()) {
-            lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
-            cm.getCurrentCalls(lastRelevantPoll);
-        }
-    }
-
-    protected void
-    pollCallsAfterDelay() {
-        Message msg = obtainMessage();
-
-        msg.what = EVENT_REPOLL_AFTER_DELAY;
-        sendMessageDelayed(msg, POLL_DELAY_MSEC);
-    }
-
-    protected boolean
-    isCommandExceptionRadioNotAvailable(Throwable e) {
-        return e != null && e instanceof CommandException
-                && ((CommandException)e).getCommandError()
-                        == CommandException.Error.RADIO_NOT_AVAILABLE;
-    }
-
-    protected abstract void handlePollCalls(AsyncResult ar);
-
-    protected void handleRadioAvailable() {
-        pollCallsWhenSafe();
-    }
-
-    /**
-     * Obtain a complete message that indicates that this operation
-     * does not require polling of getCurrentCalls(). However, if other
-     * operations that do need getCurrentCalls() are pending or are
-     * scheduled while this operation is pending, the invocation
-     * of getCurrentCalls() will be postponed until this
-     * operation is also complete.
-     */
-    protected Message
-    obtainNoPollCompleteMessage(int what) {
-        pendingOperations++;
-        lastRelevantPoll = null;
-        return obtainMessage(what);
-    }
-
-    /**
-     * @return true if we're idle or there's a call to getCurrentCalls() pending
-     * but nothing else
-     */
-    private boolean
-    checkNoOperationsPending() {
-        if (DBG_POLL) log("checkNoOperationsPending: pendingOperations=" +
-                pendingOperations);
-        return pendingOperations == 0;
-    }
-
-    /**
-     * Routine called from dial to check if the number is a test Emergency number
-     * and if so remap the number. This allows a short emergency number to be remapped
-     * to a regular number for testing how the frameworks handles emergency numbers
-     * without actually calling an emergency number.
-     *
-     * This is not a full test and is not a substitute for testing real emergency
-     * numbers but can be useful.
-     *
-     * To use this feature set a system property ril.test.emergencynumber to a pair of
-     * numbers separated by a colon. If the first number matches the number parameter
-     * this routine returns the second number. Example:
-     *
-     * ril.test.emergencynumber=112:1-123-123-45678
-     *
-     * To test Dial 112 take call then hang up on MO device to enter ECM
-     * see RIL#processSolicited RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND
-     *
-     * @param number to test if it should be remapped
-     * @return the same number or the remapped number.
-     */
-    protected String checkForTestEmergencyNumber(String dialString) {
-        String testEn = SystemProperties.get("ril.test.emergencynumber");
-        if (DBG_POLL) {
-            log("checkForTestEmergencyNumber: dialString=" + dialString +
-                " testEn=" + testEn);
-        }
-        if (!TextUtils.isEmpty(testEn)) {
-            String values[] = testEn.split(":");
-            log("checkForTestEmergencyNumber: values.length=" + values.length);
-            if (values.length == 2) {
-                if (values[0].equals(
-                        android.telephony.PhoneNumberUtils.stripSeparators(dialString))) {
-                    cm.testingEmergencyCall();
-                    log("checkForTestEmergencyNumber: remap " +
-                            dialString + " to " + values[1]);
-                    dialString = values[1];
-                }
-            }
-        }
-        return dialString;
-    }
-
-    //***** Overridden from Handler
-    public abstract void handleMessage (Message msg);
-    public abstract void registerForVoiceCallStarted(Handler h, int what, Object obj);
-    public abstract void unregisterForVoiceCallStarted(Handler h);
-    public abstract void registerForVoiceCallEnded(Handler h, int what, Object obj);
-    public abstract void unregisterForVoiceCallEnded(Handler h);
-
-    protected abstract void log(String msg);
-
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("CallTracker:");
-        pw.println(" pendingOperations=" + pendingOperations);
-        pw.println(" needsPoll=" + needsPoll);
-        pw.println(" lastRelevantPoll=" + lastRelevantPoll);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/CommandException.java b/telephony/java/com/android/internal/telephony/CommandException.java
deleted file mode 100644
index 94c544e..0000000
--- a/telephony/java/com/android/internal/telephony/CommandException.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import com.android.internal.telephony.RILConstants;
-
-import android.util.Log;
-
-/**
- * {@hide}
- */
-public class CommandException extends RuntimeException {
-    private Error e;
-
-    public enum Error {
-        INVALID_RESPONSE,
-        RADIO_NOT_AVAILABLE,
-        GENERIC_FAILURE,
-        PASSWORD_INCORRECT,
-        SIM_PIN2,
-        SIM_PUK2,
-        REQUEST_NOT_SUPPORTED,
-        OP_NOT_ALLOWED_DURING_VOICE_CALL,
-        OP_NOT_ALLOWED_BEFORE_REG_NW,
-        SMS_FAIL_RETRY,
-        SIM_ABSENT,
-        SUBSCRIPTION_NOT_AVAILABLE,
-        MODE_NOT_SUPPORTED,
-        FDN_CHECK_FAILURE,
-        ILLEGAL_SIM_OR_ME,
-    }
-
-    public CommandException(Error e) {
-        super(e.toString());
-        this.e = e;
-    }
-
-    public static CommandException
-    fromRilErrno(int ril_errno) {
-        switch(ril_errno) {
-            case RILConstants.SUCCESS:                       return null;
-            case RILConstants.RIL_ERRNO_INVALID_RESPONSE:
-                return new CommandException(Error.INVALID_RESPONSE);
-            case RILConstants.RADIO_NOT_AVAILABLE:
-                return new CommandException(Error.RADIO_NOT_AVAILABLE);
-            case RILConstants.GENERIC_FAILURE:
-                return new CommandException(Error.GENERIC_FAILURE);
-            case RILConstants.PASSWORD_INCORRECT:
-                return new CommandException(Error.PASSWORD_INCORRECT);
-            case RILConstants.SIM_PIN2:
-                return new CommandException(Error.SIM_PIN2);
-            case RILConstants.SIM_PUK2:
-                return new CommandException(Error.SIM_PUK2);
-            case RILConstants.REQUEST_NOT_SUPPORTED:
-                return new CommandException(Error.REQUEST_NOT_SUPPORTED);
-            case RILConstants.OP_NOT_ALLOWED_DURING_VOICE_CALL:
-                return new CommandException(Error.OP_NOT_ALLOWED_DURING_VOICE_CALL);
-            case RILConstants.OP_NOT_ALLOWED_BEFORE_REG_NW:
-                return new CommandException(Error.OP_NOT_ALLOWED_BEFORE_REG_NW);
-            case RILConstants.SMS_SEND_FAIL_RETRY:
-                return new CommandException(Error.SMS_FAIL_RETRY);
-            case RILConstants.SIM_ABSENT:
-                return new CommandException(Error.SIM_ABSENT);
-            case RILConstants.SUBSCRIPTION_NOT_AVAILABLE:
-                return new CommandException(Error.SUBSCRIPTION_NOT_AVAILABLE);
-            case RILConstants.MODE_NOT_SUPPORTED:
-                return new CommandException(Error.MODE_NOT_SUPPORTED);
-            case RILConstants.FDN_CHECK_FAILURE:
-                return new CommandException(Error.FDN_CHECK_FAILURE);
-            case RILConstants.ILLEGAL_SIM_OR_ME:
-                return new CommandException(Error.ILLEGAL_SIM_OR_ME);
-            default:
-                Log.e("GSM", "Unrecognized RIL errno " + ril_errno);
-                return new CommandException(Error.INVALID_RESPONSE);
-        }
-    }
-
-    public Error getCommandError() {
-        return e;
-    }
-
-
-
-}
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
deleted file mode 100644
index f7757b3..0000000
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ /dev/null
@@ -1,1579 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
-
-import android.os.Message;
-import android.os.Handler;
-import android.util.Log;
-
-/**
- * {@hide}
- */
-public interface CommandsInterface {
-    enum RadioState {
-        RADIO_OFF,         /* Radio explicitly powered off (eg CFUN=0) */
-        RADIO_UNAVAILABLE, /* Radio unavailable (eg, resetting or not booted) */
-        RADIO_ON;          /* Radio is on */
-
-        public boolean isOn() /* and available...*/ {
-            return this == RADIO_ON;
-        }
-
-        public boolean isAvailable() {
-            return this != RADIO_UNAVAILABLE;
-        }
-    }
-
-    //***** Constants
-
-    // Used as parameter to dial() and setCLIR() below
-    static final int CLIR_DEFAULT = 0;      // "use subscription default value"
-    static final int CLIR_INVOCATION = 1;   // (restrict CLI presentation)
-    static final int CLIR_SUPPRESSION = 2;  // (allow CLI presentation)
-
-
-    // Used as parameters for call forward methods below
-    static final int CF_ACTION_DISABLE          = 0;
-    static final int CF_ACTION_ENABLE           = 1;
-//  static final int CF_ACTION_UNUSED           = 2;
-    static final int CF_ACTION_REGISTRATION     = 3;
-    static final int CF_ACTION_ERASURE          = 4;
-
-    static final int CF_REASON_UNCONDITIONAL    = 0;
-    static final int CF_REASON_BUSY             = 1;
-    static final int CF_REASON_NO_REPLY         = 2;
-    static final int CF_REASON_NOT_REACHABLE    = 3;
-    static final int CF_REASON_ALL              = 4;
-    static final int CF_REASON_ALL_CONDITIONAL  = 5;
-
-    // Used for call barring methods below
-    static final String CB_FACILITY_BAOC         = "AO";
-    static final String CB_FACILITY_BAOIC        = "OI";
-    static final String CB_FACILITY_BAOICxH      = "OX";
-    static final String CB_FACILITY_BAIC         = "AI";
-    static final String CB_FACILITY_BAICr        = "IR";
-    static final String CB_FACILITY_BA_ALL       = "AB";
-    static final String CB_FACILITY_BA_MO        = "AG";
-    static final String CB_FACILITY_BA_MT        = "AC";
-    static final String CB_FACILITY_BA_SIM       = "SC";
-    static final String CB_FACILITY_BA_FD        = "FD";
-
-
-    // Used for various supp services apis
-    // See 27.007 +CCFC or +CLCK
-    static final int SERVICE_CLASS_NONE     = 0; // no user input
-    static final int SERVICE_CLASS_VOICE    = (1 << 0);
-    static final int SERVICE_CLASS_DATA     = (1 << 1); //synonym for 16+32+64+128
-    static final int SERVICE_CLASS_FAX      = (1 << 2);
-    static final int SERVICE_CLASS_SMS      = (1 << 3);
-    static final int SERVICE_CLASS_DATA_SYNC = (1 << 4);
-    static final int SERVICE_CLASS_DATA_ASYNC = (1 << 5);
-    static final int SERVICE_CLASS_PACKET   = (1 << 6);
-    static final int SERVICE_CLASS_PAD      = (1 << 7);
-    static final int SERVICE_CLASS_MAX      = (1 << 7); // Max SERVICE_CLASS value
-
-    // Numeric representation of string values returned
-    // by messages sent to setOnUSSD handler
-    static final int USSD_MODE_NOTIFY       = 0;
-    static final int USSD_MODE_REQUEST      = 1;
-
-    // GSM SMS fail cause for acknowledgeLastIncomingSMS. From TS 23.040, 9.2.3.22.
-    static final int GSM_SMS_FAIL_CAUSE_MEMORY_CAPACITY_EXCEEDED    = 0xD3;
-    static final int GSM_SMS_FAIL_CAUSE_USIM_APP_TOOLKIT_BUSY       = 0xD4;
-    static final int GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR    = 0xD5;
-    static final int GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR           = 0xFF;
-
-    // CDMA SMS fail cause for acknowledgeLastIncomingCdmaSms.  From TS N.S0005, 6.5.2.125.
-    static final int CDMA_SMS_FAIL_CAUSE_INVALID_TELESERVICE_ID     = 4;
-    static final int CDMA_SMS_FAIL_CAUSE_RESOURCE_SHORTAGE          = 35;
-    static final int CDMA_SMS_FAIL_CAUSE_OTHER_TERMINAL_PROBLEM     = 39;
-    static final int CDMA_SMS_FAIL_CAUSE_ENCODING_PROBLEM           = 96;
-
-    //***** Methods
-    RadioState getRadioState();
-
-    void getVoiceRadioTechnology(Message result);
-
-    /**
-     * Fires on any RadioState transition
-     * Always fires immediately as well
-     *
-     * do not attempt to calculate transitions by storing getRadioState() values
-     * on previous invocations of this notification. Instead, use the other
-     * registration methods
-     */
-    void registerForRadioStateChanged(Handler h, int what, Object obj);
-    void unregisterForRadioStateChanged(Handler h);
-
-    void registerForVoiceRadioTechChanged(Handler h, int what, Object obj);
-    void unregisterForVoiceRadioTechChanged(Handler h);
-
-    /**
-     * Fires on any transition into RadioState.isOn()
-     * Fires immediately if currently in that state
-     * In general, actions should be idempotent. State may change
-     * before event is received.
-     */
-    void registerForOn(Handler h, int what, Object obj);
-    void unregisterForOn(Handler h);
-
-    /**
-     * Fires on any transition out of RadioState.isAvailable()
-     * Fires immediately if currently in that state
-     * In general, actions should be idempotent. State may change
-     * before event is received.
-     */
-    void registerForAvailable(Handler h, int what, Object obj);
-    void unregisterForAvailable(Handler h);
-
-    /**
-     * Fires on any transition into !RadioState.isAvailable()
-     * Fires immediately if currently in that state
-     * In general, actions should be idempotent. State may change
-     * before event is received.
-     */
-    void registerForNotAvailable(Handler h, int what, Object obj);
-    void unregisterForNotAvailable(Handler h);
-
-    /**
-     * Fires on any transition into RADIO_OFF or !RadioState.isAvailable()
-     * Fires immediately if currently in that state
-     * In general, actions should be idempotent. State may change
-     * before event is received.
-     */
-    void registerForOffOrNotAvailable(Handler h, int what, Object obj);
-    void unregisterForOffOrNotAvailable(Handler h);
-
-    /**
-     * Fires on any change in ICC status
-     */
-    void registerForIccStatusChanged(Handler h, int what, Object obj);
-    void unregisterForIccStatusChanged(Handler h);
-
-    void registerForCallStateChanged(Handler h, int what, Object obj);
-    void unregisterForCallStateChanged(Handler h);
-    void registerForVoiceNetworkStateChanged(Handler h, int what, Object obj);
-    void unregisterForVoiceNetworkStateChanged(Handler h);
-    void registerForDataNetworkStateChanged(Handler h, int what, Object obj);
-    void unregisterForDataNetworkStateChanged(Handler h);
-
-    /** InCall voice privacy notifications */
-    void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj);
-    void unregisterForInCallVoicePrivacyOn(Handler h);
-    void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj);
-    void unregisterForInCallVoicePrivacyOff(Handler h);
-
-    /**
-     * unlike the register* methods, there's only one new 3GPP format SMS handler.
-     * if you need to unregister, you should also tell the radio to stop
-     * sending SMS's to you (via AT+CNMI)
-     *
-     * AsyncResult.result is a String containing the SMS PDU
-     */
-    void setOnNewGsmSms(Handler h, int what, Object obj);
-    void unSetOnNewGsmSms(Handler h);
-
-    /**
-     * unlike the register* methods, there's only one new 3GPP2 format SMS handler.
-     * if you need to unregister, you should also tell the radio to stop
-     * sending SMS's to you (via AT+CNMI)
-     *
-     * AsyncResult.result is a String containing the SMS PDU
-     */
-    void setOnNewCdmaSms(Handler h, int what, Object obj);
-    void unSetOnNewCdmaSms(Handler h);
-
-    /**
-     * Set the handler for SMS Cell Broadcast messages.
-     *
-     * AsyncResult.result is a byte array containing the SMS-CB PDU
-     */
-    void setOnNewGsmBroadcastSms(Handler h, int what, Object obj);
-    void unSetOnNewGsmBroadcastSms(Handler h);
-
-    /**
-     * Register for NEW_SMS_ON_SIM unsolicited message
-     *
-     * AsyncResult.result is an int array containing the index of new SMS
-     */
-    void setOnSmsOnSim(Handler h, int what, Object obj);
-    void unSetOnSmsOnSim(Handler h);
-
-    /**
-     * Register for NEW_SMS_STATUS_REPORT unsolicited message
-     *
-     * AsyncResult.result is a String containing the status report PDU
-     */
-    void setOnSmsStatus(Handler h, int what, Object obj);
-    void unSetOnSmsStatus(Handler h);
-
-    /**
-     * unlike the register* methods, there's only one NITZ time handler
-     *
-     * AsyncResult.result is an Object[]
-     * ((Object[])AsyncResult.result)[0] is a String containing the NITZ time string
-     * ((Object[])AsyncResult.result)[1] is a Long containing the milliseconds since boot as
-     *                                   returned by elapsedRealtime() when this NITZ time
-     *                                   was posted.
-     *
-     * Please note that the delivery of this message may be delayed several
-     * seconds on system startup
-     */
-    void setOnNITZTime(Handler h, int what, Object obj);
-    void unSetOnNITZTime(Handler h);
-
-    /**
-     * unlike the register* methods, there's only one USSD notify handler
-     *
-     * Represents the arrival of a USSD "notify" message, which may
-     * or may not have been triggered by a previous USSD send
-     *
-     * AsyncResult.result is a String[]
-     * ((String[])(AsyncResult.result))[0] contains status code
-     *      "0"   USSD-Notify -- text in ((const char **)data)[1]
-     *      "1"   USSD-Request -- text in ((const char **)data)[1]
-     *      "2"   Session terminated by network
-     *      "3"   other local client (eg, SIM Toolkit) has responded
-     *      "4"   Operation not supported
-     *      "5"   Network timeout
-     *
-     * ((String[])(AsyncResult.result))[1] contains the USSD message
-     * The numeric representations of these are in USSD_MODE_*
-     */
-
-    void setOnUSSD(Handler h, int what, Object obj);
-    void unSetOnUSSD(Handler h);
-
-    /**
-     * unlike the register* methods, there's only one signal strength handler
-     * AsyncResult.result is an int[2]
-     * response.obj.result[0] is received signal strength (0-31, 99)
-     * response.obj.result[1] is  bit error rate (0-7, 99)
-     * as defined in TS 27.007 8.5
-     */
-
-    void setOnSignalStrengthUpdate(Handler h, int what, Object obj);
-    void unSetOnSignalStrengthUpdate(Handler h);
-
-    /**
-     * Sets the handler for SIM/RUIM SMS storage full unsolicited message.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void setOnIccSmsFull(Handler h, int what, Object obj);
-    void unSetOnIccSmsFull(Handler h);
-
-    /**
-     * Sets the handler for SIM Refresh notifications.
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForIccRefresh(Handler h, int what, Object obj);
-    void unregisterForIccRefresh(Handler h);
-
-    void setOnIccRefresh(Handler h, int what, Object obj);
-    void unsetOnIccRefresh(Handler h);
-
-    /**
-     * Sets the handler for RING notifications.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void setOnCallRing(Handler h, int what, Object obj);
-    void unSetOnCallRing(Handler h);
-
-    /**
-     * Sets the handler for RESTRICTED_STATE changed notification,
-     * eg, for Domain Specific Access Control
-     * unlike the register* methods, there's only one signal strength handler
-     *
-     * AsyncResult.result is an int[1]
-     * response.obj.result[0] is a bitmask of RIL_RESTRICTED_STATE_* values
-     */
-
-    void setOnRestrictedStateChanged(Handler h, int what, Object obj);
-    void unSetOnRestrictedStateChanged(Handler h);
-
-    /**
-     * Sets the handler for Supplementary Service Notifications.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void setOnSuppServiceNotification(Handler h, int what, Object obj);
-    void unSetOnSuppServiceNotification(Handler h);
-
-    /**
-     * Sets the handler for Session End Notifications for CAT.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void setOnCatSessionEnd(Handler h, int what, Object obj);
-    void unSetOnCatSessionEnd(Handler h);
-
-    /**
-     * Sets the handler for Proactive Commands for CAT.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void setOnCatProactiveCmd(Handler h, int what, Object obj);
-    void unSetOnCatProactiveCmd(Handler h);
-
-    /**
-     * Sets the handler for Event Notifications for CAT.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void setOnCatEvent(Handler h, int what, Object obj);
-    void unSetOnCatEvent(Handler h);
-
-    /**
-     * Sets the handler for Call Set Up Notifications for CAT.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void setOnCatCallSetUp(Handler h, int what, Object obj);
-    void unSetOnCatCallSetUp(Handler h);
-
-    /**
-     * Enables/disbables supplementary service related notifications from
-     * the network.
-     *
-     * @param enable true to enable notifications, false to disable.
-     * @param result Message to be posted when command completes.
-     */
-    void setSuppServiceNotifications(boolean enable, Message result);
-    //void unSetSuppServiceNotifications(Handler h);
-
-    /**
-     * Sets the handler for Event Notifications for CDMA Display Info.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForDisplayInfo(Handler h, int what, Object obj);
-    void unregisterForDisplayInfo(Handler h);
-
-    /**
-     * Sets the handler for Event Notifications for CallWaiting Info.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForCallWaitingInfo(Handler h, int what, Object obj);
-    void unregisterForCallWaitingInfo(Handler h);
-
-    /**
-     * Sets the handler for Event Notifications for Signal Info.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForSignalInfo(Handler h, int what, Object obj);
-    void unregisterForSignalInfo(Handler h);
-
-    /**
-     * Registers the handler for CDMA number information record
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForNumberInfo(Handler h, int what, Object obj);
-    void unregisterForNumberInfo(Handler h);
-
-    /**
-     * Registers the handler for CDMA redirected number Information record
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForRedirectedNumberInfo(Handler h, int what, Object obj);
-    void unregisterForRedirectedNumberInfo(Handler h);
-
-    /**
-     * Registers the handler for CDMA line control information record
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForLineControlInfo(Handler h, int what, Object obj);
-    void unregisterForLineControlInfo(Handler h);
-
-    /**
-     * Registers the handler for CDMA T53 CLIR information record
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerFoT53ClirlInfo(Handler h, int what, Object obj);
-    void unregisterForT53ClirInfo(Handler h);
-
-    /**
-     * Registers the handler for CDMA T53 audio control information record
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForT53AudioControlInfo(Handler h, int what, Object obj);
-    void unregisterForT53AudioControlInfo(Handler h);
-
-    /**
-     * Fires on if Modem enters Emergency Callback mode
-     */
-    void setEmergencyCallbackMode(Handler h, int what, Object obj);
-
-     /**
-      * Fires on any CDMA OTA provision status change
-      */
-     void registerForCdmaOtaProvision(Handler h,int what, Object obj);
-     void unregisterForCdmaOtaProvision(Handler h);
-
-     /**
-      * Registers the handler when out-band ringback tone is needed.<p>
-      *
-      *  Messages received from this:
-      *  Message.obj will be an AsyncResult
-      *  AsyncResult.userObj = obj
-      *  AsyncResult.result = boolean. <p>
-      */
-     void registerForRingbackTone(Handler h, int what, Object obj);
-     void unregisterForRingbackTone(Handler h);
-
-     /**
-      * Registers the handler when mute/unmute need to be resent to get
-      * uplink audio during a call.<p>
-      *
-      * @param h Handler for notification message.
-      * @param what User-defined message code.
-      * @param obj User object.
-      *
-      */
-     void registerForResendIncallMute(Handler h, int what, Object obj);
-     void unregisterForResendIncallMute(Handler h);
-
-     /**
-      * Registers the handler for when Cdma subscription changed events
-      *
-      * @param h Handler for notification message.
-      * @param what User-defined message code.
-      * @param obj User object.
-      *
-      */
-     void registerForCdmaSubscriptionChanged(Handler h, int what, Object obj);
-     void unregisterForCdmaSubscriptionChanged(Handler h);
-
-     /**
-      * Registers the handler for when Cdma prl changed events
-      *
-      * @param h Handler for notification message.
-      * @param what User-defined message code.
-      * @param obj User object.
-      *
-      */
-     void registerForCdmaPrlChanged(Handler h, int what, Object obj);
-     void unregisterForCdmaPrlChanged(Handler h);
-
-     /**
-      * Registers the handler for when Cdma prl changed events
-      *
-      * @param h Handler for notification message.
-      * @param what User-defined message code.
-      * @param obj User object.
-      *
-      */
-     void registerForExitEmergencyCallbackMode(Handler h, int what, Object obj);
-     void unregisterForExitEmergencyCallbackMode(Handler h);
-
-     /**
-      * Registers the handler for RIL_UNSOL_RIL_CONNECT events.
-      *
-      * When ril connects or disconnects a message is sent to the registrant
-      * which contains an AsyncResult, ar, in msg.obj. The ar.result is an
-      * Integer which is the version of the ril or -1 if the ril disconnected.
-      *
-      * @param h Handler for notification message.
-      * @param what User-defined message code.
-      * @param obj User object.
-      */
-     void registerForRilConnected(Handler h, int what, Object obj);
-     void unregisterForRilConnected(Handler h);
-
-    /**
-     * Supply the ICC PIN to the ICC card
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPin(String pin, Message result);
-
-    /**
-     * Supply the PIN for the app with this AID on the ICC card
-     *
-     *  AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPinForApp(String pin, String aid, Message result);
-
-    /**
-     * Supply the ICC PUK and newPin to the ICC card
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPuk(String puk, String newPin, Message result);
-
-    /**
-     * Supply the PUK, new pin for the app with this AID on the ICC card
-     *
-     *  AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPukForApp(String puk, String newPin, String aid, Message result);
-
-    /**
-     * Supply the ICC PIN2 to the ICC card
-     * Only called following operation where ICC_PIN2 was
-     * returned as a a failure from a previous operation
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPin2(String pin2, Message result);
-
-    /**
-     * Supply the PIN2 for the app with this AID on the ICC card
-     * Only called following operation where ICC_PIN2 was
-     * returned as a a failure from a previous operation
-     *
-     *  AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPin2ForApp(String pin2, String aid, Message result);
-
-    /**
-     * Supply the SIM PUK2 to the SIM card
-     * Only called following operation where SIM_PUK2 was
-     * returned as a a failure from a previous operation
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPuk2(String puk2, String newPin2, Message result);
-
-    /**
-     * Supply the PUK2, newPin2 for the app with this AID on the ICC card
-     * Only called following operation where SIM_PUK2 was
-     * returned as a a failure from a previous operation
-     *
-     *  AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message result);
-
-    void changeIccPin(String oldPin, String newPin, Message result);
-    void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message result);
-    void changeIccPin2(String oldPin2, String newPin2, Message result);
-    void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr, Message result);
-
-    void changeBarringPassword(String facility, String oldPwd, String newPwd, Message result);
-
-    void supplyNetworkDepersonalization(String netpin, Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result contains a List of DriverCall
-     *      The ar.result List is sorted by DriverCall.index
-     */
-    void getCurrentCalls (Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result contains a List of DataCallState
-     *  @deprecated Do not use.
-     */
-    @Deprecated
-    void getPDPContextList(Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result contains a List of DataCallState
-     */
-    void getDataCallList(Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     *
-     * CLIR_DEFAULT     == on "use subscription default value"
-     * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation)
-     * CLIR_INVOCATION  == on "CLIR invocation" (restrict CLI presentation)
-     */
-    void dial (String address, int clirMode, Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     *
-     * CLIR_DEFAULT     == on "use subscription default value"
-     * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation)
-     * CLIR_INVOCATION  == on "CLIR invocation" (restrict CLI presentation)
-     */
-    void dial(String address, int clirMode, UUSInfo uusInfo, Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is String containing IMSI on success
-     */
-    void getIMSI(Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is String containing IMSI on success
-     */
-    void getIMSIForApp(String aid, Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is String containing IMEI on success
-     */
-    void getIMEI(Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is String containing IMEISV on success
-     */
-    void getIMEISV(Message result);
-
-    /**
-     * Hang up one individual connection.
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     *
-     *  3GPP 22.030 6.5.5
-     *  "Releases a specific active call X"
-     */
-    void hangupConnection (int gsmIndex, Message result);
-
-    /**
-     * 3GPP 22.030 6.5.5
-     *  "Releases all held calls or sets User Determined User Busy (UDUB)
-     *   for a waiting call."
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void hangupWaitingOrBackground (Message result);
-
-    /**
-     * 3GPP 22.030 6.5.5
-     * "Releases all active calls (if any exist) and accepts
-     *  the other (held or waiting) call."
-     *
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void hangupForegroundResumeBackground (Message result);
-
-    /**
-     * 3GPP 22.030 6.5.5
-     * "Places all active calls (if any exist) on hold and accepts
-     *  the other (held or waiting) call."
-     *
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void switchWaitingOrHoldingAndActive (Message result);
-
-    /**
-     * 3GPP 22.030 6.5.5
-     * "Adds a held call to the conversation"
-     *
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void conference (Message result);
-
-    /**
-     * Set preferred Voice Privacy (VP).
-     *
-     * @param enable true is enhanced and false is normal VP
-     * @param result is a callback message
-     */
-    void setPreferredVoicePrivacy(boolean enable, Message result);
-
-    /**
-     * Get currently set preferred Voice Privacy (VP) mode.
-     *
-     * @param result is a callback message
-     */
-    void getPreferredVoicePrivacy(Message result);
-
-    /**
-     * 3GPP 22.030 6.5.5
-     * "Places all active calls on hold except call X with which
-     *  communication shall be supported."
-     */
-    void separateConnection (int gsmIndex, Message result);
-
-    /**
-     *
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void acceptCall (Message result);
-
-    /**
-     *  also known as UDUB
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void rejectCall (Message result);
-
-    /**
-     * 3GPP 22.030 6.5.5
-     * "Connects the two calls and disconnects the subscriber from both calls"
-     *
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void explicitCallTransfer (Message result);
-
-    /**
-     * cause code returned as int[0] in Message.obj.response
-     * Returns integer cause code defined in TS 24.008
-     * Annex H or closest approximation.
-     * Most significant codes:
-     * - Any defined in 22.001 F.4 (for generating busy/congestion)
-     * - Cause 68: ACM >= ACMMax
-     */
-    void getLastCallFailCause (Message result);
-
-
-    /**
-     * Reason for last PDP context deactivate or failure to activate
-     * cause code returned as int[0] in Message.obj.response
-     * returns an integer cause code defined in TS 24.008
-     * section 6.1.3.1.3 or close approximation
-     * @deprecated Do not use.
-     */
-    @Deprecated
-    void getLastPdpFailCause (Message result);
-
-    /**
-     * The preferred new alternative to getLastPdpFailCause
-     * that is also CDMA-compatible.
-     */
-    void getLastDataCallFailCause (Message result);
-
-    void setMute (boolean enableMute, Message response);
-
-    void getMute (Message response);
-
-    /**
-     * response.obj is an AsyncResult
-     * response.obj.result is an int[2]
-     * response.obj.result[0] is received signal strength (0-31, 99)
-     * response.obj.result[1] is  bit error rate (0-7, 99)
-     * as defined in TS 27.007 8.5
-     */
-    void getSignalStrength (Message response);
-
-
-    /**
-     * response.obj.result is an int[3]
-     * response.obj.result[0] is registration state 0-5 from TS 27.007 7.2
-     * response.obj.result[1] is LAC if registered or -1 if not
-     * response.obj.result[2] is CID if registered or -1 if not
-     * valid LAC and CIDs are 0x0000 - 0xffff
-     *
-     * Please note that registration state 4 ("unknown") is treated
-     * as "out of service" above
-     */
-    void getVoiceRegistrationState (Message response);
-
-    /**
-     * response.obj.result is an int[3]
-     * response.obj.result[0] is registration state 0-5 from TS 27.007 7.2
-     * response.obj.result[1] is LAC if registered or -1 if not
-     * response.obj.result[2] is CID if registered or -1 if not
-     * valid LAC and CIDs are 0x0000 - 0xffff
-     *
-     * Please note that registration state 4 ("unknown") is treated
-     * as "out of service" above
-     */
-    void getDataRegistrationState (Message response);
-
-    /**
-     * response.obj.result is a String[3]
-     * response.obj.result[0] is long alpha or null if unregistered
-     * response.obj.result[1] is short alpha or null if unregistered
-     * response.obj.result[2] is numeric or null if unregistered
-     */
-    void getOperator(Message response);
-
-    /**
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void sendDtmf(char c, Message result);
-
-
-    /**
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void startDtmf(char c, Message result);
-
-    /**
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void stopDtmf(Message result);
-
-    /**
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void sendBurstDtmf(String dtmfString, int on, int off, Message result);
-
-    /**
-     * smscPDU is smsc address in PDU form GSM BCD format prefixed
-     *      by a length byte (as expected by TS 27.005) or NULL for default SMSC
-     * pdu is SMS in PDU format as an ASCII hex string
-     *      less the SMSC address
-     */
-    void sendSMS (String smscPDU, String pdu, Message response);
-
-    /**
-     * @param pdu is CDMA-SMS in internal pseudo-PDU format
-     * @param response sent when operation completes
-     */
-    void sendCdmaSms(byte[] pdu, Message response);
-
-    /**
-     * Deletes the specified SMS record from SIM memory (EF_SMS).
-     *
-     * @param index index of the SMS record to delete
-     * @param response sent when operation completes
-     */
-    void deleteSmsOnSim(int index, Message response);
-
-    /**
-     * Deletes the specified SMS record from RUIM memory (EF_SMS in DF_CDMA).
-     *
-     * @param index index of the SMS record to delete
-     * @param response sent when operation completes
-     */
-    void deleteSmsOnRuim(int index, Message response);
-
-    /**
-     * Writes an SMS message to SIM memory (EF_SMS).
-     *
-     * @param status status of message on SIM.  One of:
-     *                  SmsManger.STATUS_ON_ICC_READ
-     *                  SmsManger.STATUS_ON_ICC_UNREAD
-     *                  SmsManger.STATUS_ON_ICC_SENT
-     *                  SmsManger.STATUS_ON_ICC_UNSENT
-     * @param pdu message PDU, as hex string
-     * @param response sent when operation completes.
-     *                  response.obj will be an AsyncResult, and will indicate
-     *                  any error that may have occurred (eg, out of memory).
-     */
-    void writeSmsToSim(int status, String smsc, String pdu, Message response);
-
-    void writeSmsToRuim(int status, String pdu, Message response);
-
-    void setRadioPower(boolean on, Message response);
-
-    void acknowledgeLastIncomingGsmSms(boolean success, int cause, Message response);
-
-    void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message response);
-
-    /**
-     * Acknowledge successful or failed receipt of last incoming SMS,
-     * including acknowledgement TPDU to send as the RP-User-Data element
-     * of the RP-ACK or RP-ERROR PDU.
-     *
-     * @param success true to send RP-ACK, false to send RP-ERROR
-     * @param ackPdu the acknowledgement TPDU in hexadecimal format
-     * @param response sent when operation completes.
-     */
-    void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu, Message response);
-
-    /**
-     * parameters equivalent to 27.007 AT+CRSM command
-     * response.obj will be an AsyncResult
-     * response.obj.result will be an IccIoResult on success
-     */
-    void iccIO (int command, int fileid, String path, int p1, int p2, int p3,
-            String data, String pin2, Message response);
-
-    /**
-     * parameters equivalent to 27.007 AT+CRSM command
-     * response.obj will be an AsyncResult
-     * response.obj.userObj will be a IccIoResult on success
-     */
-    void iccIOForApp (int command, int fileid, String path, int p1, int p2, int p3,
-            String data, String pin2, String aid, Message response);
-
-    /**
-     * (AsyncResult)response.obj).result is an int[] with element [0] set to
-     * 1 for "CLIP is provisioned", and 0 for "CLIP is not provisioned".
-     *
-     * @param response is callback message
-     */
-
-    void queryCLIP(Message response);
-
-    /**
-     * response.obj will be a an int[2]
-     *
-     * response.obj[0] will be TS 27.007 +CLIR parameter 'n'
-     *  0 presentation indicator is used according to the subscription of the CLIR service
-     *  1 CLIR invocation
-     *  2 CLIR suppression
-     *
-     * response.obj[1] will be TS 27.007 +CLIR parameter 'm'
-     *  0 CLIR not provisioned
-     *  1 CLIR provisioned in permanent mode
-     *  2 unknown (e.g. no network, etc.)
-     *  3 CLIR temporary mode presentation restricted
-     *  4 CLIR temporary mode presentation allowed
-     */
-
-    void getCLIR(Message response);
-
-    /**
-     * clirMode is one of the CLIR_* constants above
-     *
-     * response.obj is null
-     */
-
-    void setCLIR(int clirMode, Message response);
-
-    /**
-     * (AsyncResult)response.obj).result is an int[] with element [0] set to
-     * 0 for disabled, 1 for enabled.
-     *
-     * @param serviceClass is a sum of SERVICE_CLASS_*
-     * @param response is callback message
-     */
-
-    void queryCallWaiting(int serviceClass, Message response);
-
-    /**
-     * @param enable is true to enable, false to disable
-     * @param serviceClass is a sum of SERVICE_CLASS_*
-     * @param response is callback message
-     */
-
-    void setCallWaiting(boolean enable, int serviceClass, Message response);
-
-    /**
-     * @param action is one of CF_ACTION_*
-     * @param cfReason is one of CF_REASON_*
-     * @param serviceClass is a sum of SERVICE_CLASSS_*
-     */
-    void setCallForward(int action, int cfReason, int serviceClass,
-                String number, int timeSeconds, Message response);
-
-    /**
-     * cfReason is one of CF_REASON_*
-     *
-     * ((AsyncResult)response.obj).result will be an array of
-     * CallForwardInfo's
-     *
-     * An array of length 0 means "disabled for all codes"
-     */
-    void queryCallForwardStatus(int cfReason, int serviceClass,
-            String number, Message response);
-
-    void setNetworkSelectionModeAutomatic(Message response);
-
-    void setNetworkSelectionModeManual(String operatorNumeric, Message response);
-
-    /**
-     * Queries whether the current network selection mode is automatic
-     * or manual
-     *
-     * ((AsyncResult)response.obj).result  is an int[] with element [0] being
-     * a 0 for automatic selection and a 1 for manual selection
-     */
-
-    void getNetworkSelectionMode(Message response);
-
-    /**
-     * Queries the currently available networks
-     *
-     * ((AsyncResult)response.obj).result  is a List of NetworkInfo objects
-     */
-    void getAvailableNetworks(Message response);
-
-    void getBasebandVersion (Message response);
-
-
-    /**
-     * (AsyncResult)response.obj).result will be an Integer representing
-     * the sum of enabled service classes (sum of SERVICE_CLASS_*)
-     *
-     * @param facility one of CB_FACILTY_*
-     * @param password password or "" if not required
-     * @param serviceClass is a sum of SERVICE_CLASS_*
-     * @param response is callback message
-     */
-
-    void queryFacilityLock (String facility, String password, int serviceClass,
-        Message response);
-
-    /**
-     * (AsyncResult)response.obj).result will be an Integer representing
-     * the sum of enabled service classes (sum of SERVICE_CLASS_*) for the
-     * application with appId.
-     *
-     * @param facility one of CB_FACILTY_*
-     * @param password password or "" if not required
-     * @param serviceClass is a sum of SERVICE_CLASS_*
-     * @param appId is application Id or null if none
-     * @param response is callback message
-     */
-
-    void queryFacilityLockForApp(String facility, String password, int serviceClass, String appId,
-        Message response);
-
-    /**
-     * @param facility one of CB_FACILTY_*
-     * @param lockState true means lock, false means unlock
-     * @param password password or "" if not required
-     * @param serviceClass is a sum of SERVICE_CLASS_*
-     * @param response is callback message
-     */
-    void setFacilityLock (String facility, boolean lockState, String password,
-        int serviceClass, Message response);
-
-    /**
-     * Set the facility lock for the app with this AID on the ICC card.
-     *
-     * @param facility one of CB_FACILTY_*
-     * @param lockState true means lock, false means unlock
-     * @param password password or "" if not required
-     * @param serviceClass is a sum of SERVICE_CLASS_*
-     * @param appId is application Id or null if none
-     * @param response is callback message
-     */
-    void setFacilityLockForApp(String facility, boolean lockState, String password,
-        int serviceClass, String appId, Message response);
-
-    void sendUSSD (String ussdString, Message response);
-
-    /**
-     * Cancels a pending USSD session if one exists.
-     * @param response callback message
-     */
-    void cancelPendingUssd (Message response);
-
-    void resetRadio(Message result);
-
-    /**
-     * Assign a specified band for RF configuration.
-     *
-     * @param bandMode one of BM_*_BAND
-     * @param response is callback message
-     */
-    void setBandMode (int bandMode, Message response);
-
-    /**
-     * Query the list of band mode supported by RF.
-     *
-     * @param response is callback message
-     *        ((AsyncResult)response.obj).result  is an int[] with every
-     *        element representing one avialable BM_*_BAND
-     */
-    void queryAvailableBandMode (Message response);
-
-    /**
-     * Set the current preferred network type. This will be the last
-     * networkType that was passed to setPreferredNetworkType.
-     */
-    void setCurrentPreferredNetworkType();
-
-    /**
-     *  Requests to set the preferred network type for searching and registering
-     * (CS/PS domain, RAT, and operation mode)
-     * @param networkType one of  NT_*_TYPE
-     * @param response is callback message
-     */
-    void setPreferredNetworkType(int networkType , Message response);
-
-     /**
-     *  Query the preferred network type setting
-     *
-     * @param response is callback message to report one of  NT_*_TYPE
-     */
-    void getPreferredNetworkType(Message response);
-
-    /**
-     * Query neighboring cell ids
-     *
-     * @param response s callback message to cell ids
-     */
-    void getNeighboringCids(Message response);
-
-    /**
-     * Request to enable/disable network state change notifications when
-     * location information (lac and/or cid) has changed.
-     *
-     * @param enable true to enable, false to disable
-     * @param response callback message
-     */
-    void setLocationUpdates(boolean enable, Message response);
-
-    /**
-     * Gets the default SMSC address.
-     *
-     * @param result Callback message contains the SMSC address.
-     */
-    void getSmscAddress(Message result);
-
-    /**
-     * Sets the default SMSC address.
-     *
-     * @param address new SMSC address
-     * @param result Callback message is empty on completion
-     */
-    void setSmscAddress(String address, Message result);
-
-    /**
-     * Indicates whether there is storage available for new SMS messages.
-     * @param available true if storage is available
-     * @param result callback message
-     */
-    void reportSmsMemoryStatus(boolean available, Message result);
-
-    /**
-     * Indicates to the vendor ril that StkService is running
-     * and is ready to receive RIL_UNSOL_STK_XXXX commands.
-     *
-     * @param result callback message
-     */
-    void reportStkServiceIsRunning(Message result);
-
-    void invokeOemRilRequestRaw(byte[] data, Message response);
-
-    void invokeOemRilRequestStrings(String[] strings, Message response);
-
-
-    /**
-     * Send TERMINAL RESPONSE to the SIM, after processing a proactive command
-     * sent by the SIM.
-     *
-     * @param contents  String containing SAT/USAT response in hexadecimal
-     *                  format starting with first byte of response data. See
-     *                  TS 102 223 for details.
-     * @param response  Callback message
-     */
-    public void sendTerminalResponse(String contents, Message response);
-
-    /**
-     * Send ENVELOPE to the SIM, after processing a proactive command sent by
-     * the SIM.
-     *
-     * @param contents  String containing SAT/USAT response in hexadecimal
-     *                  format starting with command tag. See TS 102 223 for
-     *                  details.
-     * @param response  Callback message
-     */
-    public void sendEnvelope(String contents, Message response);
-
-    /**
-     * Send ENVELOPE to the SIM, such as an SMS-PP data download envelope
-     * for a SIM data download message. This method has one difference
-     * from {@link #sendEnvelope}: The SW1 and SW2 status bytes from the UICC response
-     * are returned along with the response data.
-     *
-     * response.obj will be an AsyncResult
-     * response.obj.result will be an IccIoResult on success
-     *
-     * @param contents  String containing SAT/USAT response in hexadecimal
-     *                  format starting with command tag. See TS 102 223 for
-     *                  details.
-     * @param response  Callback message
-     */
-    public void sendEnvelopeWithStatus(String contents, Message response);
-
-    /**
-     * Accept or reject the call setup request from SIM.
-     *
-     * @param accept   true if the call is to be accepted, false otherwise.
-     * @param response Callback message
-     */
-    public void handleCallSetupRequestFromSim(boolean accept, Message response);
-
-    /**
-     * Activate or deactivate cell broadcast SMS for GSM.
-     *
-     * @param activate
-     *            true = activate, false = deactivate
-     * @param result Callback message is empty on completion
-     */
-    public void setGsmBroadcastActivation(boolean activate, Message result);
-
-    /**
-     * Configure cell broadcast SMS for GSM.
-     *
-     * @param response Callback message is empty on completion
-     */
-    public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response);
-
-    /**
-     * Query the current configuration of cell broadcast SMS of GSM.
-     *
-     * @param response
-     *        Callback message contains the configuration from the modem
-     *        on completion
-     */
-    public void getGsmBroadcastConfig(Message response);
-
-    //***** new Methods for CDMA support
-
-    /**
-     * Request the device ESN / MEID / IMEI / IMEISV.
-     * "response" is const char **
-     *   [0] is IMEI if GSM subscription is available
-     *   [1] is IMEISV if GSM subscription is available
-     *   [2] is ESN if CDMA subscription is available
-     *   [3] is MEID if CDMA subscription is available
-     */
-    public void getDeviceIdentity(Message response);
-
-    /**
-     * Request the device MDN / H_SID / H_NID / MIN.
-     * "response" is const char **
-     *   [0] is MDN if CDMA subscription is available
-     *   [1] is a comma separated list of H_SID (Home SID) in decimal format
-     *       if CDMA subscription is available
-     *   [2] is a comma separated list of H_NID (Home NID) in decimal format
-     *       if CDMA subscription is available
-     *   [3] is MIN (10 digits, MIN2+MIN1) if CDMA subscription is available
-     */
-    public void getCDMASubscription(Message response);
-
-    /**
-     * Send Flash Code.
-     * "response" is is NULL
-     *   [0] is a FLASH string
-     */
-    public void sendCDMAFeatureCode(String FeatureCode, Message response);
-
-    /** Set the Phone type created */
-    void setPhoneType(int phoneType);
-
-    /**
-     *  Query the CDMA roaming preference setting
-     *
-     * @param response is callback message to report one of  CDMA_RM_*
-     */
-    void queryCdmaRoamingPreference(Message response);
-
-    /**
-     *  Requests to set the CDMA roaming preference
-     * @param cdmaRoamingType one of  CDMA_RM_*
-     * @param response is callback message
-     */
-    void setCdmaRoamingPreference(int cdmaRoamingType, Message response);
-
-    /**
-     *  Requests to set the CDMA subscription mode
-     * @param cdmaSubscriptionType one of  CDMA_SUBSCRIPTION_*
-     * @param response is callback message
-     */
-    void setCdmaSubscriptionSource(int cdmaSubscriptionType, Message response);
-
-    /**
-     *  Requests to get the CDMA subscription srouce
-     * @param response is callback message
-     */
-    void getCdmaSubscriptionSource(Message response);
-
-    /**
-     *  Set the TTY mode
-     *
-     * @param ttyMode one of the following:
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
-     * @param response is callback message
-     */
-    void setTTYMode(int ttyMode, Message response);
-
-    /**
-     *  Query the TTY mode
-     * (AsyncResult)response.obj).result is an int[] with element [0] set to
-     * tty mode:
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
-     * @param response is callback message
-     */
-    void queryTTYMode(Message response);
-
-    /**
-     * Setup a packet data connection On successful completion, the result
-     * message will return a {@link DataCallState} object containing the connection
-     * information.
-     *
-     * @param radioTechnology
-     *            indicates whether to setup connection on radio technology CDMA
-     *            (0) or GSM/UMTS (1)
-     * @param profile
-     *            Profile Number or NULL to indicate default profile
-     * @param apn
-     *            the APN to connect to if radio technology is GSM/UMTS.
-     *            Otherwise null for CDMA.
-     * @param user
-     *            the username for APN, or NULL
-     * @param password
-     *            the password for APN, or NULL
-     * @param authType
-     *            the PAP / CHAP auth type. Values is one of SETUP_DATA_AUTH_*
-     * @param protocol
-     *            one of the PDP_type values in TS 27.007 section 10.1.1.
-     *            For example, "IP", "IPV6", "IPV4V6", or "PPP".
-     * @param result
-     *            Callback message
-     */
-    public void setupDataCall(String radioTechnology, String profile,
-            String apn, String user, String password, String authType,
-            String protocol, Message result);
-
-    /**
-     * Deactivate packet data connection
-     *
-     * @param cid
-     *            The connection ID
-     * @param reason
-     *            Data disconnect reason.
-     * @param result
-     *            Callback message is empty on completion
-     */
-    public void deactivateDataCall(int cid, int reason, Message result);
-
-    /**
-     * Activate or deactivate cell broadcast SMS for CDMA.
-     *
-     * @param activate
-     *            true = activate, false = deactivate
-     * @param result
-     *            Callback message is empty on completion
-     */
-    public void setCdmaBroadcastActivation(boolean activate, Message result);
-
-    /**
-     * Configure cdma cell broadcast SMS.
-     *
-     * @param result
-     *            Callback message is empty on completion
-     */
-    // TODO: Change the configValuesArray to a RIL_BroadcastSMSConfig
-    public void setCdmaBroadcastConfig(int[] configValuesArray, Message result);
-
-    /**
-     * Query the current configuration of cdma cell broadcast SMS.
-     *
-     * @param result
-     *            Callback message contains the configuration from the modem on completion
-     */
-    public void getCdmaBroadcastConfig(Message result);
-
-    /**
-     *  Requests the radio's system selection module to exit emergency callback mode.
-     *  This function should only be called from CDMAPHone.java.
-     *
-     * @param response callback message
-     */
-    public void exitEmergencyCallbackMode(Message response);
-
-    /**
-     * Request the status of the ICC and UICC cards.
-     *
-     * @param result
-     *          Callback message containing {@link IccCardStatus} structure for the card.
-     */
-    public void getIccCardStatus(Message result);
-
-    /**
-     * Return if the current radio is LTE on CDMA. This
-     * is a tri-state return value as for a period of time
-     * the mode may be unknown.
-     *
-     * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
-     * or {@link Phone#LTE_ON_CDMA_TRUE}
-     */
-    public int getLteOnCdmaMode();
-
-    /**
-     * Request the ISIM application on the UICC to perform the AKA
-     * challenge/response algorithm for IMS authentication. The nonce string
-     * and challenge response are Base64 encoded Strings.
-     *
-     * @param nonce the nonce string to pass with the ISIM authentication request
-     * @param response a callback message with the String response in the obj field
-     */
-    public void requestIsimAuthentication(String nonce, Message response);
-
-    /**
-     * Notifiy that we are testing an emergency call
-     */
-    public void testingEmergencyCall();
-}
diff --git a/telephony/java/com/android/internal/telephony/Connection.java b/telephony/java/com/android/internal/telephony/Connection.java
deleted file mode 100644
index 021602f..0000000
--- a/telephony/java/com/android/internal/telephony/Connection.java
+++ /dev/null
@@ -1,314 +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
-
-    //Caller Name Display
-    protected String cnapName;
-    protected int cnapNamePresentation  = PRESENTATION_ALLOWED;
-
-    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 CNAP name associated with connection.
-     * @return cnap name or null if unavailable
-     */
-    public String getCnapName() {
-        return cnapName;
-    }
-
-    /**
-     * Get original dial string.
-     * @return original dial string or null if unavailable
-     */
-    public String getOrigDialString(){
-        return null;
-    }
-
-    /**
-     * Gets CNAP presentation associated with connection.
-     * @return cnap name or null if unavailable
-     */
-
-    public int getCnapNamePresentation() {
-       return cnapNamePresentation;
-    };
-
-    /**
-     * @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 d8aba92..0000000
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ /dev/null
@@ -1,1285 +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.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;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * {@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 AtomicInteger mCount = new AtomicInteger(0);
-    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);
-        setLogRecSize(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");
-    }
-
-    /**
-     * Shut down this instance and its state machine.
-     */
-    private void shutDown() {
-        if (DBG) log("shutDown");
-
-        if (mAc != null) {
-            mAc.disconnected();
-            mAc = null;
-        }
-        mApnList = null;
-        mReconnectIntent = null;
-        mDataConnectionTracker = null;
-        mApn = null;
-        phone = null;
-        mLinkProperties = null;
-        mCapabilities = null;
-        lastFailCause = null;
-        userData = null;
-    }
-
-    /**
-     * 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());
-            shutDown();
-        }
-        @Override
-        public boolean processMessage(Message msg) {
-            boolean retVal = HANDLED;
-            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_DISCONNECTED: {
-                    if (VDBG) log("CMD_CHANNEL_DISCONNECTED");
-                    quit();
-                    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 retVal;
-        }
-    }
-    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 getWhatToString(int what) {
-        String info = null;
-        info = cmdToString(what);
-        if (info == null) {
-            info = DataConnectionAc.cmdToString(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..79872f3
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -0,0 +1,115 @@
+/*
+ * 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;
+
+    /***** 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..20439bc
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/IccCardConstants.java
@@ -0,0 +1,73 @@
+/*
+ * 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";
+    /* 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";
+
+    /*
+      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));
+        }
+    }
+}
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/IccException.java b/telephony/java/com/android/internal/telephony/IccException.java
deleted file mode 100644
index 1659a4e..0000000
--- a/telephony/java/com/android/internal/telephony/IccException.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 IccException extends Exception {
-    public IccException() {
-
-    }
-
-    public IccException(String s) {
-        super(s);
-    }
-}
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 41125dd..0000000
--- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java
+++ /dev/null
@@ -1,1251 +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
-
-    /** Confirmation required for third-party apps sending to an SMS short code. */
-    private static final int EVENT_CONFIRM_SEND_TO_POSSIBLE_PREMIUM_SHORT_CODE = 8;
-
-    /** Confirmation required for third-party apps sending to an SMS short code. */
-    private static final int EVENT_CONFIRM_SEND_TO_PREMIUM_SHORT_CODE = 9;
-
-    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_CONFIRM_SEND_TO_POSSIBLE_PREMIUM_SHORT_CODE:
-            handleConfirmShortCode(false, (SmsTracker)(msg.obj));
-            break;
-
-        case EVENT_CONFIRM_SEND_TO_PREMIUM_SHORT_CODE:
-            handleConfirmShortCode(true, (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);
-    }
-
-    /**
-     * 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));
-
-        // checkDestination() returns true if the destination is not a premium short code or the
-        // sending app is approved to send to short codes. Otherwise, a message is sent to our
-        // handler with the SmsTracker to request user confirmation before sending.
-        if (checkDestination(tracker)) {
-            // 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);
-            }
-        }
-    }
-
-    /**
-     * Check if destination is a potential premium short code and sender is not pre-approved to
-     * send to short codes.
-     *
-     * @param tracker the tracker for the SMS to send
-     * @return true if the destination is approved; false if user confirmation event was sent
-     */
-    boolean checkDestination(SmsTracker tracker) {
-        if (mContext.checkCallingOrSelfPermission(SEND_SMS_NO_CONFIRMATION_PERMISSION)
-                == PackageManager.PERMISSION_GRANTED) {
-            return true;            // app is pre-approved to send to short codes
-        } else {
-            String countryIso = mTelephonyManager.getSimCountryIso();
-            if (countryIso == null || countryIso.length() != 2) {
-                Log.e(TAG, "Can't get SIM country code: trying network country code");
-                countryIso = mTelephonyManager.getNetworkCountryIso();
-            }
-
-            switch (mUsageMonitor.checkDestination(tracker.mDestAddress, countryIso)) {
-                case SmsUsageMonitor.CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE:
-                    sendMessage(obtainMessage(EVENT_CONFIRM_SEND_TO_POSSIBLE_PREMIUM_SHORT_CODE,
-                            tracker));
-                    return false;   // wait for user confirmation before sending
-
-                case SmsUsageMonitor.CATEGORY_PREMIUM_SHORT_CODE:
-                    sendMessage(obtainMessage(EVENT_CONFIRM_SEND_TO_PREMIUM_SHORT_CODE,
-                            tracker));
-                    return false;   // wait for user confirmation before sending
-
-                case SmsUsageMonitor.CATEGORY_NOT_SHORT_CODE:
-                case SmsUsageMonitor.CATEGORY_FREE_SHORT_CODE:
-                case SmsUsageMonitor.CATEGORY_STANDARD_SHORT_CODE:
-                default:
-                    return true;    // destination is not a premium short code
-            }
-        }
-    }
-
-    /**
-     * 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();
-    }
-
-    /**
-     * Post an alert for user confirmation when sending to a potential short code.
-     * @param isPremium true if the destination is known to be a premium short code
-     * @param tracker the SmsTracker for the current message.
-     */
-    protected void handleConfirmShortCode(boolean isPremium, SmsTracker tracker) {
-        if (denyIfQueueLimitReached(tracker)) {
-            return;     // queue limit reached; error was returned to caller
-        }
-
-        int messageId;
-        int titleId;
-        if (isPremium) {
-            messageId = R.string.sms_premium_short_code_confirm_message;
-            titleId = R.string.sms_premium_short_code_confirm_title;
-        } else {
-            messageId = R.string.sms_short_code_confirm_message;
-            titleId = R.string.sms_short_code_confirm_title;
-        }
-
-        CharSequence appLabel = getAppLabel(tracker.mAppPackage);
-        Resources r = Resources.getSystem();
-        Spanned messageText = Html.fromHtml(r.getString(messageId, appLabel, tracker.mDestAddress));
-
-        ConfirmDialogListener listener = new ConfirmDialogListener(tracker);
-
-        AlertDialog d = new AlertDialog.Builder(mContext)
-                .setTitle(titleId)
-                .setIcon(R.drawable.stat_sys_warning)
-                .setMessage(messageText)
-                .setPositiveButton(r.getString(R.string.sms_short_code_confirm_allow), listener)
-                .setNegativeButton(r.getString(R.string.sms_short_code_confirm_deny), listener)
-// TODO: add third button for "Report malicious app" feature
-//                .setNeutralButton(r.getString(R.string.sms_short_code_confirm_report), 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 1804d97..0000000
--- a/telephony/java/com/android/internal/telephony/SmsUsageMonitor.java
+++ /dev/null
@@ -1,476 +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;
-
-    /** Return value from {@link #checkDestination} for regular phone numbers. */
-    static final int CATEGORY_NOT_SHORT_CODE = 0;
-
-    /** Return value from {@link #checkDestination} for free (no cost) short codes. */
-    static final int CATEGORY_FREE_SHORT_CODE = 1;
-
-    /** Return value from {@link #checkDestination} for standard rate (non-premium) short codes. */
-    static final int CATEGORY_STANDARD_SHORT_CODE = 2;
-
-    /** Return value from {@link #checkDestination} for possible premium short codes. */
-    static final int CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3;
-
-    /** Return value from {@link #checkDestination} for premium short codes. */
-    static final int CATEGORY_PREMIUM_SHORT_CODE = 4;
-
-    private final int mCheckPeriod;
-    private final int mMaxAllowed;
-
-    private final HashMap<String, ArrayList<Long>> mSmsStamp =
-            new HashMap<String, ArrayList<Long>>();
-
-    /** Context for retrieving regexes from XML resource. */
-    private final Context mContext;
-
-    /** Country code for the cached short code pattern matcher. */
-    private String mCurrentCountry;
-
-    /** Cached short code pattern matcher for {@link #mCurrentCountry}. */
-    private ShortCodePatternMatcher mCurrentPatternMatcher;
-
-    /** Cached short code regex patterns from secure settings for {@link #mCurrentCountry}. */
-    private String mSettingsShortCodePatterns;
-
-    /** Handler for responding to content observer updates. */
-    private final SettingsObserverHandler mSettingsObserverHandler;
-
-    /** XML tag for root element. */
-    private static final String TAG_SHORTCODES = "shortcodes";
-
-    /** XML tag for short code patterns for a specific country. */
-    private static final String TAG_SHORTCODE = "shortcode";
-
-    /** XML attribute for the country code. */
-    private static final String ATTR_COUNTRY = "country";
-
-    /** XML attribute for the short code regex pattern. */
-    private static final String ATTR_PATTERN = "pattern";
-
-    /** XML attribute for the premium short code regex pattern. */
-    private static final String ATTR_PREMIUM = "premium";
-
-    /** XML attribute for the free short code regex pattern. */
-    private static final String ATTR_FREE = "free";
-
-    /** XML attribute for the standard rate short code regex pattern. */
-    private static final String ATTR_STANDARD = "standard";
-
-    /**
-     * SMS short code regex pattern matcher for a specific country.
-     */
-    private static final class ShortCodePatternMatcher {
-        private final Pattern mShortCodePattern;
-        private final Pattern mPremiumShortCodePattern;
-        private final Pattern mFreeShortCodePattern;
-        private final Pattern mStandardShortCodePattern;
-
-        ShortCodePatternMatcher(String shortCodeRegex, String premiumShortCodeRegex,
-                String freeShortCodeRegex, String standardShortCodeRegex) {
-            mShortCodePattern = (shortCodeRegex != null ? Pattern.compile(shortCodeRegex) : null);
-            mPremiumShortCodePattern = (premiumShortCodeRegex != null ?
-                    Pattern.compile(premiumShortCodeRegex) : null);
-            mFreeShortCodePattern = (freeShortCodeRegex != null ?
-                    Pattern.compile(freeShortCodeRegex) : null);
-            mStandardShortCodePattern = (standardShortCodeRegex != null ?
-                    Pattern.compile(standardShortCodeRegex) : null);
-        }
-
-        int getNumberCategory(String phoneNumber) {
-            if (mFreeShortCodePattern != null && mFreeShortCodePattern.matcher(phoneNumber)
-                    .matches()) {
-                return CATEGORY_FREE_SHORT_CODE;
-            }
-            if (mStandardShortCodePattern != null && mStandardShortCodePattern.matcher(phoneNumber)
-                    .matches()) {
-                return CATEGORY_STANDARD_SHORT_CODE;
-            }
-            if (mPremiumShortCodePattern != null && mPremiumShortCodePattern.matcher(phoneNumber)
-                    .matches()) {
-                return CATEGORY_PREMIUM_SHORT_CODE;
-            }
-            if (mShortCodePattern != null && mShortCodePattern.matcher(phoneNumber).matches()) {
-                return CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE;
-            }
-            return CATEGORY_NOT_SHORT_CODE;
-        }
-    }
-
-    /**
-     * Observe the secure setting for updated regex patterns.
-     */
-    private static class SettingsObserver extends ContentObserver {
-        private final int mWhat;
-        private final Handler mHandler;
-
-        SettingsObserver(Handler handler, int what) {
-            super(handler);
-            mHandler = handler;
-            mWhat = what;
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            mHandler.obtainMessage(mWhat).sendToTarget();
-        }
-    }
-
-    /**
-     * Handler to update regex patterns when secure setting for the current country is updated.
-     */
-    private class SettingsObserverHandler extends Handler {
-        /** Current content observer, or null. */
-        SettingsObserver mSettingsObserver;
-
-        /** Current country code to watch for settings updates. */
-        private String mCountryIso;
-
-        /** Request to start observing a secure setting. */
-        static final int OBSERVE_SETTING = 1;
-
-        /** Handler event for updated secure settings. */
-        static final int SECURE_SETTINGS_CHANGED = 2;
-
-        /** Send a message to this handler requesting to observe the setting for a new country. */
-        void observeSettingForCountry(String countryIso) {
-            obtainMessage(OBSERVE_SETTING, countryIso).sendToTarget();
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case OBSERVE_SETTING:
-                    if (msg.obj != null && msg.obj instanceof String) {
-                        mCountryIso = (String) msg.obj;
-                        String settingName = getSettingNameForCountry(mCountryIso);
-                        ContentResolver resolver = mContext.getContentResolver();
-
-                        if (mSettingsObserver != null) {
-                            if (VDBG) log("Unregistering old content observer");
-                            resolver.unregisterContentObserver(mSettingsObserver);
-                        }
-
-                        mSettingsObserver = new SettingsObserver(this, SECURE_SETTINGS_CHANGED);
-                        resolver.registerContentObserver(
-                                Settings.Secure.getUriFor(settingName), false, mSettingsObserver);
-                        if (VDBG) log("Registered content observer for " + settingName);
-                    }
-                    break;
-
-                case SECURE_SETTINGS_CHANGED:
-                    loadPatternsFromSettings(mCountryIso);
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Create SMS usage monitor.
-     * @param context the context to use to load resources and get TelephonyManager service
-     */
-    public SmsUsageMonitor(Context context) {
-        mContext = 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);
-
-        mSettingsObserverHandler = new SettingsObserverHandler();
-    }
-
-    /**
-     * Return a pattern matcher object for the specified country.
-     * @param country the country to search for
-     * @return a {@link ShortCodePatternMatcher} for the specified country, or null if not found
-     */
-    private ShortCodePatternMatcher getPatternMatcher(String country) {
-        int id = com.android.internal.R.xml.sms_short_codes;
-        XmlResourceParser parser = mContext.getResources().getXml(id);
-
-        try {
-            return getPatternMatcher(country, parser);
-        } catch (XmlPullParserException e) {
-            Log.e(TAG, "XML parser exception reading short code pattern resource", e);
-        } catch (IOException e) {
-            Log.e(TAG, "I/O exception reading short code pattern resource", e);
-        } finally {
-            parser.close();
-        }
-        return null;    // country not found
-    }
-
-    /**
-     * Return a pattern matcher object for the specified country from a secure settings string.
-     * @return a {@link ShortCodePatternMatcher} for the specified country, or null if not found
-     */
-    private static ShortCodePatternMatcher getPatternMatcher(String country, String settingsPattern) {
-        // embed pattern tag into an XML document.
-        String document = "<shortcodes>" + settingsPattern + "</shortcodes>";
-        if (VDBG) log("loading updated patterns from: " + document);
-
-        try {
-            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
-            XmlPullParser parser = factory.newPullParser();
-            parser.setInput(new StringReader(document));
-            return getPatternMatcher(country, parser);
-        } catch (XmlPullParserException e) {
-            Log.e(TAG, "XML parser exception reading short code pattern from settings", e);
-        } catch (IOException e) {
-            Log.e(TAG, "I/O exception reading short code pattern from settings", e);
-        }
-        return null;    // country not found
-    }
-
-    /**
-     * Return a pattern matcher object for the specified country and pattern XML parser.
-     * @param country the country to search for
-     * @return a {@link ShortCodePatternMatcher} for the specified country, or null if not found
-     */
-    private static ShortCodePatternMatcher getPatternMatcher(String country, XmlPullParser parser)
-            throws XmlPullParserException, IOException
-    {
-        XmlUtils.beginDocument(parser, TAG_SHORTCODES);
-
-        while (true) {
-            XmlUtils.nextElement(parser);
-
-            String element = parser.getName();
-            if (element == null) break;
-
-            if (element.equals(TAG_SHORTCODE)) {
-                String currentCountry = parser.getAttributeValue(null, ATTR_COUNTRY);
-                if (country.equals(currentCountry)) {
-                    String pattern = parser.getAttributeValue(null, ATTR_PATTERN);
-                    String premium = parser.getAttributeValue(null, ATTR_PREMIUM);
-                    String free = parser.getAttributeValue(null, ATTR_FREE);
-                    String standard = parser.getAttributeValue(null, ATTR_STANDARD);
-                    return new ShortCodePatternMatcher(pattern, premium, free, standard);
-                }
-            } else {
-                Log.e(TAG, "Error: skipping unknown XML tag " + element);
-            }
-        }
-        return null;    // country not found
-    }
-
-    /** 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);
-        }
-    }
-
-    /**
-     * Check if the destination is a possible premium short code.
-     * NOTE: the caller is expected to strip non-digits from the destination number with
-     * {@link PhoneNumberUtils#extractNetworkPortion} before calling this method.
-     * This happens in {@link SMSDispatcher#sendRawPdu} so that we use the same phone number
-     * for testing and in the user confirmation dialog if the user needs to confirm the number.
-     * This makes it difficult for malware to fool the user or the short code pattern matcher
-     * by using non-ASCII characters to make the number appear to be different from the real
-     * destination phone number.
-     *
-     * @param destAddress the destination address to test for possible short code
-     * @return {@link #CATEGORY_NOT_SHORT_CODE}, {@link #CATEGORY_FREE_SHORT_CODE},
-     *  {@link #CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE}, or {@link #CATEGORY_PREMIUM_SHORT_CODE}.
-     */
-    public int checkDestination(String destAddress, String countryIso) {
-        synchronized (mSettingsObserverHandler) {
-            // always allow emergency numbers
-            if (PhoneNumberUtils.isEmergencyNumber(destAddress, countryIso)) {
-                return CATEGORY_NOT_SHORT_CODE;
-            }
-
-            ShortCodePatternMatcher patternMatcher = null;
-
-            if (countryIso != null) {
-                // query secure settings and initialize content observer for updated regex patterns
-                if (mCurrentCountry == null || !countryIso.equals(mCurrentCountry)) {
-                    loadPatternsFromSettings(countryIso);
-                    mSettingsObserverHandler.observeSettingForCountry(countryIso);
-                }
-
-                if (countryIso.equals(mCurrentCountry)) {
-                    patternMatcher = mCurrentPatternMatcher;
-                } else {
-                    patternMatcher = getPatternMatcher(countryIso);
-                    mCurrentCountry = countryIso;
-                    mCurrentPatternMatcher = patternMatcher;    // may be null if not found
-                }
-            }
-
-            if (patternMatcher != null) {
-                return patternMatcher.getNumberCategory(destAddress);
-            } else {
-                // Generic rule: numbers of 5 digits or less are considered potential short codes
-                Log.e(TAG, "No patterns for \"" + countryIso + "\": using generic short code rule");
-                if (destAddress.length() <= 5) {
-                    return CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE;
-                } else {
-                    return CATEGORY_NOT_SHORT_CODE;
-                }
-            }
-        }
-    }
-
-    private static String getSettingNameForCountry(String countryIso) {
-        return Settings.Secure.SMS_SHORT_CODES_PREFIX + countryIso;
-    }
-
-    /**
-     * Load regex patterns from secure settings if present.
-     * @param countryIso the country to search for
-     */
-    void loadPatternsFromSettings(String countryIso) {
-        synchronized (mSettingsObserverHandler) {
-            if (VDBG) log("loadPatternsFromSettings(" + countryIso + ") called");
-            String settingsPatterns = Settings.Secure.getString(
-                    mContext.getContentResolver(), getSettingNameForCountry(countryIso));
-            if (settingsPatterns != null && !settingsPatterns.equals(
-                    mSettingsShortCodePatterns)) {
-                // settings pattern string has changed: update the pattern matcher
-                mSettingsShortCodePatterns = settingsPatterns;
-                ShortCodePatternMatcher matcher = getPatternMatcher(countryIso, settingsPatterns);
-                if (matcher != null) {
-                    mCurrentCountry = countryIso;
-                    mCurrentPatternMatcher = matcher;
-                }
-            } else if (settingsPatterns == null && mSettingsShortCodePatterns != null) {
-                // pattern string was removed: caller will load default patterns from XML resource
-                mCurrentCountry = null;
-                mCurrentPatternMatcher = null;
-                mSettingsShortCodePatterns = null;
-            }
-        }
-    }
-
-    /**
-     * 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 a122e68..0000000
--- a/telephony/java/com/android/internal/telephony/TelephonyCapabilities.java
+++ /dev/null
@@ -1,191 +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;
-    }
-
-    /**
-     * Returns true if the device can distinguish the phone's dialing state
-     * (Call.State.DIALING/ALERTING) and connected state (Call.State.ACTIVE).
-     *
-     * Currently this returns true for GSM phones as we cannot know when a CDMA
-     * phone has transitioned from dialing/active to connected.
-     */
-    public static boolean canDistinguishDialingAndConnected(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/CatException.java b/telephony/java/com/android/internal/telephony/cat/CatException.java
deleted file mode 100644
index 1bf1369..0000000
--- a/telephony/java/com/android/internal/telephony/cat/CatException.java
+++ /dev/null
@@ -1,31 +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.util.AndroidException;
-
-
-/**
- * Base class for all the exceptions in CAT service.
- *
- * {@hide}
- */
-class CatException extends AndroidException {
-    public CatException() {
-        super();
-    }
-}
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 2b37072..0000000
--- a/telephony/java/com/android/internal/telephony/cat/CatService.java
+++ /dev/null
@@ -1,750 +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");
-                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 3e7f722..0000000
--- a/telephony/java/com/android/internal/telephony/cat/CommandDetails.java
+++ /dev/null
@@ -1,115 +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 = in.readInt() != 0;
-        commandNumber = in.readInt();
-        typeOfCommand = in.readInt();
-        commandQualifier = in.readInt();
-    }
-
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(compRequired ? 1 : 0);
-        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;
-    }
-}
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 6985979..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
+++ /dev/null
@@ -1,945 +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;
-    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;
-
-
-    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 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 141736c..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.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.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) {
-        CdmaDataConnection cdmaDc = new CdmaDataConnection(phone,
-                "CdmaDC-" + mCount.incrementAndGet(), 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 e6b45f6..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ /dev/null
@@ -1,428 +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.ContentValues;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.database.Cursor;
-import android.database.SQLException;
-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.SmsCbMessage;
-import android.telephony.SmsManager;
-import android.telephony.SmsMessage.MessageClass;
-import android.telephony.cdma.CdmaSmsCbProgramData;
-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.SmsEnvelope;
-import com.android.internal.telephony.cdma.sms.UserData;
-import com.android.internal.util.HexDump;
-
-import java.io.ByteArrayOutputStream;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-
-import android.content.res.Resources;
-
-
-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) {
-        List<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("program_data_list", (CdmaSmsCbProgramData[]) programDataList.toArray());
-        dispatch(intent, RECEIVE_SMS_PERMISSION);
-    }
-
-    /** {@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;
-    }
-}
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 25cd112..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ /dev/null
@@ -1,1751 +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.getID() +
-                        " 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 a723de3..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ /dev/null
@@ -1,997 +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.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() {
-        return mEnvelope.messageType;
-    }
-
-    /**
-     * 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.
-     */
-    private 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
-     */
-    List<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 0f49762..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
+++ /dev/null
@@ -1,1942 +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.SmsCbMessage;
-import android.telephony.SmsMessage;
-import android.telephony.cdma.CdmaSmsCbProgramData;
-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.Arrays;
-import java.util.List;
-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 List<CdmaSmsCbProgramData> serviceCategoryProgramData;
-
-    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 udhPadding = udhBytes % 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 + udhPadding, 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);
-    }
-
-    /**
-     * 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);
-            }
-            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
-    {
-        if (numFields < 0 || (numFields + offset) > data.length) {
-            throw new CodingException("UTF-8 decode failed: offset or length out of range");
-        }
-        try {
-            return new String(data, offset, numFields, "UTF-8");
-        } catch (java.io.UnsupportedEncodingException ex) {
-            throw new CodingException("UTF-8 decode failed: " + ex);
-        }
-    }
-
-    private static String decodeUtf16(byte[] data, int offset, int numFields)
-        throws CodingException
-    {
-        int byteCount = numFields * 2;
-        if (byteCount < 0 || (byteCount + offset) > data.length) {
-            throw new CodingException("UTF-16 decode failed: offset or length out of range");
-        }
-        try {
-            return new String(data, offset, byteCount, "utf-16be");
-        } catch (java.io.UnsupportedEncodingException ex) {
-            throw new CodingException("UTF-16 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
-    {
-        if (numFields < 0 || (numFields + offset) > data.length) {
-            throw new CodingException("ISO-8859-1 decode failed: offset or length out of range");
-        }
-        try {
-            return new String(data, offset, numFields, "ISO-8859-1");
-        } catch (java.io.UnsupportedEncodingException ex) {
-            throw new CodingException("ISO-8859-1 decode failed: " + ex);
-        }
-    }
-
-    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);
-            String language = getLanguageCodeForValue(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 484bab0..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 = mPendingMMIs.size() - 1; i >= 0; 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 9e32e8d..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
+++ /dev/null
@@ -1,761 +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 android.text.TextUtils;
-
-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();
-        cnapName = dc.name;
-        cnapNamePresentation = dc.namePresentation;
-        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;
-        cnapName = null;
-        cnapNamePresentation = Connection.PRESENTATION_ALLOWED;
-        numberPresentation = Connection.PRESENTATION_ALLOWED;
-        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;
-        }
-
-        // 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: 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 3e6d9a5..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
+++ /dev/null
@@ -1,165 +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) {
-        GsmDataConnection gsmDc = new GsmDataConnection(phone,
-                "GsmDC-" + mCount.incrementAndGet(), 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 6b863a7..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ /dev/null
@@ -1,2632 +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) {
-        for (ApnContext apnContext : mApnContexts.values()) {
-            if (apnContext.getDataConnectionAc() == dcac) return false;
-        }
-        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(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE connId=" + connId);
-        if (ar.userObj instanceof ApnContext) {
-            apnContext = (ApnContext) ar.userObj;
-        } else {
-            loge("Invalid ar in onDisconnectDone");
-            return;
-        }
-
-        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 networkType = mPhone.getServiceState().getNetworkType();
-
-        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 == networkType) {
-                    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 == networkType) {
-                        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 b7569da..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) &&
-                (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 d2faceb..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("en", programData.getLanguageCode());
-        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("en", programData.getLanguageCode());
-        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("en", programData.getLanguageCode());
-        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 58e73e0..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/sms/CdmaSmsTest.java
+++ /dev/null
@@ -1,887 +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;
-
-public class CdmaSmsTest extends AndroidTestCase {
-    private final static String LOG_TAG = "XXX CdmaSmsTest XXX";
-
-    @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 {
-        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;
-        UserData userData = new UserData();
-        userData.payloadStr = "01234567";
-        userData.userDataHeader = smsHeader;
-        bearerData.userData = userData;
-        byte[] encodedSms = BearerData.encode(bearerData);
-        BearerData revBearerData = BearerData.decode(encodedSms);
-        assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
-    }
-
-    @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());
-        }
-
-    }
-}
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 a607ad0..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/mockril/MockRilTest.java
+++ /dev/null
@@ -1,305 +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/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)
