diff --git a/Android.mk b/Android.mk
index 4d567df..b9157fe 100644
--- a/Android.mk
+++ b/Android.mk
@@ -38,7 +38,6 @@
        core/java/android/content/EventLogTags.logtags \
        core/java/android/speech/tts/EventLogTags.logtags \
        core/java/android/webkit/EventLogTags.logtags \
-       telephony/java/com/android/internal/telephony/EventLogTags.logtags \
 
 # The following filters out code we are temporarily not including at all.
 # TODO: Move AWT and beans (and associated harmony code) back into libcore.
@@ -204,12 +203,10 @@
 	telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
 	telephony/java/com/android/internal/telephony/ITelephony.aidl \
 	telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
-	telephony/java/com/android/internal/telephony/IIccPhoneBook.aidl \
-	telephony/java/com/android/internal/telephony/ISms.aidl \
 	telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
+	telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl \
 	wifi/java/android/net/wifi/IWifiManager.aidl \
 	wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl \
-	telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl \
 	voip/java/android/net/sip/ISipSession.aidl \
 	voip/java/android/net/sip/ISipSessionListener.aidl \
 	voip/java/android/net/sip/ISipService.aidl
@@ -339,7 +336,9 @@
 include external/junit/Common.mk
 
 non_base_dirs := \
-	../../external/apache-http/src/org/apache/http
+	../../external/apache-http/src/org/apache/http \
+	../opt/telephony/src/java/android/telephony \
+	../opt/telephony/src/java/android/telephony/gsm \
 
 # These are relative to frameworks/base
 dirs_to_check_apis := \
@@ -390,6 +389,8 @@
 			core \
 			ext \
 			framework \
+			mms-common \
+			telephony-common \
 
 framework_docs_LOCAL_MODULE_CLASS := JAVA_LIBRARIES
 framework_docs_LOCAL_DROIDDOC_HTML_DIR := docs/html
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 0d8a7cd..61e5b4c 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -133,6 +133,7 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/accessibilityservice/IAccessibilityServiceClientCallback.P)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/accessibilityservice/IAccessibilityServiceClient.P)
 $(call add-clean-step, rm -f $(PRODUCT_OUT)/system/media/video/Disco*)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/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/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 055aee3..f4ab133 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -151,12 +151,12 @@
     static native int nCreateTextureLayer(boolean opaque, int[] layerInfo);
     static native int nCreateLayer(int width, int height, boolean isOpaque, int[] layerInfo);
     static native void nResizeLayer(int layerId, int width, int height, int[] layerInfo);
+    static native void nSetOpaqueLayer(int layerId, boolean isOpaque);
     static native void nUpdateTextureLayer(int layerId, int width, int height, boolean opaque,
             SurfaceTexture surface);
     static native void nSetTextureLayerTransform(int layerId, int matrix);
     static native void nDestroyLayer(int layerId);
     static native void nDestroyLayerDeferred(int layerId);
-    static native void nFlushLayer(int layerId);
     static native void nUpdateRenderLayer(int layerId, int renderer, int displayList,
             int left, int top, int right, int bottom);
     static native boolean nCopyLayer(int layerId, int bitmap);
diff --git a/core/java/android/view/GLES20Layer.java b/core/java/android/view/GLES20Layer.java
index 4f25792..a0ae379 100644
--- a/core/java/android/view/GLES20Layer.java
+++ b/core/java/android/view/GLES20Layer.java
@@ -46,11 +46,6 @@
     boolean copyInto(Bitmap bitmap) {
         return GLES20Canvas.nCopyLayer(mLayer, bitmap.mNativeBitmap);
     }
-    
-    @Override
-    void update(int width, int height, boolean isOpaque) {
-        super.update(width, height, isOpaque);
-    }
 
     @Override
     void destroy() {
@@ -60,13 +55,6 @@
         }
         mLayer = 0;
     }
-    
-    @Override
-    void flush() {
-        if (mLayer != 0) {
-            GLES20Canvas.nFlushLayer(mLayer);
-        }
-    }
 
     static class Finalizer {
         private int mLayerId;
diff --git a/core/java/android/view/GLES20RenderLayer.java b/core/java/android/view/GLES20RenderLayer.java
index c727a36..a77425a 100644
--- a/core/java/android/view/GLES20RenderLayer.java
+++ b/core/java/android/view/GLES20RenderLayer.java
@@ -71,6 +71,12 @@
     }
 
     @Override
+    void setOpaque(boolean isOpaque) {
+        mOpaque = isOpaque;
+        GLES20Canvas.nSetOpaqueLayer(mLayer, isOpaque);
+    }
+
+    @Override
     HardwareCanvas getCanvas() {
         return mCanvas;
     }
diff --git a/core/java/android/view/GLES20TextureLayer.java b/core/java/android/view/GLES20TextureLayer.java
index 16a13cf..e198ef6 100644
--- a/core/java/android/view/GLES20TextureLayer.java
+++ b/core/java/android/view/GLES20TextureLayer.java
@@ -42,12 +42,6 @@
         }        
     }
 
-    GLES20TextureLayer(SurfaceTexture surface, boolean isOpaque) {
-        this(isOpaque);
-        mSurface = surface;
-        mSurface.attachToGLContext(mTexture);
-    }
-
     @Override
     boolean isValid() {
         return mLayer != 0 && mTexture != 0;
@@ -93,6 +87,11 @@
     }
 
     @Override
+    void setOpaque(boolean isOpaque) {
+        throw new UnsupportedOperationException("Use update(int, int, boolean) instead");
+    }
+
+    @Override
     void setTransform(Matrix matrix) {
         GLES20Canvas.nSetTextureLayerTransform(mLayer, matrix.native_instance);
     }
diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java
index e73f7bf..06c6e7c 100644
--- a/core/java/android/view/HardwareLayer.java
+++ b/core/java/android/view/HardwareLayer.java
@@ -107,6 +107,13 @@
     }
 
     /**
+     * Sets whether or not this layer should be considered opaque.
+     * 
+     * @param isOpaque True if the layer is opaque, false otherwise
+     */
+    abstract void setOpaque(boolean isOpaque);
+
+    /**
      * Indicates whether this layer can be rendered.
      * 
      * @return True if the layer can be rendered into, false otherwise
@@ -136,11 +143,6 @@
     abstract void destroy();
 
     /**
-     * Flush the render queue associated with this layer.
-     */
-    abstract void flush();
-
-    /**
      * This must be invoked before drawing onto this layer.
      * @param currentCanvas
      */
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 149470a..78b34e6 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4798,9 +4798,10 @@
     }
 
     /**
-     * Computes whether the given portion of this view is visible to the user. Such a view is
-     * attached, visible, all its predecessors are visible, has an alpha greater than zero, and
-     * the specified portion is not clipped entirely by its predecessors.
+     * Computes whether the given portion of this view is visible to the user.
+     * Such a view is attached, visible, all its predecessors are visible,
+     * has an alpha greater than zero, and the specified portion is not
+     * clipped entirely by its predecessors.
      *
      * @param boundInView the portion of the view to test; coordinates should be relative; may be
      *                    <code>null</code>, and the entire view will be tested in this case.
@@ -4814,22 +4815,26 @@
      * @hide
      */
     protected boolean isVisibleToUser(Rect boundInView) {
-        Rect visibleRect = mAttachInfo.mTmpInvalRect;
-        Point offset = mAttachInfo.mPoint;
-        // The first two checks are made also made by isShown() which
-        // however traverses the tree up to the parent to catch that.
-        // Therefore, we do some fail fast check to minimize the up
-        // tree traversal.
-        boolean isVisible = mAttachInfo != null
-            && mAttachInfo.mWindowVisibility == View.VISIBLE
-            && getAlpha() > 0
-            && isShown()
-            && getGlobalVisibleRect(visibleRect, offset);
+        if (mAttachInfo != null) {
+            Rect visibleRect = mAttachInfo.mTmpInvalRect;
+            Point offset = mAttachInfo.mPoint;
+            // The first two checks are made also made by isShown() which
+            // however traverses the tree up to the parent to catch that.
+            // Therefore, we do some fail fast check to minimize the up
+            // tree traversal.
+            boolean isVisible = mAttachInfo.mWindowVisibility == View.VISIBLE
+                && getAlpha() > 0
+                && isShown()
+                && getGlobalVisibleRect(visibleRect, offset);
             if (isVisible && boundInView != null) {
                 visibleRect.offset(-offset.x, -offset.y);
-                isVisible &= boundInView.intersect(visibleRect);
+                // isVisible is always true here, use a simple assignment
+                isVisible = boundInView.intersect(visibleRect);
             }
             return isVisible;
+        }
+
+        return false;
     }
 
     /**
@@ -5272,7 +5277,7 @@
      * @return Return true if this view applied the insets and it should not
      * continue propagating further down the hierarchy, false otherwise.
      * @see #getFitsSystemWindows()
-     * @see #setFitsSystemWindows()
+     * @see #setFitsSystemWindows(boolean) 
      * @see #setSystemUiVisibility(int)
      */
     protected boolean fitSystemWindows(Rect insets) {
@@ -6464,10 +6469,7 @@
      */
     public boolean includeForAccessibility() {
         if (mAttachInfo != null) {
-            if (!mAttachInfo.mIncludeNotImportantViews) {
-                return isImportantForAccessibility();
-            }
-            return true;
+            return mAttachInfo.mIncludeNotImportantViews || isImportantForAccessibility();
         }
         return false;
     }
@@ -11899,13 +11901,6 @@
         }
     }
 
-    // Make sure the HardwareRenderer.validate() was invoked before calling this method
-    void flushLayer() {
-        if (mLayerType == LAYER_TYPE_HARDWARE && mHardwareLayer != null) {
-            mHardwareLayer.flush();
-        }
-    }
-
     /**
      * <p>Returns a hardware layer that can be used to draw this view again
      * without executing its draw method.</p>
@@ -11932,9 +11927,24 @@
                 mHardwareLayer = mAttachInfo.mHardwareRenderer.createHardwareLayer(
                         width, height, isOpaque());
                 mLocalDirtyRect.set(0, 0, width, height);
-            } else if (mHardwareLayer.getWidth() != width || mHardwareLayer.getHeight() != height) {
-                mHardwareLayer.resize(width, height);
-                mLocalDirtyRect.set(0, 0, width, height);
+            } else {
+                if (mHardwareLayer.getWidth() != width || mHardwareLayer.getHeight() != height) {
+                    mHardwareLayer.resize(width, height);
+                    mLocalDirtyRect.set(0, 0, width, height);
+                }
+
+                // This should not be necessary but applications that change
+                // the parameters of their background drawable without calling
+                // this.setBackground(Drawable) can leave the view in a bad state
+                // (for instance isOpaque() returns true, but the background is
+                // not opaque.)
+                computeOpaqueFlags();
+
+                final boolean opaque = isOpaque();
+                if (mHardwareLayer.isOpaque() != opaque) {
+                    mHardwareLayer.setOpaque(opaque);
+                    mLocalDirtyRect.set(0, 0, width, height);
+                }
             }
 
             // The layer is not valid if the underlying GPU resources cannot be allocated
@@ -12741,10 +12751,10 @@
 
         if (more) {
             if (!a.willChangeBounds()) {
-                if ((flags & (parent.FLAG_OPTIMIZE_INVALIDATE | parent.FLAG_ANIMATION_DONE)) ==
-                        parent.FLAG_OPTIMIZE_INVALIDATE) {
-                    parent.mGroupFlags |= parent.FLAG_INVALIDATE_REQUIRED;
-                } else if ((flags & parent.FLAG_INVALIDATE_REQUIRED) == 0) {
+                if ((flags & (ViewGroup.FLAG_OPTIMIZE_INVALIDATE | ViewGroup.FLAG_ANIMATION_DONE)) ==
+                        ViewGroup.FLAG_OPTIMIZE_INVALIDATE) {
+                    parent.mGroupFlags |= ViewGroup.FLAG_INVALIDATE_REQUIRED;
+                } else if ((flags & ViewGroup.FLAG_INVALIDATE_REQUIRED) == 0) {
                     // The child need to draw an animation, potentially offscreen, so
                     // make sure we do not cancel invalidate requests
                     parent.mPrivateFlags |= DRAW_ANIMATION;
@@ -13946,6 +13956,7 @@
     public void setBackgroundColor(int color) {
         if (mBackground instanceof ColorDrawable) {
             ((ColorDrawable) mBackground).setColor(color);
+            computeOpaqueFlags();
         } else {
             setBackground(new ColorDrawable(color));
         }
@@ -13993,6 +14004,8 @@
      */
     @Deprecated
     public void setBackgroundDrawable(Drawable background) {
+        computeOpaqueFlags();
+
         if (background == mBackground) {
             return;
         }
diff --git a/core/java/android/webkit/HTML5VideoView.java b/core/java/android/webkit/HTML5VideoView.java
index 610808b..96d8248 100644
--- a/core/java/android/webkit/HTML5VideoView.java
+++ b/core/java/android/webkit/HTML5VideoView.java
@@ -35,6 +35,7 @@
     static final int STATE_PREPARED           = 2;
     static final int STATE_PLAYING            = 3;
     static final int STATE_RESETTED           = 4;
+    static final int STATE_RELEASED           = 5;
 
     protected HTML5VideoViewProxy mProxy;
 
@@ -126,7 +127,7 @@
     }
 
     public void reset() {
-        if (mCurrentState != STATE_RESETTED) {
+        if (mCurrentState < STATE_RESETTED) {
             mPlayer.reset();
         }
         mCurrentState = STATE_RESETTED;
@@ -138,6 +139,18 @@
         }
     }
 
+    public static void release() {
+        if (mPlayer != null && mCurrentState != STATE_RELEASED) {
+            mPlayer.release();
+            mPlayer = null;
+        }
+        mCurrentState = STATE_RELEASED;
+    }
+
+    public boolean isReleased() {
+        return mCurrentState == STATE_RELEASED;
+    }
+
     public boolean getPauseDuringPreparing() {
         return mPauseDuringPreparing;
     }
diff --git a/core/java/android/webkit/HTML5VideoViewProxy.java b/core/java/android/webkit/HTML5VideoViewProxy.java
index 2dba89d..701ef35 100644
--- a/core/java/android/webkit/HTML5VideoViewProxy.java
+++ b/core/java/android/webkit/HTML5VideoViewProxy.java
@@ -109,7 +109,8 @@
             mBaseLayer = layer;
             // Don't do this for full screen mode.
             if (mHTML5VideoView != null
-                && !mHTML5VideoView.isFullScreenMode()) {
+                && !mHTML5VideoView.isFullScreenMode()
+                && !mHTML5VideoView.isReleased()) {
                 int currentVideoLayerId = mHTML5VideoView.getVideoLayerId();
                 SurfaceTexture surfTexture =
                         HTML5VideoInline.getSurfaceTexture(currentVideoLayerId);
@@ -214,7 +215,9 @@
 
             boolean skipPrepare = false;
             boolean createInlineView = false;
-            if (backFromFullScreenMode && currentVideoLayerId == videoLayerId) {
+            if (backFromFullScreenMode
+                && currentVideoLayerId == videoLayerId
+                && !mHTML5VideoView.isReleased()) {
                 skipPrepare = true;
                 createInlineView = true;
             } else if(backFromFullScreenMode
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 251ddf7..038dde5 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -745,6 +745,7 @@
             // Here we just need to clean up the Surface Texture which is static.
             if (level > TRIM_MEMORY_UI_HIDDEN) {
                 HTML5VideoInline.cleanupSurfaceTexture();
+                HTML5VideoView.release();
             }
             WebViewClassic.nativeOnTrimMemory(level);
         }
diff --git a/core/java/com/google/android/mms/ContentType.java b/core/java/com/google/android/mms/ContentType.java
deleted file mode 100644
index 12a1343..0000000
--- a/core/java/com/google/android/mms/ContentType.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Esmertec AG.
- * Copyright (C) 2007-2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms;
-
-import java.util.ArrayList;
-
-public class ContentType {
-    public static final String MMS_MESSAGE       = "application/vnd.wap.mms-message";
-    // The phony content type for generic PDUs (e.g. ReadOrig.ind,
-    // Notification.ind, Delivery.ind).
-    public static final String MMS_GENERIC       = "application/vnd.wap.mms-generic";
-    public static final String MULTIPART_MIXED   = "application/vnd.wap.multipart.mixed";
-    public static final String MULTIPART_RELATED = "application/vnd.wap.multipart.related";
-    public static final String MULTIPART_ALTERNATIVE = "application/vnd.wap.multipart.alternative";
-
-    public static final String TEXT_PLAIN        = "text/plain";
-    public static final String TEXT_HTML         = "text/html";
-    public static final String TEXT_VCALENDAR    = "text/x-vCalendar";
-    public static final String TEXT_VCARD        = "text/x-vCard";
-
-    public static final String IMAGE_UNSPECIFIED = "image/*";
-    public static final String IMAGE_JPEG        = "image/jpeg";
-    public static final String IMAGE_JPG         = "image/jpg";
-    public static final String IMAGE_GIF         = "image/gif";
-    public static final String IMAGE_WBMP        = "image/vnd.wap.wbmp";
-    public static final String IMAGE_PNG         = "image/png";
-    public static final String IMAGE_X_MS_BMP    = "image/x-ms-bmp";
-
-    public static final String AUDIO_UNSPECIFIED = "audio/*";
-    public static final String AUDIO_AAC         = "audio/aac";
-    public static final String AUDIO_AMR         = "audio/amr";
-    public static final String AUDIO_IMELODY     = "audio/imelody";
-    public static final String AUDIO_MID         = "audio/mid";
-    public static final String AUDIO_MIDI        = "audio/midi";
-    public static final String AUDIO_MP3         = "audio/mp3";
-    public static final String AUDIO_MPEG3       = "audio/mpeg3";
-    public static final String AUDIO_MPEG        = "audio/mpeg";
-    public static final String AUDIO_MPG         = "audio/mpg";
-    public static final String AUDIO_MP4         = "audio/mp4";
-    public static final String AUDIO_X_MID       = "audio/x-mid";
-    public static final String AUDIO_X_MIDI      = "audio/x-midi";
-    public static final String AUDIO_X_MP3       = "audio/x-mp3";
-    public static final String AUDIO_X_MPEG3     = "audio/x-mpeg3";
-    public static final String AUDIO_X_MPEG      = "audio/x-mpeg";
-    public static final String AUDIO_X_MPG       = "audio/x-mpg";
-    public static final String AUDIO_3GPP        = "audio/3gpp";
-    public static final String AUDIO_X_WAV       = "audio/x-wav";
-    public static final String AUDIO_OGG         = "application/ogg";
-
-    public static final String VIDEO_UNSPECIFIED = "video/*";
-    public static final String VIDEO_3GPP        = "video/3gpp";
-    public static final String VIDEO_3G2         = "video/3gpp2";
-    public static final String VIDEO_H263        = "video/h263";
-    public static final String VIDEO_MP4         = "video/mp4";
-
-    public static final String APP_SMIL          = "application/smil";
-    public static final String APP_WAP_XHTML     = "application/vnd.wap.xhtml+xml";
-    public static final String APP_XHTML         = "application/xhtml+xml";
-
-    public static final String APP_DRM_CONTENT   = "application/vnd.oma.drm.content";
-    public static final String APP_DRM_MESSAGE   = "application/vnd.oma.drm.message";
-
-    private static final ArrayList<String> sSupportedContentTypes = new ArrayList<String>();
-    private static final ArrayList<String> sSupportedImageTypes = new ArrayList<String>();
-    private static final ArrayList<String> sSupportedAudioTypes = new ArrayList<String>();
-    private static final ArrayList<String> sSupportedVideoTypes = new ArrayList<String>();
-
-    static {
-        sSupportedContentTypes.add(TEXT_PLAIN);
-        sSupportedContentTypes.add(TEXT_HTML);
-        sSupportedContentTypes.add(TEXT_VCALENDAR);
-        sSupportedContentTypes.add(TEXT_VCARD);
-
-        sSupportedContentTypes.add(IMAGE_JPEG);
-        sSupportedContentTypes.add(IMAGE_GIF);
-        sSupportedContentTypes.add(IMAGE_WBMP);
-        sSupportedContentTypes.add(IMAGE_PNG);
-        sSupportedContentTypes.add(IMAGE_JPG);
-        sSupportedContentTypes.add(IMAGE_X_MS_BMP);
-        //supportedContentTypes.add(IMAGE_SVG); not yet supported.
-
-        sSupportedContentTypes.add(AUDIO_AAC);
-        sSupportedContentTypes.add(AUDIO_AMR);
-        sSupportedContentTypes.add(AUDIO_IMELODY);
-        sSupportedContentTypes.add(AUDIO_MID);
-        sSupportedContentTypes.add(AUDIO_MIDI);
-        sSupportedContentTypes.add(AUDIO_MP3);
-        sSupportedContentTypes.add(AUDIO_MPEG3);
-        sSupportedContentTypes.add(AUDIO_MPEG);
-        sSupportedContentTypes.add(AUDIO_MPG);
-        sSupportedContentTypes.add(AUDIO_X_MID);
-        sSupportedContentTypes.add(AUDIO_X_MIDI);
-        sSupportedContentTypes.add(AUDIO_X_MP3);
-        sSupportedContentTypes.add(AUDIO_X_MPEG3);
-        sSupportedContentTypes.add(AUDIO_X_MPEG);
-        sSupportedContentTypes.add(AUDIO_X_MPG);
-        sSupportedContentTypes.add(AUDIO_X_WAV);
-        sSupportedContentTypes.add(AUDIO_3GPP);
-        sSupportedContentTypes.add(AUDIO_OGG);
-
-        sSupportedContentTypes.add(VIDEO_3GPP);
-        sSupportedContentTypes.add(VIDEO_3G2);
-        sSupportedContentTypes.add(VIDEO_H263);
-        sSupportedContentTypes.add(VIDEO_MP4);
-
-        sSupportedContentTypes.add(APP_SMIL);
-        sSupportedContentTypes.add(APP_WAP_XHTML);
-        sSupportedContentTypes.add(APP_XHTML);
-
-        sSupportedContentTypes.add(APP_DRM_CONTENT);
-        sSupportedContentTypes.add(APP_DRM_MESSAGE);
-
-        // add supported image types
-        sSupportedImageTypes.add(IMAGE_JPEG);
-        sSupportedImageTypes.add(IMAGE_GIF);
-        sSupportedImageTypes.add(IMAGE_WBMP);
-        sSupportedImageTypes.add(IMAGE_PNG);
-        sSupportedImageTypes.add(IMAGE_JPG);
-        sSupportedImageTypes.add(IMAGE_X_MS_BMP);
-
-        // add supported audio types
-        sSupportedAudioTypes.add(AUDIO_AAC);
-        sSupportedAudioTypes.add(AUDIO_AMR);
-        sSupportedAudioTypes.add(AUDIO_IMELODY);
-        sSupportedAudioTypes.add(AUDIO_MID);
-        sSupportedAudioTypes.add(AUDIO_MIDI);
-        sSupportedAudioTypes.add(AUDIO_MP3);
-        sSupportedAudioTypes.add(AUDIO_MPEG3);
-        sSupportedAudioTypes.add(AUDIO_MPEG);
-        sSupportedAudioTypes.add(AUDIO_MPG);
-        sSupportedAudioTypes.add(AUDIO_MP4);
-        sSupportedAudioTypes.add(AUDIO_X_MID);
-        sSupportedAudioTypes.add(AUDIO_X_MIDI);
-        sSupportedAudioTypes.add(AUDIO_X_MP3);
-        sSupportedAudioTypes.add(AUDIO_X_MPEG3);
-        sSupportedAudioTypes.add(AUDIO_X_MPEG);
-        sSupportedAudioTypes.add(AUDIO_X_MPG);
-        sSupportedAudioTypes.add(AUDIO_X_WAV);
-        sSupportedAudioTypes.add(AUDIO_3GPP);
-        sSupportedAudioTypes.add(AUDIO_OGG);
-
-        // add supported video types
-        sSupportedVideoTypes.add(VIDEO_3GPP);
-        sSupportedVideoTypes.add(VIDEO_3G2);
-        sSupportedVideoTypes.add(VIDEO_H263);
-        sSupportedVideoTypes.add(VIDEO_MP4);
-    }
-
-    // This class should never be instantiated.
-    private ContentType() {
-    }
-
-    public static boolean isSupportedType(String contentType) {
-        return (null != contentType) && sSupportedContentTypes.contains(contentType);
-    }
-
-    public static boolean isSupportedImageType(String contentType) {
-        return isImageType(contentType) && isSupportedType(contentType);
-    }
-
-    public static boolean isSupportedAudioType(String contentType) {
-        return isAudioType(contentType) && isSupportedType(contentType);
-    }
-
-    public static boolean isSupportedVideoType(String contentType) {
-        return isVideoType(contentType) && isSupportedType(contentType);
-    }
-
-    public static boolean isTextType(String contentType) {
-        return (null != contentType) && contentType.startsWith("text/");
-    }
-
-    public static boolean isImageType(String contentType) {
-        return (null != contentType) && contentType.startsWith("image/");
-    }
-
-    public static boolean isAudioType(String contentType) {
-        return (null != contentType) && contentType.startsWith("audio/");
-    }
-
-    public static boolean isVideoType(String contentType) {
-        return (null != contentType) && contentType.startsWith("video/");
-    }
-
-    public static boolean isDrmType(String contentType) {
-        return (null != contentType)
-                && (contentType.equals(APP_DRM_CONTENT)
-                        || contentType.equals(APP_DRM_MESSAGE));
-    }
-
-    public static boolean isUnspecified(String contentType) {
-        return (null != contentType) && contentType.endsWith("*");
-    }
-
-    @SuppressWarnings("unchecked")
-    public static ArrayList<String> getImageTypes() {
-        return (ArrayList<String>) sSupportedImageTypes.clone();
-    }
-
-    @SuppressWarnings("unchecked")
-    public static ArrayList<String> getAudioTypes() {
-        return (ArrayList<String>) sSupportedAudioTypes.clone();
-    }
-
-    @SuppressWarnings("unchecked")
-    public static ArrayList<String> getVideoTypes() {
-        return (ArrayList<String>) sSupportedVideoTypes.clone();
-    }
-
-    @SuppressWarnings("unchecked")
-    public static ArrayList<String> getSupportedTypes() {
-        return (ArrayList<String>) sSupportedContentTypes.clone();
-    }
-}
diff --git a/core/java/com/google/android/mms/InvalidHeaderValueException.java b/core/java/com/google/android/mms/InvalidHeaderValueException.java
deleted file mode 100644
index 73d7832..0000000
--- a/core/java/com/google/android/mms/InvalidHeaderValueException.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms;
-
-/**
- * Thrown when an invalid header value was set.
- */
-public class InvalidHeaderValueException extends MmsException {
-    private static final long serialVersionUID = -2053384496042052262L;
-
-    /**
-     * Constructs an InvalidHeaderValueException with no detailed message.
-     */
-    public InvalidHeaderValueException() {
-        super();
-    }
-
-    /**
-     * Constructs an InvalidHeaderValueException with the specified detailed message.
-     *
-     * @param message the detailed message.
-     */
-    public InvalidHeaderValueException(String message) {
-        super(message);
-    }
-}
diff --git a/core/java/com/google/android/mms/MmsException.java b/core/java/com/google/android/mms/MmsException.java
deleted file mode 100644
index 6ca0c7e..0000000
--- a/core/java/com/google/android/mms/MmsException.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms;
-
-/**
- * A generic exception that is thrown by the Mms client.
- */
-public class MmsException extends Exception {
-    private static final long serialVersionUID = -7323249827281485390L;
-
-    /**
-     * Creates a new MmsException.
-     */
-    public MmsException() {
-        super();
-    }
-
-    /**
-     * Creates a new MmsException with the specified detail message.
-     *
-     * @param message the detail message.
-     */
-    public MmsException(String message) {
-        super(message);
-    }
-
-    /**
-     * Creates a new MmsException with the specified cause.
-     *
-     * @param cause the cause.
-     */
-    public MmsException(Throwable cause) {
-        super(cause);
-    }
-
-    /**
-     * Creates a new MmsException with the specified detail message and cause.
-     *
-     * @param message the detail message.
-     * @param cause the cause.
-     */
-    public MmsException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/core/java/com/google/android/mms/package.html b/core/java/com/google/android/mms/package.html
deleted file mode 100755
index c9f96a6..0000000
--- a/core/java/com/google/android/mms/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<body>
-
-{@hide}
-
-</body>
diff --git a/core/java/com/google/android/mms/pdu/AcknowledgeInd.java b/core/java/com/google/android/mms/pdu/AcknowledgeInd.java
deleted file mode 100644
index 0e96c60..0000000
--- a/core/java/com/google/android/mms/pdu/AcknowledgeInd.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-/**
- * M-Acknowledge.ind PDU.
- */
-public class AcknowledgeInd extends GenericPdu {
-    /**
-     * Constructor, used when composing a M-Acknowledge.ind pdu.
-     *
-     * @param mmsVersion current viersion of mms
-     * @param transactionId the transaction-id value
-     * @throws InvalidHeaderValueException if parameters are invalid.
-     *         NullPointerException if transactionId is null.
-     */
-    public AcknowledgeInd(int mmsVersion, byte[] transactionId)
-            throws InvalidHeaderValueException {
-        super();
-
-        setMessageType(PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND);
-        setMmsVersion(mmsVersion);
-        setTransactionId(transactionId);
-    }
-
-    /**
-     * Constructor with given headers.
-     *
-     * @param headers Headers for this PDU.
-     */
-    AcknowledgeInd(PduHeaders headers) {
-        super(headers);
-    }
-
-    /**
-     * Get X-Mms-Report-Allowed field value.
-     *
-     * @return the X-Mms-Report-Allowed value
-     */
-    public int getReportAllowed() {
-        return mPduHeaders.getOctet(PduHeaders.REPORT_ALLOWED);
-    }
-
-    /**
-     * Set X-Mms-Report-Allowed field value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    public void setReportAllowed(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.REPORT_ALLOWED);
-    }
-
-    /**
-     * Get X-Mms-Transaction-Id field value.
-     *
-     * @return the X-Mms-Report-Allowed value
-     */
-    public byte[] getTransactionId() {
-        return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID);
-    }
-
-    /**
-     * Set X-Mms-Transaction-Id field value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setTransactionId(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID);
-    }
-}
diff --git a/core/java/com/google/android/mms/pdu/Base64.java b/core/java/com/google/android/mms/pdu/Base64.java
deleted file mode 100644
index 604bee0..0000000
--- a/core/java/com/google/android/mms/pdu/Base64.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-public class Base64 {
-    /**
-     * Used to get the number of Quadruples.
-     */
-    static final int FOURBYTE = 4;
-
-    /**
-     * Byte used to pad output.
-     */
-    static final byte PAD = (byte) '=';
-
-    /**
-     * The base length.
-     */
-    static final int BASELENGTH = 255;
-
-    // Create arrays to hold the base64 characters
-    private static byte[] base64Alphabet = new byte[BASELENGTH];
-
-    // Populating the character arrays
-    static {
-        for (int i = 0; i < BASELENGTH; i++) {
-            base64Alphabet[i] = (byte) -1;
-        }
-        for (int i = 'Z'; i >= 'A'; i--) {
-            base64Alphabet[i] = (byte) (i - 'A');
-        }
-        for (int i = 'z'; i >= 'a'; i--) {
-            base64Alphabet[i] = (byte) (i - 'a' + 26);
-        }
-        for (int i = '9'; i >= '0'; i--) {
-            base64Alphabet[i] = (byte) (i - '0' + 52);
-        }
-
-        base64Alphabet['+'] = 62;
-        base64Alphabet['/'] = 63;
-    }
-
-    /**
-     * Decodes Base64 data into octects
-     *
-     * @param base64Data Byte array containing Base64 data
-     * @return Array containing decoded data.
-     */
-    public static byte[] decodeBase64(byte[] base64Data) {
-        // RFC 2045 requires that we discard ALL non-Base64 characters
-        base64Data = discardNonBase64(base64Data);
-
-        // handle the edge case, so we don't have to worry about it later
-        if (base64Data.length == 0) {
-            return new byte[0];
-        }
-
-        int numberQuadruple = base64Data.length / FOURBYTE;
-        byte decodedData[] = null;
-        byte b1 = 0, b2 = 0, b3 = 0, b4 = 0, marker0 = 0, marker1 = 0;
-
-        // Throw away anything not in base64Data
-
-        int encodedIndex = 0;
-        int dataIndex = 0;
-        {
-            // this sizes the output array properly - rlw
-            int lastData = base64Data.length;
-            // ignore the '=' padding
-            while (base64Data[lastData - 1] == PAD) {
-                if (--lastData == 0) {
-                    return new byte[0];
-                }
-            }
-            decodedData = new byte[lastData - numberQuadruple];
-        }
-
-        for (int i = 0; i < numberQuadruple; i++) {
-            dataIndex = i * 4;
-            marker0 = base64Data[dataIndex + 2];
-            marker1 = base64Data[dataIndex + 3];
-
-            b1 = base64Alphabet[base64Data[dataIndex]];
-            b2 = base64Alphabet[base64Data[dataIndex + 1]];
-
-            if (marker0 != PAD && marker1 != PAD) {
-                //No PAD e.g 3cQl
-                b3 = base64Alphabet[marker0];
-                b4 = base64Alphabet[marker1];
-
-                decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
-                decodedData[encodedIndex + 1] =
-                    (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
-                decodedData[encodedIndex + 2] = (byte) (b3 << 6 | b4);
-            } else if (marker0 == PAD) {
-                //Two PAD e.g. 3c[Pad][Pad]
-                decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
-            } else if (marker1 == PAD) {
-                //One PAD e.g. 3cQ[Pad]
-                b3 = base64Alphabet[marker0];
-
-                decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
-                decodedData[encodedIndex + 1] =
-                    (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
-            }
-            encodedIndex += 3;
-        }
-        return decodedData;
-    }
-
-    /**
-     * Check octect wheter it is a base64 encoding.
-     *
-     * @param octect to be checked byte
-     * @return ture if it is base64 encoding, false otherwise.
-     */
-    private static boolean isBase64(byte octect) {
-        if (octect == PAD) {
-            return true;
-        } else if (base64Alphabet[octect] == -1) {
-            return false;
-        } else {
-            return true;
-        }
-    }
-
-    /**
-     * Discards any characters outside of the base64 alphabet, per
-     * the requirements on page 25 of RFC 2045 - "Any characters
-     * outside of the base64 alphabet are to be ignored in base64
-     * encoded data."
-     *
-     * @param data The base-64 encoded data to groom
-     * @return The data, less non-base64 characters (see RFC 2045).
-     */
-    static byte[] discardNonBase64(byte[] data) {
-        byte groomedData[] = new byte[data.length];
-        int bytesCopied = 0;
-
-        for (int i = 0; i < data.length; i++) {
-            if (isBase64(data[i])) {
-                groomedData[bytesCopied++] = data[i];
-            }
-        }
-
-        byte packedData[] = new byte[bytesCopied];
-
-        System.arraycopy(groomedData, 0, packedData, 0, bytesCopied);
-
-        return packedData;
-    }
-}
diff --git a/core/java/com/google/android/mms/pdu/CharacterSets.java b/core/java/com/google/android/mms/pdu/CharacterSets.java
deleted file mode 100644
index 4e22ca5..0000000
--- a/core/java/com/google/android/mms/pdu/CharacterSets.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import java.io.UnsupportedEncodingException;
-import java.util.HashMap;
-
-public class CharacterSets {
-    /**
-     * IANA assigned MIB enum numbers.
-     *
-     * From wap-230-wsp-20010705-a.pdf
-     * Any-charset = <Octet 128>
-     * Equivalent to the special RFC2616 charset value "*"
-     */
-    public static final int ANY_CHARSET = 0x00;
-    public static final int US_ASCII    = 0x03;
-    public static final int ISO_8859_1  = 0x04;
-    public static final int ISO_8859_2  = 0x05;
-    public static final int ISO_8859_3  = 0x06;
-    public static final int ISO_8859_4  = 0x07;
-    public static final int ISO_8859_5  = 0x08;
-    public static final int ISO_8859_6  = 0x09;
-    public static final int ISO_8859_7  = 0x0A;
-    public static final int ISO_8859_8  = 0x0B;
-    public static final int ISO_8859_9  = 0x0C;
-    public static final int SHIFT_JIS   = 0x11;
-    public static final int UTF_8       = 0x6A;
-    public static final int BIG5        = 0x07EA;
-    public static final int UCS2        = 0x03E8;
-    public static final int UTF_16      = 0x03F7;
-
-    /**
-     * If the encoding of given data is unsupported, use UTF_8 to decode it.
-     */
-    public static final int DEFAULT_CHARSET = UTF_8;
-
-    /**
-     * Array of MIB enum numbers.
-     */
-    private static final int[] MIBENUM_NUMBERS = {
-        ANY_CHARSET,
-        US_ASCII,
-        ISO_8859_1,
-        ISO_8859_2,
-        ISO_8859_3,
-        ISO_8859_4,
-        ISO_8859_5,
-        ISO_8859_6,
-        ISO_8859_7,
-        ISO_8859_8,
-        ISO_8859_9,
-        SHIFT_JIS,
-        UTF_8,
-        BIG5,
-        UCS2,
-        UTF_16,
-    };
-
-    /**
-     * The Well-known-charset Mime name.
-     */
-    public static final String MIMENAME_ANY_CHARSET = "*";
-    public static final String MIMENAME_US_ASCII    = "us-ascii";
-    public static final String MIMENAME_ISO_8859_1  = "iso-8859-1";
-    public static final String MIMENAME_ISO_8859_2  = "iso-8859-2";
-    public static final String MIMENAME_ISO_8859_3  = "iso-8859-3";
-    public static final String MIMENAME_ISO_8859_4  = "iso-8859-4";
-    public static final String MIMENAME_ISO_8859_5  = "iso-8859-5";
-    public static final String MIMENAME_ISO_8859_6  = "iso-8859-6";
-    public static final String MIMENAME_ISO_8859_7  = "iso-8859-7";
-    public static final String MIMENAME_ISO_8859_8  = "iso-8859-8";
-    public static final String MIMENAME_ISO_8859_9  = "iso-8859-9";
-    public static final String MIMENAME_SHIFT_JIS   = "shift_JIS";
-    public static final String MIMENAME_UTF_8       = "utf-8";
-    public static final String MIMENAME_BIG5        = "big5";
-    public static final String MIMENAME_UCS2        = "iso-10646-ucs-2";
-    public static final String MIMENAME_UTF_16      = "utf-16";
-
-    public static final String DEFAULT_CHARSET_NAME = MIMENAME_UTF_8;
-
-    /**
-     * Array of the names of character sets.
-     */
-    private static final String[] MIME_NAMES = {
-        MIMENAME_ANY_CHARSET,
-        MIMENAME_US_ASCII,
-        MIMENAME_ISO_8859_1,
-        MIMENAME_ISO_8859_2,
-        MIMENAME_ISO_8859_3,
-        MIMENAME_ISO_8859_4,
-        MIMENAME_ISO_8859_5,
-        MIMENAME_ISO_8859_6,
-        MIMENAME_ISO_8859_7,
-        MIMENAME_ISO_8859_8,
-        MIMENAME_ISO_8859_9,
-        MIMENAME_SHIFT_JIS,
-        MIMENAME_UTF_8,
-        MIMENAME_BIG5,
-        MIMENAME_UCS2,
-        MIMENAME_UTF_16,
-    };
-
-    private static final HashMap<Integer, String> MIBENUM_TO_NAME_MAP;
-    private static final HashMap<String, Integer> NAME_TO_MIBENUM_MAP;
-
-    static {
-        // Create the HashMaps.
-        MIBENUM_TO_NAME_MAP = new HashMap<Integer, String>();
-        NAME_TO_MIBENUM_MAP = new HashMap<String, Integer>();
-        assert(MIBENUM_NUMBERS.length == MIME_NAMES.length);
-        int count = MIBENUM_NUMBERS.length - 1;
-        for(int i = 0; i <= count; i++) {
-            MIBENUM_TO_NAME_MAP.put(MIBENUM_NUMBERS[i], MIME_NAMES[i]);
-            NAME_TO_MIBENUM_MAP.put(MIME_NAMES[i], MIBENUM_NUMBERS[i]);
-        }
-    }
-
-    private CharacterSets() {} // Non-instantiatable
-
-    /**
-     * Map an MIBEnum number to the name of the charset which this number
-     * is assigned to by IANA.
-     *
-     * @param mibEnumValue An IANA assigned MIBEnum number.
-     * @return The name string of the charset.
-     * @throws UnsupportedEncodingException
-     */
-    public static String getMimeName(int mibEnumValue)
-            throws UnsupportedEncodingException {
-        String name = MIBENUM_TO_NAME_MAP.get(mibEnumValue);
-        if (name == null) {
-            throw new UnsupportedEncodingException();
-        }
-        return name;
-    }
-
-    /**
-     * Map a well-known charset name to its assigned MIBEnum number.
-     *
-     * @param mimeName The charset name.
-     * @return The MIBEnum number assigned by IANA for this charset.
-     * @throws UnsupportedEncodingException
-     */
-    public static int getMibEnumValue(String mimeName)
-            throws UnsupportedEncodingException {
-        if(null == mimeName) {
-            return -1;
-        }
-
-        Integer mibEnumValue = NAME_TO_MIBENUM_MAP.get(mimeName);
-        if (mibEnumValue == null) {
-            throw new UnsupportedEncodingException();
-        }
-        return mibEnumValue;
-    }
-}
diff --git a/core/java/com/google/android/mms/pdu/DeliveryInd.java b/core/java/com/google/android/mms/pdu/DeliveryInd.java
deleted file mode 100644
index dafa8d1..0000000
--- a/core/java/com/google/android/mms/pdu/DeliveryInd.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-/**
- * M-Delivery.Ind Pdu.
- */
-public class DeliveryInd extends GenericPdu {
-    /**
-     * Empty constructor.
-     * Since the Pdu corresponding to this class is constructed
-     * by the Proxy-Relay server, this class is only instantiated
-     * by the Pdu Parser.
-     *
-     * @throws InvalidHeaderValueException if error occurs.
-     */
-    public DeliveryInd() throws InvalidHeaderValueException {
-        super();
-        setMessageType(PduHeaders.MESSAGE_TYPE_DELIVERY_IND);
-    }
-
-    /**
-     * Constructor with given headers.
-     *
-     * @param headers Headers for this PDU.
-     */
-    DeliveryInd(PduHeaders headers) {
-        super(headers);
-    }
-
-    /**
-     * Get Date value.
-     *
-     * @return the value
-     */
-    public long getDate() {
-        return mPduHeaders.getLongInteger(PduHeaders.DATE);
-    }
-
-    /**
-     * Set Date value.
-     *
-     * @param value the value
-     */
-    public void setDate(long value) {
-        mPduHeaders.setLongInteger(value, PduHeaders.DATE);
-    }
-
-    /**
-     * Get Message-ID value.
-     *
-     * @return the value
-     */
-    public byte[] getMessageId() {
-        return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID);
-    }
-
-    /**
-     * Set Message-ID value.
-     *
-     * @param value the value, should not be null
-     * @throws NullPointerException if the value is null.
-     */
-    public void setMessageId(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID);
-    }
-
-    /**
-     * Get Status value.
-     *
-     * @return the value
-     */
-    public int getStatus() {
-        return mPduHeaders.getOctet(PduHeaders.STATUS);
-    }
-
-    /**
-     * Set Status value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    public void setStatus(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.STATUS);
-    }
-
-    /**
-     * Get To value.
-     *
-     * @return the value
-     */
-    public EncodedStringValue[] getTo() {
-        return mPduHeaders.getEncodedStringValues(PduHeaders.TO);
-    }
-
-    /**
-     * set To value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setTo(EncodedStringValue[] value) {
-        mPduHeaders.setEncodedStringValues(value, PduHeaders.TO);
-    }
-
-    /*
-     * Optional, not supported header fields:
-     *
-     *     public byte[] getApplicId() {return null;}
-     *     public void setApplicId(byte[] value) {}
-     *
-     *     public byte[] getAuxApplicId() {return null;}
-     *     public void getAuxApplicId(byte[] value) {}
-     *
-     *     public byte[] getReplyApplicId() {return 0x00;}
-     *     public void setReplyApplicId(byte[] value) {}
-     *
-     *     public EncodedStringValue getStatusText() {return null;}
-     *     public void setStatusText(EncodedStringValue value) {}
-     */
-}
diff --git a/core/java/com/google/android/mms/pdu/EncodedStringValue.java b/core/java/com/google/android/mms/pdu/EncodedStringValue.java
deleted file mode 100644
index 9495c1c..0000000
--- a/core/java/com/google/android/mms/pdu/EncodedStringValue.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Esmertec AG.
- * Copyright (C) 2007-2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import android.util.Log;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-
-/**
- * Encoded-string-value = Text-string | Value-length Char-set Text-string
- */
-public class EncodedStringValue implements Cloneable {
-    private static final String TAG = "EncodedStringValue";
-    private static final boolean DEBUG = false;
-    private static final boolean LOCAL_LOGV = false;
-
-    /**
-     * The Char-set value.
-     */
-    private int mCharacterSet;
-
-    /**
-     * The Text-string value.
-     */
-    private byte[] mData;
-
-    /**
-     * Constructor.
-     *
-     * @param charset the Char-set value
-     * @param data the Text-string value
-     * @throws NullPointerException if Text-string value is null.
-     */
-    public EncodedStringValue(int charset, byte[] data) {
-        // TODO: CharSet needs to be validated against MIBEnum.
-        if(null == data) {
-            throw new NullPointerException("EncodedStringValue: Text-string is null.");
-        }
-
-        mCharacterSet = charset;
-        mData = new byte[data.length];
-        System.arraycopy(data, 0, mData, 0, data.length);
-    }
-
-    /**
-     * Constructor.
-     *
-     * @param data the Text-string value
-     * @throws NullPointerException if Text-string value is null.
-     */
-    public EncodedStringValue(byte[] data) {
-        this(CharacterSets.DEFAULT_CHARSET, data);
-    }
-
-    public EncodedStringValue(String data) {
-        try {
-            mData = data.getBytes(CharacterSets.DEFAULT_CHARSET_NAME);
-            mCharacterSet = CharacterSets.DEFAULT_CHARSET;
-        } catch (UnsupportedEncodingException e) {
-            Log.e(TAG, "Default encoding must be supported.", e);
-        }
-    }
-
-    /**
-     * Get Char-set value.
-     *
-     * @return the value
-     */
-    public int getCharacterSet() {
-        return mCharacterSet;
-    }
-
-    /**
-     * Set Char-set value.
-     *
-     * @param charset the Char-set value
-     */
-    public void setCharacterSet(int charset) {
-        // TODO: CharSet needs to be validated against MIBEnum.
-        mCharacterSet = charset;
-    }
-
-    /**
-     * Get Text-string value.
-     *
-     * @return the value
-     */
-    public byte[] getTextString() {
-        byte[] byteArray = new byte[mData.length];
-
-        System.arraycopy(mData, 0, byteArray, 0, mData.length);
-        return byteArray;
-    }
-
-    /**
-     * Set Text-string value.
-     *
-     * @param textString the Text-string value
-     * @throws NullPointerException if Text-string value is null.
-     */
-    public void setTextString(byte[] textString) {
-        if(null == textString) {
-            throw new NullPointerException("EncodedStringValue: Text-string is null.");
-        }
-
-        mData = new byte[textString.length];
-        System.arraycopy(textString, 0, mData, 0, textString.length);
-    }
-
-    /**
-     * Convert this object to a {@link java.lang.String}. If the encoding of
-     * the EncodedStringValue is null or unsupported, it will be
-     * treated as iso-8859-1 encoding.
-     *
-     * @return The decoded String.
-     */
-    public String getString()  {
-        if (CharacterSets.ANY_CHARSET == mCharacterSet) {
-            return new String(mData); // system default encoding.
-        } else {
-            try {
-                String name = CharacterSets.getMimeName(mCharacterSet);
-                return new String(mData, name);
-            } catch (UnsupportedEncodingException e) {
-            	if (LOCAL_LOGV) {
-            		Log.v(TAG, e.getMessage(), e);
-            	}
-            	try {
-                    return new String(mData, CharacterSets.MIMENAME_ISO_8859_1);
-                } catch (UnsupportedEncodingException _) {
-                    return new String(mData); // system default encoding.
-                }
-            }
-        }
-    }
-
-    /**
-     * Append to Text-string.
-     *
-     * @param textString the textString to append
-     * @throws NullPointerException if the text String is null
-     *                      or an IOException occured.
-     */
-    public void appendTextString(byte[] textString) {
-        if(null == textString) {
-            throw new NullPointerException("Text-string is null.");
-        }
-
-        if(null == mData) {
-            mData = new byte[textString.length];
-            System.arraycopy(textString, 0, mData, 0, textString.length);
-        } else {
-            ByteArrayOutputStream newTextString = new ByteArrayOutputStream();
-            try {
-                newTextString.write(mData);
-                newTextString.write(textString);
-            } catch (IOException e) {
-                e.printStackTrace();
-                throw new NullPointerException(
-                        "appendTextString: failed when write a new Text-string");
-            }
-
-            mData = newTextString.toByteArray();
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see java.lang.Object#clone()
-     */
-    @Override
-    public Object clone() throws CloneNotSupportedException {
-        super.clone();
-        int len = mData.length;
-        byte[] dstBytes = new byte[len];
-        System.arraycopy(mData, 0, dstBytes, 0, len);
-
-        try {
-            return new EncodedStringValue(mCharacterSet, dstBytes);
-        } catch (Exception e) {
-            Log.e(TAG, "failed to clone an EncodedStringValue: " + this);
-            e.printStackTrace();
-            throw new CloneNotSupportedException(e.getMessage());
-        }
-    }
-
-    /**
-     * Split this encoded string around matches of the given pattern.
-     *
-     * @param pattern the delimiting pattern
-     * @return the array of encoded strings computed by splitting this encoded
-     *         string around matches of the given pattern
-     */
-    public EncodedStringValue[] split(String pattern) {
-        String[] temp = getString().split(pattern);
-        EncodedStringValue[] ret = new EncodedStringValue[temp.length];
-        for (int i = 0; i < ret.length; ++i) {
-            try {
-                ret[i] = new EncodedStringValue(mCharacterSet,
-                        temp[i].getBytes());
-            } catch (NullPointerException _) {
-                // Can't arrive here
-                return null;
-            }
-        }
-        return ret;
-    }
-
-    /**
-     * Extract an EncodedStringValue[] from a given String.
-     */
-    public static EncodedStringValue[] extract(String src) {
-        String[] values = src.split(";");
-
-        ArrayList<EncodedStringValue> list = new ArrayList<EncodedStringValue>();
-        for (int i = 0; i < values.length; i++) {
-            if (values[i].length() > 0) {
-                list.add(new EncodedStringValue(values[i]));
-            }
-        }
-
-        int len = list.size();
-        if (len > 0) {
-            return list.toArray(new EncodedStringValue[len]);
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Concatenate an EncodedStringValue[] into a single String.
-     */
-    public static String concat(EncodedStringValue[] addr) {
-        StringBuilder sb = new StringBuilder();
-        int maxIndex = addr.length - 1;
-        for (int i = 0; i <= maxIndex; i++) {
-            sb.append(addr[i].getString());
-            if (i < maxIndex) {
-                sb.append(";");
-            }
-        }
-
-        return sb.toString();
-    }
-
-    public static EncodedStringValue copy(EncodedStringValue value) {
-        if (value == null) {
-            return null;
-        }
-
-        return new EncodedStringValue(value.mCharacterSet, value.mData);
-    }
-    
-    public static EncodedStringValue[] encodeStrings(String[] array) {
-        int count = array.length;
-        if (count > 0) {
-            EncodedStringValue[] encodedArray = new EncodedStringValue[count];
-            for (int i = 0; i < count; i++) {
-                encodedArray[i] = new EncodedStringValue(array[i]);
-            }
-            return encodedArray;
-        }
-        return null;
-    }
-}
diff --git a/core/java/com/google/android/mms/pdu/GenericPdu.java b/core/java/com/google/android/mms/pdu/GenericPdu.java
deleted file mode 100644
index 705de6a..0000000
--- a/core/java/com/google/android/mms/pdu/GenericPdu.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-public class GenericPdu {
-    /**
-     * The headers of pdu.
-     */
-    PduHeaders mPduHeaders = null;
-
-    /**
-     * Constructor.
-     */
-    public GenericPdu() {
-        mPduHeaders = new PduHeaders();
-    }
-
-    /**
-     * Constructor.
-     *
-     * @param headers Headers for this PDU.
-     */
-    GenericPdu(PduHeaders headers) {
-        mPduHeaders = headers;
-    }
-
-    /**
-     * Get the headers of this PDU.
-     *
-     * @return A PduHeaders of this PDU.
-     */
-    PduHeaders getPduHeaders() {
-        return mPduHeaders;
-    }
-
-    /**
-     * Get X-Mms-Message-Type field value.
-     *
-     * @return the X-Mms-Report-Allowed value
-     */
-    public int getMessageType() {
-        return mPduHeaders.getOctet(PduHeaders.MESSAGE_TYPE);
-    }
-
-    /**
-     * Set X-Mms-Message-Type field value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     *         RuntimeException if field's value is not Octet.
-     */
-    public void setMessageType(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.MESSAGE_TYPE);
-    }
-
-    /**
-     * Get X-Mms-MMS-Version field value.
-     *
-     * @return the X-Mms-MMS-Version value
-     */
-    public int getMmsVersion() {
-        return mPduHeaders.getOctet(PduHeaders.MMS_VERSION);
-    }
-
-    /**
-     * Set X-Mms-MMS-Version field value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     *         RuntimeException if field's value is not Octet.
-     */
-    public void setMmsVersion(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.MMS_VERSION);
-    }
-
-    /**
-     * Get From value.
-     * From-value = Value-length
-     *      (Address-present-token Encoded-string-value | Insert-address-token)
-     *
-     * @return the value
-     */
-    public EncodedStringValue getFrom() {
-       return mPduHeaders.getEncodedStringValue(PduHeaders.FROM);
-    }
-
-    /**
-     * Set From value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setFrom(EncodedStringValue value) {
-        mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM);
-    }
-}
diff --git a/core/java/com/google/android/mms/pdu/MultimediaMessagePdu.java b/core/java/com/google/android/mms/pdu/MultimediaMessagePdu.java
deleted file mode 100644
index 5a85e0e..0000000
--- a/core/java/com/google/android/mms/pdu/MultimediaMessagePdu.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-/**
- * Multimedia message PDU.
- */
-public class MultimediaMessagePdu extends GenericPdu{
-    /**
-     * The body.
-     */
-    private PduBody mMessageBody;
-
-    /**
-     * Constructor.
-     */
-    public MultimediaMessagePdu() {
-        super();
-    }
-
-    /**
-     * Constructor.
-     *
-     * @param header the header of this PDU
-     * @param body the body of this PDU
-     */
-    public MultimediaMessagePdu(PduHeaders header, PduBody body) {
-        super(header);
-        mMessageBody = body;
-    }
-
-    /**
-     * Constructor with given headers.
-     *
-     * @param headers Headers for this PDU.
-     */
-    MultimediaMessagePdu(PduHeaders headers) {
-        super(headers);
-    }
-
-    /**
-     * Get body of the PDU.
-     *
-     * @return the body
-     */
-    public PduBody getBody() {
-        return mMessageBody;
-    }
-
-    /**
-     * Set body of the PDU.
-     *
-     * @param body the body
-     */
-    public void setBody(PduBody body) {
-        mMessageBody = body;
-    }
-
-    /**
-     * Get subject.
-     *
-     * @return the value
-     */
-    public EncodedStringValue getSubject() {
-        return mPduHeaders.getEncodedStringValue(PduHeaders.SUBJECT);
-    }
-
-    /**
-     * Set subject.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setSubject(EncodedStringValue value) {
-        mPduHeaders.setEncodedStringValue(value, PduHeaders.SUBJECT);
-    }
-
-    /**
-     * Get To value.
-     *
-     * @return the value
-     */
-    public EncodedStringValue[] getTo() {
-        return mPduHeaders.getEncodedStringValues(PduHeaders.TO);
-    }
-
-    /**
-     * Add a "To" value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void addTo(EncodedStringValue value) {
-        mPduHeaders.appendEncodedStringValue(value, PduHeaders.TO);
-    }
-
-    /**
-     * Get X-Mms-Priority value.
-     *
-     * @return the value
-     */
-    public int getPriority() {
-        return mPduHeaders.getOctet(PduHeaders.PRIORITY);
-    }
-
-    /**
-     * Set X-Mms-Priority value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    public void setPriority(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.PRIORITY);
-    }
-
-    /**
-     * Get Date value.
-     *
-     * @return the value
-     */
-    public long getDate() {
-        return mPduHeaders.getLongInteger(PduHeaders.DATE);
-    }
-
-    /**
-     * Set Date value in seconds.
-     *
-     * @param value the value
-     */
-    public void setDate(long value) {
-        mPduHeaders.setLongInteger(value, PduHeaders.DATE);
-    }
-}
diff --git a/core/java/com/google/android/mms/pdu/NotificationInd.java b/core/java/com/google/android/mms/pdu/NotificationInd.java
deleted file mode 100644
index c56cba6..0000000
--- a/core/java/com/google/android/mms/pdu/NotificationInd.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-/**
- * M-Notification.ind PDU.
- */
-public class NotificationInd extends GenericPdu {
-    /**
-     * Empty constructor.
-     * Since the Pdu corresponding to this class is constructed
-     * by the Proxy-Relay server, this class is only instantiated
-     * by the Pdu Parser.
-     *
-     * @throws InvalidHeaderValueException if error occurs.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public NotificationInd() throws InvalidHeaderValueException {
-        super();
-        setMessageType(PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND);
-    }
-
-    /**
-     * Constructor with given headers.
-     *
-     * @param headers Headers for this PDU.
-     */
-    NotificationInd(PduHeaders headers) {
-        super(headers);
-    }
-
-    /**
-     * Get X-Mms-Content-Class Value.
-     *
-     * @return the value
-     */
-    public int getContentClass() {
-        return mPduHeaders.getOctet(PduHeaders.CONTENT_CLASS);
-    }
-
-    /**
-     * Set X-Mms-Content-Class Value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public void setContentClass(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.CONTENT_CLASS);
-    }
-
-    /**
-     * Get X-Mms-Content-Location value.
-     * When used in a PDU other than M-Mbox-Delete.conf and M-Delete.conf:
-     * Content-location-value = Uri-value
-     *
-     * @return the value
-     */
-    public byte[] getContentLocation() {
-        return mPduHeaders.getTextString(PduHeaders.CONTENT_LOCATION);
-    }
-
-    /**
-     * Set X-Mms-Content-Location value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public void setContentLocation(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.CONTENT_LOCATION);
-    }
-
-    /**
-     * Get X-Mms-Expiry value.
-     *
-     * Expiry-value = Value-length
-     *      (Absolute-token Date-value | Relative-token Delta-seconds-value)
-     *
-     * @return the value
-     */
-    public long getExpiry() {
-        return mPduHeaders.getLongInteger(PduHeaders.EXPIRY);
-    }
-
-    /**
-     * Set X-Mms-Expiry value.
-     *
-     * @param value the value
-     * @throws RuntimeException if an undeclared error occurs.
-     */
-    public void setExpiry(long value) {
-        mPduHeaders.setLongInteger(value, PduHeaders.EXPIRY);
-    }
-
-    /**
-     * Get From value.
-     * From-value = Value-length
-     *      (Address-present-token Encoded-string-value | Insert-address-token)
-     *
-     * @return the value
-     */
-    public EncodedStringValue getFrom() {
-       return mPduHeaders.getEncodedStringValue(PduHeaders.FROM);
-    }
-
-    /**
-     * Set From value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public void setFrom(EncodedStringValue value) {
-        mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM);
-    }
-
-    /**
-     * Get X-Mms-Message-Class value.
-     * Message-class-value = Class-identifier | Token-text
-     * Class-identifier = Personal | Advertisement | Informational | Auto
-     *
-     * @return the value
-     */
-    public byte[] getMessageClass() {
-        return mPduHeaders.getTextString(PduHeaders.MESSAGE_CLASS);
-    }
-
-    /**
-     * Set X-Mms-Message-Class value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public void setMessageClass(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.MESSAGE_CLASS);
-    }
-
-    /**
-     * Get X-Mms-Message-Size value.
-     * Message-size-value = Long-integer
-     *
-     * @return the value
-     */
-    public long getMessageSize() {
-        return mPduHeaders.getLongInteger(PduHeaders.MESSAGE_SIZE);
-    }
-
-    /**
-     * Set X-Mms-Message-Size value.
-     *
-     * @param value the value
-     * @throws RuntimeException if an undeclared error occurs.
-     */
-    public void setMessageSize(long value) {
-        mPduHeaders.setLongInteger(value, PduHeaders.MESSAGE_SIZE);
-    }
-
-    /**
-     * Get subject.
-     *
-     * @return the value
-     */
-    public EncodedStringValue getSubject() {
-        return mPduHeaders.getEncodedStringValue(PduHeaders.SUBJECT);
-    }
-
-    /**
-     * Set subject.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public void setSubject(EncodedStringValue value) {
-        mPduHeaders.setEncodedStringValue(value, PduHeaders.SUBJECT);
-    }
-
-    /**
-     * Get X-Mms-Transaction-Id.
-     *
-     * @return the value
-     */
-    public byte[] getTransactionId() {
-        return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID);
-    }
-
-    /**
-     * Set X-Mms-Transaction-Id.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public void setTransactionId(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID);
-    }
-
-    /**
-     * Get X-Mms-Delivery-Report Value.
-     *
-     * @return the value
-     */
-    public int getDeliveryReport() {
-        return mPduHeaders.getOctet(PduHeaders.DELIVERY_REPORT);
-    }
-
-    /**
-     * Set X-Mms-Delivery-Report Value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public void setDeliveryReport(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.DELIVERY_REPORT);
-    }
-
-    /*
-     * Optional, not supported header fields:
-     *
-     *     public byte[] getApplicId() {return null;}
-     *     public void setApplicId(byte[] value) {}
-     *
-     *     public byte[] getAuxApplicId() {return null;}
-     *     public void getAuxApplicId(byte[] value) {}
-     *
-     *     public byte getDrmContent() {return 0x00;}
-     *     public void setDrmContent(byte value) {}
-     *
-     *     public byte getDistributionIndicator() {return 0x00;}
-     *     public void setDistributionIndicator(byte value) {}
-     *
-     *     public ElementDescriptorValue getElementDescriptor() {return null;}
-     *     public void getElementDescriptor(ElementDescriptorValue value) {}
-     *
-     *     public byte getPriority() {return 0x00;}
-     *     public void setPriority(byte value) {}
-     *
-     *     public byte getRecommendedRetrievalMode() {return 0x00;}
-     *     public void setRecommendedRetrievalMode(byte value) {}
-     *
-     *     public byte getRecommendedRetrievalModeText() {return 0x00;}
-     *     public void setRecommendedRetrievalModeText(byte value) {}
-     *
-     *     public byte[] getReplaceId() {return 0x00;}
-     *     public void setReplaceId(byte[] value) {}
-     *
-     *     public byte[] getReplyApplicId() {return 0x00;}
-     *     public void setReplyApplicId(byte[] value) {}
-     *
-     *     public byte getReplyCharging() {return 0x00;}
-     *     public void setReplyCharging(byte value) {}
-     *
-     *     public byte getReplyChargingDeadline() {return 0x00;}
-     *     public void setReplyChargingDeadline(byte value) {}
-     *
-     *     public byte[] getReplyChargingId() {return 0x00;}
-     *     public void setReplyChargingId(byte[] value) {}
-     *
-     *     public long getReplyChargingSize() {return 0;}
-     *     public void setReplyChargingSize(long value) {}
-     *
-     *     public byte getStored() {return 0x00;}
-     *     public void setStored(byte value) {}
-     */
-}
diff --git a/core/java/com/google/android/mms/pdu/NotifyRespInd.java b/core/java/com/google/android/mms/pdu/NotifyRespInd.java
deleted file mode 100644
index 2cc2fce..0000000
--- a/core/java/com/google/android/mms/pdu/NotifyRespInd.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-/**
- * M-NofifyResp.ind PDU.
- */
-public class NotifyRespInd extends GenericPdu {
-    /**
-     * Constructor, used when composing a M-NotifyResp.ind pdu.
-     *
-     * @param mmsVersion current version of mms
-     * @param transactionId the transaction-id value
-     * @param status the status value
-     * @throws InvalidHeaderValueException if parameters are invalid.
-     *         NullPointerException if transactionId is null.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public NotifyRespInd(int mmsVersion,
-                         byte[] transactionId,
-                         int status) throws InvalidHeaderValueException {
-        super();
-        setMessageType(PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND);
-        setMmsVersion(mmsVersion);
-        setTransactionId(transactionId);
-        setStatus(status);
-    }
-
-    /**
-     * Constructor with given headers.
-     *
-     * @param headers Headers for this PDU.
-     */
-    NotifyRespInd(PduHeaders headers) {
-        super(headers);
-    }
-
-    /**
-     * Get X-Mms-Report-Allowed field value.
-     *
-     * @return the X-Mms-Report-Allowed value
-     */
-    public int getReportAllowed() {
-        return mPduHeaders.getOctet(PduHeaders.REPORT_ALLOWED);
-    }
-
-    /**
-     * Set X-Mms-Report-Allowed field value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public void setReportAllowed(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.REPORT_ALLOWED);
-    }
-
-    /**
-     * Set X-Mms-Status field value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public void setStatus(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.STATUS);
-    }
-
-    /**
-     * GetX-Mms-Status field value.
-     *
-     * @return the X-Mms-Status value
-     */
-    public int getStatus() {
-        return mPduHeaders.getOctet(PduHeaders.STATUS);
-    }
-
-    /**
-     * Get X-Mms-Transaction-Id field value.
-     *
-     * @return the X-Mms-Report-Allowed value
-     */
-    public byte[] getTransactionId() {
-        return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID);
-    }
-
-    /**
-     * Set X-Mms-Transaction-Id field value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public void setTransactionId(byte[] value) {
-            mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID);
-    }
-}
diff --git a/core/java/com/google/android/mms/pdu/PduBody.java b/core/java/com/google/android/mms/pdu/PduBody.java
deleted file mode 100644
index fa0416c..0000000
--- a/core/java/com/google/android/mms/pdu/PduBody.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Vector;
-
-public class PduBody {
-    private Vector<PduPart> mParts = null;
-
-    private Map<String, PduPart> mPartMapByContentId = null;
-    private Map<String, PduPart> mPartMapByContentLocation = null;
-    private Map<String, PduPart> mPartMapByName = null;
-    private Map<String, PduPart> mPartMapByFileName = null;
-
-    /**
-     * Constructor.
-     */
-    public PduBody() {
-        mParts = new Vector<PduPart>();
-
-        mPartMapByContentId = new HashMap<String, PduPart>();
-        mPartMapByContentLocation  = new HashMap<String, PduPart>();
-        mPartMapByName = new HashMap<String, PduPart>();
-        mPartMapByFileName = new HashMap<String, PduPart>();
-    }
-
-    private void putPartToMaps(PduPart part) {
-        // Put part to mPartMapByContentId.
-        byte[] contentId = part.getContentId();
-        if(null != contentId) {
-            mPartMapByContentId.put(new String(contentId), part);
-        }
-
-        // Put part to mPartMapByContentLocation.
-        byte[] contentLocation = part.getContentLocation();
-        if(null != contentLocation) {
-            String clc = new String(contentLocation);
-            mPartMapByContentLocation.put(clc, part);
-        }
-
-        // Put part to mPartMapByName.
-        byte[] name = part.getName();
-        if(null != name) {
-            String clc = new String(name);
-            mPartMapByName.put(clc, part);
-        }
-
-        // Put part to mPartMapByFileName.
-        byte[] fileName = part.getFilename();
-        if(null != fileName) {
-            String clc = new String(fileName);
-            mPartMapByFileName.put(clc, part);
-        }
-    }
-
-    /**
-     * Appends the specified part to the end of this body.
-     *
-     * @param part part to be appended
-     * @return true when success, false when fail
-     * @throws NullPointerException when part is null
-     */
-    public boolean addPart(PduPart part) {
-        if(null == part) {
-            throw new NullPointerException();
-        }
-
-        putPartToMaps(part);
-        return mParts.add(part);
-    }
-
-    /**
-     * Inserts the specified part at the specified position.
-     *
-     * @param index index at which the specified part is to be inserted
-     * @param part part to be inserted
-     * @throws NullPointerException when part is null
-     */
-    public void addPart(int index, PduPart part) {
-        if(null == part) {
-            throw new NullPointerException();
-        }
-
-        putPartToMaps(part);
-        mParts.add(index, part);
-    }
-
-    /**
-     * Removes the part at the specified position.
-     *
-     * @param index index of the part to return
-     * @return part at the specified index
-     */
-    public PduPart removePart(int index) {
-        return mParts.remove(index);
-    }
-
-    /**
-     * Remove all of the parts.
-     */
-    public void removeAll() {
-        mParts.clear();
-    }
-
-    /**
-     * Get the part at the specified position.
-     *
-     * @param index index of the part to return
-     * @return part at the specified index
-     */
-    public PduPart getPart(int index) {
-        return mParts.get(index);
-    }
-
-    /**
-     * Get the index of the specified part.
-     *
-     * @param part the part object
-     * @return index the index of the first occurrence of the part in this body
-     */
-    public int getPartIndex(PduPart part) {
-        return mParts.indexOf(part);
-    }
-
-    /**
-     * Get the number of parts.
-     *
-     * @return the number of parts
-     */
-    public int getPartsNum() {
-        return mParts.size();
-    }
-
-    /**
-     * Get pdu part by content id.
-     *
-     * @param cid the value of content id.
-     * @return the pdu part.
-     */
-    public PduPart getPartByContentId(String cid) {
-        return mPartMapByContentId.get(cid);
-    }
-
-    /**
-     * Get pdu part by Content-Location. Content-Location of part is
-     * the same as filename and name(param of content-type).
-     *
-     * @param fileName the value of filename.
-     * @return the pdu part.
-     */
-    public PduPart getPartByContentLocation(String contentLocation) {
-        return mPartMapByContentLocation.get(contentLocation);
-    }
-
-    /**
-     * Get pdu part by name.
-     *
-     * @param fileName the value of filename.
-     * @return the pdu part.
-     */
-    public PduPart getPartByName(String name) {
-        return mPartMapByName.get(name);
-    }
-
-    /**
-     * Get pdu part by filename.
-     *
-     * @param fileName the value of filename.
-     * @return the pdu part.
-     */
-    public PduPart getPartByFileName(String filename) {
-        return mPartMapByFileName.get(filename);
-    }
-}
diff --git a/core/java/com/google/android/mms/pdu/PduComposer.java b/core/java/com/google/android/mms/pdu/PduComposer.java
deleted file mode 100644
index d426f89..0000000
--- a/core/java/com/google/android/mms/pdu/PduComposer.java
+++ /dev/null
@@ -1,1179 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Esmertec AG.
- * Copyright (C) 2007-2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.util.Log;
-import android.text.TextUtils;
-
-import java.io.ByteArrayOutputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Arrays;
-import java.util.HashMap;
-
-public class PduComposer {
-    /**
-     * Address type.
-     */
-    static private final int PDU_PHONE_NUMBER_ADDRESS_TYPE = 1;
-    static private final int PDU_EMAIL_ADDRESS_TYPE = 2;
-    static private final int PDU_IPV4_ADDRESS_TYPE = 3;
-    static private final int PDU_IPV6_ADDRESS_TYPE = 4;
-    static private final int PDU_UNKNOWN_ADDRESS_TYPE = 5;
-
-    /**
-     * Address regular expression string.
-     */
-    static final String REGEXP_PHONE_NUMBER_ADDRESS_TYPE = "\\+?[0-9|\\.|\\-]+";
-    static final String REGEXP_EMAIL_ADDRESS_TYPE = "[a-zA-Z| ]*\\<{0,1}[a-zA-Z| ]+@{1}" +
-            "[a-zA-Z| ]+\\.{1}[a-zA-Z| ]+\\>{0,1}";
-    static final String REGEXP_IPV6_ADDRESS_TYPE =
-        "[a-fA-F]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}" +
-        "[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}" +
-        "[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}";
-    static final String REGEXP_IPV4_ADDRESS_TYPE = "[0-9]{1,3}\\.{1}[0-9]{1,3}\\.{1}" +
-            "[0-9]{1,3}\\.{1}[0-9]{1,3}";
-
-    /**
-     * The postfix strings of address.
-     */
-    static final String STRING_PHONE_NUMBER_ADDRESS_TYPE = "/TYPE=PLMN";
-    static final String STRING_IPV4_ADDRESS_TYPE = "/TYPE=IPV4";
-    static final String STRING_IPV6_ADDRESS_TYPE = "/TYPE=IPV6";
-
-    /**
-     * Error values.
-     */
-    static private final int PDU_COMPOSE_SUCCESS = 0;
-    static private final int PDU_COMPOSE_CONTENT_ERROR = 1;
-    static private final int PDU_COMPOSE_FIELD_NOT_SET = 2;
-    static private final int PDU_COMPOSE_FIELD_NOT_SUPPORTED = 3;
-
-    /**
-     * WAP values defined in WSP spec.
-     */
-    static private final int QUOTED_STRING_FLAG = 34;
-    static private final int END_STRING_FLAG = 0;
-    static private final int LENGTH_QUOTE = 31;
-    static private final int TEXT_MAX = 127;
-    static private final int SHORT_INTEGER_MAX = 127;
-    static private final int LONG_INTEGER_LENGTH_MAX = 8;
-
-    /**
-     * Block size when read data from InputStream.
-     */
-    static private final int PDU_COMPOSER_BLOCK_SIZE = 1024;
-
-    /**
-     * The output message.
-     */
-    protected ByteArrayOutputStream mMessage = null;
-
-    /**
-     * The PDU.
-     */
-    private GenericPdu mPdu = null;
-
-    /**
-     * Current visiting position of the mMessage.
-     */
-    protected int mPosition = 0;
-
-    /**
-     * Message compose buffer stack.
-     */
-    private BufferStack mStack = null;
-
-    /**
-     * Content resolver.
-     */
-    private final ContentResolver mResolver;
-
-    /**
-     * Header of this pdu.
-     */
-    private PduHeaders mPduHeader = null;
-
-    /**
-     * Map of all content type
-     */
-    private static HashMap<String, Integer> mContentTypeMap = null;
-
-    static {
-        mContentTypeMap = new HashMap<String, Integer>();
-
-        int i;
-        for (i = 0; i < PduContentTypes.contentTypes.length; i++) {
-            mContentTypeMap.put(PduContentTypes.contentTypes[i], i);
-        }
-    }
-
-    /**
-     * Constructor.
-     *
-     * @param context the context
-     * @param pdu the pdu to be composed
-     */
-    public PduComposer(Context context, GenericPdu pdu) {
-        mPdu = pdu;
-        mResolver = context.getContentResolver();
-        mPduHeader = pdu.getPduHeaders();
-        mStack = new BufferStack();
-        mMessage = new ByteArrayOutputStream();
-        mPosition = 0;
-    }
-
-    /**
-     * Make the message. No need to check whether mandatory fields are set,
-     * because the constructors of outgoing pdus are taking care of this.
-     *
-     * @return OutputStream of maked message. Return null if
-     *         the PDU is invalid.
-     */
-    public byte[] make() {
-        // Get Message-type.
-        int type = mPdu.getMessageType();
-
-        /* make the message */
-        switch (type) {
-            case PduHeaders.MESSAGE_TYPE_SEND_REQ:
-                if (makeSendReqPdu() != PDU_COMPOSE_SUCCESS) {
-                    return null;
-                }
-                break;
-            case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND:
-                if (makeNotifyResp() != PDU_COMPOSE_SUCCESS) {
-                    return null;
-                }
-                break;
-            case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND:
-                if (makeAckInd() != PDU_COMPOSE_SUCCESS) {
-                    return null;
-                }
-                break;
-            case PduHeaders.MESSAGE_TYPE_READ_REC_IND:
-                if (makeReadRecInd() != PDU_COMPOSE_SUCCESS) {
-                    return null;
-                }
-                break;
-            default:
-                return null;
-        }
-
-        return mMessage.toByteArray();
-    }
-
-    /**
-     *  Copy buf to mMessage.
-     */
-    protected void arraycopy(byte[] buf, int pos, int length) {
-        mMessage.write(buf, pos, length);
-        mPosition = mPosition + length;
-    }
-
-    /**
-     * Append a byte to mMessage.
-     */
-    protected void append(int value) {
-        mMessage.write(value);
-        mPosition ++;
-    }
-
-    /**
-     * Append short integer value to mMessage.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendShortInteger(int value) {
-        /*
-         * From WAP-230-WSP-20010705-a:
-         * Short-integer = OCTET
-         * ; Integers in range 0-127 shall be encoded as a one octet value
-         * ; with the most significant bit set to one (1xxx xxxx) and with
-         * ; the value in the remaining least significant bits.
-         * In our implementation, only low 7 bits are stored and otherwise
-         * bits are ignored.
-         */
-        append((value | 0x80) & 0xff);
-    }
-
-    /**
-     * Append an octet number between 128 and 255 into mMessage.
-     * NOTE:
-     * A value between 0 and 127 should be appended by using appendShortInteger.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendOctet(int number) {
-        append(number);
-    }
-
-    /**
-     * Append a short length into mMessage.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendShortLength(int value) {
-        /*
-         * From WAP-230-WSP-20010705-a:
-         * Short-length = <Any octet 0-30>
-         */
-        append(value);
-    }
-
-    /**
-     * Append long integer into mMessage. it's used for really long integers.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendLongInteger(long longInt) {
-        /*
-         * From WAP-230-WSP-20010705-a:
-         * Long-integer = Short-length Multi-octet-integer
-         * ; The Short-length indicates the length of the Multi-octet-integer
-         * Multi-octet-integer = 1*30 OCTET
-         * ; The content octets shall be an unsigned integer value with the
-         * ; most significant octet encoded first (big-endian representation).
-         * ; The minimum number of octets must be used to encode the value.
-         */
-        int size;
-        long temp = longInt;
-
-        // Count the length of the long integer.
-        for(size = 0; (temp != 0) && (size < LONG_INTEGER_LENGTH_MAX); size++) {
-            temp = (temp >>> 8);
-        }
-
-        // Set Length.
-        appendShortLength(size);
-
-        // Count and set the long integer.
-        int i;
-        int shift = (size -1) * 8;
-
-        for (i = 0; i < size; i++) {
-            append((int)((longInt >>> shift) & 0xff));
-            shift = shift - 8;
-        }
-    }
-
-    /**
-     * Append text string into mMessage.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendTextString(byte[] text) {
-        /*
-         * From WAP-230-WSP-20010705-a:
-         * Text-string = [Quote] *TEXT End-of-string
-         * ; If the first character in the TEXT is in the range of 128-255,
-         * ; a Quote character must precede it. Otherwise the Quote character
-         * ;must be omitted. The Quote is not part of the contents.
-         */
-        if (((text[0])&0xff) > TEXT_MAX) { // No need to check for <= 255
-            append(TEXT_MAX);
-        }
-
-        arraycopy(text, 0, text.length);
-        append(0);
-    }
-
-    /**
-     * Append text string into mMessage.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendTextString(String str) {
-        /*
-         * From WAP-230-WSP-20010705-a:
-         * Text-string = [Quote] *TEXT End-of-string
-         * ; If the first character in the TEXT is in the range of 128-255,
-         * ; a Quote character must precede it. Otherwise the Quote character
-         * ;must be omitted. The Quote is not part of the contents.
-         */
-        appendTextString(str.getBytes());
-    }
-
-    /**
-     * Append encoded string value to mMessage.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendEncodedString(EncodedStringValue enStr) {
-        /*
-         * From OMA-TS-MMS-ENC-V1_3-20050927-C:
-         * Encoded-string-value = Text-string | Value-length Char-set Text-string
-         */
-        assert(enStr != null);
-
-        int charset = enStr.getCharacterSet();
-        byte[] textString = enStr.getTextString();
-        if (null == textString) {
-            return;
-        }
-
-        /*
-         * In the implementation of EncodedStringValue, the charset field will
-         * never be 0. It will always be composed as
-         * Encoded-string-value = Value-length Char-set Text-string
-         */
-        mStack.newbuf();
-        PositionMarker start = mStack.mark();
-
-        appendShortInteger(charset);
-        appendTextString(textString);
-
-        int len = start.getLength();
-        mStack.pop();
-        appendValueLength(len);
-        mStack.copy();
-    }
-
-    /**
-     * Append uintvar integer into mMessage.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendUintvarInteger(long value) {
-        /*
-         * From WAP-230-WSP-20010705-a:
-         * To encode a large unsigned integer, split it into 7-bit fragments
-         * and place them in the payloads of multiple octets. The most significant
-         * bits are placed in the first octets with the least significant bits
-         * ending up in the last octet. All octets MUST set the Continue bit to 1
-         * except the last octet, which MUST set the Continue bit to 0.
-         */
-        int i;
-        long max = SHORT_INTEGER_MAX;
-
-        for (i = 0; i < 5; i++) {
-            if (value < max) {
-                break;
-            }
-
-            max = (max << 7) | 0x7fl;
-        }
-
-        while(i > 0) {
-            long temp = value >>> (i * 7);
-            temp = temp & 0x7f;
-
-            append((int)((temp | 0x80) & 0xff));
-
-            i--;
-        }
-
-        append((int)(value & 0x7f));
-    }
-
-    /**
-     * Append date value into mMessage.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendDateValue(long date) {
-        /*
-         * From OMA-TS-MMS-ENC-V1_3-20050927-C:
-         * Date-value = Long-integer
-         */
-        appendLongInteger(date);
-    }
-
-    /**
-     * Append value length to mMessage.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendValueLength(long value) {
-        /*
-         * From WAP-230-WSP-20010705-a:
-         * Value-length = Short-length | (Length-quote Length)
-         * ; Value length is used to indicate the length of the value to follow
-         * Short-length = <Any octet 0-30>
-         * Length-quote = <Octet 31>
-         * Length = Uintvar-integer
-         */
-        if (value < LENGTH_QUOTE) {
-            appendShortLength((int) value);
-            return;
-        }
-
-        append(LENGTH_QUOTE);
-        appendUintvarInteger(value);
-    }
-
-    /**
-     * Append quoted string to mMessage.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendQuotedString(byte[] text) {
-        /*
-         * From WAP-230-WSP-20010705-a:
-         * Quoted-string = <Octet 34> *TEXT End-of-string
-         * ;The TEXT encodes an RFC2616 Quoted-string with the enclosing
-         * ;quotation-marks <"> removed.
-         */
-        append(QUOTED_STRING_FLAG);
-        arraycopy(text, 0, text.length);
-        append(END_STRING_FLAG);
-    }
-
-    /**
-     * Append quoted string to mMessage.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendQuotedString(String str) {
-        /*
-         * From WAP-230-WSP-20010705-a:
-         * Quoted-string = <Octet 34> *TEXT End-of-string
-         * ;The TEXT encodes an RFC2616 Quoted-string with the enclosing
-         * ;quotation-marks <"> removed.
-         */
-        appendQuotedString(str.getBytes());
-    }
-
-    private EncodedStringValue appendAddressType(EncodedStringValue address) {
-        EncodedStringValue temp = null;
-
-        try {
-            int addressType = checkAddressType(address.getString());
-            temp = EncodedStringValue.copy(address);
-            if (PDU_PHONE_NUMBER_ADDRESS_TYPE == addressType) {
-                // Phone number.
-                temp.appendTextString(STRING_PHONE_NUMBER_ADDRESS_TYPE.getBytes());
-            } else if (PDU_IPV4_ADDRESS_TYPE == addressType) {
-                // Ipv4 address.
-                temp.appendTextString(STRING_IPV4_ADDRESS_TYPE.getBytes());
-            } else if (PDU_IPV6_ADDRESS_TYPE == addressType) {
-                // Ipv6 address.
-                temp.appendTextString(STRING_IPV6_ADDRESS_TYPE.getBytes());
-            }
-        } catch (NullPointerException e) {
-            return null;
-        }
-
-        return temp;
-    }
-
-    /**
-     * Append header to mMessage.
-     */
-    private int appendHeader(int field) {
-        switch (field) {
-            case PduHeaders.MMS_VERSION:
-                appendOctet(field);
-
-                int version = mPduHeader.getOctet(field);
-                if (0 == version) {
-                    appendShortInteger(PduHeaders.CURRENT_MMS_VERSION);
-                } else {
-                    appendShortInteger(version);
-                }
-
-                break;
-
-            case PduHeaders.MESSAGE_ID:
-            case PduHeaders.TRANSACTION_ID:
-                byte[] textString = mPduHeader.getTextString(field);
-                if (null == textString) {
-                    return PDU_COMPOSE_FIELD_NOT_SET;
-                }
-
-                appendOctet(field);
-                appendTextString(textString);
-                break;
-
-            case PduHeaders.TO:
-            case PduHeaders.BCC:
-            case PduHeaders.CC:
-                EncodedStringValue[] addr = mPduHeader.getEncodedStringValues(field);
-
-                if (null == addr) {
-                    return PDU_COMPOSE_FIELD_NOT_SET;
-                }
-
-                EncodedStringValue temp;
-                for (int i = 0; i < addr.length; i++) {
-                    temp = appendAddressType(addr[i]);
-                    if (temp == null) {
-                        return PDU_COMPOSE_CONTENT_ERROR;
-                    }
-
-                    appendOctet(field);
-                    appendEncodedString(temp);
-                }
-                break;
-
-            case PduHeaders.FROM:
-                // Value-length (Address-present-token Encoded-string-value | Insert-address-token)
-                appendOctet(field);
-
-                EncodedStringValue from = mPduHeader.getEncodedStringValue(field);
-                if ((from == null)
-                        || TextUtils.isEmpty(from.getString())
-                        || new String(from.getTextString()).equals(
-                                PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR)) {
-                    // Length of from = 1
-                    append(1);
-                    // Insert-address-token = <Octet 129>
-                    append(PduHeaders.FROM_INSERT_ADDRESS_TOKEN);
-                } else {
-                    mStack.newbuf();
-                    PositionMarker fstart = mStack.mark();
-
-                    // Address-present-token = <Octet 128>
-                    append(PduHeaders.FROM_ADDRESS_PRESENT_TOKEN);
-
-                    temp = appendAddressType(from);
-                    if (temp == null) {
-                        return PDU_COMPOSE_CONTENT_ERROR;
-                    }
-
-                    appendEncodedString(temp);
-
-                    int flen = fstart.getLength();
-                    mStack.pop();
-                    appendValueLength(flen);
-                    mStack.copy();
-                }
-                break;
-
-            case PduHeaders.READ_STATUS:
-            case PduHeaders.STATUS:
-            case PduHeaders.REPORT_ALLOWED:
-            case PduHeaders.PRIORITY:
-            case PduHeaders.DELIVERY_REPORT:
-            case PduHeaders.READ_REPORT:
-                int octet = mPduHeader.getOctet(field);
-                if (0 == octet) {
-                    return PDU_COMPOSE_FIELD_NOT_SET;
-                }
-
-                appendOctet(field);
-                appendOctet(octet);
-                break;
-
-            case PduHeaders.DATE:
-                long date = mPduHeader.getLongInteger(field);
-                if (-1 == date) {
-                    return PDU_COMPOSE_FIELD_NOT_SET;
-                }
-
-                appendOctet(field);
-                appendDateValue(date);
-                break;
-
-            case PduHeaders.SUBJECT:
-                EncodedStringValue enString =
-                    mPduHeader.getEncodedStringValue(field);
-                if (null == enString) {
-                    return PDU_COMPOSE_FIELD_NOT_SET;
-                }
-
-                appendOctet(field);
-                appendEncodedString(enString);
-                break;
-
-            case PduHeaders.MESSAGE_CLASS:
-                byte[] messageClass = mPduHeader.getTextString(field);
-                if (null == messageClass) {
-                    return PDU_COMPOSE_FIELD_NOT_SET;
-                }
-
-                appendOctet(field);
-                if (Arrays.equals(messageClass,
-                        PduHeaders.MESSAGE_CLASS_ADVERTISEMENT_STR.getBytes())) {
-                    appendOctet(PduHeaders.MESSAGE_CLASS_ADVERTISEMENT);
-                } else if (Arrays.equals(messageClass,
-                        PduHeaders.MESSAGE_CLASS_AUTO_STR.getBytes())) {
-                    appendOctet(PduHeaders.MESSAGE_CLASS_AUTO);
-                } else if (Arrays.equals(messageClass,
-                        PduHeaders.MESSAGE_CLASS_PERSONAL_STR.getBytes())) {
-                    appendOctet(PduHeaders.MESSAGE_CLASS_PERSONAL);
-                } else if (Arrays.equals(messageClass,
-                        PduHeaders.MESSAGE_CLASS_INFORMATIONAL_STR.getBytes())) {
-                    appendOctet(PduHeaders.MESSAGE_CLASS_INFORMATIONAL);
-                } else {
-                    appendTextString(messageClass);
-                }
-                break;
-
-            case PduHeaders.EXPIRY:
-                long expiry = mPduHeader.getLongInteger(field);
-                if (-1 == expiry) {
-                    return PDU_COMPOSE_FIELD_NOT_SET;
-                }
-
-                appendOctet(field);
-
-                mStack.newbuf();
-                PositionMarker expiryStart = mStack.mark();
-
-                append(PduHeaders.VALUE_RELATIVE_TOKEN);
-                appendLongInteger(expiry);
-
-                int expiryLength = expiryStart.getLength();
-                mStack.pop();
-                appendValueLength(expiryLength);
-                mStack.copy();
-                break;
-
-            default:
-                return PDU_COMPOSE_FIELD_NOT_SUPPORTED;
-        }
-
-        return PDU_COMPOSE_SUCCESS;
-    }
-
-    /**
-     * Make ReadRec.Ind.
-     */
-    private int makeReadRecInd() {
-        if (mMessage == null) {
-            mMessage = new ByteArrayOutputStream();
-            mPosition = 0;
-        }
-
-        // X-Mms-Message-Type
-        appendOctet(PduHeaders.MESSAGE_TYPE);
-        appendOctet(PduHeaders.MESSAGE_TYPE_READ_REC_IND);
-
-        // X-Mms-MMS-Version
-        if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        // Message-ID
-        if (appendHeader(PduHeaders.MESSAGE_ID) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        // To
-        if (appendHeader(PduHeaders.TO) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        // From
-        if (appendHeader(PduHeaders.FROM) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        // Date Optional
-        appendHeader(PduHeaders.DATE);
-
-        // X-Mms-Read-Status
-        if (appendHeader(PduHeaders.READ_STATUS) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        // X-Mms-Applic-ID Optional(not support)
-        // X-Mms-Reply-Applic-ID Optional(not support)
-        // X-Mms-Aux-Applic-Info Optional(not support)
-
-        return PDU_COMPOSE_SUCCESS;
-    }
-
-    /**
-     * Make NotifyResp.Ind.
-     */
-    private int makeNotifyResp() {
-        if (mMessage == null) {
-            mMessage = new ByteArrayOutputStream();
-            mPosition = 0;
-        }
-
-        //    X-Mms-Message-Type
-        appendOctet(PduHeaders.MESSAGE_TYPE);
-        appendOctet(PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND);
-
-        // X-Mms-Transaction-ID
-        if (appendHeader(PduHeaders.TRANSACTION_ID) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        // X-Mms-MMS-Version
-        if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        //  X-Mms-Status
-        if (appendHeader(PduHeaders.STATUS) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        // X-Mms-Report-Allowed Optional (not support)
-        return PDU_COMPOSE_SUCCESS;
-    }
-
-    /**
-     * Make Acknowledge.Ind.
-     */
-    private int makeAckInd() {
-        if (mMessage == null) {
-            mMessage = new ByteArrayOutputStream();
-            mPosition = 0;
-        }
-
-        //    X-Mms-Message-Type
-        appendOctet(PduHeaders.MESSAGE_TYPE);
-        appendOctet(PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND);
-
-        // X-Mms-Transaction-ID
-        if (appendHeader(PduHeaders.TRANSACTION_ID) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        //     X-Mms-MMS-Version
-        if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        // X-Mms-Report-Allowed Optional
-        appendHeader(PduHeaders.REPORT_ALLOWED);
-
-        return PDU_COMPOSE_SUCCESS;
-    }
-
-    /**
-     * Make Send.req.
-     */
-    private int makeSendReqPdu() {
-        if (mMessage == null) {
-            mMessage = new ByteArrayOutputStream();
-            mPosition = 0;
-        }
-
-        // X-Mms-Message-Type
-        appendOctet(PduHeaders.MESSAGE_TYPE);
-        appendOctet(PduHeaders.MESSAGE_TYPE_SEND_REQ);
-
-        // X-Mms-Transaction-ID
-        appendOctet(PduHeaders.TRANSACTION_ID);
-
-        byte[] trid = mPduHeader.getTextString(PduHeaders.TRANSACTION_ID);
-        if (trid == null) {
-            // Transaction-ID should be set(by Transaction) before make().
-            throw new IllegalArgumentException("Transaction-ID is null.");
-        }
-        appendTextString(trid);
-
-        //  X-Mms-MMS-Version
-        if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        // Date Date-value Optional.
-        appendHeader(PduHeaders.DATE);
-
-        // From
-        if (appendHeader(PduHeaders.FROM) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        boolean recipient = false;
-
-        // To
-        if (appendHeader(PduHeaders.TO) != PDU_COMPOSE_CONTENT_ERROR) {
-            recipient = true;
-        }
-
-        // Cc
-        if (appendHeader(PduHeaders.CC) != PDU_COMPOSE_CONTENT_ERROR) {
-            recipient = true;
-        }
-
-        // Bcc
-        if (appendHeader(PduHeaders.BCC) != PDU_COMPOSE_CONTENT_ERROR) {
-            recipient = true;
-        }
-
-        // Need at least one of "cc", "bcc" and "to".
-        if (false == recipient) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        // Subject Optional
-        appendHeader(PduHeaders.SUBJECT);
-
-        // X-Mms-Message-Class Optional
-        // Message-class-value = Class-identifier | Token-text
-        appendHeader(PduHeaders.MESSAGE_CLASS);
-
-        // X-Mms-Expiry Optional
-        appendHeader(PduHeaders.EXPIRY);
-
-        // X-Mms-Priority Optional
-        appendHeader(PduHeaders.PRIORITY);
-
-        // X-Mms-Delivery-Report Optional
-        appendHeader(PduHeaders.DELIVERY_REPORT);
-
-        // X-Mms-Read-Report Optional
-        appendHeader(PduHeaders.READ_REPORT);
-
-        //    Content-Type
-        appendOctet(PduHeaders.CONTENT_TYPE);
-
-        //  Message body
-        return makeMessageBody();
-    }
-
-    /**
-     * Make message body.
-     */
-    private int makeMessageBody() {
-        // 1. add body informations
-        mStack.newbuf();  // Switching buffer because we need to
-
-        PositionMarker ctStart = mStack.mark();
-
-        // This contentTypeIdentifier should be used for type of attachment...
-        String contentType = new String(mPduHeader.getTextString(PduHeaders.CONTENT_TYPE));
-        Integer contentTypeIdentifier = mContentTypeMap.get(contentType);
-        if (contentTypeIdentifier == null) {
-            // content type is mandatory
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        appendShortInteger(contentTypeIdentifier.intValue());
-
-        // content-type parameter: start
-        PduBody body = ((SendReq) mPdu).getBody();
-        if (null == body || body.getPartsNum() == 0) {
-            // empty message
-            appendUintvarInteger(0);
-            mStack.pop();
-            mStack.copy();
-            return PDU_COMPOSE_SUCCESS;
-        }
-
-        PduPart part;
-        try {
-            part = body.getPart(0);
-
-            byte[] start = part.getContentId();
-            if (start != null) {
-                appendOctet(PduPart.P_DEP_START);
-                if (('<' == start[0]) && ('>' == start[start.length - 1])) {
-                    appendTextString(start);
-                } else {
-                    appendTextString("<" + new String(start) + ">");
-                }
-            }
-
-            // content-type parameter: type
-            appendOctet(PduPart.P_CT_MR_TYPE);
-            appendTextString(part.getContentType());
-        }
-        catch (ArrayIndexOutOfBoundsException e){
-            e.printStackTrace();
-        }
-
-        int ctLength = ctStart.getLength();
-        mStack.pop();
-        appendValueLength(ctLength);
-        mStack.copy();
-
-        // 3. add content
-        int partNum = body.getPartsNum();
-        appendUintvarInteger(partNum);
-        for (int i = 0; i < partNum; i++) {
-            part = body.getPart(i);
-            mStack.newbuf();  // Leaving space for header lengh and data length
-            PositionMarker attachment = mStack.mark();
-
-            mStack.newbuf();  // Leaving space for Content-Type length
-            PositionMarker contentTypeBegin = mStack.mark();
-
-            byte[] partContentType = part.getContentType();
-
-            if (partContentType == null) {
-                // content type is mandatory
-                return PDU_COMPOSE_CONTENT_ERROR;
-            }
-
-            // content-type value
-            Integer partContentTypeIdentifier =
-                mContentTypeMap.get(new String(partContentType));
-            if (partContentTypeIdentifier == null) {
-                appendTextString(partContentType);
-            } else {
-                appendShortInteger(partContentTypeIdentifier.intValue());
-            }
-
-            /* Content-type parameter : name.
-             * The value of name, filename, content-location is the same.
-             * Just one of them is enough for this PDU.
-             */
-            byte[] name = part.getName();
-
-            if (null == name) {
-                name = part.getFilename();
-
-                if (null == name) {
-                    name = part.getContentLocation();
-
-                    if (null == name) {
-                        /* at lease one of name, filename, Content-location
-                         * should be available.
-                         */
-                        return PDU_COMPOSE_CONTENT_ERROR;
-                    }
-                }
-            }
-            appendOctet(PduPart.P_DEP_NAME);
-            appendTextString(name);
-
-            // content-type parameter : charset
-            int charset = part.getCharset();
-            if (charset != 0) {
-                appendOctet(PduPart.P_CHARSET);
-                appendShortInteger(charset);
-            }
-
-            int contentTypeLength = contentTypeBegin.getLength();
-            mStack.pop();
-            appendValueLength(contentTypeLength);
-            mStack.copy();
-
-            // content id
-            byte[] contentId = part.getContentId();
-
-            if (null != contentId) {
-                appendOctet(PduPart.P_CONTENT_ID);
-                if (('<' == contentId[0]) && ('>' == contentId[contentId.length - 1])) {
-                    appendQuotedString(contentId);
-                } else {
-                    appendQuotedString("<" + new String(contentId) + ">");
-                }
-            }
-
-            // content-location
-            byte[] contentLocation = part.getContentLocation();
-            if (null != contentLocation) {
-            	appendOctet(PduPart.P_CONTENT_LOCATION);
-            	appendTextString(contentLocation);
-            }
-
-            // content
-            int headerLength = attachment.getLength();
-
-            int dataLength = 0; // Just for safety...
-            byte[] partData = part.getData();
-
-            if (partData != null) {
-                arraycopy(partData, 0, partData.length);
-                dataLength = partData.length;
-            } else {
-                InputStream cr;
-                try {
-                    byte[] buffer = new byte[PDU_COMPOSER_BLOCK_SIZE];
-                    cr = mResolver.openInputStream(part.getDataUri());
-                    int len = 0;
-                    while ((len = cr.read(buffer)) != -1) {
-                        mMessage.write(buffer, 0, len);
-                        mPosition += len;
-                        dataLength += len;
-                    }
-                } catch (FileNotFoundException e) {
-                    return PDU_COMPOSE_CONTENT_ERROR;
-                } catch (IOException e) {
-                    return PDU_COMPOSE_CONTENT_ERROR;
-                } catch (RuntimeException e) {
-                    return PDU_COMPOSE_CONTENT_ERROR;
-                }
-            }
-
-            if (dataLength != (attachment.getLength() - headerLength)) {
-                throw new RuntimeException("BUG: Length sanity check failed");
-            }
-
-            mStack.pop();
-            appendUintvarInteger(headerLength);
-            appendUintvarInteger(dataLength);
-            mStack.copy();
-        }
-
-        return PDU_COMPOSE_SUCCESS;
-    }
-
-    /**
-     *  Record current message informations.
-     */
-    static private class LengthRecordNode {
-        ByteArrayOutputStream currentMessage = null;
-        public int currentPosition = 0;
-
-        public LengthRecordNode next = null;
-    }
-
-    /**
-     * Mark current message position and stact size.
-     */
-    private class PositionMarker {
-        private int c_pos;   // Current position
-        private int currentStackSize;  // Current stack size
-
-        int getLength() {
-            // If these assert fails, likely that you are finding the
-            // size of buffer that is deep in BufferStack you can only
-            // find the length of the buffer that is on top
-            if (currentStackSize != mStack.stackSize) {
-                throw new RuntimeException("BUG: Invalid call to getLength()");
-            }
-
-            return mPosition - c_pos;
-        }
-    }
-
-    /**
-     * This implementation can be OPTIMIZED to use only
-     * 2 buffers. This optimization involves changing BufferStack
-     * only... Its usage (interface) will not change.
-     */
-    private class BufferStack {
-        private LengthRecordNode stack = null;
-        private LengthRecordNode toCopy = null;
-
-        int stackSize = 0;
-
-        /**
-         *  Create a new message buffer and push it into the stack.
-         */
-        void newbuf() {
-            // You can't create a new buff when toCopy != null
-            // That is after calling pop() and before calling copy()
-            // If you do, it is a bug
-            if (toCopy != null) {
-                throw new RuntimeException("BUG: Invalid newbuf() before copy()");
-            }
-
-            LengthRecordNode temp = new LengthRecordNode();
-
-            temp.currentMessage = mMessage;
-            temp.currentPosition = mPosition;
-
-            temp.next = stack;
-            stack = temp;
-
-            stackSize = stackSize + 1;
-
-            mMessage = new ByteArrayOutputStream();
-            mPosition = 0;
-        }
-
-        /**
-         *  Pop the message before and record current message in the stack.
-         */
-        void pop() {
-            ByteArrayOutputStream currentMessage = mMessage;
-            int currentPosition = mPosition;
-
-            mMessage = stack.currentMessage;
-            mPosition = stack.currentPosition;
-
-            toCopy = stack;
-            // Re using the top element of the stack to avoid memory allocation
-
-            stack = stack.next;
-            stackSize = stackSize - 1;
-
-            toCopy.currentMessage = currentMessage;
-            toCopy.currentPosition = currentPosition;
-        }
-
-        /**
-         *  Append current message to the message before.
-         */
-        void copy() {
-            arraycopy(toCopy.currentMessage.toByteArray(), 0,
-                    toCopy.currentPosition);
-
-            toCopy = null;
-        }
-
-        /**
-         *  Mark current message position
-         */
-        PositionMarker mark() {
-            PositionMarker m = new PositionMarker();
-
-            m.c_pos = mPosition;
-            m.currentStackSize = stackSize;
-
-            return m;
-        }
-    }
-
-    /**
-     * Check address type.
-     *
-     * @param address address string without the postfix stinng type,
-     *        such as "/TYPE=PLMN", "/TYPE=IPv6" and "/TYPE=IPv4"
-     * @return PDU_PHONE_NUMBER_ADDRESS_TYPE if it is phone number,
-     *         PDU_EMAIL_ADDRESS_TYPE if it is email address,
-     *         PDU_IPV4_ADDRESS_TYPE if it is ipv4 address,
-     *         PDU_IPV6_ADDRESS_TYPE if it is ipv6 address,
-     *         PDU_UNKNOWN_ADDRESS_TYPE if it is unknown.
-     */
-    protected static int checkAddressType(String address) {
-        /**
-         * From OMA-TS-MMS-ENC-V1_3-20050927-C.pdf, section 8.
-         * address = ( e-mail / device-address / alphanum-shortcode / num-shortcode)
-         * e-mail = mailbox; to the definition of mailbox as described in
-         * section 3.4 of [RFC2822], but excluding the
-         * obsolete definitions as indicated by the "obs-" prefix.
-         * device-address = ( global-phone-number "/TYPE=PLMN" )
-         * / ( ipv4 "/TYPE=IPv4" ) / ( ipv6 "/TYPE=IPv6" )
-         * / ( escaped-value "/TYPE=" address-type )
-         *
-         * global-phone-number = ["+"] 1*( DIGIT / written-sep )
-         * written-sep =("-"/".")
-         *
-         * ipv4 = 1*3DIGIT 3( "." 1*3DIGIT ) ; IPv4 address value
-         *
-         * ipv6 = 4HEXDIG 7( ":" 4HEXDIG ) ; IPv6 address per RFC 2373
-         */
-
-        if (null == address) {
-            return PDU_UNKNOWN_ADDRESS_TYPE;
-        }
-
-        if (address.matches(REGEXP_IPV4_ADDRESS_TYPE)) {
-            // Ipv4 address.
-            return PDU_IPV4_ADDRESS_TYPE;
-        }else if (address.matches(REGEXP_PHONE_NUMBER_ADDRESS_TYPE)) {
-            // Phone number.
-            return PDU_PHONE_NUMBER_ADDRESS_TYPE;
-        } else if (address.matches(REGEXP_EMAIL_ADDRESS_TYPE)) {
-            // Email address.
-            return PDU_EMAIL_ADDRESS_TYPE;
-        } else if (address.matches(REGEXP_IPV6_ADDRESS_TYPE)) {
-            // Ipv6 address.
-            return PDU_IPV6_ADDRESS_TYPE;
-        } else {
-            // Unknown address.
-            return PDU_UNKNOWN_ADDRESS_TYPE;
-        }
-    }
-}
diff --git a/core/java/com/google/android/mms/pdu/PduContentTypes.java b/core/java/com/google/android/mms/pdu/PduContentTypes.java
deleted file mode 100644
index 7799e0e..0000000
--- a/core/java/com/google/android/mms/pdu/PduContentTypes.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-public class PduContentTypes {
-    /**
-     * All content types. From:
-     * http://www.openmobilealliance.org/tech/omna/omna-wsp-content-type.htm
-     */
-    static final String[] contentTypes = {
-        "*/*",                                        /* 0x00 */
-        "text/*",                                     /* 0x01 */
-        "text/html",                                  /* 0x02 */
-        "text/plain",                                 /* 0x03 */
-        "text/x-hdml",                                /* 0x04 */
-        "text/x-ttml",                                /* 0x05 */
-        "text/x-vCalendar",                           /* 0x06 */
-        "text/x-vCard",                               /* 0x07 */
-        "text/vnd.wap.wml",                           /* 0x08 */
-        "text/vnd.wap.wmlscript",                     /* 0x09 */
-        "text/vnd.wap.wta-event",                     /* 0x0A */
-        "multipart/*",                                /* 0x0B */
-        "multipart/mixed",                            /* 0x0C */
-        "multipart/form-data",                        /* 0x0D */
-        "multipart/byterantes",                       /* 0x0E */
-        "multipart/alternative",                      /* 0x0F */
-        "application/*",                              /* 0x10 */
-        "application/java-vm",                        /* 0x11 */
-        "application/x-www-form-urlencoded",          /* 0x12 */
-        "application/x-hdmlc",                        /* 0x13 */
-        "application/vnd.wap.wmlc",                   /* 0x14 */
-        "application/vnd.wap.wmlscriptc",             /* 0x15 */
-        "application/vnd.wap.wta-eventc",             /* 0x16 */
-        "application/vnd.wap.uaprof",                 /* 0x17 */
-        "application/vnd.wap.wtls-ca-certificate",    /* 0x18 */
-        "application/vnd.wap.wtls-user-certificate",  /* 0x19 */
-        "application/x-x509-ca-cert",                 /* 0x1A */
-        "application/x-x509-user-cert",               /* 0x1B */
-        "image/*",                                    /* 0x1C */
-        "image/gif",                                  /* 0x1D */
-        "image/jpeg",                                 /* 0x1E */
-        "image/tiff",                                 /* 0x1F */
-        "image/png",                                  /* 0x20 */
-        "image/vnd.wap.wbmp",                         /* 0x21 */
-        "application/vnd.wap.multipart.*",            /* 0x22 */
-        "application/vnd.wap.multipart.mixed",        /* 0x23 */
-        "application/vnd.wap.multipart.form-data",    /* 0x24 */
-        "application/vnd.wap.multipart.byteranges",   /* 0x25 */
-        "application/vnd.wap.multipart.alternative",  /* 0x26 */
-        "application/xml",                            /* 0x27 */
-        "text/xml",                                   /* 0x28 */
-        "application/vnd.wap.wbxml",                  /* 0x29 */
-        "application/x-x968-cross-cert",              /* 0x2A */
-        "application/x-x968-ca-cert",                 /* 0x2B */
-        "application/x-x968-user-cert",               /* 0x2C */
-        "text/vnd.wap.si",                            /* 0x2D */
-        "application/vnd.wap.sic",                    /* 0x2E */
-        "text/vnd.wap.sl",                            /* 0x2F */
-        "application/vnd.wap.slc",                    /* 0x30 */
-        "text/vnd.wap.co",                            /* 0x31 */
-        "application/vnd.wap.coc",                    /* 0x32 */
-        "application/vnd.wap.multipart.related",      /* 0x33 */
-        "application/vnd.wap.sia",                    /* 0x34 */
-        "text/vnd.wap.connectivity-xml",              /* 0x35 */
-        "application/vnd.wap.connectivity-wbxml",     /* 0x36 */
-        "application/pkcs7-mime",                     /* 0x37 */
-        "application/vnd.wap.hashed-certificate",     /* 0x38 */
-        "application/vnd.wap.signed-certificate",     /* 0x39 */
-        "application/vnd.wap.cert-response",          /* 0x3A */
-        "application/xhtml+xml",                      /* 0x3B */
-        "application/wml+xml",                        /* 0x3C */
-        "text/css",                                   /* 0x3D */
-        "application/vnd.wap.mms-message",            /* 0x3E */
-        "application/vnd.wap.rollover-certificate",   /* 0x3F */
-        "application/vnd.wap.locc+wbxml",             /* 0x40 */
-        "application/vnd.wap.loc+xml",                /* 0x41 */
-        "application/vnd.syncml.dm+wbxml",            /* 0x42 */
-        "application/vnd.syncml.dm+xml",              /* 0x43 */
-        "application/vnd.syncml.notification",        /* 0x44 */
-        "application/vnd.wap.xhtml+xml",              /* 0x45 */
-        "application/vnd.wv.csp.cir",                 /* 0x46 */
-        "application/vnd.oma.dd+xml",                 /* 0x47 */
-        "application/vnd.oma.drm.message",            /* 0x48 */
-        "application/vnd.oma.drm.content",            /* 0x49 */
-        "application/vnd.oma.drm.rights+xml",         /* 0x4A */
-        "application/vnd.oma.drm.rights+wbxml",       /* 0x4B */
-        "application/vnd.wv.csp+xml",                 /* 0x4C */
-        "application/vnd.wv.csp+wbxml",               /* 0x4D */
-        "application/vnd.syncml.ds.notification",     /* 0x4E */
-        "audio/*",                                    /* 0x4F */
-        "video/*",                                    /* 0x50 */
-        "application/vnd.oma.dd2+xml",                /* 0x51 */
-        "application/mikey"                           /* 0x52 */
-    };
-}
diff --git a/core/java/com/google/android/mms/pdu/PduHeaders.java b/core/java/com/google/android/mms/pdu/PduHeaders.java
deleted file mode 100644
index 4313815..0000000
--- a/core/java/com/google/android/mms/pdu/PduHeaders.java
+++ /dev/null
@@ -1,721 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-public class PduHeaders {
-    /**
-     * All pdu header fields.
-     */
-    public static final int BCC                             = 0x81;
-    public static final int CC                              = 0x82;
-    public static final int CONTENT_LOCATION                = 0x83;
-    public static final int CONTENT_TYPE                    = 0x84;
-    public static final int DATE                            = 0x85;
-    public static final int DELIVERY_REPORT                 = 0x86;
-    public static final int DELIVERY_TIME                   = 0x87;
-    public static final int EXPIRY                          = 0x88;
-    public static final int FROM                            = 0x89;
-    public static final int MESSAGE_CLASS                   = 0x8A;
-    public static final int MESSAGE_ID                      = 0x8B;
-    public static final int MESSAGE_TYPE                    = 0x8C;
-    public static final int MMS_VERSION                     = 0x8D;
-    public static final int MESSAGE_SIZE                    = 0x8E;
-    public static final int PRIORITY                        = 0x8F;
-
-    public static final int READ_REPLY                      = 0x90;
-    public static final int READ_REPORT                     = 0x90;
-    public static final int REPORT_ALLOWED                  = 0x91;
-    public static final int RESPONSE_STATUS                 = 0x92;
-    public static final int RESPONSE_TEXT                   = 0x93;
-    public static final int SENDER_VISIBILITY               = 0x94;
-    public static final int STATUS                          = 0x95;
-    public static final int SUBJECT                         = 0x96;
-    public static final int TO                              = 0x97;
-    public static final int TRANSACTION_ID                  = 0x98;
-    public static final int RETRIEVE_STATUS                 = 0x99;
-    public static final int RETRIEVE_TEXT                   = 0x9A;
-    public static final int READ_STATUS                     = 0x9B;
-    public static final int REPLY_CHARGING                  = 0x9C;
-    public static final int REPLY_CHARGING_DEADLINE         = 0x9D;
-    public static final int REPLY_CHARGING_ID               = 0x9E;
-    public static final int REPLY_CHARGING_SIZE             = 0x9F;
-
-    public static final int PREVIOUSLY_SENT_BY              = 0xA0;
-    public static final int PREVIOUSLY_SENT_DATE            = 0xA1;
-    public static final int STORE                           = 0xA2;
-    public static final int MM_STATE                        = 0xA3;
-    public static final int MM_FLAGS                        = 0xA4;
-    public static final int STORE_STATUS                    = 0xA5;
-    public static final int STORE_STATUS_TEXT               = 0xA6;
-    public static final int STORED                          = 0xA7;
-    public static final int ATTRIBUTES                      = 0xA8;
-    public static final int TOTALS                          = 0xA9;
-    public static final int MBOX_TOTALS                     = 0xAA;
-    public static final int QUOTAS                          = 0xAB;
-    public static final int MBOX_QUOTAS                     = 0xAC;
-    public static final int MESSAGE_COUNT                   = 0xAD;
-    public static final int CONTENT                         = 0xAE;
-    public static final int START                           = 0xAF;
-
-    public static final int ADDITIONAL_HEADERS              = 0xB0;
-    public static final int DISTRIBUTION_INDICATOR          = 0xB1;
-    public static final int ELEMENT_DESCRIPTOR              = 0xB2;
-    public static final int LIMIT                           = 0xB3;
-    public static final int RECOMMENDED_RETRIEVAL_MODE      = 0xB4;
-    public static final int RECOMMENDED_RETRIEVAL_MODE_TEXT = 0xB5;
-    public static final int STATUS_TEXT                     = 0xB6;
-    public static final int APPLIC_ID                       = 0xB7;
-    public static final int REPLY_APPLIC_ID                 = 0xB8;
-    public static final int AUX_APPLIC_ID                   = 0xB9;
-    public static final int CONTENT_CLASS                   = 0xBA;
-    public static final int DRM_CONTENT                     = 0xBB;
-    public static final int ADAPTATION_ALLOWED              = 0xBC;
-    public static final int REPLACE_ID                      = 0xBD;
-    public static final int CANCEL_ID                       = 0xBE;
-    public static final int CANCEL_STATUS                   = 0xBF;
-
-    /**
-     * X-Mms-Message-Type field types.
-     */
-    public static final int MESSAGE_TYPE_SEND_REQ           = 0x80;
-    public static final int MESSAGE_TYPE_SEND_CONF          = 0x81;
-    public static final int MESSAGE_TYPE_NOTIFICATION_IND   = 0x82;
-    public static final int MESSAGE_TYPE_NOTIFYRESP_IND     = 0x83;
-    public static final int MESSAGE_TYPE_RETRIEVE_CONF      = 0x84;
-    public static final int MESSAGE_TYPE_ACKNOWLEDGE_IND    = 0x85;
-    public static final int MESSAGE_TYPE_DELIVERY_IND       = 0x86;
-    public static final int MESSAGE_TYPE_READ_REC_IND       = 0x87;
-    public static final int MESSAGE_TYPE_READ_ORIG_IND      = 0x88;
-    public static final int MESSAGE_TYPE_FORWARD_REQ        = 0x89;
-    public static final int MESSAGE_TYPE_FORWARD_CONF       = 0x8A;
-    public static final int MESSAGE_TYPE_MBOX_STORE_REQ     = 0x8B;
-    public static final int MESSAGE_TYPE_MBOX_STORE_CONF    = 0x8C;
-    public static final int MESSAGE_TYPE_MBOX_VIEW_REQ      = 0x8D;
-    public static final int MESSAGE_TYPE_MBOX_VIEW_CONF     = 0x8E;
-    public static final int MESSAGE_TYPE_MBOX_UPLOAD_REQ    = 0x8F;
-    public static final int MESSAGE_TYPE_MBOX_UPLOAD_CONF   = 0x90;
-    public static final int MESSAGE_TYPE_MBOX_DELETE_REQ    = 0x91;
-    public static final int MESSAGE_TYPE_MBOX_DELETE_CONF   = 0x92;
-    public static final int MESSAGE_TYPE_MBOX_DESCR         = 0x93;
-    public static final int MESSAGE_TYPE_DELETE_REQ         = 0x94;
-    public static final int MESSAGE_TYPE_DELETE_CONF        = 0x95;
-    public static final int MESSAGE_TYPE_CANCEL_REQ         = 0x96;
-    public static final int MESSAGE_TYPE_CANCEL_CONF        = 0x97;
-
-    /**
-     *  X-Mms-Delivery-Report |
-     *  X-Mms-Read-Report |
-     *  X-Mms-Report-Allowed |
-     *  X-Mms-Sender-Visibility |
-     *  X-Mms-Store |
-     *  X-Mms-Stored |
-     *  X-Mms-Totals |
-     *  X-Mms-Quotas |
-     *  X-Mms-Distribution-Indicator |
-     *  X-Mms-DRM-Content |
-     *  X-Mms-Adaptation-Allowed |
-     *  field types.
-     */
-    public static final int VALUE_YES                       = 0x80;
-    public static final int VALUE_NO                        = 0x81;
-
-    /**
-     *  Delivery-Time |
-     *  Expiry and Reply-Charging-Deadline |
-     *  field type components.
-     */
-    public static final int VALUE_ABSOLUTE_TOKEN            = 0x80;
-    public static final int VALUE_RELATIVE_TOKEN            = 0x81;
-
-    /**
-     * X-Mms-MMS-Version field types.
-     */
-    public static final int MMS_VERSION_1_3                 = ((1 << 4) | 3);
-    public static final int MMS_VERSION_1_2                 = ((1 << 4) | 2);
-    public static final int MMS_VERSION_1_1                 = ((1 << 4) | 1);
-    public static final int MMS_VERSION_1_0                 = ((1 << 4) | 0);
-
-    // Current version is 1.2.
-    public static final int CURRENT_MMS_VERSION             = MMS_VERSION_1_2;
-
-    /**
-     *  From field type components.
-     */
-    public static final int FROM_ADDRESS_PRESENT_TOKEN      = 0x80;
-    public static final int FROM_INSERT_ADDRESS_TOKEN       = 0x81;
-
-    public static final String FROM_ADDRESS_PRESENT_TOKEN_STR = "address-present-token";
-    public static final String FROM_INSERT_ADDRESS_TOKEN_STR = "insert-address-token";
-
-    /**
-     *  X-Mms-Status Field.
-     */
-    public static final int STATUS_EXPIRED                  = 0x80;
-    public static final int STATUS_RETRIEVED                = 0x81;
-    public static final int STATUS_REJECTED                 = 0x82;
-    public static final int STATUS_DEFERRED                 = 0x83;
-    public static final int STATUS_UNRECOGNIZED             = 0x84;
-    public static final int STATUS_INDETERMINATE            = 0x85;
-    public static final int STATUS_FORWARDED                = 0x86;
-    public static final int STATUS_UNREACHABLE              = 0x87;
-
-    /**
-     *  MM-Flags field type components.
-     */
-    public static final int MM_FLAGS_ADD_TOKEN              = 0x80;
-    public static final int MM_FLAGS_REMOVE_TOKEN           = 0x81;
-    public static final int MM_FLAGS_FILTER_TOKEN           = 0x82;
-
-    /**
-     *  X-Mms-Message-Class field types.
-     */
-    public static final int MESSAGE_CLASS_PERSONAL          = 0x80;
-    public static final int MESSAGE_CLASS_ADVERTISEMENT     = 0x81;
-    public static final int MESSAGE_CLASS_INFORMATIONAL     = 0x82;
-    public static final int MESSAGE_CLASS_AUTO              = 0x83;
-
-    public static final String MESSAGE_CLASS_PERSONAL_STR = "personal";
-    public static final String MESSAGE_CLASS_ADVERTISEMENT_STR = "advertisement";
-    public static final String MESSAGE_CLASS_INFORMATIONAL_STR = "informational";
-    public static final String MESSAGE_CLASS_AUTO_STR = "auto";
-
-    /**
-     *  X-Mms-Priority field types.
-     */
-    public static final int PRIORITY_LOW                    = 0x80;
-    public static final int PRIORITY_NORMAL                 = 0x81;
-    public static final int PRIORITY_HIGH                   = 0x82;
-
-    /**
-     *  X-Mms-Response-Status field types.
-     */
-    public static final int RESPONSE_STATUS_OK                   = 0x80;
-    public static final int RESPONSE_STATUS_ERROR_UNSPECIFIED    = 0x81;
-    public static final int RESPONSE_STATUS_ERROR_SERVICE_DENIED = 0x82;
-
-    public static final int RESPONSE_STATUS_ERROR_MESSAGE_FORMAT_CORRUPT     = 0x83;
-    public static final int RESPONSE_STATUS_ERROR_SENDING_ADDRESS_UNRESOLVED = 0x84;
-
-    public static final int RESPONSE_STATUS_ERROR_MESSAGE_NOT_FOUND    = 0x85;
-    public static final int RESPONSE_STATUS_ERROR_NETWORK_PROBLEM      = 0x86;
-    public static final int RESPONSE_STATUS_ERROR_CONTENT_NOT_ACCEPTED = 0x87;
-    public static final int RESPONSE_STATUS_ERROR_UNSUPPORTED_MESSAGE  = 0x88;
-    public static final int RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE    = 0xC0;
-
-    public static final int RESPONSE_STATUS_ERROR_TRANSIENT_SENDNG_ADDRESS_UNRESOLVED = 0xC1;
-    public static final int RESPONSE_STATUS_ERROR_TRANSIENT_MESSAGE_NOT_FOUND         = 0xC2;
-    public static final int RESPONSE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM           = 0xC3;
-    public static final int RESPONSE_STATUS_ERROR_TRANSIENT_PARTIAL_SUCCESS           = 0xC4;
-
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_FAILURE                             = 0xE0;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_SERVICE_DENIED                      = 0xE1;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_MESSAGE_FORMAT_CORRUPT              = 0xE2;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_SENDING_ADDRESS_UNRESOLVED          = 0xE3;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_MESSAGE_NOT_FOUND                   = 0xE4;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_CONTENT_NOT_ACCEPTED                = 0xE5;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_LIMITATIONS_NOT_MET  = 0xE6;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_REQUEST_NOT_ACCEPTED = 0xE6;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_FORWARDING_DENIED    = 0xE8;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_NOT_SUPPORTED        = 0xE9;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_ADDRESS_HIDING_NOT_SUPPORTED        = 0xEA;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_LACK_OF_PREPAID                     = 0xEB;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_END                                 = 0xFF;
-
-    /**
-     *  X-Mms-Retrieve-Status field types.
-     */
-    public static final int RETRIEVE_STATUS_OK                                  = 0x80;
-    public static final int RETRIEVE_STATUS_ERROR_TRANSIENT_FAILURE             = 0xC0;
-    public static final int RETRIEVE_STATUS_ERROR_TRANSIENT_MESSAGE_NOT_FOUND   = 0xC1;
-    public static final int RETRIEVE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM     = 0xC2;
-    public static final int RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE             = 0xE0;
-    public static final int RETRIEVE_STATUS_ERROR_PERMANENT_SERVICE_DENIED      = 0xE1;
-    public static final int RETRIEVE_STATUS_ERROR_PERMANENT_MESSAGE_NOT_FOUND   = 0xE2;
-    public static final int RETRIEVE_STATUS_ERROR_PERMANENT_CONTENT_UNSUPPORTED = 0xE3;
-    public static final int RETRIEVE_STATUS_ERROR_END                           = 0xFF;
-
-    /**
-     *  X-Mms-Sender-Visibility field types.
-     */
-    public static final int SENDER_VISIBILITY_HIDE          = 0x80;
-    public static final int SENDER_VISIBILITY_SHOW          = 0x81;
-
-    /**
-     *  X-Mms-Read-Status field types.
-     */
-    public static final int READ_STATUS_READ                        = 0x80;
-    public static final int READ_STATUS__DELETED_WITHOUT_BEING_READ = 0x81;
-
-    /**
-     *  X-Mms-Cancel-Status field types.
-     */
-    public static final int CANCEL_STATUS_REQUEST_SUCCESSFULLY_RECEIVED = 0x80;
-    public static final int CANCEL_STATUS_REQUEST_CORRUPTED             = 0x81;
-
-    /**
-     *  X-Mms-Reply-Charging field types.
-     */
-    public static final int REPLY_CHARGING_REQUESTED           = 0x80;
-    public static final int REPLY_CHARGING_REQUESTED_TEXT_ONLY = 0x81;
-    public static final int REPLY_CHARGING_ACCEPTED            = 0x82;
-    public static final int REPLY_CHARGING_ACCEPTED_TEXT_ONLY  = 0x83;
-
-    /**
-     *  X-Mms-MM-State field types.
-     */
-    public static final int MM_STATE_DRAFT                  = 0x80;
-    public static final int MM_STATE_SENT                   = 0x81;
-    public static final int MM_STATE_NEW                    = 0x82;
-    public static final int MM_STATE_RETRIEVED              = 0x83;
-    public static final int MM_STATE_FORWARDED              = 0x84;
-
-    /**
-     * X-Mms-Recommended-Retrieval-Mode field types.
-     */
-    public static final int RECOMMENDED_RETRIEVAL_MODE_MANUAL = 0x80;
-
-    /**
-     *  X-Mms-Content-Class field types.
-     */
-    public static final int CONTENT_CLASS_TEXT              = 0x80;
-    public static final int CONTENT_CLASS_IMAGE_BASIC       = 0x81;
-    public static final int CONTENT_CLASS_IMAGE_RICH        = 0x82;
-    public static final int CONTENT_CLASS_VIDEO_BASIC       = 0x83;
-    public static final int CONTENT_CLASS_VIDEO_RICH        = 0x84;
-    public static final int CONTENT_CLASS_MEGAPIXEL         = 0x85;
-    public static final int CONTENT_CLASS_CONTENT_BASIC     = 0x86;
-    public static final int CONTENT_CLASS_CONTENT_RICH      = 0x87;
-
-    /**
-     *  X-Mms-Store-Status field types.
-     */
-    public static final int STORE_STATUS_SUCCESS                                = 0x80;
-    public static final int STORE_STATUS_ERROR_TRANSIENT_FAILURE                = 0xC0;
-    public static final int STORE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM        = 0xC1;
-    public static final int STORE_STATUS_ERROR_PERMANENT_FAILURE                = 0xE0;
-    public static final int STORE_STATUS_ERROR_PERMANENT_SERVICE_DENIED         = 0xE1;
-    public static final int STORE_STATUS_ERROR_PERMANENT_MESSAGE_FORMAT_CORRUPT = 0xE2;
-    public static final int STORE_STATUS_ERROR_PERMANENT_MESSAGE_NOT_FOUND      = 0xE3;
-    public static final int STORE_STATUS_ERROR_PERMANENT_MMBOX_FULL             = 0xE4;
-    public static final int STORE_STATUS_ERROR_END                              = 0xFF;
-
-    /**
-     * The map contains the value of all headers.
-     */
-    private HashMap<Integer, Object> mHeaderMap = null;
-
-    /**
-     * Constructor of PduHeaders.
-     */
-    public PduHeaders() {
-        mHeaderMap = new HashMap<Integer, Object>();
-    }
-
-    /**
-     * Get octet value by header field.
-     *
-     * @param field the field
-     * @return the octet value of the pdu header
-     *          with specified header field. Return 0 if
-     *          the value is not set.
-     */
-    protected int getOctet(int field) {
-        Integer octet = (Integer) mHeaderMap.get(field);
-        if (null == octet) {
-            return 0;
-        }
-
-        return octet;
-    }
-
-    /**
-     * Set octet value to pdu header by header field.
-     *
-     * @param value the value
-     * @param field the field
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    protected void setOctet(int value, int field)
-            throws InvalidHeaderValueException{
-        /**
-         * Check whether this field can be set for specific
-         * header and check validity of the field.
-         */
-        switch (field) {
-            case REPORT_ALLOWED:
-            case ADAPTATION_ALLOWED:
-            case DELIVERY_REPORT:
-            case DRM_CONTENT:
-            case DISTRIBUTION_INDICATOR:
-            case QUOTAS:
-            case READ_REPORT:
-            case STORE:
-            case STORED:
-            case TOTALS:
-            case SENDER_VISIBILITY:
-                if ((VALUE_YES != value) && (VALUE_NO != value)) {
-                    // Invalid value.
-                    throw new InvalidHeaderValueException("Invalid Octet value!");
-                }
-                break;
-            case READ_STATUS:
-                if ((READ_STATUS_READ != value) &&
-                        (READ_STATUS__DELETED_WITHOUT_BEING_READ != value)) {
-                    // Invalid value.
-                    throw new InvalidHeaderValueException("Invalid Octet value!");
-                }
-                break;
-            case CANCEL_STATUS:
-                if ((CANCEL_STATUS_REQUEST_SUCCESSFULLY_RECEIVED != value) &&
-                        (CANCEL_STATUS_REQUEST_CORRUPTED != value)) {
-                    // Invalid value.
-                    throw new InvalidHeaderValueException("Invalid Octet value!");
-                }
-                break;
-            case PRIORITY:
-                if ((value < PRIORITY_LOW) || (value > PRIORITY_HIGH)) {
-                    // Invalid value.
-                    throw new InvalidHeaderValueException("Invalid Octet value!");
-                }
-                break;
-            case STATUS:
-                if ((value < STATUS_EXPIRED) || (value > STATUS_UNREACHABLE)) {
-                    // Invalid value.
-                    throw new InvalidHeaderValueException("Invalid Octet value!");
-                }
-                break;
-            case REPLY_CHARGING:
-                if ((value < REPLY_CHARGING_REQUESTED)
-                        || (value > REPLY_CHARGING_ACCEPTED_TEXT_ONLY)) {
-                    // Invalid value.
-                    throw new InvalidHeaderValueException("Invalid Octet value!");
-                }
-                break;
-            case MM_STATE:
-                if ((value < MM_STATE_DRAFT) || (value > MM_STATE_FORWARDED)) {
-                    // Invalid value.
-                    throw new InvalidHeaderValueException("Invalid Octet value!");
-                }
-                break;
-            case RECOMMENDED_RETRIEVAL_MODE:
-                if (RECOMMENDED_RETRIEVAL_MODE_MANUAL != value) {
-                    // Invalid value.
-                    throw new InvalidHeaderValueException("Invalid Octet value!");
-                }
-                break;
-            case CONTENT_CLASS:
-                if ((value < CONTENT_CLASS_TEXT)
-                        || (value > CONTENT_CLASS_CONTENT_RICH)) {
-                    // Invalid value.
-                    throw new InvalidHeaderValueException("Invalid Octet value!");
-                }
-                break;
-            case RETRIEVE_STATUS:
-                // According to oma-ts-mms-enc-v1_3, section 7.3.50, we modify the invalid value.
-                if ((value > RETRIEVE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM) &&
-                        (value < RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE)) {
-                    value = RETRIEVE_STATUS_ERROR_TRANSIENT_FAILURE;
-                } else if ((value > RETRIEVE_STATUS_ERROR_PERMANENT_CONTENT_UNSUPPORTED) &&
-                        (value <= RETRIEVE_STATUS_ERROR_END)) {
-                    value = RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE;
-                } else if ((value < RETRIEVE_STATUS_OK) ||
-                        ((value > RETRIEVE_STATUS_OK) &&
-                                (value < RETRIEVE_STATUS_ERROR_TRANSIENT_FAILURE)) ||
-                                (value > RETRIEVE_STATUS_ERROR_END)) {
-                    value = RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE;
-                }
-                break;
-            case STORE_STATUS:
-                // According to oma-ts-mms-enc-v1_3, section 7.3.58, we modify the invalid value.
-                if ((value > STORE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM) &&
-                        (value < STORE_STATUS_ERROR_PERMANENT_FAILURE)) {
-                    value = STORE_STATUS_ERROR_TRANSIENT_FAILURE;
-                } else if ((value > STORE_STATUS_ERROR_PERMANENT_MMBOX_FULL) &&
-                        (value <= STORE_STATUS_ERROR_END)) {
-                    value = STORE_STATUS_ERROR_PERMANENT_FAILURE;
-                } else if ((value < STORE_STATUS_SUCCESS) ||
-                        ((value > STORE_STATUS_SUCCESS) &&
-                                (value < STORE_STATUS_ERROR_TRANSIENT_FAILURE)) ||
-                                (value > STORE_STATUS_ERROR_END)) {
-                    value = STORE_STATUS_ERROR_PERMANENT_FAILURE;
-                }
-                break;
-            case RESPONSE_STATUS:
-                // According to oma-ts-mms-enc-v1_3, section 7.3.48, we modify the invalid value.
-                if ((value > RESPONSE_STATUS_ERROR_TRANSIENT_PARTIAL_SUCCESS) &&
-                        (value < RESPONSE_STATUS_ERROR_PERMANENT_FAILURE)) {
-                    value = RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE;
-                } else if (((value > RESPONSE_STATUS_ERROR_PERMANENT_LACK_OF_PREPAID) &&
-                        (value <= RESPONSE_STATUS_ERROR_PERMANENT_END)) ||
-                        (value < RESPONSE_STATUS_OK) ||
-                        ((value > RESPONSE_STATUS_ERROR_UNSUPPORTED_MESSAGE) &&
-                                (value < RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE)) ||
-                                (value > RESPONSE_STATUS_ERROR_PERMANENT_END)) {
-                    value = RESPONSE_STATUS_ERROR_PERMANENT_FAILURE;
-                }
-                break;
-            case MMS_VERSION:
-                if ((value < MMS_VERSION_1_0)|| (value > MMS_VERSION_1_3)) {
-                    value = CURRENT_MMS_VERSION; // Current version is the default value.
-                }
-                break;
-            case MESSAGE_TYPE:
-                if ((value < MESSAGE_TYPE_SEND_REQ) || (value > MESSAGE_TYPE_CANCEL_CONF)) {
-                    // Invalid value.
-                    throw new InvalidHeaderValueException("Invalid Octet value!");
-                }
-                break;
-            default:
-                // This header value should not be Octect.
-                throw new RuntimeException("Invalid header field!");
-        }
-        mHeaderMap.put(field, value);
-    }
-
-    /**
-     * Get TextString value by header field.
-     *
-     * @param field the field
-     * @return the TextString value of the pdu header
-     *          with specified header field
-     */
-    protected byte[] getTextString(int field) {
-        return (byte[]) mHeaderMap.get(field);
-    }
-
-    /**
-     * Set TextString value to pdu header by header field.
-     *
-     * @param value the value
-     * @param field the field
-     * @return the TextString value of the pdu header
-     *          with specified header field
-     * @throws NullPointerException if the value is null.
-     */
-    protected void setTextString(byte[] value, int field) {
-        /**
-         * Check whether this field can be set for specific
-         * header and check validity of the field.
-         */
-        if (null == value) {
-            throw new NullPointerException();
-        }
-
-        switch (field) {
-            case TRANSACTION_ID:
-            case REPLY_CHARGING_ID:
-            case AUX_APPLIC_ID:
-            case APPLIC_ID:
-            case REPLY_APPLIC_ID:
-            case MESSAGE_ID:
-            case REPLACE_ID:
-            case CANCEL_ID:
-            case CONTENT_LOCATION:
-            case MESSAGE_CLASS:
-            case CONTENT_TYPE:
-                break;
-            default:
-                // This header value should not be Text-String.
-                throw new RuntimeException("Invalid header field!");
-        }
-        mHeaderMap.put(field, value);
-    }
-
-    /**
-     * Get EncodedStringValue value by header field.
-     *
-     * @param field the field
-     * @return the EncodedStringValue value of the pdu header
-     *          with specified header field
-     */
-    protected EncodedStringValue getEncodedStringValue(int field) {
-        return (EncodedStringValue) mHeaderMap.get(field);
-    }
-
-    /**
-     * Get TO, CC or BCC header value.
-     *
-     * @param field the field
-     * @return the EncodeStringValue array of the pdu header
-     *          with specified header field
-     */
-    protected EncodedStringValue[] getEncodedStringValues(int field) {
-        ArrayList<EncodedStringValue> list =
-                (ArrayList<EncodedStringValue>) mHeaderMap.get(field);
-        if (null == list) {
-            return null;
-        }
-        EncodedStringValue[] values = new EncodedStringValue[list.size()];
-        return list.toArray(values);
-    }
-
-    /**
-     * Set EncodedStringValue value to pdu header by header field.
-     *
-     * @param value the value
-     * @param field the field
-     * @return the EncodedStringValue value of the pdu header
-     *          with specified header field
-     * @throws NullPointerException if the value is null.
-     */
-    protected void setEncodedStringValue(EncodedStringValue value, int field) {
-        /**
-         * Check whether this field can be set for specific
-         * header and check validity of the field.
-         */
-        if (null == value) {
-            throw new NullPointerException();
-        }
-
-        switch (field) {
-            case SUBJECT:
-            case RECOMMENDED_RETRIEVAL_MODE_TEXT:
-            case RETRIEVE_TEXT:
-            case STATUS_TEXT:
-            case STORE_STATUS_TEXT:
-            case RESPONSE_TEXT:
-            case FROM:
-            case PREVIOUSLY_SENT_BY:
-            case MM_FLAGS:
-                break;
-            default:
-                // This header value should not be Encoded-String-Value.
-                throw new RuntimeException("Invalid header field!");
-        }
-
-        mHeaderMap.put(field, value);
-    }
-
-    /**
-     * Set TO, CC or BCC header value.
-     *
-     * @param value the value
-     * @param field the field
-     * @return the EncodedStringValue value array of the pdu header
-     *          with specified header field
-     * @throws NullPointerException if the value is null.
-     */
-    protected void setEncodedStringValues(EncodedStringValue[] value, int field) {
-        /**
-         * Check whether this field can be set for specific
-         * header and check validity of the field.
-         */
-        if (null == value) {
-            throw new NullPointerException();
-        }
-
-        switch (field) {
-            case BCC:
-            case CC:
-            case TO:
-                break;
-            default:
-                // This header value should not be Encoded-String-Value.
-                throw new RuntimeException("Invalid header field!");
-        }
-
-        ArrayList<EncodedStringValue> list = new ArrayList<EncodedStringValue>();
-        for (int i = 0; i < value.length; i++) {
-            list.add(value[i]);
-        }
-        mHeaderMap.put(field, list);
-    }
-
-    /**
-     * Append one EncodedStringValue to another.
-     *
-     * @param value the EncodedStringValue to append
-     * @param field the field
-     * @throws NullPointerException if the value is null.
-     */
-    protected void appendEncodedStringValue(EncodedStringValue value,
-                                    int field) {
-        if (null == value) {
-            throw new NullPointerException();
-        }
-
-        switch (field) {
-            case BCC:
-            case CC:
-            case TO:
-                break;
-            default:
-                throw new RuntimeException("Invalid header field!");
-        }
-
-        ArrayList<EncodedStringValue> list =
-            (ArrayList<EncodedStringValue>) mHeaderMap.get(field);
-        if (null == list) {
-            list  = new ArrayList<EncodedStringValue>();
-        }
-        list.add(value);
-        mHeaderMap.put(field, list);
-    }
-
-    /**
-     * Get LongInteger value by header field.
-     *
-     * @param field the field
-     * @return the LongInteger value of the pdu header
-     *          with specified header field. if return -1, the
-     *          field is not existed in pdu header.
-     */
-    protected long getLongInteger(int field) {
-        Long longInteger = (Long) mHeaderMap.get(field);
-        if (null == longInteger) {
-            return -1;
-        }
-
-        return longInteger.longValue();
-    }
-
-    /**
-     * Set LongInteger value to pdu header by header field.
-     *
-     * @param value the value
-     * @param field the field
-     */
-    protected void setLongInteger(long value, int field) {
-        /**
-         * Check whether this field can be set for specific
-         * header and check validity of the field.
-         */
-        switch (field) {
-            case DATE:
-            case REPLY_CHARGING_SIZE:
-            case MESSAGE_SIZE:
-            case MESSAGE_COUNT:
-            case START:
-            case LIMIT:
-            case DELIVERY_TIME:
-            case EXPIRY:
-            case REPLY_CHARGING_DEADLINE:
-            case PREVIOUSLY_SENT_DATE:
-                break;
-            default:
-                // This header value should not be LongInteger.
-                throw new RuntimeException("Invalid header field!");
-        }
-        mHeaderMap.put(field, value);
-    }
-}
diff --git a/core/java/com/google/android/mms/pdu/PduParser.java b/core/java/com/google/android/mms/pdu/PduParser.java
deleted file mode 100755
index 015d864..0000000
--- a/core/java/com/google/android/mms/pdu/PduParser.java
+++ /dev/null
@@ -1,1912 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Esmertec AG.
- * Copyright (C) 2007-2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.ContentType;
-import com.google.android.mms.InvalidHeaderValueException;
-
-import android.util.Log;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.Arrays;
-import java.util.HashMap;
-
-import android.content.res.Resources;
-
-public class PduParser {
-    /**
-     *  The next are WAP values defined in WSP specification.
-     */
-    private static final int QUOTE = 127;
-    private static final int LENGTH_QUOTE = 31;
-    private static final int TEXT_MIN = 32;
-    private static final int TEXT_MAX = 127;
-    private static final int SHORT_INTEGER_MAX = 127;
-    private static final int SHORT_LENGTH_MAX = 30;
-    private static final int LONG_INTEGER_LENGTH_MAX = 8;
-    private static final int QUOTED_STRING_FLAG = 34;
-    private static final int END_STRING_FLAG = 0x00;
-    //The next two are used by the interface "parseWapString" to
-    //distinguish Text-String and Quoted-String.
-    private static final int TYPE_TEXT_STRING = 0;
-    private static final int TYPE_QUOTED_STRING = 1;
-    private static final int TYPE_TOKEN_STRING = 2;
-
-    /**
-     * Specify the part position.
-     */
-    private static final int THE_FIRST_PART = 0;
-    private static final int THE_LAST_PART = 1;
-
-    /**
-     * The pdu data.
-     */
-    private ByteArrayInputStream mPduDataStream = null;
-
-    /**
-     * Store pdu headers
-     */
-    private PduHeaders mHeaders = null;
-
-    /**
-     * Store pdu parts.
-     */
-    private PduBody mBody = null;
-
-    /**
-     * Store the "type" parameter in "Content-Type" header field.
-     */
-    private static byte[] mTypeParam = null;
-
-    /**
-     * Store the "start" parameter in "Content-Type" header field.
-     */
-    private static byte[] mStartParam = null;
-
-    /**
-     * The log tag.
-     */
-    private static final String LOG_TAG = "PduParser";
-    private static final boolean DEBUG = false;
-    private static final boolean LOCAL_LOGV = false;
-
-    /**
-     * Constructor.
-     *
-     * @param pduDataStream pdu data to be parsed
-     */
-    public PduParser(byte[] pduDataStream) {
-        mPduDataStream = new ByteArrayInputStream(pduDataStream);
-    }
-
-    /**
-     * Parse the pdu.
-     *
-     * @return the pdu structure if parsing successfully.
-     *         null if parsing error happened or mandatory fields are not set.
-     */
-    public GenericPdu parse(){
-        if (mPduDataStream == null) {
-            return null;
-        }
-
-        /* parse headers */
-        mHeaders = parseHeaders(mPduDataStream);
-        if (null == mHeaders) {
-            // Parse headers failed.
-            return null;
-        }
-
-        /* get the message type */
-        int messageType = mHeaders.getOctet(PduHeaders.MESSAGE_TYPE);
-
-        /* check mandatory header fields */
-        if (false == checkMandatoryHeader(mHeaders)) {
-            log("check mandatory headers failed!");
-            return null;
-        }
-
-        if ((PduHeaders.MESSAGE_TYPE_SEND_REQ == messageType) ||
-                (PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF == messageType)) {
-            /* need to parse the parts */
-            mBody = parseParts(mPduDataStream);
-            if (null == mBody) {
-                // Parse parts failed.
-                return null;
-            }
-        }
-
-        switch (messageType) {
-            case PduHeaders.MESSAGE_TYPE_SEND_REQ:
-                SendReq sendReq = new SendReq(mHeaders, mBody);
-                return sendReq;
-            case PduHeaders.MESSAGE_TYPE_SEND_CONF:
-                SendConf sendConf = new SendConf(mHeaders);
-                return sendConf;
-            case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND:
-                NotificationInd notificationInd =
-                    new NotificationInd(mHeaders);
-                return notificationInd;
-            case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND:
-                NotifyRespInd notifyRespInd =
-                    new NotifyRespInd(mHeaders);
-                return notifyRespInd;
-            case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF:
-                RetrieveConf retrieveConf =
-                    new RetrieveConf(mHeaders, mBody);
-
-                byte[] contentType = retrieveConf.getContentType();
-                if (null == contentType) {
-                    return null;
-                }
-                String ctTypeStr = new String(contentType);
-                if (ctTypeStr.equals(ContentType.MULTIPART_MIXED)
-                        || ctTypeStr.equals(ContentType.MULTIPART_RELATED)
-                        || ctTypeStr.equals(ContentType.MULTIPART_ALTERNATIVE)) {
-                    // The MMS content type must be "application/vnd.wap.multipart.mixed"
-                    // or "application/vnd.wap.multipart.related"
-                    // or "application/vnd.wap.multipart.alternative"
-                    return retrieveConf;
-                } else if (ctTypeStr.equals(ContentType.MULTIPART_ALTERNATIVE)) {
-                    // "application/vnd.wap.multipart.alternative"
-                    // should take only the first part.
-                    PduPart firstPart = mBody.getPart(0);
-                    mBody.removeAll();
-                    mBody.addPart(0, firstPart);
-                    return retrieveConf;
-                }
-                return null;
-            case PduHeaders.MESSAGE_TYPE_DELIVERY_IND:
-                DeliveryInd deliveryInd =
-                    new DeliveryInd(mHeaders);
-                return deliveryInd;
-            case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND:
-                AcknowledgeInd acknowledgeInd =
-                    new AcknowledgeInd(mHeaders);
-                return acknowledgeInd;
-            case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND:
-                ReadOrigInd readOrigInd =
-                    new ReadOrigInd(mHeaders);
-                return readOrigInd;
-            case PduHeaders.MESSAGE_TYPE_READ_REC_IND:
-                ReadRecInd readRecInd =
-                    new ReadRecInd(mHeaders);
-                return readRecInd;
-            default:
-                log("Parser doesn't support this message type in this version!");
-            return null;
-        }
-    }
-
-    /**
-     * Parse pdu headers.
-     *
-     * @param pduDataStream pdu data input stream
-     * @return headers in PduHeaders structure, null when parse fail
-     */
-    protected PduHeaders parseHeaders(ByteArrayInputStream pduDataStream){
-        if (pduDataStream == null) {
-            return null;
-        }
-
-        boolean keepParsing = true;
-        PduHeaders headers = new PduHeaders();
-
-        while (keepParsing && (pduDataStream.available() > 0)) {
-            pduDataStream.mark(1);
-            int headerField = extractByteValue(pduDataStream);
-            /* parse custom text header */
-            if ((headerField >= TEXT_MIN) && (headerField <= TEXT_MAX)) {
-                pduDataStream.reset();
-                byte [] bVal = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-                if (LOCAL_LOGV) {
-                    Log.v(LOG_TAG, "TextHeader: " + new String(bVal));
-                }
-                /* we should ignore it at the moment */
-                continue;
-            }
-            switch (headerField) {
-                case PduHeaders.MESSAGE_TYPE:
-                {
-                    int messageType = extractByteValue(pduDataStream);
-                    switch (messageType) {
-                        // We don't support these kind of messages now.
-                        case PduHeaders.MESSAGE_TYPE_FORWARD_REQ:
-                        case PduHeaders.MESSAGE_TYPE_FORWARD_CONF:
-                        case PduHeaders.MESSAGE_TYPE_MBOX_STORE_REQ:
-                        case PduHeaders.MESSAGE_TYPE_MBOX_STORE_CONF:
-                        case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_REQ:
-                        case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_CONF:
-                        case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_REQ:
-                        case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_CONF:
-                        case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_REQ:
-                        case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_CONF:
-                        case PduHeaders.MESSAGE_TYPE_MBOX_DESCR:
-                        case PduHeaders.MESSAGE_TYPE_DELETE_REQ:
-                        case PduHeaders.MESSAGE_TYPE_DELETE_CONF:
-                        case PduHeaders.MESSAGE_TYPE_CANCEL_REQ:
-                        case PduHeaders.MESSAGE_TYPE_CANCEL_CONF:
-                            return null;
-                    }
-                    try {
-                        headers.setOctet(messageType, headerField);
-                    } catch(InvalidHeaderValueException e) {
-                        log("Set invalid Octet value: " + messageType +
-                                " into the header filed: " + headerField);
-                        return null;
-                    } catch(RuntimeException e) {
-                        log(headerField + "is not Octet header field!");
-                        return null;
-                    }
-                    break;
-                }
-                /* Octect value */
-                case PduHeaders.REPORT_ALLOWED:
-                case PduHeaders.ADAPTATION_ALLOWED:
-                case PduHeaders.DELIVERY_REPORT:
-                case PduHeaders.DRM_CONTENT:
-                case PduHeaders.DISTRIBUTION_INDICATOR:
-                case PduHeaders.QUOTAS:
-                case PduHeaders.READ_REPORT:
-                case PduHeaders.STORE:
-                case PduHeaders.STORED:
-                case PduHeaders.TOTALS:
-                case PduHeaders.SENDER_VISIBILITY:
-                case PduHeaders.READ_STATUS:
-                case PduHeaders.CANCEL_STATUS:
-                case PduHeaders.PRIORITY:
-                case PduHeaders.STATUS:
-                case PduHeaders.REPLY_CHARGING:
-                case PduHeaders.MM_STATE:
-                case PduHeaders.RECOMMENDED_RETRIEVAL_MODE:
-                case PduHeaders.CONTENT_CLASS:
-                case PduHeaders.RETRIEVE_STATUS:
-                case PduHeaders.STORE_STATUS:
-                    /**
-                     * The following field has a different value when
-                     * used in the M-Mbox-Delete.conf and M-Delete.conf PDU.
-                     * For now we ignore this fact, since we do not support these PDUs
-                     */
-                case PduHeaders.RESPONSE_STATUS:
-                {
-                    int value = extractByteValue(pduDataStream);
-
-                    try {
-                        headers.setOctet(value, headerField);
-                    } catch(InvalidHeaderValueException e) {
-                        log("Set invalid Octet value: " + value +
-                                " into the header filed: " + headerField);
-                        return null;
-                    } catch(RuntimeException e) {
-                        log(headerField + "is not Octet header field!");
-                        return null;
-                    }
-                    break;
-                }
-
-                /* Long-Integer */
-                case PduHeaders.DATE:
-                case PduHeaders.REPLY_CHARGING_SIZE:
-                case PduHeaders.MESSAGE_SIZE:
-                {
-                    try {
-                        long value = parseLongInteger(pduDataStream);
-                        headers.setLongInteger(value, headerField);
-                    } catch(RuntimeException e) {
-                        log(headerField + "is not Long-Integer header field!");
-                        return null;
-                    }
-                    break;
-                }
-
-                /* Integer-Value */
-                case PduHeaders.MESSAGE_COUNT:
-                case PduHeaders.START:
-                case PduHeaders.LIMIT:
-                {
-                    try {
-                        long value = parseIntegerValue(pduDataStream);
-                        headers.setLongInteger(value, headerField);
-                    } catch(RuntimeException e) {
-                        log(headerField + "is not Long-Integer header field!");
-                        return null;
-                    }
-                    break;
-                }
-
-                /* Text-String */
-                case PduHeaders.TRANSACTION_ID:
-                case PduHeaders.REPLY_CHARGING_ID:
-                case PduHeaders.AUX_APPLIC_ID:
-                case PduHeaders.APPLIC_ID:
-                case PduHeaders.REPLY_APPLIC_ID:
-                    /**
-                     * The next three header fields are email addresses
-                     * as defined in RFC2822,
-                     * not including the characters "<" and ">"
-                     */
-                case PduHeaders.MESSAGE_ID:
-                case PduHeaders.REPLACE_ID:
-                case PduHeaders.CANCEL_ID:
-                    /**
-                     * The following field has a different value when
-                     * used in the M-Mbox-Delete.conf and M-Delete.conf PDU.
-                     * For now we ignore this fact, since we do not support these PDUs
-                     */
-                case PduHeaders.CONTENT_LOCATION:
-                {
-                    byte[] value = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-                    if (null != value) {
-                        try {
-                            headers.setTextString(value, headerField);
-                        } catch(NullPointerException e) {
-                            log("null pointer error!");
-                        } catch(RuntimeException e) {
-                            log(headerField + "is not Text-String header field!");
-                            return null;
-                        }
-                    }
-                    break;
-                }
-
-                /* Encoded-string-value */
-                case PduHeaders.SUBJECT:
-                case PduHeaders.RECOMMENDED_RETRIEVAL_MODE_TEXT:
-                case PduHeaders.RETRIEVE_TEXT:
-                case PduHeaders.STATUS_TEXT:
-                case PduHeaders.STORE_STATUS_TEXT:
-                    /* the next one is not support
-                     * M-Mbox-Delete.conf and M-Delete.conf now */
-                case PduHeaders.RESPONSE_TEXT:
-                {
-                    EncodedStringValue value =
-                        parseEncodedStringValue(pduDataStream);
-                    if (null != value) {
-                        try {
-                            headers.setEncodedStringValue(value, headerField);
-                        } catch(NullPointerException e) {
-                            log("null pointer error!");
-                        } catch (RuntimeException e) {
-                            log(headerField + "is not Encoded-String-Value header field!");
-                            return null;
-                        }
-                    }
-                    break;
-                }
-
-                /* Addressing model */
-                case PduHeaders.BCC:
-                case PduHeaders.CC:
-                case PduHeaders.TO:
-                {
-                    EncodedStringValue value =
-                        parseEncodedStringValue(pduDataStream);
-                    if (null != value) {
-                        byte[] address = value.getTextString();
-                        if (null != address) {
-                            String str = new String(address);
-                            int endIndex = str.indexOf("/");
-                            if (endIndex > 0) {
-                                str = str.substring(0, endIndex);
-                            }
-                            try {
-                                value.setTextString(str.getBytes());
-                            } catch(NullPointerException e) {
-                                log("null pointer error!");
-                                return null;
-                            }
-                        }
-
-                        try {
-                            headers.appendEncodedStringValue(value, headerField);
-                        } catch(NullPointerException e) {
-                            log("null pointer error!");
-                        } catch(RuntimeException e) {
-                            log(headerField + "is not Encoded-String-Value header field!");
-                            return null;
-                        }
-                    }
-                    break;
-                }
-
-                /* Value-length
-                 * (Absolute-token Date-value | Relative-token Delta-seconds-value) */
-                case PduHeaders.DELIVERY_TIME:
-                case PduHeaders.EXPIRY:
-                case PduHeaders.REPLY_CHARGING_DEADLINE:
-                {
-                    /* parse Value-length */
-                    parseValueLength(pduDataStream);
-
-                    /* Absolute-token or Relative-token */
-                    int token = extractByteValue(pduDataStream);
-
-                    /* Date-value or Delta-seconds-value */
-                    long timeValue;
-                    try {
-                        timeValue = parseLongInteger(pduDataStream);
-                    } catch(RuntimeException e) {
-                        log(headerField + "is not Long-Integer header field!");
-                        return null;
-                    }
-                    if (PduHeaders.VALUE_RELATIVE_TOKEN == token) {
-                        /* need to convert the Delta-seconds-value
-                         * into Date-value */
-                        timeValue = System.currentTimeMillis()/1000 + timeValue;
-                    }
-
-                    try {
-                        headers.setLongInteger(timeValue, headerField);
-                    } catch(RuntimeException e) {
-                        log(headerField + "is not Long-Integer header field!");
-                        return null;
-                    }
-                    break;
-                }
-
-                case PduHeaders.FROM: {
-                    /* From-value =
-                     * Value-length
-                     * (Address-present-token Encoded-string-value | Insert-address-token)
-                     */
-                    EncodedStringValue from = null;
-                    parseValueLength(pduDataStream); /* parse value-length */
-
-                    /* Address-present-token or Insert-address-token */
-                    int fromToken = extractByteValue(pduDataStream);
-
-                    /* Address-present-token or Insert-address-token */
-                    if (PduHeaders.FROM_ADDRESS_PRESENT_TOKEN == fromToken) {
-                        /* Encoded-string-value */
-                        from = parseEncodedStringValue(pduDataStream);
-                        if (null != from) {
-                            byte[] address = from.getTextString();
-                            if (null != address) {
-                                String str = new String(address);
-                                int endIndex = str.indexOf("/");
-                                if (endIndex > 0) {
-                                    str = str.substring(0, endIndex);
-                                }
-                                try {
-                                    from.setTextString(str.getBytes());
-                                } catch(NullPointerException e) {
-                                    log("null pointer error!");
-                                    return null;
-                                }
-                            }
-                        }
-                    } else {
-                        try {
-                            from = new EncodedStringValue(
-                                    PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR.getBytes());
-                        } catch(NullPointerException e) {
-                            log(headerField + "is not Encoded-String-Value header field!");
-                            return null;
-                        }
-                    }
-
-                    try {
-                        headers.setEncodedStringValue(from, PduHeaders.FROM);
-                    } catch(NullPointerException e) {
-                        log("null pointer error!");
-                    } catch(RuntimeException e) {
-                        log(headerField + "is not Encoded-String-Value header field!");
-                        return null;
-                    }
-                    break;
-                }
-
-                case PduHeaders.MESSAGE_CLASS: {
-                    /* Message-class-value = Class-identifier | Token-text */
-                    pduDataStream.mark(1);
-                    int messageClass = extractByteValue(pduDataStream);
-
-                    if (messageClass >= PduHeaders.MESSAGE_CLASS_PERSONAL) {
-                        /* Class-identifier */
-                        try {
-                            if (PduHeaders.MESSAGE_CLASS_PERSONAL == messageClass) {
-                                headers.setTextString(
-                                        PduHeaders.MESSAGE_CLASS_PERSONAL_STR.getBytes(),
-                                        PduHeaders.MESSAGE_CLASS);
-                            } else if (PduHeaders.MESSAGE_CLASS_ADVERTISEMENT == messageClass) {
-                                headers.setTextString(
-                                        PduHeaders.MESSAGE_CLASS_ADVERTISEMENT_STR.getBytes(),
-                                        PduHeaders.MESSAGE_CLASS);
-                            } else if (PduHeaders.MESSAGE_CLASS_INFORMATIONAL == messageClass) {
-                                headers.setTextString(
-                                        PduHeaders.MESSAGE_CLASS_INFORMATIONAL_STR.getBytes(),
-                                        PduHeaders.MESSAGE_CLASS);
-                            } else if (PduHeaders.MESSAGE_CLASS_AUTO == messageClass) {
-                                headers.setTextString(
-                                        PduHeaders.MESSAGE_CLASS_AUTO_STR.getBytes(),
-                                        PduHeaders.MESSAGE_CLASS);
-                            }
-                        } catch(NullPointerException e) {
-                            log("null pointer error!");
-                        } catch(RuntimeException e) {
-                            log(headerField + "is not Text-String header field!");
-                            return null;
-                        }
-                    } else {
-                        /* Token-text */
-                        pduDataStream.reset();
-                        byte[] messageClassString = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-                        if (null != messageClassString) {
-                            try {
-                                headers.setTextString(messageClassString, PduHeaders.MESSAGE_CLASS);
-                            } catch(NullPointerException e) {
-                                log("null pointer error!");
-                            } catch(RuntimeException e) {
-                                log(headerField + "is not Text-String header field!");
-                                return null;
-                            }
-                        }
-                    }
-                    break;
-                }
-
-                case PduHeaders.MMS_VERSION: {
-                    int version = parseShortInteger(pduDataStream);
-
-                    try {
-                        headers.setOctet(version, PduHeaders.MMS_VERSION);
-                    } catch(InvalidHeaderValueException e) {
-                        log("Set invalid Octet value: " + version +
-                                " into the header filed: " + headerField);
-                        return null;
-                    } catch(RuntimeException e) {
-                        log(headerField + "is not Octet header field!");
-                        return null;
-                    }
-                    break;
-                }
-
-                case PduHeaders.PREVIOUSLY_SENT_BY: {
-                    /* Previously-sent-by-value =
-                     * Value-length Forwarded-count-value Encoded-string-value */
-                    /* parse value-length */
-                    parseValueLength(pduDataStream);
-
-                    /* parse Forwarded-count-value */
-                    try {
-                        parseIntegerValue(pduDataStream);
-                    } catch(RuntimeException e) {
-                        log(headerField + " is not Integer-Value");
-                        return null;
-                    }
-
-                    /* parse Encoded-string-value */
-                    EncodedStringValue previouslySentBy =
-                        parseEncodedStringValue(pduDataStream);
-                    if (null != previouslySentBy) {
-                        try {
-                            headers.setEncodedStringValue(previouslySentBy,
-                                    PduHeaders.PREVIOUSLY_SENT_BY);
-                        } catch(NullPointerException e) {
-                            log("null pointer error!");
-                        } catch(RuntimeException e) {
-                            log(headerField + "is not Encoded-String-Value header field!");
-                            return null;
-                        }
-                    }
-                    break;
-                }
-
-                case PduHeaders.PREVIOUSLY_SENT_DATE: {
-                    /* Previously-sent-date-value =
-                     * Value-length Forwarded-count-value Date-value */
-                    /* parse value-length */
-                    parseValueLength(pduDataStream);
-
-                    /* parse Forwarded-count-value */
-                    try {
-                        parseIntegerValue(pduDataStream);
-                    } catch(RuntimeException e) {
-                        log(headerField + " is not Integer-Value");
-                        return null;
-                    }
-
-                    /* Date-value */
-                    try {
-                        long perviouslySentDate = parseLongInteger(pduDataStream);
-                        headers.setLongInteger(perviouslySentDate,
-                                PduHeaders.PREVIOUSLY_SENT_DATE);
-                    } catch(RuntimeException e) {
-                        log(headerField + "is not Long-Integer header field!");
-                        return null;
-                    }
-                    break;
-                }
-
-                case PduHeaders.MM_FLAGS: {
-                    /* MM-flags-value =
-                     * Value-length
-                     * ( Add-token | Remove-token | Filter-token )
-                     * Encoded-string-value
-                     */
-
-                    /* parse Value-length */
-                    parseValueLength(pduDataStream);
-
-                    /* Add-token | Remove-token | Filter-token */
-                    extractByteValue(pduDataStream);
-
-                    /* Encoded-string-value */
-                    parseEncodedStringValue(pduDataStream);
-
-                    /* not store this header filed in "headers",
-                     * because now PduHeaders doesn't support it */
-                    break;
-                }
-
-                /* Value-length
-                 * (Message-total-token | Size-total-token) Integer-Value */
-                case PduHeaders.MBOX_TOTALS:
-                case PduHeaders.MBOX_QUOTAS:
-                {
-                    /* Value-length */
-                    parseValueLength(pduDataStream);
-
-                    /* Message-total-token | Size-total-token */
-                    extractByteValue(pduDataStream);
-
-                    /*Integer-Value*/
-                    try {
-                        parseIntegerValue(pduDataStream);
-                    } catch(RuntimeException e) {
-                        log(headerField + " is not Integer-Value");
-                        return null;
-                    }
-
-                    /* not store these headers filed in "headers",
-                    because now PduHeaders doesn't support them */
-                    break;
-                }
-
-                case PduHeaders.ELEMENT_DESCRIPTOR: {
-                    parseContentType(pduDataStream, null);
-
-                    /* not store this header filed in "headers",
-                    because now PduHeaders doesn't support it */
-                    break;
-                }
-
-                case PduHeaders.CONTENT_TYPE: {
-                    HashMap<Integer, Object> map =
-                        new HashMap<Integer, Object>();
-                    byte[] contentType =
-                        parseContentType(pduDataStream, map);
-
-                    if (null != contentType) {
-                        try {
-                            headers.setTextString(contentType, PduHeaders.CONTENT_TYPE);
-                        } catch(NullPointerException e) {
-                            log("null pointer error!");
-                        } catch(RuntimeException e) {
-                            log(headerField + "is not Text-String header field!");
-                            return null;
-                        }
-                    }
-
-                    /* get start parameter */
-                    mStartParam = (byte[]) map.get(PduPart.P_START);
-
-                    /* get charset parameter */
-                    mTypeParam= (byte[]) map.get(PduPart.P_TYPE);
-
-                    keepParsing = false;
-                    break;
-                }
-
-                case PduHeaders.CONTENT:
-                case PduHeaders.ADDITIONAL_HEADERS:
-                case PduHeaders.ATTRIBUTES:
-                default: {
-                    log("Unknown header");
-                }
-            }
-        }
-
-        return headers;
-    }
-
-    /**
-     * Parse pdu parts.
-     *
-     * @param pduDataStream pdu data input stream
-     * @return parts in PduBody structure
-     */
-    protected static PduBody parseParts(ByteArrayInputStream pduDataStream) {
-        if (pduDataStream == null) {
-            return null;
-        }
-
-        int count = parseUnsignedInt(pduDataStream); // get the number of parts
-        PduBody body = new PduBody();
-
-        for (int i = 0 ; i < count ; i++) {
-            int headerLength = parseUnsignedInt(pduDataStream);
-            int dataLength = parseUnsignedInt(pduDataStream);
-            PduPart part = new PduPart();
-            int startPos = pduDataStream.available();
-            if (startPos <= 0) {
-                // Invalid part.
-                return null;
-            }
-
-            /* parse part's content-type */
-            HashMap<Integer, Object> map = new HashMap<Integer, Object>();
-            byte[] contentType = parseContentType(pduDataStream, map);
-            if (null != contentType) {
-                part.setContentType(contentType);
-            } else {
-                part.setContentType((PduContentTypes.contentTypes[0]).getBytes()); //"*/*"
-            }
-
-            /* get name parameter */
-            byte[] name = (byte[]) map.get(PduPart.P_NAME);
-            if (null != name) {
-                part.setName(name);
-            }
-
-            /* get charset parameter */
-            Integer charset = (Integer) map.get(PduPart.P_CHARSET);
-            if (null != charset) {
-                part.setCharset(charset);
-            }
-
-            /* parse part's headers */
-            int endPos = pduDataStream.available();
-            int partHeaderLen = headerLength - (startPos - endPos);
-            if (partHeaderLen > 0) {
-                if (false == parsePartHeaders(pduDataStream, part, partHeaderLen)) {
-                    // Parse part header faild.
-                    return null;
-                }
-            } else if (partHeaderLen < 0) {
-                // Invalid length of content-type.
-                return null;
-            }
-
-            /* FIXME: check content-id, name, filename and content location,
-             * if not set anyone of them, generate a default content-location
-             */
-            if ((null == part.getContentLocation())
-                    && (null == part.getName())
-                    && (null == part.getFilename())
-                    && (null == part.getContentId())) {
-                part.setContentLocation(Long.toOctalString(
-                        System.currentTimeMillis()).getBytes());
-            }
-
-            /* get part's data */
-            if (dataLength > 0) {
-                byte[] partData = new byte[dataLength];
-                String partContentType = new String(part.getContentType());
-                pduDataStream.read(partData, 0, dataLength);
-                if (partContentType.equalsIgnoreCase(ContentType.MULTIPART_ALTERNATIVE)) {
-                    // parse "multipart/vnd.wap.multipart.alternative".
-                    PduBody childBody = parseParts(new ByteArrayInputStream(partData));
-                    // take the first part of children.
-                    part = childBody.getPart(0);
-                } else {
-                    // Check Content-Transfer-Encoding.
-                    byte[] partDataEncoding = part.getContentTransferEncoding();
-                    if (null != partDataEncoding) {
-                        String encoding = new String(partDataEncoding);
-                        if (encoding.equalsIgnoreCase(PduPart.P_BASE64)) {
-                            // Decode "base64" into "binary".
-                            partData = Base64.decodeBase64(partData);
-                        } else if (encoding.equalsIgnoreCase(PduPart.P_QUOTED_PRINTABLE)) {
-                            // Decode "quoted-printable" into "binary".
-                            partData = QuotedPrintable.decodeQuotedPrintable(partData);
-                        } else {
-                            // "binary" is the default encoding.
-                        }
-                    }
-                    if (null == partData) {
-                        log("Decode part data error!");
-                        return null;
-                    }
-                    part.setData(partData);
-                }
-            }
-
-            /* add this part to body */
-            if (THE_FIRST_PART == checkPartPosition(part)) {
-                /* this is the first part */
-                body.addPart(0, part);
-            } else {
-                /* add the part to the end */
-                body.addPart(part);
-            }
-        }
-
-        return body;
-    }
-
-    /**
-     * Log status.
-     *
-     * @param text log information
-     */
-    private static void log(String text) {
-        if (LOCAL_LOGV) {
-            Log.v(LOG_TAG, text);
-        }
-    }
-
-    /**
-     * Parse unsigned integer.
-     *
-     * @param pduDataStream pdu data input stream
-     * @return the integer, -1 when failed
-     */
-    protected static int parseUnsignedInt(ByteArrayInputStream pduDataStream) {
-        /**
-         * From wap-230-wsp-20010705-a.pdf
-         * The maximum size of a uintvar is 32 bits.
-         * So it will be encoded in no more than 5 octets.
-         */
-        assert(null != pduDataStream);
-        int result = 0;
-        int temp = pduDataStream.read();
-        if (temp == -1) {
-            return temp;
-        }
-
-        while((temp & 0x80) != 0) {
-            result = result << 7;
-            result |= temp & 0x7F;
-            temp = pduDataStream.read();
-            if (temp == -1) {
-                return temp;
-            }
-        }
-
-        result = result << 7;
-        result |= temp & 0x7F;
-
-        return result;
-    }
-
-    /**
-     * Parse value length.
-     *
-     * @param pduDataStream pdu data input stream
-     * @return the integer
-     */
-    protected static int parseValueLength(ByteArrayInputStream pduDataStream) {
-        /**
-         * From wap-230-wsp-20010705-a.pdf
-         * Value-length = Short-length | (Length-quote Length)
-         * Short-length = <Any octet 0-30>
-         * Length-quote = <Octet 31>
-         * Length = Uintvar-integer
-         * Uintvar-integer = 1*5 OCTET
-         */
-        assert(null != pduDataStream);
-        int temp = pduDataStream.read();
-        assert(-1 != temp);
-        int first = temp & 0xFF;
-
-        if (first <= SHORT_LENGTH_MAX) {
-            return first;
-        } else if (first == LENGTH_QUOTE) {
-            return parseUnsignedInt(pduDataStream);
-        }
-
-        throw new RuntimeException ("Value length > LENGTH_QUOTE!");
-    }
-
-    /**
-     * Parse encoded string value.
-     *
-     * @param pduDataStream pdu data input stream
-     * @return the EncodedStringValue
-     */
-    protected static EncodedStringValue parseEncodedStringValue(ByteArrayInputStream pduDataStream){
-        /**
-         * From OMA-TS-MMS-ENC-V1_3-20050927-C.pdf
-         * Encoded-string-value = Text-string | Value-length Char-set Text-string
-         */
-        assert(null != pduDataStream);
-        pduDataStream.mark(1);
-        EncodedStringValue returnValue = null;
-        int charset = 0;
-        int temp = pduDataStream.read();
-        assert(-1 != temp);
-        int first = temp & 0xFF;
-        if (first == 0) {
-            return null;    //  Blank subject, bail.
-        }
-
-        pduDataStream.reset();
-        if (first < TEXT_MIN) {
-            parseValueLength(pduDataStream);
-
-            charset = parseShortInteger(pduDataStream); //get the "Charset"
-        }
-
-        byte[] textString = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-
-        try {
-            if (0 != charset) {
-                returnValue = new EncodedStringValue(charset, textString);
-            } else {
-                returnValue = new EncodedStringValue(textString);
-            }
-        } catch(Exception e) {
-            return null;
-        }
-
-        return returnValue;
-    }
-
-    /**
-     * Parse Text-String or Quoted-String.
-     *
-     * @param pduDataStream pdu data input stream
-     * @param stringType TYPE_TEXT_STRING or TYPE_QUOTED_STRING
-     * @return the string without End-of-string in byte array
-     */
-    protected static byte[] parseWapString(ByteArrayInputStream pduDataStream,
-            int stringType) {
-        assert(null != pduDataStream);
-        /**
-         * From wap-230-wsp-20010705-a.pdf
-         * Text-string = [Quote] *TEXT End-of-string
-         * If the first character in the TEXT is in the range of 128-255,
-         * a Quote character must precede it.
-         * Otherwise the Quote character must be omitted.
-         * The Quote is not part of the contents.
-         * Quote = <Octet 127>
-         * End-of-string = <Octet 0>
-         *
-         * Quoted-string = <Octet 34> *TEXT End-of-string
-         *
-         * Token-text = Token End-of-string
-         */
-
-        // Mark supposed beginning of Text-string
-        // We will have to mark again if first char is QUOTE or QUOTED_STRING_FLAG
-        pduDataStream.mark(1);
-
-        // Check first char
-        int temp = pduDataStream.read();
-        assert(-1 != temp);
-        if ((TYPE_QUOTED_STRING == stringType) &&
-                (QUOTED_STRING_FLAG == temp)) {
-            // Mark again if QUOTED_STRING_FLAG and ignore it
-            pduDataStream.mark(1);
-        } else if ((TYPE_TEXT_STRING == stringType) &&
-                (QUOTE == temp)) {
-            // Mark again if QUOTE and ignore it
-            pduDataStream.mark(1);
-        } else {
-            // Otherwise go back to origin
-            pduDataStream.reset();
-        }
-
-        // We are now definitely at the beginning of string
-        /**
-         * Return *TOKEN or *TEXT (Text-String without QUOTE,
-         * Quoted-String without QUOTED_STRING_FLAG and without End-of-string)
-         */
-        return getWapString(pduDataStream, stringType);
-    }
-
-    /**
-     * Check TOKEN data defined in RFC2616.
-     * @param ch checking data
-     * @return true when ch is TOKEN, false when ch is not TOKEN
-     */
-    protected static boolean isTokenCharacter(int ch) {
-        /**
-         * Token      = 1*<any CHAR except CTLs or separators>
-         * separators = "("(40) | ")"(41) | "<"(60) | ">"(62) | "@"(64)
-         *            | ","(44) | ";"(59) | ":"(58) | "\"(92) | <">(34)
-         *            | "/"(47) | "["(91) | "]"(93) | "?"(63) | "="(61)
-         *            | "{"(123) | "}"(125) | SP(32) | HT(9)
-         * CHAR       = <any US-ASCII character (octets 0 - 127)>
-         * CTL        = <any US-ASCII control character
-         *            (octets 0 - 31) and DEL (127)>
-         * SP         = <US-ASCII SP, space (32)>
-         * HT         = <US-ASCII HT, horizontal-tab (9)>
-         */
-        if((ch < 33) || (ch > 126)) {
-            return false;
-        }
-
-        switch(ch) {
-            case '"': /* '"' */
-            case '(': /* '(' */
-            case ')': /* ')' */
-            case ',': /* ',' */
-            case '/': /* '/' */
-            case ':': /* ':' */
-            case ';': /* ';' */
-            case '<': /* '<' */
-            case '=': /* '=' */
-            case '>': /* '>' */
-            case '?': /* '?' */
-            case '@': /* '@' */
-            case '[': /* '[' */
-            case '\\': /* '\' */
-            case ']': /* ']' */
-            case '{': /* '{' */
-            case '}': /* '}' */
-                return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Check TEXT data defined in RFC2616.
-     * @param ch checking data
-     * @return true when ch is TEXT, false when ch is not TEXT
-     */
-    protected static boolean isText(int ch) {
-        /**
-         * TEXT = <any OCTET except CTLs,
-         *      but including LWS>
-         * CTL  = <any US-ASCII control character
-         *      (octets 0 - 31) and DEL (127)>
-         * LWS  = [CRLF] 1*( SP | HT )
-         * CRLF = CR LF
-         * CR   = <US-ASCII CR, carriage return (13)>
-         * LF   = <US-ASCII LF, linefeed (10)>
-         */
-        if(((ch >= 32) && (ch <= 126)) || ((ch >= 128) && (ch <= 255))) {
-            return true;
-        }
-
-        switch(ch) {
-            case '\t': /* '\t' */
-            case '\n': /* '\n' */
-            case '\r': /* '\r' */
-                return true;
-        }
-
-        return false;
-    }
-
-    protected static byte[] getWapString(ByteArrayInputStream pduDataStream,
-            int stringType) {
-        assert(null != pduDataStream);
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        int temp = pduDataStream.read();
-        assert(-1 != temp);
-        while((-1 != temp) && ('\0' != temp)) {
-            // check each of the character
-            if (stringType == TYPE_TOKEN_STRING) {
-                if (isTokenCharacter(temp)) {
-                    out.write(temp);
-                }
-            } else {
-                if (isText(temp)) {
-                    out.write(temp);
-                }
-            }
-
-            temp = pduDataStream.read();
-            assert(-1 != temp);
-        }
-
-        if (out.size() > 0) {
-            return out.toByteArray();
-        }
-
-        return null;
-    }
-
-    /**
-     * Extract a byte value from the input stream.
-     *
-     * @param pduDataStream pdu data input stream
-     * @return the byte
-     */
-    protected static int extractByteValue(ByteArrayInputStream pduDataStream) {
-        assert(null != pduDataStream);
-        int temp = pduDataStream.read();
-        assert(-1 != temp);
-        return temp & 0xFF;
-    }
-
-    /**
-     * Parse Short-Integer.
-     *
-     * @param pduDataStream pdu data input stream
-     * @return the byte
-     */
-    protected static int parseShortInteger(ByteArrayInputStream pduDataStream) {
-        /**
-         * From wap-230-wsp-20010705-a.pdf
-         * Short-integer = OCTET
-         * Integers in range 0-127 shall be encoded as a one
-         * octet value with the most significant bit set to one (1xxx xxxx)
-         * and with the value in the remaining least significant bits.
-         */
-        assert(null != pduDataStream);
-        int temp = pduDataStream.read();
-        assert(-1 != temp);
-        return temp & 0x7F;
-    }
-
-    /**
-     * Parse Long-Integer.
-     *
-     * @param pduDataStream pdu data input stream
-     * @return long integer
-     */
-    protected static long parseLongInteger(ByteArrayInputStream pduDataStream) {
-        /**
-         * From wap-230-wsp-20010705-a.pdf
-         * Long-integer = Short-length Multi-octet-integer
-         * The Short-length indicates the length of the Multi-octet-integer
-         * Multi-octet-integer = 1*30 OCTET
-         * The content octets shall be an unsigned integer value
-         * with the most significant octet encoded first (big-endian representation).
-         * The minimum number of octets must be used to encode the value.
-         * Short-length = <Any octet 0-30>
-         */
-        assert(null != pduDataStream);
-        int temp = pduDataStream.read();
-        assert(-1 != temp);
-        int count = temp & 0xFF;
-
-        if (count > LONG_INTEGER_LENGTH_MAX) {
-            throw new RuntimeException("Octet count greater than 8 and I can't represent that!");
-        }
-
-        long result = 0;
-
-        for (int i = 0 ; i < count ; i++) {
-            temp = pduDataStream.read();
-            assert(-1 != temp);
-            result <<= 8;
-            result += (temp & 0xFF);
-        }
-
-        return result;
-    }
-
-    /**
-     * Parse Integer-Value.
-     *
-     * @param pduDataStream pdu data input stream
-     * @return long integer
-     */
-    protected static long parseIntegerValue(ByteArrayInputStream pduDataStream) {
-        /**
-         * From wap-230-wsp-20010705-a.pdf
-         * Integer-Value = Short-integer | Long-integer
-         */
-        assert(null != pduDataStream);
-        pduDataStream.mark(1);
-        int temp = pduDataStream.read();
-        assert(-1 != temp);
-        pduDataStream.reset();
-        if (temp > SHORT_INTEGER_MAX) {
-            return parseShortInteger(pduDataStream);
-        } else {
-            return parseLongInteger(pduDataStream);
-        }
-    }
-
-    /**
-     * To skip length of the wap value.
-     *
-     * @param pduDataStream pdu data input stream
-     * @param length area size
-     * @return the values in this area
-     */
-    protected static int skipWapValue(ByteArrayInputStream pduDataStream, int length) {
-        assert(null != pduDataStream);
-        byte[] area = new byte[length];
-        int readLen = pduDataStream.read(area, 0, length);
-        if (readLen < length) { //The actually read length is lower than the length
-            return -1;
-        } else {
-            return readLen;
-        }
-    }
-
-    /**
-     * Parse content type parameters. For now we just support
-     * four parameters used in mms: "type", "start", "name", "charset".
-     *
-     * @param pduDataStream pdu data input stream
-     * @param map to store parameters of Content-Type field
-     * @param length length of all the parameters
-     */
-    protected static void parseContentTypeParams(ByteArrayInputStream pduDataStream,
-            HashMap<Integer, Object> map, Integer length) {
-        /**
-         * From wap-230-wsp-20010705-a.pdf
-         * Parameter = Typed-parameter | Untyped-parameter
-         * Typed-parameter = Well-known-parameter-token Typed-value
-         * the actual expected type of the value is implied by the well-known parameter
-         * Well-known-parameter-token = Integer-value
-         * the code values used for parameters are specified in the Assigned Numbers appendix
-         * Typed-value = Compact-value | Text-value
-         * In addition to the expected type, there may be no value.
-         * If the value cannot be encoded using the expected type, it shall be encoded as text.
-         * Compact-value = Integer-value |
-         * Date-value | Delta-seconds-value | Q-value | Version-value |
-         * Uri-value
-         * Untyped-parameter = Token-text Untyped-value
-         * the type of the value is unknown, but it shall be encoded as an integer,
-         * if that is possible.
-         * Untyped-value = Integer-value | Text-value
-         */
-        assert(null != pduDataStream);
-        assert(length > 0);
-
-        int startPos = pduDataStream.available();
-        int tempPos = 0;
-        int lastLen = length;
-        while(0 < lastLen) {
-            int param = pduDataStream.read();
-            assert(-1 != param);
-            lastLen--;
-
-            switch (param) {
-                /**
-                 * From rfc2387, chapter 3.1
-                 * The type parameter must be specified and its value is the MIME media
-                 * type of the "root" body part. It permits a MIME user agent to
-                 * determine the content-type without reference to the enclosed body
-                 * part. If the value of the type parameter and the root body part's
-                 * content-type differ then the User Agent's behavior is undefined.
-                 *
-                 * From wap-230-wsp-20010705-a.pdf
-                 * type = Constrained-encoding
-                 * Constrained-encoding = Extension-Media | Short-integer
-                 * Extension-media = *TEXT End-of-string
-                 */
-                case PduPart.P_TYPE:
-                case PduPart.P_CT_MR_TYPE:
-                    pduDataStream.mark(1);
-                    int first = extractByteValue(pduDataStream);
-                    pduDataStream.reset();
-                    if (first > TEXT_MAX) {
-                        // Short-integer (well-known type)
-                        int index = parseShortInteger(pduDataStream);
-
-                        if (index < PduContentTypes.contentTypes.length) {
-                            byte[] type = (PduContentTypes.contentTypes[index]).getBytes();
-                            map.put(PduPart.P_TYPE, type);
-                        } else {
-                            //not support this type, ignore it.
-                        }
-                    } else {
-                        // Text-String (extension-media)
-                        byte[] type = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-                        if ((null != type) && (null != map)) {
-                            map.put(PduPart.P_TYPE, type);
-                        }
-                    }
-
-                    tempPos = pduDataStream.available();
-                    lastLen = length - (startPos - tempPos);
-                    break;
-
-                    /**
-                     * From oma-ts-mms-conf-v1_3.pdf, chapter 10.2.3.
-                     * Start Parameter Referring to Presentation
-                     *
-                     * From rfc2387, chapter 3.2
-                     * The start parameter, if given, is the content-ID of the compound
-                     * object's "root". If not present the "root" is the first body part in
-                     * the Multipart/Related entity. The "root" is the element the
-                     * applications processes first.
-                     *
-                     * From wap-230-wsp-20010705-a.pdf
-                     * start = Text-String
-                     */
-                case PduPart.P_START:
-                case PduPart.P_DEP_START:
-                    byte[] start = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-                    if ((null != start) && (null != map)) {
-                        map.put(PduPart.P_START, start);
-                    }
-
-                    tempPos = pduDataStream.available();
-                    lastLen = length - (startPos - tempPos);
-                    break;
-
-                    /**
-                     * From oma-ts-mms-conf-v1_3.pdf
-                     * In creation, the character set SHALL be either us-ascii
-                     * (IANA MIBenum 3) or utf-8 (IANA MIBenum 106)[Unicode].
-                     * In retrieval, both us-ascii and utf-8 SHALL be supported.
-                     *
-                     * From wap-230-wsp-20010705-a.pdf
-                     * charset = Well-known-charset|Text-String
-                     * Well-known-charset = Any-charset | Integer-value
-                     * Both are encoded using values from Character Set
-                     * Assignments table in Assigned Numbers
-                     * Any-charset = <Octet 128>
-                     * Equivalent to the special RFC2616 charset value "*"
-                     */
-                case PduPart.P_CHARSET:
-                    pduDataStream.mark(1);
-                    int firstValue = extractByteValue(pduDataStream);
-                    pduDataStream.reset();
-                    //Check first char
-                    if (((firstValue > TEXT_MIN) && (firstValue < TEXT_MAX)) ||
-                            (END_STRING_FLAG == firstValue)) {
-                        //Text-String (extension-charset)
-                        byte[] charsetStr = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-                        try {
-                            int charsetInt = CharacterSets.getMibEnumValue(
-                                    new String(charsetStr));
-                            map.put(PduPart.P_CHARSET, charsetInt);
-                        } catch (UnsupportedEncodingException e) {
-                            // Not a well-known charset, use "*".
-                            Log.e(LOG_TAG, Arrays.toString(charsetStr), e);
-                            map.put(PduPart.P_CHARSET, CharacterSets.ANY_CHARSET);
-                        }
-                    } else {
-                        //Well-known-charset
-                        int charset = (int) parseIntegerValue(pduDataStream);
-                        if (map != null) {
-                            map.put(PduPart.P_CHARSET, charset);
-                        }
-                    }
-
-                    tempPos = pduDataStream.available();
-                    lastLen = length - (startPos - tempPos);
-                    break;
-
-                    /**
-                     * From oma-ts-mms-conf-v1_3.pdf
-                     * A name for multipart object SHALL be encoded using name-parameter
-                     * for Content-Type header in WSP multipart headers.
-                     *
-                     * From wap-230-wsp-20010705-a.pdf
-                     * name = Text-String
-                     */
-                case PduPart.P_DEP_NAME:
-                case PduPart.P_NAME:
-                    byte[] name = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-                    if ((null != name) && (null != map)) {
-                        map.put(PduPart.P_NAME, name);
-                    }
-
-                    tempPos = pduDataStream.available();
-                    lastLen = length - (startPos - tempPos);
-                    break;
-                default:
-                    if (LOCAL_LOGV) {
-                        Log.v(LOG_TAG, "Not supported Content-Type parameter");
-                    }
-                if (-1 == skipWapValue(pduDataStream, lastLen)) {
-                    Log.e(LOG_TAG, "Corrupt Content-Type");
-                } else {
-                    lastLen = 0;
-                }
-                break;
-            }
-        }
-
-        if (0 != lastLen) {
-            Log.e(LOG_TAG, "Corrupt Content-Type");
-        }
-    }
-
-    /**
-     * Parse content type.
-     *
-     * @param pduDataStream pdu data input stream
-     * @param map to store parameters in Content-Type header field
-     * @return Content-Type value
-     */
-    protected static byte[] parseContentType(ByteArrayInputStream pduDataStream,
-            HashMap<Integer, Object> map) {
-        /**
-         * From wap-230-wsp-20010705-a.pdf
-         * Content-type-value = Constrained-media | Content-general-form
-         * Content-general-form = Value-length Media-type
-         * Media-type = (Well-known-media | Extension-Media) *(Parameter)
-         */
-        assert(null != pduDataStream);
-
-        byte[] contentType = null;
-        pduDataStream.mark(1);
-        int temp = pduDataStream.read();
-        assert(-1 != temp);
-        pduDataStream.reset();
-
-        int cur = (temp & 0xFF);
-
-        if (cur < TEXT_MIN) {
-            int length = parseValueLength(pduDataStream);
-            int startPos = pduDataStream.available();
-            pduDataStream.mark(1);
-            temp = pduDataStream.read();
-            assert(-1 != temp);
-            pduDataStream.reset();
-            int first = (temp & 0xFF);
-
-            if ((first >= TEXT_MIN) && (first <= TEXT_MAX)) {
-                contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-            } else if (first > TEXT_MAX) {
-                int index = parseShortInteger(pduDataStream);
-
-                if (index < PduContentTypes.contentTypes.length) { //well-known type
-                    contentType = (PduContentTypes.contentTypes[index]).getBytes();
-                } else {
-                    pduDataStream.reset();
-                    contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-                }
-            } else {
-                Log.e(LOG_TAG, "Corrupt content-type");
-                return (PduContentTypes.contentTypes[0]).getBytes(); //"*/*"
-            }
-
-            int endPos = pduDataStream.available();
-            int parameterLen = length - (startPos - endPos);
-            if (parameterLen > 0) {//have parameters
-                parseContentTypeParams(pduDataStream, map, parameterLen);
-            }
-
-            if (parameterLen < 0) {
-                Log.e(LOG_TAG, "Corrupt MMS message");
-                return (PduContentTypes.contentTypes[0]).getBytes(); //"*/*"
-            }
-        } else if (cur <= TEXT_MAX) {
-            contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-        } else {
-            contentType =
-                (PduContentTypes.contentTypes[parseShortInteger(pduDataStream)]).getBytes();
-        }
-
-        return contentType;
-    }
-
-    /**
-     * Parse part's headers.
-     *
-     * @param pduDataStream pdu data input stream
-     * @param part to store the header informations of the part
-     * @param length length of the headers
-     * @return true if parse successfully, false otherwise
-     */
-    protected static boolean parsePartHeaders(ByteArrayInputStream pduDataStream,
-            PduPart part, int length) {
-        assert(null != pduDataStream);
-        assert(null != part);
-        assert(length > 0);
-
-        /**
-         * From oma-ts-mms-conf-v1_3.pdf, chapter 10.2.
-         * A name for multipart object SHALL be encoded using name-parameter
-         * for Content-Type header in WSP multipart headers.
-         * In decoding, name-parameter of Content-Type SHALL be used if available.
-         * If name-parameter of Content-Type is not available,
-         * filename parameter of Content-Disposition header SHALL be used if available.
-         * If neither name-parameter of Content-Type header nor filename parameter
-         * of Content-Disposition header is available,
-         * Content-Location header SHALL be used if available.
-         *
-         * Within SMIL part the reference to the media object parts SHALL use
-         * either Content-ID or Content-Location mechanism [RFC2557]
-         * and the corresponding WSP part headers in media object parts
-         * contain the corresponding definitions.
-         */
-        int startPos = pduDataStream.available();
-        int tempPos = 0;
-        int lastLen = length;
-        while(0 < lastLen) {
-            int header = pduDataStream.read();
-            assert(-1 != header);
-            lastLen--;
-
-            if (header > TEXT_MAX) {
-                // Number assigned headers.
-                switch (header) {
-                    case PduPart.P_CONTENT_LOCATION:
-                        /**
-                         * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21
-                         * Content-location-value = Uri-value
-                         */
-                        byte[] contentLocation = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-                        if (null != contentLocation) {
-                            part.setContentLocation(contentLocation);
-                        }
-
-                        tempPos = pduDataStream.available();
-                        lastLen = length - (startPos - tempPos);
-                        break;
-                    case PduPart.P_CONTENT_ID:
-                        /**
-                         * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21
-                         * Content-ID-value = Quoted-string
-                         */
-                        byte[] contentId = parseWapString(pduDataStream, TYPE_QUOTED_STRING);
-                        if (null != contentId) {
-                            part.setContentId(contentId);
-                        }
-
-                        tempPos = pduDataStream.available();
-                        lastLen = length - (startPos - tempPos);
-                        break;
-                    case PduPart.P_DEP_CONTENT_DISPOSITION:
-                    case PduPart.P_CONTENT_DISPOSITION:
-                        /**
-                         * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21
-                         * Content-disposition-value = Value-length Disposition *(Parameter)
-                         * Disposition = Form-data | Attachment | Inline | Token-text
-                         * Form-data = <Octet 128>
-                         * Attachment = <Octet 129>
-                         * Inline = <Octet 130>
-                         */
-
-                        /*
-                         * some carrier mmsc servers do not support content_disposition
-                         * field correctly
-                         */
-                        boolean contentDisposition = Resources.getSystem().getBoolean(com
-                                .android.internal.R.bool.config_mms_content_disposition_support);
-
-                        if (contentDisposition) {
-                            int len = parseValueLength(pduDataStream);
-                            pduDataStream.mark(1);
-                            int thisStartPos = pduDataStream.available();
-                            int thisEndPos = 0;
-                            int value = pduDataStream.read();
-
-                            if (value == PduPart.P_DISPOSITION_FROM_DATA ) {
-                                part.setContentDisposition(PduPart.DISPOSITION_FROM_DATA);
-                            } else if (value == PduPart.P_DISPOSITION_ATTACHMENT) {
-                                part.setContentDisposition(PduPart.DISPOSITION_ATTACHMENT);
-                            } else if (value == PduPart.P_DISPOSITION_INLINE) {
-                                part.setContentDisposition(PduPart.DISPOSITION_INLINE);
-                            } else {
-                                pduDataStream.reset();
-                                /* Token-text */
-                                part.setContentDisposition(parseWapString(pduDataStream
-                                        , TYPE_TEXT_STRING));
-                            }
-
-                            /* get filename parameter and skip other parameters */
-                            thisEndPos = pduDataStream.available();
-                            if (thisStartPos - thisEndPos < len) {
-                                value = pduDataStream.read();
-                                if (value == PduPart.P_FILENAME) { //filename is text-string
-                                    part.setFilename(parseWapString(pduDataStream
-                                            , TYPE_TEXT_STRING));
-                                }
-
-                                /* skip other parameters */
-                                thisEndPos = pduDataStream.available();
-                                if (thisStartPos - thisEndPos < len) {
-                                    int last = len - (thisStartPos - thisEndPos);
-                                    byte[] temp = new byte[last];
-                                    pduDataStream.read(temp, 0, last);
-                                }
-                            }
-
-                            tempPos = pduDataStream.available();
-                            lastLen = length - (startPos - tempPos);
-                        }
-                        break;
-                    default:
-                        if (LOCAL_LOGV) {
-                            Log.v(LOG_TAG, "Not supported Part headers: " + header);
-                        }
-                    if (-1 == skipWapValue(pduDataStream, lastLen)) {
-                        Log.e(LOG_TAG, "Corrupt Part headers");
-                        return false;
-                    }
-                    lastLen = 0;
-                    break;
-                }
-            } else if ((header >= TEXT_MIN) && (header <= TEXT_MAX)) {
-                // Not assigned header.
-                byte[] tempHeader = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-                byte[] tempValue = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-
-                // Check the header whether it is "Content-Transfer-Encoding".
-                if (true ==
-                    PduPart.CONTENT_TRANSFER_ENCODING.equalsIgnoreCase(new String(tempHeader))) {
-                    part.setContentTransferEncoding(tempValue);
-                }
-
-                tempPos = pduDataStream.available();
-                lastLen = length - (startPos - tempPos);
-            } else {
-                if (LOCAL_LOGV) {
-                    Log.v(LOG_TAG, "Not supported Part headers: " + header);
-                }
-                // Skip all headers of this part.
-                if (-1 == skipWapValue(pduDataStream, lastLen)) {
-                    Log.e(LOG_TAG, "Corrupt Part headers");
-                    return false;
-                }
-                lastLen = 0;
-            }
-        }
-
-        if (0 != lastLen) {
-            Log.e(LOG_TAG, "Corrupt Part headers");
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Check the position of a specified part.
-     *
-     * @param part the part to be checked
-     * @return part position, THE_FIRST_PART when it's the
-     * first one, THE_LAST_PART when it's the last one.
-     */
-    private static int checkPartPosition(PduPart part) {
-        assert(null != part);
-        if ((null == mTypeParam) &&
-                (null == mStartParam)) {
-            return THE_LAST_PART;
-        }
-
-        /* check part's content-id */
-        if (null != mStartParam) {
-            byte[] contentId = part.getContentId();
-            if (null != contentId) {
-                if (true == Arrays.equals(mStartParam, contentId)) {
-                    return THE_FIRST_PART;
-                }
-            }
-        }
-
-        /* check part's content-type */
-        if (null != mTypeParam) {
-            byte[] contentType = part.getContentType();
-            if (null != contentType) {
-                if (true == Arrays.equals(mTypeParam, contentType)) {
-                    return THE_FIRST_PART;
-                }
-            }
-        }
-
-        return THE_LAST_PART;
-    }
-
-    /**
-     * Check mandatory headers of a pdu.
-     *
-     * @param headers pdu headers
-     * @return true if the pdu has all of the mandatory headers, false otherwise.
-     */
-    protected static boolean checkMandatoryHeader(PduHeaders headers) {
-        if (null == headers) {
-            return false;
-        }
-
-        /* get message type */
-        int messageType = headers.getOctet(PduHeaders.MESSAGE_TYPE);
-
-        /* check Mms-Version field */
-        int mmsVersion = headers.getOctet(PduHeaders.MMS_VERSION);
-        if (0 == mmsVersion) {
-            // Every message should have Mms-Version field.
-            return false;
-        }
-
-        /* check mandatory header fields */
-        switch (messageType) {
-            case PduHeaders.MESSAGE_TYPE_SEND_REQ:
-                // Content-Type field.
-                byte[] srContentType = headers.getTextString(PduHeaders.CONTENT_TYPE);
-                if (null == srContentType) {
-                    return false;
-                }
-
-                // From field.
-                EncodedStringValue srFrom = headers.getEncodedStringValue(PduHeaders.FROM);
-                if (null == srFrom) {
-                    return false;
-                }
-
-                // Transaction-Id field.
-                byte[] srTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID);
-                if (null == srTransactionId) {
-                    return false;
-                }
-
-                break;
-            case PduHeaders.MESSAGE_TYPE_SEND_CONF:
-                // Response-Status field.
-                int scResponseStatus = headers.getOctet(PduHeaders.RESPONSE_STATUS);
-                if (0 == scResponseStatus) {
-                    return false;
-                }
-
-                // Transaction-Id field.
-                byte[] scTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID);
-                if (null == scTransactionId) {
-                    return false;
-                }
-
-                break;
-            case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND:
-                // Content-Location field.
-                byte[] niContentLocation = headers.getTextString(PduHeaders.CONTENT_LOCATION);
-                if (null == niContentLocation) {
-                    return false;
-                }
-
-                // Expiry field.
-                long niExpiry = headers.getLongInteger(PduHeaders.EXPIRY);
-                if (-1 == niExpiry) {
-                    return false;
-                }
-
-                // Message-Class field.
-                byte[] niMessageClass = headers.getTextString(PduHeaders.MESSAGE_CLASS);
-                if (null == niMessageClass) {
-                    return false;
-                }
-
-                // Message-Size field.
-                long niMessageSize = headers.getLongInteger(PduHeaders.MESSAGE_SIZE);
-                if (-1 == niMessageSize) {
-                    return false;
-                }
-
-                // Transaction-Id field.
-                byte[] niTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID);
-                if (null == niTransactionId) {
-                    return false;
-                }
-
-                break;
-            case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND:
-                // Status field.
-                int nriStatus = headers.getOctet(PduHeaders.STATUS);
-                if (0 == nriStatus) {
-                    return false;
-                }
-
-                // Transaction-Id field.
-                byte[] nriTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID);
-                if (null == nriTransactionId) {
-                    return false;
-                }
-
-                break;
-            case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF:
-                // Content-Type field.
-                byte[] rcContentType = headers.getTextString(PduHeaders.CONTENT_TYPE);
-                if (null == rcContentType) {
-                    return false;
-                }
-
-                // Date field.
-                long rcDate = headers.getLongInteger(PduHeaders.DATE);
-                if (-1 == rcDate) {
-                    return false;
-                }
-
-                break;
-            case PduHeaders.MESSAGE_TYPE_DELIVERY_IND:
-                // Date field.
-                long diDate = headers.getLongInteger(PduHeaders.DATE);
-                if (-1 == diDate) {
-                    return false;
-                }
-
-                // Message-Id field.
-                byte[] diMessageId = headers.getTextString(PduHeaders.MESSAGE_ID);
-                if (null == diMessageId) {
-                    return false;
-                }
-
-                // Status field.
-                int diStatus = headers.getOctet(PduHeaders.STATUS);
-                if (0 == diStatus) {
-                    return false;
-                }
-
-                // To field.
-                EncodedStringValue[] diTo = headers.getEncodedStringValues(PduHeaders.TO);
-                if (null == diTo) {
-                    return false;
-                }
-
-                break;
-            case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND:
-                // Transaction-Id field.
-                byte[] aiTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID);
-                if (null == aiTransactionId) {
-                    return false;
-                }
-
-                break;
-            case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND:
-                // Date field.
-                long roDate = headers.getLongInteger(PduHeaders.DATE);
-                if (-1 == roDate) {
-                    return false;
-                }
-
-                // From field.
-                EncodedStringValue roFrom = headers.getEncodedStringValue(PduHeaders.FROM);
-                if (null == roFrom) {
-                    return false;
-                }
-
-                // Message-Id field.
-                byte[] roMessageId = headers.getTextString(PduHeaders.MESSAGE_ID);
-                if (null == roMessageId) {
-                    return false;
-                }
-
-                // Read-Status field.
-                int roReadStatus = headers.getOctet(PduHeaders.READ_STATUS);
-                if (0 == roReadStatus) {
-                    return false;
-                }
-
-                // To field.
-                EncodedStringValue[] roTo = headers.getEncodedStringValues(PduHeaders.TO);
-                if (null == roTo) {
-                    return false;
-                }
-
-                break;
-            case PduHeaders.MESSAGE_TYPE_READ_REC_IND:
-                // From field.
-                EncodedStringValue rrFrom = headers.getEncodedStringValue(PduHeaders.FROM);
-                if (null == rrFrom) {
-                    return false;
-                }
-
-                // Message-Id field.
-                byte[] rrMessageId = headers.getTextString(PduHeaders.MESSAGE_ID);
-                if (null == rrMessageId) {
-                    return false;
-                }
-
-                // Read-Status field.
-                int rrReadStatus = headers.getOctet(PduHeaders.READ_STATUS);
-                if (0 == rrReadStatus) {
-                    return false;
-                }
-
-                // To field.
-                EncodedStringValue[] rrTo = headers.getEncodedStringValues(PduHeaders.TO);
-                if (null == rrTo) {
-                    return false;
-                }
-
-                break;
-            default:
-                // Parser doesn't support this message type in this version.
-                return false;
-        }
-
-        return true;
-    }
-}
diff --git a/core/java/com/google/android/mms/pdu/PduPart.java b/core/java/com/google/android/mms/pdu/PduPart.java
deleted file mode 100644
index b43e388..0000000
--- a/core/java/com/google/android/mms/pdu/PduPart.java
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Esmertec AG.
- * Copyright (C) 2007-2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import android.net.Uri;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * The pdu part.
- */
-public class PduPart {
-    /**
-     * Well-Known Parameters.
-     */
-    public static final int P_Q                  = 0x80;
-    public static final int P_CHARSET            = 0x81;
-    public static final int P_LEVEL              = 0x82;
-    public static final int P_TYPE               = 0x83;
-    public static final int P_DEP_NAME           = 0x85;
-    public static final int P_DEP_FILENAME       = 0x86;
-    public static final int P_DIFFERENCES        = 0x87;
-    public static final int P_PADDING            = 0x88;
-    // This value of "TYPE" s used with Content-Type: multipart/related
-    public static final int P_CT_MR_TYPE         = 0x89;
-    public static final int P_DEP_START          = 0x8A;
-    public static final int P_DEP_START_INFO     = 0x8B;
-    public static final int P_DEP_COMMENT        = 0x8C;
-    public static final int P_DEP_DOMAIN         = 0x8D;
-    public static final int P_MAX_AGE            = 0x8E;
-    public static final int P_DEP_PATH           = 0x8F;
-    public static final int P_SECURE             = 0x90;
-    public static final int P_SEC                = 0x91;
-    public static final int P_MAC                = 0x92;
-    public static final int P_CREATION_DATE      = 0x93;
-    public static final int P_MODIFICATION_DATE  = 0x94;
-    public static final int P_READ_DATE          = 0x95;
-    public static final int P_SIZE               = 0x96;
-    public static final int P_NAME               = 0x97;
-    public static final int P_FILENAME           = 0x98;
-    public static final int P_START              = 0x99;
-    public static final int P_START_INFO         = 0x9A;
-    public static final int P_COMMENT            = 0x9B;
-    public static final int P_DOMAIN             = 0x9C;
-    public static final int P_PATH               = 0x9D;
-
-    /**
-     *  Header field names.
-     */
-     public static final int P_CONTENT_TYPE       = 0x91;
-     public static final int P_CONTENT_LOCATION   = 0x8E;
-     public static final int P_CONTENT_ID         = 0xC0;
-     public static final int P_DEP_CONTENT_DISPOSITION = 0xAE;
-     public static final int P_CONTENT_DISPOSITION = 0xC5;
-    // The next header is unassigned header, use reserved header(0x48) value.
-     public static final int P_CONTENT_TRANSFER_ENCODING = 0xC8;
-
-     /**
-      * Content=Transfer-Encoding string.
-      */
-     public static final String CONTENT_TRANSFER_ENCODING =
-             "Content-Transfer-Encoding";
-
-     /**
-      * Value of Content-Transfer-Encoding.
-      */
-     public static final String P_BINARY = "binary";
-     public static final String P_7BIT = "7bit";
-     public static final String P_8BIT = "8bit";
-     public static final String P_BASE64 = "base64";
-     public static final String P_QUOTED_PRINTABLE = "quoted-printable";
-
-     /**
-      * Value of disposition can be set to PduPart when the value is octet in
-      * the PDU.
-      * "from-data" instead of Form-data<Octet 128>.
-      * "attachment" instead of Attachment<Octet 129>.
-      * "inline" instead of Inline<Octet 130>.
-      */
-     static final byte[] DISPOSITION_FROM_DATA = "from-data".getBytes();
-     static final byte[] DISPOSITION_ATTACHMENT = "attachment".getBytes();
-     static final byte[] DISPOSITION_INLINE = "inline".getBytes();
-
-     /**
-      * Content-Disposition value.
-      */
-     public static final int P_DISPOSITION_FROM_DATA  = 0x80;
-     public static final int P_DISPOSITION_ATTACHMENT = 0x81;
-     public static final int P_DISPOSITION_INLINE     = 0x82;
-
-     /**
-      * Header of part.
-      */
-     private Map<Integer, Object> mPartHeader = null;
-
-     /**
-      * Data uri.
-      */
-     private Uri mUri = null;
-
-     /**
-      * Part data.
-      */
-     private byte[] mPartData = null;
-
-     private static final String TAG = "PduPart";
-
-     /**
-      * Empty Constructor.
-      */
-     public PduPart() {
-         mPartHeader = new HashMap<Integer, Object>();
-     }
-
-     /**
-      * Set part data. The data are stored as byte array.
-      *
-      * @param data the data
-      */
-     public void setData(byte[] data) {
-         if(data == null) {
-            return;
-        }
-
-         mPartData = new byte[data.length];
-         System.arraycopy(data, 0, mPartData, 0, data.length);
-     }
-
-     /**
-      * @return A copy of the part data or null if the data wasn't set or
-      *         the data is stored as Uri.
-      * @see #getDataUri
-      */
-     public byte[] getData() {
-         if(mPartData == null) {
-            return null;
-         }
-
-         byte[] byteArray = new byte[mPartData.length];
-         System.arraycopy(mPartData, 0, byteArray, 0, mPartData.length);
-         return byteArray;
-     }
-
-     /**
-      * Set data uri. The data are stored as Uri.
-      *
-      * @param uri the uri
-      */
-     public void setDataUri(Uri uri) {
-         mUri = uri;
-     }
-
-     /**
-      * @return The Uri of the part data or null if the data wasn't set or
-      *         the data is stored as byte array.
-      * @see #getData
-      */
-     public Uri getDataUri() {
-         return mUri;
-     }
-
-     /**
-      * Set Content-id value
-      *
-      * @param contentId the content-id value
-      * @throws NullPointerException if the value is null.
-      */
-     public void setContentId(byte[] contentId) {
-         if((contentId == null) || (contentId.length == 0)) {
-             throw new IllegalArgumentException(
-                     "Content-Id may not be null or empty.");
-         }
-
-         if ((contentId.length > 1)
-                 && ((char) contentId[0] == '<')
-                 && ((char) contentId[contentId.length - 1] == '>')) {
-             mPartHeader.put(P_CONTENT_ID, contentId);
-             return;
-         }
-
-         // Insert beginning '<' and trailing '>' for Content-Id.
-         byte[] buffer = new byte[contentId.length + 2];
-         buffer[0] = (byte) (0xff & '<');
-         buffer[buffer.length - 1] = (byte) (0xff & '>');
-         System.arraycopy(contentId, 0, buffer, 1, contentId.length);
-         mPartHeader.put(P_CONTENT_ID, buffer);
-     }
-
-     /**
-      * Get Content-id value.
-      *
-      * @return the value
-      */
-     public byte[] getContentId() {
-         return (byte[]) mPartHeader.get(P_CONTENT_ID);
-     }
-
-     /**
-      * Set Char-set value.
-      *
-      * @param charset the value
-      */
-     public void setCharset(int charset) {
-         mPartHeader.put(P_CHARSET, charset);
-     }
-
-     /**
-      * Get Char-set value
-      *
-      * @return the charset value. Return 0 if charset was not set.
-      */
-     public int getCharset() {
-         Integer charset = (Integer) mPartHeader.get(P_CHARSET);
-         if(charset == null) {
-             return 0;
-         } else {
-             return charset.intValue();
-         }
-     }
-
-     /**
-      * Set Content-Location value.
-      *
-      * @param contentLocation the value
-      * @throws NullPointerException if the value is null.
-      */
-     public void setContentLocation(byte[] contentLocation) {
-         if(contentLocation == null) {
-             throw new NullPointerException("null content-location");
-         }
-
-         mPartHeader.put(P_CONTENT_LOCATION, contentLocation);
-     }
-
-     /**
-      * Get Content-Location value.
-      *
-      * @return the value
-      *     return PduPart.disposition[0] instead of <Octet 128> (Form-data).
-      *     return PduPart.disposition[1] instead of <Octet 129> (Attachment).
-      *     return PduPart.disposition[2] instead of <Octet 130> (Inline).
-      */
-     public byte[] getContentLocation() {
-         return (byte[]) mPartHeader.get(P_CONTENT_LOCATION);
-     }
-
-     /**
-      * Set Content-Disposition value.
-      * Use PduPart.disposition[0] instead of <Octet 128> (Form-data).
-      * Use PduPart.disposition[1] instead of <Octet 129> (Attachment).
-      * Use PduPart.disposition[2] instead of <Octet 130> (Inline).
-      *
-      * @param contentDisposition the value
-      * @throws NullPointerException if the value is null.
-      */
-     public void setContentDisposition(byte[] contentDisposition) {
-         if(contentDisposition == null) {
-             throw new NullPointerException("null content-disposition");
-         }
-
-         mPartHeader.put(P_CONTENT_DISPOSITION, contentDisposition);
-     }
-
-     /**
-      * Get Content-Disposition value.
-      *
-      * @return the value
-      */
-     public byte[] getContentDisposition() {
-         return (byte[]) mPartHeader.get(P_CONTENT_DISPOSITION);
-     }
-
-     /**
-      *  Set Content-Type value.
-      *
-      *  @param value the value
-      *  @throws NullPointerException if the value is null.
-      */
-     public void setContentType(byte[] contentType) {
-         if(contentType == null) {
-             throw new NullPointerException("null content-type");
-         }
-
-         mPartHeader.put(P_CONTENT_TYPE, contentType);
-     }
-
-     /**
-      * Get Content-Type value of part.
-      *
-      * @return the value
-      */
-     public byte[] getContentType() {
-         return (byte[]) mPartHeader.get(P_CONTENT_TYPE);
-     }
-
-     /**
-      * Set Content-Transfer-Encoding value
-      *
-      * @param contentId the content-id value
-      * @throws NullPointerException if the value is null.
-      */
-     public void setContentTransferEncoding(byte[] contentTransferEncoding) {
-         if(contentTransferEncoding == null) {
-             throw new NullPointerException("null content-transfer-encoding");
-         }
-
-         mPartHeader.put(P_CONTENT_TRANSFER_ENCODING, contentTransferEncoding);
-     }
-
-     /**
-      * Get Content-Transfer-Encoding value.
-      *
-      * @return the value
-      */
-     public byte[] getContentTransferEncoding() {
-         return (byte[]) mPartHeader.get(P_CONTENT_TRANSFER_ENCODING);
-     }
-
-     /**
-      * Set Content-type parameter: name.
-      *
-      * @param name the name value
-      * @throws NullPointerException if the value is null.
-      */
-     public void setName(byte[] name) {
-         if(null == name) {
-             throw new NullPointerException("null content-id");
-         }
-
-         mPartHeader.put(P_NAME, name);
-     }
-
-     /**
-      *  Get content-type parameter: name.
-      *
-      *  @return the name
-      */
-     public byte[] getName() {
-         return (byte[]) mPartHeader.get(P_NAME);
-     }
-
-     /**
-      * Get Content-disposition parameter: filename
-      *
-      * @param fileName the filename value
-      * @throws NullPointerException if the value is null.
-      */
-     public void setFilename(byte[] fileName) {
-         if(null == fileName) {
-             throw new NullPointerException("null content-id");
-         }
-
-         mPartHeader.put(P_FILENAME, fileName);
-     }
-
-     /**
-      * Set Content-disposition parameter: filename
-      *
-      * @return the filename
-      */
-     public byte[] getFilename() {
-         return (byte[]) mPartHeader.get(P_FILENAME);
-     }
-
-    public String generateLocation() {
-        // Assumption: At least one of the content-location / name / filename
-        // or content-id should be set. This is guaranteed by the PduParser
-        // for incoming messages and by MM composer for outgoing messages.
-        byte[] location = (byte[]) mPartHeader.get(P_NAME);
-        if(null == location) {
-            location = (byte[]) mPartHeader.get(P_FILENAME);
-
-            if (null == location) {
-                location = (byte[]) mPartHeader.get(P_CONTENT_LOCATION);
-            }
-        }
-
-        if (null == location) {
-            byte[] contentId = (byte[]) mPartHeader.get(P_CONTENT_ID);
-            return "cid:" + new String(contentId);
-        } else {
-            return new String(location);
-        }
-    }
-}
-
diff --git a/core/java/com/google/android/mms/pdu/PduPersister.java b/core/java/com/google/android/mms/pdu/PduPersister.java
deleted file mode 100644
index ee285aa..0000000
--- a/core/java/com/google/android/mms/pdu/PduPersister.java
+++ /dev/null
@@ -1,1477 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Esmertec AG.
- * Copyright (C) 2007-2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.ContentType;
-import com.google.android.mms.InvalidHeaderValueException;
-import com.google.android.mms.MmsException;
-import com.google.android.mms.util.DownloadDrmHelper;
-import com.google.android.mms.util.DrmConvertSession;
-import com.google.android.mms.util.PduCache;
-import com.google.android.mms.util.PduCacheEntry;
-import com.google.android.mms.util.SqliteWrapper;
-
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteException;
-import android.drm.DrmManagerClient;
-import android.net.Uri;
-import android.os.FileUtils;
-import android.provider.MediaStore;
-import android.provider.Telephony;
-import android.provider.Telephony.Mms;
-import android.provider.Telephony.MmsSms;
-import android.provider.Telephony.Threads;
-import android.provider.Telephony.Mms.Addr;
-import android.provider.Telephony.Mms.Part;
-import android.provider.Telephony.MmsSms.PendingMessages;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-
-import com.google.android.mms.pdu.EncodedStringValue;
-
-/**
- * This class is the high-level manager of PDU storage.
- */
-public class PduPersister {
-    private static final String TAG = "PduPersister";
-    private static final boolean DEBUG = false;
-    private static final boolean LOCAL_LOGV = false;
-
-    private static final long DUMMY_THREAD_ID = Long.MAX_VALUE;
-
-    /**
-     * The uri of temporary drm objects.
-     */
-    public static final String TEMPORARY_DRM_OBJECT_URI =
-        "content://mms/" + Long.MAX_VALUE + "/part";
-    /**
-     * Indicate that we transiently failed to process a MM.
-     */
-    public static final int PROC_STATUS_TRANSIENT_FAILURE   = 1;
-    /**
-     * Indicate that we permanently failed to process a MM.
-     */
-    public static final int PROC_STATUS_PERMANENTLY_FAILURE = 2;
-    /**
-     * Indicate that we have successfully processed a MM.
-     */
-    public static final int PROC_STATUS_COMPLETED           = 3;
-
-    private static PduPersister sPersister;
-    private static final PduCache PDU_CACHE_INSTANCE;
-
-    private static final int[] ADDRESS_FIELDS = new int[] {
-            PduHeaders.BCC,
-            PduHeaders.CC,
-            PduHeaders.FROM,
-            PduHeaders.TO
-    };
-
-    private static final String[] PDU_PROJECTION = new String[] {
-        Mms._ID,
-        Mms.MESSAGE_BOX,
-        Mms.THREAD_ID,
-        Mms.RETRIEVE_TEXT,
-        Mms.SUBJECT,
-        Mms.CONTENT_LOCATION,
-        Mms.CONTENT_TYPE,
-        Mms.MESSAGE_CLASS,
-        Mms.MESSAGE_ID,
-        Mms.RESPONSE_TEXT,
-        Mms.TRANSACTION_ID,
-        Mms.CONTENT_CLASS,
-        Mms.DELIVERY_REPORT,
-        Mms.MESSAGE_TYPE,
-        Mms.MMS_VERSION,
-        Mms.PRIORITY,
-        Mms.READ_REPORT,
-        Mms.READ_STATUS,
-        Mms.REPORT_ALLOWED,
-        Mms.RETRIEVE_STATUS,
-        Mms.STATUS,
-        Mms.DATE,
-        Mms.DELIVERY_TIME,
-        Mms.EXPIRY,
-        Mms.MESSAGE_SIZE,
-        Mms.SUBJECT_CHARSET,
-        Mms.RETRIEVE_TEXT_CHARSET,
-    };
-
-    private static final int PDU_COLUMN_ID                    = 0;
-    private static final int PDU_COLUMN_MESSAGE_BOX           = 1;
-    private static final int PDU_COLUMN_THREAD_ID             = 2;
-    private static final int PDU_COLUMN_RETRIEVE_TEXT         = 3;
-    private static final int PDU_COLUMN_SUBJECT               = 4;
-    private static final int PDU_COLUMN_CONTENT_LOCATION      = 5;
-    private static final int PDU_COLUMN_CONTENT_TYPE          = 6;
-    private static final int PDU_COLUMN_MESSAGE_CLASS         = 7;
-    private static final int PDU_COLUMN_MESSAGE_ID            = 8;
-    private static final int PDU_COLUMN_RESPONSE_TEXT         = 9;
-    private static final int PDU_COLUMN_TRANSACTION_ID        = 10;
-    private static final int PDU_COLUMN_CONTENT_CLASS         = 11;
-    private static final int PDU_COLUMN_DELIVERY_REPORT       = 12;
-    private static final int PDU_COLUMN_MESSAGE_TYPE          = 13;
-    private static final int PDU_COLUMN_MMS_VERSION           = 14;
-    private static final int PDU_COLUMN_PRIORITY              = 15;
-    private static final int PDU_COLUMN_READ_REPORT           = 16;
-    private static final int PDU_COLUMN_READ_STATUS           = 17;
-    private static final int PDU_COLUMN_REPORT_ALLOWED        = 18;
-    private static final int PDU_COLUMN_RETRIEVE_STATUS       = 19;
-    private static final int PDU_COLUMN_STATUS                = 20;
-    private static final int PDU_COLUMN_DATE                  = 21;
-    private static final int PDU_COLUMN_DELIVERY_TIME         = 22;
-    private static final int PDU_COLUMN_EXPIRY                = 23;
-    private static final int PDU_COLUMN_MESSAGE_SIZE          = 24;
-    private static final int PDU_COLUMN_SUBJECT_CHARSET       = 25;
-    private static final int PDU_COLUMN_RETRIEVE_TEXT_CHARSET = 26;
-
-    private static final String[] PART_PROJECTION = new String[] {
-        Part._ID,
-        Part.CHARSET,
-        Part.CONTENT_DISPOSITION,
-        Part.CONTENT_ID,
-        Part.CONTENT_LOCATION,
-        Part.CONTENT_TYPE,
-        Part.FILENAME,
-        Part.NAME,
-        Part.TEXT
-    };
-
-    private static final int PART_COLUMN_ID                  = 0;
-    private static final int PART_COLUMN_CHARSET             = 1;
-    private static final int PART_COLUMN_CONTENT_DISPOSITION = 2;
-    private static final int PART_COLUMN_CONTENT_ID          = 3;
-    private static final int PART_COLUMN_CONTENT_LOCATION    = 4;
-    private static final int PART_COLUMN_CONTENT_TYPE        = 5;
-    private static final int PART_COLUMN_FILENAME            = 6;
-    private static final int PART_COLUMN_NAME                = 7;
-    private static final int PART_COLUMN_TEXT                = 8;
-
-    private static final HashMap<Uri, Integer> MESSAGE_BOX_MAP;
-    // These map are used for convenience in persist() and load().
-    private static final HashMap<Integer, Integer> CHARSET_COLUMN_INDEX_MAP;
-    private static final HashMap<Integer, Integer> ENCODED_STRING_COLUMN_INDEX_MAP;
-    private static final HashMap<Integer, Integer> TEXT_STRING_COLUMN_INDEX_MAP;
-    private static final HashMap<Integer, Integer> OCTET_COLUMN_INDEX_MAP;
-    private static final HashMap<Integer, Integer> LONG_COLUMN_INDEX_MAP;
-    private static final HashMap<Integer, String> CHARSET_COLUMN_NAME_MAP;
-    private static final HashMap<Integer, String> ENCODED_STRING_COLUMN_NAME_MAP;
-    private static final HashMap<Integer, String> TEXT_STRING_COLUMN_NAME_MAP;
-    private static final HashMap<Integer, String> OCTET_COLUMN_NAME_MAP;
-    private static final HashMap<Integer, String> LONG_COLUMN_NAME_MAP;
-
-    static {
-        MESSAGE_BOX_MAP = new HashMap<Uri, Integer>();
-        MESSAGE_BOX_MAP.put(Mms.Inbox.CONTENT_URI,  Mms.MESSAGE_BOX_INBOX);
-        MESSAGE_BOX_MAP.put(Mms.Sent.CONTENT_URI,   Mms.MESSAGE_BOX_SENT);
-        MESSAGE_BOX_MAP.put(Mms.Draft.CONTENT_URI,  Mms.MESSAGE_BOX_DRAFTS);
-        MESSAGE_BOX_MAP.put(Mms.Outbox.CONTENT_URI, Mms.MESSAGE_BOX_OUTBOX);
-
-        CHARSET_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>();
-        CHARSET_COLUMN_INDEX_MAP.put(PduHeaders.SUBJECT, PDU_COLUMN_SUBJECT_CHARSET);
-        CHARSET_COLUMN_INDEX_MAP.put(PduHeaders.RETRIEVE_TEXT, PDU_COLUMN_RETRIEVE_TEXT_CHARSET);
-
-        CHARSET_COLUMN_NAME_MAP = new HashMap<Integer, String>();
-        CHARSET_COLUMN_NAME_MAP.put(PduHeaders.SUBJECT, Mms.SUBJECT_CHARSET);
-        CHARSET_COLUMN_NAME_MAP.put(PduHeaders.RETRIEVE_TEXT, Mms.RETRIEVE_TEXT_CHARSET);
-
-        // Encoded string field code -> column index/name map.
-        ENCODED_STRING_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>();
-        ENCODED_STRING_COLUMN_INDEX_MAP.put(PduHeaders.RETRIEVE_TEXT, PDU_COLUMN_RETRIEVE_TEXT);
-        ENCODED_STRING_COLUMN_INDEX_MAP.put(PduHeaders.SUBJECT, PDU_COLUMN_SUBJECT);
-
-        ENCODED_STRING_COLUMN_NAME_MAP = new HashMap<Integer, String>();
-        ENCODED_STRING_COLUMN_NAME_MAP.put(PduHeaders.RETRIEVE_TEXT, Mms.RETRIEVE_TEXT);
-        ENCODED_STRING_COLUMN_NAME_MAP.put(PduHeaders.SUBJECT, Mms.SUBJECT);
-
-        // Text string field code -> column index/name map.
-        TEXT_STRING_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>();
-        TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.CONTENT_LOCATION, PDU_COLUMN_CONTENT_LOCATION);
-        TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.CONTENT_TYPE, PDU_COLUMN_CONTENT_TYPE);
-        TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_CLASS, PDU_COLUMN_MESSAGE_CLASS);
-        TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_ID, PDU_COLUMN_MESSAGE_ID);
-        TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.RESPONSE_TEXT, PDU_COLUMN_RESPONSE_TEXT);
-        TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.TRANSACTION_ID, PDU_COLUMN_TRANSACTION_ID);
-
-        TEXT_STRING_COLUMN_NAME_MAP = new HashMap<Integer, String>();
-        TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.CONTENT_LOCATION, Mms.CONTENT_LOCATION);
-        TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.CONTENT_TYPE, Mms.CONTENT_TYPE);
-        TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_CLASS, Mms.MESSAGE_CLASS);
-        TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_ID, Mms.MESSAGE_ID);
-        TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.RESPONSE_TEXT, Mms.RESPONSE_TEXT);
-        TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.TRANSACTION_ID, Mms.TRANSACTION_ID);
-
-        // Octet field code -> column index/name map.
-        OCTET_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>();
-        OCTET_COLUMN_INDEX_MAP.put(PduHeaders.CONTENT_CLASS, PDU_COLUMN_CONTENT_CLASS);
-        OCTET_COLUMN_INDEX_MAP.put(PduHeaders.DELIVERY_REPORT, PDU_COLUMN_DELIVERY_REPORT);
-        OCTET_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_TYPE, PDU_COLUMN_MESSAGE_TYPE);
-        OCTET_COLUMN_INDEX_MAP.put(PduHeaders.MMS_VERSION, PDU_COLUMN_MMS_VERSION);
-        OCTET_COLUMN_INDEX_MAP.put(PduHeaders.PRIORITY, PDU_COLUMN_PRIORITY);
-        OCTET_COLUMN_INDEX_MAP.put(PduHeaders.READ_REPORT, PDU_COLUMN_READ_REPORT);
-        OCTET_COLUMN_INDEX_MAP.put(PduHeaders.READ_STATUS, PDU_COLUMN_READ_STATUS);
-        OCTET_COLUMN_INDEX_MAP.put(PduHeaders.REPORT_ALLOWED, PDU_COLUMN_REPORT_ALLOWED);
-        OCTET_COLUMN_INDEX_MAP.put(PduHeaders.RETRIEVE_STATUS, PDU_COLUMN_RETRIEVE_STATUS);
-        OCTET_COLUMN_INDEX_MAP.put(PduHeaders.STATUS, PDU_COLUMN_STATUS);
-
-        OCTET_COLUMN_NAME_MAP = new HashMap<Integer, String>();
-        OCTET_COLUMN_NAME_MAP.put(PduHeaders.CONTENT_CLASS, Mms.CONTENT_CLASS);
-        OCTET_COLUMN_NAME_MAP.put(PduHeaders.DELIVERY_REPORT, Mms.DELIVERY_REPORT);
-        OCTET_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_TYPE, Mms.MESSAGE_TYPE);
-        OCTET_COLUMN_NAME_MAP.put(PduHeaders.MMS_VERSION, Mms.MMS_VERSION);
-        OCTET_COLUMN_NAME_MAP.put(PduHeaders.PRIORITY, Mms.PRIORITY);
-        OCTET_COLUMN_NAME_MAP.put(PduHeaders.READ_REPORT, Mms.READ_REPORT);
-        OCTET_COLUMN_NAME_MAP.put(PduHeaders.READ_STATUS, Mms.READ_STATUS);
-        OCTET_COLUMN_NAME_MAP.put(PduHeaders.REPORT_ALLOWED, Mms.REPORT_ALLOWED);
-        OCTET_COLUMN_NAME_MAP.put(PduHeaders.RETRIEVE_STATUS, Mms.RETRIEVE_STATUS);
-        OCTET_COLUMN_NAME_MAP.put(PduHeaders.STATUS, Mms.STATUS);
-
-        // Long field code -> column index/name map.
-        LONG_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>();
-        LONG_COLUMN_INDEX_MAP.put(PduHeaders.DATE, PDU_COLUMN_DATE);
-        LONG_COLUMN_INDEX_MAP.put(PduHeaders.DELIVERY_TIME, PDU_COLUMN_DELIVERY_TIME);
-        LONG_COLUMN_INDEX_MAP.put(PduHeaders.EXPIRY, PDU_COLUMN_EXPIRY);
-        LONG_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_SIZE, PDU_COLUMN_MESSAGE_SIZE);
-
-        LONG_COLUMN_NAME_MAP = new HashMap<Integer, String>();
-        LONG_COLUMN_NAME_MAP.put(PduHeaders.DATE, Mms.DATE);
-        LONG_COLUMN_NAME_MAP.put(PduHeaders.DELIVERY_TIME, Mms.DELIVERY_TIME);
-        LONG_COLUMN_NAME_MAP.put(PduHeaders.EXPIRY, Mms.EXPIRY);
-        LONG_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_SIZE, Mms.MESSAGE_SIZE);
-
-        PDU_CACHE_INSTANCE = PduCache.getInstance();
-     }
-
-    private final Context mContext;
-    private final ContentResolver mContentResolver;
-    private final DrmManagerClient mDrmManagerClient;
-
-    private PduPersister(Context context) {
-        mContext = context;
-        mContentResolver = context.getContentResolver();
-        mDrmManagerClient = new DrmManagerClient(context);
-     }
-
-    /** Get(or create if not exist) an instance of PduPersister */
-    public static PduPersister getPduPersister(Context context) {
-        if ((sPersister == null) || !context.equals(sPersister.mContext)) {
-            sPersister = new PduPersister(context);
-        }
-
-        return sPersister;
-    }
-
-    private void setEncodedStringValueToHeaders(
-            Cursor c, int columnIndex,
-            PduHeaders headers, int mapColumn) {
-        String s = c.getString(columnIndex);
-        if ((s != null) && (s.length() > 0)) {
-            int charsetColumnIndex = CHARSET_COLUMN_INDEX_MAP.get(mapColumn);
-            int charset = c.getInt(charsetColumnIndex);
-            EncodedStringValue value = new EncodedStringValue(
-                    charset, getBytes(s));
-            headers.setEncodedStringValue(value, mapColumn);
-        }
-    }
-
-    private void setTextStringToHeaders(
-            Cursor c, int columnIndex,
-            PduHeaders headers, int mapColumn) {
-        String s = c.getString(columnIndex);
-        if (s != null) {
-            headers.setTextString(getBytes(s), mapColumn);
-        }
-    }
-
-    private void setOctetToHeaders(
-            Cursor c, int columnIndex,
-            PduHeaders headers, int mapColumn) throws InvalidHeaderValueException {
-        if (!c.isNull(columnIndex)) {
-            int b = c.getInt(columnIndex);
-            headers.setOctet(b, mapColumn);
-        }
-    }
-
-    private void setLongToHeaders(
-            Cursor c, int columnIndex,
-            PduHeaders headers, int mapColumn) {
-        if (!c.isNull(columnIndex)) {
-            long l = c.getLong(columnIndex);
-            headers.setLongInteger(l, mapColumn);
-        }
-    }
-
-    private Integer getIntegerFromPartColumn(Cursor c, int columnIndex) {
-        if (!c.isNull(columnIndex)) {
-            return c.getInt(columnIndex);
-        }
-        return null;
-    }
-
-    private byte[] getByteArrayFromPartColumn(Cursor c, int columnIndex) {
-        if (!c.isNull(columnIndex)) {
-            return getBytes(c.getString(columnIndex));
-        }
-        return null;
-    }
-
-    private PduPart[] loadParts(long msgId) throws MmsException {
-        Cursor c = SqliteWrapper.query(mContext, mContentResolver,
-                Uri.parse("content://mms/" + msgId + "/part"),
-                PART_PROJECTION, null, null, null);
-
-        PduPart[] parts = null;
-
-        try {
-            if ((c == null) || (c.getCount() == 0)) {
-                if (LOCAL_LOGV) {
-                    Log.v(TAG, "loadParts(" + msgId + "): no part to load.");
-                }
-                return null;
-            }
-
-            int partCount = c.getCount();
-            int partIdx = 0;
-            parts = new PduPart[partCount];
-            while (c.moveToNext()) {
-                PduPart part = new PduPart();
-                Integer charset = getIntegerFromPartColumn(
-                        c, PART_COLUMN_CHARSET);
-                if (charset != null) {
-                    part.setCharset(charset);
-                }
-
-                byte[] contentDisposition = getByteArrayFromPartColumn(
-                        c, PART_COLUMN_CONTENT_DISPOSITION);
-                if (contentDisposition != null) {
-                    part.setContentDisposition(contentDisposition);
-                }
-
-                byte[] contentId = getByteArrayFromPartColumn(
-                        c, PART_COLUMN_CONTENT_ID);
-                if (contentId != null) {
-                    part.setContentId(contentId);
-                }
-
-                byte[] contentLocation = getByteArrayFromPartColumn(
-                        c, PART_COLUMN_CONTENT_LOCATION);
-                if (contentLocation != null) {
-                    part.setContentLocation(contentLocation);
-                }
-
-                byte[] contentType = getByteArrayFromPartColumn(
-                        c, PART_COLUMN_CONTENT_TYPE);
-                if (contentType != null) {
-                    part.setContentType(contentType);
-                } else {
-                    throw new MmsException("Content-Type must be set.");
-                }
-
-                byte[] fileName = getByteArrayFromPartColumn(
-                        c, PART_COLUMN_FILENAME);
-                if (fileName != null) {
-                    part.setFilename(fileName);
-                }
-
-                byte[] name = getByteArrayFromPartColumn(
-                        c, PART_COLUMN_NAME);
-                if (name != null) {
-                    part.setName(name);
-                }
-
-                // Construct a Uri for this part.
-                long partId = c.getLong(PART_COLUMN_ID);
-                Uri partURI = Uri.parse("content://mms/part/" + partId);
-                part.setDataUri(partURI);
-
-                // For images/audio/video, we won't keep their data in Part
-                // because their renderer accept Uri as source.
-                String type = toIsoString(contentType);
-                if (!ContentType.isImageType(type)
-                        && !ContentType.isAudioType(type)
-                        && !ContentType.isVideoType(type)) {
-                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                    InputStream is = null;
-
-                    // Store simple string values directly in the database instead of an
-                    // external file.  This makes the text searchable and retrieval slightly
-                    // faster.
-                    if (ContentType.TEXT_PLAIN.equals(type) || ContentType.APP_SMIL.equals(type)
-                            || ContentType.TEXT_HTML.equals(type)) {
-                        String text = c.getString(PART_COLUMN_TEXT);
-                        byte [] blob = new EncodedStringValue(text != null ? text : "")
-                            .getTextString();
-                        baos.write(blob, 0, blob.length);
-                    } else {
-
-                        try {
-                            is = mContentResolver.openInputStream(partURI);
-
-                            byte[] buffer = new byte[256];
-                            int len = is.read(buffer);
-                            while (len >= 0) {
-                                baos.write(buffer, 0, len);
-                                len = is.read(buffer);
-                            }
-                        } catch (IOException e) {
-                            Log.e(TAG, "Failed to load part data", e);
-                            c.close();
-                            throw new MmsException(e);
-                        } finally {
-                            if (is != null) {
-                                try {
-                                    is.close();
-                                } catch (IOException e) {
-                                    Log.e(TAG, "Failed to close stream", e);
-                                } // Ignore
-                            }
-                        }
-                    }
-                    part.setData(baos.toByteArray());
-                }
-                parts[partIdx++] = part;
-            }
-        } finally {
-            if (c != null) {
-                c.close();
-            }
-        }
-
-        return parts;
-    }
-
-    private void loadAddress(long msgId, PduHeaders headers) {
-        Cursor c = SqliteWrapper.query(mContext, mContentResolver,
-                Uri.parse("content://mms/" + msgId + "/addr"),
-                new String[] { Addr.ADDRESS, Addr.CHARSET, Addr.TYPE },
-                null, null, null);
-
-        if (c != null) {
-            try {
-                while (c.moveToNext()) {
-                    String addr = c.getString(0);
-                    if (!TextUtils.isEmpty(addr)) {
-                        int addrType = c.getInt(2);
-                        switch (addrType) {
-                            case PduHeaders.FROM:
-                                headers.setEncodedStringValue(
-                                        new EncodedStringValue(c.getInt(1), getBytes(addr)),
-                                        addrType);
-                                break;
-                            case PduHeaders.TO:
-                            case PduHeaders.CC:
-                            case PduHeaders.BCC:
-                                headers.appendEncodedStringValue(
-                                        new EncodedStringValue(c.getInt(1), getBytes(addr)),
-                                        addrType);
-                                break;
-                            default:
-                                Log.e(TAG, "Unknown address type: " + addrType);
-                                break;
-                        }
-                    }
-                }
-            } finally {
-                c.close();
-            }
-        }
-    }
-
-    /**
-     * Load a PDU from storage by given Uri.
-     *
-     * @param uri The Uri of the PDU to be loaded.
-     * @return A generic PDU object, it may be cast to dedicated PDU.
-     * @throws MmsException Failed to load some fields of a PDU.
-     */
-    public GenericPdu load(Uri uri) throws MmsException {
-        GenericPdu pdu = null;
-        PduCacheEntry cacheEntry = null;
-        int msgBox = 0;
-        long threadId = -1;
-        try {
-            synchronized(PDU_CACHE_INSTANCE) {
-                if (PDU_CACHE_INSTANCE.isUpdating(uri)) {
-                    if (LOCAL_LOGV) {
-                        Log.v(TAG, "load: " + uri + " blocked by isUpdating()");
-                    }
-                    try {
-                        PDU_CACHE_INSTANCE.wait();
-                    } catch (InterruptedException e) {
-                        Log.e(TAG, "load: ", e);
-                    }
-                    cacheEntry = PDU_CACHE_INSTANCE.get(uri);
-                    if (cacheEntry != null) {
-                        return cacheEntry.getPdu();
-                    }
-                }
-                // Tell the cache to indicate to other callers that this item
-                // is currently being updated.
-                PDU_CACHE_INSTANCE.setUpdating(uri, true);
-            }
-
-            Cursor c = SqliteWrapper.query(mContext, mContentResolver, uri,
-                    PDU_PROJECTION, null, null, null);
-            PduHeaders headers = new PduHeaders();
-            Set<Entry<Integer, Integer>> set;
-            long msgId = ContentUris.parseId(uri);
-
-            try {
-                if ((c == null) || (c.getCount() != 1) || !c.moveToFirst()) {
-                    throw new MmsException("Bad uri: " + uri);
-                }
-
-                msgBox = c.getInt(PDU_COLUMN_MESSAGE_BOX);
-                threadId = c.getLong(PDU_COLUMN_THREAD_ID);
-
-                set = ENCODED_STRING_COLUMN_INDEX_MAP.entrySet();
-                for (Entry<Integer, Integer> e : set) {
-                    setEncodedStringValueToHeaders(
-                            c, e.getValue(), headers, e.getKey());
-                }
-
-                set = TEXT_STRING_COLUMN_INDEX_MAP.entrySet();
-                for (Entry<Integer, Integer> e : set) {
-                    setTextStringToHeaders(
-                            c, e.getValue(), headers, e.getKey());
-                }
-
-                set = OCTET_COLUMN_INDEX_MAP.entrySet();
-                for (Entry<Integer, Integer> e : set) {
-                    setOctetToHeaders(
-                            c, e.getValue(), headers, e.getKey());
-                }
-
-                set = LONG_COLUMN_INDEX_MAP.entrySet();
-                for (Entry<Integer, Integer> e : set) {
-                    setLongToHeaders(
-                            c, e.getValue(), headers, e.getKey());
-                }
-            } finally {
-                if (c != null) {
-                    c.close();
-                }
-            }
-
-            // Check whether 'msgId' has been assigned a valid value.
-            if (msgId == -1L) {
-                throw new MmsException("Error! ID of the message: -1.");
-            }
-
-            // Load address information of the MM.
-            loadAddress(msgId, headers);
-
-            int msgType = headers.getOctet(PduHeaders.MESSAGE_TYPE);
-            PduBody body = new PduBody();
-
-            // For PDU which type is M_retrieve.conf or Send.req, we should
-            // load multiparts and put them into the body of the PDU.
-            if ((msgType == PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF)
-                    || (msgType == PduHeaders.MESSAGE_TYPE_SEND_REQ)) {
-                PduPart[] parts = loadParts(msgId);
-                if (parts != null) {
-                    int partsNum = parts.length;
-                    for (int i = 0; i < partsNum; i++) {
-                        body.addPart(parts[i]);
-                    }
-                }
-            }
-
-            switch (msgType) {
-            case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND:
-                pdu = new NotificationInd(headers);
-                break;
-            case PduHeaders.MESSAGE_TYPE_DELIVERY_IND:
-                pdu = new DeliveryInd(headers);
-                break;
-            case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND:
-                pdu = new ReadOrigInd(headers);
-                break;
-            case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF:
-                pdu = new RetrieveConf(headers, body);
-                break;
-            case PduHeaders.MESSAGE_TYPE_SEND_REQ:
-                pdu = new SendReq(headers, body);
-                break;
-            case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND:
-                pdu = new AcknowledgeInd(headers);
-                break;
-            case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND:
-                pdu = new NotifyRespInd(headers);
-                break;
-            case PduHeaders.MESSAGE_TYPE_READ_REC_IND:
-                pdu = new ReadRecInd(headers);
-                break;
-            case PduHeaders.MESSAGE_TYPE_SEND_CONF:
-            case PduHeaders.MESSAGE_TYPE_FORWARD_REQ:
-            case PduHeaders.MESSAGE_TYPE_FORWARD_CONF:
-            case PduHeaders.MESSAGE_TYPE_MBOX_STORE_REQ:
-            case PduHeaders.MESSAGE_TYPE_MBOX_STORE_CONF:
-            case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_REQ:
-            case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_CONF:
-            case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_REQ:
-            case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_CONF:
-            case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_REQ:
-            case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_CONF:
-            case PduHeaders.MESSAGE_TYPE_MBOX_DESCR:
-            case PduHeaders.MESSAGE_TYPE_DELETE_REQ:
-            case PduHeaders.MESSAGE_TYPE_DELETE_CONF:
-            case PduHeaders.MESSAGE_TYPE_CANCEL_REQ:
-            case PduHeaders.MESSAGE_TYPE_CANCEL_CONF:
-                throw new MmsException(
-                        "Unsupported PDU type: " + Integer.toHexString(msgType));
-
-            default:
-                throw new MmsException(
-                        "Unrecognized PDU type: " + Integer.toHexString(msgType));
-            }
-        } finally {
-            synchronized(PDU_CACHE_INSTANCE) {
-                if (pdu != null) {
-                    assert(PDU_CACHE_INSTANCE.get(uri) == null);
-                    // Update the cache entry with the real info
-                    cacheEntry = new PduCacheEntry(pdu, msgBox, threadId);
-                    PDU_CACHE_INSTANCE.put(uri, cacheEntry);
-                }
-                PDU_CACHE_INSTANCE.setUpdating(uri, false);
-                PDU_CACHE_INSTANCE.notifyAll(); // tell anybody waiting on this entry to go ahead
-            }
-        }
-        return pdu;
-    }
-
-    private void persistAddress(
-            long msgId, int type, EncodedStringValue[] array) {
-        ContentValues values = new ContentValues(3);
-
-        for (EncodedStringValue addr : array) {
-            values.clear(); // Clear all values first.
-            values.put(Addr.ADDRESS, toIsoString(addr.getTextString()));
-            values.put(Addr.CHARSET, addr.getCharacterSet());
-            values.put(Addr.TYPE, type);
-
-            Uri uri = Uri.parse("content://mms/" + msgId + "/addr");
-            SqliteWrapper.insert(mContext, mContentResolver, uri, values);
-        }
-    }
-
-    public Uri persistPart(PduPart part, long msgId)
-            throws MmsException {
-        Uri uri = Uri.parse("content://mms/" + msgId + "/part");
-        ContentValues values = new ContentValues(8);
-
-        int charset = part.getCharset();
-        if (charset != 0 ) {
-            values.put(Part.CHARSET, charset);
-        }
-
-        String contentType = null;
-        if (part.getContentType() != null) {
-            contentType = toIsoString(part.getContentType());
-
-            // There is no "image/jpg" in Android (and it's an invalid mimetype).
-            // Change it to "image/jpeg"
-            if (ContentType.IMAGE_JPG.equals(contentType)) {
-                contentType = ContentType.IMAGE_JPEG;
-            }
-
-            values.put(Part.CONTENT_TYPE, contentType);
-            // To ensure the SMIL part is always the first part.
-            if (ContentType.APP_SMIL.equals(contentType)) {
-                values.put(Part.SEQ, -1);
-            }
-        } else {
-            throw new MmsException("MIME type of the part must be set.");
-        }
-
-        if (part.getFilename() != null) {
-            String fileName = new String(part.getFilename());
-            values.put(Part.FILENAME, fileName);
-        }
-
-        if (part.getName() != null) {
-            String name = new String(part.getName());
-            values.put(Part.NAME, name);
-        }
-
-        Object value = null;
-        if (part.getContentDisposition() != null) {
-            value = toIsoString(part.getContentDisposition());
-            values.put(Part.CONTENT_DISPOSITION, (String) value);
-        }
-
-        if (part.getContentId() != null) {
-            value = toIsoString(part.getContentId());
-            values.put(Part.CONTENT_ID, (String) value);
-        }
-
-        if (part.getContentLocation() != null) {
-            value = toIsoString(part.getContentLocation());
-            values.put(Part.CONTENT_LOCATION, (String) value);
-        }
-
-        Uri res = SqliteWrapper.insert(mContext, mContentResolver, uri, values);
-        if (res == null) {
-            throw new MmsException("Failed to persist part, return null.");
-        }
-
-        persistData(part, res, contentType);
-        // After successfully store the data, we should update
-        // the dataUri of the part.
-        part.setDataUri(res);
-
-        return res;
-    }
-
-    /**
-     * Save data of the part into storage. The source data may be given
-     * by a byte[] or a Uri. If it's a byte[], directly save it
-     * into storage, otherwise load source data from the dataUri and then
-     * save it. If the data is an image, we may scale down it according
-     * to user preference.
-     *
-     * @param part The PDU part which contains data to be saved.
-     * @param uri The URI of the part.
-     * @param contentType The MIME type of the part.
-     * @throws MmsException Cannot find source data or error occurred
-     *         while saving the data.
-     */
-    private void persistData(PduPart part, Uri uri,
-            String contentType)
-            throws MmsException {
-        OutputStream os = null;
-        InputStream is = null;
-        DrmConvertSession drmConvertSession = null;
-        Uri dataUri = null;
-        String path = null;
-
-        try {
-            byte[] data = part.getData();
-            if (ContentType.TEXT_PLAIN.equals(contentType)
-                    || ContentType.APP_SMIL.equals(contentType)
-                    || ContentType.TEXT_HTML.equals(contentType)) {
-                ContentValues cv = new ContentValues();
-                cv.put(Telephony.Mms.Part.TEXT, new EncodedStringValue(data).getString());
-                if (mContentResolver.update(uri, cv, null, null) != 1) {
-                    throw new MmsException("unable to update " + uri.toString());
-                }
-            } else {
-                boolean isDrm = DownloadDrmHelper.isDrmConvertNeeded(contentType);
-                if (isDrm) {
-                    if (uri != null) {
-                        try {
-                            path = convertUriToPath(mContext, uri);
-                            if (LOCAL_LOGV) {
-                                Log.v(TAG, "drm uri: " + uri + " path: " + path);
-                            }
-                            File f = new File(path);
-                            long len = f.length();
-                            if (LOCAL_LOGV) {
-                                Log.v(TAG, "drm path: " + path + " len: " + len);
-                            }
-                            if (len > 0) {
-                                // we're not going to re-persist and re-encrypt an already
-                                // converted drm file
-                                return;
-                            }
-                        } catch (Exception e) {
-                            Log.e(TAG, "Can't get file info for: " + part.getDataUri(), e);
-                        }
-                    }
-                    // We haven't converted the file yet, start the conversion
-                    drmConvertSession = DrmConvertSession.open(mContext, contentType);
-                    if (drmConvertSession == null) {
-                        throw new MmsException("Mimetype " + contentType +
-                                " can not be converted.");
-                    }
-                }
-                os = mContentResolver.openOutputStream(uri);
-                if (data == null) {
-                    dataUri = part.getDataUri();
-                    if ((dataUri == null) || (dataUri == uri)) {
-                        Log.w(TAG, "Can't find data for this part.");
-                        return;
-                    }
-                    is = mContentResolver.openInputStream(dataUri);
-
-                    if (LOCAL_LOGV) {
-                        Log.v(TAG, "Saving data to: " + uri);
-                    }
-
-                    byte[] buffer = new byte[8192];
-                    for (int len = 0; (len = is.read(buffer)) != -1; ) {
-                        if (!isDrm) {
-                            os.write(buffer, 0, len);
-                        } else {
-                            byte[] convertedData = drmConvertSession.convert(buffer, len);
-                            if (convertedData != null) {
-                                os.write(convertedData, 0, convertedData.length);
-                            } else {
-                                throw new MmsException("Error converting drm data.");
-                            }
-                        }
-                    }
-                } else {
-                    if (LOCAL_LOGV) {
-                        Log.v(TAG, "Saving data to: " + uri);
-                    }
-                    if (!isDrm) {
-                        os.write(data);
-                    } else {
-                        dataUri = uri;
-                        byte[] convertedData = drmConvertSession.convert(data, data.length);
-                        if (convertedData != null) {
-                            os.write(convertedData, 0, convertedData.length);
-                        } else {
-                            throw new MmsException("Error converting drm data.");
-                        }
-                    }
-                }
-            }
-        } catch (FileNotFoundException e) {
-            Log.e(TAG, "Failed to open Input/Output stream.", e);
-            throw new MmsException(e);
-        } catch (IOException e) {
-            Log.e(TAG, "Failed to read/write data.", e);
-            throw new MmsException(e);
-        } finally {
-            if (os != null) {
-                try {
-                    os.close();
-                } catch (IOException e) {
-                    Log.e(TAG, "IOException while closing: " + os, e);
-                } // Ignore
-            }
-            if (is != null) {
-                try {
-                    is.close();
-                } catch (IOException e) {
-                    Log.e(TAG, "IOException while closing: " + is, e);
-                } // Ignore
-            }
-            if (drmConvertSession != null) {
-                drmConvertSession.close(path);
-
-                // Reset the permissions on the encrypted part file so everyone has only read
-                // permission.
-                File f = new File(path);
-                ContentValues values = new ContentValues(0);
-                SqliteWrapper.update(mContext, mContentResolver,
-                                     Uri.parse("content://mms/resetFilePerm/" + f.getName()),
-                                     values, null, null);
-            }
-        }
-    }
-
-    /**
-     * This method expects uri in the following format
-     *     content://media/<table_name>/<row_index> (or)
-     *     file://sdcard/test.mp4
-     *     http://test.com/test.mp4
-     *
-     * Here <table_name> shall be "video" or "audio" or "images"
-     * <row_index> the index of the content in given table
-     */
-    static public String convertUriToPath(Context context, Uri uri) {
-        String path = null;
-        if (null != uri) {
-            String scheme = uri.getScheme();
-            if (null == scheme || scheme.equals("") ||
-                    scheme.equals(ContentResolver.SCHEME_FILE)) {
-                path = uri.getPath();
-
-            } else if (scheme.equals("http")) {
-                path = uri.toString();
-
-            } else if (scheme.equals(ContentResolver.SCHEME_CONTENT)) {
-                String[] projection = new String[] {MediaStore.MediaColumns.DATA};
-                Cursor cursor = null;
-                try {
-                    cursor = context.getContentResolver().query(uri, projection, null,
-                            null, null);
-                    if (null == cursor || 0 == cursor.getCount() || !cursor.moveToFirst()) {
-                        throw new IllegalArgumentException("Given Uri could not be found" +
-                                " in media store");
-                    }
-                    int pathIndex = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
-                    path = cursor.getString(pathIndex);
-                } catch (SQLiteException e) {
-                    throw new IllegalArgumentException("Given Uri is not formatted in a way " +
-                            "so that it can be found in media store.");
-                } finally {
-                    if (null != cursor) {
-                        cursor.close();
-                    }
-                }
-            } else {
-                throw new IllegalArgumentException("Given Uri scheme is not supported");
-            }
-        }
-        return path;
-    }
-
-    private void updateAddress(
-            long msgId, int type, EncodedStringValue[] array) {
-        // Delete old address information and then insert new ones.
-        SqliteWrapper.delete(mContext, mContentResolver,
-                Uri.parse("content://mms/" + msgId + "/addr"),
-                Addr.TYPE + "=" + type, null);
-
-        persistAddress(msgId, type, array);
-    }
-
-    /**
-     * Update headers of a SendReq.
-     *
-     * @param uri The PDU which need to be updated.
-     * @param pdu New headers.
-     * @throws MmsException Bad URI or updating failed.
-     */
-    public void updateHeaders(Uri uri, SendReq sendReq) {
-        synchronized(PDU_CACHE_INSTANCE) {
-            // If the cache item is getting updated, wait until it's done updating before
-            // purging it.
-            if (PDU_CACHE_INSTANCE.isUpdating(uri)) {
-                if (LOCAL_LOGV) {
-                    Log.v(TAG, "updateHeaders: " + uri + " blocked by isUpdating()");
-                }
-                try {
-                    PDU_CACHE_INSTANCE.wait();
-                } catch (InterruptedException e) {
-                    Log.e(TAG, "updateHeaders: ", e);
-                }
-            }
-        }
-        PDU_CACHE_INSTANCE.purge(uri);
-
-        ContentValues values = new ContentValues(10);
-        byte[] contentType = sendReq.getContentType();
-        if (contentType != null) {
-            values.put(Mms.CONTENT_TYPE, toIsoString(contentType));
-        }
-
-        long date = sendReq.getDate();
-        if (date != -1) {
-            values.put(Mms.DATE, date);
-        }
-
-        int deliveryReport = sendReq.getDeliveryReport();
-        if (deliveryReport != 0) {
-            values.put(Mms.DELIVERY_REPORT, deliveryReport);
-        }
-
-        long expiry = sendReq.getExpiry();
-        if (expiry != -1) {
-            values.put(Mms.EXPIRY, expiry);
-        }
-
-        byte[] msgClass = sendReq.getMessageClass();
-        if (msgClass != null) {
-            values.put(Mms.MESSAGE_CLASS, toIsoString(msgClass));
-        }
-
-        int priority = sendReq.getPriority();
-        if (priority != 0) {
-            values.put(Mms.PRIORITY, priority);
-        }
-
-        int readReport = sendReq.getReadReport();
-        if (readReport != 0) {
-            values.put(Mms.READ_REPORT, readReport);
-        }
-
-        byte[] transId = sendReq.getTransactionId();
-        if (transId != null) {
-            values.put(Mms.TRANSACTION_ID, toIsoString(transId));
-        }
-
-        EncodedStringValue subject = sendReq.getSubject();
-        if (subject != null) {
-            values.put(Mms.SUBJECT, toIsoString(subject.getTextString()));
-            values.put(Mms.SUBJECT_CHARSET, subject.getCharacterSet());
-        } else {
-            values.put(Mms.SUBJECT, "");
-        }
-
-        long messageSize = sendReq.getMessageSize();
-        if (messageSize > 0) {
-            values.put(Mms.MESSAGE_SIZE, messageSize);
-        }
-
-        PduHeaders headers = sendReq.getPduHeaders();
-        HashSet<String> recipients = new HashSet<String>();
-        for (int addrType : ADDRESS_FIELDS) {
-            EncodedStringValue[] array = null;
-            if (addrType == PduHeaders.FROM) {
-                EncodedStringValue v = headers.getEncodedStringValue(addrType);
-                if (v != null) {
-                    array = new EncodedStringValue[1];
-                    array[0] = v;
-                }
-            } else {
-                array = headers.getEncodedStringValues(addrType);
-            }
-
-            if (array != null) {
-                long msgId = ContentUris.parseId(uri);
-                updateAddress(msgId, addrType, array);
-                if (addrType == PduHeaders.TO) {
-                    for (EncodedStringValue v : array) {
-                        if (v != null) {
-                            recipients.add(v.getString());
-                        }
-                    }
-                }
-            }
-        }
-        if (!recipients.isEmpty()) {
-            long threadId = Threads.getOrCreateThreadId(mContext, recipients);
-            values.put(Mms.THREAD_ID, threadId);
-        }
-
-        SqliteWrapper.update(mContext, mContentResolver, uri, values, null, null);
-    }
-
-    private void updatePart(Uri uri, PduPart part) throws MmsException {
-        ContentValues values = new ContentValues(7);
-
-        int charset = part.getCharset();
-        if (charset != 0 ) {
-            values.put(Part.CHARSET, charset);
-        }
-
-        String contentType = null;
-        if (part.getContentType() != null) {
-            contentType = toIsoString(part.getContentType());
-            values.put(Part.CONTENT_TYPE, contentType);
-        } else {
-            throw new MmsException("MIME type of the part must be set.");
-        }
-
-        if (part.getFilename() != null) {
-            String fileName = new String(part.getFilename());
-            values.put(Part.FILENAME, fileName);
-        }
-
-        if (part.getName() != null) {
-            String name = new String(part.getName());
-            values.put(Part.NAME, name);
-        }
-
-        Object value = null;
-        if (part.getContentDisposition() != null) {
-            value = toIsoString(part.getContentDisposition());
-            values.put(Part.CONTENT_DISPOSITION, (String) value);
-        }
-
-        if (part.getContentId() != null) {
-            value = toIsoString(part.getContentId());
-            values.put(Part.CONTENT_ID, (String) value);
-        }
-
-        if (part.getContentLocation() != null) {
-            value = toIsoString(part.getContentLocation());
-            values.put(Part.CONTENT_LOCATION, (String) value);
-        }
-
-        SqliteWrapper.update(mContext, mContentResolver, uri, values, null, null);
-
-        // Only update the data when:
-        // 1. New binary data supplied or
-        // 2. The Uri of the part is different from the current one.
-        if ((part.getData() != null)
-                || (uri != part.getDataUri())) {
-            persistData(part, uri, contentType);
-        }
-    }
-
-    /**
-     * Update all parts of a PDU.
-     *
-     * @param uri The PDU which need to be updated.
-     * @param body New message body of the PDU.
-     * @throws MmsException Bad URI or updating failed.
-     */
-    public void updateParts(Uri uri, PduBody body)
-            throws MmsException {
-        try {
-            PduCacheEntry cacheEntry;
-            synchronized(PDU_CACHE_INSTANCE) {
-                if (PDU_CACHE_INSTANCE.isUpdating(uri)) {
-                    if (LOCAL_LOGV) {
-                        Log.v(TAG, "updateParts: " + uri + " blocked by isUpdating()");
-                    }
-                    try {
-                        PDU_CACHE_INSTANCE.wait();
-                    } catch (InterruptedException e) {
-                        Log.e(TAG, "updateParts: ", e);
-                    }
-                    cacheEntry = PDU_CACHE_INSTANCE.get(uri);
-                    if (cacheEntry != null) {
-                        ((MultimediaMessagePdu) cacheEntry.getPdu()).setBody(body);
-                    }
-                }
-                // Tell the cache to indicate to other callers that this item
-                // is currently being updated.
-                PDU_CACHE_INSTANCE.setUpdating(uri, true);
-            }
-
-            ArrayList<PduPart> toBeCreated = new ArrayList<PduPart>();
-            HashMap<Uri, PduPart> toBeUpdated = new HashMap<Uri, PduPart>();
-
-            int partsNum = body.getPartsNum();
-            StringBuilder filter = new StringBuilder().append('(');
-            for (int i = 0; i < partsNum; i++) {
-                PduPart part = body.getPart(i);
-                Uri partUri = part.getDataUri();
-                if ((partUri == null) || !partUri.getAuthority().startsWith("mms")) {
-                    toBeCreated.add(part);
-                } else {
-                    toBeUpdated.put(partUri, part);
-
-                    // Don't use 'i > 0' to determine whether we should append
-                    // 'AND' since 'i = 0' may be skipped in another branch.
-                    if (filter.length() > 1) {
-                        filter.append(" AND ");
-                    }
-
-                    filter.append(Part._ID);
-                    filter.append("!=");
-                    DatabaseUtils.appendEscapedSQLString(filter, partUri.getLastPathSegment());
-                }
-            }
-            filter.append(')');
-
-            long msgId = ContentUris.parseId(uri);
-
-            // Remove the parts which doesn't exist anymore.
-            SqliteWrapper.delete(mContext, mContentResolver,
-                    Uri.parse(Mms.CONTENT_URI + "/" + msgId + "/part"),
-                    filter.length() > 2 ? filter.toString() : null, null);
-
-            // Create new parts which didn't exist before.
-            for (PduPart part : toBeCreated) {
-                persistPart(part, msgId);
-            }
-
-            // Update the modified parts.
-            for (Map.Entry<Uri, PduPart> e : toBeUpdated.entrySet()) {
-                updatePart(e.getKey(), e.getValue());
-            }
-        } finally {
-            synchronized(PDU_CACHE_INSTANCE) {
-                PDU_CACHE_INSTANCE.setUpdating(uri, false);
-                PDU_CACHE_INSTANCE.notifyAll();
-            }
-        }
-    }
-
-    /**
-     * Persist a PDU object to specific location in the storage.
-     *
-     * @param pdu The PDU object to be stored.
-     * @param uri Where to store the given PDU object.
-     * @return A Uri which can be used to access the stored PDU.
-     */
-    public Uri persist(GenericPdu pdu, Uri uri) throws MmsException {
-        if (uri == null) {
-            throw new MmsException("Uri may not be null.");
-        }
-        long msgId = -1;
-        try {
-            msgId = ContentUris.parseId(uri);
-        } catch (NumberFormatException e) {
-            // the uri ends with "inbox" or something else like that
-        }
-        boolean existingUri = msgId != -1;
-
-        if (!existingUri && MESSAGE_BOX_MAP.get(uri) == null) {
-            throw new MmsException(
-                    "Bad destination, must be one of "
-                    + "content://mms/inbox, content://mms/sent, "
-                    + "content://mms/drafts, content://mms/outbox, "
-                    + "content://mms/temp.");
-        }
-        synchronized(PDU_CACHE_INSTANCE) {
-            // If the cache item is getting updated, wait until it's done updating before
-            // purging it.
-            if (PDU_CACHE_INSTANCE.isUpdating(uri)) {
-                if (LOCAL_LOGV) {
-                    Log.v(TAG, "persist: " + uri + " blocked by isUpdating()");
-                }
-                try {
-                    PDU_CACHE_INSTANCE.wait();
-                } catch (InterruptedException e) {
-                    Log.e(TAG, "persist1: ", e);
-                }
-            }
-        }
-        PDU_CACHE_INSTANCE.purge(uri);
-
-        PduHeaders header = pdu.getPduHeaders();
-        PduBody body = null;
-        ContentValues values = new ContentValues();
-        Set<Entry<Integer, String>> set;
-
-        set = ENCODED_STRING_COLUMN_NAME_MAP.entrySet();
-        for (Entry<Integer, String> e : set) {
-            int field = e.getKey();
-            EncodedStringValue encodedString = header.getEncodedStringValue(field);
-            if (encodedString != null) {
-                String charsetColumn = CHARSET_COLUMN_NAME_MAP.get(field);
-                values.put(e.getValue(), toIsoString(encodedString.getTextString()));
-                values.put(charsetColumn, encodedString.getCharacterSet());
-            }
-        }
-
-        set = TEXT_STRING_COLUMN_NAME_MAP.entrySet();
-        for (Entry<Integer, String> e : set){
-            byte[] text = header.getTextString(e.getKey());
-            if (text != null) {
-                values.put(e.getValue(), toIsoString(text));
-            }
-        }
-
-        set = OCTET_COLUMN_NAME_MAP.entrySet();
-        for (Entry<Integer, String> e : set){
-            int b = header.getOctet(e.getKey());
-            if (b != 0) {
-                values.put(e.getValue(), b);
-            }
-        }
-
-        set = LONG_COLUMN_NAME_MAP.entrySet();
-        for (Entry<Integer, String> e : set){
-            long l = header.getLongInteger(e.getKey());
-            if (l != -1L) {
-                values.put(e.getValue(), l);
-            }
-        }
-
-        HashMap<Integer, EncodedStringValue[]> addressMap =
-                new HashMap<Integer, EncodedStringValue[]>(ADDRESS_FIELDS.length);
-        // Save address information.
-        for (int addrType : ADDRESS_FIELDS) {
-            EncodedStringValue[] array = null;
-            if (addrType == PduHeaders.FROM) {
-                EncodedStringValue v = header.getEncodedStringValue(addrType);
-                if (v != null) {
-                    array = new EncodedStringValue[1];
-                    array[0] = v;
-                }
-            } else {
-                array = header.getEncodedStringValues(addrType);
-            }
-            addressMap.put(addrType, array);
-        }
-
-        HashSet<String> recipients = new HashSet<String>();
-        int msgType = pdu.getMessageType();
-        // Here we only allocate thread ID for M-Notification.ind,
-        // M-Retrieve.conf and M-Send.req.
-        // Some of other PDU types may be allocated a thread ID outside
-        // this scope.
-        if ((msgType == PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND)
-                || (msgType == PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF)
-                || (msgType == PduHeaders.MESSAGE_TYPE_SEND_REQ)) {
-            EncodedStringValue[] array = null;
-            switch (msgType) {
-                case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND:
-                case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF:
-                    array = addressMap.get(PduHeaders.FROM);
-                    break;
-                case PduHeaders.MESSAGE_TYPE_SEND_REQ:
-                    array = addressMap.get(PduHeaders.TO);
-                    break;
-            }
-
-            if (array != null) {
-                for (EncodedStringValue v : array) {
-                    if (v != null) {
-                        recipients.add(v.getString());
-                    }
-                }
-            }
-            if (!recipients.isEmpty()) {
-                long threadId = Threads.getOrCreateThreadId(mContext, recipients);
-                values.put(Mms.THREAD_ID, threadId);
-            }
-        }
-
-        // Save parts first to avoid inconsistent message is loaded
-        // while saving the parts.
-        long dummyId = System.currentTimeMillis(); // Dummy ID of the msg.
-        // Get body if the PDU is a RetrieveConf or SendReq.
-        if (pdu instanceof MultimediaMessagePdu) {
-            body = ((MultimediaMessagePdu) pdu).getBody();
-            // Start saving parts if necessary.
-            if (body != null) {
-                int partsNum = body.getPartsNum();
-                for (int i = 0; i < partsNum; i++) {
-                    PduPart part = body.getPart(i);
-                    persistPart(part, dummyId);
-                }
-            }
-        }
-
-        Uri res = null;
-        if (existingUri) {
-            res = uri;
-            SqliteWrapper.update(mContext, mContentResolver, res, values, null, null);
-        } else {
-            res = SqliteWrapper.insert(mContext, mContentResolver, uri, values);
-            if (res == null) {
-                throw new MmsException("persist() failed: return null.");
-            }
-            // Get the real ID of the PDU and update all parts which were
-            // saved with the dummy ID.
-            msgId = ContentUris.parseId(res);
-        }
-
-        values = new ContentValues(1);
-        values.put(Part.MSG_ID, msgId);
-        SqliteWrapper.update(mContext, mContentResolver,
-                             Uri.parse("content://mms/" + dummyId + "/part"),
-                             values, null, null);
-        // We should return the longest URI of the persisted PDU, for
-        // example, if input URI is "content://mms/inbox" and the _ID of
-        // persisted PDU is '8', we should return "content://mms/inbox/8"
-        // instead of "content://mms/8".
-        // FIXME: Should the MmsProvider be responsible for this???
-        if (!existingUri) {
-            res = Uri.parse(uri + "/" + msgId);
-        }
-
-        // Save address information.
-        for (int addrType : ADDRESS_FIELDS) {
-            EncodedStringValue[] array = addressMap.get(addrType);
-            if (array != null) {
-                persistAddress(msgId, addrType, array);
-            }
-        }
-
-        return res;
-    }
-
-    /**
-     * Move a PDU object from one location to another.
-     *
-     * @param from Specify the PDU object to be moved.
-     * @param to The destination location, should be one of the following:
-     *        "content://mms/inbox", "content://mms/sent",
-     *        "content://mms/drafts", "content://mms/outbox",
-     *        "content://mms/trash".
-     * @return New Uri of the moved PDU.
-     * @throws MmsException Error occurred while moving the message.
-     */
-    public Uri move(Uri from, Uri to) throws MmsException {
-        // Check whether the 'msgId' has been assigned a valid value.
-        long msgId = ContentUris.parseId(from);
-        if (msgId == -1L) {
-            throw new MmsException("Error! ID of the message: -1.");
-        }
-
-        // Get corresponding int value of destination box.
-        Integer msgBox = MESSAGE_BOX_MAP.get(to);
-        if (msgBox == null) {
-            throw new MmsException(
-                    "Bad destination, must be one of "
-                    + "content://mms/inbox, content://mms/sent, "
-                    + "content://mms/drafts, content://mms/outbox, "
-                    + "content://mms/temp.");
-        }
-
-        ContentValues values = new ContentValues(1);
-        values.put(Mms.MESSAGE_BOX, msgBox);
-        SqliteWrapper.update(mContext, mContentResolver, from, values, null, null);
-        return ContentUris.withAppendedId(to, msgId);
-    }
-
-    /**
-     * Wrap a byte[] into a String.
-     */
-    public static String toIsoString(byte[] bytes) {
-        try {
-            return new String(bytes, CharacterSets.MIMENAME_ISO_8859_1);
-        } catch (UnsupportedEncodingException e) {
-            // Impossible to reach here!
-            Log.e(TAG, "ISO_8859_1 must be supported!", e);
-            return "";
-        }
-    }
-
-    /**
-     * Unpack a given String into a byte[].
-     */
-    public static byte[] getBytes(String data) {
-        try {
-            return data.getBytes(CharacterSets.MIMENAME_ISO_8859_1);
-        } catch (UnsupportedEncodingException e) {
-            // Impossible to reach here!
-            Log.e(TAG, "ISO_8859_1 must be supported!", e);
-            return new byte[0];
-        }
-    }
-
-    /**
-     * Remove all objects in the temporary path.
-     */
-    public void release() {
-        Uri uri = Uri.parse(TEMPORARY_DRM_OBJECT_URI);
-        SqliteWrapper.delete(mContext, mContentResolver, uri, null, null);
-    }
-
-    /**
-     * Find all messages to be sent or downloaded before certain time.
-     */
-    public Cursor getPendingMessages(long dueTime) {
-        Uri.Builder uriBuilder = PendingMessages.CONTENT_URI.buildUpon();
-        uriBuilder.appendQueryParameter("protocol", "mms");
-
-        String selection = PendingMessages.ERROR_TYPE + " < ?"
-                + " AND " + PendingMessages.DUE_TIME + " <= ?";
-
-        String[] selectionArgs = new String[] {
-                String.valueOf(MmsSms.ERR_TYPE_GENERIC_PERMANENT),
-                String.valueOf(dueTime)
-        };
-
-        return SqliteWrapper.query(mContext, mContentResolver,
-                uriBuilder.build(), null, selection, selectionArgs,
-                PendingMessages.DUE_TIME);
-    }
-}
diff --git a/core/java/com/google/android/mms/pdu/QuotedPrintable.java b/core/java/com/google/android/mms/pdu/QuotedPrintable.java
deleted file mode 100644
index a34ed12..0000000
--- a/core/java/com/google/android/mms/pdu/QuotedPrintable.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import java.io.ByteArrayOutputStream;
-
-public class QuotedPrintable {
-    private static byte ESCAPE_CHAR = '=';
-
-    /**
-     * Decodes an array quoted-printable characters into an array of original bytes.
-     * Escaped characters are converted back to their original representation.
-     *
-     * <p>
-     * This function implements a subset of
-     * quoted-printable encoding specification (rule #1 and rule #2)
-     * as defined in RFC 1521.
-     * </p>
-     *
-     * @param bytes array of quoted-printable characters
-     * @return array of original bytes,
-     *         null if quoted-printable decoding is unsuccessful.
-     */
-    public static final byte[] decodeQuotedPrintable(byte[] bytes) {
-        if (bytes == null) {
-            return null;
-        }
-        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-        for (int i = 0; i < bytes.length; i++) {
-            int b = bytes[i];
-            if (b == ESCAPE_CHAR) {
-                try {
-                    if('\r' == (char)bytes[i + 1] &&
-                            '\n' == (char)bytes[i + 2]) {
-                        i += 2;
-                        continue;
-                    }
-                    int u = Character.digit((char) bytes[++i], 16);
-                    int l = Character.digit((char) bytes[++i], 16);
-                    if (u == -1 || l == -1) {
-                        return null;
-                    }
-                    buffer.write((char) ((u << 4) + l));
-                } catch (ArrayIndexOutOfBoundsException e) {
-                    return null;
-                }
-            } else {
-                buffer.write(b);
-            }
-        }
-        return buffer.toByteArray();
-    }
-}
diff --git a/core/java/com/google/android/mms/pdu/ReadOrigInd.java b/core/java/com/google/android/mms/pdu/ReadOrigInd.java
deleted file mode 100644
index 1bfc0bb..0000000
--- a/core/java/com/google/android/mms/pdu/ReadOrigInd.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-public class ReadOrigInd extends GenericPdu {
-    /**
-     * Empty constructor.
-     * Since the Pdu corresponding to this class is constructed
-     * by the Proxy-Relay server, this class is only instantiated
-     * by the Pdu Parser.
-     *
-     * @throws InvalidHeaderValueException if error occurs.
-     */
-    public ReadOrigInd() throws InvalidHeaderValueException {
-        super();
-        setMessageType(PduHeaders.MESSAGE_TYPE_READ_ORIG_IND);
-    }
-
-    /**
-     * Constructor with given headers.
-     *
-     * @param headers Headers for this PDU.
-     */
-    ReadOrigInd(PduHeaders headers) {
-        super(headers);
-    }
-
-    /**
-     * Get Date value.
-     *
-     * @return the value
-     */
-    public long getDate() {
-        return mPduHeaders.getLongInteger(PduHeaders.DATE);
-    }
-
-    /**
-     * Set Date value.
-     *
-     * @param value the value
-     */
-    public void setDate(long value) {
-        mPduHeaders.setLongInteger(value, PduHeaders.DATE);
-    }
-
-    /**
-     * Get From value.
-     * From-value = Value-length
-     *      (Address-present-token Encoded-string-value | Insert-address-token)
-     *
-     * @return the value
-     */
-    public EncodedStringValue getFrom() {
-       return mPduHeaders.getEncodedStringValue(PduHeaders.FROM);
-    }
-
-    /**
-     * Set From value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setFrom(EncodedStringValue value) {
-        mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM);
-    }
-
-    /**
-     * Get Message-ID value.
-     *
-     * @return the value
-     */
-    public byte[] getMessageId() {
-        return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID);
-    }
-
-    /**
-     * Set Message-ID value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setMessageId(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID);
-    }
-
-    /**
-     * Get X-MMS-Read-status value.
-     *
-     * @return the value
-     */
-    public int getReadStatus() {
-        return mPduHeaders.getOctet(PduHeaders.READ_STATUS);
-    }
-
-    /**
-     * Set X-MMS-Read-status value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    public void setReadStatus(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.READ_STATUS);
-    }
-
-    /**
-     * Get To value.
-     *
-     * @return the value
-     */
-    public EncodedStringValue[] getTo() {
-        return mPduHeaders.getEncodedStringValues(PduHeaders.TO);
-    }
-
-    /**
-     * Set To value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setTo(EncodedStringValue[] value) {
-        mPduHeaders.setEncodedStringValues(value, PduHeaders.TO);
-    }
-
-    /*
-     * Optional, not supported header fields:
-     *
-     *     public byte[] getApplicId() {return null;}
-     *     public void setApplicId(byte[] value) {}
-     *
-     *     public byte[] getAuxApplicId() {return null;}
-     *     public void getAuxApplicId(byte[] value) {}
-     *
-     *     public byte[] getReplyApplicId() {return 0x00;}
-     *     public void setReplyApplicId(byte[] value) {}
-     */
-}
diff --git a/core/java/com/google/android/mms/pdu/ReadRecInd.java b/core/java/com/google/android/mms/pdu/ReadRecInd.java
deleted file mode 100644
index 880e3ac..0000000
--- a/core/java/com/google/android/mms/pdu/ReadRecInd.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-public class ReadRecInd extends GenericPdu {
-    /**
-     * Constructor, used when composing a M-ReadRec.ind pdu.
-     *
-     * @param from the from value
-     * @param messageId the message ID value
-     * @param mmsVersion current viersion of mms
-     * @param readStatus the read status value
-     * @param to the to value
-     * @throws InvalidHeaderValueException if parameters are invalid.
-     *         NullPointerException if messageId or to is null.
-     */
-    public ReadRecInd(EncodedStringValue from,
-                      byte[] messageId,
-                      int mmsVersion,
-                      int readStatus,
-                      EncodedStringValue[] to) throws InvalidHeaderValueException {
-        super();
-        setMessageType(PduHeaders.MESSAGE_TYPE_READ_REC_IND);
-        setFrom(from);
-        setMessageId(messageId);
-        setMmsVersion(mmsVersion);
-        setTo(to);
-        setReadStatus(readStatus);
-    }
-
-    /**
-     * Constructor with given headers.
-     *
-     * @param headers Headers for this PDU.
-     */
-    ReadRecInd(PduHeaders headers) {
-        super(headers);
-    }
-
-    /**
-     * Get Date value.
-     *
-     * @return the value
-     */
-    public long getDate() {
-        return mPduHeaders.getLongInteger(PduHeaders.DATE);
-    }
-
-    /**
-     * Set Date value.
-     *
-     * @param value the value
-     */
-    public void setDate(long value) {
-        mPduHeaders.setLongInteger(value, PduHeaders.DATE);
-    }
-
-    /**
-     * Get Message-ID value.
-     *
-     * @return the value
-     */
-    public byte[] getMessageId() {
-        return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID);
-    }
-
-    /**
-     * Set Message-ID value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setMessageId(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID);
-    }
-
-    /**
-     * Get To value.
-     *
-     * @return the value
-     */
-    public EncodedStringValue[] getTo() {
-        return mPduHeaders.getEncodedStringValues(PduHeaders.TO);
-    }
-
-    /**
-     * Set To value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setTo(EncodedStringValue[] value) {
-        mPduHeaders.setEncodedStringValues(value, PduHeaders.TO);
-    }
-
-    /**
-     * Get X-MMS-Read-status value.
-     *
-     * @return the value
-     */
-    public int getReadStatus() {
-        return mPduHeaders.getOctet(PduHeaders.READ_STATUS);
-    }
-
-    /**
-     * Set X-MMS-Read-status value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    public void setReadStatus(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.READ_STATUS);
-    }
-
-    /*
-     * Optional, not supported header fields:
-     *
-     *     public byte[] getApplicId() {return null;}
-     *     public void setApplicId(byte[] value) {}
-     *
-     *     public byte[] getAuxApplicId() {return null;}
-     *     public void getAuxApplicId(byte[] value) {}
-     *
-     *     public byte[] getReplyApplicId() {return 0x00;}
-     *     public void setReplyApplicId(byte[] value) {}
-     */
-}
diff --git a/core/java/com/google/android/mms/pdu/RetrieveConf.java b/core/java/com/google/android/mms/pdu/RetrieveConf.java
deleted file mode 100644
index 98e67c0..0000000
--- a/core/java/com/google/android/mms/pdu/RetrieveConf.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-/**
- * M-Retrive.conf Pdu.
- */
-public class RetrieveConf extends MultimediaMessagePdu {
-    /**
-     * Empty constructor.
-     * Since the Pdu corresponding to this class is constructed
-     * by the Proxy-Relay server, this class is only instantiated
-     * by the Pdu Parser.
-     *
-     * @throws InvalidHeaderValueException if error occurs.
-     */
-    public RetrieveConf() throws InvalidHeaderValueException {
-        super();
-        setMessageType(PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF);
-    }
-
-    /**
-     * Constructor with given headers.
-     *
-     * @param headers Headers for this PDU.
-     */
-    RetrieveConf(PduHeaders headers) {
-        super(headers);
-    }
-
-    /**
-     * Constructor with given headers and body
-     *
-     * @param headers Headers for this PDU.
-     * @param body Body of this PDu.
-     */
-    RetrieveConf(PduHeaders headers, PduBody body) {
-        super(headers, body);
-    }
-
-    /**
-     * Get CC value.
-     *
-     * @return the value
-     */
-    public EncodedStringValue[] getCc() {
-        return mPduHeaders.getEncodedStringValues(PduHeaders.CC);
-    }
-
-    /**
-     * Add a "CC" value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void addCc(EncodedStringValue value) {
-        mPduHeaders.appendEncodedStringValue(value, PduHeaders.CC);
-    }
-
-    /**
-     * Get Content-type value.
-     *
-     * @return the value
-     */
-    public byte[] getContentType() {
-        return mPduHeaders.getTextString(PduHeaders.CONTENT_TYPE);
-    }
-
-    /**
-     * Set Content-type value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setContentType(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.CONTENT_TYPE);
-    }
-
-    /**
-     * Get X-Mms-Delivery-Report value.
-     *
-     * @return the value
-     */
-    public int getDeliveryReport() {
-        return mPduHeaders.getOctet(PduHeaders.DELIVERY_REPORT);
-    }
-
-    /**
-     * Set X-Mms-Delivery-Report value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    public void setDeliveryReport(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.DELIVERY_REPORT);
-    }
-
-    /**
-     * Get From value.
-     * From-value = Value-length
-     *      (Address-present-token Encoded-string-value | Insert-address-token)
-     *
-     * @return the value
-     */
-    public EncodedStringValue getFrom() {
-       return mPduHeaders.getEncodedStringValue(PduHeaders.FROM);
-    }
-
-    /**
-     * Set From value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setFrom(EncodedStringValue value) {
-        mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM);
-    }
-
-    /**
-     * Get X-Mms-Message-Class value.
-     * Message-class-value = Class-identifier | Token-text
-     * Class-identifier = Personal | Advertisement | Informational | Auto
-     *
-     * @return the value
-     */
-    public byte[] getMessageClass() {
-        return mPduHeaders.getTextString(PduHeaders.MESSAGE_CLASS);
-    }
-
-    /**
-     * Set X-Mms-Message-Class value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setMessageClass(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.MESSAGE_CLASS);
-    }
-
-    /**
-     * Get Message-ID value.
-     *
-     * @return the value
-     */
-    public byte[] getMessageId() {
-        return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID);
-    }
-
-    /**
-     * Set Message-ID value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setMessageId(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID);
-    }
-
-    /**
-     * Get X-Mms-Read-Report value.
-     *
-     * @return the value
-     */
-    public int getReadReport() {
-        return mPduHeaders.getOctet(PduHeaders.READ_REPORT);
-    }
-
-    /**
-     * Set X-Mms-Read-Report value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    public void setReadReport(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.READ_REPORT);
-    }
-
-    /**
-     * Get X-Mms-Retrieve-Status value.
-     *
-     * @return the value
-     */
-    public int getRetrieveStatus() {
-        return mPduHeaders.getOctet(PduHeaders.RETRIEVE_STATUS);
-    }
-
-    /**
-     * Set X-Mms-Retrieve-Status value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    public void setRetrieveStatus(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.RETRIEVE_STATUS);
-    }
-
-    /**
-     * Get X-Mms-Retrieve-Text value.
-     *
-     * @return the value
-     */
-    public EncodedStringValue getRetrieveText() {
-        return mPduHeaders.getEncodedStringValue(PduHeaders.RETRIEVE_TEXT);
-    }
-
-    /**
-     * Set X-Mms-Retrieve-Text value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setRetrieveText(EncodedStringValue value) {
-        mPduHeaders.setEncodedStringValue(value, PduHeaders.RETRIEVE_TEXT);
-    }
-
-    /**
-     * Get X-Mms-Transaction-Id.
-     *
-     * @return the value
-     */
-    public byte[] getTransactionId() {
-        return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID);
-    }
-
-    /**
-     * Set X-Mms-Transaction-Id.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setTransactionId(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID);
-    }
-
-    /*
-     * Optional, not supported header fields:
-     *
-     *     public byte[] getApplicId() {return null;}
-     *     public void setApplicId(byte[] value) {}
-     *
-     *     public byte[] getAuxApplicId() {return null;}
-     *     public void getAuxApplicId(byte[] value) {}
-     *
-     *     public byte getContentClass() {return 0x00;}
-     *     public void setApplicId(byte value) {}
-     *
-     *     public byte getDrmContent() {return 0x00;}
-     *     public void setDrmContent(byte value) {}
-     *
-     *     public byte getDistributionIndicator() {return 0x00;}
-     *     public void setDistributionIndicator(byte value) {}
-     *
-     *     public PreviouslySentByValue getPreviouslySentBy() {return null;}
-     *     public void setPreviouslySentBy(PreviouslySentByValue value) {}
-     *
-     *     public PreviouslySentDateValue getPreviouslySentDate() {}
-     *     public void setPreviouslySentDate(PreviouslySentDateValue value) {}
-     *
-     *     public MmFlagsValue getMmFlags() {return null;}
-     *     public void setMmFlags(MmFlagsValue value) {}
-     *
-     *     public MmStateValue getMmState() {return null;}
-     *     public void getMmState(MmStateValue value) {}
-     *
-     *     public byte[] getReplaceId() {return 0x00;}
-     *     public void setReplaceId(byte[] value) {}
-     *
-     *     public byte[] getReplyApplicId() {return 0x00;}
-     *     public void setReplyApplicId(byte[] value) {}
-     *
-     *     public byte getReplyCharging() {return 0x00;}
-     *     public void setReplyCharging(byte value) {}
-     *
-     *     public byte getReplyChargingDeadline() {return 0x00;}
-     *     public void setReplyChargingDeadline(byte value) {}
-     *
-     *     public byte[] getReplyChargingId() {return 0x00;}
-     *     public void setReplyChargingId(byte[] value) {}
-     *
-     *     public long getReplyChargingSize() {return 0;}
-     *     public void setReplyChargingSize(long value) {}
-     */
-}
diff --git a/core/java/com/google/android/mms/pdu/SendConf.java b/core/java/com/google/android/mms/pdu/SendConf.java
deleted file mode 100644
index 0568fe79..0000000
--- a/core/java/com/google/android/mms/pdu/SendConf.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-public class SendConf extends GenericPdu {
-    /**
-     * Empty constructor.
-     * Since the Pdu corresponding to this class is constructed
-     * by the Proxy-Relay server, this class is only instantiated
-     * by the Pdu Parser.
-     *
-     * @throws InvalidHeaderValueException if error occurs.
-     */
-    public SendConf() throws InvalidHeaderValueException {
-        super();
-        setMessageType(PduHeaders.MESSAGE_TYPE_SEND_CONF);
-    }
-
-    /**
-     * Constructor with given headers.
-     *
-     * @param headers Headers for this PDU.
-     */
-    SendConf(PduHeaders headers) {
-        super(headers);
-    }
-
-    /**
-     * Get Message-ID value.
-     *
-     * @return the value
-     */
-    public byte[] getMessageId() {
-        return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID);
-    }
-
-    /**
-     * Set Message-ID value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setMessageId(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID);
-    }
-
-    /**
-     * Get X-Mms-Response-Status.
-     *
-     * @return the value
-     */
-    public int getResponseStatus() {
-        return mPduHeaders.getOctet(PduHeaders.RESPONSE_STATUS);
-    }
-
-    /**
-     * Set X-Mms-Response-Status.
-     *
-     * @param value the values
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    public void setResponseStatus(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.RESPONSE_STATUS);
-    }
-
-    /**
-     * Get X-Mms-Transaction-Id field value.
-     *
-     * @return the X-Mms-Report-Allowed value
-     */
-    public byte[] getTransactionId() {
-        return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID);
-    }
-
-    /**
-     * Set X-Mms-Transaction-Id field value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setTransactionId(byte[] value) {
-            mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID);
-    }
-
-    /*
-     * Optional, not supported header fields:
-     *
-     *    public byte[] getContentLocation() {return null;}
-     *    public void setContentLocation(byte[] value) {}
-     *
-     *    public EncodedStringValue getResponseText() {return null;}
-     *    public void setResponseText(EncodedStringValue value) {}
-     *
-     *    public byte getStoreStatus() {return 0x00;}
-     *    public void setStoreStatus(byte value) {}
-     *
-     *    public byte[] getStoreStatusText() {return null;}
-     *    public void setStoreStatusText(byte[] value) {}
-     */
-}
diff --git a/core/java/com/google/android/mms/pdu/SendReq.java b/core/java/com/google/android/mms/pdu/SendReq.java
deleted file mode 100644
index 597cd00..0000000
--- a/core/java/com/google/android/mms/pdu/SendReq.java
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Esmertec AG.
- * Copyright (C) 2007-2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import android.util.Log;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-public class SendReq extends MultimediaMessagePdu {
-    private static final String TAG = "SendReq";
-
-    public SendReq() {
-        super();
-
-        try {
-            setMessageType(PduHeaders.MESSAGE_TYPE_SEND_REQ);
-            setMmsVersion(PduHeaders.CURRENT_MMS_VERSION);
-            // FIXME: Content-type must be decided according to whether
-            // SMIL part present.
-            setContentType("application/vnd.wap.multipart.related".getBytes());
-            setFrom(new EncodedStringValue(PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR.getBytes()));
-            setTransactionId(generateTransactionId());
-        } catch (InvalidHeaderValueException e) {
-            // Impossible to reach here since all headers we set above are valid.
-            Log.e(TAG, "Unexpected InvalidHeaderValueException.", e);
-            throw new RuntimeException(e);
-        }
-    }
-
-    private byte[] generateTransactionId() {
-        String transactionId = "T" + Long.toHexString(System.currentTimeMillis());
-        return transactionId.getBytes();
-    }
-
-    /**
-     * Constructor, used when composing a M-Send.req pdu.
-     *
-     * @param contentType the content type value
-     * @param from the from value
-     * @param mmsVersion current viersion of mms
-     * @param transactionId the transaction-id value
-     * @throws InvalidHeaderValueException if parameters are invalid.
-     *         NullPointerException if contentType, form or transactionId is null.
-     */
-    public SendReq(byte[] contentType,
-                   EncodedStringValue from,
-                   int mmsVersion,
-                   byte[] transactionId) throws InvalidHeaderValueException {
-        super();
-        setMessageType(PduHeaders.MESSAGE_TYPE_SEND_REQ);
-        setContentType(contentType);
-        setFrom(from);
-        setMmsVersion(mmsVersion);
-        setTransactionId(transactionId);
-    }
-
-    /**
-     * Constructor with given headers.
-     *
-     * @param headers Headers for this PDU.
-     */
-    SendReq(PduHeaders headers) {
-        super(headers);
-    }
-
-    /**
-     * Constructor with given headers and body
-     *
-     * @param headers Headers for this PDU.
-     * @param body Body of this PDu.
-     */
-    SendReq(PduHeaders headers, PduBody body) {
-        super(headers, body);
-    }
-
-    /**
-     * Get Bcc value.
-     *
-     * @return the value
-     */
-    public EncodedStringValue[] getBcc() {
-        return mPduHeaders.getEncodedStringValues(PduHeaders.BCC);
-    }
-
-    /**
-     * Add a "BCC" value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void addBcc(EncodedStringValue value) {
-        mPduHeaders.appendEncodedStringValue(value, PduHeaders.BCC);
-    }
-
-    /**
-     * Set "BCC" value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setBcc(EncodedStringValue[] value) {
-        mPduHeaders.setEncodedStringValues(value, PduHeaders.BCC);
-    }
-
-    /**
-     * Get CC value.
-     *
-     * @return the value
-     */
-    public EncodedStringValue[] getCc() {
-        return mPduHeaders.getEncodedStringValues(PduHeaders.CC);
-    }
-
-    /**
-     * Add a "CC" value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void addCc(EncodedStringValue value) {
-        mPduHeaders.appendEncodedStringValue(value, PduHeaders.CC);
-    }
-
-    /**
-     * Set "CC" value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setCc(EncodedStringValue[] value) {
-        mPduHeaders.setEncodedStringValues(value, PduHeaders.CC);
-    }
-
-    /**
-     * Get Content-type value.
-     *
-     * @return the value
-     */
-    public byte[] getContentType() {
-        return mPduHeaders.getTextString(PduHeaders.CONTENT_TYPE);
-    }
-
-    /**
-     * Set Content-type value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setContentType(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.CONTENT_TYPE);
-    }
-
-    /**
-     * Get X-Mms-Delivery-Report value.
-     *
-     * @return the value
-     */
-    public int getDeliveryReport() {
-        return mPduHeaders.getOctet(PduHeaders.DELIVERY_REPORT);
-    }
-
-    /**
-     * Set X-Mms-Delivery-Report value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    public void setDeliveryReport(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.DELIVERY_REPORT);
-    }
-
-    /**
-     * Get X-Mms-Expiry value.
-     *
-     * Expiry-value = Value-length
-     *      (Absolute-token Date-value | Relative-token Delta-seconds-value)
-     *
-     * @return the value
-     */
-    public long getExpiry() {
-        return mPduHeaders.getLongInteger(PduHeaders.EXPIRY);
-    }
-
-    /**
-     * Set X-Mms-Expiry value.
-     *
-     * @param value the value
-     */
-    public void setExpiry(long value) {
-        mPduHeaders.setLongInteger(value, PduHeaders.EXPIRY);
-    }
-
-    /**
-     * Get X-Mms-MessageSize value.
-     *
-     * Expiry-value = size of message
-     *
-     * @return the value
-     */
-    public long getMessageSize() {
-        return mPduHeaders.getLongInteger(PduHeaders.MESSAGE_SIZE);
-    }
-
-    /**
-     * Set X-Mms-MessageSize value.
-     *
-     * @param value the value
-     */
-    public void setMessageSize(long value) {
-        mPduHeaders.setLongInteger(value, PduHeaders.MESSAGE_SIZE);
-    }
-
-    /**
-     * Get X-Mms-Message-Class value.
-     * Message-class-value = Class-identifier | Token-text
-     * Class-identifier = Personal | Advertisement | Informational | Auto
-     *
-     * @return the value
-     */
-    public byte[] getMessageClass() {
-        return mPduHeaders.getTextString(PduHeaders.MESSAGE_CLASS);
-    }
-
-    /**
-     * Set X-Mms-Message-Class value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setMessageClass(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.MESSAGE_CLASS);
-    }
-
-    /**
-     * Get X-Mms-Read-Report value.
-     *
-     * @return the value
-     */
-    public int getReadReport() {
-        return mPduHeaders.getOctet(PduHeaders.READ_REPORT);
-    }
-
-    /**
-     * Set X-Mms-Read-Report value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    public void setReadReport(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.READ_REPORT);
-    }
-
-    /**
-     * Set "To" value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setTo(EncodedStringValue[] value) {
-        mPduHeaders.setEncodedStringValues(value, PduHeaders.TO);
-    }
-
-    /**
-     * Get X-Mms-Transaction-Id field value.
-     *
-     * @return the X-Mms-Report-Allowed value
-     */
-    public byte[] getTransactionId() {
-        return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID);
-    }
-
-    /**
-     * Set X-Mms-Transaction-Id field value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setTransactionId(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID);
-    }
-
-    /*
-     * Optional, not supported header fields:
-     *
-     *     public byte getAdaptationAllowed() {return 0};
-     *     public void setAdaptationAllowed(btye value) {};
-     *
-     *     public byte[] getApplicId() {return null;}
-     *     public void setApplicId(byte[] value) {}
-     *
-     *     public byte[] getAuxApplicId() {return null;}
-     *     public void getAuxApplicId(byte[] value) {}
-     *
-     *     public byte getContentClass() {return 0x00;}
-     *     public void setApplicId(byte value) {}
-     *
-     *     public long getDeliveryTime() {return 0};
-     *     public void setDeliveryTime(long value) {};
-     *
-     *     public byte getDrmContent() {return 0x00;}
-     *     public void setDrmContent(byte value) {}
-     *
-     *     public MmFlagsValue getMmFlags() {return null;}
-     *     public void setMmFlags(MmFlagsValue value) {}
-     *
-     *     public MmStateValue getMmState() {return null;}
-     *     public void getMmState(MmStateValue value) {}
-     *
-     *     public byte[] getReplyApplicId() {return 0x00;}
-     *     public void setReplyApplicId(byte[] value) {}
-     *
-     *     public byte getReplyCharging() {return 0x00;}
-     *     public void setReplyCharging(byte value) {}
-     *
-     *     public byte getReplyChargingDeadline() {return 0x00;}
-     *     public void setReplyChargingDeadline(byte value) {}
-     *
-     *     public byte[] getReplyChargingId() {return 0x00;}
-     *     public void setReplyChargingId(byte[] value) {}
-     *
-     *     public long getReplyChargingSize() {return 0;}
-     *     public void setReplyChargingSize(long value) {}
-     *
-     *     public byte[] getReplyApplicId() {return 0x00;}
-     *     public void setReplyApplicId(byte[] value) {}
-     *
-     *     public byte getStore() {return 0x00;}
-     *     public void setStore(byte value) {}
-     */
-}
diff --git a/core/java/com/google/android/mms/pdu/package.html b/core/java/com/google/android/mms/pdu/package.html
deleted file mode 100755
index c9f96a6..0000000
--- a/core/java/com/google/android/mms/pdu/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<body>
-
-{@hide}
-
-</body>
diff --git a/core/java/com/google/android/mms/util/AbstractCache.java b/core/java/com/google/android/mms/util/AbstractCache.java
deleted file mode 100644
index 39b2abf..0000000
--- a/core/java/com/google/android/mms/util/AbstractCache.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2008 Esmertec AG.
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.util;
-
-import android.util.Log;
-
-import java.util.HashMap;
-
-public abstract class AbstractCache<K, V> {
-    private static final String TAG = "AbstractCache";
-    private static final boolean DEBUG = false;
-    private static final boolean LOCAL_LOGV = false;
-
-    private static final int MAX_CACHED_ITEMS  = 500;
-
-    private final HashMap<K, CacheEntry<V>> mCacheMap;
-
-    protected AbstractCache() {
-        mCacheMap = new HashMap<K, CacheEntry<V>>();
-    }
-
-    public boolean put(K key, V value) {
-        if (LOCAL_LOGV) {
-            Log.v(TAG, "Trying to put " + key + " into cache.");
-        }
-
-        if (mCacheMap.size() >= MAX_CACHED_ITEMS) {
-            // TODO Should remove the oldest or least hit cached entry
-            // and then cache the new one.
-            if (LOCAL_LOGV) {
-                Log.v(TAG, "Failed! size limitation reached.");
-            }
-            return false;
-        }
-
-        if (key != null) {
-            CacheEntry<V> cacheEntry = new CacheEntry<V>();
-            cacheEntry.value = value;
-            mCacheMap.put(key, cacheEntry);
-
-            if (LOCAL_LOGV) {
-                Log.v(TAG, key + " cached, " + mCacheMap.size() + " items total.");
-            }
-            return true;
-        }
-        return false;
-    }
-
-    public V get(K key) {
-        if (LOCAL_LOGV) {
-            Log.v(TAG, "Trying to get " + key + " from cache.");
-        }
-
-        if (key != null) {
-            CacheEntry<V> cacheEntry = mCacheMap.get(key);
-            if (cacheEntry != null) {
-                cacheEntry.hit++;
-                if (LOCAL_LOGV) {
-                    Log.v(TAG, key + " hit " + cacheEntry.hit + " times.");
-                }
-                return cacheEntry.value;
-            }
-        }
-        return null;
-    }
-
-    public V purge(K key) {
-        if (LOCAL_LOGV) {
-            Log.v(TAG, "Trying to purge " + key);
-        }
-
-        CacheEntry<V> v = mCacheMap.remove(key);
-
-        if (LOCAL_LOGV) {
-            Log.v(TAG, mCacheMap.size() + " items cached.");
-        }
-
-        return v != null ? v.value : null;
-    }
-
-    public void purgeAll() {
-        if (LOCAL_LOGV) {
-            Log.v(TAG, "Purging cache, " + mCacheMap.size()
-                    + " items dropped.");
-        }
-        mCacheMap.clear();
-    }
-
-    public int size() {
-        return mCacheMap.size();
-    }
-
-    private static class CacheEntry<V> {
-        int hit;
-        V value;
-    }
-}
diff --git a/core/java/com/google/android/mms/util/DownloadDrmHelper.java b/core/java/com/google/android/mms/util/DownloadDrmHelper.java
deleted file mode 100644
index 6852eca..0000000
--- a/core/java/com/google/android/mms/util/DownloadDrmHelper.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package com.google.android.mms.util;
-
-import android.content.Context;
-import android.drm.DrmManagerClient;
-import android.util.Log;
-
-public class DownloadDrmHelper {
-    private static final String TAG = "DownloadDrmHelper";
-
-    /** The MIME type of special DRM files */
-    public static final String MIMETYPE_DRM_MESSAGE = "application/vnd.oma.drm.message";
-
-    /** The extensions of special DRM files */
-    public static final String EXTENSION_DRM_MESSAGE = ".dm";
-
-    public static final String EXTENSION_INTERNAL_FWDL = ".fl";
-
-    /**
-     * Checks if the Media Type is a DRM Media Type
-     *
-     * @param drmManagerClient A DrmManagerClient
-     * @param mimetype Media Type to check
-     * @return True if the Media Type is DRM else false
-     */
-    public static boolean isDrmMimeType(Context context, String mimetype) {
-        boolean result = false;
-        if (context != null) {
-            try {
-                DrmManagerClient drmClient = new DrmManagerClient(context);
-                if (drmClient != null && mimetype != null && mimetype.length() > 0) {
-                    result = drmClient.canHandle("", mimetype);
-                }
-            } catch (IllegalArgumentException e) {
-                Log.w(TAG,
-                        "DrmManagerClient instance could not be created, context is Illegal.");
-            } catch (IllegalStateException e) {
-                Log.w(TAG, "DrmManagerClient didn't initialize properly.");
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Checks if the Media Type needs to be DRM converted
-     *
-     * @param mimetype Media type of the content
-     * @return True if convert is needed else false
-     */
-    public static boolean isDrmConvertNeeded(String mimetype) {
-        return MIMETYPE_DRM_MESSAGE.equals(mimetype);
-    }
-
-    /**
-     * Modifies the file extension for a DRM Forward Lock file NOTE: This
-     * function shouldn't be called if the file shouldn't be DRM converted
-     */
-    public static String modifyDrmFwLockFileExtension(String filename) {
-        if (filename != null) {
-            int extensionIndex;
-            extensionIndex = filename.lastIndexOf(".");
-            if (extensionIndex != -1) {
-                filename = filename.substring(0, extensionIndex);
-            }
-            filename = filename.concat(EXTENSION_INTERNAL_FWDL);
-        }
-        return filename;
-    }
-
-    /**
-     * Gets the original mime type of DRM protected content.
-     *
-     * @param context The context
-     * @param path Path to the file
-     * @param containingMime The current mime type of of the file i.e. the
-     *            containing mime type
-     * @return The original mime type of the file if DRM protected else the
-     *         currentMime
-     */
-    public static String getOriginalMimeType(Context context, String path, String containingMime) {
-        String result = containingMime;
-        DrmManagerClient drmClient = new DrmManagerClient(context);
-        try {
-            if (drmClient.canHandle(path, null)) {
-                result = drmClient.getOriginalMimeType(path);
-            }
-        } catch (IllegalArgumentException ex) {
-            Log.w(TAG,
-                    "Can't get original mime type since path is null or empty string.");
-        } catch (IllegalStateException ex) {
-            Log.w(TAG, "DrmManagerClient didn't initialize properly.");
-        }
-        return result;
-    }
-}
diff --git a/core/java/com/google/android/mms/util/DrmConvertSession.java b/core/java/com/google/android/mms/util/DrmConvertSession.java
deleted file mode 100644
index 2d8f274..0000000
--- a/core/java/com/google/android/mms/util/DrmConvertSession.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-package com.google.android.mms.util;
-
-import android.content.Context;
-import android.drm.DrmConvertedStatus;
-import android.drm.DrmManagerClient;
-import android.util.Log;
-import android.provider.Downloads;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-
-
-public class DrmConvertSession {
-    private DrmManagerClient mDrmClient;
-    private int mConvertSessionId;
-    private static final String TAG = "DrmConvertSession";
-
-    private DrmConvertSession(DrmManagerClient drmClient, int convertSessionId) {
-        mDrmClient = drmClient;
-        mConvertSessionId = convertSessionId;
-    }
-
-    /**
-     * Start of converting a file.
-     *
-     * @param context The context of the application running the convert session.
-     * @param mimeType Mimetype of content that shall be converted.
-     * @return A convert session or null in case an error occurs.
-     */
-    public static DrmConvertSession open(Context context, String mimeType) {
-        DrmManagerClient drmClient = null;
-        int convertSessionId = -1;
-        if (context != null && mimeType != null && !mimeType.equals("")) {
-            try {
-                drmClient = new DrmManagerClient(context);
-                try {
-                    convertSessionId = drmClient.openConvertSession(mimeType);
-                } catch (IllegalArgumentException e) {
-                    Log.w(TAG, "Conversion of Mimetype: " + mimeType
-                            + " is not supported.", e);
-                } catch (IllegalStateException e) {
-                    Log.w(TAG, "Could not access Open DrmFramework.", e);
-                }
-            } catch (IllegalArgumentException e) {
-                Log.w(TAG,
-                        "DrmManagerClient instance could not be created, context is Illegal.");
-            } catch (IllegalStateException e) {
-                Log.w(TAG, "DrmManagerClient didn't initialize properly.");
-            }
-        }
-
-        if (drmClient == null || convertSessionId < 0) {
-            return null;
-        } else {
-            return new DrmConvertSession(drmClient, convertSessionId);
-        }
-    }
-    /**
-     * Convert a buffer of data to protected format.
-     *
-     * @param buffer Buffer filled with data to convert.
-     * @param size The number of bytes that shall be converted.
-     * @return A Buffer filled with converted data, if execution is ok, in all
-     *         other case null.
-     */
-    public byte [] convert(byte[] inBuffer, int size) {
-        byte[] result = null;
-        if (inBuffer != null) {
-            DrmConvertedStatus convertedStatus = null;
-            try {
-                if (size != inBuffer.length) {
-                    byte[] buf = new byte[size];
-                    System.arraycopy(inBuffer, 0, buf, 0, size);
-                    convertedStatus = mDrmClient.convertData(mConvertSessionId, buf);
-                } else {
-                    convertedStatus = mDrmClient.convertData(mConvertSessionId, inBuffer);
-                }
-
-                if (convertedStatus != null &&
-                        convertedStatus.statusCode == DrmConvertedStatus.STATUS_OK &&
-                        convertedStatus.convertedData != null) {
-                    result = convertedStatus.convertedData;
-                }
-            } catch (IllegalArgumentException e) {
-                Log.w(TAG, "Buffer with data to convert is illegal. Convertsession: "
-                        + mConvertSessionId, e);
-            } catch (IllegalStateException e) {
-                Log.w(TAG, "Could not convert data. Convertsession: " +
-                        mConvertSessionId, e);
-            }
-        } else {
-            throw new IllegalArgumentException("Parameter inBuffer is null");
-        }
-        return result;
-    }
-
-    /**
-     * Ends a conversion session of a file.
-     *
-     * @param fileName The filename of the converted file.
-     * @return Downloads.Impl.STATUS_SUCCESS if execution is ok.
-     *         Downloads.Impl.STATUS_FILE_ERROR in case converted file can not
-     *         be accessed. Downloads.Impl.STATUS_NOT_ACCEPTABLE if a problem
-     *         occurs when accessing drm framework.
-     *         Downloads.Impl.STATUS_UNKNOWN_ERROR if a general error occurred.
-     */
-    public int close(String filename) {
-        DrmConvertedStatus convertedStatus = null;
-        int result = Downloads.Impl.STATUS_UNKNOWN_ERROR;
-        if (mDrmClient != null && mConvertSessionId >= 0) {
-            try {
-                convertedStatus = mDrmClient.closeConvertSession(mConvertSessionId);
-                if (convertedStatus == null ||
-                        convertedStatus.statusCode != DrmConvertedStatus.STATUS_OK ||
-                        convertedStatus.convertedData == null) {
-                    result = Downloads.Impl.STATUS_NOT_ACCEPTABLE;
-                } else {
-                    RandomAccessFile rndAccessFile = null;
-                    try {
-                        rndAccessFile = new RandomAccessFile(filename, "rw");
-                        rndAccessFile.seek(convertedStatus.offset);
-                        rndAccessFile.write(convertedStatus.convertedData);
-                        result = Downloads.Impl.STATUS_SUCCESS;
-                    } catch (FileNotFoundException e) {
-                        result = Downloads.Impl.STATUS_FILE_ERROR;
-                        Log.w(TAG, "File: " + filename + " could not be found.", e);
-                    } catch (IOException e) {
-                        result = Downloads.Impl.STATUS_FILE_ERROR;
-                        Log.w(TAG, "Could not access File: " + filename + " .", e);
-                    } catch (IllegalArgumentException e) {
-                        result = Downloads.Impl.STATUS_FILE_ERROR;
-                        Log.w(TAG, "Could not open file in mode: rw", e);
-                    } catch (SecurityException e) {
-                        Log.w(TAG, "Access to File: " + filename +
-                                " was denied denied by SecurityManager.", e);
-                    } finally {
-                        if (rndAccessFile != null) {
-                            try {
-                                rndAccessFile.close();
-                            } catch (IOException e) {
-                                result = Downloads.Impl.STATUS_FILE_ERROR;
-                                Log.w(TAG, "Failed to close File:" + filename
-                                        + ".", e);
-                            }
-                        }
-                    }
-                }
-            } catch (IllegalStateException e) {
-                Log.w(TAG, "Could not close convertsession. Convertsession: " +
-                        mConvertSessionId, e);
-            }
-        }
-        return result;
-    }
-}
diff --git a/core/java/com/google/android/mms/util/PduCache.java b/core/java/com/google/android/mms/util/PduCache.java
deleted file mode 100644
index de83124..0000000
--- a/core/java/com/google/android/mms/util/PduCache.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Copyright (C) 2008 Esmertec AG.
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.util;
-
-import android.content.ContentUris;
-import android.content.UriMatcher;
-import android.net.Uri;
-import android.provider.Telephony.Mms;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.HashSet;
-
-public final class PduCache extends AbstractCache<Uri, PduCacheEntry> {
-    private static final String TAG = "PduCache";
-    private static final boolean DEBUG = false;
-    private static final boolean LOCAL_LOGV = false;
-
-    private static final int MMS_ALL             = 0;
-    private static final int MMS_ALL_ID          = 1;
-    private static final int MMS_INBOX           = 2;
-    private static final int MMS_INBOX_ID        = 3;
-    private static final int MMS_SENT            = 4;
-    private static final int MMS_SENT_ID         = 5;
-    private static final int MMS_DRAFTS          = 6;
-    private static final int MMS_DRAFTS_ID       = 7;
-    private static final int MMS_OUTBOX          = 8;
-    private static final int MMS_OUTBOX_ID       = 9;
-    private static final int MMS_CONVERSATION    = 10;
-    private static final int MMS_CONVERSATION_ID = 11;
-
-    private static final UriMatcher URI_MATCHER;
-    private static final HashMap<Integer, Integer> MATCH_TO_MSGBOX_ID_MAP;
-
-    private static PduCache sInstance;
-
-    static {
-        URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
-        URI_MATCHER.addURI("mms", null,         MMS_ALL);
-        URI_MATCHER.addURI("mms", "#",          MMS_ALL_ID);
-        URI_MATCHER.addURI("mms", "inbox",      MMS_INBOX);
-        URI_MATCHER.addURI("mms", "inbox/#",    MMS_INBOX_ID);
-        URI_MATCHER.addURI("mms", "sent",       MMS_SENT);
-        URI_MATCHER.addURI("mms", "sent/#",     MMS_SENT_ID);
-        URI_MATCHER.addURI("mms", "drafts",     MMS_DRAFTS);
-        URI_MATCHER.addURI("mms", "drafts/#",   MMS_DRAFTS_ID);
-        URI_MATCHER.addURI("mms", "outbox",     MMS_OUTBOX);
-        URI_MATCHER.addURI("mms", "outbox/#",   MMS_OUTBOX_ID);
-        URI_MATCHER.addURI("mms-sms", "conversations",   MMS_CONVERSATION);
-        URI_MATCHER.addURI("mms-sms", "conversations/#", MMS_CONVERSATION_ID);
-
-        MATCH_TO_MSGBOX_ID_MAP = new HashMap<Integer, Integer>();
-        MATCH_TO_MSGBOX_ID_MAP.put(MMS_INBOX,  Mms.MESSAGE_BOX_INBOX);
-        MATCH_TO_MSGBOX_ID_MAP.put(MMS_SENT,   Mms.MESSAGE_BOX_SENT);
-        MATCH_TO_MSGBOX_ID_MAP.put(MMS_DRAFTS, Mms.MESSAGE_BOX_DRAFTS);
-        MATCH_TO_MSGBOX_ID_MAP.put(MMS_OUTBOX, Mms.MESSAGE_BOX_OUTBOX);
-    }
-
-    private final HashMap<Integer, HashSet<Uri>> mMessageBoxes;
-    private final HashMap<Long, HashSet<Uri>> mThreads;
-    private final HashSet<Uri> mUpdating;
-
-    private PduCache() {
-        mMessageBoxes = new HashMap<Integer, HashSet<Uri>>();
-        mThreads = new HashMap<Long, HashSet<Uri>>();
-        mUpdating = new HashSet<Uri>();
-    }
-
-    synchronized public static final PduCache getInstance() {
-        if (sInstance == null) {
-            if (LOCAL_LOGV) {
-                Log.v(TAG, "Constructing new PduCache instance.");
-            }
-            sInstance = new PduCache();
-        }
-        return sInstance;
-    }
-
-    @Override
-    synchronized public boolean put(Uri uri, PduCacheEntry entry) {
-        int msgBoxId = entry.getMessageBox();
-        HashSet<Uri> msgBox = mMessageBoxes.get(msgBoxId);
-        if (msgBox == null) {
-            msgBox = new HashSet<Uri>();
-            mMessageBoxes.put(msgBoxId, msgBox);
-        }
-
-        long threadId = entry.getThreadId();
-        HashSet<Uri> thread = mThreads.get(threadId);
-        if (thread == null) {
-            thread = new HashSet<Uri>();
-            mThreads.put(threadId, thread);
-        }
-
-        Uri finalKey = normalizeKey(uri);
-        boolean result = super.put(finalKey, entry);
-        if (result) {
-            msgBox.add(finalKey);
-            thread.add(finalKey);
-        }
-        setUpdating(uri, false);
-        return result;
-    }
-
-    synchronized public void setUpdating(Uri uri, boolean updating) {
-        if (updating) {
-            mUpdating.add(uri);
-        } else {
-            mUpdating.remove(uri);
-        }
-    }
-
-    synchronized public boolean isUpdating(Uri uri) {
-        return mUpdating.contains(uri);
-    }
-
-    @Override
-    synchronized public PduCacheEntry purge(Uri uri) {
-        int match = URI_MATCHER.match(uri);
-        switch (match) {
-            case MMS_ALL_ID:
-                return purgeSingleEntry(uri);
-            case MMS_INBOX_ID:
-            case MMS_SENT_ID:
-            case MMS_DRAFTS_ID:
-            case MMS_OUTBOX_ID:
-                String msgId = uri.getLastPathSegment();
-                return purgeSingleEntry(Uri.withAppendedPath(Mms.CONTENT_URI, msgId));
-            // Implicit batch of purge, return null.
-            case MMS_ALL:
-            case MMS_CONVERSATION:
-                purgeAll();
-                return null;
-            case MMS_INBOX:
-            case MMS_SENT:
-            case MMS_DRAFTS:
-            case MMS_OUTBOX:
-                purgeByMessageBox(MATCH_TO_MSGBOX_ID_MAP.get(match));
-                return null;
-            case MMS_CONVERSATION_ID:
-                purgeByThreadId(ContentUris.parseId(uri));
-                return null;
-            default:
-                return null;
-        }
-    }
-
-    private PduCacheEntry purgeSingleEntry(Uri key) {
-        mUpdating.remove(key);
-        PduCacheEntry entry = super.purge(key);
-        if (entry != null) {
-            removeFromThreads(key, entry);
-            removeFromMessageBoxes(key, entry);
-            return entry;
-        }
-        return null;
-    }
-
-    @Override
-    synchronized public void purgeAll() {
-        super.purgeAll();
-
-        mMessageBoxes.clear();
-        mThreads.clear();
-        mUpdating.clear();
-    }
-
-    /**
-     * @param uri The Uri to be normalized.
-     * @return Uri The normalized key of cached entry.
-     */
-    private Uri normalizeKey(Uri uri) {
-        int match = URI_MATCHER.match(uri);
-        Uri normalizedKey = null;
-
-        switch (match) {
-            case MMS_ALL_ID:
-                normalizedKey = uri;
-                break;
-            case MMS_INBOX_ID:
-            case MMS_SENT_ID:
-            case MMS_DRAFTS_ID:
-            case MMS_OUTBOX_ID:
-                String msgId = uri.getLastPathSegment();
-                normalizedKey = Uri.withAppendedPath(Mms.CONTENT_URI, msgId);
-                break;
-            default:
-                return null;
-        }
-
-        if (LOCAL_LOGV) {
-            Log.v(TAG, uri + " -> " + normalizedKey);
-        }
-        return normalizedKey;
-    }
-
-    private void purgeByMessageBox(Integer msgBoxId) {
-        if (LOCAL_LOGV) {
-            Log.v(TAG, "Purge cache in message box: " + msgBoxId);
-        }
-
-        if (msgBoxId != null) {
-            HashSet<Uri> msgBox = mMessageBoxes.remove(msgBoxId);
-            if (msgBox != null) {
-                for (Uri key : msgBox) {
-                    mUpdating.remove(key);
-                    PduCacheEntry entry = super.purge(key);
-                    if (entry != null) {
-                        removeFromThreads(key, entry);
-                    }
-                }
-            }
-        }
-    }
-
-    private void removeFromThreads(Uri key, PduCacheEntry entry) {
-        HashSet<Uri> thread = mThreads.get(entry.getThreadId());
-        if (thread != null) {
-            thread.remove(key);
-        }
-    }
-
-    private void purgeByThreadId(long threadId) {
-        if (LOCAL_LOGV) {
-            Log.v(TAG, "Purge cache in thread: " + threadId);
-        }
-
-        HashSet<Uri> thread = mThreads.remove(threadId);
-        if (thread != null) {
-            for (Uri key : thread) {
-                mUpdating.remove(key);
-                PduCacheEntry entry = super.purge(key);
-                if (entry != null) {
-                    removeFromMessageBoxes(key, entry);
-                }
-            }
-        }
-    }
-
-    private void removeFromMessageBoxes(Uri key, PduCacheEntry entry) {
-        HashSet<Uri> msgBox = mThreads.get(Long.valueOf(entry.getMessageBox()));
-        if (msgBox != null) {
-            msgBox.remove(key);
-        }
-    }
-}
diff --git a/core/java/com/google/android/mms/util/PduCacheEntry.java b/core/java/com/google/android/mms/util/PduCacheEntry.java
deleted file mode 100644
index 8b41386..0000000
--- a/core/java/com/google/android/mms/util/PduCacheEntry.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2008 Esmertec AG.
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.util;
-
-import com.google.android.mms.pdu.GenericPdu;
-
-public final class PduCacheEntry {
-    private final GenericPdu mPdu;
-    private final int mMessageBox;
-    private final long mThreadId;
-
-    public PduCacheEntry(GenericPdu pdu, int msgBox, long threadId) {
-        mPdu = pdu;
-        mMessageBox = msgBox;
-        mThreadId = threadId;
-    }
-
-    public GenericPdu getPdu() {
-        return mPdu;
-    }
-
-    public int getMessageBox() {
-        return mMessageBox;
-    }
-
-    public long getThreadId() {
-        return mThreadId;
-    }
-}
diff --git a/core/java/com/google/android/mms/util/SqliteWrapper.java b/core/java/com/google/android/mms/util/SqliteWrapper.java
deleted file mode 100644
index bcdac22..0000000
--- a/core/java/com/google/android/mms/util/SqliteWrapper.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2008 Esmertec AG.
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.util;
-
-import android.app.ActivityManager;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteException;
-import android.net.Uri;
-import android.util.Log;
-import android.widget.Toast;
-
-public final class SqliteWrapper {
-    private static final String TAG = "SqliteWrapper";
-    private static final String SQLITE_EXCEPTION_DETAIL_MESSAGE
-                = "unable to open database file";
-
-    private SqliteWrapper() {
-        // Forbidden being instantiated.
-    }
-
-    // FIXME: It looks like outInfo.lowMemory does not work well as we expected.
-    // after run command: adb shell fillup -p 100, outInfo.lowMemory is still false.
-    private static boolean isLowMemory(Context context) {
-        if (null == context) {
-            return false;
-        }
-
-        ActivityManager am = (ActivityManager)
-                        context.getSystemService(Context.ACTIVITY_SERVICE);
-        ActivityManager.MemoryInfo outInfo = new ActivityManager.MemoryInfo();
-        am.getMemoryInfo(outInfo);
-
-        return outInfo.lowMemory;
-    }
-
-    // FIXME: need to optimize this method.
-    private static boolean isLowMemory(SQLiteException e) {
-        return e.getMessage().equals(SQLITE_EXCEPTION_DETAIL_MESSAGE);
-    }
-
-    public static void checkSQLiteException(Context context, SQLiteException e) {
-        if (isLowMemory(e)) {
-            Toast.makeText(context, com.android.internal.R.string.low_memory,
-                    Toast.LENGTH_SHORT).show();
-        } else {
-            throw e;
-        }
-    }
-
-    public static Cursor query(Context context, ContentResolver resolver, Uri uri,
-            String[] projection, String selection, String[] selectionArgs, String sortOrder) {
-        try {
-            return resolver.query(uri, projection, selection, selectionArgs, sortOrder);
-        } catch (SQLiteException e) {
-            Log.e(TAG, "Catch a SQLiteException when query: ", e);
-            checkSQLiteException(context, e);
-            return null;
-        }
-    }
-
-    public static boolean requery(Context context, Cursor cursor) {
-        try {
-            return cursor.requery();
-        } catch (SQLiteException e) {
-            Log.e(TAG, "Catch a SQLiteException when requery: ", e);
-            checkSQLiteException(context, e);
-            return false;
-        }
-    }
-    public static int update(Context context, ContentResolver resolver, Uri uri,
-            ContentValues values, String where, String[] selectionArgs) {
-        try {
-            return resolver.update(uri, values, where, selectionArgs);
-        } catch (SQLiteException e) {
-            Log.e(TAG, "Catch a SQLiteException when update: ", e);
-            checkSQLiteException(context, e);
-            return -1;
-        }
-    }
-
-    public static int delete(Context context, ContentResolver resolver, Uri uri,
-            String where, String[] selectionArgs) {
-        try {
-            return resolver.delete(uri, where, selectionArgs);
-        } catch (SQLiteException e) {
-            Log.e(TAG, "Catch a SQLiteException when delete: ", e);
-            checkSQLiteException(context, e);
-            return -1;
-        }
-    }
-
-    public static Uri insert(Context context, ContentResolver resolver,
-            Uri uri, ContentValues values) {
-        try {
-            return resolver.insert(uri, values);
-        } catch (SQLiteException e) {
-            Log.e(TAG, "Catch a SQLiteException when insert: ", e);
-            checkSQLiteException(context, e);
-            return null;
-        }
-    }
-}
diff --git a/core/java/com/google/android/mms/util/package.html b/core/java/com/google/android/mms/util/package.html
deleted file mode 100755
index c9f96a6..0000000
--- a/core/java/com/google/android/mms/util/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<body>
-
-{@hide}
-
-</body>
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 1f2b4ba..eb39b12 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -32,6 +32,7 @@
 	com_google_android_gles_jni_EGLImpl.cpp \
 	com_google_android_gles_jni_GLImpl.cpp.arm \
 	android_app_NativeActivity.cpp \
+	android_opengl_EGL14.cpp \
 	android_opengl_GLES10.cpp \
 	android_opengl_GLES10Ext.cpp \
 	android_opengl_GLES11.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 7a23747..532a6e5 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -68,6 +68,7 @@
 
 extern int register_com_google_android_gles_jni_EGLImpl(JNIEnv* env);
 extern int register_com_google_android_gles_jni_GLImpl(JNIEnv* env);
+extern int register_android_opengl_jni_EGL14(JNIEnv* env);
 extern int register_android_opengl_jni_GLES10(JNIEnv* env);
 extern int register_android_opengl_jni_GLES10Ext(JNIEnv* env);
 extern int register_android_opengl_jni_GLES11(JNIEnv* env);
@@ -1105,6 +1106,7 @@
     REG_JNI(register_android_view_TextureView),
     REG_JNI(register_com_google_android_gles_jni_EGLImpl),
     REG_JNI(register_com_google_android_gles_jni_GLImpl),
+    REG_JNI(register_android_opengl_jni_EGL14),
     REG_JNI(register_android_opengl_jni_GLES10),
     REG_JNI(register_android_opengl_jni_GLES10Ext),
     REG_JNI(register_android_opengl_jni_GLES11),
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index 5466be4..2bdba87 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -345,26 +345,10 @@
 
 void TextLayoutShaper::init() {
     mDefaultTypeface = SkFontHost::CreateTypeface(NULL, NULL, NULL, 0, SkTypeface::kNormal);
-    mArabicTypeface = NULL;
-    mHebrewRegularTypeface = NULL;
-    mHebrewBoldTypeface = NULL;
-    mBengaliTypeface = NULL;
-    mThaiTypeface = NULL;
-    mDevanagariRegularTypeface = NULL;
-    mTamilRegularTypeface = NULL;
-    mTamilBoldTypeface = NULL;
 }
 
 void TextLayoutShaper::unrefTypefaces() {
     SkSafeUnref(mDefaultTypeface);
-    SkSafeUnref(mArabicTypeface);
-    SkSafeUnref(mHebrewRegularTypeface);
-    SkSafeUnref(mHebrewBoldTypeface);
-    SkSafeUnref(mBengaliTypeface);
-    SkSafeUnref(mThaiTypeface);
-    SkSafeUnref(mDevanagariRegularTypeface);
-    SkSafeUnref(mTamilRegularTypeface);
-    SkSafeUnref(mTamilBoldTypeface);
 }
 
 TextLayoutShaper::~TextLayoutShaper() {
@@ -750,115 +734,32 @@
  * assumption is that its lifetime is managed elsewhere - in particular, the fallback typefaces
  * for the default font live in a global cache.
  */
-SkTypeface* TextLayoutShaper::typefaceForUnichar(const SkPaint* paint, SkTypeface* typeface,
-        SkUnichar unichar, HB_Script script) {
-    // Set the correct Typeface depending on the script
-    switch (script) {
-    case HB_Script_Arabic:
-        typeface = getCachedTypeface(&mArabicTypeface, HB_Script_Arabic,
-                SkTypeface::kNormal);
-#if DEBUG_GLYPHS
-        ALOGD("Using Arabic Typeface");
-#endif
-        break;
-
-    case HB_Script_Hebrew:
-        if (typeface) {
-            switch (typeface->style()) {
-            case SkTypeface::kBold:
-            case SkTypeface::kBoldItalic:
-                typeface = getCachedTypeface(&mHebrewBoldTypeface, HB_Script_Hebrew,
-                        SkTypeface::kBold);
-#if DEBUG_GLYPHS
-                ALOGD("Using Hebrew Bold/BoldItalic Typeface");
-#endif
-                break;
-
-            case SkTypeface::kNormal:
-            case SkTypeface::kItalic:
-            default:
-                typeface = getCachedTypeface(&mHebrewRegularTypeface, HB_Script_Hebrew,
-                        SkTypeface::kNormal);
-#if DEBUG_GLYPHS
-                ALOGD("Using Hebrew Regular/Italic Typeface");
-#endif
-                break;
-            }
-        } else {
-            typeface = getCachedTypeface(&mHebrewRegularTypeface, HB_Script_Hebrew,
-                    SkTypeface::kNormal);
-#if DEBUG_GLYPHS
-            ALOGD("Using Hebrew Regular Typeface");
-#endif
-        }
-        break;
-
-    case HB_Script_Bengali:
-        typeface = getCachedTypeface(&mBengaliTypeface, HB_Script_Bengali,
-                SkTypeface::kNormal);
-#if DEBUG_GLYPHS
-        ALOGD("Using Bengali Typeface");
-#endif
-        break;
-
-    case HB_Script_Thai:
-        typeface = getCachedTypeface(&mThaiTypeface, HB_Script_Thai,
-                SkTypeface::kNormal);
-#if DEBUG_GLYPHS
-        ALOGD("Using Thai Typeface");
-#endif
-        break;
-
-    case HB_Script_Devanagari:
-       typeface = getCachedTypeface(&mDevanagariRegularTypeface, HB_Script_Devanagari,
-               SkTypeface::kNormal);
-#if DEBUG_GLYPHS
-       ALOGD("Using Devanagari Regular Typeface");
-#endif
-        break;
-
-    case HB_Script_Tamil:
-        if (typeface) {
-            switch (typeface->style()) {
-            case SkTypeface::kBold:
-            case SkTypeface::kBoldItalic:
-                typeface = getCachedTypeface(&mTamilBoldTypeface, HB_Script_Tamil,
-                        SkTypeface::kBold);
-#if DEBUG_GLYPHS
-                ALOGD("Using Tamil Bold Typeface");
-#endif
-                break;
-
-            case SkTypeface::kNormal:
-            case SkTypeface::kItalic:
-            default:
-                typeface = getCachedTypeface(&mTamilRegularTypeface, HB_Script_Tamil,
-                        SkTypeface::kNormal);
-#if DEBUG_GLYPHS
-                ALOGD("Using Tamil Regular Typeface");
-#endif
-                break;
-            }
-        } else {
-            typeface = getCachedTypeface(&mTamilRegularTypeface, HB_Script_Tamil,
-                    SkTypeface::kNormal);
-#if DEBUG_GLYPHS
-            ALOGD("Using Tamil Regular Typeface");
-#endif
-        }
-        break;
-
-    default:
-#if DEBUG_GLYPHS
-        if (typeface) {
-            ALOGD("Using Paint Typeface");
-        }
-#endif
-        break;
+SkTypeface* TextLayoutShaper::typefaceForScript(const SkPaint* paint, SkTypeface* typeface,
+        HB_Script script) {
+    SkTypeface::Style currentStyle = SkTypeface::kNormal;
+    if (typeface) {
+        currentStyle = typeface->style();
     }
+    typeface = SkCreateTypefaceForScript(script, currentStyle);
+#if DEBUG_GLYPHS
+    ALOGD("Using Harfbuzz Script %d, Style %d", script, currentStyle);
+#endif
     return typeface;
 }
 
+bool TextLayoutShaper::isComplexScript(HB_Script script) {
+    switch (script) {
+    case HB_Script_Common:
+    case HB_Script_Greek:
+    case HB_Script_Cyrillic:
+    case HB_Script_Hangul:
+    case HB_Script_Inherited:
+        return false;
+    default:
+        return true;
+    }
+}
+
 size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) {
     // Reset kerning
     mShaperItem.kerning_applied = false;
@@ -874,37 +775,35 @@
     // If we are a "common" script we dont need to shift
     size_t baseGlyphCount = 0;
     SkUnichar firstUnichar = 0;
-    switch (mShaperItem.item.script) {
-    case HB_Script_Arabic:
-    case HB_Script_Hebrew:
-    case HB_Script_Bengali:
-    case HB_Script_Devanagari:
-    case HB_Script_Tamil:
-    case HB_Script_Thai:{
-        const uint16_t* text16 = (const uint16_t*)(mShaperItem.string + mShaperItem.item.pos);
+    if (isComplexScript(mShaperItem.item.script)) {
+        const uint16_t* text16 = (const uint16_t*) (mShaperItem.string + mShaperItem.item.pos);
         const uint16_t* text16End = text16 + mShaperItem.item.length;
         firstUnichar = SkUTF16_NextUnichar(&text16);
         while (firstUnichar == ' ' && text16 < text16End) {
             firstUnichar = SkUTF16_NextUnichar(&text16);
         }
         baseGlyphCount = paint->getBaseGlyphCount(firstUnichar);
-        break;
-    }
-    default:
-        break;
     }
 
-    // We test the baseGlyphCount to see if the typeface supports the requested script
     if (baseGlyphCount != 0) {
-        typeface = typefaceForUnichar(paint, typeface, firstUnichar, mShaperItem.item.script);
+        typeface = typefaceForScript(paint, typeface, mShaperItem.item.script);
+        if (!typeface) {
+            typeface = mDefaultTypeface;
+            SkSafeRef(typeface);
+#if DEBUG_GLYPHS
+            ALOGD("Using Default Typeface");
+#endif
+        }
+    } else {
+        if (!typeface) {
+            typeface = mDefaultTypeface;
+#if DEBUG_GLYPHS
+            ALOGD("Using Default Typeface");
+#endif
+        }
+        SkSafeRef(typeface);
     }
 
-    if (!typeface) {
-        typeface = mDefaultTypeface;
-#if DEBUG_GLYPHS
-        ALOGD("Using Default Typeface");
-#endif
-    }
     mShapingPaint.setTypeface(typeface);
     mShaperItem.face = getCachedHBFace(typeface);
 
@@ -912,6 +811,7 @@
     ALOGD("Run typeface = %p, uniqueID = %d, hb_face = %p",
             typeface, typeface->uniqueID(), mShaperItem.face);
 #endif
+    SkSafeUnref(typeface);
 
     // Shape
     assert(mShaperItem.item.length > 0); // Harfbuzz will overwrite other memory if length is 0.
@@ -960,25 +860,6 @@
     delete[] mShaperItem.log_clusters;
 }
 
-SkTypeface* TextLayoutShaper::getCachedTypeface(SkTypeface** typeface, HB_Script script,
-        SkTypeface::Style style) {
-    if (!*typeface) {
-        *typeface = SkCreateTypefaceForScript(script, style);
-        // CreateFromFile(path) can return NULL if the path is non existing
-        if (!*typeface) {
-#if DEBUG_GLYPHS
-        ALOGD("No font for Harfbuzz script %d, will use default font", script);
-#endif
-            return mDefaultTypeface;
-        }
-        (*typeface)->ref();
-#if DEBUG_GLYPHS
-        ALOGD("Created SkTypeface for Harfbuzz script %d with uniqueID = %d", script, (*typeface)->uniqueID());
-#endif
-    }
-    return *typeface;
-}
-
 HB_Face TextLayoutShaper::getCachedHBFace(SkTypeface* typeface) {
     SkFontID fontId = typeface->uniqueID();
     ssize_t index = mCachedHBFaces.indexOfKey(fontId);
diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h
index 62d1796..0b25e93 100644
--- a/core/jni/android/graphics/TextLayoutCache.h
+++ b/core/jni/android/graphics/TextLayoutCache.h
@@ -189,17 +189,9 @@
     SkPaint mShapingPaint;
 
     /**
-     * Skia typefaces cached for shaping
+     * Skia default typeface to be returned if we cannot resolve script
      */
     SkTypeface* mDefaultTypeface;
-    SkTypeface* mArabicTypeface;
-    SkTypeface* mHebrewRegularTypeface;
-    SkTypeface* mHebrewBoldTypeface;
-    SkTypeface* mBengaliTypeface;
-    SkTypeface* mThaiTypeface;
-    SkTypeface* mDevanagariRegularTypeface;
-    SkTypeface* mTamilRegularTypeface;
-    SkTypeface* mTamilBoldTypeface;
 
     /**
      * Cache of Harfbuzz faces
@@ -224,8 +216,8 @@
     void init();
     void unrefTypefaces();
 
-    SkTypeface* typefaceForUnichar(const SkPaint* paint, SkTypeface* typeface,
-        SkUnichar unichar, HB_Script script);
+    SkTypeface* typefaceForScript(const SkPaint* paint, SkTypeface* typeface,
+        HB_Script script);
 
     size_t shapeFontRun(const SkPaint* paint, bool isRTL);
 
@@ -245,6 +237,7 @@
     bool doShaping(size_t size);
     void createShaperItemGlyphArrays(size_t size);
     void deleteShaperItemGlyphArrays();
+    bool isComplexScript(HB_Script script);
 
 }; // TextLayoutShaper
 
diff --git a/core/jni/android_opengl_EGL14.cpp b/core/jni/android_opengl_EGL14.cpp
new file mode 100644
index 0000000..c271aeb
--- /dev/null
+++ b/core/jni/android_opengl_EGL14.cpp
@@ -0,0 +1,1247 @@
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+// This source file is automatically generated
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include <android_runtime/AndroidRuntime.h>
+#include <android_runtime/android_view_Surface.h>
+#include <android_runtime/android_graphics_SurfaceTexture.h>
+#include <utils/misc.h>
+
+#include <assert.h>
+#include <EGL/egl.h>
+
+#include <gui/Surface.h>
+#include <gui/SurfaceTexture.h>
+#include <gui/SurfaceTextureClient.h>
+
+#include <ui/ANativeObjectBase.h>
+
+static int initialized = 0;
+
+static jclass egldisplayClass;
+static jclass eglcontextClass;
+static jclass eglsurfaceClass;
+static jclass eglconfigClass;
+
+static jmethodID egldisplayGetHandleID;
+static jmethodID eglcontextGetHandleID;
+static jmethodID eglsurfaceGetHandleID;
+static jmethodID eglconfigGetHandleID;
+
+static jmethodID egldisplayConstructor;
+static jmethodID eglcontextConstructor;
+static jmethodID eglsurfaceConstructor;
+static jmethodID eglconfigConstructor;
+
+static jobject eglNoContextObject;
+static jobject eglNoDisplayObject;
+static jobject eglNoSurfaceObject;
+
+
+
+/* Cache method IDs each time the class is loaded. */
+
+static void
+nativeClassInit(JNIEnv *_env, jclass glImplClass)
+{
+    jclass egldisplayClassLocal = _env->FindClass("android/opengl/EGLDisplay");
+    egldisplayClass = (jclass) _env->NewGlobalRef(egldisplayClassLocal);
+    jclass eglcontextClassLocal = _env->FindClass("android/opengl/EGLContext");
+    eglcontextClass = (jclass) _env->NewGlobalRef(eglcontextClassLocal);
+    jclass eglsurfaceClassLocal = _env->FindClass("android/opengl/EGLSurface");
+    eglsurfaceClass = (jclass) _env->NewGlobalRef(eglsurfaceClassLocal);
+    jclass eglconfigClassLocal = _env->FindClass("android/opengl/EGLConfig");
+    eglconfigClass = (jclass) _env->NewGlobalRef(eglconfigClassLocal);
+
+    egldisplayGetHandleID = _env->GetMethodID(egldisplayClass, "getHandle", "()I");
+    eglcontextGetHandleID = _env->GetMethodID(eglcontextClass, "getHandle", "()I");
+    eglsurfaceGetHandleID = _env->GetMethodID(eglsurfaceClass, "getHandle", "()I");
+    eglconfigGetHandleID = _env->GetMethodID(eglconfigClass, "getHandle", "()I");
+
+
+    egldisplayConstructor = _env->GetMethodID(egldisplayClass, "<init>", "(I)V");
+    eglcontextConstructor = _env->GetMethodID(eglcontextClass, "<init>", "(I)V");
+    eglsurfaceConstructor = _env->GetMethodID(eglsurfaceClass, "<init>", "(I)V");
+    eglconfigConstructor = _env->GetMethodID(eglconfigClass, "<init>", "(I)V");
+
+    jobject localeglNoContextObject = _env->NewObject(eglcontextClass, eglcontextConstructor, (jint)EGL_NO_CONTEXT);
+    eglNoContextObject = _env->NewGlobalRef(localeglNoContextObject);
+    jobject localeglNoDisplayObject = _env->NewObject(egldisplayClass, egldisplayConstructor, (jint)EGL_NO_DISPLAY);
+    eglNoDisplayObject = _env->NewGlobalRef(localeglNoDisplayObject);
+    jobject localeglNoSurfaceObject = _env->NewObject(eglsurfaceClass, eglsurfaceConstructor, (jint)EGL_NO_SURFACE);
+    eglNoSurfaceObject = _env->NewGlobalRef(localeglNoSurfaceObject);
+
+
+    jclass eglClass = _env->FindClass("android/opengl/EGL14");
+    jfieldID noContextFieldID = _env->GetStaticFieldID(eglClass, "EGL_NO_CONTEXT", "Landroid/opengl/EGLContext;");
+    _env->SetStaticObjectField(eglClass, noContextFieldID, eglNoContextObject);
+
+    jfieldID noDisplayFieldID = _env->GetStaticFieldID(eglClass, "EGL_NO_DISPLAY", "Landroid/opengl/EGLDisplay;");
+    _env->SetStaticObjectField(eglClass, noDisplayFieldID, eglNoDisplayObject);
+
+    jfieldID noSurfaceFieldID = _env->GetStaticFieldID(eglClass, "EGL_NO_SURFACE", "Landroid/opengl/EGLSurface;");
+    _env->SetStaticObjectField(eglClass, noSurfaceFieldID, eglNoSurfaceObject);
+}
+
+static void *
+fromEGLHandle(JNIEnv *_env, jmethodID mid, jobject obj) {
+    if (obj == NULL){
+        jniThrowException(_env, "java/lang/IllegalArgumentException",
+                          "Object is set to null.");
+    }
+
+    return (void*) (_env->CallIntMethod(obj, mid));
+}
+
+static jobject
+toEGLHandle(JNIEnv *_env, jclass cls, jmethodID con, void * handle) {
+    if (cls == eglcontextClass &&
+       (EGLContext)handle == EGL_NO_CONTEXT) {
+           return eglNoContextObject;
+    }
+
+    if (cls == egldisplayClass &&
+       (EGLDisplay)handle == EGL_NO_DISPLAY) {
+           return eglNoDisplayObject;
+    }
+
+    if (cls == eglsurfaceClass &&
+       (EGLSurface)handle == EGL_NO_SURFACE) {
+           return eglNoSurfaceObject;
+    }
+
+    return _env->NewObject(cls, con, (jint)handle);
+}
+
+// --------------------------------------------------------------------------
+/* EGLint eglGetError ( void ) */
+static jint
+android_eglGetError
+  (JNIEnv *_env, jobject _this) {
+    EGLint _returnValue = (EGLint) 0;
+    _returnValue = eglGetError();
+    return _returnValue;
+}
+
+/* EGLDisplay eglGetDisplay ( EGLNativeDisplayType display_id ) */
+static jobject
+android_eglGetDisplay
+  (JNIEnv *_env, jobject _this, jint display_id) {
+    EGLDisplay _returnValue = (EGLDisplay) 0;
+    _returnValue = eglGetDisplay(
+        (EGLNativeDisplayType)display_id
+    );
+    return toEGLHandle(_env, egldisplayClass, egldisplayConstructor, _returnValue);
+}
+
+/* EGLBoolean eglInitialize ( EGLDisplay dpy, EGLint *major, EGLint *minor ) */
+static jboolean
+android_eglInitialize
+  (JNIEnv *_env, jobject _this, jobject dpy, jintArray major_ref, jint majorOffset, jintArray minor_ref, jint minorOffset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLint *major_base = (EGLint *) 0;
+    jint _majorRemaining;
+    EGLint *major = (EGLint *) 0;
+    EGLint *minor_base = (EGLint *) 0;
+    jint _minorRemaining;
+    EGLint *minor = (EGLint *) 0;
+
+    if (!major_ref) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "major == null";
+        goto exit;
+    }
+    if (majorOffset < 0) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "majorOffset < 0";
+        goto exit;
+    }
+    _majorRemaining = _env->GetArrayLength(major_ref) - majorOffset;
+    if (_majorRemaining < 1) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - majorOffset < 1 < needed";
+        goto exit;
+    }
+    major_base = (EGLint *)
+        _env->GetPrimitiveArrayCritical(major_ref, (jboolean *)0);
+    major = major_base + majorOffset;
+
+    if (!minor_ref) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "minor == null";
+        goto exit;
+    }
+    if (minorOffset < 0) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "minorOffset < 0";
+        goto exit;
+    }
+    _minorRemaining = _env->GetArrayLength(minor_ref) - minorOffset;
+    if (_minorRemaining < 1) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - minorOffset < 1 < needed";
+        goto exit;
+    }
+    minor_base = (EGLint *)
+        _env->GetPrimitiveArrayCritical(minor_ref, (jboolean *)0);
+    minor = minor_base + minorOffset;
+
+    _returnValue = eglInitialize(
+        (EGLDisplay)dpy_native,
+        (EGLint *)major,
+        (EGLint *)minor
+    );
+
+exit:
+    if (minor_base) {
+        _env->ReleasePrimitiveArrayCritical(minor_ref, minor_base,
+            _exception ? JNI_ABORT: 0);
+    }
+    if (major_base) {
+        _env->ReleasePrimitiveArrayCritical(major_ref, major_base,
+            _exception ? JNI_ABORT: 0);
+    }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
+    return _returnValue;
+}
+
+/* EGLBoolean eglTerminate ( EGLDisplay dpy ) */
+static jboolean
+android_eglTerminate
+  (JNIEnv *_env, jobject _this, jobject dpy) {
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+
+    _returnValue = eglTerminate(
+        (EGLDisplay)dpy_native
+    );
+    return _returnValue;
+}
+
+/* const char * eglQueryString ( EGLDisplay dpy, EGLint name ) */
+static jstring
+android_eglQueryString__Landroind_opengl_EGLDisplay_2I
+  (JNIEnv *_env, jobject _this, jobject dpy, jint name) {
+    const char* chars = (const char*) eglQueryString(
+        (EGLDisplay)fromEGLHandle(_env, egldisplayGetHandleID, dpy),
+        (EGLint)name
+    );
+    return _env->NewStringUTF(chars);
+}
+/* EGLBoolean eglGetConfigs ( EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config ) */
+static jboolean
+android_eglGetConfigs
+  (JNIEnv *_env, jobject _this, jobject dpy, jobjectArray configs_ref, jint configsOffset, jint config_size, jintArray num_config_ref, jint num_configOffset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    jint _configsRemaining;
+    EGLConfig *configs = (EGLConfig *) 0;
+    EGLint *num_config_base = (EGLint *) 0;
+    jint _num_configRemaining;
+    EGLint *num_config = (EGLint *) 0;
+
+    if (!configs_ref) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "configs == null";
+        goto exit;
+    }
+    if (configsOffset < 0) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "configsOffset < 0";
+        goto exit;
+    }
+    _configsRemaining = _env->GetArrayLength(configs_ref) - configsOffset;
+    if (_configsRemaining < config_size) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - configsOffset < config_size < needed";
+        goto exit;
+    }
+    configs = new EGLConfig[_configsRemaining];
+
+    if (!num_config_ref) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "num_config == null";
+        goto exit;
+    }
+    if (num_configOffset < 0) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "num_configOffset < 0";
+        goto exit;
+    }
+    _num_configRemaining = _env->GetArrayLength(num_config_ref) - num_configOffset;
+    num_config_base = (EGLint *)
+        _env->GetPrimitiveArrayCritical(num_config_ref, (jboolean *)0);
+    num_config = num_config_base + num_configOffset;
+
+    _returnValue = eglGetConfigs(
+        (EGLDisplay)dpy_native,
+        (EGLConfig *)configs,
+        (EGLint)config_size,
+        (EGLint *)num_config
+    );
+
+exit:
+    if (num_config_base) {
+        _env->ReleasePrimitiveArrayCritical(num_config_ref, num_config_base,
+            _exception ? JNI_ABORT: 0);
+    }
+    if (configs) {
+        for (int i = 0; i < _configsRemaining; i++) {
+            jobject configs_new = toEGLHandle(_env, eglconfigClass, eglconfigConstructor, configs[i]);
+            _env->SetObjectArrayElement(configs_ref, i + configsOffset, configs_new);
+        }
+        delete[] configs;
+    }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
+    return _returnValue;
+}
+
+/* EGLBoolean eglChooseConfig ( EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config ) */
+static jboolean
+android_eglChooseConfig
+  (JNIEnv *_env, jobject _this, jobject dpy, jintArray attrib_list_ref, jint attrib_listOffset, jobjectArray configs_ref, jint configsOffset, jint config_size, jintArray num_config_ref, jint num_configOffset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    bool attrib_list_sentinel = false;
+    EGLint *attrib_list_base = (EGLint *) 0;
+    jint _attrib_listRemaining;
+    EGLint *attrib_list = (EGLint *) 0;
+    jint _configsRemaining;
+    EGLConfig *configs = (EGLConfig *) 0;
+    EGLint *num_config_base = (EGLint *) 0;
+    jint _num_configRemaining;
+    EGLint *num_config = (EGLint *) 0;
+
+    if (!attrib_list_ref) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "attrib_list == null";
+        goto exit;
+    }
+    if (attrib_listOffset < 0) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "attrib_listOffset < 0";
+        goto exit;
+    }
+    _attrib_listRemaining = _env->GetArrayLength(attrib_list_ref) - attrib_listOffset;
+    attrib_list_base = (EGLint *)
+        _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0);
+    attrib_list = attrib_list_base + attrib_listOffset;
+    attrib_list_sentinel = false;
+    for (int i = _attrib_listRemaining - 1; i >= 0; i--)  {
+        if (attrib_list[i] == EGL_NONE){
+            attrib_list_sentinel = true;
+            break;
+        }
+    }
+    if (attrib_list_sentinel == false) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "attrib_list must contain EGL_NONE!";
+        goto exit;
+    }
+
+    if (!configs_ref) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "configs == null";
+        goto exit;
+    }
+    if (configsOffset < 0) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "configsOffset < 0";
+        goto exit;
+    }
+    _configsRemaining = _env->GetArrayLength(configs_ref) - configsOffset;
+    if (_configsRemaining < config_size) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - configsOffset < config_size < needed";
+        goto exit;
+    }
+    configs = new EGLConfig[_configsRemaining];
+
+    if (!num_config_ref) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "num_config == null";
+        goto exit;
+    }
+    if (num_configOffset < 0) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "num_configOffset < 0";
+        goto exit;
+    }
+    _num_configRemaining = _env->GetArrayLength(num_config_ref) - num_configOffset;
+    if (_num_configRemaining < 1) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - num_configOffset < 1 < needed";
+        goto exit;
+    }
+    num_config_base = (EGLint *)
+        _env->GetPrimitiveArrayCritical(num_config_ref, (jboolean *)0);
+    num_config = num_config_base + num_configOffset;
+
+    _returnValue = eglChooseConfig(
+        (EGLDisplay)dpy_native,
+        (EGLint *)attrib_list,
+        (EGLConfig *)configs,
+        (EGLint)config_size,
+        (EGLint *)num_config
+    );
+
+exit:
+    if (num_config_base) {
+        _env->ReleasePrimitiveArrayCritical(num_config_ref, num_config_base,
+            _exception ? JNI_ABORT: 0);
+    }
+    if (attrib_list_base) {
+        _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base,
+            JNI_ABORT);
+    }
+    if (configs) {
+        for (int i = 0; i < _configsRemaining; i++) {
+            jobject configs_new = toEGLHandle(_env, eglconfigClass, eglconfigConstructor, configs[i]);
+            _env->SetObjectArrayElement(configs_ref, i + configsOffset, configs_new);
+        }
+        delete[] configs;
+    }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
+    return _returnValue;
+}
+
+/* EGLBoolean eglGetConfigAttrib ( EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value ) */
+static jboolean
+android_eglGetConfigAttrib
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject config, jint attribute, jintArray value_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLConfig config_native = (EGLConfig) fromEGLHandle(_env, eglconfigGetHandleID, config);
+    EGLint *value_base = (EGLint *) 0;
+    jint _remaining;
+    EGLint *value = (EGLint *) 0;
+
+    if (!value_ref) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "value == null";
+        goto exit;
+    }
+    if (offset < 0) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
+        goto exit;
+    }
+    _remaining = _env->GetArrayLength(value_ref) - offset;
+    if (_remaining < 1) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
+        goto exit;
+    }
+    value_base = (EGLint *)
+        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+    value = value_base + offset;
+
+    _returnValue = eglGetConfigAttrib(
+        (EGLDisplay)dpy_native,
+        (EGLConfig)config_native,
+        (EGLint)attribute,
+        (EGLint *)value
+    );
+
+exit:
+    if (value_base) {
+        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+            _exception ? JNI_ABORT: 0);
+    }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
+    return _returnValue;
+}
+
+/* EGLSurface eglCreateWindowSurface ( EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list ) */
+static jobject
+android_eglCreateWindowSurface
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject config, jobject win, jintArray attrib_list_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType = "";
+    const char * _exceptionMessage = "";
+    EGLSurface _returnValue = (EGLSurface) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLConfig config_native = (EGLConfig) fromEGLHandle(_env, eglconfigGetHandleID, config);
+    int attrib_list_sentinel = 0;
+    EGLint *attrib_list_base = (EGLint *) 0;
+    jint _remaining;
+    EGLint *attrib_list = (EGLint *) 0;
+    android::sp<ANativeWindow> window;
+
+    if (!attrib_list_ref) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "attrib_list == null";
+        goto exit;
+    }
+    if (offset < 0) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
+        goto exit;
+    }
+    if (win == NULL) {
+not_valid_surface:
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "Make sure the SurfaceView or associated SurfaceHolder has a valid Surface";
+        goto exit;
+    }
+
+    window = android::android_Surface_getNativeWindow(_env, win);
+
+    if (window == NULL)
+        goto not_valid_surface;
+
+    _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
+    attrib_list_base = (EGLint *)
+        _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0);
+    attrib_list = attrib_list_base + offset;
+    attrib_list_sentinel = 0;
+    for (int i = _remaining - 1; i >= 0; i--)  {
+        if (*((EGLint*)(attrib_list + i)) == EGL_NONE){
+            attrib_list_sentinel = 1;
+            break;
+        }
+    }
+    if (attrib_list_sentinel == 0) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "attrib_list must contain EGL_NONE!";
+        goto exit;
+    }
+
+    _returnValue = eglCreateWindowSurface(
+        (EGLDisplay)dpy_native,
+        (EGLConfig)config_native,
+        (EGLNativeWindowType)window.get(),
+        (EGLint *)attrib_list
+    );
+
+exit:
+    if (attrib_list_base) {
+        _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base,
+            JNI_ABORT);
+    }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
+    return toEGLHandle(_env, eglsurfaceClass, eglsurfaceConstructor, _returnValue);
+}
+
+/* EGLSurface eglCreateWindowSurface ( EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list ) */
+static jobject
+android_eglCreateWindowSurfaceTexture
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject config, jobject win, jintArray attrib_list_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType = "";
+    const char * _exceptionMessage = "";
+    EGLSurface _returnValue = (EGLSurface) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLConfig config_native = (EGLConfig) fromEGLHandle(_env, eglconfigGetHandleID, config);
+    int attrib_list_sentinel = 0;
+    EGLint *attrib_list_base = (EGLint *) 0;
+    jint _remaining;
+    EGLint *attrib_list = (EGLint *) 0;
+    android::sp<ANativeWindow> window;
+    android::sp<android::SurfaceTexture> surfaceTexture;
+
+    if (!attrib_list_ref) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "attrib_list == null";
+        goto exit;
+    }
+    if (offset < 0) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
+        goto exit;
+    }
+    if (win == NULL) {
+not_valid_surface:
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "Make sure the SurfaceView or associated SurfaceHolder has a valid Surface";
+        goto exit;
+    }
+    surfaceTexture = android::SurfaceTexture_getSurfaceTexture(_env, win);
+    window = new android::SurfaceTextureClient(surfaceTexture);
+
+    if (window == NULL)
+        goto not_valid_surface;
+
+    _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
+    attrib_list_base = (EGLint *)
+        _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0);
+    attrib_list = attrib_list_base + offset;
+    attrib_list_sentinel = 0;
+    for (int i = _remaining - 1; i >= 0; i--)  {
+        if (*((EGLint*)(attrib_list + i)) == EGL_NONE){
+            attrib_list_sentinel = 1;
+            break;
+        }
+    }
+    if (attrib_list_sentinel == 0) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "attrib_list must contain EGL_NONE!";
+        goto exit;
+    }
+
+    _returnValue = eglCreateWindowSurface(
+        (EGLDisplay)dpy_native,
+        (EGLConfig)config_native,
+        (EGLNativeWindowType)window.get(),
+        (EGLint *)attrib_list
+    );
+
+exit:
+    if (attrib_list_base) {
+        _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base,
+            JNI_ABORT);
+    }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
+    return toEGLHandle(_env, eglsurfaceClass, eglsurfaceConstructor, _returnValue);
+}
+/* EGLSurface eglCreatePbufferSurface ( EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list ) */
+static jobject
+android_eglCreatePbufferSurface
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject config, jintArray attrib_list_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
+    EGLSurface _returnValue = (EGLSurface) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLConfig config_native = (EGLConfig) fromEGLHandle(_env, eglconfigGetHandleID, config);
+    bool attrib_list_sentinel = false;
+    EGLint *attrib_list_base = (EGLint *) 0;
+    jint _remaining;
+    EGLint *attrib_list = (EGLint *) 0;
+
+    if (!attrib_list_ref) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "attrib_list == null";
+        goto exit;
+    }
+    if (offset < 0) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
+        goto exit;
+    }
+    _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
+    attrib_list_base = (EGLint *)
+        _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0);
+    attrib_list = attrib_list_base + offset;
+    attrib_list_sentinel = false;
+    for (int i = _remaining - 1; i >= 0; i--)  {
+        if (attrib_list[i] == EGL_NONE){
+            attrib_list_sentinel = true;
+            break;
+        }
+    }
+    if (attrib_list_sentinel == false) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "attrib_list must contain EGL_NONE!";
+        goto exit;
+    }
+
+    _returnValue = eglCreatePbufferSurface(
+        (EGLDisplay)dpy_native,
+        (EGLConfig)config_native,
+        (EGLint *)attrib_list
+    );
+
+exit:
+    if (attrib_list_base) {
+        _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base,
+            JNI_ABORT);
+    }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
+    return toEGLHandle(_env, eglsurfaceClass, eglsurfaceConstructor, _returnValue);
+}
+
+/* EGLSurface eglCreatePixmapSurface ( EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list ) */
+static jobject
+android_eglCreatePixmapSurface
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject config, jint pixmap, jintArray attrib_list_ref, jint offset) {
+    jniThrowException(_env, "java/lang/UnsupportedOperationException",
+        "eglCreatePixmapSurface");
+    return toEGLHandle(_env, eglsurfaceClass, eglsurfaceConstructor, (EGLSurface) 0);
+}
+
+/* EGLBoolean eglDestroySurface ( EGLDisplay dpy, EGLSurface surface ) */
+static jboolean
+android_eglDestroySurface
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject surface) {
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLSurface surface_native = (EGLSurface) fromEGLHandle(_env, eglsurfaceGetHandleID, surface);
+
+    _returnValue = eglDestroySurface(
+        (EGLDisplay)dpy_native,
+        (EGLSurface)surface_native
+    );
+    return _returnValue;
+}
+
+/* EGLBoolean eglQuerySurface ( EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value ) */
+static jboolean
+android_eglQuerySurface
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject surface, jint attribute, jintArray value_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLSurface surface_native = (EGLSurface) fromEGLHandle(_env, eglsurfaceGetHandleID, surface);
+    EGLint *value_base = (EGLint *) 0;
+    jint _remaining;
+    EGLint *value = (EGLint *) 0;
+
+    if (!value_ref) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "value == null";
+        goto exit;
+    }
+    if (offset < 0) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
+        goto exit;
+    }
+    _remaining = _env->GetArrayLength(value_ref) - offset;
+    if (_remaining < 1) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
+        goto exit;
+    }
+    value_base = (EGLint *)
+        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+    value = value_base + offset;
+
+    _returnValue = eglQuerySurface(
+        (EGLDisplay)dpy_native,
+        (EGLSurface)surface_native,
+        (EGLint)attribute,
+        (EGLint *)value
+    );
+
+exit:
+    if (value_base) {
+        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+            _exception ? JNI_ABORT: 0);
+    }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
+    return _returnValue;
+}
+
+/* EGLBoolean eglBindAPI ( EGLenum api ) */
+static jboolean
+android_eglBindAPI
+  (JNIEnv *_env, jobject _this, jint api) {
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    _returnValue = eglBindAPI(
+        (EGLenum)api
+    );
+    return _returnValue;
+}
+
+/* EGLenum eglQueryAPI ( void ) */
+static jint
+android_eglQueryAPI
+  (JNIEnv *_env, jobject _this) {
+    EGLenum _returnValue = (EGLenum) 0;
+    _returnValue = eglQueryAPI();
+    return _returnValue;
+}
+
+/* EGLBoolean eglWaitClient ( void ) */
+static jboolean
+android_eglWaitClient
+  (JNIEnv *_env, jobject _this) {
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    _returnValue = eglWaitClient();
+    return _returnValue;
+}
+
+/* EGLBoolean eglReleaseThread ( void ) */
+static jboolean
+android_eglReleaseThread
+  (JNIEnv *_env, jobject _this) {
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    _returnValue = eglReleaseThread();
+    return _returnValue;
+}
+
+/* EGLSurface eglCreatePbufferFromClientBuffer ( EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list ) */
+static jobject
+android_eglCreatePbufferFromClientBuffer
+  (JNIEnv *_env, jobject _this, jobject dpy, jint buftype, jint buffer, jobject config, jintArray attrib_list_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
+    EGLSurface _returnValue = (EGLSurface) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLConfig config_native = (EGLConfig) fromEGLHandle(_env, eglconfigGetHandleID, config);
+    bool attrib_list_sentinel = false;
+    EGLint *attrib_list_base = (EGLint *) 0;
+    jint _remaining;
+    EGLint *attrib_list = (EGLint *) 0;
+
+    if (!attrib_list_ref) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "attrib_list == null";
+        goto exit;
+    }
+    if (offset < 0) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
+        goto exit;
+    }
+    _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
+    attrib_list_base = (EGLint *)
+        _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0);
+    attrib_list = attrib_list_base + offset;
+    attrib_list_sentinel = false;
+    for (int i = _remaining - 1; i >= 0; i--)  {
+        if (attrib_list[i] == EGL_NONE){
+            attrib_list_sentinel = true;
+            break;
+        }
+    }
+    if (attrib_list_sentinel == false) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "attrib_list must contain EGL_NONE!";
+        goto exit;
+    }
+
+    _returnValue = eglCreatePbufferFromClientBuffer(
+        (EGLDisplay)dpy_native,
+        (EGLenum)buftype,
+        (EGLClientBuffer)buffer,
+        (EGLConfig)config_native,
+        (EGLint *)attrib_list
+    );
+
+exit:
+    if (attrib_list_base) {
+        _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base,
+            JNI_ABORT);
+    }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
+    return toEGLHandle(_env, eglsurfaceClass, eglsurfaceConstructor, _returnValue);
+}
+
+/* EGLBoolean eglSurfaceAttrib ( EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value ) */
+static jboolean
+android_eglSurfaceAttrib
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject surface, jint attribute, jint value) {
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLSurface surface_native = (EGLSurface) fromEGLHandle(_env, eglsurfaceGetHandleID, surface);
+
+    _returnValue = eglSurfaceAttrib(
+        (EGLDisplay)dpy_native,
+        (EGLSurface)surface_native,
+        (EGLint)attribute,
+        (EGLint)value
+    );
+    return _returnValue;
+}
+
+/* EGLBoolean eglBindTexImage ( EGLDisplay dpy, EGLSurface surface, EGLint buffer ) */
+static jboolean
+android_eglBindTexImage
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject surface, jint buffer) {
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLSurface surface_native = (EGLSurface) fromEGLHandle(_env, eglsurfaceGetHandleID, surface);
+
+    _returnValue = eglBindTexImage(
+        (EGLDisplay)dpy_native,
+        (EGLSurface)surface_native,
+        (EGLint)buffer
+    );
+    return _returnValue;
+}
+
+/* EGLBoolean eglReleaseTexImage ( EGLDisplay dpy, EGLSurface surface, EGLint buffer ) */
+static jboolean
+android_eglReleaseTexImage
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject surface, jint buffer) {
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLSurface surface_native = (EGLSurface) fromEGLHandle(_env, eglsurfaceGetHandleID, surface);
+
+    _returnValue = eglReleaseTexImage(
+        (EGLDisplay)dpy_native,
+        (EGLSurface)surface_native,
+        (EGLint)buffer
+    );
+    return _returnValue;
+}
+
+/* EGLBoolean eglSwapInterval ( EGLDisplay dpy, EGLint interval ) */
+static jboolean
+android_eglSwapInterval
+  (JNIEnv *_env, jobject _this, jobject dpy, jint interval) {
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+
+    _returnValue = eglSwapInterval(
+        (EGLDisplay)dpy_native,
+        (EGLint)interval
+    );
+    return _returnValue;
+}
+
+/* EGLContext eglCreateContext ( EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list ) */
+static jobject
+android_eglCreateContext
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject config, jobject share_context, jintArray attrib_list_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
+    EGLContext _returnValue = (EGLContext) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLConfig config_native = (EGLConfig) fromEGLHandle(_env, eglconfigGetHandleID, config);
+    EGLContext share_context_native = (EGLContext) fromEGLHandle(_env, eglcontextGetHandleID, share_context);
+    bool attrib_list_sentinel = false;
+    EGLint *attrib_list_base = (EGLint *) 0;
+    jint _remaining;
+    EGLint *attrib_list = (EGLint *) 0;
+
+    if (!attrib_list_ref) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "attrib_list == null";
+        goto exit;
+    }
+    if (offset < 0) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
+        goto exit;
+    }
+    _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
+    attrib_list_base = (EGLint *)
+        _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0);
+    attrib_list = attrib_list_base + offset;
+    attrib_list_sentinel = false;
+    for (int i = _remaining - 1; i >= 0; i--)  {
+        if (attrib_list[i] == EGL_NONE){
+            attrib_list_sentinel = true;
+            break;
+        }
+    }
+    if (attrib_list_sentinel == false) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "attrib_list must contain EGL_NONE!";
+        goto exit;
+    }
+
+    _returnValue = eglCreateContext(
+        (EGLDisplay)dpy_native,
+        (EGLConfig)config_native,
+        (EGLContext)share_context_native,
+        (EGLint *)attrib_list
+    );
+
+exit:
+    if (attrib_list_base) {
+        _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base,
+            JNI_ABORT);
+    }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
+    return toEGLHandle(_env, eglcontextClass, eglcontextConstructor, _returnValue);
+}
+
+/* EGLBoolean eglDestroyContext ( EGLDisplay dpy, EGLContext ctx ) */
+static jboolean
+android_eglDestroyContext
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject ctx) {
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLContext ctx_native = (EGLContext) fromEGLHandle(_env, eglcontextGetHandleID, ctx);
+
+    _returnValue = eglDestroyContext(
+        (EGLDisplay)dpy_native,
+        (EGLContext)ctx_native
+    );
+    return _returnValue;
+}
+
+/* EGLBoolean eglMakeCurrent ( EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx ) */
+static jboolean
+android_eglMakeCurrent
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject draw, jobject read, jobject ctx) {
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLSurface draw_native = (EGLSurface) fromEGLHandle(_env, eglsurfaceGetHandleID, draw);
+    EGLSurface read_native = (EGLSurface) fromEGLHandle(_env, eglsurfaceGetHandleID, read);
+    EGLContext ctx_native = (EGLContext) fromEGLHandle(_env, eglcontextGetHandleID, ctx);
+
+    _returnValue = eglMakeCurrent(
+        (EGLDisplay)dpy_native,
+        (EGLSurface)draw_native,
+        (EGLSurface)read_native,
+        (EGLContext)ctx_native
+    );
+    return _returnValue;
+}
+
+/* EGLContext eglGetCurrentContext ( void ) */
+static jobject
+android_eglGetCurrentContext
+  (JNIEnv *_env, jobject _this) {
+    EGLContext _returnValue = (EGLContext) 0;
+    _returnValue = eglGetCurrentContext();
+    return toEGLHandle(_env, eglcontextClass, eglcontextConstructor, _returnValue);
+}
+
+/* EGLSurface eglGetCurrentSurface ( EGLint readdraw ) */
+static jobject
+android_eglGetCurrentSurface
+  (JNIEnv *_env, jobject _this, jint readdraw) {
+    EGLSurface _returnValue = (EGLSurface) 0;
+    _returnValue = eglGetCurrentSurface(
+        (EGLint)readdraw
+    );
+    return toEGLHandle(_env, eglsurfaceClass, eglsurfaceConstructor, _returnValue);
+}
+
+/* EGLDisplay eglGetCurrentDisplay ( void ) */
+static jobject
+android_eglGetCurrentDisplay
+  (JNIEnv *_env, jobject _this) {
+    EGLDisplay _returnValue = (EGLDisplay) 0;
+    _returnValue = eglGetCurrentDisplay();
+    return toEGLHandle(_env, egldisplayClass, egldisplayConstructor, _returnValue);
+}
+
+/* EGLBoolean eglQueryContext ( EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value ) */
+static jboolean
+android_eglQueryContext
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject ctx, jint attribute, jintArray value_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLContext ctx_native = (EGLContext) fromEGLHandle(_env, eglcontextGetHandleID, ctx);
+    EGLint *value_base = (EGLint *) 0;
+    jint _remaining;
+    EGLint *value = (EGLint *) 0;
+
+    if (!value_ref) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "value == null";
+        goto exit;
+    }
+    if (offset < 0) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
+        goto exit;
+    }
+    _remaining = _env->GetArrayLength(value_ref) - offset;
+    if (_remaining < 1) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
+        goto exit;
+    }
+    value_base = (EGLint *)
+        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+    value = value_base + offset;
+
+    _returnValue = eglQueryContext(
+        (EGLDisplay)dpy_native,
+        (EGLContext)ctx_native,
+        (EGLint)attribute,
+        (EGLint *)value
+    );
+
+exit:
+    if (value_base) {
+        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+            _exception ? JNI_ABORT: 0);
+    }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
+    return _returnValue;
+}
+
+/* EGLBoolean eglWaitGL ( void ) */
+static jboolean
+android_eglWaitGL
+  (JNIEnv *_env, jobject _this) {
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    _returnValue = eglWaitGL();
+    return _returnValue;
+}
+
+/* EGLBoolean eglWaitNative ( EGLint engine ) */
+static jboolean
+android_eglWaitNative
+  (JNIEnv *_env, jobject _this, jint engine) {
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    _returnValue = eglWaitNative(
+        (EGLint)engine
+    );
+    return _returnValue;
+}
+
+/* EGLBoolean eglSwapBuffers ( EGLDisplay dpy, EGLSurface surface ) */
+static jboolean
+android_eglSwapBuffers
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject surface) {
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLSurface surface_native = (EGLSurface) fromEGLHandle(_env, eglsurfaceGetHandleID, surface);
+
+    _returnValue = eglSwapBuffers(
+        (EGLDisplay)dpy_native,
+        (EGLSurface)surface_native
+    );
+    return _returnValue;
+}
+
+/* EGLBoolean eglCopyBuffers ( EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target ) */
+static jboolean
+android_eglCopyBuffers
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject surface, jint target) {
+    jniThrowException(_env, "java/lang/UnsupportedOperationException",
+        "eglCopyBuffers");
+    return (EGLBoolean) 0;
+}
+
+static const char *classPathName = "android/opengl/EGL14";
+
+static JNINativeMethod methods[] = {
+{"_nativeClassInit", "()V", (void*)nativeClassInit },
+{"eglGetError", "()I", (void *) android_eglGetError },
+{"eglGetDisplay", "(I)Landroid/opengl/EGLDisplay;", (void *) android_eglGetDisplay },
+{"eglInitialize", "(Landroid/opengl/EGLDisplay;[II[II)Z", (void *) android_eglInitialize },
+{"eglTerminate", "(Landroid/opengl/EGLDisplay;)Z", (void *) android_eglTerminate },
+{"eglQueryString", "(Landroid/opengl/EGLDisplay;I)Ljava/lang/String;", (void *) android_eglQueryString__Landroind_opengl_EGLDisplay_2I },
+{"eglGetConfigs", "(Landroid/opengl/EGLDisplay;[Landroid/opengl/EGLConfig;II[II)Z", (void *) android_eglGetConfigs },
+{"eglChooseConfig", "(Landroid/opengl/EGLDisplay;[II[Landroid/opengl/EGLConfig;II[II)Z", (void *) android_eglChooseConfig },
+{"eglGetConfigAttrib", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLConfig;I[II)Z", (void *) android_eglGetConfigAttrib },
+{"_eglCreateWindowSurface", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLConfig;Ljava/lang/Object;[II)Landroid/opengl/EGLSurface;", (void *) android_eglCreateWindowSurface },
+{"_eglCreateWindowSurfaceTexture", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLConfig;Ljava/lang/Object;[II)Landroid/opengl/EGLSurface;", (void *) android_eglCreateWindowSurfaceTexture },
+{"eglCreatePbufferSurface", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLConfig;[II)Landroid/opengl/EGLSurface;", (void *) android_eglCreatePbufferSurface },
+{"eglCreatePixmapSurface", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLConfig;I[II)Landroid/opengl/EGLSurface;", (void *) android_eglCreatePixmapSurface },
+{"eglDestroySurface", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSurface;)Z", (void *) android_eglDestroySurface },
+{"eglQuerySurface", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSurface;I[II)Z", (void *) android_eglQuerySurface },
+{"eglBindAPI", "(I)Z", (void *) android_eglBindAPI },
+{"eglQueryAPI", "()I", (void *) android_eglQueryAPI },
+{"eglWaitClient", "()Z", (void *) android_eglWaitClient },
+{"eglReleaseThread", "()Z", (void *) android_eglReleaseThread },
+{"eglCreatePbufferFromClientBuffer", "(Landroid/opengl/EGLDisplay;IILandroid/opengl/EGLConfig;[II)Landroid/opengl/EGLSurface;", (void *) android_eglCreatePbufferFromClientBuffer },
+{"eglSurfaceAttrib", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSurface;II)Z", (void *) android_eglSurfaceAttrib },
+{"eglBindTexImage", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSurface;I)Z", (void *) android_eglBindTexImage },
+{"eglReleaseTexImage", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSurface;I)Z", (void *) android_eglReleaseTexImage },
+{"eglSwapInterval", "(Landroid/opengl/EGLDisplay;I)Z", (void *) android_eglSwapInterval },
+{"eglCreateContext", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLConfig;Landroid/opengl/EGLContext;[II)Landroid/opengl/EGLContext;", (void *) android_eglCreateContext },
+{"eglDestroyContext", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLContext;)Z", (void *) android_eglDestroyContext },
+{"eglMakeCurrent", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSurface;Landroid/opengl/EGLSurface;Landroid/opengl/EGLContext;)Z", (void *) android_eglMakeCurrent },
+{"eglGetCurrentContext", "()Landroid/opengl/EGLContext;", (void *) android_eglGetCurrentContext },
+{"eglGetCurrentSurface", "(I)Landroid/opengl/EGLSurface;", (void *) android_eglGetCurrentSurface },
+{"eglGetCurrentDisplay", "()Landroid/opengl/EGLDisplay;", (void *) android_eglGetCurrentDisplay },
+{"eglQueryContext", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLContext;I[II)Z", (void *) android_eglQueryContext },
+{"eglWaitGL", "()Z", (void *) android_eglWaitGL },
+{"eglWaitNative", "(I)Z", (void *) android_eglWaitNative },
+{"eglSwapBuffers", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSurface;)Z", (void *) android_eglSwapBuffers },
+{"eglCopyBuffers", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSurface;I)Z", (void *) android_eglCopyBuffers },
+};
+
+int register_android_opengl_jni_EGL14(JNIEnv *_env)
+{
+    int err;
+    err = android::AndroidRuntime::registerNativeMethods(_env, classPathName, methods, NELEM(methods));
+    return err;
+}
diff --git a/core/jni/android_opengl_GLES10.cpp b/core/jni/android_opengl_GLES10.cpp
index 6c29d6c..73696ec 100644
--- a/core/jni/android_opengl_GLES10.cpp
+++ b/core/jni/android_opengl_GLES10.cpp
@@ -404,21 +404,30 @@
 static void
 android_glDeleteTextures__I_3II
   (JNIEnv *_env, jobject _this, jint n, jintArray textures_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *textures_base = (GLuint *) 0;
     jint _remaining;
     GLuint *textures = (GLuint *) 0;
 
     if (!textures_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "textures == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "textures == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(textures_ref) - offset;
     if (_remaining < n) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < n");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < n < needed";
         goto exit;
     }
     textures_base = (GLuint *)
@@ -435,19 +444,27 @@
         _env->ReleasePrimitiveArrayCritical(textures_ref, textures_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDeleteTextures ( GLsizei n, const GLuint *textures ) */
 static void
 android_glDeleteTextures__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject textures_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLuint *textures = (GLuint *) 0;
 
     textures = (GLuint *)getPointer(_env, textures_buf, &_array, &_remaining);
     if (_remaining < n) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < n");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < n < needed";
         goto exit;
     }
     glDeleteTextures(
@@ -459,6 +476,9 @@
     if (_array) {
         releasePointer(_env, _array, textures, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDepthFunc ( GLenum func ) */
@@ -532,13 +552,18 @@
 static void
 android_glDrawElements__IIILjava_nio_Buffer_2
   (JNIEnv *_env, jobject _this, jint mode, jint count, jint type, jobject indices_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLvoid *indices = (GLvoid *) 0;
 
     indices = (GLvoid *)getPointer(_env, indices_buf, &_array, &_remaining);
     if (_remaining < count) {
-        jniThrowException(_env, "java/lang/ArrayIndexOutOfBoundsException", "remaining() < count");
+        _exception = 1;
+        _exceptionType = "java/lang/ArrayIndexOutOfBoundsException";
+        _exceptionMessage = "remaining() < count < needed";
         goto exit;
     }
     glDrawElements(
@@ -552,6 +577,9 @@
     if (_array) {
         releasePointer(_env, _array, indices, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glEnable ( GLenum cap ) */
@@ -600,16 +628,23 @@
 static void
 android_glFogfv__I_3FI
   (JNIEnv *_env, jobject _this, jint pname, jfloatArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -639,7 +674,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfloat *)
@@ -656,12 +693,18 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glFogfv ( GLenum pname, const GLfloat *params ) */
 static void
 android_glFogfv__ILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -693,7 +736,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glFogfv(
@@ -705,6 +750,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glFogx ( GLenum pname, GLfixed param ) */
@@ -721,16 +769,23 @@
 static void
 android_glFogxv__I_3II
   (JNIEnv *_env, jobject _this, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -760,7 +815,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfixed *)
@@ -777,12 +834,18 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glFogxv ( GLenum pname, const GLfixed *params ) */
 static void
 android_glFogxv__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -814,7 +877,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glFogxv(
@@ -826,6 +891,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glFrontFace ( GLenum mode ) */
@@ -870,24 +938,29 @@
 android_glGenTextures__I_3II
   (JNIEnv *_env, jobject _this, jint n, jintArray textures_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *textures_base = (GLuint *) 0;
     jint _remaining;
     GLuint *textures = (GLuint *) 0;
 
     if (!textures_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "textures == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "textures == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(textures_ref) - offset;
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < n < needed";
         goto exit;
     }
     textures_base = (GLuint *)
@@ -904,6 +977,9 @@
         _env->ReleasePrimitiveArrayCritical(textures_ref, textures_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGenTextures ( GLsizei n, GLuint *textures ) */
@@ -911,6 +987,8 @@
 android_glGenTextures__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject textures_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLuint *textures = (GLuint *) 0;
@@ -918,7 +996,8 @@
     textures = (GLuint *)getPointer(_env, textures_buf, &_array, &_remaining);
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < n < needed";
         goto exit;
     }
     glGenTextures(
@@ -930,6 +1009,9 @@
     if (_array) {
         releasePointer(_env, _array, textures, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* GLenum glGetError ( void ) */
@@ -946,18 +1028,22 @@
 android_glGetIntegerv__I_3II
   (JNIEnv *_env, jobject _this, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -1294,7 +1380,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLint *)
@@ -1311,6 +1398,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetIntegerv ( GLenum pname, GLint *params ) */
@@ -1318,6 +1408,8 @@
 android_glGetIntegerv__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -1656,7 +1748,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glGetIntegerv(
@@ -1668,6 +1761,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* const GLubyte * glGetString ( GLenum name ) */
@@ -1699,16 +1795,23 @@
 static void
 android_glLightModelfv__I_3FI
   (JNIEnv *_env, jobject _this, jint pname, jfloatArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -1729,7 +1832,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfloat *)
@@ -1746,12 +1851,18 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLightModelfv ( GLenum pname, const GLfloat *params ) */
 static void
 android_glLightModelfv__ILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -1774,7 +1885,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glLightModelfv(
@@ -1786,6 +1899,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLightModelx ( GLenum pname, GLfixed param ) */
@@ -1802,16 +1918,23 @@
 static void
 android_glLightModelxv__I_3II
   (JNIEnv *_env, jobject _this, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -1832,7 +1955,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfixed *)
@@ -1849,12 +1974,18 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLightModelxv ( GLenum pname, const GLfixed *params ) */
 static void
 android_glLightModelxv__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -1877,7 +2008,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glLightModelxv(
@@ -1889,6 +2022,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLightf ( GLenum light, GLenum pname, GLfloat param ) */
@@ -1906,16 +2042,23 @@
 static void
 android_glLightfv__II_3FI
   (JNIEnv *_env, jobject _this, jint light, jint pname, jfloatArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -1962,7 +2105,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfloat *)
@@ -1980,12 +2125,18 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLightfv ( GLenum light, GLenum pname, const GLfloat *params ) */
 static void
 android_glLightfv__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint light, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -2034,7 +2185,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glLightfv(
@@ -2047,6 +2200,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLightx ( GLenum light, GLenum pname, GLfixed param ) */
@@ -2064,16 +2220,23 @@
 static void
 android_glLightxv__II_3II
   (JNIEnv *_env, jobject _this, jint light, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -2120,7 +2283,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfixed *)
@@ -2138,12 +2303,18 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLightxv ( GLenum light, GLenum pname, const GLfixed *params ) */
 static void
 android_glLightxv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint light, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -2192,7 +2363,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glLightxv(
@@ -2205,6 +2378,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLineWidth ( GLfloat width ) */
@@ -2236,16 +2412,23 @@
 static void
 android_glLoadMatrixf___3FI
   (JNIEnv *_env, jobject _this, jfloatArray m_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *m_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *m = (GLfloat *) 0;
 
     if (!m_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "m == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "m == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(m_ref) - offset;
@@ -2262,6 +2445,9 @@
         _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLoadMatrixf ( const GLfloat *m ) */
@@ -2285,16 +2471,23 @@
 static void
 android_glLoadMatrixx___3II
   (JNIEnv *_env, jobject _this, jintArray m_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *m_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *m = (GLfixed *) 0;
 
     if (!m_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "m == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "m == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(m_ref) - offset;
@@ -2311,6 +2504,9 @@
         _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLoadMatrixx ( const GLfixed *m ) */
@@ -2354,16 +2550,23 @@
 static void
 android_glMaterialfv__II_3FI
   (JNIEnv *_env, jobject _this, jint face, jint pname, jfloatArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -2396,7 +2599,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfloat *)
@@ -2414,12 +2619,18 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glMaterialfv ( GLenum face, GLenum pname, const GLfloat *params ) */
 static void
 android_glMaterialfv__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint face, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -2454,7 +2665,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glMaterialfv(
@@ -2467,6 +2680,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glMaterialx ( GLenum face, GLenum pname, GLfixed param ) */
@@ -2484,16 +2700,23 @@
 static void
 android_glMaterialxv__II_3II
   (JNIEnv *_env, jobject _this, jint face, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -2526,7 +2749,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfixed *)
@@ -2544,12 +2769,18 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glMaterialxv ( GLenum face, GLenum pname, const GLfixed *params ) */
 static void
 android_glMaterialxv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint face, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -2584,7 +2815,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glMaterialxv(
@@ -2597,6 +2830,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glMatrixMode ( GLenum mode ) */
@@ -2612,16 +2848,23 @@
 static void
 android_glMultMatrixf___3FI
   (JNIEnv *_env, jobject _this, jfloatArray m_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *m_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *m = (GLfloat *) 0;
 
     if (!m_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "m == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "m == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(m_ref) - offset;
@@ -2638,6 +2881,9 @@
         _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glMultMatrixf ( const GLfloat *m ) */
@@ -2661,16 +2907,23 @@
 static void
 android_glMultMatrixx___3II
   (JNIEnv *_env, jobject _this, jintArray m_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *m_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *m = (GLfixed *) 0;
 
     if (!m_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "m == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "m == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(m_ref) - offset;
@@ -2687,6 +2940,9 @@
         _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glMultMatrixx ( const GLfixed *m ) */
@@ -2870,7 +3126,6 @@
 static void
 android_glReadPixels__IIIIIILjava_nio_Buffer_2
   (JNIEnv *_env, jobject _this, jint x, jint y, jint width, jint height, jint format, jint type, jobject pixels_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLvoid *pixels = (GLvoid *) 0;
@@ -2886,7 +3141,7 @@
         (GLvoid *)pixels
     );
     if (_array) {
-        releasePointer(_env, _array, pixels, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, pixels, JNI_TRUE);
     }
 }
 
@@ -3046,16 +3301,23 @@
 static void
 android_glTexEnvfv__II_3FI
   (JNIEnv *_env, jobject _this, jint target, jint pname, jfloatArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -3082,7 +3344,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfloat *)
@@ -3100,12 +3364,18 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexEnvfv ( GLenum target, GLenum pname, const GLfloat *params ) */
 static void
 android_glTexEnvfv__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -3134,7 +3404,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glTexEnvfv(
@@ -3147,6 +3419,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexEnvx ( GLenum target, GLenum pname, GLfixed param ) */
@@ -3164,16 +3439,23 @@
 static void
 android_glTexEnvxv__II_3II
   (JNIEnv *_env, jobject _this, jint target, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -3200,7 +3482,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfixed *)
@@ -3218,12 +3502,18 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexEnvxv ( GLenum target, GLenum pname, const GLfixed *params ) */
 static void
 android_glTexEnvxv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -3252,7 +3542,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glTexEnvxv(
@@ -3265,6 +3557,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexImage2D ( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels ) */
diff --git a/core/jni/android_opengl_GLES10Ext.cpp b/core/jni/android_opengl_GLES10Ext.cpp
index 1154cef..16a884a 100644
--- a/core/jni/android_opengl_GLES10Ext.cpp
+++ b/core/jni/android_opengl_GLES10Ext.cpp
@@ -106,6 +106,8 @@
 android_glQueryMatrixxOES___3II_3II
   (JNIEnv *_env, jobject _this, jintArray mantissa_ref, jint mantissaOffset, jintArray exponent_ref, jint exponentOffset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLbitfield _returnValue = -1;
     GLfixed *mantissa_base = (GLfixed *) 0;
     jint _mantissaRemaining;
@@ -116,18 +118,21 @@
 
     if (!mantissa_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "mantissa == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "mantissa == null";
         goto exit;
     }
     if (mantissaOffset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "mantissaOffset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "mantissaOffset < 0";
         goto exit;
     }
     _mantissaRemaining = _env->GetArrayLength(mantissa_ref) - mantissaOffset;
     if (_mantissaRemaining < 16) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - mantissaOffset < 16");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - mantissaOffset < 16 < needed";
         goto exit;
     }
     mantissa_base = (GLfixed *)
@@ -136,18 +141,21 @@
 
     if (!exponent_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "exponent == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "exponent == null";
         goto exit;
     }
     if (exponentOffset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "exponentOffset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "exponentOffset < 0";
         goto exit;
     }
     _exponentRemaining = _env->GetArrayLength(exponent_ref) - exponentOffset;
     if (_exponentRemaining < 16) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - exponentOffset < 16");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - exponentOffset < 16 < needed";
         goto exit;
     }
     exponent_base = (GLint *)
@@ -168,6 +176,9 @@
         _env->ReleasePrimitiveArrayCritical(mantissa_ref, mantissa_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
     return _returnValue;
 }
 
@@ -176,6 +187,8 @@
 android_glQueryMatrixxOES__Ljava_nio_IntBuffer_2Ljava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jobject mantissa_buf, jobject exponent_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _mantissaArray = (jarray) 0;
     jarray _exponentArray = (jarray) 0;
     GLbitfield _returnValue = -1;
@@ -187,13 +200,15 @@
     mantissa = (GLfixed *)getPointer(_env, mantissa_buf, &_mantissaArray, &_mantissaRemaining);
     if (_mantissaRemaining < 16) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 16");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 16 < needed";
         goto exit;
     }
     exponent = (GLint *)getPointer(_env, exponent_buf, &_exponentArray, &_exponentRemaining);
     if (_exponentRemaining < 16) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 16");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 16 < needed";
         goto exit;
     }
     _returnValue = glQueryMatrixxOES(
@@ -208,6 +223,9 @@
     if (_exponentArray) {
         releasePointer(_env, _exponentArray, mantissa, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
     return _returnValue;
 }
 
diff --git a/core/jni/android_opengl_GLES11.cpp b/core/jni/android_opengl_GLES11.cpp
index d038f20..ee7cb12 100644
--- a/core/jni/android_opengl_GLES11.cpp
+++ b/core/jni/android_opengl_GLES11.cpp
@@ -136,6 +136,9 @@
 static void
 android_glBufferData__IILjava_nio_Buffer_2I
   (JNIEnv *_env, jobject _this, jint target, jint size, jobject data_buf, jint usage) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLvoid *data = (GLvoid *) 0;
@@ -143,7 +146,9 @@
     if (data_buf) {
         data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining);
         if (_remaining < size) {
-            jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < size");
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "remaining() < size < needed";
             goto exit;
         }
     }
@@ -158,19 +163,27 @@
     if (_array) {
         releasePointer(_env, _array, data, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glBufferSubData ( GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data ) */
 static void
 android_glBufferSubData__IIILjava_nio_Buffer_2
   (JNIEnv *_env, jobject _this, jint target, jint offset, jint size, jobject data_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLvoid *data = (GLvoid *) 0;
 
     data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining);
     if (_remaining < size) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < size");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < size < needed";
         goto exit;
     }
     glBufferSubData(
@@ -184,22 +197,32 @@
     if (_array) {
         releasePointer(_env, _array, data, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glClipPlanef ( GLenum plane, const GLfloat *equation ) */
 static void
 android_glClipPlanef__I_3FI
   (JNIEnv *_env, jobject _this, jint plane, jfloatArray equation_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *equation_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *equation = (GLfloat *) 0;
 
     if (!equation_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "equation == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "equation == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(equation_ref) - offset;
@@ -217,12 +240,18 @@
         _env->ReleasePrimitiveArrayCritical(equation_ref, equation_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glClipPlanef ( GLenum plane, const GLfloat *equation ) */
 static void
 android_glClipPlanef__ILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint plane, jobject equation_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *equation = (GLfloat *) 0;
@@ -235,22 +264,32 @@
     if (_array) {
         releasePointer(_env, _array, equation, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glClipPlanex ( GLenum plane, const GLfixed *equation ) */
 static void
 android_glClipPlanex__I_3II
   (JNIEnv *_env, jobject _this, jint plane, jintArray equation_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *equation_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *equation = (GLfixed *) 0;
 
     if (!equation_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "equation == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "equation == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(equation_ref) - offset;
@@ -268,12 +307,18 @@
         _env->ReleasePrimitiveArrayCritical(equation_ref, equation_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glClipPlanex ( GLenum plane, const GLfixed *equation ) */
 static void
 android_glClipPlanex__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint plane, jobject equation_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *equation = (GLfixed *) 0;
@@ -286,6 +331,9 @@
     if (_array) {
         releasePointer(_env, _array, equation, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glColor4ub ( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha ) */
@@ -316,21 +364,30 @@
 static void
 android_glDeleteBuffers__I_3II
   (JNIEnv *_env, jobject _this, jint n, jintArray buffers_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *buffers_base = (GLuint *) 0;
     jint _remaining;
     GLuint *buffers = (GLuint *) 0;
 
     if (!buffers_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "buffers == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "buffers == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(buffers_ref) - offset;
     if (_remaining < n) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < n");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < n < needed";
         goto exit;
     }
     buffers_base = (GLuint *)
@@ -347,19 +404,27 @@
         _env->ReleasePrimitiveArrayCritical(buffers_ref, buffers_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDeleteBuffers ( GLsizei n, const GLuint *buffers ) */
 static void
 android_glDeleteBuffers__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject buffers_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLuint *buffers = (GLuint *) 0;
 
     buffers = (GLuint *)getPointer(_env, buffers_buf, &_array, &_remaining);
     if (_remaining < n) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < n");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < n < needed";
         goto exit;
     }
     glDeleteBuffers(
@@ -371,18 +436,27 @@
     if (_array) {
         releasePointer(_env, _array, buffers, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDrawElements ( GLenum mode, GLsizei count, GLenum type, GLint offset ) */
 static void
 android_glDrawElements__IIII
   (JNIEnv *_env, jobject _this, jint mode, jint count, jint type, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     glDrawElements(
         (GLenum)mode,
         (GLsizei)count,
         (GLenum)type,
         (const GLvoid *)offset
     );
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGenBuffers ( GLsizei n, GLuint *buffers ) */
@@ -390,24 +464,29 @@
 android_glGenBuffers__I_3II
   (JNIEnv *_env, jobject _this, jint n, jintArray buffers_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *buffers_base = (GLuint *) 0;
     jint _remaining;
     GLuint *buffers = (GLuint *) 0;
 
     if (!buffers_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "buffers == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "buffers == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(buffers_ref) - offset;
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < n < needed";
         goto exit;
     }
     buffers_base = (GLuint *)
@@ -424,6 +503,9 @@
         _env->ReleasePrimitiveArrayCritical(buffers_ref, buffers_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGenBuffers ( GLsizei n, GLuint *buffers ) */
@@ -431,6 +513,8 @@
 android_glGenBuffers__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject buffers_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLuint *buffers = (GLuint *) 0;
@@ -438,7 +522,8 @@
     buffers = (GLuint *)getPointer(_env, buffers_buf, &_array, &_remaining);
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < n < needed";
         goto exit;
     }
     glGenBuffers(
@@ -450,6 +535,9 @@
     if (_array) {
         releasePointer(_env, _array, buffers, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetBooleanv ( GLenum pname, GLboolean *params ) */
@@ -457,18 +545,22 @@
 android_glGetBooleanv__I_3ZI
   (JNIEnv *_env, jobject _this, jint pname, jbooleanArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLboolean *params_base = (GLboolean *) 0;
     jint _remaining;
     GLboolean *params = (GLboolean *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -486,13 +578,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetBooleanv ( GLenum pname, GLboolean *params ) */
 static void
 android_glGetBooleanv__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLboolean *params = (GLboolean *) 0;
@@ -503,7 +597,7 @@
         (GLboolean *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -512,24 +606,29 @@
 android_glGetBufferParameteriv__II_3II
   (JNIEnv *_env, jobject _this, jint target, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLint *)
@@ -547,6 +646,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetBufferParameteriv ( GLenum target, GLenum pname, GLint *params ) */
@@ -554,6 +656,8 @@
 android_glGetBufferParameteriv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -561,7 +665,8 @@
     params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glGetBufferParameteriv(
@@ -574,6 +679,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetClipPlanef ( GLenum pname, GLfloat *eqn ) */
@@ -581,18 +689,22 @@
 android_glGetClipPlanef__I_3FI
   (JNIEnv *_env, jobject _this, jint pname, jfloatArray eqn_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *eqn_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *eqn = (GLfloat *) 0;
 
     if (!eqn_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "eqn == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "eqn == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(eqn_ref) - offset;
@@ -610,13 +722,15 @@
         _env->ReleasePrimitiveArrayCritical(eqn_ref, eqn_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetClipPlanef ( GLenum pname, GLfloat *eqn ) */
 static void
 android_glGetClipPlanef__ILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject eqn_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *eqn = (GLfloat *) 0;
@@ -627,7 +741,7 @@
         (GLfloat *)eqn
     );
     if (_array) {
-        releasePointer(_env, _array, eqn, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, eqn, JNI_TRUE);
     }
 }
 
@@ -636,18 +750,22 @@
 android_glGetClipPlanex__I_3II
   (JNIEnv *_env, jobject _this, jint pname, jintArray eqn_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *eqn_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *eqn = (GLfixed *) 0;
 
     if (!eqn_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "eqn == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "eqn == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(eqn_ref) - offset;
@@ -665,13 +783,15 @@
         _env->ReleasePrimitiveArrayCritical(eqn_ref, eqn_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetClipPlanex ( GLenum pname, GLfixed *eqn ) */
 static void
 android_glGetClipPlanex__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject eqn_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *eqn = (GLfixed *) 0;
@@ -682,7 +802,7 @@
         (GLfixed *)eqn
     );
     if (_array) {
-        releasePointer(_env, _array, eqn, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, eqn, JNI_TRUE);
     }
 }
 
@@ -691,18 +811,22 @@
 android_glGetFixedv__I_3II
   (JNIEnv *_env, jobject _this, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -720,13 +844,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetFixedv ( GLenum pname, GLfixed *params ) */
 static void
 android_glGetFixedv__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -737,7 +863,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -746,18 +872,22 @@
 android_glGetFloatv__I_3FI
   (JNIEnv *_env, jobject _this, jint pname, jfloatArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -775,13 +905,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetFloatv ( GLenum pname, GLfloat *params ) */
 static void
 android_glGetFloatv__ILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -792,7 +924,7 @@
         (GLfloat *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -801,18 +933,22 @@
 android_glGetLightfv__II_3FI
   (JNIEnv *_env, jobject _this, jint light, jint pname, jfloatArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -860,7 +996,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfloat *)
@@ -878,6 +1015,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetLightfv ( GLenum light, GLenum pname, GLfloat *params ) */
@@ -885,6 +1025,8 @@
 android_glGetLightfv__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint light, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -934,7 +1076,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glGetLightfv(
@@ -947,6 +1090,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetLightxv ( GLenum light, GLenum pname, GLfixed *params ) */
@@ -954,18 +1100,22 @@
 android_glGetLightxv__II_3II
   (JNIEnv *_env, jobject _this, jint light, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -1013,7 +1163,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfixed *)
@@ -1031,6 +1182,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetLightxv ( GLenum light, GLenum pname, GLfixed *params ) */
@@ -1038,6 +1192,8 @@
 android_glGetLightxv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint light, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -1087,7 +1243,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glGetLightxv(
@@ -1100,6 +1257,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetMaterialfv ( GLenum face, GLenum pname, GLfloat *params ) */
@@ -1107,18 +1267,22 @@
 android_glGetMaterialfv__II_3FI
   (JNIEnv *_env, jobject _this, jint face, jint pname, jfloatArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -1152,7 +1316,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfloat *)
@@ -1170,6 +1335,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetMaterialfv ( GLenum face, GLenum pname, GLfloat *params ) */
@@ -1177,6 +1345,8 @@
 android_glGetMaterialfv__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint face, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -1212,7 +1382,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glGetMaterialfv(
@@ -1225,6 +1396,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetMaterialxv ( GLenum face, GLenum pname, GLfixed *params ) */
@@ -1232,18 +1406,22 @@
 android_glGetMaterialxv__II_3II
   (JNIEnv *_env, jobject _this, jint face, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -1277,7 +1455,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfixed *)
@@ -1295,6 +1474,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetMaterialxv ( GLenum face, GLenum pname, GLfixed *params ) */
@@ -1302,6 +1484,8 @@
 android_glGetMaterialxv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint face, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -1337,7 +1521,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glGetMaterialxv(
@@ -1350,6 +1535,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexEnvfv ( GLenum env, GLenum pname, GLfloat *params ) */
@@ -1357,18 +1545,22 @@
 android_glGetTexEnvfv__II_3FI
   (JNIEnv *_env, jobject _this, jint env, jint pname, jfloatArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -1396,7 +1588,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfloat *)
@@ -1414,6 +1607,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexEnvfv ( GLenum env, GLenum pname, GLfloat *params ) */
@@ -1421,6 +1617,8 @@
 android_glGetTexEnvfv__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint env, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -1450,7 +1648,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glGetTexEnvfv(
@@ -1463,6 +1662,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexEnviv ( GLenum env, GLenum pname, GLint *params ) */
@@ -1470,18 +1672,22 @@
 android_glGetTexEnviv__II_3II
   (JNIEnv *_env, jobject _this, jint env, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -1509,7 +1715,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLint *)
@@ -1527,6 +1734,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexEnviv ( GLenum env, GLenum pname, GLint *params ) */
@@ -1534,6 +1744,8 @@
 android_glGetTexEnviv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint env, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -1563,7 +1775,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glGetTexEnviv(
@@ -1576,6 +1789,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexEnvxv ( GLenum env, GLenum pname, GLfixed *params ) */
@@ -1583,18 +1799,22 @@
 android_glGetTexEnvxv__II_3II
   (JNIEnv *_env, jobject _this, jint env, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -1622,7 +1842,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfixed *)
@@ -1640,6 +1861,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexEnvxv ( GLenum env, GLenum pname, GLfixed *params ) */
@@ -1647,6 +1871,8 @@
 android_glGetTexEnvxv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint env, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -1676,7 +1902,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glGetTexEnvxv(
@@ -1689,6 +1916,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexParameterfv ( GLenum target, GLenum pname, GLfloat *params ) */
@@ -1696,24 +1926,29 @@
 android_glGetTexParameterfv__II_3FI
   (JNIEnv *_env, jobject _this, jint target, jint pname, jfloatArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLfloat *)
@@ -1731,6 +1966,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexParameterfv ( GLenum target, GLenum pname, GLfloat *params ) */
@@ -1738,6 +1976,8 @@
 android_glGetTexParameterfv__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -1745,7 +1985,8 @@
     params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glGetTexParameterfv(
@@ -1758,6 +1999,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexParameteriv ( GLenum target, GLenum pname, GLint *params ) */
@@ -1765,24 +2009,29 @@
 android_glGetTexParameteriv__II_3II
   (JNIEnv *_env, jobject _this, jint target, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLint *)
@@ -1800,6 +2049,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexParameteriv ( GLenum target, GLenum pname, GLint *params ) */
@@ -1807,6 +2059,8 @@
 android_glGetTexParameteriv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -1814,7 +2068,8 @@
     params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glGetTexParameteriv(
@@ -1827,6 +2082,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexParameterxv ( GLenum target, GLenum pname, GLfixed *params ) */
@@ -1834,24 +2092,29 @@
 android_glGetTexParameterxv__II_3II
   (JNIEnv *_env, jobject _this, jint target, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLfixed *)
@@ -1869,6 +2132,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexParameterxv ( GLenum target, GLenum pname, GLfixed *params ) */
@@ -1876,6 +2142,8 @@
 android_glGetTexParameterxv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -1883,7 +2151,8 @@
     params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glGetTexParameterxv(
@@ -1896,6 +2165,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* GLboolean glIsBuffer ( GLuint buffer ) */
@@ -1956,21 +2228,30 @@
 static void
 android_glPointParameterfv__I_3FI
   (JNIEnv *_env, jobject _this, jint pname, jfloatArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLfloat *)
@@ -1987,19 +2268,27 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glPointParameterfv ( GLenum pname, const GLfloat *params ) */
 static void
 android_glPointParameterfv__ILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glPointParameterfv(
@@ -2011,6 +2300,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glPointParameterx ( GLenum pname, GLfixed param ) */
@@ -2027,21 +2319,30 @@
 static void
 android_glPointParameterxv__I_3II
   (JNIEnv *_env, jobject _this, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLfixed *)
@@ -2058,19 +2359,27 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glPointParameterxv ( GLenum pname, const GLfixed *params ) */
 static void
 android_glPointParameterxv__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glPointParameterxv(
@@ -2082,6 +2391,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glPointSizePointerOES ( GLenum type, GLsizei stride, const GLvoid *pointer ) */
@@ -2133,16 +2445,23 @@
 static void
 android_glTexEnviv__II_3II
   (JNIEnv *_env, jobject _this, jint target, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -2169,7 +2488,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLint *)
@@ -2187,12 +2508,18 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexEnviv ( GLenum target, GLenum pname, const GLint *params ) */
 static void
 android_glTexEnviv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -2221,7 +2548,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glTexEnviv(
@@ -2234,27 +2563,39 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexParameterfv ( GLenum target, GLenum pname, const GLfloat *params ) */
 static void
 android_glTexParameterfv__II_3FI
   (JNIEnv *_env, jobject _this, jint target, jint pname, jfloatArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLfloat *)
@@ -2272,19 +2613,27 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexParameterfv ( GLenum target, GLenum pname, const GLfloat *params ) */
 static void
 android_glTexParameterfv__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glTexParameterfv(
@@ -2297,6 +2646,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexParameteri ( GLenum target, GLenum pname, GLint param ) */
@@ -2314,21 +2666,30 @@
 static void
 android_glTexParameteriv__II_3II
   (JNIEnv *_env, jobject _this, jint target, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLint *)
@@ -2346,19 +2707,27 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexParameteriv ( GLenum target, GLenum pname, const GLint *params ) */
 static void
 android_glTexParameteriv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glTexParameteriv(
@@ -2371,27 +2740,39 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexParameterxv ( GLenum target, GLenum pname, const GLfixed *params ) */
 static void
 android_glTexParameterxv__II_3II
   (JNIEnv *_env, jobject _this, jint target, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLfixed *)
@@ -2409,19 +2790,27 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexParameterxv ( GLenum target, GLenum pname, const GLfixed *params ) */
 static void
 android_glTexParameterxv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glTexParameterxv(
@@ -2434,6 +2823,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glVertexPointer ( GLint size, GLenum type, GLsizei stride, GLint offset ) */
diff --git a/core/jni/android_opengl_GLES11Ext.cpp b/core/jni/android_opengl_GLES11Ext.cpp
index d6dc0fe..a05f809 100644
--- a/core/jni/android_opengl_GLES11Ext.cpp
+++ b/core/jni/android_opengl_GLES11Ext.cpp
@@ -197,21 +197,30 @@
 static void
 android_glDrawTexsvOES___3SI
   (JNIEnv *_env, jobject _this, jshortArray coords_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLshort *coords_base = (GLshort *) 0;
     jint _remaining;
     GLshort *coords = (GLshort *) 0;
 
     if (!coords_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "coords == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "coords == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(coords_ref) - offset;
     if (_remaining < 5) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 5");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 5 < needed";
         goto exit;
     }
     coords_base = (GLshort *)
@@ -227,19 +236,27 @@
         _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDrawTexsvOES ( const GLshort *coords ) */
 static void
 android_glDrawTexsvOES__Ljava_nio_ShortBuffer_2
   (JNIEnv *_env, jobject _this, jobject coords_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLshort *coords = (GLshort *) 0;
 
     coords = (GLshort *)getPointer(_env, coords_buf, &_array, &_remaining);
     if (_remaining < 5) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 5");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 5 < needed";
         goto exit;
     }
     glDrawTexsvOES(
@@ -250,27 +267,39 @@
     if (_array) {
         releasePointer(_env, _array, coords, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDrawTexivOES ( const GLint *coords ) */
 static void
 android_glDrawTexivOES___3II
   (JNIEnv *_env, jobject _this, jintArray coords_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *coords_base = (GLint *) 0;
     jint _remaining;
     GLint *coords = (GLint *) 0;
 
     if (!coords_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "coords == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "coords == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(coords_ref) - offset;
     if (_remaining < 5) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 5");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 5 < needed";
         goto exit;
     }
     coords_base = (GLint *)
@@ -286,19 +315,27 @@
         _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDrawTexivOES ( const GLint *coords ) */
 static void
 android_glDrawTexivOES__Ljava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jobject coords_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *coords = (GLint *) 0;
 
     coords = (GLint *)getPointer(_env, coords_buf, &_array, &_remaining);
     if (_remaining < 5) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 5");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 5 < needed";
         goto exit;
     }
     glDrawTexivOES(
@@ -309,27 +346,39 @@
     if (_array) {
         releasePointer(_env, _array, coords, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDrawTexxvOES ( const GLfixed *coords ) */
 static void
 android_glDrawTexxvOES___3II
   (JNIEnv *_env, jobject _this, jintArray coords_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *coords_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *coords = (GLfixed *) 0;
 
     if (!coords_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "coords == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "coords == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(coords_ref) - offset;
     if (_remaining < 5) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 5");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 5 < needed";
         goto exit;
     }
     coords_base = (GLfixed *)
@@ -345,19 +394,27 @@
         _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDrawTexxvOES ( const GLfixed *coords ) */
 static void
 android_glDrawTexxvOES__Ljava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jobject coords_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *coords = (GLfixed *) 0;
 
     coords = (GLfixed *)getPointer(_env, coords_buf, &_array, &_remaining);
     if (_remaining < 5) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 5");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 5 < needed";
         goto exit;
     }
     glDrawTexxvOES(
@@ -368,6 +425,9 @@
     if (_array) {
         releasePointer(_env, _array, coords, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDrawTexfOES ( GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height ) */
@@ -387,21 +447,30 @@
 static void
 android_glDrawTexfvOES___3FI
   (JNIEnv *_env, jobject _this, jfloatArray coords_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *coords_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *coords = (GLfloat *) 0;
 
     if (!coords_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "coords == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "coords == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(coords_ref) - offset;
     if (_remaining < 5) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 5");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 5 < needed";
         goto exit;
     }
     coords_base = (GLfloat *)
@@ -417,19 +486,27 @@
         _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDrawTexfvOES ( const GLfloat *coords ) */
 static void
 android_glDrawTexfvOES__Ljava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jobject coords_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *coords = (GLfloat *) 0;
 
     coords = (GLfloat *)getPointer(_env, coords_buf, &_array, &_remaining);
     if (_remaining < 5) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 5");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 5 < needed";
         goto exit;
     }
     glDrawTexfvOES(
@@ -440,13 +517,15 @@
     if (_array) {
         releasePointer(_env, _array, coords, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glEGLImageTargetTexture2DOES ( GLenum target, GLeglImageOES image ) */
 static void
 android_glEGLImageTargetTexture2DOES__ILjava_nio_Buffer_2
   (JNIEnv *_env, jobject _this, jint target, jobject image_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLeglImageOES image = (GLeglImageOES) 0;
@@ -457,7 +536,7 @@
         (GLeglImageOES)image
     );
     if (_array) {
-        releasePointer(_env, _array, image, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, image, JNI_TRUE);
     }
 }
 
@@ -465,7 +544,6 @@
 static void
 android_glEGLImageTargetRenderbufferStorageOES__ILjava_nio_Buffer_2
   (JNIEnv *_env, jobject _this, jint target, jobject image_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLeglImageOES image = (GLeglImageOES) 0;
@@ -476,7 +554,7 @@
         (GLeglImageOES)image
     );
     if (_array) {
-        releasePointer(_env, _array, image, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, image, JNI_TRUE);
     }
 }
 
@@ -515,16 +593,23 @@
 static void
 android_glClipPlanexOES__I_3II
   (JNIEnv *_env, jobject _this, jint plane, jintArray equation_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *equation_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *equation = (GLfixed *) 0;
 
     if (!equation_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "equation == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "equation == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(equation_ref) - offset;
@@ -542,6 +627,9 @@
         _env->ReleasePrimitiveArrayCritical(equation_ref, equation_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glClipPlanexOES ( GLenum plane, const GLfixed *equation ) */
@@ -598,16 +686,23 @@
 static void
 android_glFogxvOES__I_3II
   (JNIEnv *_env, jobject _this, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -625,6 +720,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glFogxvOES ( GLenum pname, const GLfixed *params ) */
@@ -664,24 +762,29 @@
 android_glGetClipPlanexOES__I_3II
   (JNIEnv *_env, jobject _this, jint pname, jintArray eqn_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *eqn_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *eqn = (GLfixed *) 0;
 
     if (!eqn_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "eqn == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "eqn == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(eqn_ref) - offset;
     if (_remaining < 4) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 4");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 4 < needed";
         goto exit;
     }
     eqn_base = (GLfixed *)
@@ -698,6 +801,9 @@
         _env->ReleasePrimitiveArrayCritical(eqn_ref, eqn_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetClipPlanexOES ( GLenum pname, GLfixed *eqn ) */
@@ -705,6 +811,8 @@
 android_glGetClipPlanexOES__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject eqn_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *eqn = (GLfixed *) 0;
@@ -712,7 +820,8 @@
     eqn = (GLfixed *)getPointer(_env, eqn_buf, &_array, &_remaining);
     if (_remaining < 4) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 4");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 4 < needed";
         goto exit;
     }
     glGetClipPlanexOES(
@@ -724,6 +833,9 @@
     if (_array) {
         releasePointer(_env, _array, eqn, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetFixedvOES ( GLenum pname, GLfixed *params ) */
@@ -731,18 +843,22 @@
 android_glGetFixedvOES__I_3II
   (JNIEnv *_env, jobject _this, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -760,13 +876,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetFixedvOES ( GLenum pname, GLfixed *params ) */
 static void
 android_glGetFixedvOES__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -777,7 +895,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -786,18 +904,22 @@
 android_glGetLightxvOES__II_3II
   (JNIEnv *_env, jobject _this, jint light, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -816,13 +938,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetLightxvOES ( GLenum light, GLenum pname, GLfixed *params ) */
 static void
 android_glGetLightxvOES__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint light, jint pname, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -834,7 +958,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -843,18 +967,22 @@
 android_glGetMaterialxvOES__II_3II
   (JNIEnv *_env, jobject _this, jint face, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -873,13 +1001,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetMaterialxvOES ( GLenum face, GLenum pname, GLfixed *params ) */
 static void
 android_glGetMaterialxvOES__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint face, jint pname, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -891,7 +1021,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -900,18 +1030,22 @@
 android_glGetTexEnvxvOES__II_3II
   (JNIEnv *_env, jobject _this, jint env, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -930,13 +1064,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexEnvxvOES ( GLenum env, GLenum pname, GLfixed *params ) */
 static void
 android_glGetTexEnvxvOES__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint env, jint pname, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -948,7 +1084,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -957,18 +1093,22 @@
 android_glGetTexParameterxvOES__II_3II
   (JNIEnv *_env, jobject _this, jint target, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -987,13 +1127,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexParameterxvOES ( GLenum target, GLenum pname, GLfixed *params ) */
 static void
 android_glGetTexParameterxvOES__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -1005,7 +1147,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -1023,16 +1165,23 @@
 static void
 android_glLightModelxvOES__I_3II
   (JNIEnv *_env, jobject _this, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -1050,6 +1199,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLightModelxvOES ( GLenum pname, const GLfixed *params ) */
@@ -1085,16 +1237,23 @@
 static void
 android_glLightxvOES__II_3II
   (JNIEnv *_env, jobject _this, jint light, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -1113,6 +1272,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLightxvOES ( GLenum light, GLenum pname, const GLfixed *params ) */
@@ -1147,16 +1309,23 @@
 static void
 android_glLoadMatrixxOES___3II
   (JNIEnv *_env, jobject _this, jintArray m_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *m_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *m = (GLfixed *) 0;
 
     if (!m_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "m == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "m == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(m_ref) - offset;
@@ -1173,6 +1342,9 @@
         _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLoadMatrixxOES ( const GLfixed *m ) */
@@ -1207,16 +1379,23 @@
 static void
 android_glMaterialxvOES__II_3II
   (JNIEnv *_env, jobject _this, jint face, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -1235,6 +1414,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glMaterialxvOES ( GLenum face, GLenum pname, const GLfixed *params ) */
@@ -1260,16 +1442,23 @@
 static void
 android_glMultMatrixxOES___3II
   (JNIEnv *_env, jobject _this, jintArray m_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *m_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *m = (GLfixed *) 0;
 
     if (!m_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "m == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "m == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(m_ref) - offset;
@@ -1286,6 +1475,9 @@
         _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glMultMatrixxOES ( const GLfixed *m ) */
@@ -1357,16 +1549,23 @@
 static void
 android_glPointParameterxvOES__I_3II
   (JNIEnv *_env, jobject _this, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -1384,6 +1583,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glPointParameterxvOES ( GLenum pname, const GLfixed *params ) */
@@ -1471,16 +1673,23 @@
 static void
 android_glTexEnvxvOES__II_3II
   (JNIEnv *_env, jobject _this, jint target, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -1499,6 +1708,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexEnvxvOES ( GLenum target, GLenum pname, const GLfixed *params ) */
@@ -1535,16 +1747,23 @@
 static void
 android_glTexParameterxvOES__II_3II
   (JNIEnv *_env, jobject _this, jint target, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -1563,6 +1782,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexParameterxvOES ( GLenum target, GLenum pname, const GLfixed *params ) */
@@ -1620,21 +1842,30 @@
 static void
 android_glDeleteRenderbuffersOES__I_3II
   (JNIEnv *_env, jobject _this, jint n, jintArray renderbuffers_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *renderbuffers_base = (GLuint *) 0;
     jint _remaining;
     GLuint *renderbuffers = (GLuint *) 0;
 
     if (!renderbuffers_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "renderbuffers == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "renderbuffers == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(renderbuffers_ref) - offset;
     if (_remaining < n) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < n");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < n < needed";
         goto exit;
     }
     renderbuffers_base = (GLuint *)
@@ -1651,19 +1882,27 @@
         _env->ReleasePrimitiveArrayCritical(renderbuffers_ref, renderbuffers_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDeleteRenderbuffersOES ( GLsizei n, const GLuint *renderbuffers ) */
 static void
 android_glDeleteRenderbuffersOES__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject renderbuffers_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLuint *renderbuffers = (GLuint *) 0;
 
     renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, &_array, &_remaining);
     if (_remaining < n) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < n");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < n < needed";
         goto exit;
     }
     glDeleteRenderbuffersOES(
@@ -1675,6 +1914,9 @@
     if (_array) {
         releasePointer(_env, _array, renderbuffers, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGenRenderbuffersOES ( GLsizei n, GLuint *renderbuffers ) */
@@ -1682,24 +1924,29 @@
 android_glGenRenderbuffersOES__I_3II
   (JNIEnv *_env, jobject _this, jint n, jintArray renderbuffers_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *renderbuffers_base = (GLuint *) 0;
     jint _remaining;
     GLuint *renderbuffers = (GLuint *) 0;
 
     if (!renderbuffers_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "renderbuffers == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "renderbuffers == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(renderbuffers_ref) - offset;
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < n < needed";
         goto exit;
     }
     renderbuffers_base = (GLuint *)
@@ -1716,6 +1963,9 @@
         _env->ReleasePrimitiveArrayCritical(renderbuffers_ref, renderbuffers_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGenRenderbuffersOES ( GLsizei n, GLuint *renderbuffers ) */
@@ -1723,6 +1973,8 @@
 android_glGenRenderbuffersOES__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject renderbuffers_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLuint *renderbuffers = (GLuint *) 0;
@@ -1730,7 +1982,8 @@
     renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, &_array, &_remaining);
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < n < needed";
         goto exit;
     }
     glGenRenderbuffersOES(
@@ -1742,6 +1995,9 @@
     if (_array) {
         releasePointer(_env, _array, renderbuffers, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glRenderbufferStorageOES ( GLenum target, GLenum internalformat, GLsizei width, GLsizei height ) */
@@ -1761,24 +2017,29 @@
 android_glGetRenderbufferParameterivOES__II_3II
   (JNIEnv *_env, jobject _this, jint target, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLint *)
@@ -1796,6 +2057,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetRenderbufferParameterivOES ( GLenum target, GLenum pname, GLint *params ) */
@@ -1803,6 +2067,8 @@
 android_glGetRenderbufferParameterivOES__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -1810,7 +2076,8 @@
     params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glGetRenderbufferParameterivOES(
@@ -1823,6 +2090,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* GLboolean glIsFramebufferOES ( GLuint framebuffer ) */
@@ -1850,21 +2120,30 @@
 static void
 android_glDeleteFramebuffersOES__I_3II
   (JNIEnv *_env, jobject _this, jint n, jintArray framebuffers_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *framebuffers_base = (GLuint *) 0;
     jint _remaining;
     GLuint *framebuffers = (GLuint *) 0;
 
     if (!framebuffers_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "framebuffers == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "framebuffers == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(framebuffers_ref) - offset;
     if (_remaining < n) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < n");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < n < needed";
         goto exit;
     }
     framebuffers_base = (GLuint *)
@@ -1881,19 +2160,27 @@
         _env->ReleasePrimitiveArrayCritical(framebuffers_ref, framebuffers_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDeleteFramebuffersOES ( GLsizei n, const GLuint *framebuffers ) */
 static void
 android_glDeleteFramebuffersOES__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject framebuffers_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLuint *framebuffers = (GLuint *) 0;
 
     framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, &_array, &_remaining);
     if (_remaining < n) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < n");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < n < needed";
         goto exit;
     }
     glDeleteFramebuffersOES(
@@ -1905,6 +2192,9 @@
     if (_array) {
         releasePointer(_env, _array, framebuffers, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGenFramebuffersOES ( GLsizei n, GLuint *framebuffers ) */
@@ -1912,24 +2202,29 @@
 android_glGenFramebuffersOES__I_3II
   (JNIEnv *_env, jobject _this, jint n, jintArray framebuffers_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *framebuffers_base = (GLuint *) 0;
     jint _remaining;
     GLuint *framebuffers = (GLuint *) 0;
 
     if (!framebuffers_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "framebuffers == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "framebuffers == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(framebuffers_ref) - offset;
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < n < needed";
         goto exit;
     }
     framebuffers_base = (GLuint *)
@@ -1946,6 +2241,9 @@
         _env->ReleasePrimitiveArrayCritical(framebuffers_ref, framebuffers_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGenFramebuffersOES ( GLsizei n, GLuint *framebuffers ) */
@@ -1953,6 +2251,8 @@
 android_glGenFramebuffersOES__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject framebuffers_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLuint *framebuffers = (GLuint *) 0;
@@ -1960,7 +2260,8 @@
     framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, &_array, &_remaining);
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < n < needed";
         goto exit;
     }
     glGenFramebuffersOES(
@@ -1972,6 +2273,9 @@
     if (_array) {
         releasePointer(_env, _array, framebuffers, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* GLenum glCheckFramebufferStatusOES ( GLenum target ) */
@@ -2015,24 +2319,29 @@
 android_glGetFramebufferAttachmentParameterivOES__III_3II
   (JNIEnv *_env, jobject _this, jint target, jint attachment, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLint *)
@@ -2051,6 +2360,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetFramebufferAttachmentParameterivOES ( GLenum target, GLenum attachment, GLenum pname, GLint *params ) */
@@ -2058,6 +2370,8 @@
 android_glGetFramebufferAttachmentParameterivOES__IIILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint attachment, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -2065,7 +2379,8 @@
     params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glGetFramebufferAttachmentParameterivOES(
@@ -2079,6 +2394,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGenerateMipmapOES ( GLenum target ) */
@@ -2194,16 +2512,23 @@
 static void
 android_glClipPlanefOES__I_3FI
   (JNIEnv *_env, jobject _this, jint plane, jfloatArray equation_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *equation_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *equation = (GLfloat *) 0;
 
     if (!equation_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "equation == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "equation == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(equation_ref) - offset;
@@ -2221,6 +2546,9 @@
         _env->ReleasePrimitiveArrayCritical(equation_ref, equation_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glClipPlanefOES ( GLenum plane, const GLfloat *equation ) */
@@ -2246,24 +2574,29 @@
 android_glGetClipPlanefOES__I_3FI
   (JNIEnv *_env, jobject _this, jint pname, jfloatArray eqn_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *eqn_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *eqn = (GLfloat *) 0;
 
     if (!eqn_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "eqn == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "eqn == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(eqn_ref) - offset;
     if (_remaining < 4) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 4");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 4 < needed";
         goto exit;
     }
     eqn_base = (GLfloat *)
@@ -2280,6 +2613,9 @@
         _env->ReleasePrimitiveArrayCritical(eqn_ref, eqn_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetClipPlanefOES ( GLenum pname, GLfloat *eqn ) */
@@ -2287,6 +2623,8 @@
 android_glGetClipPlanefOES__ILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject eqn_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *eqn = (GLfloat *) 0;
@@ -2294,7 +2632,8 @@
     eqn = (GLfloat *)getPointer(_env, eqn_buf, &_array, &_remaining);
     if (_remaining < 4) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 4");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 4 < needed";
         goto exit;
     }
     glGetClipPlanefOES(
@@ -2306,6 +2645,9 @@
     if (_array) {
         releasePointer(_env, _array, eqn, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glClearDepthfOES ( GLclampf depth ) */
@@ -2332,16 +2674,23 @@
 static void
 android_glTexGenfvOES__II_3FI
   (JNIEnv *_env, jobject _this, jint coord, jint pname, jfloatArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -2360,6 +2709,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexGenfvOES ( GLenum coord, GLenum pname, const GLfloat *params ) */
@@ -2396,16 +2748,23 @@
 static void
 android_glTexGenivOES__II_3II
   (JNIEnv *_env, jobject _this, jint coord, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -2424,6 +2783,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexGenivOES ( GLenum coord, GLenum pname, const GLint *params ) */
@@ -2460,16 +2822,23 @@
 static void
 android_glTexGenxvOES__II_3II
   (JNIEnv *_env, jobject _this, jint coord, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -2488,6 +2857,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexGenxvOES ( GLenum coord, GLenum pname, const GLfixed *params ) */
@@ -2514,18 +2886,22 @@
 android_glGetTexGenfvOES__II_3FI
   (JNIEnv *_env, jobject _this, jint coord, jint pname, jfloatArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -2544,13 +2920,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexGenfvOES ( GLenum coord, GLenum pname, GLfloat *params ) */
 static void
 android_glGetTexGenfvOES__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint coord, jint pname, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -2562,7 +2940,7 @@
         (GLfloat *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -2571,18 +2949,22 @@
 android_glGetTexGenivOES__II_3II
   (JNIEnv *_env, jobject _this, jint coord, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -2601,13 +2983,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexGenivOES ( GLenum coord, GLenum pname, GLint *params ) */
 static void
 android_glGetTexGenivOES__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint coord, jint pname, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -2619,7 +3003,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -2628,18 +3012,22 @@
 android_glGetTexGenxvOES__II_3II
   (JNIEnv *_env, jobject _this, jint coord, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -2658,13 +3046,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexGenxvOES ( GLenum coord, GLenum pname, GLfixed *params ) */
 static void
 android_glGetTexGenxvOES__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint coord, jint pname, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -2676,7 +3066,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
diff --git a/core/jni/android_opengl_GLES20.cpp b/core/jni/android_opengl_GLES20.cpp
index a53e4d7..87ff270 100644
--- a/core/jni/android_opengl_GLES20.cpp
+++ b/core/jni/android_opengl_GLES20.cpp
@@ -150,10 +150,14 @@
 static void
 android_glBindAttribLocation__IILjava_lang_String_2
   (JNIEnv *_env, jobject _this, jint program, jint index, jstring name) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     const char* _nativename = 0;
 
     if (!name) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "name == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "name == null";
         goto exit;
     }
     _nativename = _env->GetStringUTFChars(name, 0);
@@ -169,6 +173,9 @@
         _env->ReleaseStringUTFChars(name, _nativename);
     }
 
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glBindBuffer ( GLenum target, GLuint buffer ) */
@@ -268,6 +275,9 @@
 static void
 android_glBufferData__IILjava_nio_Buffer_2I
   (JNIEnv *_env, jobject _this, jint target, jint size, jobject data_buf, jint usage) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLvoid *data = (GLvoid *) 0;
@@ -275,7 +285,9 @@
     if (data_buf) {
         data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining);
         if (_remaining < size) {
-            jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < size");
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "remaining() < size < needed";
             goto exit;
         }
     }
@@ -290,19 +302,27 @@
     if (_array) {
         releasePointer(_env, _array, data, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glBufferSubData ( GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data ) */
 static void
 android_glBufferSubData__IIILjava_nio_Buffer_2
   (JNIEnv *_env, jobject _this, jint target, jint offset, jint size, jobject data_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLvoid *data = (GLvoid *) 0;
 
     data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining);
     if (_remaining < size) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < size");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < size < needed";
         goto exit;
     }
     glBufferSubData(
@@ -316,6 +336,9 @@
     if (_array) {
         releasePointer(_env, _array, data, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* GLenum glCheckFramebufferStatus ( GLenum target ) */
@@ -503,21 +526,30 @@
 static void
 android_glDeleteBuffers__I_3II
   (JNIEnv *_env, jobject _this, jint n, jintArray buffers_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *buffers_base = (GLuint *) 0;
     jint _remaining;
     GLuint *buffers = (GLuint *) 0;
 
     if (!buffers_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "buffers == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "buffers == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(buffers_ref) - offset;
     if (_remaining < n) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < n");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < n < needed";
         goto exit;
     }
     buffers_base = (GLuint *)
@@ -534,19 +566,27 @@
         _env->ReleasePrimitiveArrayCritical(buffers_ref, buffers_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDeleteBuffers ( GLsizei n, const GLuint *buffers ) */
 static void
 android_glDeleteBuffers__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject buffers_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLuint *buffers = (GLuint *) 0;
 
     buffers = (GLuint *)getPointer(_env, buffers_buf, &_array, &_remaining);
     if (_remaining < n) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < n");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < n < needed";
         goto exit;
     }
     glDeleteBuffers(
@@ -558,22 +598,32 @@
     if (_array) {
         releasePointer(_env, _array, buffers, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDeleteFramebuffers ( GLsizei n, const GLuint *framebuffers ) */
 static void
 android_glDeleteFramebuffers__I_3II
   (JNIEnv *_env, jobject _this, jint n, jintArray framebuffers_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *framebuffers_base = (GLuint *) 0;
     jint _remaining;
     GLuint *framebuffers = (GLuint *) 0;
 
     if (!framebuffers_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "framebuffers == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "framebuffers == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(framebuffers_ref) - offset;
@@ -591,6 +641,9 @@
         _env->ReleasePrimitiveArrayCritical(framebuffers_ref, framebuffers_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDeleteFramebuffers ( GLsizei n, const GLuint *framebuffers ) */
@@ -624,16 +677,23 @@
 static void
 android_glDeleteRenderbuffers__I_3II
   (JNIEnv *_env, jobject _this, jint n, jintArray renderbuffers_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *renderbuffers_base = (GLuint *) 0;
     jint _remaining;
     GLuint *renderbuffers = (GLuint *) 0;
 
     if (!renderbuffers_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "renderbuffers == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "renderbuffers == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(renderbuffers_ref) - offset;
@@ -651,6 +711,9 @@
         _env->ReleasePrimitiveArrayCritical(renderbuffers_ref, renderbuffers_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDeleteRenderbuffers ( GLsizei n, const GLuint *renderbuffers ) */
@@ -684,21 +747,30 @@
 static void
 android_glDeleteTextures__I_3II
   (JNIEnv *_env, jobject _this, jint n, jintArray textures_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *textures_base = (GLuint *) 0;
     jint _remaining;
     GLuint *textures = (GLuint *) 0;
 
     if (!textures_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "textures == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "textures == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(textures_ref) - offset;
     if (_remaining < n) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < n");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < n < needed";
         goto exit;
     }
     textures_base = (GLuint *)
@@ -715,19 +787,27 @@
         _env->ReleasePrimitiveArrayCritical(textures_ref, textures_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDeleteTextures ( GLsizei n, const GLuint *textures ) */
 static void
 android_glDeleteTextures__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject textures_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLuint *textures = (GLuint *) 0;
 
     textures = (GLuint *)getPointer(_env, textures_buf, &_array, &_remaining);
     if (_remaining < n) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < n");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < n < needed";
         goto exit;
     }
     glDeleteTextures(
@@ -739,6 +819,9 @@
     if (_array) {
         releasePointer(_env, _array, textures, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDepthFunc ( GLenum func ) */
@@ -812,25 +895,36 @@
 static void
 android_glDrawElements__IIII
   (JNIEnv *_env, jobject _this, jint mode, jint count, jint type, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     glDrawElements(
         (GLenum)mode,
         (GLsizei)count,
         (GLenum)type,
         (const GLvoid *)offset
     );
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDrawElements ( GLenum mode, GLsizei count, GLenum type, const GLvoid *indices ) */
 static void
 android_glDrawElements__IIILjava_nio_Buffer_2
   (JNIEnv *_env, jobject _this, jint mode, jint count, jint type, jobject indices_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLvoid *indices = (GLvoid *) 0;
 
     indices = (GLvoid *)getPointer(_env, indices_buf, &_array, &_remaining);
     if (_remaining < count) {
-        jniThrowException(_env, "java/lang/ArrayIndexOutOfBoundsException", "remaining() < count");
+        _exception = 1;
+        _exceptionType = "java/lang/ArrayIndexOutOfBoundsException";
+        _exceptionMessage = "remaining() < count < needed";
         goto exit;
     }
     glDrawElements(
@@ -844,6 +938,9 @@
     if (_array) {
         releasePointer(_env, _array, indices, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glEnable ( GLenum cap ) */
@@ -917,24 +1014,29 @@
 android_glGenBuffers__I_3II
   (JNIEnv *_env, jobject _this, jint n, jintArray buffers_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *buffers_base = (GLuint *) 0;
     jint _remaining;
     GLuint *buffers = (GLuint *) 0;
 
     if (!buffers_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "buffers == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "buffers == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(buffers_ref) - offset;
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < n < needed";
         goto exit;
     }
     buffers_base = (GLuint *)
@@ -951,6 +1053,9 @@
         _env->ReleasePrimitiveArrayCritical(buffers_ref, buffers_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGenBuffers ( GLsizei n, GLuint *buffers ) */
@@ -958,6 +1063,8 @@
 android_glGenBuffers__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject buffers_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLuint *buffers = (GLuint *) 0;
@@ -965,7 +1072,8 @@
     buffers = (GLuint *)getPointer(_env, buffers_buf, &_array, &_remaining);
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < n < needed";
         goto exit;
     }
     glGenBuffers(
@@ -977,6 +1085,9 @@
     if (_array) {
         releasePointer(_env, _array, buffers, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGenerateMipmap ( GLenum target ) */
@@ -993,18 +1104,22 @@
 android_glGenFramebuffers__I_3II
   (JNIEnv *_env, jobject _this, jint n, jintArray framebuffers_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *framebuffers_base = (GLuint *) 0;
     jint _remaining;
     GLuint *framebuffers = (GLuint *) 0;
 
     if (!framebuffers_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "framebuffers == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "framebuffers == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(framebuffers_ref) - offset;
@@ -1022,13 +1137,15 @@
         _env->ReleasePrimitiveArrayCritical(framebuffers_ref, framebuffers_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGenFramebuffers ( GLsizei n, GLuint *framebuffers ) */
 static void
 android_glGenFramebuffers__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject framebuffers_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLuint *framebuffers = (GLuint *) 0;
@@ -1039,7 +1156,7 @@
         (GLuint *)framebuffers
     );
     if (_array) {
-        releasePointer(_env, _array, framebuffers, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, framebuffers, JNI_TRUE);
     }
 }
 
@@ -1048,18 +1165,22 @@
 android_glGenRenderbuffers__I_3II
   (JNIEnv *_env, jobject _this, jint n, jintArray renderbuffers_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *renderbuffers_base = (GLuint *) 0;
     jint _remaining;
     GLuint *renderbuffers = (GLuint *) 0;
 
     if (!renderbuffers_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "renderbuffers == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "renderbuffers == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(renderbuffers_ref) - offset;
@@ -1077,13 +1198,15 @@
         _env->ReleasePrimitiveArrayCritical(renderbuffers_ref, renderbuffers_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGenRenderbuffers ( GLsizei n, GLuint *renderbuffers ) */
 static void
 android_glGenRenderbuffers__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject renderbuffers_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLuint *renderbuffers = (GLuint *) 0;
@@ -1094,7 +1217,7 @@
         (GLuint *)renderbuffers
     );
     if (_array) {
-        releasePointer(_env, _array, renderbuffers, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, renderbuffers, JNI_TRUE);
     }
 }
 
@@ -1103,24 +1226,29 @@
 android_glGenTextures__I_3II
   (JNIEnv *_env, jobject _this, jint n, jintArray textures_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *textures_base = (GLuint *) 0;
     jint _remaining;
     GLuint *textures = (GLuint *) 0;
 
     if (!textures_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "textures == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "textures == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(textures_ref) - offset;
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < n < needed";
         goto exit;
     }
     textures_base = (GLuint *)
@@ -1137,6 +1265,9 @@
         _env->ReleasePrimitiveArrayCritical(textures_ref, textures_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGenTextures ( GLsizei n, GLuint *textures ) */
@@ -1144,6 +1275,8 @@
 android_glGenTextures__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject textures_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLuint *textures = (GLuint *) 0;
@@ -1151,7 +1284,8 @@
     textures = (GLuint *)getPointer(_env, textures_buf, &_array, &_remaining);
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < n < needed";
         goto exit;
     }
     glGenTextures(
@@ -1163,6 +1297,9 @@
     if (_array) {
         releasePointer(_env, _array, textures, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetActiveAttrib ( GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, char *name ) */
@@ -1170,6 +1307,8 @@
 android_glGetActiveAttrib__III_3II_3II_3II_3BI
   (JNIEnv *_env, jobject _this, jint program, jint index, jint bufsize, jintArray length_ref, jint lengthOffset, jintArray size_ref, jint sizeOffset, jintArray type_ref, jint typeOffset, jbyteArray name_ref, jint nameOffset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLsizei *length_base = (GLsizei *) 0;
     jint _lengthRemaining;
     GLsizei *length = (GLsizei *) 0;
@@ -1185,12 +1324,14 @@
 
     if (!length_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length == null";
         goto exit;
     }
     if (lengthOffset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "lengthOffset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "lengthOffset < 0";
         goto exit;
     }
     _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
@@ -1200,12 +1341,14 @@
 
     if (!size_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "size == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "size == null";
         goto exit;
     }
     if (sizeOffset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "sizeOffset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "sizeOffset < 0";
         goto exit;
     }
     _sizeRemaining = _env->GetArrayLength(size_ref) - sizeOffset;
@@ -1215,12 +1358,14 @@
 
     if (!type_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "type == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "type == null";
         goto exit;
     }
     if (typeOffset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "typeOffset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "typeOffset < 0";
         goto exit;
     }
     _typeRemaining = _env->GetArrayLength(type_ref) - typeOffset;
@@ -1230,12 +1375,14 @@
 
     if (!name_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "name == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "name == null";
         goto exit;
     }
     if (nameOffset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "nameOffset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "nameOffset < 0";
         goto exit;
     }
     _nameRemaining = _env->GetArrayLength(name_ref) - nameOffset;
@@ -1270,13 +1417,15 @@
         _env->ReleasePrimitiveArrayCritical(length_ref, length_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetActiveAttrib ( GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, char *name ) */
 static void
 android_glGetActiveAttrib__IIILjava_nio_IntBuffer_2Ljava_nio_IntBuffer_2Ljava_nio_IntBuffer_2B
   (JNIEnv *_env, jobject _this, jint program, jint index, jint bufsize, jobject length_buf, jobject size_buf, jobject type_buf, jbyte name) {
-    jint _exception = 0;
     jarray _lengthArray = (jarray) 0;
     jarray _sizeArray = (jarray) 0;
     jarray _typeArray = (jarray) 0;
@@ -1300,13 +1449,13 @@
         (char *)name
     );
     if (_lengthArray) {
-        releasePointer(_env, _lengthArray, type, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _lengthArray, type, JNI_TRUE);
     }
     if (_sizeArray) {
-        releasePointer(_env, _sizeArray, size, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _sizeArray, size, JNI_TRUE);
     }
     if (_typeArray) {
-        releasePointer(_env, _typeArray, length, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _typeArray, length, JNI_TRUE);
     }
 }
 
@@ -1315,6 +1464,8 @@
 android_glGetActiveUniform__III_3II_3II_3II_3BI
   (JNIEnv *_env, jobject _this, jint program, jint index, jint bufsize, jintArray length_ref, jint lengthOffset, jintArray size_ref, jint sizeOffset, jintArray type_ref, jint typeOffset, jbyteArray name_ref, jint nameOffset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLsizei *length_base = (GLsizei *) 0;
     jint _lengthRemaining;
     GLsizei *length = (GLsizei *) 0;
@@ -1330,12 +1481,14 @@
 
     if (!length_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length == null";
         goto exit;
     }
     if (lengthOffset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "lengthOffset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "lengthOffset < 0";
         goto exit;
     }
     _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
@@ -1345,12 +1498,14 @@
 
     if (!size_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "size == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "size == null";
         goto exit;
     }
     if (sizeOffset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "sizeOffset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "sizeOffset < 0";
         goto exit;
     }
     _sizeRemaining = _env->GetArrayLength(size_ref) - sizeOffset;
@@ -1360,12 +1515,14 @@
 
     if (!type_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "type == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "type == null";
         goto exit;
     }
     if (typeOffset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "typeOffset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "typeOffset < 0";
         goto exit;
     }
     _typeRemaining = _env->GetArrayLength(type_ref) - typeOffset;
@@ -1375,12 +1532,14 @@
 
     if (!name_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "name == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "name == null";
         goto exit;
     }
     if (nameOffset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "nameOffset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "nameOffset < 0";
         goto exit;
     }
     _nameRemaining = _env->GetArrayLength(name_ref) - nameOffset;
@@ -1415,13 +1574,15 @@
         _env->ReleasePrimitiveArrayCritical(length_ref, length_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetActiveUniform ( GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, char *name ) */
 static void
 android_glGetActiveUniform__IIILjava_nio_IntBuffer_2Ljava_nio_IntBuffer_2Ljava_nio_IntBuffer_2B
   (JNIEnv *_env, jobject _this, jint program, jint index, jint bufsize, jobject length_buf, jobject size_buf, jobject type_buf, jbyte name) {
-    jint _exception = 0;
     jarray _lengthArray = (jarray) 0;
     jarray _sizeArray = (jarray) 0;
     jarray _typeArray = (jarray) 0;
@@ -1445,13 +1606,13 @@
         (char *)name
     );
     if (_lengthArray) {
-        releasePointer(_env, _lengthArray, type, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _lengthArray, type, JNI_TRUE);
     }
     if (_sizeArray) {
-        releasePointer(_env, _sizeArray, size, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _sizeArray, size, JNI_TRUE);
     }
     if (_typeArray) {
-        releasePointer(_env, _typeArray, length, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _typeArray, length, JNI_TRUE);
     }
 }
 
@@ -1460,6 +1621,8 @@
 android_glGetAttachedShaders__II_3II_3II
   (JNIEnv *_env, jobject _this, jint program, jint maxcount, jintArray count_ref, jint countOffset, jintArray shaders_ref, jint shadersOffset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLsizei *count_base = (GLsizei *) 0;
     jint _countRemaining;
     GLsizei *count = (GLsizei *) 0;
@@ -1469,12 +1632,14 @@
 
     if (!count_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "count == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "count == null";
         goto exit;
     }
     if (countOffset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "countOffset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "countOffset < 0";
         goto exit;
     }
     _countRemaining = _env->GetArrayLength(count_ref) - countOffset;
@@ -1484,12 +1649,14 @@
 
     if (!shaders_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "shaders == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "shaders == null";
         goto exit;
     }
     if (shadersOffset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "shadersOffset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "shadersOffset < 0";
         goto exit;
     }
     _shadersRemaining = _env->GetArrayLength(shaders_ref) - shadersOffset;
@@ -1513,13 +1680,15 @@
         _env->ReleasePrimitiveArrayCritical(count_ref, count_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetAttachedShaders ( GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders ) */
 static void
 android_glGetAttachedShaders__IILjava_nio_IntBuffer_2Ljava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint maxcount, jobject count_buf, jobject shaders_buf) {
-    jint _exception = 0;
     jarray _countArray = (jarray) 0;
     jarray _shadersArray = (jarray) 0;
     jint _countRemaining;
@@ -1536,10 +1705,10 @@
         (GLuint *)shaders
     );
     if (_countArray) {
-        releasePointer(_env, _countArray, shaders, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _countArray, shaders, JNI_TRUE);
     }
     if (_shadersArray) {
-        releasePointer(_env, _shadersArray, count, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _shadersArray, count, JNI_TRUE);
     }
 }
 
@@ -1547,11 +1716,15 @@
 static jint
 android_glGetAttribLocation__ILjava_lang_String_2
   (JNIEnv *_env, jobject _this, jint program, jstring name) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     int _returnValue = 0;
     const char* _nativename = 0;
 
     if (!name) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "name == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "name == null";
         goto exit;
     }
     _nativename = _env->GetStringUTFChars(name, 0);
@@ -1566,6 +1739,9 @@
         _env->ReleaseStringUTFChars(name, _nativename);
     }
 
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
     return _returnValue;
 }
 
@@ -1574,18 +1750,22 @@
 android_glGetBooleanv__I_3ZI
   (JNIEnv *_env, jobject _this, jint pname, jbooleanArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLboolean *params_base = (GLboolean *) 0;
     jint _remaining;
     GLboolean *params = (GLboolean *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -1603,13 +1783,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetBooleanv ( GLenum pname, GLboolean *params ) */
 static void
 android_glGetBooleanv__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLboolean *params = (GLboolean *) 0;
@@ -1620,7 +1802,7 @@
         (GLboolean *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -1629,24 +1811,29 @@
 android_glGetBufferParameteriv__II_3II
   (JNIEnv *_env, jobject _this, jint target, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLint *)
@@ -1664,6 +1851,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetBufferParameteriv ( GLenum target, GLenum pname, GLint *params ) */
@@ -1671,6 +1861,8 @@
 android_glGetBufferParameteriv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -1678,7 +1870,8 @@
     params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glGetBufferParameteriv(
@@ -1691,6 +1884,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* GLenum glGetError ( void ) */
@@ -1707,18 +1903,22 @@
 android_glGetFloatv__I_3FI
   (JNIEnv *_env, jobject _this, jint pname, jfloatArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -1736,13 +1936,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetFloatv ( GLenum pname, GLfloat *params ) */
 static void
 android_glGetFloatv__ILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -1753,7 +1955,7 @@
         (GLfloat *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -1762,18 +1964,22 @@
 android_glGetFramebufferAttachmentParameteriv__III_3II
   (JNIEnv *_env, jobject _this, jint target, jint attachment, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -1793,13 +1999,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetFramebufferAttachmentParameteriv ( GLenum target, GLenum attachment, GLenum pname, GLint *params ) */
 static void
 android_glGetFramebufferAttachmentParameteriv__IIILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint attachment, jint pname, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -1812,7 +2020,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -1821,18 +2029,22 @@
 android_glGetIntegerv__I_3II
   (JNIEnv *_env, jobject _this, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -2169,7 +2381,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLint *)
@@ -2186,6 +2399,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetIntegerv ( GLenum pname, GLint *params ) */
@@ -2193,6 +2409,8 @@
 android_glGetIntegerv__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -2531,7 +2749,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glGetIntegerv(
@@ -2543,6 +2762,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetProgramiv ( GLuint program, GLenum pname, GLint *params ) */
@@ -2550,18 +2772,22 @@
 android_glGetProgramiv__II_3II
   (JNIEnv *_env, jobject _this, jint program, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -2580,13 +2806,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetProgramiv ( GLuint program, GLenum pname, GLint *params ) */
 static void
 android_glGetProgramiv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint pname, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -2598,7 +2826,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -2626,18 +2854,22 @@
 android_glGetRenderbufferParameteriv__II_3II
   (JNIEnv *_env, jobject _this, jint target, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -2656,13 +2888,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetRenderbufferParameteriv ( GLenum target, GLenum pname, GLint *params ) */
 static void
 android_glGetRenderbufferParameteriv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -2674,7 +2908,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -2683,18 +2917,22 @@
 android_glGetShaderiv__II_3II
   (JNIEnv *_env, jobject _this, jint shader, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -2713,13 +2951,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetShaderiv ( GLuint shader, GLenum pname, GLint *params ) */
 static void
 android_glGetShaderiv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint shader, jint pname, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -2731,7 +2971,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -2759,6 +2999,8 @@
 android_glGetShaderPrecisionFormat__II_3II_3II
   (JNIEnv *_env, jobject _this, jint shadertype, jint precisiontype, jintArray range_ref, jint rangeOffset, jintArray precision_ref, jint precisionOffset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *range_base = (GLint *) 0;
     jint _rangeRemaining;
     GLint *range = (GLint *) 0;
@@ -2768,12 +3010,14 @@
 
     if (!range_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "range == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "range == null";
         goto exit;
     }
     if (rangeOffset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "rangeOffset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "rangeOffset < 0";
         goto exit;
     }
     _rangeRemaining = _env->GetArrayLength(range_ref) - rangeOffset;
@@ -2783,12 +3027,14 @@
 
     if (!precision_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "precision == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "precision == null";
         goto exit;
     }
     if (precisionOffset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "precisionOffset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "precisionOffset < 0";
         goto exit;
     }
     _precisionRemaining = _env->GetArrayLength(precision_ref) - precisionOffset;
@@ -2812,13 +3058,15 @@
         _env->ReleasePrimitiveArrayCritical(range_ref, range_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetShaderPrecisionFormat ( GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision ) */
 static void
 android_glGetShaderPrecisionFormat__IILjava_nio_IntBuffer_2Ljava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint shadertype, jint precisiontype, jobject range_buf, jobject precision_buf) {
-    jint _exception = 0;
     jarray _rangeArray = (jarray) 0;
     jarray _precisionArray = (jarray) 0;
     jint _rangeRemaining;
@@ -2835,10 +3083,10 @@
         (GLint *)precision
     );
     if (_rangeArray) {
-        releasePointer(_env, _rangeArray, precision, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _rangeArray, precision, JNI_TRUE);
     }
     if (_precisionArray) {
-        releasePointer(_env, _precisionArray, range, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _precisionArray, range, JNI_TRUE);
     }
 }
 
@@ -2847,6 +3095,8 @@
 android_glGetShaderSource__II_3II_3BI
   (JNIEnv *_env, jobject _this, jint shader, jint bufsize, jintArray length_ref, jint lengthOffset, jbyteArray source_ref, jint sourceOffset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLsizei *length_base = (GLsizei *) 0;
     jint _lengthRemaining;
     GLsizei *length = (GLsizei *) 0;
@@ -2856,12 +3106,14 @@
 
     if (!length_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length == null";
         goto exit;
     }
     if (lengthOffset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "lengthOffset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "lengthOffset < 0";
         goto exit;
     }
     _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
@@ -2871,12 +3123,14 @@
 
     if (!source_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "source == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "source == null";
         goto exit;
     }
     if (sourceOffset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "sourceOffset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "sourceOffset < 0";
         goto exit;
     }
     _sourceRemaining = _env->GetArrayLength(source_ref) - sourceOffset;
@@ -2900,13 +3154,15 @@
         _env->ReleasePrimitiveArrayCritical(length_ref, length_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetShaderSource ( GLuint shader, GLsizei bufsize, GLsizei *length, char *source ) */
 static void
 android_glGetShaderSource__IILjava_nio_IntBuffer_2B
   (JNIEnv *_env, jobject _this, jint shader, jint bufsize, jobject length_buf, jbyte source) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLsizei *length = (GLsizei *) 0;
@@ -2919,7 +3175,7 @@
         (char *)source
     );
     if (_array) {
-        releasePointer(_env, _array, length, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, length, JNI_TRUE);
     }
 }
 
@@ -2933,24 +3189,29 @@
 android_glGetTexParameterfv__II_3FI
   (JNIEnv *_env, jobject _this, jint target, jint pname, jfloatArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLfloat *)
@@ -2968,6 +3229,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexParameterfv ( GLenum target, GLenum pname, GLfloat *params ) */
@@ -2975,6 +3239,8 @@
 android_glGetTexParameterfv__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -2982,7 +3248,8 @@
     params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glGetTexParameterfv(
@@ -2995,6 +3262,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexParameteriv ( GLenum target, GLenum pname, GLint *params ) */
@@ -3002,24 +3272,29 @@
 android_glGetTexParameteriv__II_3II
   (JNIEnv *_env, jobject _this, jint target, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLint *)
@@ -3037,6 +3312,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexParameteriv ( GLenum target, GLenum pname, GLint *params ) */
@@ -3044,6 +3322,8 @@
 android_glGetTexParameteriv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -3051,7 +3331,8 @@
     params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glGetTexParameteriv(
@@ -3064,6 +3345,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetUniformfv ( GLuint program, GLint location, GLfloat *params ) */
@@ -3071,18 +3355,22 @@
 android_glGetUniformfv__II_3FI
   (JNIEnv *_env, jobject _this, jint program, jint location, jfloatArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -3101,13 +3389,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetUniformfv ( GLuint program, GLint location, GLfloat *params ) */
 static void
 android_glGetUniformfv__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -3119,7 +3409,7 @@
         (GLfloat *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -3128,18 +3418,22 @@
 android_glGetUniformiv__II_3II
   (JNIEnv *_env, jobject _this, jint program, jint location, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -3158,13 +3452,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetUniformiv ( GLuint program, GLint location, GLint *params ) */
 static void
 android_glGetUniformiv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -3176,7 +3472,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -3184,11 +3480,15 @@
 static jint
 android_glGetUniformLocation__ILjava_lang_String_2
   (JNIEnv *_env, jobject _this, jint program, jstring name) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     int _returnValue = 0;
     const char* _nativename = 0;
 
     if (!name) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "name == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "name == null";
         goto exit;
     }
     _nativename = _env->GetStringUTFChars(name, 0);
@@ -3203,6 +3503,9 @@
         _env->ReleaseStringUTFChars(name, _nativename);
     }
 
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
     return _returnValue;
 }
 
@@ -3211,18 +3514,22 @@
 android_glGetVertexAttribfv__II_3FI
   (JNIEnv *_env, jobject _this, jint index, jint pname, jfloatArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -3241,13 +3548,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetVertexAttribfv ( GLuint index, GLenum pname, GLfloat *params ) */
 static void
 android_glGetVertexAttribfv__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint index, jint pname, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -3259,7 +3568,7 @@
         (GLfloat *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -3268,18 +3577,22 @@
 android_glGetVertexAttribiv__II_3II
   (JNIEnv *_env, jobject _this, jint index, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -3298,13 +3611,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetVertexAttribiv ( GLuint index, GLenum pname, GLint *params ) */
 static void
 android_glGetVertexAttribiv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint index, jint pname, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -3316,7 +3631,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -3449,7 +3764,6 @@
 static void
 android_glReadPixels__IIIIIILjava_nio_Buffer_2
   (JNIEnv *_env, jobject _this, jint x, jint y, jint width, jint height, jint format, jint type, jobject pixels_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLvoid *pixels = (GLvoid *) 0;
@@ -3465,7 +3779,7 @@
         (GLvoid *)pixels
     );
     if (_array) {
-        releasePointer(_env, _array, pixels, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, pixels, JNI_TRUE);
     }
 }
 
@@ -3514,6 +3828,9 @@
 static void
 android_glShaderBinary__I_3IIILjava_nio_Buffer_2I
   (JNIEnv *_env, jobject _this, jint n, jintArray shaders_ref, jint offset, jint binaryformat, jobject binary_buf, jint length) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     GLuint *shaders_base = (GLuint *) 0;
     jint _shadersRemaining;
@@ -3522,11 +3839,15 @@
     GLvoid *binary = (GLvoid *) 0;
 
     if (!shaders_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "shaders == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "shaders == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _shadersRemaining = _env->GetArrayLength(shaders_ref) - offset;
@@ -3551,6 +3872,9 @@
         _env->ReleasePrimitiveArrayCritical(shaders_ref, shaders_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glShaderBinary ( GLsizei n, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length ) */
@@ -3705,21 +4029,30 @@
 static void
 android_glTexParameterfv__II_3FI
   (JNIEnv *_env, jobject _this, jint target, jint pname, jfloatArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLfloat *)
@@ -3737,19 +4070,27 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexParameterfv ( GLenum target, GLenum pname, const GLfloat *params ) */
 static void
 android_glTexParameterfv__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glTexParameterfv(
@@ -3762,6 +4103,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexParameteri ( GLenum target, GLenum pname, GLint param ) */
@@ -3779,21 +4123,30 @@
 static void
 android_glTexParameteriv__II_3II
   (JNIEnv *_env, jobject _this, jint target, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLint *)
@@ -3811,19 +4164,27 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexParameteriv ( GLenum target, GLenum pname, const GLint *params ) */
 static void
 android_glTexParameteriv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glTexParameteriv(
@@ -3836,6 +4197,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexSubImage2D ( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels ) */
@@ -3879,16 +4243,23 @@
 static void
 android_glUniform1fv__II_3FI
   (JNIEnv *_env, jobject _this, jint location, jint count, jfloatArray v_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *v_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *v = (GLfloat *) 0;
 
     if (!v_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "v == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "v == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(v_ref) - offset;
@@ -3907,6 +4278,9 @@
         _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glUniform1fv ( GLint location, GLsizei count, const GLfloat *v ) */
@@ -3942,16 +4316,23 @@
 static void
 android_glUniform1iv__II_3II
   (JNIEnv *_env, jobject _this, jint location, jint count, jintArray v_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *v_base = (GLint *) 0;
     jint _remaining;
     GLint *v = (GLint *) 0;
 
     if (!v_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "v == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "v == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(v_ref) - offset;
@@ -3970,6 +4351,9 @@
         _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glUniform1iv ( GLint location, GLsizei count, const GLint *v ) */
@@ -4006,16 +4390,23 @@
 static void
 android_glUniform2fv__II_3FI
   (JNIEnv *_env, jobject _this, jint location, jint count, jfloatArray v_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *v_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *v = (GLfloat *) 0;
 
     if (!v_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "v == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "v == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(v_ref) - offset;
@@ -4034,6 +4425,9 @@
         _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glUniform2fv ( GLint location, GLsizei count, const GLfloat *v ) */
@@ -4070,16 +4464,23 @@
 static void
 android_glUniform2iv__II_3II
   (JNIEnv *_env, jobject _this, jint location, jint count, jintArray v_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *v_base = (GLint *) 0;
     jint _remaining;
     GLint *v = (GLint *) 0;
 
     if (!v_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "v == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "v == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(v_ref) - offset;
@@ -4098,6 +4499,9 @@
         _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glUniform2iv ( GLint location, GLsizei count, const GLint *v ) */
@@ -4135,16 +4539,23 @@
 static void
 android_glUniform3fv__II_3FI
   (JNIEnv *_env, jobject _this, jint location, jint count, jfloatArray v_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *v_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *v = (GLfloat *) 0;
 
     if (!v_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "v == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "v == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(v_ref) - offset;
@@ -4163,6 +4574,9 @@
         _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glUniform3fv ( GLint location, GLsizei count, const GLfloat *v ) */
@@ -4200,16 +4614,23 @@
 static void
 android_glUniform3iv__II_3II
   (JNIEnv *_env, jobject _this, jint location, jint count, jintArray v_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *v_base = (GLint *) 0;
     jint _remaining;
     GLint *v = (GLint *) 0;
 
     if (!v_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "v == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "v == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(v_ref) - offset;
@@ -4228,6 +4649,9 @@
         _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glUniform3iv ( GLint location, GLsizei count, const GLint *v ) */
@@ -4266,16 +4690,23 @@
 static void
 android_glUniform4fv__II_3FI
   (JNIEnv *_env, jobject _this, jint location, jint count, jfloatArray v_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *v_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *v = (GLfloat *) 0;
 
     if (!v_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "v == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "v == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(v_ref) - offset;
@@ -4294,6 +4725,9 @@
         _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glUniform4fv ( GLint location, GLsizei count, const GLfloat *v ) */
@@ -4332,16 +4766,23 @@
 static void
 android_glUniform4iv__II_3II
   (JNIEnv *_env, jobject _this, jint location, jint count, jintArray v_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *v_base = (GLint *) 0;
     jint _remaining;
     GLint *v = (GLint *) 0;
 
     if (!v_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "v == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "v == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(v_ref) - offset;
@@ -4360,6 +4801,9 @@
         _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glUniform4iv ( GLint location, GLsizei count, const GLint *v ) */
@@ -4385,16 +4829,23 @@
 static void
 android_glUniformMatrix2fv__IIZ_3FI
   (JNIEnv *_env, jobject _this, jint location, jint count, jboolean transpose, jfloatArray value_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *value_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
     if (!value_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "value == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "value == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
@@ -4414,6 +4865,9 @@
         _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glUniformMatrix2fv ( GLint location, GLsizei count, GLboolean transpose, const GLfloat *value ) */
@@ -4440,16 +4894,23 @@
 static void
 android_glUniformMatrix3fv__IIZ_3FI
   (JNIEnv *_env, jobject _this, jint location, jint count, jboolean transpose, jfloatArray value_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *value_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
     if (!value_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "value == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "value == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
@@ -4469,6 +4930,9 @@
         _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glUniformMatrix3fv ( GLint location, GLsizei count, GLboolean transpose, const GLfloat *value ) */
@@ -4495,16 +4959,23 @@
 static void
 android_glUniformMatrix4fv__IIZ_3FI
   (JNIEnv *_env, jobject _this, jint location, jint count, jboolean transpose, jfloatArray value_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *value_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
     if (!value_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "value == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "value == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
@@ -4524,6 +4995,9 @@
         _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glUniformMatrix4fv ( GLint location, GLsizei count, GLboolean transpose, const GLfloat *value ) */
@@ -4578,16 +5052,23 @@
 static void
 android_glVertexAttrib1fv__I_3FI
   (JNIEnv *_env, jobject _this, jint indx, jfloatArray values_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *values_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *values = (GLfloat *) 0;
 
     if (!values_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "values == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "values == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(values_ref) - offset;
@@ -4605,6 +5086,9 @@
         _env->ReleasePrimitiveArrayCritical(values_ref, values_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glVertexAttrib1fv ( GLuint indx, const GLfloat *values ) */
@@ -4640,16 +5124,23 @@
 static void
 android_glVertexAttrib2fv__I_3FI
   (JNIEnv *_env, jobject _this, jint indx, jfloatArray values_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *values_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *values = (GLfloat *) 0;
 
     if (!values_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "values == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "values == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(values_ref) - offset;
@@ -4667,6 +5158,9 @@
         _env->ReleasePrimitiveArrayCritical(values_ref, values_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glVertexAttrib2fv ( GLuint indx, const GLfloat *values ) */
@@ -4703,16 +5197,23 @@
 static void
 android_glVertexAttrib3fv__I_3FI
   (JNIEnv *_env, jobject _this, jint indx, jfloatArray values_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *values_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *values = (GLfloat *) 0;
 
     if (!values_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "values == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "values == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(values_ref) - offset;
@@ -4730,6 +5231,9 @@
         _env->ReleasePrimitiveArrayCritical(values_ref, values_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glVertexAttrib3fv ( GLuint indx, const GLfloat *values ) */
@@ -4767,16 +5271,23 @@
 static void
 android_glVertexAttrib4fv__I_3FI
   (JNIEnv *_env, jobject _this, jint indx, jfloatArray values_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *values_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *values = (GLfloat *) 0;
 
     if (!values_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "values == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "values == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(values_ref) - offset;
@@ -4794,6 +5305,9 @@
         _env->ReleasePrimitiveArrayCritical(values_ref, values_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glVertexAttrib4fv ( GLuint indx, const GLfloat *values ) */
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index a51b77e..9040941 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -769,6 +769,13 @@
     env->ReleaseIntArrayElements(layerInfo, storage, 0);
 }
 
+static void android_view_GLES20Canvas_setOpaqueLayer(JNIEnv* env, jobject clazz,
+        Layer* layer, jboolean isOpaque) {
+    if (layer) {
+        layer->setBlend(!isOpaque);
+    }
+}
+
 static void android_view_GLES20Canvas_updateTextureLayer(JNIEnv* env, jobject clazz,
         Layer* layer, jint width, jint height, jboolean isOpaque, jobject surface) {
     float transform[16];
@@ -803,10 +810,6 @@
     LayerRenderer::destroyLayerDeferred(layer);
 }
 
-static void android_view_GLES20Canvas_flushLayer(JNIEnv* env, jobject clazz, Layer* layer) {
-    LayerRenderer::flushLayer(layer);
-}
-
 static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, Layer* layer, jfloat x, jfloat y, SkPaint* paint) {
     renderer->drawLayer(layer, x, y, paint);
@@ -969,13 +972,13 @@
     { "nCreateLayerRenderer",    "(I)I",       (void*) android_view_GLES20Canvas_createLayerRenderer },
     { "nCreateLayer",            "(IIZ[I)I",   (void*) android_view_GLES20Canvas_createLayer },
     { "nResizeLayer",            "(III[I)V" ,  (void*) android_view_GLES20Canvas_resizeLayer },
+    { "nSetOpaqueLayer",         "(IZ)V",      (void*) android_view_GLES20Canvas_setOpaqueLayer },
     { "nCreateTextureLayer",     "(Z[I)I",     (void*) android_view_GLES20Canvas_createTextureLayer },
     { "nUpdateTextureLayer",     "(IIIZLandroid/graphics/SurfaceTexture;)V",
             (void*) android_view_GLES20Canvas_updateTextureLayer },
     { "nUpdateRenderLayer",      "(IIIIIII)V", (void*) android_view_GLES20Canvas_updateRenderLayer },
     { "nDestroyLayer",           "(I)V",       (void*) android_view_GLES20Canvas_destroyLayer },
     { "nDestroyLayerDeferred",   "(I)V",       (void*) android_view_GLES20Canvas_destroyLayerDeferred },
-    { "nFlushLayer",             "(I)V",       (void*) android_view_GLES20Canvas_flushLayer },
     { "nDrawLayer",              "(IIFFI)V",   (void*) android_view_GLES20Canvas_drawLayer },
     { "nCopyLayer",              "(II)Z",      (void*) android_view_GLES20Canvas_copyLayer },
 
diff --git a/core/jni/com_google_android_gles_jni_GLImpl.cpp b/core/jni/com_google_android_gles_jni_GLImpl.cpp
index 8777131..0310dc7 100644
--- a/core/jni/com_google_android_gles_jni_GLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_GLImpl.cpp
@@ -530,21 +530,30 @@
 static void
 android_glDeleteTextures__I_3II
   (JNIEnv *_env, jobject _this, jint n, jintArray textures_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *textures_base = (GLuint *) 0;
     jint _remaining;
     GLuint *textures = (GLuint *) 0;
 
     if (!textures_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "textures == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "textures == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(textures_ref) - offset;
     if (_remaining < n) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < n");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < n < needed";
         goto exit;
     }
     textures_base = (GLuint *)
@@ -561,19 +570,27 @@
         _env->ReleasePrimitiveArrayCritical(textures_ref, textures_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDeleteTextures ( GLsizei n, const GLuint *textures ) */
 static void
 android_glDeleteTextures__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject textures_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLuint *textures = (GLuint *) 0;
 
     textures = (GLuint *)getPointer(_env, textures_buf, &_array, &_remaining);
     if (_remaining < n) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < n");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < n < needed";
         goto exit;
     }
     glDeleteTextures(
@@ -585,6 +602,9 @@
     if (_array) {
         releasePointer(_env, _array, textures, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDepthFunc ( GLenum func ) */
@@ -658,13 +678,18 @@
 static void
 android_glDrawElements__IIILjava_nio_Buffer_2
   (JNIEnv *_env, jobject _this, jint mode, jint count, jint type, jobject indices_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLvoid *indices = (GLvoid *) 0;
 
     indices = (GLvoid *)getPointer(_env, indices_buf, &_array, &_remaining);
     if (_remaining < count) {
-        jniThrowException(_env, "java/lang/ArrayIndexOutOfBoundsException", "remaining() < count");
+        _exception = 1;
+        _exceptionType = "java/lang/ArrayIndexOutOfBoundsException";
+        _exceptionMessage = "remaining() < count < needed";
         goto exit;
     }
     glDrawElements(
@@ -678,6 +703,9 @@
     if (_array) {
         releasePointer(_env, _array, indices, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glEnable ( GLenum cap ) */
@@ -726,16 +754,23 @@
 static void
 android_glFogfv__I_3FI
   (JNIEnv *_env, jobject _this, jint pname, jfloatArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -765,7 +800,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfloat *)
@@ -782,12 +819,18 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glFogfv ( GLenum pname, const GLfloat *params ) */
 static void
 android_glFogfv__ILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -819,7 +862,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glFogfv(
@@ -831,6 +876,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glFogx ( GLenum pname, GLfixed param ) */
@@ -847,16 +895,23 @@
 static void
 android_glFogxv__I_3II
   (JNIEnv *_env, jobject _this, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -886,7 +941,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfixed *)
@@ -903,12 +960,18 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glFogxv ( GLenum pname, const GLfixed *params ) */
 static void
 android_glFogxv__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -940,7 +1003,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glFogxv(
@@ -952,6 +1017,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glFrontFace ( GLenum mode ) */
@@ -996,24 +1064,29 @@
 android_glGenTextures__I_3II
   (JNIEnv *_env, jobject _this, jint n, jintArray textures_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *textures_base = (GLuint *) 0;
     jint _remaining;
     GLuint *textures = (GLuint *) 0;
 
     if (!textures_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "textures == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "textures == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(textures_ref) - offset;
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < n < needed";
         goto exit;
     }
     textures_base = (GLuint *)
@@ -1030,6 +1103,9 @@
         _env->ReleasePrimitiveArrayCritical(textures_ref, textures_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGenTextures ( GLsizei n, GLuint *textures ) */
@@ -1037,6 +1113,8 @@
 android_glGenTextures__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject textures_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLuint *textures = (GLuint *) 0;
@@ -1044,7 +1122,8 @@
     textures = (GLuint *)getPointer(_env, textures_buf, &_array, &_remaining);
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < n < needed";
         goto exit;
     }
     glGenTextures(
@@ -1056,6 +1135,9 @@
     if (_array) {
         releasePointer(_env, _array, textures, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* GLenum glGetError ( void ) */
@@ -1072,18 +1154,22 @@
 android_glGetIntegerv__I_3II
   (JNIEnv *_env, jobject _this, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -1420,7 +1506,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLint *)
@@ -1437,6 +1524,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetIntegerv ( GLenum pname, GLint *params ) */
@@ -1444,6 +1534,8 @@
 android_glGetIntegerv__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -1782,7 +1874,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glGetIntegerv(
@@ -1794,6 +1887,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* const GLubyte * glGetString ( GLenum name ) */
@@ -1825,16 +1921,23 @@
 static void
 android_glLightModelfv__I_3FI
   (JNIEnv *_env, jobject _this, jint pname, jfloatArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -1855,7 +1958,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfloat *)
@@ -1872,12 +1977,18 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLightModelfv ( GLenum pname, const GLfloat *params ) */
 static void
 android_glLightModelfv__ILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -1900,7 +2011,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glLightModelfv(
@@ -1912,6 +2025,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLightModelx ( GLenum pname, GLfixed param ) */
@@ -1928,16 +2044,23 @@
 static void
 android_glLightModelxv__I_3II
   (JNIEnv *_env, jobject _this, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -1958,7 +2081,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfixed *)
@@ -1975,12 +2100,18 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLightModelxv ( GLenum pname, const GLfixed *params ) */
 static void
 android_glLightModelxv__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -2003,7 +2134,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glLightModelxv(
@@ -2015,6 +2148,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLightf ( GLenum light, GLenum pname, GLfloat param ) */
@@ -2032,16 +2168,23 @@
 static void
 android_glLightfv__II_3FI
   (JNIEnv *_env, jobject _this, jint light, jint pname, jfloatArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -2088,7 +2231,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfloat *)
@@ -2106,12 +2251,18 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLightfv ( GLenum light, GLenum pname, const GLfloat *params ) */
 static void
 android_glLightfv__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint light, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -2160,7 +2311,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glLightfv(
@@ -2173,6 +2326,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLightx ( GLenum light, GLenum pname, GLfixed param ) */
@@ -2190,16 +2346,23 @@
 static void
 android_glLightxv__II_3II
   (JNIEnv *_env, jobject _this, jint light, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -2246,7 +2409,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfixed *)
@@ -2264,12 +2429,18 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLightxv ( GLenum light, GLenum pname, const GLfixed *params ) */
 static void
 android_glLightxv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint light, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -2318,7 +2489,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glLightxv(
@@ -2331,6 +2504,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLineWidth ( GLfloat width ) */
@@ -2362,16 +2538,23 @@
 static void
 android_glLoadMatrixf___3FI
   (JNIEnv *_env, jobject _this, jfloatArray m_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *m_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *m = (GLfloat *) 0;
 
     if (!m_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "m == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "m == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(m_ref) - offset;
@@ -2388,6 +2571,9 @@
         _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLoadMatrixf ( const GLfloat *m ) */
@@ -2411,16 +2597,23 @@
 static void
 android_glLoadMatrixx___3II
   (JNIEnv *_env, jobject _this, jintArray m_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *m_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *m = (GLfixed *) 0;
 
     if (!m_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "m == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "m == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(m_ref) - offset;
@@ -2437,6 +2630,9 @@
         _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLoadMatrixx ( const GLfixed *m ) */
@@ -2480,16 +2676,23 @@
 static void
 android_glMaterialfv__II_3FI
   (JNIEnv *_env, jobject _this, jint face, jint pname, jfloatArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -2522,7 +2725,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfloat *)
@@ -2540,12 +2745,18 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glMaterialfv ( GLenum face, GLenum pname, const GLfloat *params ) */
 static void
 android_glMaterialfv__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint face, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -2580,7 +2791,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glMaterialfv(
@@ -2593,6 +2806,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glMaterialx ( GLenum face, GLenum pname, GLfixed param ) */
@@ -2610,16 +2826,23 @@
 static void
 android_glMaterialxv__II_3II
   (JNIEnv *_env, jobject _this, jint face, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -2652,7 +2875,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfixed *)
@@ -2670,12 +2895,18 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glMaterialxv ( GLenum face, GLenum pname, const GLfixed *params ) */
 static void
 android_glMaterialxv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint face, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -2710,7 +2941,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glMaterialxv(
@@ -2723,6 +2956,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glMatrixMode ( GLenum mode ) */
@@ -2738,16 +2974,23 @@
 static void
 android_glMultMatrixf___3FI
   (JNIEnv *_env, jobject _this, jfloatArray m_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *m_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *m = (GLfloat *) 0;
 
     if (!m_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "m == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "m == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(m_ref) - offset;
@@ -2764,6 +3007,9 @@
         _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glMultMatrixf ( const GLfloat *m ) */
@@ -2787,16 +3033,23 @@
 static void
 android_glMultMatrixx___3II
   (JNIEnv *_env, jobject _this, jintArray m_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *m_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *m = (GLfixed *) 0;
 
     if (!m_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "m == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "m == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(m_ref) - offset;
@@ -2813,6 +3066,9 @@
         _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glMultMatrixx ( const GLfixed *m ) */
@@ -2996,7 +3252,6 @@
 static void
 android_glReadPixels__IIIIIILjava_nio_Buffer_2
   (JNIEnv *_env, jobject _this, jint x, jint y, jint width, jint height, jint format, jint type, jobject pixels_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLvoid *pixels = (GLvoid *) 0;
@@ -3012,7 +3267,7 @@
         (GLvoid *)pixels
     );
     if (_array) {
-        releasePointer(_env, _array, pixels, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, pixels, JNI_TRUE);
     }
 }
 
@@ -3172,16 +3427,23 @@
 static void
 android_glTexEnvfv__II_3FI
   (JNIEnv *_env, jobject _this, jint target, jint pname, jfloatArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -3208,7 +3470,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfloat *)
@@ -3226,12 +3490,18 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexEnvfv ( GLenum target, GLenum pname, const GLfloat *params ) */
 static void
 android_glTexEnvfv__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -3260,7 +3530,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glTexEnvfv(
@@ -3273,6 +3545,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexEnvx ( GLenum target, GLenum pname, GLfixed param ) */
@@ -3290,16 +3565,23 @@
 static void
 android_glTexEnvxv__II_3II
   (JNIEnv *_env, jobject _this, jint target, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -3326,7 +3608,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfixed *)
@@ -3344,12 +3628,18 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexEnvxv ( GLenum target, GLenum pname, const GLfixed *params ) */
 static void
 android_glTexEnvxv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -3378,7 +3668,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glTexEnvxv(
@@ -3391,6 +3683,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexImage2D ( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels ) */
@@ -3531,6 +3826,8 @@
 android_glQueryMatrixxOES___3II_3II
   (JNIEnv *_env, jobject _this, jintArray mantissa_ref, jint mantissaOffset, jintArray exponent_ref, jint exponentOffset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLbitfield _returnValue = -1;
     GLfixed *mantissa_base = (GLfixed *) 0;
     jint _mantissaRemaining;
@@ -3541,18 +3838,21 @@
 
     if (!mantissa_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "mantissa == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "mantissa == null";
         goto exit;
     }
     if (mantissaOffset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "mantissaOffset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "mantissaOffset < 0";
         goto exit;
     }
     _mantissaRemaining = _env->GetArrayLength(mantissa_ref) - mantissaOffset;
     if (_mantissaRemaining < 16) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - mantissaOffset < 16");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - mantissaOffset < 16 < needed";
         goto exit;
     }
     mantissa_base = (GLfixed *)
@@ -3561,18 +3861,21 @@
 
     if (!exponent_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "exponent == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "exponent == null";
         goto exit;
     }
     if (exponentOffset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "exponentOffset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "exponentOffset < 0";
         goto exit;
     }
     _exponentRemaining = _env->GetArrayLength(exponent_ref) - exponentOffset;
     if (_exponentRemaining < 16) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - exponentOffset < 16");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - exponentOffset < 16 < needed";
         goto exit;
     }
     exponent_base = (GLint *)
@@ -3593,6 +3896,9 @@
         _env->ReleasePrimitiveArrayCritical(mantissa_ref, mantissa_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
     return _returnValue;
 }
 
@@ -3601,6 +3907,8 @@
 android_glQueryMatrixxOES__Ljava_nio_IntBuffer_2Ljava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jobject mantissa_buf, jobject exponent_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _mantissaArray = (jarray) 0;
     jarray _exponentArray = (jarray) 0;
     GLbitfield _returnValue = -1;
@@ -3612,13 +3920,15 @@
     mantissa = (GLfixed *)getPointer(_env, mantissa_buf, &_mantissaArray, &_mantissaRemaining);
     if (_mantissaRemaining < 16) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 16");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 16 < needed";
         goto exit;
     }
     exponent = (GLint *)getPointer(_env, exponent_buf, &_exponentArray, &_exponentRemaining);
     if (_exponentRemaining < 16) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 16");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 16 < needed";
         goto exit;
     }
     _returnValue = glQueryMatrixxOES(
@@ -3633,6 +3943,9 @@
     if (_exponentArray) {
         releasePointer(_env, _exponentArray, mantissa, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
     return _returnValue;
 }
 
@@ -3650,6 +3963,9 @@
 static void
 android_glBufferData__IILjava_nio_Buffer_2I
   (JNIEnv *_env, jobject _this, jint target, jint size, jobject data_buf, jint usage) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLvoid *data = (GLvoid *) 0;
@@ -3657,7 +3973,9 @@
     if (data_buf) {
         data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining);
         if (_remaining < size) {
-            jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < size");
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "remaining() < size < needed";
             goto exit;
         }
     }
@@ -3672,19 +3990,27 @@
     if (_array) {
         releasePointer(_env, _array, data, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glBufferSubData ( GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data ) */
 static void
 android_glBufferSubData__IIILjava_nio_Buffer_2
   (JNIEnv *_env, jobject _this, jint target, jint offset, jint size, jobject data_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLvoid *data = (GLvoid *) 0;
 
     data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining);
     if (_remaining < size) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < size");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < size < needed";
         goto exit;
     }
     glBufferSubData(
@@ -3698,27 +4024,39 @@
     if (_array) {
         releasePointer(_env, _array, data, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glClipPlanef ( GLenum plane, const GLfloat *equation ) */
 static void
 android_glClipPlanef__I_3FI
   (JNIEnv *_env, jobject _this, jint plane, jfloatArray equation_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *equation_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *equation = (GLfloat *) 0;
 
     if (!equation_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "equation == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "equation == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(equation_ref) - offset;
     if (_remaining < 4) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 4");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 4 < needed";
         goto exit;
     }
     equation_base = (GLfloat *)
@@ -3735,19 +4073,27 @@
         _env->ReleasePrimitiveArrayCritical(equation_ref, equation_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glClipPlanef ( GLenum plane, const GLfloat *equation ) */
 static void
 android_glClipPlanef__ILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint plane, jobject equation_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *equation = (GLfloat *) 0;
 
     equation = (GLfloat *)getPointer(_env, equation_buf, &_array, &_remaining);
     if (_remaining < 4) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 4");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 4 < needed";
         goto exit;
     }
     glClipPlanef(
@@ -3759,27 +4105,39 @@
     if (_array) {
         releasePointer(_env, _array, equation, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glClipPlanex ( GLenum plane, const GLfixed *equation ) */
 static void
 android_glClipPlanex__I_3II
   (JNIEnv *_env, jobject _this, jint plane, jintArray equation_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *equation_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *equation = (GLfixed *) 0;
 
     if (!equation_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "equation == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "equation == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(equation_ref) - offset;
     if (_remaining < 4) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 4");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 4 < needed";
         goto exit;
     }
     equation_base = (GLfixed *)
@@ -3796,19 +4154,27 @@
         _env->ReleasePrimitiveArrayCritical(equation_ref, equation_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glClipPlanex ( GLenum plane, const GLfixed *equation ) */
 static void
 android_glClipPlanex__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint plane, jobject equation_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *equation = (GLfixed *) 0;
 
     equation = (GLfixed *)getPointer(_env, equation_buf, &_array, &_remaining);
     if (_remaining < 4) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 4");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 4 < needed";
         goto exit;
     }
     glClipPlanex(
@@ -3820,6 +4186,9 @@
     if (_array) {
         releasePointer(_env, _array, equation, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glColor4ub ( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha ) */
@@ -3850,21 +4219,30 @@
 static void
 android_glDeleteBuffers__I_3II
   (JNIEnv *_env, jobject _this, jint n, jintArray buffers_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *buffers_base = (GLuint *) 0;
     jint _remaining;
     GLuint *buffers = (GLuint *) 0;
 
     if (!buffers_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "buffers == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "buffers == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(buffers_ref) - offset;
     if (_remaining < n) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < n");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < n < needed";
         goto exit;
     }
     buffers_base = (GLuint *)
@@ -3881,19 +4259,27 @@
         _env->ReleasePrimitiveArrayCritical(buffers_ref, buffers_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDeleteBuffers ( GLsizei n, const GLuint *buffers ) */
 static void
 android_glDeleteBuffers__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject buffers_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLuint *buffers = (GLuint *) 0;
 
     buffers = (GLuint *)getPointer(_env, buffers_buf, &_array, &_remaining);
     if (_remaining < n) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < n");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < n < needed";
         goto exit;
     }
     glDeleteBuffers(
@@ -3905,18 +4291,27 @@
     if (_array) {
         releasePointer(_env, _array, buffers, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDrawElements ( GLenum mode, GLsizei count, GLenum type, GLint offset ) */
 static void
 android_glDrawElements__IIII
   (JNIEnv *_env, jobject _this, jint mode, jint count, jint type, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     glDrawElements(
         (GLenum)mode,
         (GLsizei)count,
         (GLenum)type,
         (const GLvoid *)offset
     );
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGenBuffers ( GLsizei n, GLuint *buffers ) */
@@ -3924,24 +4319,29 @@
 android_glGenBuffers__I_3II
   (JNIEnv *_env, jobject _this, jint n, jintArray buffers_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *buffers_base = (GLuint *) 0;
     jint _remaining;
     GLuint *buffers = (GLuint *) 0;
 
     if (!buffers_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "buffers == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "buffers == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(buffers_ref) - offset;
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < n < needed";
         goto exit;
     }
     buffers_base = (GLuint *)
@@ -3958,6 +4358,9 @@
         _env->ReleasePrimitiveArrayCritical(buffers_ref, buffers_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGenBuffers ( GLsizei n, GLuint *buffers ) */
@@ -3965,6 +4368,8 @@
 android_glGenBuffers__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject buffers_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLuint *buffers = (GLuint *) 0;
@@ -3972,7 +4377,8 @@
     buffers = (GLuint *)getPointer(_env, buffers_buf, &_array, &_remaining);
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < n < needed";
         goto exit;
     }
     glGenBuffers(
@@ -3984,6 +4390,9 @@
     if (_array) {
         releasePointer(_env, _array, buffers, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetBooleanv ( GLenum pname, GLboolean *params ) */
@@ -3991,18 +4400,22 @@
 android_glGetBooleanv__I_3ZI
   (JNIEnv *_env, jobject _this, jint pname, jbooleanArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLboolean *params_base = (GLboolean *) 0;
     jint _remaining;
     GLboolean *params = (GLboolean *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -4020,13 +4433,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetBooleanv ( GLenum pname, GLboolean *params ) */
 static void
 android_glGetBooleanv__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLboolean *params = (GLboolean *) 0;
@@ -4037,7 +4452,7 @@
         (GLboolean *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -4062,18 +4477,22 @@
 android_glGetClipPlanef__I_3FI
   (JNIEnv *_env, jobject _this, jint pname, jfloatArray eqn_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *eqn_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *eqn = (GLfloat *) 0;
 
     if (!eqn_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "eqn == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "eqn == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(eqn_ref) - offset;
@@ -4091,13 +4510,15 @@
         _env->ReleasePrimitiveArrayCritical(eqn_ref, eqn_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetClipPlanef ( GLenum pname, GLfloat *eqn ) */
 static void
 android_glGetClipPlanef__ILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject eqn_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *eqn = (GLfloat *) 0;
@@ -4108,7 +4529,7 @@
         (GLfloat *)eqn
     );
     if (_array) {
-        releasePointer(_env, _array, eqn, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, eqn, JNI_TRUE);
     }
 }
 
@@ -4117,18 +4538,22 @@
 android_glGetClipPlanex__I_3II
   (JNIEnv *_env, jobject _this, jint pname, jintArray eqn_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *eqn_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *eqn = (GLfixed *) 0;
 
     if (!eqn_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "eqn == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "eqn == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(eqn_ref) - offset;
@@ -4146,13 +4571,15 @@
         _env->ReleasePrimitiveArrayCritical(eqn_ref, eqn_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetClipPlanex ( GLenum pname, GLfixed *eqn ) */
 static void
 android_glGetClipPlanex__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject eqn_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *eqn = (GLfixed *) 0;
@@ -4163,7 +4590,7 @@
         (GLfixed *)eqn
     );
     if (_array) {
-        releasePointer(_env, _array, eqn, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, eqn, JNI_TRUE);
     }
 }
 
@@ -4172,18 +4599,22 @@
 android_glGetFixedv__I_3II
   (JNIEnv *_env, jobject _this, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -4201,13 +4632,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetFixedv ( GLenum pname, GLfixed *params ) */
 static void
 android_glGetFixedv__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -4218,7 +4651,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -4227,18 +4660,22 @@
 android_glGetFloatv__I_3FI
   (JNIEnv *_env, jobject _this, jint pname, jfloatArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -4256,13 +4693,15 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetFloatv ( GLenum pname, GLfloat *params ) */
 static void
 android_glGetFloatv__ILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -4273,7 +4712,7 @@
         (GLfloat *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -4282,18 +4721,22 @@
 android_glGetLightfv__II_3FI
   (JNIEnv *_env, jobject _this, jint light, jint pname, jfloatArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -4341,7 +4784,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfloat *)
@@ -4359,6 +4803,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetLightfv ( GLenum light, GLenum pname, GLfloat *params ) */
@@ -4366,6 +4813,8 @@
 android_glGetLightfv__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint light, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -4415,7 +4864,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glGetLightfv(
@@ -4428,6 +4878,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetLightxv ( GLenum light, GLenum pname, GLfixed *params ) */
@@ -4435,18 +4888,22 @@
 android_glGetLightxv__II_3II
   (JNIEnv *_env, jobject _this, jint light, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -4494,7 +4951,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfixed *)
@@ -4512,6 +4970,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetLightxv ( GLenum light, GLenum pname, GLfixed *params ) */
@@ -4519,6 +4980,8 @@
 android_glGetLightxv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint light, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -4568,7 +5031,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glGetLightxv(
@@ -4581,6 +5045,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetMaterialfv ( GLenum face, GLenum pname, GLfloat *params ) */
@@ -4588,18 +5055,22 @@
 android_glGetMaterialfv__II_3FI
   (JNIEnv *_env, jobject _this, jint face, jint pname, jfloatArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -4633,7 +5104,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfloat *)
@@ -4651,6 +5123,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetMaterialfv ( GLenum face, GLenum pname, GLfloat *params ) */
@@ -4658,6 +5133,8 @@
 android_glGetMaterialfv__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint face, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -4693,7 +5170,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glGetMaterialfv(
@@ -4706,6 +5184,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetMaterialxv ( GLenum face, GLenum pname, GLfixed *params ) */
@@ -4713,18 +5194,22 @@
 android_glGetMaterialxv__II_3II
   (JNIEnv *_env, jobject _this, jint face, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -4758,7 +5243,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfixed *)
@@ -4776,6 +5262,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetMaterialxv ( GLenum face, GLenum pname, GLfixed *params ) */
@@ -4783,6 +5272,8 @@
 android_glGetMaterialxv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint face, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -4818,7 +5309,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glGetMaterialxv(
@@ -4831,6 +5323,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexEnviv ( GLenum env, GLenum pname, GLint *params ) */
@@ -4838,18 +5333,22 @@
 android_glGetTexEnviv__II_3II
   (JNIEnv *_env, jobject _this, jint env, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -4877,7 +5376,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLint *)
@@ -4895,6 +5395,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexEnviv ( GLenum env, GLenum pname, GLint *params ) */
@@ -4902,6 +5405,8 @@
 android_glGetTexEnviv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint env, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -4931,7 +5436,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glGetTexEnviv(
@@ -4944,6 +5450,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexEnvxv ( GLenum env, GLenum pname, GLfixed *params ) */
@@ -4951,18 +5460,22 @@
 android_glGetTexEnvxv__II_3II
   (JNIEnv *_env, jobject _this, jint env, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -4990,7 +5503,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLfixed *)
@@ -5008,6 +5522,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexEnvxv ( GLenum env, GLenum pname, GLfixed *params ) */
@@ -5015,6 +5532,8 @@
 android_glGetTexEnvxv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint env, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -5044,7 +5563,8 @@
     }
     if (_remaining < _needed) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glGetTexEnvxv(
@@ -5057,6 +5577,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexParameterfv ( GLenum target, GLenum pname, GLfloat *params ) */
@@ -5064,24 +5587,29 @@
 android_glGetTexParameterfv__II_3FI
   (JNIEnv *_env, jobject _this, jint target, jint pname, jfloatArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLfloat *)
@@ -5099,6 +5627,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexParameterfv ( GLenum target, GLenum pname, GLfloat *params ) */
@@ -5106,6 +5637,8 @@
 android_glGetTexParameterfv__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -5113,7 +5646,8 @@
     params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glGetTexParameterfv(
@@ -5126,6 +5660,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexParameteriv ( GLenum target, GLenum pname, GLint *params ) */
@@ -5133,24 +5670,29 @@
 android_glGetTexParameteriv__II_3II
   (JNIEnv *_env, jobject _this, jint target, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLint *)
@@ -5168,6 +5710,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexParameteriv ( GLenum target, GLenum pname, GLint *params ) */
@@ -5175,6 +5720,8 @@
 android_glGetTexParameteriv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -5182,7 +5729,8 @@
     params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glGetTexParameteriv(
@@ -5195,6 +5743,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexParameterxv ( GLenum target, GLenum pname, GLfixed *params ) */
@@ -5202,24 +5753,29 @@
 android_glGetTexParameterxv__II_3II
   (JNIEnv *_env, jobject _this, jint target, jint pname, jintArray params_ref, jint offset) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLfixed *)
@@ -5237,6 +5793,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexParameterxv ( GLenum target, GLenum pname, GLfixed *params ) */
@@ -5244,6 +5803,8 @@
 android_glGetTexParameterxv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
@@ -5251,7 +5812,8 @@
     params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glGetTexParameterxv(
@@ -5264,6 +5826,9 @@
     if (_array) {
         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* GLboolean glIsBuffer ( GLuint buffer ) */
@@ -5324,21 +5889,30 @@
 static void
 android_glPointParameterfv__I_3FI
   (JNIEnv *_env, jobject _this, jint pname, jfloatArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLfloat *)
@@ -5355,19 +5929,27 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glPointParameterfv ( GLenum pname, const GLfloat *params ) */
 static void
 android_glPointParameterfv__ILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glPointParameterfv(
@@ -5379,6 +5961,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glPointParameterx ( GLenum pname, GLfixed param ) */
@@ -5395,21 +5980,30 @@
 static void
 android_glPointParameterxv__I_3II
   (JNIEnv *_env, jobject _this, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLfixed *)
@@ -5426,19 +6020,27 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glPointParameterxv ( GLenum pname, const GLfixed *params ) */
 static void
 android_glPointParameterxv__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glPointParameterxv(
@@ -5450,6 +6052,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glPointSizePointerOES ( GLenum type, GLsizei stride, const GLvoid *pointer ) */
@@ -5501,16 +6106,23 @@
 static void
 android_glTexEnviv__II_3II
   (JNIEnv *_env, jobject _this, jint target, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -5537,7 +6149,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < needed";
         goto exit;
     }
     params_base = (GLint *)
@@ -5555,12 +6169,18 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexEnviv ( GLenum target, GLenum pname, const GLint *params ) */
 static void
 android_glTexEnviv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -5589,7 +6209,9 @@
             break;
     }
     if (_remaining < _needed) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < needed");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < needed";
         goto exit;
     }
     glTexEnviv(
@@ -5602,27 +6224,39 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexParameterfv ( GLenum target, GLenum pname, const GLfloat *params ) */
 static void
 android_glTexParameterfv__II_3FI
   (JNIEnv *_env, jobject _this, jint target, jint pname, jfloatArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLfloat *)
@@ -5640,19 +6274,27 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexParameterfv ( GLenum target, GLenum pname, const GLfloat *params ) */
 static void
 android_glTexParameterfv__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glTexParameterfv(
@@ -5665,6 +6307,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexParameteri ( GLenum target, GLenum pname, GLint param ) */
@@ -5682,21 +6327,30 @@
 static void
 android_glTexParameteriv__II_3II
   (JNIEnv *_env, jobject _this, jint target, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLint *)
@@ -5714,19 +6368,27 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexParameteriv ( GLenum target, GLenum pname, const GLint *params ) */
 static void
 android_glTexParameteriv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glTexParameteriv(
@@ -5739,27 +6401,39 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexParameterxv ( GLenum target, GLenum pname, const GLfixed *params ) */
 static void
 android_glTexParameterxv__II_3II
   (JNIEnv *_env, jobject _this, jint target, jint pname, jintArray params_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *params_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     if (!params_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 1 < needed";
         goto exit;
     }
     params_base = (GLfixed *)
@@ -5777,19 +6451,27 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexParameterxv ( GLenum target, GLenum pname, const GLfixed *params ) */
 static void
 android_glTexParameterxv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
     params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining);
     if (_remaining < 1) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 1");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
     glTexParameterxv(
@@ -5802,6 +6484,9 @@
     if (_array) {
         releasePointer(_env, _array, params, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glVertexPointer ( GLint size, GLenum type, GLsizei stride, GLint offset ) */
@@ -5842,21 +6527,30 @@
 static void
 android_glDrawTexfvOES___3FI
   (JNIEnv *_env, jobject _this, jfloatArray coords_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *coords_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *coords = (GLfloat *) 0;
 
     if (!coords_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "coords == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "coords == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(coords_ref) - offset;
     if (_remaining < 5) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 5");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 5 < needed";
         goto exit;
     }
     coords_base = (GLfloat *)
@@ -5872,19 +6566,27 @@
         _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDrawTexfvOES ( const GLfloat *coords ) */
 static void
 android_glDrawTexfvOES__Ljava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jobject coords_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *coords = (GLfloat *) 0;
 
     coords = (GLfloat *)getPointer(_env, coords_buf, &_array, &_remaining);
     if (_remaining < 5) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 5");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 5 < needed";
         goto exit;
     }
     glDrawTexfvOES(
@@ -5895,6 +6597,9 @@
     if (_array) {
         releasePointer(_env, _array, coords, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDrawTexiOES ( GLint x, GLint y, GLint z, GLint width, GLint height ) */
@@ -5914,21 +6619,30 @@
 static void
 android_glDrawTexivOES___3II
   (JNIEnv *_env, jobject _this, jintArray coords_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *coords_base = (GLint *) 0;
     jint _remaining;
     GLint *coords = (GLint *) 0;
 
     if (!coords_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "coords == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "coords == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(coords_ref) - offset;
     if (_remaining < 5) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 5");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 5 < needed";
         goto exit;
     }
     coords_base = (GLint *)
@@ -5944,19 +6658,27 @@
         _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDrawTexivOES ( const GLint *coords ) */
 static void
 android_glDrawTexivOES__Ljava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jobject coords_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *coords = (GLint *) 0;
 
     coords = (GLint *)getPointer(_env, coords_buf, &_array, &_remaining);
     if (_remaining < 5) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 5");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 5 < needed";
         goto exit;
     }
     glDrawTexivOES(
@@ -5967,6 +6689,9 @@
     if (_array) {
         releasePointer(_env, _array, coords, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDrawTexsOES ( GLshort x, GLshort y, GLshort z, GLshort width, GLshort height ) */
@@ -5986,21 +6711,30 @@
 static void
 android_glDrawTexsvOES___3SI
   (JNIEnv *_env, jobject _this, jshortArray coords_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLshort *coords_base = (GLshort *) 0;
     jint _remaining;
     GLshort *coords = (GLshort *) 0;
 
     if (!coords_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "coords == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "coords == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(coords_ref) - offset;
     if (_remaining < 5) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 5");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 5 < needed";
         goto exit;
     }
     coords_base = (GLshort *)
@@ -6016,19 +6750,27 @@
         _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDrawTexsvOES ( const GLshort *coords ) */
 static void
 android_glDrawTexsvOES__Ljava_nio_ShortBuffer_2
   (JNIEnv *_env, jobject _this, jobject coords_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLshort *coords = (GLshort *) 0;
 
     coords = (GLshort *)getPointer(_env, coords_buf, &_array, &_remaining);
     if (_remaining < 5) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 5");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 5 < needed";
         goto exit;
     }
     glDrawTexsvOES(
@@ -6039,6 +6781,9 @@
     if (_array) {
         releasePointer(_env, _array, coords, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDrawTexxOES ( GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height ) */
@@ -6058,21 +6803,30 @@
 static void
 android_glDrawTexxvOES___3II
   (JNIEnv *_env, jobject _this, jintArray coords_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfixed *coords_base = (GLfixed *) 0;
     jint _remaining;
     GLfixed *coords = (GLfixed *) 0;
 
     if (!coords_ref) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "coords == null");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "coords == null";
         goto exit;
     }
     if (offset < 0) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(coords_ref) - offset;
     if (_remaining < 5) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < 5");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < 5 < needed";
         goto exit;
     }
     coords_base = (GLfixed *)
@@ -6088,19 +6842,27 @@
         _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
             JNI_ABORT);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDrawTexxvOES ( const GLfixed *coords ) */
 static void
 android_glDrawTexxvOES__Ljava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jobject coords_buf) {
+    jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfixed *coords = (GLfixed *) 0;
 
     coords = (GLfixed *)getPointer(_env, coords_buf, &_array, &_remaining);
     if (_remaining < 5) {
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < 5");
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < 5 < needed";
         goto exit;
     }
     glDrawTexxvOES(
@@ -6111,6 +6873,9 @@
     if (_array) {
         releasePointer(_env, _array, coords, JNI_FALSE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glLoadPaletteFromModelViewMatrixOES ( void ) */
@@ -6273,7 +7038,7 @@
     if (! supportsExtension(_env, _this, have_OES_framebuffer_objectID)) {
         jniThrowException(_env, "java/lang/UnsupportedOperationException",
             "glCheckFramebufferStatusOES");
-            return 0;
+    return 0;
     }
     GLint _returnValue = 0;
     _returnValue = glCheckFramebufferStatusOES(
@@ -6292,24 +7057,29 @@
             return;
     }
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *framebuffers_base = (GLuint *) 0;
     jint _remaining;
     GLuint *framebuffers = (GLuint *) 0;
 
     if (!framebuffers_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "framebuffers == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "framebuffers == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(framebuffers_ref) - offset;
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < n < needed";
         goto exit;
     }
     framebuffers_base = (GLuint *)
@@ -6326,6 +7096,9 @@
         _env->ReleasePrimitiveArrayCritical(framebuffers_ref, framebuffers_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDeleteFramebuffersOES ( GLint n, GLuint *framebuffers ) */
@@ -6338,6 +7111,8 @@
             return;
     }
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLuint *framebuffers = (GLuint *) 0;
@@ -6345,7 +7120,8 @@
     framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, &_array, &_remaining);
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < n < needed";
         goto exit;
     }
     glDeleteFramebuffersOES(
@@ -6357,6 +7133,9 @@
     if (_array) {
         releasePointer(_env, _array, framebuffers, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDeleteRenderbuffersOES ( GLint n, GLuint *renderbuffers ) */
@@ -6369,24 +7148,29 @@
             return;
     }
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *renderbuffers_base = (GLuint *) 0;
     jint _remaining;
     GLuint *renderbuffers = (GLuint *) 0;
 
     if (!renderbuffers_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "renderbuffers == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "renderbuffers == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(renderbuffers_ref) - offset;
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < n < needed";
         goto exit;
     }
     renderbuffers_base = (GLuint *)
@@ -6403,6 +7187,9 @@
         _env->ReleasePrimitiveArrayCritical(renderbuffers_ref, renderbuffers_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glDeleteRenderbuffersOES ( GLint n, GLuint *renderbuffers ) */
@@ -6415,6 +7202,8 @@
             return;
     }
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLuint *renderbuffers = (GLuint *) 0;
@@ -6422,7 +7211,8 @@
     renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, &_array, &_remaining);
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < n < needed";
         goto exit;
     }
     glDeleteRenderbuffersOES(
@@ -6434,6 +7224,9 @@
     if (_array) {
         releasePointer(_env, _array, renderbuffers, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glFramebufferRenderbufferOES ( GLint target, GLint attachment, GLint renderbuffertarget, GLint renderbuffer ) */
@@ -6495,24 +7288,29 @@
             return;
     }
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *framebuffers_base = (GLuint *) 0;
     jint _remaining;
     GLuint *framebuffers = (GLuint *) 0;
 
     if (!framebuffers_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "framebuffers == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "framebuffers == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(framebuffers_ref) - offset;
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < n < needed";
         goto exit;
     }
     framebuffers_base = (GLuint *)
@@ -6529,6 +7327,9 @@
         _env->ReleasePrimitiveArrayCritical(framebuffers_ref, framebuffers_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGenFramebuffersOES ( GLint n, GLuint *framebuffers ) */
@@ -6541,6 +7342,8 @@
             return;
     }
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLuint *framebuffers = (GLuint *) 0;
@@ -6548,7 +7351,8 @@
     framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, &_array, &_remaining);
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < n < needed";
         goto exit;
     }
     glGenFramebuffersOES(
@@ -6560,6 +7364,9 @@
     if (_array) {
         releasePointer(_env, _array, framebuffers, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGenRenderbuffersOES ( GLint n, GLuint *renderbuffers ) */
@@ -6572,24 +7379,29 @@
             return;
     }
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLuint *renderbuffers_base = (GLuint *) 0;
     jint _remaining;
     GLuint *renderbuffers = (GLuint *) 0;
 
     if (!renderbuffers_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "renderbuffers == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "renderbuffers == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(renderbuffers_ref) - offset;
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "length - offset < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "length - offset < n < needed";
         goto exit;
     }
     renderbuffers_base = (GLuint *)
@@ -6606,6 +7418,9 @@
         _env->ReleasePrimitiveArrayCritical(renderbuffers_ref, renderbuffers_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGenRenderbuffersOES ( GLint n, GLuint *renderbuffers ) */
@@ -6618,6 +7433,8 @@
             return;
     }
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLuint *renderbuffers = (GLuint *) 0;
@@ -6625,7 +7442,8 @@
     renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, &_array, &_remaining);
     if (_remaining < n) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "remaining() < n");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < n < needed";
         goto exit;
     }
     glGenRenderbuffersOES(
@@ -6637,6 +7455,9 @@
     if (_array) {
         releasePointer(_env, _array, renderbuffers, _exception ? JNI_FALSE : JNI_TRUE);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetFramebufferAttachmentParameterivOES ( GLint target, GLint attachment, GLint pname, GLint *params ) */
@@ -6649,18 +7470,22 @@
             return;
     }
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -6680,6 +7505,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetFramebufferAttachmentParameterivOES ( GLint target, GLint attachment, GLint pname, GLint *params ) */
@@ -6691,7 +7519,6 @@
             "glGetFramebufferAttachmentParameterivOES");
             return;
     }
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -6704,7 +7531,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -6718,18 +7545,22 @@
             return;
     }
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -6748,6 +7579,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetRenderbufferParameterivOES ( GLint target, GLint pname, GLint *params ) */
@@ -6759,7 +7593,6 @@
             "glGetRenderbufferParameterivOES");
             return;
     }
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -6771,7 +7604,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -6785,18 +7618,22 @@
             return;
     }
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -6815,6 +7652,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexGenfv ( GLint coord, GLint pname, GLfloat *params ) */
@@ -6826,7 +7666,6 @@
             "glGetTexGenfv");
             return;
     }
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -6838,7 +7677,7 @@
         (GLfloat *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -6852,18 +7691,22 @@
             return;
     }
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -6882,6 +7725,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexGeniv ( GLint coord, GLint pname, GLint *params ) */
@@ -6893,7 +7739,6 @@
             "glGetTexGeniv");
             return;
     }
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -6905,7 +7750,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -6919,18 +7764,22 @@
             return;
     }
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -6949,6 +7798,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glGetTexGenxv ( GLint coord, GLint pname, GLint *params ) */
@@ -6960,7 +7812,6 @@
             "glGetTexGenxv");
             return;
     }
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -6972,7 +7823,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -6983,7 +7834,7 @@
     if (! supportsExtension(_env, _this, have_OES_framebuffer_objectID)) {
         jniThrowException(_env, "java/lang/UnsupportedOperationException",
             "glIsFramebufferOES");
-            return JNI_FALSE;
+    return JNI_FALSE;
     }
     GLboolean _returnValue = JNI_FALSE;
     _returnValue = glIsFramebufferOES(
@@ -6999,7 +7850,7 @@
     if (! supportsExtension(_env, _this, have_OES_framebuffer_objectID)) {
         jniThrowException(_env, "java/lang/UnsupportedOperationException",
             "glIsRenderbufferOES");
-            return JNI_FALSE;
+    return JNI_FALSE;
     }
     GLboolean _returnValue = JNI_FALSE;
     _returnValue = glIsRenderbufferOES(
@@ -7051,18 +7902,22 @@
             return;
     }
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLfloat *params_base = (GLfloat *) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -7081,6 +7936,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexGenfv ( GLint coord, GLint pname, GLfloat *params ) */
@@ -7092,7 +7950,6 @@
             "glTexGenfv");
             return;
     }
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
@@ -7104,7 +7961,7 @@
         (GLfloat *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -7134,18 +7991,22 @@
             return;
     }
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -7164,6 +8025,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexGeniv ( GLint coord, GLint pname, GLint *params ) */
@@ -7175,7 +8039,6 @@
             "glTexGeniv");
             return;
     }
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -7187,7 +8050,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
@@ -7217,18 +8080,22 @@
             return;
     }
     jint _exception = 0;
+    const char * _exceptionType;
+    const char * _exceptionMessage;
     GLint *params_base = (GLint *) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
     if (!params_ref) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "params == null");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "params == null";
         goto exit;
     }
     if (offset < 0) {
         _exception = 1;
-        jniThrowException(_env, "java/lang/IllegalArgumentException", "offset < 0");
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
         goto exit;
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
@@ -7247,6 +8114,9 @@
         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
             _exception ? JNI_ABORT: 0);
     }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
 }
 
 /* void glTexGenxv ( GLint coord, GLint pname, GLint *params ) */
@@ -7258,7 +8128,6 @@
             "glTexGenxv");
             return;
     }
-    jint _exception = 0;
     jarray _array = (jarray) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
@@ -7270,7 +8139,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releasePointer(_env, _array, params, JNI_TRUE);
     }
 }
 
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 0c7d4ca..dd29c92 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -78,7 +78,7 @@
     <string name="RestrictedOnAllVoice" msgid="3396963652108151260">"تمام سرویس‎های صدا مسدود هستند."</string>
     <string name="RestrictedOnSms" msgid="8314352327461638897">"سرویس پیامک مسدود شده است."</string>
     <string name="RestrictedOnVoiceData" msgid="996636487106171320">"سرویس‎‎های صدا/داده مسدود شدند."</string>
-    <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"سرویس های صوتی/پیامک مسدود شده اند"</string>
+    <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"سرویس‌های صوتی/پیامک مسدود شده‌اند"</string>
     <string name="RestrictedOnAll" msgid="5643028264466092821">"تمام سرویس‌های صدا/داده/ پیامک مسدود هستند."</string>
     <string name="serviceClassVoice" msgid="1258393812335258019">"صوتی"</string>
     <string name="serviceClassData" msgid="872456782077937893">"داده"</string>
@@ -163,7 +163,7 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"بیشتر از 999"</string>
     <string name="safeMode" msgid="2788228061547930246">"حالت ایمن"</string>
     <string name="android_system_label" msgid="6577375335728551336">"سیستم Android"</string>
-    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"سرویس های غیر رایگان"</string>
+    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"سرویس‌های غیر رایگان"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"انجام کارهایی که برای شما هزینه دارد."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"پیام های شما"</string>
     <string name="permgroupdesc_messages" msgid="7821999071003699236">"پیام کوتاه، ایمیل و دیگر پیامها را بخوانید."</string>
@@ -225,8 +225,8 @@
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"به برنامه اجازه می‎دهد تا کارها را حذف کند و برنامه‎های آنها را متوقف کند. برنامه‎های مخرب می‌توانند در اجرای برنامه‎های دیگر اختلال ایجاد ‎کنند."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"شروع هر نوع فعالیت"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"به برنامه اجازه می‎دهد هر فعالیتی را شروع کند بدون اینکه وضعیت صادرشده یا حفاظت با مجوز در نظر گرفته شود."</string>
-    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"تنظیم سازگاری با صفحه نمایش"</string>
-    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"به برنامه کاربردی اجازه کنترل حالت سازگاری صفحه نمایش برای برنامه‌های دیگر را می‌دهد. برنامه‌های خرابکار ممکن است باعث کارکرد نادرست دیگر برنامه‌ها شوند."</string>
+    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"تنظیم سازگاری با صفحهٔ نمایش"</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"به برنامه کاربردی اجازه کنترل حالت سازگاری صفحهٔ نمایش برای برنامه‌های دیگر را می‌دهد. برنامه‌های خرابکار ممکن است باعث کارکرد نادرست دیگر برنامه‌ها شوند."</string>
     <string name="permlab_setDebugApp" msgid="3022107198686584052">"فعال کردن عیب‌یابی برنامه"</string>
     <string name="permdesc_setDebugApp" msgid="4474512416299013256">"به برنامه اجازه می‎دهد تا عیب‌یابی را برای برنامه‌ای دیگر فعال کند. برنامه‎های مخرب می‎توانند از آن استفاده کنند تا اجرای برنامه‎های دیگر را متوقف کنند."</string>
     <string name="permlab_changeConfiguration" msgid="4162092185124234480">"تغییر تنظیمات نمایشگر سیستم"</string>
@@ -258,7 +258,7 @@
     <string name="permlab_setProcessLimit" msgid="2451873664363662666">"محدود کردن تعداد فرآیندهای در حال اجرا"</string>
     <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"به برنامه اجازه می‎دهد تا حداکثر تعداد پردازشهایی را که اجرا خواهد شد کنترل کند. هرگز برای برنامه‎های عادی لازم نیست."</string>
     <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"بستن اجباری برنامه‌های پس‌زمینه"</string>
-    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"به برنامه اجازه می‎دهد تا به محض اینکه فعالیتها به پس زمینه رفتند تمام شوند. برای برنامه‎های عادی نیازی نیست."</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"به برنامه اجازه می‎دهد تا به محض اینکه فعالیتها به پس‌زمینه رفتند تمام شوند. برای برنامه‎های عادی نیازی نیست."</string>
     <string name="permlab_batteryStats" msgid="7863923071360031652">"اصلاح کردن آمار مربوط به باتری"</string>
     <string name="permdesc_batteryStats" msgid="6835186932305744068">"به برنامه اجازه می‎دهد تا آمار جمع آوری شده باتری را تغییر دهد. برای استفاده برنامه‎های عادی نیست."</string>
     <string name="permlab_backup" msgid="470013022865453920">"کنترل نسخه پشتیبان سیستم و بازیابی"</string>
@@ -336,7 +336,7 @@
     <string name="permdesc_writeSettings" msgid="7775723441558907181">"به برنامه اجازه می‎دهد تا داده‎های تنظیم سیستم را تغییر دهد. برنامه‎های مخرب می‎توانند پیکربندی سیستم شما را خراب کنند."</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"اصلاح کردن تنظیمات سیستم ایمن"</string>
     <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"به برنامه اجازه می‎دهد داده‎های تنظیمات امنیتی سیستم را تغییر دهد. برای استفاده برنامه‎های عادی نیست."</string>
-    <string name="permlab_writeGservices" msgid="2149426664226152185">"اصلاح کردن نقشه سرویس های Google"</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"اصلاح کردن نقشه سرویس‌های Google"</string>
     <string name="permdesc_writeGservices" msgid="1287309437638380229">"به برنامه اجازه می‎دهد تا نقشه سرویس‌های Google را تغییر دهد. برای استفاده برنامه‎های عادی نیست."</string>
     <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"اجرا هنگام راه‌اندازی"</string>
     <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"به برنامه اجازه می‎دهد تا به محض اتمام راه‎اندازی سیستم خودبخود شروع به کار کند. این کار ممکن است باعث شود مدت زمان بیشتری صرف شدوع به کار رایانه لوحی شود و به برنامه اجازه می‎دهد تا با اجرای همیشگی رایانه لوحی را کند کند."</string>
@@ -432,7 +432,7 @@
     <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"راه اندازی مستقیم تنظیم رایانه لوحی CDMA"</string>
     <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"شروع مستقیم راه اندازی تلفن CDMA"</string>
     <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"به برنامه اجازه می‎دهد تا شرایط مقررات CDMA را شروع کند. برنامه‎های مخرب می‎توانند شرایط مقررات CDMA را در مواقع غیرضروری شروع کند."</string>
-    <string name="permlab_locationUpdates" msgid="7785408253364335740">"کنترل اعلان های به روز رسانی مکان"</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"کنترل اعلان های به‌روزرسانی مکان"</string>
     <string name="permdesc_locationUpdates" msgid="1120741557891438876">"به برنامه اجازه می‎دهد اعلانهای به‎روزرسانی موقعیت مکانی را از رادیو فعال/غیرفعال کند. برای استفاده برنامه‎های عادی نیست."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"دسترسی به مشخصات اعلام ورود"</string>
     <string name="permdesc_checkinProperties" msgid="4024526968630194128">"به برنامه اجازه می‎دهد دسترسی به ویژگیهای بارگذاری شده توسط سرویسهای ورود را بخواند/بنویسد. برای استفاده برنامه‎های عادی مورد نیاز نیست."</string>
@@ -486,8 +486,8 @@
     <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"به برنامه اجازه می‎دهد تا وضعیت اتصال شبکه را تغییر دهد."</string>
     <string name="permlab_changeTetherState" msgid="5952584964373017960">"تغییر قابلیت اتصال داده با سیم"</string>
     <string name="permdesc_changeTetherState" msgid="1524441344412319780">"به برنامه اجازه می‎دهد تا وضعیت اتصال شبکه اتصال داده با سیم را تغییر دهد."</string>
-    <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"تغییر تنظیمات میزان استفاده داده در پس زمینه"</string>
-    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"به برنامه اجازه می‎دهد تا تنظیم کاربرد داده‎های پس زمینه را تغییر دهد."</string>
+    <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"تغییر تنظیمات میزان استفاده داده در پس‌زمینه"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"به برنامه اجازه می‎دهد تا تنظیم کاربرد داده‎های پس‌زمینه را تغییر دهد."</string>
     <string name="permlab_accessWifiState" msgid="5202012949247040011">"مشاهده اتصالات Wi-Fi"</string>
     <string name="permdesc_accessWifiState" msgid="5002798077387803726">"به برنامه امکان می‌دهد اطلاعات مربوط به شبکه Wi-Fi را مشاهده کند، به عنوان مثال فعال بودن Wi-Fi و نام دستگاه‌های Wi-Fi متصل."</string>
     <string name="permlab_changeWifiState" msgid="6550641188749128035">"اتصال به Wi-Fi و قطع اتصال از آن"</string>
@@ -674,7 +674,7 @@
     <string name="relationTypeSister" msgid="1735983554479076481">"خواهر"</string>
     <string name="relationTypeSpouse" msgid="394136939428698117">"همسر"</string>
     <string name="sipAddressTypeCustom" msgid="2473580593111590945">"سفارشی"</string>
-    <string name="sipAddressTypeHome" msgid="6093598181069359295">"صفحه اصلی"</string>
+    <string name="sipAddressTypeHome" msgid="6093598181069359295">"صفحهٔ اصلی"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"محل کار"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"سایر موارد"</string>
     <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"پین کد را وارد کنید"</string>
@@ -698,7 +698,7 @@
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"دوباره امتحان کنید"</string>
     <string name="lockscreen_password_wrong" msgid="5737815393253165301">"دوباره امتحان کنید"</string>
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"دفعات تلاش برای Face Unlock از حداکثر مجاز بیشتر شد"</string>
-    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"در حال شارژ،<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"در حال شارژ، <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="lockscreen_charged" msgid="4938930459620989972">"شارژ شد."</string>
     <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="lockscreen_low_battery" msgid="1482873981919249740">"شارژر خود را متصل کنید."</string>
@@ -1244,9 +1244,9 @@
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"برای بازگشایی قفل، بلغزانید."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"برای شنیدن کلیدهای گذرواژه که با صدای بلند خوانده می‌شوند، هدست را وصل کنید."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"نقطه."</string>
-    <string name="action_bar_home_description" msgid="5293600496601490216">"رفتن به صفحه اصلی"</string>
+    <string name="action_bar_home_description" msgid="5293600496601490216">"رفتن به صفحهٔ اصلی"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"حرکت به بالا"</string>
-    <string name="action_menu_overflow_description" msgid="2295659037509008453">"سایر گزینه ها"</string>
+    <string name="action_menu_overflow_description" msgid="2295659037509008453">"سایر گزینه‌ها"</string>
     <string name="storage_internal" msgid="4891916833657929263">"حافظه داخلی"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"کارت SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"حافظه USB"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 31bda10..dc01b63 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -434,8 +434,8 @@
     <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Mengizinkan apl memulai penyediaan CDMA. Apl berbahaya dapat memulai penyediaan CDMA yang tidak perlu."</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"mengontrol pemberitahuan pembaruan lokasi"</string>
     <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Mengizinkan apl mengaktifkan/menonaktifkan pemberitahuan pembaruan lokasi dari radio. Tidak untuk digunakan oleh apl normal."</string>
-    <string name="permlab_checkinProperties" msgid="7855259461268734914">"akses properti lapor masuk"</string>
-    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Mengizinkan apl membaca/menulis akses ke properti yang diunggah oleh layanan lapor masuk. Tidak untuk digunakan oleh apl normal."</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"akses properti check in"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Mengizinkan apl membaca/menulis akses ke properti yang diunggah oleh layanan check in. Tidak untuk digunakan oleh apl normal."</string>
     <string name="permlab_bindGadget" msgid="776905339015863471">"pilih widget"</string>
     <string name="permdesc_bindGadget" msgid="8261326938599049290">"Mengizinkan apl memberi tahu sistem tentang widget mana yang dapat digunakan oleh suatu apl. Apl dengan izin ini dapat memberikan akses ke data pribadi untuk apl lain. Tidak untuk digunakan oleh apl normal."</string>
     <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"ubah kondisi ponsel"</string>
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/data/fonts/AndroidEmoji.ttf b/data/fonts/AndroidEmoji.ttf
index 4c017d5..92bf047 100644
--- a/data/fonts/AndroidEmoji.ttf
+++ b/data/fonts/AndroidEmoji.ttf
Binary files differ
diff --git a/docs/html/guide/google/gcm/gcm.jd b/docs/html/guide/google/gcm/gcm.jd
index d871fb4..3884244 100644
--- a/docs/html/guide/google/gcm/gcm.jd
+++ b/docs/html/guide/google/gcm/gcm.jd
@@ -620,7 +620,7 @@
 Authorization:key=AIzaSyB-1uEai2WiUapxCs2Q0GZYzPu7Udno5aA
 
 {
-  "registration_id" : "APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...",
+  "registration_ids" : ["APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx..."],
   "data" : {
     ...
   },
@@ -874,7 +874,10 @@
   <li>Implement exponential back-off in your retry mechanism. This means an exponentially increasing delay after each failed retry (e.g. if you waited one second before the first retry, wait at least two second before the next one, then 4 seconds and so on). If you're sending multiple messages, delay each one independently by an additional random amount to avoid issuing a new request for all messages at the same time.</li>
 </ul>
 Senders that cause problems risk being blacklisted.
-<br/>Happens when the HTTP status code is 500 or 503; or when the <code>error</code> field of a JSON object in the <code>results</code> array is <code>Unavailable</code>.
+<br/>Happens when the HTTP status code is 500 or 503, or when the <code>error</code> field of a JSON object in the <code>results</code> array is <code>InternalServerError</code> or <code>Unavailable</code>.</dd>
+
+<dt id="ttl_error"><strong>Invalid Time To Live</strong></dt>
+  <dd>The value for the Time to Live field must be an integer representing a duration in seconds between 0 and 2,419,200 (4 weeks). Happens when error code is <code>InvalidTtl</code>.
 </dd>
 </dl>
 <h4>Example responses</h4>
diff --git a/docs/html/tools/adk/adk2.jd b/docs/html/tools/adk/adk2.jd
index ee9c0d8..d5be8ab 100644
--- a/docs/html/tools/adk/adk2.jd
+++ b/docs/html/tools/adk/adk2.jd
@@ -26,10 +26,12 @@
 
     <h2>See also</h2>
     <ol>
+      <li><a href="https://developers.google.com/events/io/sessions/gooio2012/128/">
+        Google I/O Session Video</a></li>
       <li><a href="aoa.html">Android Open Accessory Protocol</a></li>
       <li><a href="aoa2.html">Android Open Accessory Protocol 2.0</a></li>
-      <li><a href="{@docRoot}guide/topics/connectivity/usb/accessory.html">USB Accessory Dev
-      Guide</a></li>
+      <li><a href="{@docRoot}guide/topics/connectivity/usb/accessory.html">
+        USB Accessory Dev Guide</a></li>
     </ol>
   </div>
 </div>
@@ -231,7 +233,12 @@
 system.</li>
   <li>Download and setup the {@code repo} tool, as described on the <a
 href="http://source.android.com/source/downloading.html#installing-repo">Android open source
-project</a> site.</li>
+project</a> site.
+    <p class="note"><strong>Note:</strong> Developers using Windows must use a Linux compatibility
+package, such as <a href="http://www.cygwin.com/">cygwin</a>, to install and run {@code repo}.
+Within your compatibility environment, you must install {@code curl}, {@code git} and {@code
+python} to be able to download and use the {@code repo} tool.</p>
+  </li>
   <li>In a terminal window, create a new directory for the downloaded source files, initialize and
 synchronize a local repository:
 <pre>
@@ -268,7 +275,7 @@
     href="http://java.oracle.com">java.oracle.com</a>.</li>
   <li>Download the ADK 2012 IDE for your development platform:
     <ul>
-      <li><a href="https://dl-ssl.google.com/android/adk/adk2012_ide-win32-20120626.zip">
+      <li><a href="https://dl-ssl.google.com/android/adk/adk2012_ide-win32-20120629.zip">
           Windows</a></li>
       <li><a href="https://dl-ssl.google.com/android/adk/adk2012_ide-macosx-20120626.zip">
           Mac</a></li>
diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h
index 8f3a0a3..531aa5b 100644
--- a/libs/hwui/LayerRenderer.h
+++ b/libs/hwui/LayerRenderer.h
@@ -61,12 +61,13 @@
             bool isOpaque, GLenum renderTarget, float* transform);
     ANDROID_API static void destroyLayer(Layer* layer);
     ANDROID_API static void destroyLayerDeferred(Layer* layer);
-    ANDROID_API static void flushLayer(Layer* layer);
     ANDROID_API static bool copyLayer(Layer* layer, SkBitmap* bitmap);
 
 private:
     void generateMesh();
 
+    static void flushLayer(Layer* layer);
+
     Layer* mLayer;
 }; // class LayerRenderer
 
diff --git a/opengl/java/android/opengl/EGL14.java b/opengl/java/android/opengl/EGL14.java
new file mode 100644
index 0000000..31fc04a
--- /dev/null
+++ b/opengl/java/android/opengl/EGL14.java
@@ -0,0 +1,446 @@
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+// This source file is automatically generated
+
+package android.opengl;
+
+import android.graphics.SurfaceTexture;
+import android.view.Surface;
+import android.view.SurfaceView;
+import android.view.SurfaceHolder;
+
+
+/**
+* @hide
+*/
+public class EGL14 {
+
+public static final int EGL_DEFAULT_DISPLAY            = 0;
+public static EGLContext EGL_NO_CONTEXT                = null;
+public static EGLDisplay EGL_NO_DISPLAY                = null;
+public static EGLSurface EGL_NO_SURFACE                = null;
+
+public static final int EGL_FALSE                          = 0;
+public static final int EGL_TRUE                           = 1;
+public static final int EGL_SUCCESS                        = 0x3000;
+public static final int EGL_NOT_INITIALIZED                = 0x3001;
+public static final int EGL_BAD_ACCESS                     = 0x3002;
+public static final int EGL_BAD_ALLOC                      = 0x3003;
+public static final int EGL_BAD_ATTRIBUTE                  = 0x3004;
+public static final int EGL_BAD_CONFIG                     = 0x3005;
+public static final int EGL_BAD_CONTEXT                    = 0x3006;
+public static final int EGL_BAD_CURRENT_SURFACE            = 0x3007;
+public static final int EGL_BAD_DISPLAY                    = 0x3008;
+public static final int EGL_BAD_MATCH                      = 0x3009;
+public static final int EGL_BAD_NATIVE_PIXMAP              = 0x300A;
+public static final int EGL_BAD_NATIVE_WINDOW              = 0x300B;
+public static final int EGL_BAD_PARAMETER                  = 0x300C;
+public static final int EGL_BAD_SURFACE                    = 0x300D;
+public static final int EGL_CONTEXT_LOST                   = 0x300E;
+public static final int EGL_BUFFER_SIZE                    = 0x3020;
+public static final int EGL_ALPHA_SIZE                     = 0x3021;
+public static final int EGL_BLUE_SIZE                      = 0x3022;
+public static final int EGL_GREEN_SIZE                     = 0x3023;
+public static final int EGL_RED_SIZE                       = 0x3024;
+public static final int EGL_DEPTH_SIZE                     = 0x3025;
+public static final int EGL_STENCIL_SIZE                   = 0x3026;
+public static final int EGL_CONFIG_CAVEAT                  = 0x3027;
+public static final int EGL_CONFIG_ID                      = 0x3028;
+public static final int EGL_LEVEL                          = 0x3029;
+public static final int EGL_MAX_PBUFFER_HEIGHT             = 0x302A;
+public static final int EGL_MAX_PBUFFER_PIXELS             = 0x302B;
+public static final int EGL_MAX_PBUFFER_WIDTH              = 0x302C;
+public static final int EGL_NATIVE_RENDERABLE              = 0x302D;
+public static final int EGL_NATIVE_VISUAL_ID               = 0x302E;
+public static final int EGL_NATIVE_VISUAL_TYPE             = 0x302F;
+public static final int EGL_SAMPLES                        = 0x3031;
+public static final int EGL_SAMPLE_BUFFERS                 = 0x3032;
+public static final int EGL_SURFACE_TYPE                   = 0x3033;
+public static final int EGL_TRANSPARENT_TYPE               = 0x3034;
+public static final int EGL_TRANSPARENT_BLUE_VALUE         = 0x3035;
+public static final int EGL_TRANSPARENT_GREEN_VALUE        = 0x3036;
+public static final int EGL_TRANSPARENT_RED_VALUE          = 0x3037;
+public static final int EGL_NONE                           = 0x3038;
+public static final int EGL_BIND_TO_TEXTURE_RGB            = 0x3039;
+public static final int EGL_BIND_TO_TEXTURE_RGBA           = 0x303A;
+public static final int EGL_MIN_SWAP_INTERVAL              = 0x303B;
+public static final int EGL_MAX_SWAP_INTERVAL              = 0x303C;
+public static final int EGL_LUMINANCE_SIZE                 = 0x303D;
+public static final int EGL_ALPHA_MASK_SIZE                = 0x303E;
+public static final int EGL_COLOR_BUFFER_TYPE              = 0x303F;
+public static final int EGL_RENDERABLE_TYPE                = 0x3040;
+public static final int EGL_MATCH_NATIVE_PIXMAP            = 0x3041;
+public static final int EGL_CONFORMANT                     = 0x3042;
+public static final int EGL_SLOW_CONFIG                    = 0x3050;
+public static final int EGL_NON_CONFORMANT_CONFIG          = 0x3051;
+public static final int EGL_TRANSPARENT_RGB                = 0x3052;
+public static final int EGL_RGB_BUFFER                     = 0x308E;
+public static final int EGL_LUMINANCE_BUFFER               = 0x308F;
+public static final int EGL_NO_TEXTURE                     = 0x305C;
+public static final int EGL_TEXTURE_RGB                    = 0x305D;
+public static final int EGL_TEXTURE_RGBA                   = 0x305E;
+public static final int EGL_TEXTURE_2D                     = 0x305F;
+public static final int EGL_PBUFFER_BIT                    = 0x0001;
+public static final int EGL_PIXMAP_BIT                     = 0x0002;
+public static final int EGL_WINDOW_BIT                     = 0x0004;
+public static final int EGL_VG_COLORSPACE_LINEAR_BIT       = 0x0020;
+public static final int EGL_VG_ALPHA_FORMAT_PRE_BIT        = 0x0040;
+public static final int EGL_MULTISAMPLE_RESOLVE_BOX_BIT    = 0x0200;
+public static final int EGL_SWAP_BEHAVIOR_PRESERVED_BIT    = 0x0400;
+public static final int EGL_OPENGL_ES_BIT                  = 0x0001;
+public static final int EGL_OPENVG_BIT                     = 0x0002;
+public static final int EGL_OPENGL_ES2_BIT                 = 0x0004;
+public static final int EGL_OPENGL_BIT                     = 0x0008;
+public static final int EGL_VENDOR                         = 0x3053;
+public static final int EGL_VERSION                        = 0x3054;
+public static final int EGL_EXTENSIONS                     = 0x3055;
+public static final int EGL_CLIENT_APIS                    = 0x308D;
+public static final int EGL_HEIGHT                         = 0x3056;
+public static final int EGL_WIDTH                          = 0x3057;
+public static final int EGL_LARGEST_PBUFFER                = 0x3058;
+public static final int EGL_TEXTURE_FORMAT                 = 0x3080;
+public static final int EGL_TEXTURE_TARGET                 = 0x3081;
+public static final int EGL_MIPMAP_TEXTURE                 = 0x3082;
+public static final int EGL_MIPMAP_LEVEL                   = 0x3083;
+public static final int EGL_RENDER_BUFFER                  = 0x3086;
+public static final int EGL_VG_COLORSPACE                  = 0x3087;
+public static final int EGL_VG_ALPHA_FORMAT                = 0x3088;
+public static final int EGL_HORIZONTAL_RESOLUTION          = 0x3090;
+public static final int EGL_VERTICAL_RESOLUTION            = 0x3091;
+public static final int EGL_PIXEL_ASPECT_RATIO             = 0x3092;
+public static final int EGL_SWAP_BEHAVIOR                  = 0x3093;
+public static final int EGL_MULTISAMPLE_RESOLVE            = 0x3099;
+public static final int EGL_BACK_BUFFER                    = 0x3084;
+public static final int EGL_SINGLE_BUFFER                  = 0x3085;
+public static final int EGL_VG_COLORSPACE_sRGB             = 0x3089;
+public static final int EGL_VG_COLORSPACE_LINEAR           = 0x308A;
+public static final int EGL_VG_ALPHA_FORMAT_NONPRE         = 0x308B;
+public static final int EGL_VG_ALPHA_FORMAT_PRE            = 0x308C;
+public static final int EGL_DISPLAY_SCALING                = 10000;
+public static final int EGL_BUFFER_PRESERVED               = 0x3094;
+public static final int EGL_BUFFER_DESTROYED               = 0x3095;
+public static final int EGL_OPENVG_IMAGE                   = 0x3096;
+public static final int EGL_CONTEXT_CLIENT_TYPE            = 0x3097;
+public static final int EGL_CONTEXT_CLIENT_VERSION         = 0x3098;
+public static final int EGL_MULTISAMPLE_RESOLVE_DEFAULT    = 0x309A;
+public static final int EGL_MULTISAMPLE_RESOLVE_BOX        = 0x309B;
+public static final int EGL_OPENGL_ES_API                  = 0x30A0;
+public static final int EGL_OPENVG_API                     = 0x30A1;
+public static final int EGL_OPENGL_API                     = 0x30A2;
+public static final int EGL_DRAW                           = 0x3059;
+public static final int EGL_READ                           = 0x305A;
+public static final int EGL_CORE_NATIVE_ENGINE             = 0x305B;
+
+    native private static void _nativeClassInit();
+    static {
+        _nativeClassInit();
+    }
+    /* @hide C function EGLint eglGetError ( void ) */
+
+    public static native int eglGetError(
+    );
+
+    /* @hide C function EGLDisplay eglGetDisplay ( EGLNativeDisplayType display_id ) */
+
+    public static native EGLDisplay eglGetDisplay(
+        int display_id
+    );
+
+    /* @hide C function EGLBoolean eglInitialize ( EGLDisplay dpy, EGLint *major, EGLint *minor ) */
+
+    public static native boolean eglInitialize(
+        EGLDisplay dpy,
+        int[] major,
+        int majorOffset,
+        int[] minor,
+        int minorOffset
+    );
+
+    /* @hide C function EGLBoolean eglTerminate ( EGLDisplay dpy ) */
+
+    public static native boolean eglTerminate(
+        EGLDisplay dpy
+    );
+
+    // C function const char * eglQueryString ( EGLDisplay dpy, EGLint name )
+
+    public static native String eglQueryString(
+        EGLDisplay dpy,
+        int name
+    );
+    /* @hide C function EGLBoolean eglGetConfigs ( EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config ) */
+
+    public static native boolean eglGetConfigs(
+        EGLDisplay dpy,
+        EGLConfig[] configs,
+        int configsOffset,
+        int config_size,
+        int[] num_config,
+        int num_configOffset
+    );
+
+    /* @hide C function EGLBoolean eglChooseConfig ( EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config ) */
+
+    public static native boolean eglChooseConfig(
+        EGLDisplay dpy,
+        int[] attrib_list,
+        int attrib_listOffset,
+        EGLConfig[] configs,
+        int configsOffset,
+        int config_size,
+        int[] num_config,
+        int num_configOffset
+    );
+
+    /* @hide C function EGLBoolean eglGetConfigAttrib ( EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value ) */
+
+    public static native boolean eglGetConfigAttrib(
+        EGLDisplay dpy,
+        EGLConfig config,
+        int attribute,
+        int[] value,
+        int offset
+    );
+
+    // C function EGLSurface eglCreateWindowSurface ( EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list )
+
+    private static native EGLSurface _eglCreateWindowSurface(
+        EGLDisplay dpy,
+        EGLConfig config,
+        Object win,
+        int[] attrib_list,
+        int offset
+    );
+
+    private static native EGLSurface _eglCreateWindowSurfaceTexture(
+        EGLDisplay dpy,
+        EGLConfig config,
+        Object win,
+        int[] attrib_list,
+        int offset
+    );
+
+    public static EGLSurface eglCreateWindowSurface(EGLDisplay dpy,
+        EGLConfig config,
+        Object win,
+        int[] attrib_list,
+        int offset
+    ){
+        Surface sur = null;
+        if (win instanceof SurfaceView) {
+            SurfaceView surfaceView = (SurfaceView)win;
+            sur = surfaceView.getHolder().getSurface();
+        } else if (win instanceof SurfaceHolder) {
+            SurfaceHolder holder = (SurfaceHolder)win;
+            sur = holder.getSurface();
+        }
+
+        EGLSurface surface;
+        if (sur != null) {
+            surface = _eglCreateWindowSurface(dpy, config, sur, attrib_list, offset);
+        } else if (win instanceof SurfaceTexture) {
+            surface = _eglCreateWindowSurfaceTexture(dpy, config,
+                    win, attrib_list, offset);
+        } else {
+            throw new java.lang.UnsupportedOperationException(
+                "eglCreateWindowSurface() can only be called with an instance of " +
+                "SurfaceView, SurfaceTexture or SurfaceHolder at the moment, " +
+                "this will be fixed later.");
+        }
+
+        return surface;
+    }
+    /* @hide C function EGLSurface eglCreatePbufferSurface ( EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list ) */
+
+    public static native EGLSurface eglCreatePbufferSurface(
+        EGLDisplay dpy,
+        EGLConfig config,
+        int[] attrib_list,
+        int offset
+    );
+
+    /* @hide C function EGLSurface eglCreatePixmapSurface ( EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list ) */
+
+    public static native EGLSurface eglCreatePixmapSurface(
+        EGLDisplay dpy,
+        EGLConfig config,
+        int pixmap,
+        int[] attrib_list,
+        int offset
+    );
+
+    /* @hide C function EGLBoolean eglDestroySurface ( EGLDisplay dpy, EGLSurface surface ) */
+
+    public static native boolean eglDestroySurface(
+        EGLDisplay dpy,
+        EGLSurface surface
+    );
+
+    /* @hide C function EGLBoolean eglQuerySurface ( EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value ) */
+
+    public static native boolean eglQuerySurface(
+        EGLDisplay dpy,
+        EGLSurface surface,
+        int attribute,
+        int[] value,
+        int offset
+    );
+
+    /* @hide C function EGLBoolean eglBindAPI ( EGLenum api ) */
+
+    public static native boolean eglBindAPI(
+        int api
+    );
+
+    /* @hide C function EGLenum eglQueryAPI ( void ) */
+
+    public static native int eglQueryAPI(
+    );
+
+    /* @hide C function EGLBoolean eglWaitClient ( void ) */
+
+    public static native boolean eglWaitClient(
+    );
+
+    /* @hide C function EGLBoolean eglReleaseThread ( void ) */
+
+    public static native boolean eglReleaseThread(
+    );
+
+    /* @hide C function EGLSurface eglCreatePbufferFromClientBuffer ( EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list ) */
+
+    public static native EGLSurface eglCreatePbufferFromClientBuffer(
+        EGLDisplay dpy,
+        int buftype,
+        int buffer,
+        EGLConfig config,
+        int[] attrib_list,
+        int offset
+    );
+
+    /* @hide C function EGLBoolean eglSurfaceAttrib ( EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value ) */
+
+    public static native boolean eglSurfaceAttrib(
+        EGLDisplay dpy,
+        EGLSurface surface,
+        int attribute,
+        int value
+    );
+
+    /* @hide C function EGLBoolean eglBindTexImage ( EGLDisplay dpy, EGLSurface surface, EGLint buffer ) */
+
+    public static native boolean eglBindTexImage(
+        EGLDisplay dpy,
+        EGLSurface surface,
+        int buffer
+    );
+
+    /* @hide C function EGLBoolean eglReleaseTexImage ( EGLDisplay dpy, EGLSurface surface, EGLint buffer ) */
+
+    public static native boolean eglReleaseTexImage(
+        EGLDisplay dpy,
+        EGLSurface surface,
+        int buffer
+    );
+
+    /* @hide C function EGLBoolean eglSwapInterval ( EGLDisplay dpy, EGLint interval ) */
+
+    public static native boolean eglSwapInterval(
+        EGLDisplay dpy,
+        int interval
+    );
+
+    /* @hide C function EGLContext eglCreateContext ( EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list ) */
+
+    public static native EGLContext eglCreateContext(
+        EGLDisplay dpy,
+        EGLConfig config,
+        EGLContext share_context,
+        int[] attrib_list,
+        int offset
+    );
+
+    /* @hide C function EGLBoolean eglDestroyContext ( EGLDisplay dpy, EGLContext ctx ) */
+
+    public static native boolean eglDestroyContext(
+        EGLDisplay dpy,
+        EGLContext ctx
+    );
+
+    /* @hide C function EGLBoolean eglMakeCurrent ( EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx ) */
+
+    public static native boolean eglMakeCurrent(
+        EGLDisplay dpy,
+        EGLSurface draw,
+        EGLSurface read,
+        EGLContext ctx
+    );
+
+    /* @hide C function EGLContext eglGetCurrentContext ( void ) */
+
+    public static native EGLContext eglGetCurrentContext(
+    );
+
+    /* @hide C function EGLSurface eglGetCurrentSurface ( EGLint readdraw ) */
+
+    public static native EGLSurface eglGetCurrentSurface(
+        int readdraw
+    );
+
+    /* @hide C function EGLDisplay eglGetCurrentDisplay ( void ) */
+
+    public static native EGLDisplay eglGetCurrentDisplay(
+    );
+
+    /* @hide C function EGLBoolean eglQueryContext ( EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value ) */
+
+    public static native boolean eglQueryContext(
+        EGLDisplay dpy,
+        EGLContext ctx,
+        int attribute,
+        int[] value,
+        int offset
+    );
+
+    /* @hide C function EGLBoolean eglWaitGL ( void ) */
+
+    public static native boolean eglWaitGL(
+    );
+
+    /* @hide C function EGLBoolean eglWaitNative ( EGLint engine ) */
+
+    public static native boolean eglWaitNative(
+        int engine
+    );
+
+    /* @hide C function EGLBoolean eglSwapBuffers ( EGLDisplay dpy, EGLSurface surface ) */
+
+    public static native boolean eglSwapBuffers(
+        EGLDisplay dpy,
+        EGLSurface surface
+    );
+
+    /* @hide C function EGLBoolean eglCopyBuffers ( EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target ) */
+
+    public static native boolean eglCopyBuffers(
+        EGLDisplay dpy,
+        EGLSurface surface,
+        int target
+    );
+
+}
diff --git a/opengl/java/android/opengl/EGLConfig.java b/opengl/java/android/opengl/EGLConfig.java
new file mode 100644
index 0000000..d9aebfc
--- /dev/null
+++ b/opengl/java/android/opengl/EGLConfig.java
@@ -0,0 +1,41 @@
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.opengl;
+
+/**
+ * @hide
+ */
+public class EGLConfig extends EGLObjectHandle {
+    public EGLConfig(int handle) {
+        super(handle);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        EGLConfig that = (EGLConfig) o;
+        return getHandle() == that.getHandle();
+    }
+
+    @Override
+    public int hashCode() {
+        return getHandle();
+    }
+}
diff --git a/opengl/java/android/opengl/EGLContext.java b/opengl/java/android/opengl/EGLContext.java
new file mode 100644
index 0000000..7b194f3
--- /dev/null
+++ b/opengl/java/android/opengl/EGLContext.java
@@ -0,0 +1,41 @@
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.opengl;
+
+/**
+ * @hide
+ */
+public class EGLContext extends EGLObjectHandle {
+    public EGLContext(int handle) {
+        super(handle);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        EGLContext that = (EGLContext) o;
+        return getHandle() == that.getHandle();
+    }
+
+    @Override
+    public int hashCode() {
+        return getHandle();
+    }
+}
diff --git a/opengl/java/android/opengl/EGLDisplay.java b/opengl/java/android/opengl/EGLDisplay.java
new file mode 100644
index 0000000..a090cf0
--- /dev/null
+++ b/opengl/java/android/opengl/EGLDisplay.java
@@ -0,0 +1,41 @@
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.opengl;
+
+/**
+ * @hide
+ */
+public class EGLDisplay extends EGLObjectHandle {
+    public EGLDisplay(int handle) {
+        super(handle);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        EGLDisplay that = (EGLDisplay) o;
+        return getHandle() == that.getHandle();
+    }
+
+    @Override
+    public int hashCode() {
+        return getHandle();
+    }
+}
diff --git a/opengl/java/android/opengl/EGLObjectHandle.java b/opengl/java/android/opengl/EGLObjectHandle.java
new file mode 100644
index 0000000..01f9bd4
--- /dev/null
+++ b/opengl/java/android/opengl/EGLObjectHandle.java
@@ -0,0 +1,33 @@
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.opengl;
+
+/**
+ * @hide
+ */
+public abstract class EGLObjectHandle {
+    private final int mHandle;
+
+    public EGLObjectHandle(int handle) {
+        mHandle = handle;
+    }
+
+    public int getHandle() {
+        return mHandle;
+    }
+}
diff --git a/opengl/java/android/opengl/EGLSurface.java b/opengl/java/android/opengl/EGLSurface.java
new file mode 100644
index 0000000..4800a64
--- /dev/null
+++ b/opengl/java/android/opengl/EGLSurface.java
@@ -0,0 +1,41 @@
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.opengl;
+
+/**
+ * @hide
+ */
+public class EGLSurface extends EGLObjectHandle {
+    public EGLSurface(int handle) {
+        super(handle);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        EGLSurface that = (EGLSurface) o;
+        return getHandle() == that.getHandle();
+    }
+
+    @Override
+    public int hashCode() {
+        return getHandle();
+    }
+}
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/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index a216d6c..61a58d3 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -74,7 +74,7 @@
     <string name="use_ptp_button_title" msgid="7517127540301625751">"تصب به عنوان دوربین (PTP)"</string>
     <string name="installer_cd_button_title" msgid="2312667578562201583">"برنامه Android File Transfer را برای Mac نصب کنید"</string>
     <string name="accessibility_back" msgid="567011538994429120">"برگشت"</string>
-    <string name="accessibility_home" msgid="8217216074895377641">"صفحه اصلی"</string>
+    <string name="accessibility_home" msgid="8217216074895377641">"صفحهٔ اصلی"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"منو"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"برنامه‌های اخیر"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"کلید تغییر روش ورود متن."</string>
@@ -138,7 +138,7 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"جستجو برای GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"مکان تنظیم شده توسط GPS"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"پاک کردن تمام اعلان‌ها"</string>
-    <string name="dreams_dock_launcher" msgid="3541196417659166245">"فعال کردن محافظ صفحه نمایش"</string>
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"فعال کردن محافظ صفحهٔ نمایش"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"اطلاعات برنامه"</string>
     <string name="close_universe" msgid="3736513750241754348">"بستن"</string>
     <string name="notifications_off_title" msgid="8936620513608443224">"اعلان‌ها خاموش"</string>
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 35cdf9b..0000000
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ /dev/null
@@ -1,721 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-
-import android.content.Context;
-import android.os.RegistrantList;
-import android.os.Registrant;
-import android.os.Handler;
-import android.os.AsyncResult;
-import android.os.SystemProperties;
-import android.util.Log;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * {@hide}
- */
-public abstract class BaseCommands implements CommandsInterface {
-    static final String LOG_TAG = "RILB";
-
-    //***** Instance Variables
-    protected Context mContext;
-    protected RadioState mState = RadioState.RADIO_UNAVAILABLE;
-    protected Object mStateMonitor = new Object();
-
-    protected RegistrantList mRadioStateChangedRegistrants = new RegistrantList();
-    protected RegistrantList mOnRegistrants = new RegistrantList();
-    protected RegistrantList mAvailRegistrants = new RegistrantList();
-    protected RegistrantList mOffOrNotAvailRegistrants = new RegistrantList();
-    protected RegistrantList mNotAvailRegistrants = new RegistrantList();
-    protected RegistrantList mCallStateRegistrants = new RegistrantList();
-    protected RegistrantList mVoiceNetworkStateRegistrants = new RegistrantList();
-    protected RegistrantList mDataNetworkStateRegistrants = new RegistrantList();
-    protected RegistrantList mVoiceRadioTechChangedRegistrants = new RegistrantList();
-    protected RegistrantList mIccStatusChangedRegistrants = new RegistrantList();
-    protected RegistrantList mVoicePrivacyOnRegistrants = new RegistrantList();
-    protected RegistrantList mVoicePrivacyOffRegistrants = new RegistrantList();
-    protected Registrant mUnsolOemHookRawRegistrant;
-    protected RegistrantList mOtaProvisionRegistrants = new RegistrantList();
-    protected RegistrantList mCallWaitingInfoRegistrants = new RegistrantList();
-    protected RegistrantList mDisplayInfoRegistrants = new RegistrantList();
-    protected RegistrantList mSignalInfoRegistrants = new RegistrantList();
-    protected RegistrantList mNumberInfoRegistrants = new RegistrantList();
-    protected RegistrantList mRedirNumInfoRegistrants = new RegistrantList();
-    protected RegistrantList mLineControlInfoRegistrants = new RegistrantList();
-    protected RegistrantList mT53ClirInfoRegistrants = new RegistrantList();
-    protected RegistrantList mT53AudCntrlInfoRegistrants = new RegistrantList();
-    protected RegistrantList mRingbackToneRegistrants = new RegistrantList();
-    protected RegistrantList mResendIncallMuteRegistrants = new RegistrantList();
-    protected RegistrantList mCdmaSubscriptionChangedRegistrants = new RegistrantList();
-    protected RegistrantList mCdmaPrlChangedRegistrants = new RegistrantList();
-    protected RegistrantList mExitEmergencyCallbackModeRegistrants = new RegistrantList();
-    protected RegistrantList mRilConnectedRegistrants = new RegistrantList();
-    protected RegistrantList mIccRefreshRegistrants = new RegistrantList();
-
-    protected Registrant mGsmSmsRegistrant;
-    protected Registrant mCdmaSmsRegistrant;
-    protected Registrant mNITZTimeRegistrant;
-    protected Registrant mSignalStrengthRegistrant;
-    protected Registrant mUSSDRegistrant;
-    protected Registrant mSmsOnSimRegistrant;
-    protected Registrant mSmsStatusRegistrant;
-    protected Registrant mSsnRegistrant;
-    protected Registrant mCatSessionEndRegistrant;
-    protected Registrant mCatProCmdRegistrant;
-    protected Registrant mCatEventRegistrant;
-    protected Registrant mCatCallSetUpRegistrant;
-    protected Registrant mIccSmsFullRegistrant;
-    protected Registrant mEmergencyCallbackModeRegistrant;
-    protected Registrant mRingRegistrant;
-    protected Registrant mRestrictedStateRegistrant;
-    protected Registrant mGsmBroadcastSmsRegistrant;
-
-    // Preferred network type received from PhoneFactory.
-    // This is used when establishing a connection to the
-    // vendor ril so it starts up in the correct mode.
-    protected int mPreferredNetworkType;
-    // CDMA subscription received from PhoneFactory
-    protected int mCdmaSubscription;
-    // Type of Phone, GSM or CDMA. Set by CDMAPhone or GSMPhone.
-    protected int mPhoneType;
-    // RIL Version
-    protected int mRilVersion = -1;
-
-    public BaseCommands(Context context) {
-        mContext = context;  // May be null (if so we won't log statistics)
-    }
-
-    //***** CommandsInterface implementation
-
-    public RadioState getRadioState() {
-        return mState;
-    }
-
-    public void registerForRadioStateChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        synchronized (mStateMonitor) {
-            mRadioStateChangedRegistrants.add(r);
-            r.notifyRegistrant();
-        }
-    }
-
-    public void unregisterForRadioStateChanged(Handler h) {
-        synchronized (mStateMonitor) {
-            mRadioStateChangedRegistrants.remove(h);
-        }
-    }
-
-    public void registerForOn(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        synchronized (mStateMonitor) {
-            mOnRegistrants.add(r);
-
-            if (mState.isOn()) {
-                r.notifyRegistrant(new AsyncResult(null, null, null));
-            }
-        }
-    }
-    public void unregisterForOn(Handler h) {
-        synchronized (mStateMonitor) {
-            mOnRegistrants.remove(h);
-        }
-    }
-
-
-    public void registerForAvailable(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        synchronized (mStateMonitor) {
-            mAvailRegistrants.add(r);
-
-            if (mState.isAvailable()) {
-                r.notifyRegistrant(new AsyncResult(null, null, null));
-            }
-        }
-    }
-
-    public void unregisterForAvailable(Handler h) {
-        synchronized(mStateMonitor) {
-            mAvailRegistrants.remove(h);
-        }
-    }
-
-    public void registerForNotAvailable(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        synchronized (mStateMonitor) {
-            mNotAvailRegistrants.add(r);
-
-            if (!mState.isAvailable()) {
-                r.notifyRegistrant(new AsyncResult(null, null, null));
-            }
-        }
-    }
-
-    public void unregisterForNotAvailable(Handler h) {
-        synchronized (mStateMonitor) {
-            mNotAvailRegistrants.remove(h);
-        }
-    }
-
-    public void registerForOffOrNotAvailable(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        synchronized (mStateMonitor) {
-            mOffOrNotAvailRegistrants.add(r);
-
-            if (mState == RadioState.RADIO_OFF || !mState.isAvailable()) {
-                r.notifyRegistrant(new AsyncResult(null, null, null));
-            }
-        }
-    }
-    public void unregisterForOffOrNotAvailable(Handler h) {
-        synchronized(mStateMonitor) {
-            mOffOrNotAvailRegistrants.remove(h);
-        }
-    }
-
-    public void registerForCallStateChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        mCallStateRegistrants.add(r);
-    }
-
-    public void unregisterForCallStateChanged(Handler h) {
-        mCallStateRegistrants.remove(h);
-    }
-
-    public void registerForVoiceNetworkStateChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        mVoiceNetworkStateRegistrants.add(r);
-    }
-
-    public void unregisterForVoiceNetworkStateChanged(Handler h) {
-        mVoiceNetworkStateRegistrants.remove(h);
-    }
-
-    public void registerForDataNetworkStateChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        mDataNetworkStateRegistrants.add(r);
-    }
-
-    public void unregisterForDataNetworkStateChanged(Handler h) {
-        mDataNetworkStateRegistrants.remove(h);
-    }
-
-    public void registerForVoiceRadioTechChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mVoiceRadioTechChangedRegistrants.add(r);
-    }
-
-    public void unregisterForVoiceRadioTechChanged(Handler h) {
-        mVoiceRadioTechChangedRegistrants.remove(h);
-    }
-
-    public void registerForIccStatusChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mIccStatusChangedRegistrants.add(r);
-    }
-
-    public void unregisterForIccStatusChanged(Handler h) {
-        mIccStatusChangedRegistrants.remove(h);
-    }
-
-    public void setOnNewGsmSms(Handler h, int what, Object obj) {
-        mGsmSmsRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnNewGsmSms(Handler h) {
-        mGsmSmsRegistrant.clear();
-    }
-
-    public void setOnNewCdmaSms(Handler h, int what, Object obj) {
-        mCdmaSmsRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnNewCdmaSms(Handler h) {
-        mCdmaSmsRegistrant.clear();
-    }
-
-    public void setOnNewGsmBroadcastSms(Handler h, int what, Object obj) {
-        mGsmBroadcastSmsRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnNewGsmBroadcastSms(Handler h) {
-        mGsmBroadcastSmsRegistrant.clear();
-    }
-
-    public void setOnSmsOnSim(Handler h, int what, Object obj) {
-        mSmsOnSimRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnSmsOnSim(Handler h) {
-        mSmsOnSimRegistrant.clear();
-    }
-
-    public void setOnSmsStatus(Handler h, int what, Object obj) {
-        mSmsStatusRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnSmsStatus(Handler h) {
-        mSmsStatusRegistrant.clear();
-    }
-
-    public void setOnSignalStrengthUpdate(Handler h, int what, Object obj) {
-        mSignalStrengthRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnSignalStrengthUpdate(Handler h) {
-        mSignalStrengthRegistrant.clear();
-    }
-
-    public void setOnNITZTime(Handler h, int what, Object obj) {
-        mNITZTimeRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnNITZTime(Handler h) {
-        mNITZTimeRegistrant.clear();
-    }
-
-    public void setOnUSSD(Handler h, int what, Object obj) {
-        mUSSDRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnUSSD(Handler h) {
-        mUSSDRegistrant.clear();
-    }
-
-    public void setOnSuppServiceNotification(Handler h, int what, Object obj) {
-        mSsnRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnSuppServiceNotification(Handler h) {
-        mSsnRegistrant.clear();
-    }
-
-    public void setOnCatSessionEnd(Handler h, int what, Object obj) {
-        mCatSessionEndRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnCatSessionEnd(Handler h) {
-        mCatSessionEndRegistrant.clear();
-    }
-
-    public void setOnCatProactiveCmd(Handler h, int what, Object obj) {
-        mCatProCmdRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnCatProactiveCmd(Handler h) {
-        mCatProCmdRegistrant.clear();
-    }
-
-    public void setOnCatEvent(Handler h, int what, Object obj) {
-        mCatEventRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnCatEvent(Handler h) {
-        mCatEventRegistrant.clear();
-    }
-
-    public void setOnCatCallSetUp(Handler h, int what, Object obj) {
-        mCatCallSetUpRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnCatCallSetUp(Handler h) {
-        mCatCallSetUpRegistrant.clear();
-    }
-
-    public void setOnIccSmsFull(Handler h, int what, Object obj) {
-        mIccSmsFullRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnIccSmsFull(Handler h) {
-        mIccSmsFullRegistrant.clear();
-    }
-
-    public void registerForIccRefresh(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mIccRefreshRegistrants.add(r);
-    }
-    public void setOnIccRefresh(Handler h, int what, Object obj) {
-        registerForIccRefresh(h, what, obj);
-    }
-
-    public void setEmergencyCallbackMode(Handler h, int what, Object obj) {
-        mEmergencyCallbackModeRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unregisterForIccRefresh(Handler h) {
-        mIccRefreshRegistrants.remove(h);
-    }
-    public void unsetOnIccRefresh(Handler h) {
-        unregisterForIccRefresh(h);
-    }
-
-    public void setOnCallRing(Handler h, int what, Object obj) {
-        mRingRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnCallRing(Handler h) {
-        mRingRegistrant.clear();
-    }
-
-    public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mVoicePrivacyOnRegistrants.add(r);
-    }
-
-    public void unregisterForInCallVoicePrivacyOn(Handler h){
-        mVoicePrivacyOnRegistrants.remove(h);
-    }
-
-    public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mVoicePrivacyOffRegistrants.add(r);
-    }
-
-    public void unregisterForInCallVoicePrivacyOff(Handler h){
-        mVoicePrivacyOffRegistrants.remove(h);
-    }
-
-    public void setOnRestrictedStateChanged(Handler h, int what, Object obj) {
-        mRestrictedStateRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnRestrictedStateChanged(Handler h) {
-        mRestrictedStateRegistrant.clear();
-    }
-
-    public void registerForDisplayInfo(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mDisplayInfoRegistrants.add(r);
-    }
-
-    public void unregisterForDisplayInfo(Handler h) {
-        mDisplayInfoRegistrants.remove(h);
-    }
-
-    public void registerForCallWaitingInfo(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mCallWaitingInfoRegistrants.add(r);
-    }
-
-    public void unregisterForCallWaitingInfo(Handler h) {
-        mCallWaitingInfoRegistrants.remove(h);
-    }
-
-    public void registerForSignalInfo(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mSignalInfoRegistrants.add(r);
-    }
-
-    public void setOnUnsolOemHookRaw(Handler h, int what, Object obj) {
-        mUnsolOemHookRawRegistrant = new Registrant (h, what, obj);
-    }
-
-    public void unSetOnUnsolOemHookRaw(Handler h) {
-        mUnsolOemHookRawRegistrant.clear();
-    }
-
-    public void unregisterForSignalInfo(Handler h) {
-        mSignalInfoRegistrants.remove(h);
-    }
-
-    public void registerForCdmaOtaProvision(Handler h,int what, Object obj){
-        Registrant r = new Registrant (h, what, obj);
-        mOtaProvisionRegistrants.add(r);
-    }
-
-    public void unregisterForCdmaOtaProvision(Handler h){
-        mOtaProvisionRegistrants.remove(h);
-    }
-
-    public void registerForNumberInfo(Handler h,int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mNumberInfoRegistrants.add(r);
-    }
-
-    public void unregisterForNumberInfo(Handler h){
-        mNumberInfoRegistrants.remove(h);
-    }
-
-     public void registerForRedirectedNumberInfo(Handler h,int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mRedirNumInfoRegistrants.add(r);
-    }
-
-    public void unregisterForRedirectedNumberInfo(Handler h) {
-        mRedirNumInfoRegistrants.remove(h);
-    }
-
-    public void registerForLineControlInfo(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mLineControlInfoRegistrants.add(r);
-    }
-
-    public void unregisterForLineControlInfo(Handler h) {
-        mLineControlInfoRegistrants.remove(h);
-    }
-
-    public void registerFoT53ClirlInfo(Handler h,int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mT53ClirInfoRegistrants.add(r);
-    }
-
-    public void unregisterForT53ClirInfo(Handler h) {
-        mT53ClirInfoRegistrants.remove(h);
-    }
-
-    public void registerForT53AudioControlInfo(Handler h,int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mT53AudCntrlInfoRegistrants.add(r);
-    }
-
-    public void unregisterForT53AudioControlInfo(Handler h) {
-        mT53AudCntrlInfoRegistrants.remove(h);
-    }
-
-    public void registerForRingbackTone(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mRingbackToneRegistrants.add(r);
-    }
-
-    public void unregisterForRingbackTone(Handler h) {
-        mRingbackToneRegistrants.remove(h);
-    }
-
-    public void registerForResendIncallMute(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mResendIncallMuteRegistrants.add(r);
-    }
-
-    public void unregisterForResendIncallMute(Handler h) {
-        mResendIncallMuteRegistrants.remove(h);
-    }
-
-    @Override
-    public void registerForCdmaSubscriptionChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mCdmaSubscriptionChangedRegistrants.add(r);
-    }
-
-    @Override
-    public void unregisterForCdmaSubscriptionChanged(Handler h) {
-        mCdmaSubscriptionChangedRegistrants.remove(h);
-    }
-
-    @Override
-    public void registerForCdmaPrlChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mCdmaPrlChangedRegistrants.add(r);
-    }
-
-    @Override
-    public void unregisterForCdmaPrlChanged(Handler h) {
-        mCdmaPrlChangedRegistrants.remove(h);
-    }
-
-    @Override
-    public void registerForExitEmergencyCallbackMode(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-        mExitEmergencyCallbackModeRegistrants.add(r);
-    }
-
-    @Override
-    public void unregisterForExitEmergencyCallbackMode(Handler h) {
-        mExitEmergencyCallbackModeRegistrants.remove(h);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void registerForRilConnected(Handler h, int what, Object obj) {
-        Log.d(LOG_TAG, "registerForRilConnected h=" + h + " w=" + what);
-        Registrant r = new Registrant (h, what, obj);
-        mRilConnectedRegistrants.add(r);
-        if (mRilVersion != -1) {
-            Log.d(LOG_TAG, "Notifying: ril connected mRilVersion=" + mRilVersion);
-            r.notifyRegistrant(new AsyncResult(null, new Integer(mRilVersion), null));
-        }
-    }
-
-    @Override
-    public void unregisterForRilConnected(Handler h) {
-        mRilConnectedRegistrants.remove(h);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setCurrentPreferredNetworkType() {
-    }
-
-    //***** Protected Methods
-    /**
-     * Store new RadioState and send notification based on the changes
-     *
-     * This function is called only by RIL.java when receiving unsolicited
-     * RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED
-     *
-     * RadioState has 3 values : RADIO_OFF, RADIO_UNAVAILABLE, RADIO_ON.
-     *
-     * @param newState new RadioState decoded from RIL_UNSOL_RADIO_STATE_CHANGED
-     */
-    protected void setRadioState(RadioState newState) {
-        RadioState oldState;
-
-        synchronized (mStateMonitor) {
-            if (false) {
-                Log.v(LOG_TAG, "setRadioState old: " + mState
-                    + " new " + newState);
-            }
-
-            oldState = mState;
-            mState = newState;
-
-            if (oldState == mState) {
-                // no state transition
-                return;
-            }
-
-            mRadioStateChangedRegistrants.notifyRegistrants();
-
-            if (mState.isAvailable() && !oldState.isAvailable()) {
-                Log.d(LOG_TAG,"Notifying: radio available");
-                mAvailRegistrants.notifyRegistrants();
-                onRadioAvailable();
-            }
-
-            if (!mState.isAvailable() && oldState.isAvailable()) {
-                Log.d(LOG_TAG,"Notifying: radio not available");
-                mNotAvailRegistrants.notifyRegistrants();
-            }
-
-            if (mState.isOn() && !oldState.isOn()) {
-                Log.d(LOG_TAG,"Notifying: Radio On");
-                mOnRegistrants.notifyRegistrants();
-            }
-
-            if ((!mState.isOn() || !mState.isAvailable())
-                && !((!oldState.isOn() || !oldState.isAvailable()))
-            ) {
-                Log.d(LOG_TAG,"Notifying: radio off or not available");
-                mOffOrNotAvailRegistrants.notifyRegistrants();
-            }
-        }
-    }
-
-    protected void onRadioAvailable() {
-    }
-
-    /**
-     * The contents of the /proc/cmdline file
-     */
-    private static String getProcCmdLine()
-    {
-        String cmdline = "";
-        FileInputStream is = null;
-        try {
-            is = new FileInputStream("/proc/cmdline");
-            byte [] buffer = new byte[2048];
-            int count = is.read(buffer);
-            if (count > 0) {
-                cmdline = new String(buffer, 0, count);
-            }
-        } catch (IOException e) {
-            Log.d(LOG_TAG, "No /proc/cmdline exception=" + e);
-        } finally {
-            if (is != null) {
-                try {
-                    is.close();
-                } catch (IOException e) {
-                }
-            }
-        }
-        Log.d(LOG_TAG, "/proc/cmdline=" + cmdline);
-        return cmdline;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public int getLteOnCdmaMode() {
-        return getLteOnCdmaModeStatic();
-    }
-
-    /** Kernel command line */
-    private static final String sKernelCmdLine = getProcCmdLine();
-
-    /** Pattern for selecting the product type from the kernel command line */
-    private static final Pattern sProductTypePattern =
-        Pattern.compile("\\sproduct_type\\s*=\\s*(\\w+)");
-
-    /** The ProductType used for LTE on CDMA devices */
-    private static final String sLteOnCdmaProductType =
-        SystemProperties.get(TelephonyProperties.PROPERTY_LTE_ON_CDMA_PRODUCT_TYPE, "");
-
-    /**
-     * Return if the current radio is LTE on CDMA. This
-     * is a tri-state return value as for a period of time
-     * the mode may be unknown.
-     *
-     * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
-     * or {@link Phone#LTE_ON_CDMA_TRUE}
-     */
-    public static int getLteOnCdmaModeStatic() {
-        int retVal;
-        int curVal;
-        String productType = "";
-
-        curVal = SystemProperties.getInt(TelephonyProperties.PROPERTY_LTE_ON_CDMA_DEVICE,
-                    Phone.LTE_ON_CDMA_UNKNOWN);
-        retVal = curVal;
-        if (retVal == Phone.LTE_ON_CDMA_UNKNOWN) {
-            Matcher matcher = sProductTypePattern.matcher(sKernelCmdLine);
-            if (matcher.find()) {
-                productType = matcher.group(1);
-                if (sLteOnCdmaProductType.equals(productType)) {
-                    retVal = Phone.LTE_ON_CDMA_TRUE;
-                } else {
-                    retVal = Phone.LTE_ON_CDMA_FALSE;
-                }
-            } else {
-                retVal = Phone.LTE_ON_CDMA_FALSE;
-            }
-        }
-
-        Log.d(LOG_TAG, "getLteOnCdmaMode=" + retVal + " curVal=" + curVal +
-                " product_type='" + productType +
-                "' lteOnCdmaProductType='" + sLteOnCdmaProductType + "'");
-        return retVal;
-    }
-
-    @Override
-    public void testingEmergencyCall() {}
-}
diff --git a/telephony/java/com/android/internal/telephony/Call.java b/telephony/java/com/android/internal/telephony/Call.java
deleted file mode 100644
index 4967ab8..0000000
--- a/telephony/java/com/android/internal/telephony/Call.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import java.util.List;
-
-import android.util.Log;
-
-/**
- * {@hide}
- */
-public abstract class Call {
-    /* Enums */
-
-    public enum State {
-        IDLE, ACTIVE, HOLDING, DIALING, ALERTING, INCOMING, WAITING, DISCONNECTED, DISCONNECTING;
-
-        public boolean isAlive() {
-            return !(this == IDLE || this == DISCONNECTED || this == DISCONNECTING);
-        }
-
-        public boolean isRinging() {
-            return this == INCOMING || this == WAITING;
-        }
-
-        public boolean isDialing() {
-            return this == DIALING || this == ALERTING;
-        }
-    }
-
-
-    /* Instance Variables */
-
-    public State state = State.IDLE;
-
-
-    // Flag to indicate if the current calling/caller information
-    // is accurate. If false the information is known to be accurate.
-    //
-    // For CDMA, during call waiting/3 way, there is no network response
-    // if call waiting is answered, network timed out, dropped, 3 way
-    // merged, etc.
-    protected boolean isGeneric = false;
-
-    protected final String LOG_TAG = "Call";
-
-    /* Instance Methods */
-
-    /** Do not modify the List result!!! This list is not yours to keep
-     *  It will change across event loop iterations            top
-     */
-
-    public abstract List<Connection> getConnections();
-    public abstract Phone getPhone();
-    public abstract boolean isMultiparty();
-    public abstract void hangup() throws CallStateException;
-
-
-    /**
-     * hasConnection
-     *
-     * @param c a Connection object
-     * @return true if the call contains the connection object passed in
-     */
-    public boolean hasConnection(Connection c) {
-        return c.getCall() == this;
-    }
-
-    /**
-     * hasConnections
-     * @return true if the call contains one or more connections
-     */
-    public boolean hasConnections() {
-        List connections = getConnections();
-
-        if (connections == null) {
-            return false;
-        }
-
-        return connections.size() > 0;
-    }
-
-    /**
-     * getState
-     * @return state of class call
-     */
-    public State getState() {
-        return state;
-    }
-
-    /**
-     * isIdle
-     *
-     * FIXME rename
-     * @return true if the call contains only disconnected connections (if any)
-     */
-    public boolean isIdle() {
-        return !getState().isAlive();
-    }
-
-    /**
-     * Returns the Connection associated with this Call that was created
-     * first, or null if there are no Connections in this Call
-     */
-    public Connection
-    getEarliestConnection() {
-        List l;
-        long time = Long.MAX_VALUE;
-        Connection c;
-        Connection earliest = null;
-
-        l = getConnections();
-
-        if (l.size() == 0) {
-            return null;
-        }
-
-        for (int i = 0, s = l.size() ; i < s ; i++) {
-            c = (Connection) l.get(i);
-            long t;
-
-            t = c.getCreateTime();
-
-            if (t < time) {
-                earliest = c;
-                time = t;
-            }
-        }
-
-        return earliest;
-    }
-
-    public long
-    getEarliestCreateTime() {
-        List l;
-        long time = Long.MAX_VALUE;
-
-        l = getConnections();
-
-        if (l.size() == 0) {
-            return 0;
-        }
-
-        for (int i = 0, s = l.size() ; i < s ; i++) {
-            Connection c = (Connection) l.get(i);
-            long t;
-
-            t = c.getCreateTime();
-
-            time = t < time ? t : time;
-        }
-
-        return time;
-    }
-
-    public long
-    getEarliestConnectTime() {
-        long time = Long.MAX_VALUE;
-        List l = getConnections();
-
-        if (l.size() == 0) {
-            return 0;
-        }
-
-        for (int i = 0, s = l.size() ; i < s ; i++) {
-            Connection c = (Connection) l.get(i);
-            long t;
-
-            t = c.getConnectTime();
-
-            time = t < time ? t : time;
-        }
-
-        return time;
-    }
-
-
-    public boolean
-    isDialingOrAlerting() {
-        return getState().isDialing();
-    }
-
-    public boolean
-    isRinging() {
-        return getState().isRinging();
-    }
-
-    /**
-     * Returns the Connection associated with this Call that was created
-     * last, or null if there are no Connections in this Call
-     */
-    public Connection
-    getLatestConnection() {
-        List l = getConnections();
-        if (l.size() == 0) {
-            return null;
-        }
-
-        long time = 0;
-        Connection latest = null;
-        for (int i = 0, s = l.size() ; i < s ; i++) {
-            Connection c = (Connection) l.get(i);
-            long t = c.getCreateTime();
-
-            if (t > time) {
-                latest = c;
-                time = t;
-            }
-        }
-
-        return latest;
-    }
-
-    /**
-     * To indicate if the connection information is accurate
-     * or not. false means accurate. Only used for CDMA.
-     */
-    public boolean isGeneric() {
-        return isGeneric;
-    }
-
-    /**
-     * Set the generic instance variable
-     */
-    public void setGeneric(boolean generic) {
-        isGeneric = generic;
-    }
-
-    /**
-     * Hangup call if it is alive
-     */
-    public void hangupIfAlive() {
-        if (getState().isAlive()) {
-            try {
-                hangup();
-            } catch (CallStateException ex) {
-                Log.w(LOG_TAG, " hangupIfActive: caught " + ex);
-            }
-        }
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/CallForwardInfo.java b/telephony/java/com/android/internal/telephony/CallForwardInfo.java
deleted file mode 100644
index 8b853b0..0000000
--- a/telephony/java/com/android/internal/telephony/CallForwardInfo.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.telephony.PhoneNumberUtils;
-
-/**
- * See also RIL_CallForwardInfo in include/telephony/ril.h
- *
- * {@hide}
- */
-public class CallForwardInfo {
-    public int             status;      /*1 = active, 0 = not active */
-    public int             reason;      /* from TS 27.007 7.11 "reason" */
-    public int             serviceClass; /* Sum of CommandsInterface.SERVICE_CLASS */
-    public int             toa;         /* "type" from TS 27.007 7.11 */
-    public String          number;      /* "number" from TS 27.007 7.11 */
-    public int             timeSeconds; /* for CF no reply only */
-
-    public String toString() {
-        return super.toString() + (status == 0 ? " not active " : " active ")
-            + " reason: " + reason
-            + " serviceClass: " + serviceClass
-            + " \"" + PhoneNumberUtils.stringFromStringAndTOA(number, toa) + "\" "
-            + timeSeconds + " seconds";
-
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java
deleted file mode 100644
index f825f31..0000000
--- a/telephony/java/com/android/internal/telephony/CallManager.java
+++ /dev/null
@@ -1,1855 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import com.android.internal.telephony.sip.SipPhone;
-
-import android.content.Context;
-import android.media.AudioManager;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.RegistrantList;
-import android.os.Registrant;
-import android.telephony.PhoneStateListener;
-import android.telephony.ServiceState;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-
-
-/**
- * @hide
- *
- * CallManager class provides an abstract layer for PhoneApp to access
- * and control calls. It implements Phone interface.
- *
- * CallManager provides call and connection control as well as
- * channel capability.
- *
- * There are three categories of APIs CallManager provided
- *
- *  1. Call control and operation, such as dial() and hangup()
- *  2. Channel capabilities, such as CanConference()
- *  3. Register notification
- *
- *
- */
-public final class CallManager {
-
-    private static final String LOG_TAG ="CallManager";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    private static final int EVENT_DISCONNECT = 100;
-    private static final int EVENT_PRECISE_CALL_STATE_CHANGED = 101;
-    private static final int EVENT_NEW_RINGING_CONNECTION = 102;
-    private static final int EVENT_UNKNOWN_CONNECTION = 103;
-    private static final int EVENT_INCOMING_RING = 104;
-    private static final int EVENT_RINGBACK_TONE = 105;
-    private static final int EVENT_IN_CALL_VOICE_PRIVACY_ON = 106;
-    private static final int EVENT_IN_CALL_VOICE_PRIVACY_OFF = 107;
-    private static final int EVENT_CALL_WAITING = 108;
-    private static final int EVENT_DISPLAY_INFO = 109;
-    private static final int EVENT_SIGNAL_INFO = 110;
-    private static final int EVENT_CDMA_OTA_STATUS_CHANGE = 111;
-    private static final int EVENT_RESEND_INCALL_MUTE = 112;
-    private static final int EVENT_MMI_INITIATE = 113;
-    private static final int EVENT_MMI_COMPLETE = 114;
-    private static final int EVENT_ECM_TIMER_RESET = 115;
-    private static final int EVENT_SUBSCRIPTION_INFO_READY = 116;
-    private static final int EVENT_SUPP_SERVICE_FAILED = 117;
-    private static final int EVENT_SERVICE_STATE_CHANGED = 118;
-    private static final int EVENT_POST_DIAL_CHARACTER = 119;
-
-    // Singleton instance
-    private static final CallManager INSTANCE = new CallManager();
-
-    // list of registered phones, which are PhoneBase objs
-    private final ArrayList<Phone> mPhones;
-
-    // list of supported ringing calls
-    private final ArrayList<Call> mRingingCalls;
-
-    // list of supported background calls
-    private final ArrayList<Call> mBackgroundCalls;
-
-    // list of supported foreground calls
-    private final ArrayList<Call> mForegroundCalls;
-
-    // empty connection list
-    private final ArrayList<Connection> emptyConnections = new ArrayList<Connection>();
-
-    // default phone as the first phone registered, which is PhoneBase obj
-    private Phone mDefaultPhone;
-
-    // state registrants
-    protected final RegistrantList mPreciseCallStateRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mNewRingingConnectionRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mIncomingRingRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mDisconnectRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mMmiRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mUnknownConnectionRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mRingbackToneRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mInCallVoicePrivacyOnRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mInCallVoicePrivacyOffRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mCallWaitingRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mDisplayInfoRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mSignalInfoRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mCdmaOtaStatusChangeRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mResendIncallMuteRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mMmiInitiateRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mMmiCompleteRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mEcmTimerResetRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mSubscriptionInfoReadyRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mSuppServiceFailedRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mServiceStateChangedRegistrants
-    = new RegistrantList();
-
-    protected final RegistrantList mPostDialCharacterRegistrants
-    = new RegistrantList();
-
-    private CallManager() {
-        mPhones = new ArrayList<Phone>();
-        mRingingCalls = new ArrayList<Call>();
-        mBackgroundCalls = new ArrayList<Call>();
-        mForegroundCalls = new ArrayList<Call>();
-        mDefaultPhone = null;
-    }
-
-    /**
-     * get singleton instance of CallManager
-     * @return CallManager
-     */
-    public static CallManager getInstance() {
-        return INSTANCE;
-    }
-
-    /**
-     * Get the corresponding PhoneBase obj
-     *
-     * @param phone a Phone object
-     * @return the corresponding PhoneBase obj in Phone if Phone
-     * is a PhoneProxy obj
-     * or the Phone itself if Phone is not a PhoneProxy obj
-     */
-    private static Phone getPhoneBase(Phone phone) {
-        if (phone instanceof PhoneProxy) {
-            return phone.getForegroundCall().getPhone();
-        }
-        return phone;
-    }
-
-    /**
-     * Check if two phones refer to the same PhoneBase obj
-     *
-     * Note: PhoneBase, not PhoneProxy, is to be used inside of CallManager
-     *
-     * Both PhoneBase and PhoneProxy implement Phone interface, so
-     * they have same phone APIs, such as dial(). The real implementation, for
-     * example in GSM,  is in GSMPhone as extend from PhoneBase, so that
-     * foregroundCall.getPhone() returns GSMPhone obj. On the other hand,
-     * PhoneFactory.getDefaultPhone() returns PhoneProxy obj, which has a class
-     * member of GSMPhone.
-     *
-     * So for phone returned by PhoneFacotry, which is used by PhoneApp,
-     *        phone.getForegroundCall().getPhone() != phone
-     * but
-     *        isSamePhone(phone, phone.getForegroundCall().getPhone()) == true
-     *
-     * @param p1 is the first Phone obj
-     * @param p2 is the second Phone obj
-     * @return true if p1 and p2 refer to the same phone
-     */
-    public static boolean isSamePhone(Phone p1, Phone p2) {
-        return (getPhoneBase(p1) == getPhoneBase(p2));
-    }
-
-    /**
-     * Returns all the registered phone objects.
-     * @return all the registered phone objects.
-     */
-    public List<Phone> getAllPhones() {
-        return Collections.unmodifiableList(mPhones);
-    }
-
-    /**
-     * Get current coarse-grained voice call state.
-     * If the Call Manager has an active call and call waiting occurs,
-     * then the phone state is RINGING not OFFHOOK
-     *
-     */
-    public Phone.State getState() {
-        Phone.State s = Phone.State.IDLE;
-
-        for (Phone phone : mPhones) {
-            if (phone.getState() == Phone.State.RINGING) {
-                s = Phone.State.RINGING;
-            } else if (phone.getState() == Phone.State.OFFHOOK) {
-                if (s == Phone.State.IDLE) s = Phone.State.OFFHOOK;
-            }
-        }
-        return s;
-    }
-
-    /**
-     * @return the service state of CallManager, which represents the
-     * highest priority state of all the service states of phones
-     *
-     * The priority is defined as
-     *
-     * STATE_IN_SERIVCE > STATE_OUT_OF_SERIVCE > STATE_EMERGENCY > STATE_POWER_OFF
-     *
-     */
-
-    public int getServiceState() {
-        int resultState = ServiceState.STATE_OUT_OF_SERVICE;
-
-        for (Phone phone : mPhones) {
-            int serviceState = phone.getServiceState().getState();
-            if (serviceState == ServiceState.STATE_IN_SERVICE) {
-                // IN_SERVICE has the highest priority
-                resultState = serviceState;
-                break;
-            } else if (serviceState == ServiceState.STATE_OUT_OF_SERVICE) {
-                // OUT_OF_SERVICE replaces EMERGENCY_ONLY and POWER_OFF
-                // Note: EMERGENCY_ONLY is not in use at this moment
-                if ( resultState == ServiceState.STATE_EMERGENCY_ONLY ||
-                        resultState == ServiceState.STATE_POWER_OFF) {
-                    resultState = serviceState;
-                }
-            } else if (serviceState == ServiceState.STATE_EMERGENCY_ONLY) {
-                if (resultState == ServiceState.STATE_POWER_OFF) {
-                    resultState = serviceState;
-                }
-            }
-        }
-        return resultState;
-    }
-
-    /**
-     * Register phone to CallManager
-     * @param phone to be registered
-     * @return true if register successfully
-     */
-    public boolean registerPhone(Phone phone) {
-        Phone basePhone = getPhoneBase(phone);
-
-        if (basePhone != null && !mPhones.contains(basePhone)) {
-
-            if (DBG) {
-                Log.d(LOG_TAG, "registerPhone(" +
-                        phone.getPhoneName() + " " + phone + ")");
-            }
-
-            if (mPhones.isEmpty()) {
-                mDefaultPhone = basePhone;
-            }
-            mPhones.add(basePhone);
-            mRingingCalls.add(basePhone.getRingingCall());
-            mBackgroundCalls.add(basePhone.getBackgroundCall());
-            mForegroundCalls.add(basePhone.getForegroundCall());
-            registerForPhoneStates(basePhone);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * unregister phone from CallManager
-     * @param phone to be unregistered
-     */
-    public void unregisterPhone(Phone phone) {
-        Phone basePhone = getPhoneBase(phone);
-
-        if (basePhone != null && mPhones.contains(basePhone)) {
-
-            if (DBG) {
-                Log.d(LOG_TAG, "unregisterPhone(" +
-                        phone.getPhoneName() + " " + phone + ")");
-            }
-
-            mPhones.remove(basePhone);
-            mRingingCalls.remove(basePhone.getRingingCall());
-            mBackgroundCalls.remove(basePhone.getBackgroundCall());
-            mForegroundCalls.remove(basePhone.getForegroundCall());
-            unregisterForPhoneStates(basePhone);
-            if (basePhone == mDefaultPhone) {
-                if (mPhones.isEmpty()) {
-                    mDefaultPhone = null;
-                } else {
-                    mDefaultPhone = mPhones.get(0);
-                }
-            }
-        }
-    }
-
-    /**
-     * return the default phone or null if no phone available
-     */
-    public Phone getDefaultPhone() {
-        return mDefaultPhone;
-    }
-
-    /**
-     * @return the phone associated with the foreground call
-     */
-    public Phone getFgPhone() {
-        return getActiveFgCall().getPhone();
-    }
-
-    /**
-     * @return the phone associated with the background call
-     */
-    public Phone getBgPhone() {
-        return getFirstActiveBgCall().getPhone();
-    }
-
-    /**
-     * @return the phone associated with the ringing call
-     */
-    public Phone getRingingPhone() {
-        return getFirstActiveRingingCall().getPhone();
-    }
-
-    public void setAudioMode() {
-        Context context = getContext();
-        if (context == null) return;
-        AudioManager audioManager = (AudioManager)
-                context.getSystemService(Context.AUDIO_SERVICE);
-
-        // change the audio mode and request/abandon audio focus according to phone state,
-        // but only on audio mode transitions
-        switch (getState()) {
-            case RINGING:
-                if (audioManager.getMode() != AudioManager.MODE_RINGTONE) {
-                    // only request audio focus if the ringtone is going to be heard
-                    if (audioManager.getStreamVolume(AudioManager.STREAM_RING) > 0) {
-                        if (VDBG) Log.d(LOG_TAG, "requestAudioFocus on STREAM_RING");
-                        audioManager.requestAudioFocusForCall(AudioManager.STREAM_RING,
-                                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
-                    }
-                    audioManager.setMode(AudioManager.MODE_RINGTONE);
-                }
-                break;
-            case OFFHOOK:
-                Phone offhookPhone = getFgPhone();
-                if (getActiveFgCallState() == Call.State.IDLE) {
-                    // There is no active Fg calls, the OFFHOOK state
-                    // is set by the Bg call. So set the phone to bgPhone.
-                    offhookPhone = getBgPhone();
-                }
-
-                int newAudioMode = AudioManager.MODE_IN_CALL;
-                if (offhookPhone instanceof SipPhone) {
-                    // enable IN_COMMUNICATION audio mode instead for sipPhone
-                    newAudioMode = AudioManager.MODE_IN_COMMUNICATION;
-                }
-                if (audioManager.getMode() != newAudioMode) {
-                    // request audio focus before setting the new mode
-                    if (VDBG) Log.d(LOG_TAG, "requestAudioFocus on STREAM_VOICE_CALL");
-                    audioManager.requestAudioFocusForCall(AudioManager.STREAM_VOICE_CALL,
-                            AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
-                    audioManager.setMode(newAudioMode);
-                }
-                break;
-            case IDLE:
-                if (audioManager.getMode() != AudioManager.MODE_NORMAL) {
-                    audioManager.setMode(AudioManager.MODE_NORMAL);
-                    if (VDBG) Log.d(LOG_TAG, "abandonAudioFocus");
-                    // abandon audio focus after the mode has been set back to normal
-                    audioManager.abandonAudioFocusForCall();
-                }
-                break;
-        }
-    }
-
-    private Context getContext() {
-        Phone defaultPhone = getDefaultPhone();
-        return ((defaultPhone == null) ? null : defaultPhone.getContext());
-    }
-
-    private void registerForPhoneStates(Phone phone) {
-        // for common events supported by all phones
-        phone.registerForPreciseCallStateChanged(mHandler, EVENT_PRECISE_CALL_STATE_CHANGED, null);
-        phone.registerForDisconnect(mHandler, EVENT_DISCONNECT, null);
-        phone.registerForNewRingingConnection(mHandler, EVENT_NEW_RINGING_CONNECTION, null);
-        phone.registerForUnknownConnection(mHandler, EVENT_UNKNOWN_CONNECTION, null);
-        phone.registerForIncomingRing(mHandler, EVENT_INCOMING_RING, null);
-        phone.registerForRingbackTone(mHandler, EVENT_RINGBACK_TONE, null);
-        phone.registerForInCallVoicePrivacyOn(mHandler, EVENT_IN_CALL_VOICE_PRIVACY_ON, null);
-        phone.registerForInCallVoicePrivacyOff(mHandler, EVENT_IN_CALL_VOICE_PRIVACY_OFF, null);
-        phone.registerForDisplayInfo(mHandler, EVENT_DISPLAY_INFO, null);
-        phone.registerForSignalInfo(mHandler, EVENT_SIGNAL_INFO, null);
-        phone.registerForResendIncallMute(mHandler, EVENT_RESEND_INCALL_MUTE, null);
-        phone.registerForMmiInitiate(mHandler, EVENT_MMI_INITIATE, null);
-        phone.registerForMmiComplete(mHandler, EVENT_MMI_COMPLETE, null);
-        phone.registerForSuppServiceFailed(mHandler, EVENT_SUPP_SERVICE_FAILED, null);
-        phone.registerForServiceStateChanged(mHandler, EVENT_SERVICE_STATE_CHANGED, null);
-
-        // for events supported only by GSM and CDMA phone
-        if (phone.getPhoneType() == Phone.PHONE_TYPE_GSM ||
-                phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) {
-            phone.setOnPostDialCharacter(mHandler, EVENT_POST_DIAL_CHARACTER, null);
-        }
-
-        // for events supported only by CDMA phone
-        if (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA ){
-            phone.registerForCdmaOtaStatusChange(mHandler, EVENT_CDMA_OTA_STATUS_CHANGE, null);
-            phone.registerForSubscriptionInfoReady(mHandler, EVENT_SUBSCRIPTION_INFO_READY, null);
-            phone.registerForCallWaiting(mHandler, EVENT_CALL_WAITING, null);
-            phone.registerForEcmTimerReset(mHandler, EVENT_ECM_TIMER_RESET, null);
-        }
-    }
-
-    private void unregisterForPhoneStates(Phone phone) {
-        //  for common events supported by all phones
-        phone.unregisterForPreciseCallStateChanged(mHandler);
-        phone.unregisterForDisconnect(mHandler);
-        phone.unregisterForNewRingingConnection(mHandler);
-        phone.unregisterForUnknownConnection(mHandler);
-        phone.unregisterForIncomingRing(mHandler);
-        phone.unregisterForRingbackTone(mHandler);
-        phone.unregisterForInCallVoicePrivacyOn(mHandler);
-        phone.unregisterForInCallVoicePrivacyOff(mHandler);
-        phone.unregisterForDisplayInfo(mHandler);
-        phone.unregisterForSignalInfo(mHandler);
-        phone.unregisterForResendIncallMute(mHandler);
-        phone.unregisterForMmiInitiate(mHandler);
-        phone.unregisterForMmiComplete(mHandler);
-        phone.unregisterForSuppServiceFailed(mHandler);
-        phone.unregisterForServiceStateChanged(mHandler);
-
-        // for events supported only by GSM and CDMA phone
-        if (phone.getPhoneType() == Phone.PHONE_TYPE_GSM ||
-                phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) {
-            phone.setOnPostDialCharacter(null, EVENT_POST_DIAL_CHARACTER, null);
-        }
-
-        // for events supported only by CDMA phone
-        if (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA ){
-            phone.unregisterForCdmaOtaStatusChange(mHandler);
-            phone.unregisterForSubscriptionInfoReady(mHandler);
-            phone.unregisterForCallWaiting(mHandler);
-            phone.unregisterForEcmTimerReset(mHandler);
-        }
-    }
-
-    /**
-     * Answers a ringing or waiting call.
-     *
-     * Active call, if any, go on hold.
-     * If active call can't be held, i.e., a background call of the same channel exists,
-     * the active call will be hang up.
-     *
-     * Answering occurs asynchronously, and final notification occurs via
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}.
-     *
-     * @exception CallStateException when call is not ringing or waiting
-     */
-    public void acceptCall(Call ringingCall) throws CallStateException {
-        Phone ringingPhone = ringingCall.getPhone();
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "acceptCall(" +ringingCall + " from " + ringingCall.getPhone() + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if ( hasActiveFgCall() ) {
-            Phone activePhone = getActiveFgCall().getPhone();
-            boolean hasBgCall = ! (activePhone.getBackgroundCall().isIdle());
-            boolean sameChannel = (activePhone == ringingPhone);
-
-            if (VDBG) {
-                Log.d(LOG_TAG, "hasBgCall: "+ hasBgCall + "sameChannel:" + sameChannel);
-            }
-
-            if (sameChannel && hasBgCall) {
-                getActiveFgCall().hangup();
-            } else if (!sameChannel && !hasBgCall) {
-                activePhone.switchHoldingAndActive();
-            } else if (!sameChannel && hasBgCall) {
-                getActiveFgCall().hangup();
-            }
-        }
-
-        ringingPhone.acceptCall();
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End acceptCall(" +ringingCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-    }
-
-    /**
-     * Reject (ignore) a ringing call. In GSM, this means UDUB
-     * (User Determined User Busy). Reject occurs asynchronously,
-     * and final notification occurs via
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}.
-     *
-     * @exception CallStateException when no call is ringing or waiting
-     */
-    public void rejectCall(Call ringingCall) throws CallStateException {
-        if (VDBG) {
-            Log.d(LOG_TAG, "rejectCall(" +ringingCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        Phone ringingPhone = ringingCall.getPhone();
-
-        ringingPhone.rejectCall();
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End rejectCall(" +ringingCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-    }
-
-    /**
-     * Places active call on hold, and makes held call active.
-     * Switch occurs asynchronously and may fail.
-     *
-     * There are 4 scenarios
-     * 1. only active call but no held call, aka, hold
-     * 2. no active call but only held call, aka, unhold
-     * 3. both active and held calls from same phone, aka, swap
-     * 4. active and held calls from different phones, aka, phone swap
-     *
-     * Final notification occurs via
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}.
-     *
-     * @exception CallStateException if active call is ringing, waiting, or
-     * dialing/alerting, or heldCall can't be active.
-     * In these cases, this operation may not be performed.
-     */
-    public void switchHoldingAndActive(Call heldCall) throws CallStateException {
-        Phone activePhone = null;
-        Phone heldPhone = null;
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "switchHoldingAndActive(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (hasActiveFgCall()) {
-            activePhone = getActiveFgCall().getPhone();
-        }
-
-        if (heldCall != null) {
-            heldPhone = heldCall.getPhone();
-        }
-
-        if (activePhone != null) {
-            activePhone.switchHoldingAndActive();
-        }
-
-        if (heldPhone != null && heldPhone != activePhone) {
-            heldPhone.switchHoldingAndActive();
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End switchHoldingAndActive(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-    }
-
-    /**
-     * Hangup foreground call and resume the specific background call
-     *
-     * Note: this is noop if there is no foreground call or the heldCall is null
-     *
-     * @param heldCall to become foreground
-     * @throws CallStateException
-     */
-    public void hangupForegroundResumeBackground(Call heldCall) throws CallStateException {
-        Phone foregroundPhone = null;
-        Phone backgroundPhone = null;
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "hangupForegroundResumeBackground(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (hasActiveFgCall()) {
-            foregroundPhone = getFgPhone();
-            if (heldCall != null) {
-                backgroundPhone = heldCall.getPhone();
-                if (foregroundPhone == backgroundPhone) {
-                    getActiveFgCall().hangup();
-                } else {
-                // the call to be hangup and resumed belongs to different phones
-                    getActiveFgCall().hangup();
-                    switchHoldingAndActive(heldCall);
-                }
-            }
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End hangupForegroundResumeBackground(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-    }
-
-    /**
-     * Whether or not the phone can conference in the current phone
-     * state--that is, one call holding and one call active.
-     * @return true if the phone can conference; false otherwise.
-     */
-    public boolean canConference(Call heldCall) {
-        Phone activePhone = null;
-        Phone heldPhone = null;
-
-        if (hasActiveFgCall()) {
-            activePhone = getActiveFgCall().getPhone();
-        }
-
-        if (heldCall != null) {
-            heldPhone = heldCall.getPhone();
-        }
-
-        return heldPhone.getClass().equals(activePhone.getClass());
-    }
-
-    /**
-     * Conferences holding and active. Conference occurs asynchronously
-     * and may fail. Final notification occurs via
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}.
-     *
-     * @exception CallStateException if canConference() would return false.
-     * In these cases, this operation may not be performed.
-     */
-    public void conference(Call heldCall) throws CallStateException {
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "conference(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-
-        Phone fgPhone = getFgPhone();
-        if (fgPhone instanceof SipPhone) {
-            ((SipPhone) fgPhone).conference(heldCall);
-        } else if (canConference(heldCall)) {
-            fgPhone.conference();
-        } else {
-            throw(new CallStateException("Can't conference foreground and selected background call"));
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End conference(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-    }
-
-    /**
-     * Initiate a new voice connection. This happens asynchronously, so you
-     * cannot assume the audio path is connected (or a call index has been
-     * assigned) until PhoneStateChanged notification has occurred.
-     *
-     * @exception CallStateException if a new outgoing call is not currently
-     * possible because no more call slots exist or a call exists that is
-     * dialing, alerting, ringing, or waiting.  Other errors are
-     * handled asynchronously.
-     */
-    public Connection dial(Phone phone, String dialString) throws CallStateException {
-        Phone basePhone = getPhoneBase(phone);
-        Connection result;
-
-        if (VDBG) {
-            Log.d(LOG_TAG, " dial(" + basePhone + ", "+ dialString + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (!canDial(phone)) {
-            throw new CallStateException("cannot dial in current state");
-        }
-
-        if ( hasActiveFgCall() ) {
-            Phone activePhone = getActiveFgCall().getPhone();
-            boolean hasBgCall = !(activePhone.getBackgroundCall().isIdle());
-
-            if (DBG) {
-                Log.d(LOG_TAG, "hasBgCall: "+ hasBgCall + " sameChannel:" + (activePhone == basePhone));
-            }
-
-            if (activePhone != basePhone) {
-                if (hasBgCall) {
-                    Log.d(LOG_TAG, "Hangup");
-                    getActiveFgCall().hangup();
-                } else {
-                    Log.d(LOG_TAG, "Switch");
-                    activePhone.switchHoldingAndActive();
-                }
-            }
-        }
-
-        result = basePhone.dial(dialString);
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End dial(" + basePhone + ", "+ dialString + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        return result;
-    }
-
-    /**
-     * Initiate a new voice connection. This happens asynchronously, so you
-     * cannot assume the audio path is connected (or a call index has been
-     * assigned) until PhoneStateChanged notification has occurred.
-     *
-     * @exception CallStateException if a new outgoing call is not currently
-     * possible because no more call slots exist or a call exists that is
-     * dialing, alerting, ringing, or waiting.  Other errors are
-     * handled asynchronously.
-     */
-    public Connection dial(Phone phone, String dialString, UUSInfo uusInfo) throws CallStateException {
-        return phone.dial(dialString, uusInfo);
-    }
-
-    /**
-     * clear disconnect connection for each phone
-     */
-    public void clearDisconnected() {
-        for(Phone phone : mPhones) {
-            phone.clearDisconnected();
-        }
-    }
-
-    /**
-     * Phone can make a call only if ALL of the following are true:
-     *        - Phone is not powered off
-     *        - There's no incoming or waiting call
-     *        - There's available call slot in either foreground or background
-     *        - The foreground call is ACTIVE or IDLE or DISCONNECTED.
-     *          (We mainly need to make sure it *isn't* DIALING or ALERTING.)
-     * @param phone
-     * @return true if the phone can make a new call
-     */
-    private boolean canDial(Phone phone) {
-        int serviceState = phone.getServiceState().getState();
-        boolean hasRingingCall = hasActiveRingingCall();
-        boolean hasActiveCall = hasActiveFgCall();
-        boolean hasHoldingCall = hasActiveBgCall();
-        boolean allLinesTaken = hasActiveCall && hasHoldingCall;
-        Call.State fgCallState = getActiveFgCallState();
-
-        boolean result = (serviceState != ServiceState.STATE_POWER_OFF
-                && !hasRingingCall
-                && !allLinesTaken
-                && ((fgCallState == Call.State.ACTIVE)
-                    || (fgCallState == Call.State.IDLE)
-                    || (fgCallState == Call.State.DISCONNECTED)));
-
-        if (result == false) {
-            Log.d(LOG_TAG, "canDial serviceState=" + serviceState
-                            + " hasRingingCall=" + hasRingingCall
-                            + " hasActiveCall=" + hasActiveCall
-                            + " hasHoldingCall=" + hasHoldingCall
-                            + " allLinesTaken=" + allLinesTaken
-                            + " fgCallState=" + fgCallState);
-        }
-        return result;
-    }
-
-    /**
-     * Whether or not the phone can do explicit call transfer in the current
-     * phone state--that is, one call holding and one call active.
-     * @return true if the phone can do explicit call transfer; false otherwise.
-     */
-    public boolean canTransfer(Call heldCall) {
-        Phone activePhone = null;
-        Phone heldPhone = null;
-
-        if (hasActiveFgCall()) {
-            activePhone = getActiveFgCall().getPhone();
-        }
-
-        if (heldCall != null) {
-            heldPhone = heldCall.getPhone();
-        }
-
-        return (heldPhone == activePhone && activePhone.canTransfer());
-    }
-
-    /**
-     * Connects the held call and active call
-     * Disconnects the subscriber from both calls
-     *
-     * Explicit Call Transfer occurs asynchronously
-     * and may fail. Final notification occurs via
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}.
-     *
-     * @exception CallStateException if canTransfer() would return false.
-     * In these cases, this operation may not be performed.
-     */
-    public void explicitCallTransfer(Call heldCall) throws CallStateException {
-        if (VDBG) {
-            Log.d(LOG_TAG, " explicitCallTransfer(" + heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (canTransfer(heldCall)) {
-            heldCall.getPhone().explicitCallTransfer();
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End explicitCallTransfer(" + heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-    }
-
-    /**
-     * Returns a list of MMI codes that are pending for a phone. (They have initiated
-     * but have not yet completed).
-     * Presently there is only ever one.
-     *
-     * Use <code>registerForMmiInitiate</code>
-     * and <code>registerForMmiComplete</code> for change notification.
-     * @return null if phone doesn't have or support mmi code
-     */
-    public List<? extends MmiCode> getPendingMmiCodes(Phone phone) {
-        Log.e(LOG_TAG, "getPendingMmiCodes not implemented");
-        return null;
-    }
-
-    /**
-     * Sends user response to a USSD REQUEST message.  An MmiCode instance
-     * representing this response is sent to handlers registered with
-     * registerForMmiInitiate.
-     *
-     * @param ussdMessge    Message to send in the response.
-     * @return false if phone doesn't support ussd service
-     */
-    public boolean sendUssdResponse(Phone phone, String ussdMessge) {
-        Log.e(LOG_TAG, "sendUssdResponse not implemented");
-        return false;
-    }
-
-    /**
-     * Mutes or unmutes the microphone for the active call. The microphone
-     * is automatically unmuted if a call is answered, dialed, or resumed
-     * from a holding state.
-     *
-     * @param muted true to mute the microphone,
-     * false to activate the microphone.
-     */
-
-    public void setMute(boolean muted) {
-        if (VDBG) {
-            Log.d(LOG_TAG, " setMute(" + muted + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (hasActiveFgCall()) {
-            getActiveFgCall().getPhone().setMute(muted);
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End setMute(" + muted + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-    }
-
-    /**
-     * Gets current mute status. Use
-     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPreciseCallStateChanged()}
-     * as a change notifcation, although presently phone state changed is not
-     * fired when setMute() is called.
-     *
-     * @return true is muting, false is unmuting
-     */
-    public boolean getMute() {
-        if (hasActiveFgCall()) {
-            return getActiveFgCall().getPhone().getMute();
-        } else if (hasActiveBgCall()) {
-            return getFirstActiveBgCall().getPhone().getMute();
-        }
-        return false;
-    }
-
-    /**
-     * Enables or disables echo suppression.
-     */
-    public void setEchoSuppressionEnabled(boolean enabled) {
-        if (VDBG) {
-            Log.d(LOG_TAG, " setEchoSuppression(" + enabled + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (hasActiveFgCall()) {
-            getActiveFgCall().getPhone().setEchoSuppressionEnabled(enabled);
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End setEchoSuppression(" + enabled + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-    }
-
-    /**
-     * Play a DTMF tone on the active call.
-     *
-     * @param c should be one of 0-9, '*' or '#'. Other values will be
-     * silently ignored.
-     * @return false if no active call or the active call doesn't support
-     *         dtmf tone
-     */
-    public boolean sendDtmf(char c) {
-        boolean result = false;
-
-        if (VDBG) {
-            Log.d(LOG_TAG, " sendDtmf(" + c + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (hasActiveFgCall()) {
-            getActiveFgCall().getPhone().sendDtmf(c);
-            result = true;
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End sendDtmf(" + c + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-        return result;
-    }
-
-    /**
-     * Start to paly a DTMF tone on the active call.
-     * or there is a playing DTMF tone.
-     * @param c should be one of 0-9, '*' or '#'. Other values will be
-     * silently ignored.
-     *
-     * @return false if no active call or the active call doesn't support
-     *         dtmf tone
-     */
-    public boolean startDtmf(char c) {
-        boolean result = false;
-
-        if (VDBG) {
-            Log.d(LOG_TAG, " startDtmf(" + c + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (hasActiveFgCall()) {
-            getActiveFgCall().getPhone().startDtmf(c);
-            result = true;
-        }
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End startDtmf(" + c + ")");
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        return result;
-    }
-
-    /**
-     * Stop the playing DTMF tone. Ignored if there is no playing DTMF
-     * tone or no active call.
-     */
-    public void stopDtmf() {
-        if (VDBG) {
-            Log.d(LOG_TAG, " stopDtmf()" );
-            Log.d(LOG_TAG, this.toString());
-        }
-
-        if (hasActiveFgCall()) getFgPhone().stopDtmf();
-
-        if (VDBG) {
-            Log.d(LOG_TAG, "End stopDtmf()");
-            Log.d(LOG_TAG, this.toString());
-        }
-    }
-
-    /**
-     * send burst DTMF tone, it can send the string as single character or multiple character
-     * ignore if there is no active call or not valid digits string.
-     * Valid digit means only includes characters ISO-LATIN characters 0-9, *, #
-     * The difference between sendDtmf and sendBurstDtmf is sendDtmf only sends one character,
-     * this api can send single character and multiple character, also, this api has response
-     * back to caller.
-     *
-     * @param dtmfString is string representing the dialing digit(s) in the active call
-     * @param on the DTMF ON length in milliseconds, or 0 for default
-     * @param off the DTMF OFF length in milliseconds, or 0 for default
-     * @param onComplete is the callback message when the action is processed by BP
-     *
-     */
-    public boolean sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) {
-        if (hasActiveFgCall()) {
-            getActiveFgCall().getPhone().sendBurstDtmf(dtmfString, on, off, onComplete);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Notifies when a voice connection has disconnected, either due to local
-     * or remote hangup or error.
-     *
-     *  Messages received from this will have the following members:<p>
-     *  <ul><li>Message.obj will be an AsyncResult</li>
-     *  <li>AsyncResult.userObj = obj</li>
-     *  <li>AsyncResult.result = a Connection object that is
-     *  no longer connected.</li></ul>
-     */
-    public void registerForDisconnect(Handler h, int what, Object obj) {
-        mDisconnectRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for voice disconnection notification.
-     * Extraneous calls are tolerated silently
-     */
-    public void unregisterForDisconnect(Handler h){
-        mDisconnectRegistrants.remove(h);
-    }
-
-    /**
-     * Register for getting notifications for change in the Call State {@link Call.State}
-     * This is called PreciseCallState because the call state is more precise than the
-     * {@link Phone.State} which can be obtained using the {@link PhoneStateListener}
-     *
-     * Resulting events will have an AsyncResult in <code>Message.obj</code>.
-     * AsyncResult.userData will be set to the obj argument here.
-     * The <em>h</em> parameter is held only by a weak reference.
-     */
-    public void registerForPreciseCallStateChanged(Handler h, int what, Object obj){
-        mPreciseCallStateRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for voice call state change notifications.
-     * Extraneous calls are tolerated silently.
-     */
-    public void unregisterForPreciseCallStateChanged(Handler h){
-        mPreciseCallStateRegistrants.remove(h);
-    }
-
-    /**
-     * Notifies when a previously untracked non-ringing/waiting connection has appeared.
-     * This is likely due to some other entity (eg, SIM card application) initiating a call.
-     */
-    public void registerForUnknownConnection(Handler h, int what, Object obj){
-        mUnknownConnectionRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for unknown connection notifications.
-     */
-    public void unregisterForUnknownConnection(Handler h){
-        mUnknownConnectionRegistrants.remove(h);
-    }
-
-
-    /**
-     * Notifies when a new ringing or waiting connection has appeared.<p>
-     *
-     *  Messages received from this:
-     *  Message.obj will be an AsyncResult
-     *  AsyncResult.userObj = obj
-     *  AsyncResult.result = a Connection. <p>
-     *  Please check Connection.isRinging() to make sure the Connection
-     *  has not dropped since this message was posted.
-     *  If Connection.isRinging() is true, then
-     *   Connection.getCall() == Phone.getRingingCall()
-     */
-    public void registerForNewRingingConnection(Handler h, int what, Object obj){
-        mNewRingingConnectionRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for new ringing connection notification.
-     * Extraneous calls are tolerated silently
-     */
-
-    public void unregisterForNewRingingConnection(Handler h){
-        mNewRingingConnectionRegistrants.remove(h);
-    }
-
-    /**
-     * Notifies when an incoming call rings.<p>
-     *
-     *  Messages received from this:
-     *  Message.obj will be an AsyncResult
-     *  AsyncResult.userObj = obj
-     *  AsyncResult.result = a Connection. <p>
-     */
-    public void registerForIncomingRing(Handler h, int what, Object obj){
-        mIncomingRingRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for ring notification.
-     * Extraneous calls are tolerated silently
-     */
-
-    public void unregisterForIncomingRing(Handler h){
-        mIncomingRingRegistrants.remove(h);
-    }
-
-    /**
-     * Notifies when out-band ringback tone is needed.<p>
-     *
-     *  Messages received from this:
-     *  Message.obj will be an AsyncResult
-     *  AsyncResult.userObj = obj
-     *  AsyncResult.result = boolean, true to start play ringback tone
-     *                       and false to stop. <p>
-     */
-    public void registerForRingbackTone(Handler h, int what, Object obj){
-        mRingbackToneRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for ringback tone notification.
-     */
-
-    public void unregisterForRingbackTone(Handler h){
-        mRingbackToneRegistrants.remove(h);
-    }
-
-    /**
-     * Registers the handler to reset the uplink mute state to get
-     * uplink audio.
-     */
-    public void registerForResendIncallMute(Handler h, int what, Object obj){
-        mResendIncallMuteRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for resend incall mute notifications.
-     */
-    public void unregisterForResendIncallMute(Handler h){
-        mResendIncallMuteRegistrants.remove(h);
-    }
-
-    /**
-     * Register for notifications of initiation of a new MMI code request.
-     * MMI codes for GSM are discussed in 3GPP TS 22.030.<p>
-     *
-     * Example: If Phone.dial is called with "*#31#", then the app will
-     * be notified here.<p>
-     *
-     * The returned <code>Message.obj</code> will contain an AsyncResult.
-     *
-     * <code>obj.result</code> will be an "MmiCode" object.
-     */
-    public void registerForMmiInitiate(Handler h, int what, Object obj){
-        mMmiInitiateRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for new MMI initiate notification.
-     * Extraneous calls are tolerated silently
-     */
-    public void unregisterForMmiInitiate(Handler h){
-        mMmiInitiateRegistrants.remove(h);
-    }
-
-    /**
-     * Register for notifications that an MMI request has completed
-     * its network activity and is in its final state. This may mean a state
-     * of COMPLETE, FAILED, or CANCELLED.
-     *
-     * <code>Message.obj</code> will contain an AsyncResult.
-     * <code>obj.result</code> will be an "MmiCode" object
-     */
-    public void registerForMmiComplete(Handler h, int what, Object obj){
-        mMmiCompleteRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for MMI complete notification.
-     * Extraneous calls are tolerated silently
-     */
-    public void unregisterForMmiComplete(Handler h){
-        mMmiCompleteRegistrants.remove(h);
-    }
-
-    /**
-     * Registration point for Ecm timer reset
-     * @param h handler to notify
-     * @param what user-defined message code
-     * @param obj placed in Message.obj
-     */
-    public void registerForEcmTimerReset(Handler h, int what, Object obj){
-        mEcmTimerResetRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregister for notification for Ecm timer reset
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForEcmTimerReset(Handler h){
-        mEcmTimerResetRegistrants.remove(h);
-    }
-
-    /**
-     * Register for ServiceState changed.
-     * Message.obj will contain an AsyncResult.
-     * AsyncResult.result will be a ServiceState instance
-     */
-    public void registerForServiceStateChanged(Handler h, int what, Object obj){
-        mServiceStateChangedRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for ServiceStateChange notification.
-     * Extraneous calls are tolerated silently
-     */
-    public void unregisterForServiceStateChanged(Handler h){
-        mServiceStateChangedRegistrants.remove(h);
-    }
-
-    /**
-     * Register for notifications when a supplementary service attempt fails.
-     * Message.obj will contain an AsyncResult.
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    public void registerForSuppServiceFailed(Handler h, int what, Object obj){
-        mSuppServiceFailedRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregister for notifications when a supplementary service attempt fails.
-     * Extraneous calls are tolerated silently
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForSuppServiceFailed(Handler h){
-        mSuppServiceFailedRegistrants.remove(h);
-    }
-
-    /**
-     * Register for notifications when a sInCall VoicePrivacy is enabled
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){
-        mInCallVoicePrivacyOnRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregister for notifications when a sInCall VoicePrivacy is enabled
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForInCallVoicePrivacyOn(Handler h){
-        mInCallVoicePrivacyOnRegistrants.remove(h);
-    }
-
-    /**
-     * Register for notifications when a sInCall VoicePrivacy is disabled
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){
-        mInCallVoicePrivacyOffRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregister for notifications when a sInCall VoicePrivacy is disabled
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForInCallVoicePrivacyOff(Handler h){
-        mInCallVoicePrivacyOffRegistrants.remove(h);
-    }
-
-    /**
-     * Register for notifications when CDMA call waiting comes
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    public void registerForCallWaiting(Handler h, int what, Object obj){
-        mCallWaitingRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregister for notifications when CDMA Call waiting comes
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForCallWaiting(Handler h){
-        mCallWaitingRegistrants.remove(h);
-    }
-
-
-    /**
-     * Register for signal information notifications from the network.
-     * Message.obj will contain an AsyncResult.
-     * AsyncResult.result will be a SuppServiceNotification instance.
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-
-    public void registerForSignalInfo(Handler h, int what, Object obj){
-        mSignalInfoRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for signal information notifications.
-     * Extraneous calls are tolerated silently
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForSignalInfo(Handler h){
-        mSignalInfoRegistrants.remove(h);
-    }
-
-    /**
-     * Register for display information notifications from the network.
-     * Message.obj will contain an AsyncResult.
-     * AsyncResult.result will be a SuppServiceNotification instance.
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    public void registerForDisplayInfo(Handler h, int what, Object obj){
-        mDisplayInfoRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregisters for display information notifications.
-     * Extraneous calls are tolerated silently
-     *
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForDisplayInfo(Handler h) {
-        mDisplayInfoRegistrants.remove(h);
-    }
-
-    /**
-     * Register for notifications when CDMA OTA Provision status change
-     *
-     * @param h Handler that receives the notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj){
-        mCdmaOtaStatusChangeRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregister for notifications when CDMA OTA Provision status change
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForCdmaOtaStatusChange(Handler h){
-        mCdmaOtaStatusChangeRegistrants.remove(h);
-    }
-
-    /**
-     * Registration point for subscription info ready
-     * @param h handler to notify
-     * @param what what code of message when delivered
-     * @param obj placed in Message.obj
-     */
-    public void registerForSubscriptionInfoReady(Handler h, int what, Object obj){
-        mSubscriptionInfoReadyRegistrants.addUnique(h, what, obj);
-    }
-
-    /**
-     * Unregister for notifications for subscription info
-     * @param h Handler to be removed from the registrant list.
-     */
-    public void unregisterForSubscriptionInfoReady(Handler h){
-        mSubscriptionInfoReadyRegistrants.remove(h);
-    }
-
-    /**
-     * Sets an event to be fired when the telephony system processes
-     * a post-dial character on an outgoing call.<p>
-     *
-     * Messages of type <code>what</code> will be sent to <code>h</code>.
-     * The <code>obj</code> field of these Message's will be instances of
-     * <code>AsyncResult</code>. <code>Message.obj.result</code> will be
-     * a Connection object.<p>
-     *
-     * Message.arg1 will be the post dial character being processed,
-     * or 0 ('\0') if end of string.<p>
-     *
-     * If Connection.getPostDialState() == WAIT,
-     * the application must call
-     * {@link com.android.internal.telephony.Connection#proceedAfterWaitChar()
-     * Connection.proceedAfterWaitChar()} or
-     * {@link com.android.internal.telephony.Connection#cancelPostDial()
-     * Connection.cancelPostDial()}
-     * for the telephony system to continue playing the post-dial
-     * DTMF sequence.<p>
-     *
-     * If Connection.getPostDialState() == WILD,
-     * the application must call
-     * {@link com.android.internal.telephony.Connection#proceedAfterWildChar
-     * Connection.proceedAfterWildChar()}
-     * or
-     * {@link com.android.internal.telephony.Connection#cancelPostDial()
-     * Connection.cancelPostDial()}
-     * for the telephony system to continue playing the
-     * post-dial DTMF sequence.<p>
-     *
-     */
-    public void registerForPostDialCharacter(Handler h, int what, Object obj){
-        mPostDialCharacterRegistrants.addUnique(h, what, obj);
-    }
-
-    public void unregisterForPostDialCharacter(Handler h){
-        mPostDialCharacterRegistrants.remove(h);
-    }
-
-    /* APIs to access foregroudCalls, backgroudCalls, and ringingCalls
-     * 1. APIs to access list of calls
-     * 2. APIs to check if any active call, which has connection other than
-     * disconnected ones, pleaser refer to Call.isIdle()
-     * 3. APIs to return first active call
-     * 4. APIs to return the connections of first active call
-     * 5. APIs to return other property of first active call
-     */
-
-    /**
-     * @return list of all ringing calls
-     */
-    public List<Call> getRingingCalls() {
-        return Collections.unmodifiableList(mRingingCalls);
-    }
-
-    /**
-     * @return list of all foreground calls
-     */
-    public List<Call> getForegroundCalls() {
-        return Collections.unmodifiableList(mForegroundCalls);
-    }
-
-    /**
-     * @return list of all background calls
-     */
-    public List<Call> getBackgroundCalls() {
-        return Collections.unmodifiableList(mBackgroundCalls);
-    }
-
-    /**
-     * Return true if there is at least one active foreground call
-     */
-    public boolean hasActiveFgCall() {
-        return (getFirstActiveCall(mForegroundCalls) != null);
-    }
-
-    /**
-     * Return true if there is at least one active background call
-     */
-    public boolean hasActiveBgCall() {
-        // TODO since hasActiveBgCall may get called often
-        // better to cache it to improve performance
-        return (getFirstActiveCall(mBackgroundCalls) != null);
-    }
-
-    /**
-     * Return true if there is at least one active ringing call
-     *
-     */
-    public boolean hasActiveRingingCall() {
-        return (getFirstActiveCall(mRingingCalls) != null);
-    }
-
-    /**
-     * return the active foreground call from foreground calls
-     *
-     * Active call means the call is NOT in Call.State.IDLE
-     *
-     * 1. If there is active foreground call, return it
-     * 2. If there is no active foreground call, return the
-     *    foreground call associated with default phone, which state is IDLE.
-     * 3. If there is no phone registered at all, return null.
-     *
-     */
-    public Call getActiveFgCall() {
-        Call call = getFirstNonIdleCall(mForegroundCalls);
-        if (call == null) {
-            call = (mDefaultPhone == null)
-                    ? null
-                    : mDefaultPhone.getForegroundCall();
-        }
-        return call;
-    }
-
-    // Returns the first call that is not in IDLE state. If both active calls
-    // and disconnecting/disconnected calls exist, return the first active call.
-    private Call getFirstNonIdleCall(List<Call> calls) {
-        Call result = null;
-        for (Call call : calls) {
-            if (!call.isIdle()) {
-                return call;
-            } else if (call.getState() != Call.State.IDLE) {
-                if (result == null) result = call;
-            }
-        }
-        return result;
-    }
-
-    /**
-     * return one active background call from background calls
-     *
-     * Active call means the call is NOT idle defined by Call.isIdle()
-     *
-     * 1. If there is only one active background call, return it
-     * 2. If there is more than one active background call, return the first one
-     * 3. If there is no active background call, return the background call
-     *    associated with default phone, which state is IDLE.
-     * 4. If there is no background call at all, return null.
-     *
-     * Complete background calls list can be get by getBackgroundCalls()
-     */
-    public Call getFirstActiveBgCall() {
-        Call call = getFirstNonIdleCall(mBackgroundCalls);
-        if (call == null) {
-            call = (mDefaultPhone == null)
-                    ? null
-                    : mDefaultPhone.getBackgroundCall();
-        }
-        return call;
-    }
-
-    /**
-     * return one active ringing call from ringing calls
-     *
-     * Active call means the call is NOT idle defined by Call.isIdle()
-     *
-     * 1. If there is only one active ringing call, return it
-     * 2. If there is more than one active ringing call, return the first one
-     * 3. If there is no active ringing call, return the ringing call
-     *    associated with default phone, which state is IDLE.
-     * 4. If there is no ringing call at all, return null.
-     *
-     * Complete ringing calls list can be get by getRingingCalls()
-     */
-    public Call getFirstActiveRingingCall() {
-        Call call = getFirstNonIdleCall(mRingingCalls);
-        if (call == null) {
-            call = (mDefaultPhone == null)
-                    ? null
-                    : mDefaultPhone.getRingingCall();
-        }
-        return call;
-    }
-
-    /**
-     * @return the state of active foreground call
-     * return IDLE if there is no active foreground call
-     */
-    public Call.State getActiveFgCallState() {
-        Call fgCall = getActiveFgCall();
-
-        if (fgCall != null) {
-            return fgCall.getState();
-        }
-
-        return Call.State.IDLE;
-    }
-
-    /**
-     * @return the connections of active foreground call
-     * return empty list if there is no active foreground call
-     */
-    public List<Connection> getFgCallConnections() {
-        Call fgCall = getActiveFgCall();
-        if ( fgCall != null) {
-            return fgCall.getConnections();
-        }
-        return emptyConnections;
-    }
-
-    /**
-     * @return the connections of active background call
-     * return empty list if there is no active background call
-     */
-    public List<Connection> getBgCallConnections() {
-        Call bgCall = getFirstActiveBgCall();
-        if ( bgCall != null) {
-            return bgCall.getConnections();
-        }
-        return emptyConnections;
-    }
-
-    /**
-     * @return the latest connection of active foreground call
-     * return null if there is no active foreground call
-     */
-    public Connection getFgCallLatestConnection() {
-        Call fgCall = getActiveFgCall();
-        if ( fgCall != null) {
-            return fgCall.getLatestConnection();
-        }
-        return null;
-    }
-
-    /**
-     * @return true if there is at least one Foreground call in disconnected state
-     */
-    public boolean hasDisconnectedFgCall() {
-        return (getFirstCallOfState(mForegroundCalls, Call.State.DISCONNECTED) != null);
-    }
-
-    /**
-     * @return true if there is at least one background call in disconnected state
-     */
-    public boolean hasDisconnectedBgCall() {
-        return (getFirstCallOfState(mBackgroundCalls, Call.State.DISCONNECTED) != null);
-    }
-
-    /**
-     * @return the first active call from a call list
-     */
-    private  Call getFirstActiveCall(ArrayList<Call> calls) {
-        for (Call call : calls) {
-            if (!call.isIdle()) {
-                return call;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * @return the first call in a the Call.state from a call list
-     */
-    private Call getFirstCallOfState(ArrayList<Call> calls, Call.State state) {
-        for (Call call : calls) {
-            if (call.getState() == state) {
-                return call;
-            }
-        }
-        return null;
-    }
-
-
-    private boolean hasMoreThanOneRingingCall() {
-        int count = 0;
-        for (Call call : mRingingCalls) {
-            if (call.getState().isRinging()) {
-                if (++count > 1) return true;
-            }
-        }
-        return false;
-    }
-
-    private Handler mHandler = new Handler() {
-
-        @Override
-        public void handleMessage(Message msg) {
-
-            switch (msg.what) {
-                case EVENT_DISCONNECT:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_DISCONNECT)");
-                    mDisconnectRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_PRECISE_CALL_STATE_CHANGED:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_PRECISE_CALL_STATE_CHANGED)");
-                    mPreciseCallStateRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_NEW_RINGING_CONNECTION:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_NEW_RINGING_CONNECTION)");
-                    if (getActiveFgCallState().isDialing() || hasMoreThanOneRingingCall()) {
-                        Connection c = (Connection) ((AsyncResult) msg.obj).result;
-                        try {
-                            Log.d(LOG_TAG, "silently drop incoming call: " + c.getCall());
-                            c.getCall().hangup();
-                        } catch (CallStateException e) {
-                            Log.w(LOG_TAG, "new ringing connection", e);
-                        }
-                    } else {
-                        mNewRingingConnectionRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    }
-                    break;
-                case EVENT_UNKNOWN_CONNECTION:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_UNKNOWN_CONNECTION)");
-                    mUnknownConnectionRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_INCOMING_RING:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_INCOMING_RING)");
-                    // The event may come from RIL who's not aware of an ongoing fg call
-                    if (!hasActiveFgCall()) {
-                        mIncomingRingRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    }
-                    break;
-                case EVENT_RINGBACK_TONE:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_RINGBACK_TONE)");
-                    mRingbackToneRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_IN_CALL_VOICE_PRIVACY_ON:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_IN_CALL_VOICE_PRIVACY_ON)");
-                    mInCallVoicePrivacyOnRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_IN_CALL_VOICE_PRIVACY_OFF:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_IN_CALL_VOICE_PRIVACY_OFF)");
-                    mInCallVoicePrivacyOffRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_CALL_WAITING:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_CALL_WAITING)");
-                    mCallWaitingRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_DISPLAY_INFO:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_DISPLAY_INFO)");
-                    mDisplayInfoRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_SIGNAL_INFO:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SIGNAL_INFO)");
-                    mSignalInfoRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_CDMA_OTA_STATUS_CHANGE:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_CDMA_OTA_STATUS_CHANGE)");
-                    mCdmaOtaStatusChangeRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_RESEND_INCALL_MUTE:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_RESEND_INCALL_MUTE)");
-                    mResendIncallMuteRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_MMI_INITIATE:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_MMI_INITIATE)");
-                    mMmiInitiateRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_MMI_COMPLETE:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_MMI_COMPLETE)");
-                    mMmiCompleteRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_ECM_TIMER_RESET:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_ECM_TIMER_RESET)");
-                    mEcmTimerResetRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_SUBSCRIPTION_INFO_READY:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SUBSCRIPTION_INFO_READY)");
-                    mSubscriptionInfoReadyRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_SUPP_SERVICE_FAILED:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SUPP_SERVICE_FAILED)");
-                    mSuppServiceFailedRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_SERVICE_STATE_CHANGED:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SERVICE_STATE_CHANGED)");
-                    mServiceStateChangedRegistrants.notifyRegistrants((AsyncResult) msg.obj);
-                    break;
-                case EVENT_POST_DIAL_CHARACTER:
-                    // we need send the character that is being processed in msg.arg1
-                    // so can't use notifyRegistrants()
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_POST_DIAL_CHARACTER)");
-                    for(int i=0; i < mPostDialCharacterRegistrants.size(); i++) {
-                        Message notifyMsg;
-                        notifyMsg = ((Registrant)mPostDialCharacterRegistrants.get(i)).messageForRegistrant();
-                        notifyMsg.obj = msg.obj;
-                        notifyMsg.arg1 = msg.arg1;
-                        notifyMsg.sendToTarget();
-                    }
-                    break;
-            }
-        }
-    };
-
-    @Override
-    public String toString() {
-        Call call;
-        StringBuilder b = new StringBuilder();
-
-        b.append("CallManager {");
-        b.append("\nstate = " + getState());
-        call = getActiveFgCall();
-        b.append("\n- Foreground: " + getActiveFgCallState());
-        b.append(" from " + call.getPhone());
-        b.append("\n  Conn: ").append(getFgCallConnections());
-        call = getFirstActiveBgCall();
-        b.append("\n- Background: " + call.getState());
-        b.append(" from " + call.getPhone());
-        b.append("\n  Conn: ").append(getBgCallConnections());
-        call = getFirstActiveRingingCall();
-        b.append("\n- Ringing: " +call.getState());
-        b.append(" from " + call.getPhone());
-
-        for (Phone phone : getAllPhones()) {
-            if (phone != null) {
-                b.append("\nPhone: " + phone + ", name = " + phone.getPhoneName()
-                        + ", state = " + phone.getState());
-                call = phone.getForegroundCall();
-                b.append("\n- Foreground: ").append(call);
-                call = phone.getBackgroundCall();
-                b.append(" Background: ").append(call);
-                call = phone.getRingingCall();
-                b.append(" Ringing: ").append(call);
-            }
-        }
-        b.append("\n}");
-        return b.toString();
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/CallStateException.java b/telephony/java/com/android/internal/telephony/CallStateException.java
deleted file mode 100644
index 6087124..0000000
--- a/telephony/java/com/android/internal/telephony/CallStateException.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-/**
- * {@hide}
- */
-public class CallStateException extends Exception
-{
-    public
-    CallStateException()
-    {
-    }
-
-    public
-    CallStateException(String string)
-    {
-        super(string);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/CallTracker.java b/telephony/java/com/android/internal/telephony/CallTracker.java
deleted file mode 100644
index 62caf01..0000000
--- a/telephony/java/com/android/internal/telephony/CallTracker.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.telephony.CommandException;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-
-/**
- * {@hide}
- */
-public abstract class CallTracker extends Handler {
-
-    private static final boolean DBG_POLL = false;
-
-    //***** Constants
-
-    static final int POLL_DELAY_MSEC = 250;
-
-    protected int pendingOperations;
-    protected boolean needsPoll;
-    protected Message lastRelevantPoll;
-
-    public CommandsInterface cm;
-
-
-    //***** Events
-
-    protected static final int EVENT_POLL_CALLS_RESULT             = 1;
-    protected static final int EVENT_CALL_STATE_CHANGE             = 2;
-    protected static final int EVENT_REPOLL_AFTER_DELAY            = 3;
-    protected static final int EVENT_OPERATION_COMPLETE            = 4;
-    protected static final int EVENT_GET_LAST_CALL_FAIL_CAUSE      = 5;
-
-    protected static final int EVENT_SWITCH_RESULT                 = 8;
-    protected static final int EVENT_RADIO_AVAILABLE               = 9;
-    protected static final int EVENT_RADIO_NOT_AVAILABLE           = 10;
-    protected static final int EVENT_CONFERENCE_RESULT             = 11;
-    protected static final int EVENT_SEPARATE_RESULT               = 12;
-    protected static final int EVENT_ECT_RESULT                    = 13;
-    protected static final int EVENT_EXIT_ECM_RESPONSE_CDMA        = 14;
-    protected static final int EVENT_CALL_WAITING_INFO_CDMA        = 15;
-    protected static final int EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA = 16;
-
-    protected void pollCallsWhenSafe() {
-        needsPoll = true;
-
-        if (checkNoOperationsPending()) {
-            lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
-            cm.getCurrentCalls(lastRelevantPoll);
-        }
-    }
-
-    protected void
-    pollCallsAfterDelay() {
-        Message msg = obtainMessage();
-
-        msg.what = EVENT_REPOLL_AFTER_DELAY;
-        sendMessageDelayed(msg, POLL_DELAY_MSEC);
-    }
-
-    protected boolean
-    isCommandExceptionRadioNotAvailable(Throwable e) {
-        return e != null && e instanceof CommandException
-                && ((CommandException)e).getCommandError()
-                        == CommandException.Error.RADIO_NOT_AVAILABLE;
-    }
-
-    protected abstract void handlePollCalls(AsyncResult ar);
-
-    protected void handleRadioAvailable() {
-        pollCallsWhenSafe();
-    }
-
-    /**
-     * Obtain a complete message that indicates that this operation
-     * does not require polling of getCurrentCalls(). However, if other
-     * operations that do need getCurrentCalls() are pending or are
-     * scheduled while this operation is pending, the invocation
-     * of getCurrentCalls() will be postponed until this
-     * operation is also complete.
-     */
-    protected Message
-    obtainNoPollCompleteMessage(int what) {
-        pendingOperations++;
-        lastRelevantPoll = null;
-        return obtainMessage(what);
-    }
-
-    /**
-     * @return true if we're idle or there's a call to getCurrentCalls() pending
-     * but nothing else
-     */
-    private boolean
-    checkNoOperationsPending() {
-        if (DBG_POLL) log("checkNoOperationsPending: pendingOperations=" +
-                pendingOperations);
-        return pendingOperations == 0;
-    }
-
-    /**
-     * Routine called from dial to check if the number is a test Emergency number
-     * and if so remap the number. This allows a short emergency number to be remapped
-     * to a regular number for testing how the frameworks handles emergency numbers
-     * without actually calling an emergency number.
-     *
-     * This is not a full test and is not a substitute for testing real emergency
-     * numbers but can be useful.
-     *
-     * To use this feature set a system property ril.test.emergencynumber to a pair of
-     * numbers separated by a colon. If the first number matches the number parameter
-     * this routine returns the second number. Example:
-     *
-     * ril.test.emergencynumber=112:1-123-123-45678
-     *
-     * To test Dial 112 take call then hang up on MO device to enter ECM
-     * see RIL#processSolicited RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND
-     *
-     * @param number to test if it should be remapped
-     * @return the same number or the remapped number.
-     */
-    protected String checkForTestEmergencyNumber(String dialString) {
-        String testEn = SystemProperties.get("ril.test.emergencynumber");
-        if (DBG_POLL) {
-            log("checkForTestEmergencyNumber: dialString=" + dialString +
-                " testEn=" + testEn);
-        }
-        if (!TextUtils.isEmpty(testEn)) {
-            String values[] = testEn.split(":");
-            log("checkForTestEmergencyNumber: values.length=" + values.length);
-            if (values.length == 2) {
-                if (values[0].equals(
-                        android.telephony.PhoneNumberUtils.stripSeparators(dialString))) {
-                    cm.testingEmergencyCall();
-                    log("checkForTestEmergencyNumber: remap " +
-                            dialString + " to " + values[1]);
-                    dialString = values[1];
-                }
-            }
-        }
-        return dialString;
-    }
-
-    //***** Overridden from Handler
-    public abstract void handleMessage (Message msg);
-    public abstract void registerForVoiceCallStarted(Handler h, int what, Object obj);
-    public abstract void unregisterForVoiceCallStarted(Handler h);
-    public abstract void registerForVoiceCallEnded(Handler h, int what, Object obj);
-    public abstract void unregisterForVoiceCallEnded(Handler h);
-
-    protected abstract void log(String msg);
-
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("CallTracker:");
-        pw.println(" pendingOperations=" + pendingOperations);
-        pw.println(" needsPoll=" + needsPoll);
-        pw.println(" lastRelevantPoll=" + lastRelevantPoll);
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/CommandException.java b/telephony/java/com/android/internal/telephony/CommandException.java
deleted file mode 100644
index 94c544e..0000000
--- a/telephony/java/com/android/internal/telephony/CommandException.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import com.android.internal.telephony.RILConstants;
-
-import android.util.Log;
-
-/**
- * {@hide}
- */
-public class CommandException extends RuntimeException {
-    private Error e;
-
-    public enum Error {
-        INVALID_RESPONSE,
-        RADIO_NOT_AVAILABLE,
-        GENERIC_FAILURE,
-        PASSWORD_INCORRECT,
-        SIM_PIN2,
-        SIM_PUK2,
-        REQUEST_NOT_SUPPORTED,
-        OP_NOT_ALLOWED_DURING_VOICE_CALL,
-        OP_NOT_ALLOWED_BEFORE_REG_NW,
-        SMS_FAIL_RETRY,
-        SIM_ABSENT,
-        SUBSCRIPTION_NOT_AVAILABLE,
-        MODE_NOT_SUPPORTED,
-        FDN_CHECK_FAILURE,
-        ILLEGAL_SIM_OR_ME,
-    }
-
-    public CommandException(Error e) {
-        super(e.toString());
-        this.e = e;
-    }
-
-    public static CommandException
-    fromRilErrno(int ril_errno) {
-        switch(ril_errno) {
-            case RILConstants.SUCCESS:                       return null;
-            case RILConstants.RIL_ERRNO_INVALID_RESPONSE:
-                return new CommandException(Error.INVALID_RESPONSE);
-            case RILConstants.RADIO_NOT_AVAILABLE:
-                return new CommandException(Error.RADIO_NOT_AVAILABLE);
-            case RILConstants.GENERIC_FAILURE:
-                return new CommandException(Error.GENERIC_FAILURE);
-            case RILConstants.PASSWORD_INCORRECT:
-                return new CommandException(Error.PASSWORD_INCORRECT);
-            case RILConstants.SIM_PIN2:
-                return new CommandException(Error.SIM_PIN2);
-            case RILConstants.SIM_PUK2:
-                return new CommandException(Error.SIM_PUK2);
-            case RILConstants.REQUEST_NOT_SUPPORTED:
-                return new CommandException(Error.REQUEST_NOT_SUPPORTED);
-            case RILConstants.OP_NOT_ALLOWED_DURING_VOICE_CALL:
-                return new CommandException(Error.OP_NOT_ALLOWED_DURING_VOICE_CALL);
-            case RILConstants.OP_NOT_ALLOWED_BEFORE_REG_NW:
-                return new CommandException(Error.OP_NOT_ALLOWED_BEFORE_REG_NW);
-            case RILConstants.SMS_SEND_FAIL_RETRY:
-                return new CommandException(Error.SMS_FAIL_RETRY);
-            case RILConstants.SIM_ABSENT:
-                return new CommandException(Error.SIM_ABSENT);
-            case RILConstants.SUBSCRIPTION_NOT_AVAILABLE:
-                return new CommandException(Error.SUBSCRIPTION_NOT_AVAILABLE);
-            case RILConstants.MODE_NOT_SUPPORTED:
-                return new CommandException(Error.MODE_NOT_SUPPORTED);
-            case RILConstants.FDN_CHECK_FAILURE:
-                return new CommandException(Error.FDN_CHECK_FAILURE);
-            case RILConstants.ILLEGAL_SIM_OR_ME:
-                return new CommandException(Error.ILLEGAL_SIM_OR_ME);
-            default:
-                Log.e("GSM", "Unrecognized RIL errno " + ril_errno);
-                return new CommandException(Error.INVALID_RESPONSE);
-        }
-    }
-
-    public Error getCommandError() {
-        return e;
-    }
-
-
-
-}
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
deleted file mode 100644
index f7757b3..0000000
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ /dev/null
@@ -1,1579 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
-
-import android.os.Message;
-import android.os.Handler;
-import android.util.Log;
-
-/**
- * {@hide}
- */
-public interface CommandsInterface {
-    enum RadioState {
-        RADIO_OFF,         /* Radio explicitly powered off (eg CFUN=0) */
-        RADIO_UNAVAILABLE, /* Radio unavailable (eg, resetting or not booted) */
-        RADIO_ON;          /* Radio is on */
-
-        public boolean isOn() /* and available...*/ {
-            return this == RADIO_ON;
-        }
-
-        public boolean isAvailable() {
-            return this != RADIO_UNAVAILABLE;
-        }
-    }
-
-    //***** Constants
-
-    // Used as parameter to dial() and setCLIR() below
-    static final int CLIR_DEFAULT = 0;      // "use subscription default value"
-    static final int CLIR_INVOCATION = 1;   // (restrict CLI presentation)
-    static final int CLIR_SUPPRESSION = 2;  // (allow CLI presentation)
-
-
-    // Used as parameters for call forward methods below
-    static final int CF_ACTION_DISABLE          = 0;
-    static final int CF_ACTION_ENABLE           = 1;
-//  static final int CF_ACTION_UNUSED           = 2;
-    static final int CF_ACTION_REGISTRATION     = 3;
-    static final int CF_ACTION_ERASURE          = 4;
-
-    static final int CF_REASON_UNCONDITIONAL    = 0;
-    static final int CF_REASON_BUSY             = 1;
-    static final int CF_REASON_NO_REPLY         = 2;
-    static final int CF_REASON_NOT_REACHABLE    = 3;
-    static final int CF_REASON_ALL              = 4;
-    static final int CF_REASON_ALL_CONDITIONAL  = 5;
-
-    // Used for call barring methods below
-    static final String CB_FACILITY_BAOC         = "AO";
-    static final String CB_FACILITY_BAOIC        = "OI";
-    static final String CB_FACILITY_BAOICxH      = "OX";
-    static final String CB_FACILITY_BAIC         = "AI";
-    static final String CB_FACILITY_BAICr        = "IR";
-    static final String CB_FACILITY_BA_ALL       = "AB";
-    static final String CB_FACILITY_BA_MO        = "AG";
-    static final String CB_FACILITY_BA_MT        = "AC";
-    static final String CB_FACILITY_BA_SIM       = "SC";
-    static final String CB_FACILITY_BA_FD        = "FD";
-
-
-    // Used for various supp services apis
-    // See 27.007 +CCFC or +CLCK
-    static final int SERVICE_CLASS_NONE     = 0; // no user input
-    static final int SERVICE_CLASS_VOICE    = (1 << 0);
-    static final int SERVICE_CLASS_DATA     = (1 << 1); //synonym for 16+32+64+128
-    static final int SERVICE_CLASS_FAX      = (1 << 2);
-    static final int SERVICE_CLASS_SMS      = (1 << 3);
-    static final int SERVICE_CLASS_DATA_SYNC = (1 << 4);
-    static final int SERVICE_CLASS_DATA_ASYNC = (1 << 5);
-    static final int SERVICE_CLASS_PACKET   = (1 << 6);
-    static final int SERVICE_CLASS_PAD      = (1 << 7);
-    static final int SERVICE_CLASS_MAX      = (1 << 7); // Max SERVICE_CLASS value
-
-    // Numeric representation of string values returned
-    // by messages sent to setOnUSSD handler
-    static final int USSD_MODE_NOTIFY       = 0;
-    static final int USSD_MODE_REQUEST      = 1;
-
-    // GSM SMS fail cause for acknowledgeLastIncomingSMS. From TS 23.040, 9.2.3.22.
-    static final int GSM_SMS_FAIL_CAUSE_MEMORY_CAPACITY_EXCEEDED    = 0xD3;
-    static final int GSM_SMS_FAIL_CAUSE_USIM_APP_TOOLKIT_BUSY       = 0xD4;
-    static final int GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR    = 0xD5;
-    static final int GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR           = 0xFF;
-
-    // CDMA SMS fail cause for acknowledgeLastIncomingCdmaSms.  From TS N.S0005, 6.5.2.125.
-    static final int CDMA_SMS_FAIL_CAUSE_INVALID_TELESERVICE_ID     = 4;
-    static final int CDMA_SMS_FAIL_CAUSE_RESOURCE_SHORTAGE          = 35;
-    static final int CDMA_SMS_FAIL_CAUSE_OTHER_TERMINAL_PROBLEM     = 39;
-    static final int CDMA_SMS_FAIL_CAUSE_ENCODING_PROBLEM           = 96;
-
-    //***** Methods
-    RadioState getRadioState();
-
-    void getVoiceRadioTechnology(Message result);
-
-    /**
-     * Fires on any RadioState transition
-     * Always fires immediately as well
-     *
-     * do not attempt to calculate transitions by storing getRadioState() values
-     * on previous invocations of this notification. Instead, use the other
-     * registration methods
-     */
-    void registerForRadioStateChanged(Handler h, int what, Object obj);
-    void unregisterForRadioStateChanged(Handler h);
-
-    void registerForVoiceRadioTechChanged(Handler h, int what, Object obj);
-    void unregisterForVoiceRadioTechChanged(Handler h);
-
-    /**
-     * Fires on any transition into RadioState.isOn()
-     * Fires immediately if currently in that state
-     * In general, actions should be idempotent. State may change
-     * before event is received.
-     */
-    void registerForOn(Handler h, int what, Object obj);
-    void unregisterForOn(Handler h);
-
-    /**
-     * Fires on any transition out of RadioState.isAvailable()
-     * Fires immediately if currently in that state
-     * In general, actions should be idempotent. State may change
-     * before event is received.
-     */
-    void registerForAvailable(Handler h, int what, Object obj);
-    void unregisterForAvailable(Handler h);
-
-    /**
-     * Fires on any transition into !RadioState.isAvailable()
-     * Fires immediately if currently in that state
-     * In general, actions should be idempotent. State may change
-     * before event is received.
-     */
-    void registerForNotAvailable(Handler h, int what, Object obj);
-    void unregisterForNotAvailable(Handler h);
-
-    /**
-     * Fires on any transition into RADIO_OFF or !RadioState.isAvailable()
-     * Fires immediately if currently in that state
-     * In general, actions should be idempotent. State may change
-     * before event is received.
-     */
-    void registerForOffOrNotAvailable(Handler h, int what, Object obj);
-    void unregisterForOffOrNotAvailable(Handler h);
-
-    /**
-     * Fires on any change in ICC status
-     */
-    void registerForIccStatusChanged(Handler h, int what, Object obj);
-    void unregisterForIccStatusChanged(Handler h);
-
-    void registerForCallStateChanged(Handler h, int what, Object obj);
-    void unregisterForCallStateChanged(Handler h);
-    void registerForVoiceNetworkStateChanged(Handler h, int what, Object obj);
-    void unregisterForVoiceNetworkStateChanged(Handler h);
-    void registerForDataNetworkStateChanged(Handler h, int what, Object obj);
-    void unregisterForDataNetworkStateChanged(Handler h);
-
-    /** InCall voice privacy notifications */
-    void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj);
-    void unregisterForInCallVoicePrivacyOn(Handler h);
-    void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj);
-    void unregisterForInCallVoicePrivacyOff(Handler h);
-
-    /**
-     * unlike the register* methods, there's only one new 3GPP format SMS handler.
-     * if you need to unregister, you should also tell the radio to stop
-     * sending SMS's to you (via AT+CNMI)
-     *
-     * AsyncResult.result is a String containing the SMS PDU
-     */
-    void setOnNewGsmSms(Handler h, int what, Object obj);
-    void unSetOnNewGsmSms(Handler h);
-
-    /**
-     * unlike the register* methods, there's only one new 3GPP2 format SMS handler.
-     * if you need to unregister, you should also tell the radio to stop
-     * sending SMS's to you (via AT+CNMI)
-     *
-     * AsyncResult.result is a String containing the SMS PDU
-     */
-    void setOnNewCdmaSms(Handler h, int what, Object obj);
-    void unSetOnNewCdmaSms(Handler h);
-
-    /**
-     * Set the handler for SMS Cell Broadcast messages.
-     *
-     * AsyncResult.result is a byte array containing the SMS-CB PDU
-     */
-    void setOnNewGsmBroadcastSms(Handler h, int what, Object obj);
-    void unSetOnNewGsmBroadcastSms(Handler h);
-
-    /**
-     * Register for NEW_SMS_ON_SIM unsolicited message
-     *
-     * AsyncResult.result is an int array containing the index of new SMS
-     */
-    void setOnSmsOnSim(Handler h, int what, Object obj);
-    void unSetOnSmsOnSim(Handler h);
-
-    /**
-     * Register for NEW_SMS_STATUS_REPORT unsolicited message
-     *
-     * AsyncResult.result is a String containing the status report PDU
-     */
-    void setOnSmsStatus(Handler h, int what, Object obj);
-    void unSetOnSmsStatus(Handler h);
-
-    /**
-     * unlike the register* methods, there's only one NITZ time handler
-     *
-     * AsyncResult.result is an Object[]
-     * ((Object[])AsyncResult.result)[0] is a String containing the NITZ time string
-     * ((Object[])AsyncResult.result)[1] is a Long containing the milliseconds since boot as
-     *                                   returned by elapsedRealtime() when this NITZ time
-     *                                   was posted.
-     *
-     * Please note that the delivery of this message may be delayed several
-     * seconds on system startup
-     */
-    void setOnNITZTime(Handler h, int what, Object obj);
-    void unSetOnNITZTime(Handler h);
-
-    /**
-     * unlike the register* methods, there's only one USSD notify handler
-     *
-     * Represents the arrival of a USSD "notify" message, which may
-     * or may not have been triggered by a previous USSD send
-     *
-     * AsyncResult.result is a String[]
-     * ((String[])(AsyncResult.result))[0] contains status code
-     *      "0"   USSD-Notify -- text in ((const char **)data)[1]
-     *      "1"   USSD-Request -- text in ((const char **)data)[1]
-     *      "2"   Session terminated by network
-     *      "3"   other local client (eg, SIM Toolkit) has responded
-     *      "4"   Operation not supported
-     *      "5"   Network timeout
-     *
-     * ((String[])(AsyncResult.result))[1] contains the USSD message
-     * The numeric representations of these are in USSD_MODE_*
-     */
-
-    void setOnUSSD(Handler h, int what, Object obj);
-    void unSetOnUSSD(Handler h);
-
-    /**
-     * unlike the register* methods, there's only one signal strength handler
-     * AsyncResult.result is an int[2]
-     * response.obj.result[0] is received signal strength (0-31, 99)
-     * response.obj.result[1] is  bit error rate (0-7, 99)
-     * as defined in TS 27.007 8.5
-     */
-
-    void setOnSignalStrengthUpdate(Handler h, int what, Object obj);
-    void unSetOnSignalStrengthUpdate(Handler h);
-
-    /**
-     * Sets the handler for SIM/RUIM SMS storage full unsolicited message.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void setOnIccSmsFull(Handler h, int what, Object obj);
-    void unSetOnIccSmsFull(Handler h);
-
-    /**
-     * Sets the handler for SIM Refresh notifications.
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForIccRefresh(Handler h, int what, Object obj);
-    void unregisterForIccRefresh(Handler h);
-
-    void setOnIccRefresh(Handler h, int what, Object obj);
-    void unsetOnIccRefresh(Handler h);
-
-    /**
-     * Sets the handler for RING notifications.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void setOnCallRing(Handler h, int what, Object obj);
-    void unSetOnCallRing(Handler h);
-
-    /**
-     * Sets the handler for RESTRICTED_STATE changed notification,
-     * eg, for Domain Specific Access Control
-     * unlike the register* methods, there's only one signal strength handler
-     *
-     * AsyncResult.result is an int[1]
-     * response.obj.result[0] is a bitmask of RIL_RESTRICTED_STATE_* values
-     */
-
-    void setOnRestrictedStateChanged(Handler h, int what, Object obj);
-    void unSetOnRestrictedStateChanged(Handler h);
-
-    /**
-     * Sets the handler for Supplementary Service Notifications.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void setOnSuppServiceNotification(Handler h, int what, Object obj);
-    void unSetOnSuppServiceNotification(Handler h);
-
-    /**
-     * Sets the handler for Session End Notifications for CAT.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void setOnCatSessionEnd(Handler h, int what, Object obj);
-    void unSetOnCatSessionEnd(Handler h);
-
-    /**
-     * Sets the handler for Proactive Commands for CAT.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void setOnCatProactiveCmd(Handler h, int what, Object obj);
-    void unSetOnCatProactiveCmd(Handler h);
-
-    /**
-     * Sets the handler for Event Notifications for CAT.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void setOnCatEvent(Handler h, int what, Object obj);
-    void unSetOnCatEvent(Handler h);
-
-    /**
-     * Sets the handler for Call Set Up Notifications for CAT.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void setOnCatCallSetUp(Handler h, int what, Object obj);
-    void unSetOnCatCallSetUp(Handler h);
-
-    /**
-     * Enables/disbables supplementary service related notifications from
-     * the network.
-     *
-     * @param enable true to enable notifications, false to disable.
-     * @param result Message to be posted when command completes.
-     */
-    void setSuppServiceNotifications(boolean enable, Message result);
-    //void unSetSuppServiceNotifications(Handler h);
-
-    /**
-     * Sets the handler for Event Notifications for CDMA Display Info.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForDisplayInfo(Handler h, int what, Object obj);
-    void unregisterForDisplayInfo(Handler h);
-
-    /**
-     * Sets the handler for Event Notifications for CallWaiting Info.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForCallWaitingInfo(Handler h, int what, Object obj);
-    void unregisterForCallWaitingInfo(Handler h);
-
-    /**
-     * Sets the handler for Event Notifications for Signal Info.
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForSignalInfo(Handler h, int what, Object obj);
-    void unregisterForSignalInfo(Handler h);
-
-    /**
-     * Registers the handler for CDMA number information record
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForNumberInfo(Handler h, int what, Object obj);
-    void unregisterForNumberInfo(Handler h);
-
-    /**
-     * Registers the handler for CDMA redirected number Information record
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForRedirectedNumberInfo(Handler h, int what, Object obj);
-    void unregisterForRedirectedNumberInfo(Handler h);
-
-    /**
-     * Registers the handler for CDMA line control information record
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForLineControlInfo(Handler h, int what, Object obj);
-    void unregisterForLineControlInfo(Handler h);
-
-    /**
-     * Registers the handler for CDMA T53 CLIR information record
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerFoT53ClirlInfo(Handler h, int what, Object obj);
-    void unregisterForT53ClirInfo(Handler h);
-
-    /**
-     * Registers the handler for CDMA T53 audio control information record
-     * Unlike the register* methods, there's only one notification handler
-     *
-     * @param h Handler for notification message.
-     * @param what User-defined message code.
-     * @param obj User object.
-     */
-    void registerForT53AudioControlInfo(Handler h, int what, Object obj);
-    void unregisterForT53AudioControlInfo(Handler h);
-
-    /**
-     * Fires on if Modem enters Emergency Callback mode
-     */
-    void setEmergencyCallbackMode(Handler h, int what, Object obj);
-
-     /**
-      * Fires on any CDMA OTA provision status change
-      */
-     void registerForCdmaOtaProvision(Handler h,int what, Object obj);
-     void unregisterForCdmaOtaProvision(Handler h);
-
-     /**
-      * Registers the handler when out-band ringback tone is needed.<p>
-      *
-      *  Messages received from this:
-      *  Message.obj will be an AsyncResult
-      *  AsyncResult.userObj = obj
-      *  AsyncResult.result = boolean. <p>
-      */
-     void registerForRingbackTone(Handler h, int what, Object obj);
-     void unregisterForRingbackTone(Handler h);
-
-     /**
-      * Registers the handler when mute/unmute need to be resent to get
-      * uplink audio during a call.<p>
-      *
-      * @param h Handler for notification message.
-      * @param what User-defined message code.
-      * @param obj User object.
-      *
-      */
-     void registerForResendIncallMute(Handler h, int what, Object obj);
-     void unregisterForResendIncallMute(Handler h);
-
-     /**
-      * Registers the handler for when Cdma subscription changed events
-      *
-      * @param h Handler for notification message.
-      * @param what User-defined message code.
-      * @param obj User object.
-      *
-      */
-     void registerForCdmaSubscriptionChanged(Handler h, int what, Object obj);
-     void unregisterForCdmaSubscriptionChanged(Handler h);
-
-     /**
-      * Registers the handler for when Cdma prl changed events
-      *
-      * @param h Handler for notification message.
-      * @param what User-defined message code.
-      * @param obj User object.
-      *
-      */
-     void registerForCdmaPrlChanged(Handler h, int what, Object obj);
-     void unregisterForCdmaPrlChanged(Handler h);
-
-     /**
-      * Registers the handler for when Cdma prl changed events
-      *
-      * @param h Handler for notification message.
-      * @param what User-defined message code.
-      * @param obj User object.
-      *
-      */
-     void registerForExitEmergencyCallbackMode(Handler h, int what, Object obj);
-     void unregisterForExitEmergencyCallbackMode(Handler h);
-
-     /**
-      * Registers the handler for RIL_UNSOL_RIL_CONNECT events.
-      *
-      * When ril connects or disconnects a message is sent to the registrant
-      * which contains an AsyncResult, ar, in msg.obj. The ar.result is an
-      * Integer which is the version of the ril or -1 if the ril disconnected.
-      *
-      * @param h Handler for notification message.
-      * @param what User-defined message code.
-      * @param obj User object.
-      */
-     void registerForRilConnected(Handler h, int what, Object obj);
-     void unregisterForRilConnected(Handler h);
-
-    /**
-     * Supply the ICC PIN to the ICC card
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPin(String pin, Message result);
-
-    /**
-     * Supply the PIN for the app with this AID on the ICC card
-     *
-     *  AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPinForApp(String pin, String aid, Message result);
-
-    /**
-     * Supply the ICC PUK and newPin to the ICC card
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPuk(String puk, String newPin, Message result);
-
-    /**
-     * Supply the PUK, new pin for the app with this AID on the ICC card
-     *
-     *  AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPukForApp(String puk, String newPin, String aid, Message result);
-
-    /**
-     * Supply the ICC PIN2 to the ICC card
-     * Only called following operation where ICC_PIN2 was
-     * returned as a a failure from a previous operation
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPin2(String pin2, Message result);
-
-    /**
-     * Supply the PIN2 for the app with this AID on the ICC card
-     * Only called following operation where ICC_PIN2 was
-     * returned as a a failure from a previous operation
-     *
-     *  AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPin2ForApp(String pin2, String aid, Message result);
-
-    /**
-     * Supply the SIM PUK2 to the SIM card
-     * Only called following operation where SIM_PUK2 was
-     * returned as a a failure from a previous operation
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPuk2(String puk2, String newPin2, Message result);
-
-    /**
-     * Supply the PUK2, newPin2 for the app with this AID on the ICC card
-     * Only called following operation where SIM_PUK2 was
-     * returned as a a failure from a previous operation
-     *
-     *  AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
-     *
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  This exception is CommandException with an error of PASSWORD_INCORRECT
-     *  if the password is incorrect
-     *
-     * ar.exception and ar.result are null on success
-     */
-
-    void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message result);
-
-    void changeIccPin(String oldPin, String newPin, Message result);
-    void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message result);
-    void changeIccPin2(String oldPin2, String newPin2, Message result);
-    void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr, Message result);
-
-    void changeBarringPassword(String facility, String oldPwd, String newPwd, Message result);
-
-    void supplyNetworkDepersonalization(String netpin, Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result contains a List of DriverCall
-     *      The ar.result List is sorted by DriverCall.index
-     */
-    void getCurrentCalls (Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result contains a List of DataCallState
-     *  @deprecated Do not use.
-     */
-    @Deprecated
-    void getPDPContextList(Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result contains a List of DataCallState
-     */
-    void getDataCallList(Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     *
-     * CLIR_DEFAULT     == on "use subscription default value"
-     * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation)
-     * CLIR_INVOCATION  == on "CLIR invocation" (restrict CLI presentation)
-     */
-    void dial (String address, int clirMode, Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     *
-     * CLIR_DEFAULT     == on "use subscription default value"
-     * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation)
-     * CLIR_INVOCATION  == on "CLIR invocation" (restrict CLI presentation)
-     */
-    void dial(String address, int clirMode, UUSInfo uusInfo, Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is String containing IMSI on success
-     */
-    void getIMSI(Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is String containing IMSI on success
-     */
-    void getIMSIForApp(String aid, Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is String containing IMEI on success
-     */
-    void getIMEI(Message result);
-
-    /**
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is String containing IMEISV on success
-     */
-    void getIMEISV(Message result);
-
-    /**
-     * Hang up one individual connection.
-     *  returned message
-     *  retMsg.obj = AsyncResult ar
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     *
-     *  3GPP 22.030 6.5.5
-     *  "Releases a specific active call X"
-     */
-    void hangupConnection (int gsmIndex, Message result);
-
-    /**
-     * 3GPP 22.030 6.5.5
-     *  "Releases all held calls or sets User Determined User Busy (UDUB)
-     *   for a waiting call."
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void hangupWaitingOrBackground (Message result);
-
-    /**
-     * 3GPP 22.030 6.5.5
-     * "Releases all active calls (if any exist) and accepts
-     *  the other (held or waiting) call."
-     *
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void hangupForegroundResumeBackground (Message result);
-
-    /**
-     * 3GPP 22.030 6.5.5
-     * "Places all active calls (if any exist) on hold and accepts
-     *  the other (held or waiting) call."
-     *
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void switchWaitingOrHoldingAndActive (Message result);
-
-    /**
-     * 3GPP 22.030 6.5.5
-     * "Adds a held call to the conversation"
-     *
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void conference (Message result);
-
-    /**
-     * Set preferred Voice Privacy (VP).
-     *
-     * @param enable true is enhanced and false is normal VP
-     * @param result is a callback message
-     */
-    void setPreferredVoicePrivacy(boolean enable, Message result);
-
-    /**
-     * Get currently set preferred Voice Privacy (VP) mode.
-     *
-     * @param result is a callback message
-     */
-    void getPreferredVoicePrivacy(Message result);
-
-    /**
-     * 3GPP 22.030 6.5.5
-     * "Places all active calls on hold except call X with which
-     *  communication shall be supported."
-     */
-    void separateConnection (int gsmIndex, Message result);
-
-    /**
-     *
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void acceptCall (Message result);
-
-    /**
-     *  also known as UDUB
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void rejectCall (Message result);
-
-    /**
-     * 3GPP 22.030 6.5.5
-     * "Connects the two calls and disconnects the subscriber from both calls"
-     *
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void explicitCallTransfer (Message result);
-
-    /**
-     * cause code returned as int[0] in Message.obj.response
-     * Returns integer cause code defined in TS 24.008
-     * Annex H or closest approximation.
-     * Most significant codes:
-     * - Any defined in 22.001 F.4 (for generating busy/congestion)
-     * - Cause 68: ACM >= ACMMax
-     */
-    void getLastCallFailCause (Message result);
-
-
-    /**
-     * Reason for last PDP context deactivate or failure to activate
-     * cause code returned as int[0] in Message.obj.response
-     * returns an integer cause code defined in TS 24.008
-     * section 6.1.3.1.3 or close approximation
-     * @deprecated Do not use.
-     */
-    @Deprecated
-    void getLastPdpFailCause (Message result);
-
-    /**
-     * The preferred new alternative to getLastPdpFailCause
-     * that is also CDMA-compatible.
-     */
-    void getLastDataCallFailCause (Message result);
-
-    void setMute (boolean enableMute, Message response);
-
-    void getMute (Message response);
-
-    /**
-     * response.obj is an AsyncResult
-     * response.obj.result is an int[2]
-     * response.obj.result[0] is received signal strength (0-31, 99)
-     * response.obj.result[1] is  bit error rate (0-7, 99)
-     * as defined in TS 27.007 8.5
-     */
-    void getSignalStrength (Message response);
-
-
-    /**
-     * response.obj.result is an int[3]
-     * response.obj.result[0] is registration state 0-5 from TS 27.007 7.2
-     * response.obj.result[1] is LAC if registered or -1 if not
-     * response.obj.result[2] is CID if registered or -1 if not
-     * valid LAC and CIDs are 0x0000 - 0xffff
-     *
-     * Please note that registration state 4 ("unknown") is treated
-     * as "out of service" above
-     */
-    void getVoiceRegistrationState (Message response);
-
-    /**
-     * response.obj.result is an int[3]
-     * response.obj.result[0] is registration state 0-5 from TS 27.007 7.2
-     * response.obj.result[1] is LAC if registered or -1 if not
-     * response.obj.result[2] is CID if registered or -1 if not
-     * valid LAC and CIDs are 0x0000 - 0xffff
-     *
-     * Please note that registration state 4 ("unknown") is treated
-     * as "out of service" above
-     */
-    void getDataRegistrationState (Message response);
-
-    /**
-     * response.obj.result is a String[3]
-     * response.obj.result[0] is long alpha or null if unregistered
-     * response.obj.result[1] is short alpha or null if unregistered
-     * response.obj.result[2] is numeric or null if unregistered
-     */
-    void getOperator(Message response);
-
-    /**
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void sendDtmf(char c, Message result);
-
-
-    /**
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void startDtmf(char c, Message result);
-
-    /**
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void stopDtmf(Message result);
-
-    /**
-     *  ar.exception carries exception on failure
-     *  ar.userObject contains the orignal value of result.obj
-     *  ar.result is null on success and failure
-     */
-    void sendBurstDtmf(String dtmfString, int on, int off, Message result);
-
-    /**
-     * smscPDU is smsc address in PDU form GSM BCD format prefixed
-     *      by a length byte (as expected by TS 27.005) or NULL for default SMSC
-     * pdu is SMS in PDU format as an ASCII hex string
-     *      less the SMSC address
-     */
-    void sendSMS (String smscPDU, String pdu, Message response);
-
-    /**
-     * @param pdu is CDMA-SMS in internal pseudo-PDU format
-     * @param response sent when operation completes
-     */
-    void sendCdmaSms(byte[] pdu, Message response);
-
-    /**
-     * Deletes the specified SMS record from SIM memory (EF_SMS).
-     *
-     * @param index index of the SMS record to delete
-     * @param response sent when operation completes
-     */
-    void deleteSmsOnSim(int index, Message response);
-
-    /**
-     * Deletes the specified SMS record from RUIM memory (EF_SMS in DF_CDMA).
-     *
-     * @param index index of the SMS record to delete
-     * @param response sent when operation completes
-     */
-    void deleteSmsOnRuim(int index, Message response);
-
-    /**
-     * Writes an SMS message to SIM memory (EF_SMS).
-     *
-     * @param status status of message on SIM.  One of:
-     *                  SmsManger.STATUS_ON_ICC_READ
-     *                  SmsManger.STATUS_ON_ICC_UNREAD
-     *                  SmsManger.STATUS_ON_ICC_SENT
-     *                  SmsManger.STATUS_ON_ICC_UNSENT
-     * @param pdu message PDU, as hex string
-     * @param response sent when operation completes.
-     *                  response.obj will be an AsyncResult, and will indicate
-     *                  any error that may have occurred (eg, out of memory).
-     */
-    void writeSmsToSim(int status, String smsc, String pdu, Message response);
-
-    void writeSmsToRuim(int status, String pdu, Message response);
-
-    void setRadioPower(boolean on, Message response);
-
-    void acknowledgeLastIncomingGsmSms(boolean success, int cause, Message response);
-
-    void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message response);
-
-    /**
-     * Acknowledge successful or failed receipt of last incoming SMS,
-     * including acknowledgement TPDU to send as the RP-User-Data element
-     * of the RP-ACK or RP-ERROR PDU.
-     *
-     * @param success true to send RP-ACK, false to send RP-ERROR
-     * @param ackPdu the acknowledgement TPDU in hexadecimal format
-     * @param response sent when operation completes.
-     */
-    void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu, Message response);
-
-    /**
-     * parameters equivalent to 27.007 AT+CRSM command
-     * response.obj will be an AsyncResult
-     * response.obj.result will be an IccIoResult on success
-     */
-    void iccIO (int command, int fileid, String path, int p1, int p2, int p3,
-            String data, String pin2, Message response);
-
-    /**
-     * parameters equivalent to 27.007 AT+CRSM command
-     * response.obj will be an AsyncResult
-     * response.obj.userObj will be a IccIoResult on success
-     */
-    void iccIOForApp (int command, int fileid, String path, int p1, int p2, int p3,
-            String data, String pin2, String aid, Message response);
-
-    /**
-     * (AsyncResult)response.obj).result is an int[] with element [0] set to
-     * 1 for "CLIP is provisioned", and 0 for "CLIP is not provisioned".
-     *
-     * @param response is callback message
-     */
-
-    void queryCLIP(Message response);
-
-    /**
-     * response.obj will be a an int[2]
-     *
-     * response.obj[0] will be TS 27.007 +CLIR parameter 'n'
-     *  0 presentation indicator is used according to the subscription of the CLIR service
-     *  1 CLIR invocation
-     *  2 CLIR suppression
-     *
-     * response.obj[1] will be TS 27.007 +CLIR parameter 'm'
-     *  0 CLIR not provisioned
-     *  1 CLIR provisioned in permanent mode
-     *  2 unknown (e.g. no network, etc.)
-     *  3 CLIR temporary mode presentation restricted
-     *  4 CLIR temporary mode presentation allowed
-     */
-
-    void getCLIR(Message response);
-
-    /**
-     * clirMode is one of the CLIR_* constants above
-     *
-     * response.obj is null
-     */
-
-    void setCLIR(int clirMode, Message response);
-
-    /**
-     * (AsyncResult)response.obj).result is an int[] with element [0] set to
-     * 0 for disabled, 1 for enabled.
-     *
-     * @param serviceClass is a sum of SERVICE_CLASS_*
-     * @param response is callback message
-     */
-
-    void queryCallWaiting(int serviceClass, Message response);
-
-    /**
-     * @param enable is true to enable, false to disable
-     * @param serviceClass is a sum of SERVICE_CLASS_*
-     * @param response is callback message
-     */
-
-    void setCallWaiting(boolean enable, int serviceClass, Message response);
-
-    /**
-     * @param action is one of CF_ACTION_*
-     * @param cfReason is one of CF_REASON_*
-     * @param serviceClass is a sum of SERVICE_CLASSS_*
-     */
-    void setCallForward(int action, int cfReason, int serviceClass,
-                String number, int timeSeconds, Message response);
-
-    /**
-     * cfReason is one of CF_REASON_*
-     *
-     * ((AsyncResult)response.obj).result will be an array of
-     * CallForwardInfo's
-     *
-     * An array of length 0 means "disabled for all codes"
-     */
-    void queryCallForwardStatus(int cfReason, int serviceClass,
-            String number, Message response);
-
-    void setNetworkSelectionModeAutomatic(Message response);
-
-    void setNetworkSelectionModeManual(String operatorNumeric, Message response);
-
-    /**
-     * Queries whether the current network selection mode is automatic
-     * or manual
-     *
-     * ((AsyncResult)response.obj).result  is an int[] with element [0] being
-     * a 0 for automatic selection and a 1 for manual selection
-     */
-
-    void getNetworkSelectionMode(Message response);
-
-    /**
-     * Queries the currently available networks
-     *
-     * ((AsyncResult)response.obj).result  is a List of NetworkInfo objects
-     */
-    void getAvailableNetworks(Message response);
-
-    void getBasebandVersion (Message response);
-
-
-    /**
-     * (AsyncResult)response.obj).result will be an Integer representing
-     * the sum of enabled service classes (sum of SERVICE_CLASS_*)
-     *
-     * @param facility one of CB_FACILTY_*
-     * @param password password or "" if not required
-     * @param serviceClass is a sum of SERVICE_CLASS_*
-     * @param response is callback message
-     */
-
-    void queryFacilityLock (String facility, String password, int serviceClass,
-        Message response);
-
-    /**
-     * (AsyncResult)response.obj).result will be an Integer representing
-     * the sum of enabled service classes (sum of SERVICE_CLASS_*) for the
-     * application with appId.
-     *
-     * @param facility one of CB_FACILTY_*
-     * @param password password or "" if not required
-     * @param serviceClass is a sum of SERVICE_CLASS_*
-     * @param appId is application Id or null if none
-     * @param response is callback message
-     */
-
-    void queryFacilityLockForApp(String facility, String password, int serviceClass, String appId,
-        Message response);
-
-    /**
-     * @param facility one of CB_FACILTY_*
-     * @param lockState true means lock, false means unlock
-     * @param password password or "" if not required
-     * @param serviceClass is a sum of SERVICE_CLASS_*
-     * @param response is callback message
-     */
-    void setFacilityLock (String facility, boolean lockState, String password,
-        int serviceClass, Message response);
-
-    /**
-     * Set the facility lock for the app with this AID on the ICC card.
-     *
-     * @param facility one of CB_FACILTY_*
-     * @param lockState true means lock, false means unlock
-     * @param password password or "" if not required
-     * @param serviceClass is a sum of SERVICE_CLASS_*
-     * @param appId is application Id or null if none
-     * @param response is callback message
-     */
-    void setFacilityLockForApp(String facility, boolean lockState, String password,
-        int serviceClass, String appId, Message response);
-
-    void sendUSSD (String ussdString, Message response);
-
-    /**
-     * Cancels a pending USSD session if one exists.
-     * @param response callback message
-     */
-    void cancelPendingUssd (Message response);
-
-    void resetRadio(Message result);
-
-    /**
-     * Assign a specified band for RF configuration.
-     *
-     * @param bandMode one of BM_*_BAND
-     * @param response is callback message
-     */
-    void setBandMode (int bandMode, Message response);
-
-    /**
-     * Query the list of band mode supported by RF.
-     *
-     * @param response is callback message
-     *        ((AsyncResult)response.obj).result  is an int[] with every
-     *        element representing one avialable BM_*_BAND
-     */
-    void queryAvailableBandMode (Message response);
-
-    /**
-     * Set the current preferred network type. This will be the last
-     * networkType that was passed to setPreferredNetworkType.
-     */
-    void setCurrentPreferredNetworkType();
-
-    /**
-     *  Requests to set the preferred network type for searching and registering
-     * (CS/PS domain, RAT, and operation mode)
-     * @param networkType one of  NT_*_TYPE
-     * @param response is callback message
-     */
-    void setPreferredNetworkType(int networkType , Message response);
-
-     /**
-     *  Query the preferred network type setting
-     *
-     * @param response is callback message to report one of  NT_*_TYPE
-     */
-    void getPreferredNetworkType(Message response);
-
-    /**
-     * Query neighboring cell ids
-     *
-     * @param response s callback message to cell ids
-     */
-    void getNeighboringCids(Message response);
-
-    /**
-     * Request to enable/disable network state change notifications when
-     * location information (lac and/or cid) has changed.
-     *
-     * @param enable true to enable, false to disable
-     * @param response callback message
-     */
-    void setLocationUpdates(boolean enable, Message response);
-
-    /**
-     * Gets the default SMSC address.
-     *
-     * @param result Callback message contains the SMSC address.
-     */
-    void getSmscAddress(Message result);
-
-    /**
-     * Sets the default SMSC address.
-     *
-     * @param address new SMSC address
-     * @param result Callback message is empty on completion
-     */
-    void setSmscAddress(String address, Message result);
-
-    /**
-     * Indicates whether there is storage available for new SMS messages.
-     * @param available true if storage is available
-     * @param result callback message
-     */
-    void reportSmsMemoryStatus(boolean available, Message result);
-
-    /**
-     * Indicates to the vendor ril that StkService is running
-     * and is ready to receive RIL_UNSOL_STK_XXXX commands.
-     *
-     * @param result callback message
-     */
-    void reportStkServiceIsRunning(Message result);
-
-    void invokeOemRilRequestRaw(byte[] data, Message response);
-
-    void invokeOemRilRequestStrings(String[] strings, Message response);
-
-
-    /**
-     * Send TERMINAL RESPONSE to the SIM, after processing a proactive command
-     * sent by the SIM.
-     *
-     * @param contents  String containing SAT/USAT response in hexadecimal
-     *                  format starting with first byte of response data. See
-     *                  TS 102 223 for details.
-     * @param response  Callback message
-     */
-    public void sendTerminalResponse(String contents, Message response);
-
-    /**
-     * Send ENVELOPE to the SIM, after processing a proactive command sent by
-     * the SIM.
-     *
-     * @param contents  String containing SAT/USAT response in hexadecimal
-     *                  format starting with command tag. See TS 102 223 for
-     *                  details.
-     * @param response  Callback message
-     */
-    public void sendEnvelope(String contents, Message response);
-
-    /**
-     * Send ENVELOPE to the SIM, such as an SMS-PP data download envelope
-     * for a SIM data download message. This method has one difference
-     * from {@link #sendEnvelope}: The SW1 and SW2 status bytes from the UICC response
-     * are returned along with the response data.
-     *
-     * response.obj will be an AsyncResult
-     * response.obj.result will be an IccIoResult on success
-     *
-     * @param contents  String containing SAT/USAT response in hexadecimal
-     *                  format starting with command tag. See TS 102 223 for
-     *                  details.
-     * @param response  Callback message
-     */
-    public void sendEnvelopeWithStatus(String contents, Message response);
-
-    /**
-     * Accept or reject the call setup request from SIM.
-     *
-     * @param accept   true if the call is to be accepted, false otherwise.
-     * @param response Callback message
-     */
-    public void handleCallSetupRequestFromSim(boolean accept, Message response);
-
-    /**
-     * Activate or deactivate cell broadcast SMS for GSM.
-     *
-     * @param activate
-     *            true = activate, false = deactivate
-     * @param result Callback message is empty on completion
-     */
-    public void setGsmBroadcastActivation(boolean activate, Message result);
-
-    /**
-     * Configure cell broadcast SMS for GSM.
-     *
-     * @param response Callback message is empty on completion
-     */
-    public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response);
-
-    /**
-     * Query the current configuration of cell broadcast SMS of GSM.
-     *
-     * @param response
-     *        Callback message contains the configuration from the modem
-     *        on completion
-     */
-    public void getGsmBroadcastConfig(Message response);
-
-    //***** new Methods for CDMA support
-
-    /**
-     * Request the device ESN / MEID / IMEI / IMEISV.
-     * "response" is const char **
-     *   [0] is IMEI if GSM subscription is available
-     *   [1] is IMEISV if GSM subscription is available
-     *   [2] is ESN if CDMA subscription is available
-     *   [3] is MEID if CDMA subscription is available
-     */
-    public void getDeviceIdentity(Message response);
-
-    /**
-     * Request the device MDN / H_SID / H_NID / MIN.
-     * "response" is const char **
-     *   [0] is MDN if CDMA subscription is available
-     *   [1] is a comma separated list of H_SID (Home SID) in decimal format
-     *       if CDMA subscription is available
-     *   [2] is a comma separated list of H_NID (Home NID) in decimal format
-     *       if CDMA subscription is available
-     *   [3] is MIN (10 digits, MIN2+MIN1) if CDMA subscription is available
-     */
-    public void getCDMASubscription(Message response);
-
-    /**
-     * Send Flash Code.
-     * "response" is is NULL
-     *   [0] is a FLASH string
-     */
-    public void sendCDMAFeatureCode(String FeatureCode, Message response);
-
-    /** Set the Phone type created */
-    void setPhoneType(int phoneType);
-
-    /**
-     *  Query the CDMA roaming preference setting
-     *
-     * @param response is callback message to report one of  CDMA_RM_*
-     */
-    void queryCdmaRoamingPreference(Message response);
-
-    /**
-     *  Requests to set the CDMA roaming preference
-     * @param cdmaRoamingType one of  CDMA_RM_*
-     * @param response is callback message
-     */
-    void setCdmaRoamingPreference(int cdmaRoamingType, Message response);
-
-    /**
-     *  Requests to set the CDMA subscription mode
-     * @param cdmaSubscriptionType one of  CDMA_SUBSCRIPTION_*
-     * @param response is callback message
-     */
-    void setCdmaSubscriptionSource(int cdmaSubscriptionType, Message response);
-
-    /**
-     *  Requests to get the CDMA subscription srouce
-     * @param response is callback message
-     */
-    void getCdmaSubscriptionSource(Message response);
-
-    /**
-     *  Set the TTY mode
-     *
-     * @param ttyMode one of the following:
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
-     * @param response is callback message
-     */
-    void setTTYMode(int ttyMode, Message response);
-
-    /**
-     *  Query the TTY mode
-     * (AsyncResult)response.obj).result is an int[] with element [0] set to
-     * tty mode:
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
-     * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
-     * @param response is callback message
-     */
-    void queryTTYMode(Message response);
-
-    /**
-     * Setup a packet data connection On successful completion, the result
-     * message will return a {@link DataCallState} object containing the connection
-     * information.
-     *
-     * @param radioTechnology
-     *            indicates whether to setup connection on radio technology CDMA
-     *            (0) or GSM/UMTS (1)
-     * @param profile
-     *            Profile Number or NULL to indicate default profile
-     * @param apn
-     *            the APN to connect to if radio technology is GSM/UMTS.
-     *            Otherwise null for CDMA.
-     * @param user
-     *            the username for APN, or NULL
-     * @param password
-     *            the password for APN, or NULL
-     * @param authType
-     *            the PAP / CHAP auth type. Values is one of SETUP_DATA_AUTH_*
-     * @param protocol
-     *            one of the PDP_type values in TS 27.007 section 10.1.1.
-     *            For example, "IP", "IPV6", "IPV4V6", or "PPP".
-     * @param result
-     *            Callback message
-     */
-    public void setupDataCall(String radioTechnology, String profile,
-            String apn, String user, String password, String authType,
-            String protocol, Message result);
-
-    /**
-     * Deactivate packet data connection
-     *
-     * @param cid
-     *            The connection ID
-     * @param reason
-     *            Data disconnect reason.
-     * @param result
-     *            Callback message is empty on completion
-     */
-    public void deactivateDataCall(int cid, int reason, Message result);
-
-    /**
-     * Activate or deactivate cell broadcast SMS for CDMA.
-     *
-     * @param activate
-     *            true = activate, false = deactivate
-     * @param result
-     *            Callback message is empty on completion
-     */
-    public void setCdmaBroadcastActivation(boolean activate, Message result);
-
-    /**
-     * Configure cdma cell broadcast SMS.
-     *
-     * @param result
-     *            Callback message is empty on completion
-     */
-    // TODO: Change the configValuesArray to a RIL_BroadcastSMSConfig
-    public void setCdmaBroadcastConfig(int[] configValuesArray, Message result);
-
-    /**
-     * Query the current configuration of cdma cell broadcast SMS.
-     *
-     * @param result
-     *            Callback message contains the configuration from the modem on completion
-     */
-    public void getCdmaBroadcastConfig(Message result);
-
-    /**
-     *  Requests the radio's system selection module to exit emergency callback mode.
-     *  This function should only be called from CDMAPHone.java.
-     *
-     * @param response callback message
-     */
-    public void exitEmergencyCallbackMode(Message response);
-
-    /**
-     * Request the status of the ICC and UICC cards.
-     *
-     * @param result
-     *          Callback message containing {@link IccCardStatus} structure for the card.
-     */
-    public void getIccCardStatus(Message result);
-
-    /**
-     * Return if the current radio is LTE on CDMA. This
-     * is a tri-state return value as for a period of time
-     * the mode may be unknown.
-     *
-     * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
-     * or {@link Phone#LTE_ON_CDMA_TRUE}
-     */
-    public int getLteOnCdmaMode();
-
-    /**
-     * Request the ISIM application on the UICC to perform the AKA
-     * challenge/response algorithm for IMS authentication. The nonce string
-     * and challenge response are Base64 encoded Strings.
-     *
-     * @param nonce the nonce string to pass with the ISIM authentication request
-     * @param response a callback message with the String response in the obj field
-     */
-    public void requestIsimAuthentication(String nonce, Message response);
-
-    /**
-     * Notifiy that we are testing an emergency call
-     */
-    public void testingEmergencyCall();
-}
diff --git a/telephony/java/com/android/internal/telephony/Connection.java b/telephony/java/com/android/internal/telephony/Connection.java
deleted file mode 100644
index 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 ac8c4c1..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 3149ee1..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/mockril/MockRilTest.java
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.mockril;
-
-import android.util.Log;
-import android.test.InstrumentationTestCase;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-import com.android.internal.communication.MsgHeader;
-import com.android.internal.communication.Msg;
-import com.android.internal.telephony.RilChannel;
-import com.android.internal.telephony.ril_proto.RilCtrlCmds;
-import com.android.internal.telephony.ril_proto.RilCmds;
-
-import com.android.frameworks.telephonytests.TelephonyMockRilTestRunner;
-import com.google.protobuf.micro.InvalidProtocolBufferMicroException;
-
-// Test suite for test ril
-public class MockRilTest extends InstrumentationTestCase {
-    private static final String TAG = "MockRilTest";
-
-    RilChannel mMockRilChannel;
-    TelephonyMockRilTestRunner mRunner;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mRunner = (TelephonyMockRilTestRunner)getInstrumentation();
-        mMockRilChannel = mRunner.mMockRilChannel;
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    static void log(String s) {
-        Log.v(TAG, s);
-    }
-
-    /**
-     * Test Case 1: Test protobuf serialization and deserialization
-     * @throws InvalidProtocolBufferMicroException
-     */
-    public void testProtobufSerDes() throws InvalidProtocolBufferMicroException {
-        log("testProtobufSerdes E");
-
-        RilCtrlCmds.CtrlRspRadioState rs = new RilCtrlCmds.CtrlRspRadioState();
-        assertTrue(String.format("expected rs.state == 0 was %d", rs.getState()),
-                rs.getState() == 0);
-        rs.setState(1);
-        assertTrue(String.format("expected rs.state == 1 was %d", rs.getState()),
-                rs.getState() == 1);
-
-        byte[] rs_ser = rs.toByteArray();
-        RilCtrlCmds.CtrlRspRadioState rsNew = RilCtrlCmds.CtrlRspRadioState.parseFrom(rs_ser);
-        assertTrue(String.format("expected rsNew.state == 1 was %d", rs.getState()),
-                rs.getState() == 1);
-
-        log("testProtobufSerdes X");
-    }
-
-    /**
-     * Test case 2: Test echo command works using writeMsg & readMsg
-     */
-    public void testEchoMsg() throws IOException {
-        log("testEchoMsg E");
-
-        MsgHeader mh = new MsgHeader();
-        mh.setCmd(0);
-        mh.setToken(1);
-        mh.setStatus(2);
-        ByteBuffer data = ByteBuffer.allocate(3);
-        data.put((byte)3);
-        data.put((byte)4);
-        data.put((byte)5);
-        Msg.send(mMockRilChannel, mh, data);
-
-        Msg respMsg = Msg.recv(mMockRilChannel);
-        assertTrue(String.format("expected mhd.header.cmd == 0 was %d",respMsg.getCmd()),
-                respMsg.getCmd() == 0);
-        assertTrue(String.format("expected mhd.header.token == 1 was %d",respMsg.getToken()),
-                respMsg.getToken() == 1);
-        assertTrue(String.format("expected mhd.header.status == 2 was %d", respMsg.getStatus()),
-                respMsg.getStatus() == 2);
-        assertTrue(String.format("expected mhd.data[0] == 3 was %d", respMsg.getData(0)),
-                respMsg.getData(0) == 3);
-        assertTrue(String.format("expected mhd.data[1] == 4 was %d", respMsg.getData(1)),
-                respMsg.getData(1) == 4);
-        assertTrue(String.format("expected mhd.data[2] == 5 was %d", respMsg.getData(2)),
-                respMsg.getData(2) == 5);
-
-        log("testEchoMsg X");
-    }
-
-    /**
-     * Test case 3: Test get as
-     */
-    public void testGetAs() {
-        log("testGetAs E");
-
-        // Use a message header as the protobuf data content
-        MsgHeader mh = new MsgHeader();
-        mh.setCmd(12345);
-        mh.setToken(9876);
-        mh.setStatus(7654);
-        mh.setLengthData(4321);
-        byte[] data = mh.toByteArray();
-        MsgHeader mhResult = Msg.getAs(MsgHeader.class, data);
-
-        assertTrue(String.format("expected cmd == 12345 was %d", mhResult.getCmd()),
-                mhResult.getCmd() == 12345);
-        assertTrue(String.format("expected token == 9876 was %d", mhResult.getToken()),
-                mhResult.getToken() == 9876);
-        assertTrue(String.format("expected status == 7654 was %d", mhResult.getStatus()),
-                mhResult.getStatus() == 7654);
-        assertTrue(String.format("expected lengthData == 4321 was %d", mhResult.getLengthData()),
-                mhResult.getLengthData() == 4321);
-
-        Msg msg = Msg.obtain();
-        msg.setData(ByteBuffer.wrap(data));
-
-        mhResult = msg.getDataAs(MsgHeader.class);
-
-        assertTrue(String.format("expected cmd == 12345 was %d", mhResult.getCmd()),
-                mhResult.getCmd() == 12345);
-        assertTrue(String.format("expected token == 9876 was %d", mhResult.getToken()),
-                mhResult.getToken() == 9876);
-        assertTrue(String.format("expected status == 7654 was %d", mhResult.getStatus()),
-                mhResult.getStatus() == 7654);
-        assertTrue(String.format("expected lengthData == 4321 was %d", mhResult.getLengthData()),
-                mhResult.getLengthData() == 4321);
-
-        log("testGetAs X");
-    }
-
-    /**
-     * Test case 3: test get radio state
-     */
-    public void testGetRadioState() throws IOException {
-        log("testGetRadioState E");
-
-        Msg.send(mMockRilChannel, 1, 9876, 0, null);
-
-        Msg resp = Msg.recv(mMockRilChannel);
-        //resp.printHeader("testGetRadioState");
-
-        assertTrue(String.format("expected cmd == 1 was %d", resp.getCmd()),
-                resp.getCmd() == 1);
-        assertTrue(String.format("expected token == 9876 was %d", resp.getToken()),
-                resp.getToken() == 9876);
-        assertTrue(String.format("expected status == 0 was %d", resp.getStatus()),
-                resp.getStatus() == 0);
-
-        RilCtrlCmds.CtrlRspRadioState rsp = resp.getDataAs(RilCtrlCmds.CtrlRspRadioState.class);
-
-        int state = rsp.getState();
-        log("testGetRadioState state=" + state);
-        assertTrue(String.format("expected RadioState >= 0 && RadioState <= 9 was %d", state),
-                ((state >= 0) && (state <= 9)));
-
-        log("testGetRadioState X");
-    }
-
-    /**
-     * Test case 5: test set radio state
-     */
-    public void testSetRadioState() throws IOException {
-        log("testSetRadioState E");
-
-        RilCtrlCmds.CtrlReqRadioState cmdrs = new RilCtrlCmds.CtrlReqRadioState();
-        assertEquals(0, cmdrs.getState());
-
-        cmdrs.setState(RilCmds.RADIOSTATE_SIM_NOT_READY);
-        assertEquals(2, cmdrs.getState());
-
-        Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_RADIO_STATE, 0, 0, cmdrs);
-
-        Msg resp = Msg.recv(mMockRilChannel);
-        log("get response status :" + resp.getStatus());
-        log("get response for command: " + resp.getCmd());
-        log("get command token: " + resp.getToken());
-
-        RilCtrlCmds.CtrlRspRadioState rsp = resp.getDataAs(RilCtrlCmds.CtrlRspRadioState.class);
-
-        int state = rsp.getState();
-        log("get response for testSetRadioState: " + state);
-        assertTrue(RilCmds.RADIOSTATE_SIM_NOT_READY == state);
-    }
-
-    /**
-     * Test case 6: test start incoming call and hangup it.
-     */
-    public void testStartIncomingCallAndHangup() throws IOException {
-        log("testStartIncomingCallAndHangup");
-        RilCtrlCmds.CtrlReqSetMTCall cmd = new RilCtrlCmds.CtrlReqSetMTCall();
-        String incomingCall = "6502889108";
-        // set the MT call
-        cmd.setPhoneNumber(incomingCall);
-        Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_MT_CALL, 0, 0, cmd);
-        // get response
-        Msg resp = Msg.recv(mMockRilChannel);
-        log("Get response status: " + resp.getStatus());
-        assertTrue("The ril is not in a proper state to set MT calls.",
-                   resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
-
-        // allow the incoming call alerting for some time
-        try {
-            Thread.sleep(5000);
-        } catch (InterruptedException e) {}
-
-        // we are playing a trick to assume the current is 1
-        RilCtrlCmds.CtrlHangupConnRemote hangupCmd = new RilCtrlCmds.CtrlHangupConnRemote();
-        hangupCmd.setConnectionId(1);
-        hangupCmd.setCallFailCause(16);   // normal hangup
-        Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_HANGUP_CONN_REMOTE, 0, 0, hangupCmd);
-
-        // get response
-        resp = Msg.recv(mMockRilChannel);
-        log("Get response for hangup connection: " + resp.getStatus());
-        assertTrue("CTRL_CMD_HANGUP_CONN_REMOTE failed",
-                   resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
-    }
-
-    /**
-     * Test case 7: test set call transition flag
-     */
-    public void testSetCallTransitionFlag() throws IOException {
-        log("testSetCallTransitionFlag");
-        // Set flag to true:
-        RilCtrlCmds.CtrlSetCallTransitionFlag cmd = new RilCtrlCmds.CtrlSetCallTransitionFlag();
-        cmd.setFlag(true);
-        Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_CALL_TRANSITION_FLAG, 0, 0, cmd);
-
-        Msg resp = Msg.recv(mMockRilChannel);
-        log("Get response status: " + resp.getStatus());
-        assertTrue("Set call transition flag failed",
-                   resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
-
-        // add a dialing call
-        RilCtrlCmds.CtrlReqAddDialingCall cmdDialCall = new RilCtrlCmds.CtrlReqAddDialingCall();
-        String phoneNumber = "5102345678";
-        cmdDialCall.setPhoneNumber(phoneNumber);
-        Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_ADD_DIALING_CALL, 0, 0, cmdDialCall);
-        resp = Msg.recv(mMockRilChannel);
-        log("Get response status for adding a dialing call: " + resp.getStatus());
-        assertTrue("add dialing call failed",
-                   resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
-        try {
-            Thread.sleep(5000);
-        } catch (InterruptedException e) {}
-
-        // send command to force call state change
-        Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_CALL_ALERT, 0, 0, null);
-        resp = Msg.recv(mMockRilChannel);
-        log("Get response status: " + resp.getStatus());
-        assertTrue("Set call alert failed",
-                   resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
-
-        try {
-            Thread.sleep(2000);
-        } catch (InterruptedException e) {}
-
-        // send command to force call state change
-        Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_CALL_ACTIVE, 0, 0, null);
-        resp = Msg.recv(mMockRilChannel);
-        log("Get response status: " + resp.getStatus());
-        assertTrue("Set call active failed",
-                   resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
-
-        // hangup the active all remotely
-        RilCtrlCmds.CtrlHangupConnRemote hangupCmd = new RilCtrlCmds.CtrlHangupConnRemote();
-        hangupCmd.setConnectionId(1);
-        hangupCmd.setCallFailCause(16);   // normal hangup
-        Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_HANGUP_CONN_REMOTE, 0, 0, hangupCmd);
-        resp = Msg.recv(mMockRilChannel);
-        log("Get response for hangup connection: " + resp.getStatus());
-        assertTrue("CTRL_CMD_HANGUP_CONN_REMOTE failed",
-                   resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
-
-        // set the flag to false
-        cmd.setFlag(false);
-        Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_CALL_TRANSITION_FLAG, 0, 0, cmd);
-        resp = Msg.recv(mMockRilChannel);
-        assertTrue("Set call transition flag failed",
-                   resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
-    }
-}
diff --git a/tests/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)
