diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index 6c3f0bf..3625733 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -43,10 +43,7 @@
 import android.widget.Toast;
 
 import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallManager;
 import com.android.internal.telephony.CallStateException;
-import android.telephony.CallerInfo;
-import android.telephony.CallerInfoAsyncQuery;
 import com.android.internal.telephony.Connection;
 import com.android.internal.telephony.IccCard;
 import com.android.internal.telephony.MmiCode;
@@ -54,10 +51,8 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.TelephonyCapabilities;
-import com.android.phone.CallGatewayManager.RawGatewayInfo;
 import com.android.phone.settings.SuppServicesUiUtil;
 
-import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -131,79 +126,35 @@
     }
 
     /**
-     * @see placeCall below
-     */
-    public static int placeCall(Context context, Phone phone, String number, Uri contactRef,
-            boolean isEmergencyCall) {
-        return placeCall(context, phone, number, contactRef, isEmergencyCall,
-                CallGatewayManager.EMPTY_INFO, null);
-    }
-
-    /**
      * Dial the number using the phone passed in.
      *
-     * If the connection is establised, this method issues a sync call
-     * that may block to query the caller info.
-     * TODO: Change the logic to use the async query.
-     *
      * @param context To perform the CallerInfo query.
      * @param phone the Phone object.
      * @param number to be dialed as requested by the user. This is
      * NOT the phone number to connect to. It is used only to build the
      * call card and to update the call log. See above for restrictions.
-     * @param contactRef that triggered the call. Typically a 'tel:'
-     * uri but can also be a 'content://contacts' one.
-     * @param isEmergencyCall indicates that whether or not this is an
-     * emergency call
-     * @param gatewayUri Is the address used to setup the connection, null
-     * if not using a gateway
-     * @param callGateway Class for setting gateway data on a successful call.
      *
      * @return either CALL_STATUS_DIALED or CALL_STATUS_FAILED
      */
-    public static int placeCall(Context context, Phone phone, String number, Uri contactRef,
-            boolean isEmergencyCall, RawGatewayInfo gatewayInfo, CallGatewayManager callGateway) {
-        final Uri gatewayUri = gatewayInfo.gatewayUri;
+    public static int placeOtaspCall(Context context, Phone phone, String number) {
+        final Uri gatewayUri = null;
 
         if (VDBG) {
             log("placeCall()... number: '" + number + "'"
-                    + ", GW:'" + gatewayUri + "'"
-                    + ", contactRef:" + contactRef
-                    + ", isEmergencyCall: " + isEmergencyCall);
+                    + ", GW:'" + gatewayUri + "'");
         } else {
             log("placeCall()... number: " + toLogSafePhoneNumber(number)
-                    + ", GW: " + (gatewayUri != null ? "non-null" : "null")
-                    + ", emergency? " + isEmergencyCall);
+                    + ", GW: " + (gatewayUri != null ? "non-null" : "null"));
         }
         final PhoneGlobals app = PhoneGlobals.getInstance();
 
         boolean useGateway = false;
-        if (null != gatewayUri &&
-            !isEmergencyCall &&
-            PhoneUtils.isRoutableViaGateway(number)) {  // Filter out MMI, OTA and other codes.
-            useGateway = true;
-        }
+        Uri contactRef = null;
 
         int status = CALL_STATUS_DIALED;
         Connection connection;
         String numberToDial;
-        if (useGateway) {
-            // TODO: 'tel' should be a constant defined in framework base
-            // somewhere (it is in webkit.)
-            if (null == gatewayUri || !PhoneAccount.SCHEME_TEL.equals(gatewayUri.getScheme())) {
-                Log.e(LOG_TAG, "Unsupported URL:" + gatewayUri);
-                return CALL_STATUS_FAILED;
-            }
-
-            // We can use getSchemeSpecificPart because we don't allow #
-            // in the gateway numbers (treated a fragment delim.) However
-            // if we allow more complex gateway numbers sequence (with
-            // passwords or whatnot) that use #, this may break.
-            // TODO: Need to support MMI codes.
-            numberToDial = gatewayUri.getSchemeSpecificPart();
-        } else {
-            numberToDial = number;
-        }
+        numberToDial = number;
 
         try {
             connection = app.mCM.dial(phone, numberToDial, VideoProfile.STATE_AUDIO_ONLY);
@@ -228,33 +179,6 @@
             if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
                 updateCdmaCallStateOnNewOutgoingCall(app, connection);
             }
-
-            if (gatewayUri == null) {
-                // phone.dial() succeeded: we're now in a normal phone call.
-                // attach the URI to the CallerInfo Object if it is there,
-                // otherwise just attach the Uri Reference.
-                // if the uri does not have a "content" scheme, then we treat
-                // it as if it does NOT have a unique reference.
-                String content = context.getContentResolver().SCHEME_CONTENT;
-                if ((contactRef != null) && (contactRef.getScheme().equals(content))) {
-                    Object userDataObject = connection.getUserData();
-                    if (userDataObject == null) {
-                        connection.setUserData(contactRef);
-                    } else {
-                        // TODO: This branch is dead code, we have
-                        // just created the connection which has
-                        // no user data (null) by default.
-                        if (userDataObject instanceof CallerInfo) {
-                        ((CallerInfo) userDataObject).contactRefUri = contactRef;
-                        } else {
-                        ((CallerInfoToken) userDataObject).currentInfo.contactRefUri =
-                            contactRef;
-                        }
-                    }
-                }
-            }
-
-            startGetCallerInfo(context, connection, null, null, gatewayInfo);
         }
 
         return status;
@@ -662,533 +586,12 @@
         return canceled;
     }
 
-    /**
-     * Returns the caller-id info corresponding to the specified Connection.
-     * (This is just a simple wrapper around CallerInfo.getCallerInfo(): we
-     * extract a phone number from the specified Connection, and feed that
-     * number into CallerInfo.getCallerInfo().)
-     *
-     * The returned CallerInfo may be null in certain error cases, like if the
-     * specified Connection was null, or if we weren't able to get a valid
-     * phone number from the Connection.
-     *
-     * Finally, if the getCallerInfo() call did succeed, we save the resulting
-     * CallerInfo object in the "userData" field of the Connection.
-     *
-     * NOTE: This API should be avoided, with preference given to the
-     * asynchronous startGetCallerInfo API.
-     */
-    static CallerInfo getCallerInfo(Context context, Connection c) {
-        CallerInfo info = null;
-
-        if (c != null) {
-            //See if there is a URI attached.  If there is, this means
-            //that there is no CallerInfo queried yet, so we'll need to
-            //replace the URI with a full CallerInfo object.
-            Object userDataObject = c.getUserData();
-            if (userDataObject instanceof Uri) {
-                info = CallerInfo.getCallerInfo(context, (Uri) userDataObject);
-                if (info != null) {
-                    c.setUserData(info);
-                }
-            } else {
-                if (userDataObject instanceof CallerInfoToken) {
-                    //temporary result, while query is running
-                    info = ((CallerInfoToken) userDataObject).currentInfo;
-                } else {
-                    //final query result
-                    info = (CallerInfo) userDataObject;
-                }
-                if (info == null) {
-                    // No URI, or Existing CallerInfo, so we'll have to make do with
-                    // querying a new CallerInfo using the connection's phone number.
-                    String number = c.getAddress();
-
-                    if (DBG) log("getCallerInfo: number = " + toLogSafePhoneNumber(number));
-
-                    if (!TextUtils.isEmpty(number)) {
-                        info = CallerInfo.getCallerInfo(context, number);
-                        if (info != null) {
-                            c.setUserData(info);
-                        }
-                    }
-                }
-            }
-        }
-        return info;
-    }
-
-    /**
-     * Class returned by the startGetCallerInfo call to package a temporary
-     * CallerInfo Object, to be superceded by the CallerInfo Object passed
-     * into the listener when the query with token mAsyncQueryToken is complete.
-     */
-    public static class CallerInfoToken {
-        /**indicates that there will no longer be updates to this request.*/
-        public boolean isFinal;
-
-        public CallerInfo currentInfo;
-        public CallerInfoAsyncQuery asyncQuery;
-    }
-
-    /**
-     * place a temporary callerinfo object in the hands of the caller and notify
-     * caller when the actual query is done.
-     */
-    static CallerInfoToken startGetCallerInfo(Context context, Connection c,
-            CallerInfoAsyncQuery.OnQueryCompleteListener listener, Object cookie,
-            RawGatewayInfo info) {
-        CallerInfoToken cit;
-
-        if (c == null) {
-            //TODO: perhaps throw an exception here.
-            cit = new CallerInfoToken();
-            cit.asyncQuery = null;
-            return cit;
-        }
-
-        Object userDataObject = c.getUserData();
-
-        // There are now 3 states for the Connection's userData object:
-        //
-        //   (1) Uri - query has not been executed yet
-        //
-        //   (2) CallerInfoToken - query is executing, but has not completed.
-        //
-        //   (3) CallerInfo - query has executed.
-        //
-        // In each case we have slightly different behaviour:
-        //   1. If the query has not been executed yet (Uri or null), we start
-        //      query execution asynchronously, and note it by attaching a
-        //      CallerInfoToken as the userData.
-        //   2. If the query is executing (CallerInfoToken), we've essentially
-        //      reached a state where we've received multiple requests for the
-        //      same callerInfo.  That means that once the query is complete,
-        //      we'll need to execute the additional listener requested.
-        //   3. If the query has already been executed (CallerInfo), we just
-        //      return the CallerInfo object as expected.
-        //   4. Regarding isFinal - there are cases where the CallerInfo object
-        //      will not be attached, like when the number is empty (caller id
-        //      blocking).  This flag is used to indicate that the
-        //      CallerInfoToken object is going to be permanent since no
-        //      query results will be returned.  In the case where a query
-        //      has been completed, this flag is used to indicate to the caller
-        //      that the data will not be updated since it is valid.
-        //
-        //      Note: For the case where a number is NOT retrievable, we leave
-        //      the CallerInfo as null in the CallerInfoToken.  This is
-        //      something of a departure from the original code, since the old
-        //      code manufactured a CallerInfo object regardless of the query
-        //      outcome.  From now on, we will append an empty CallerInfo
-        //      object, to mirror previous behaviour, and to avoid Null Pointer
-        //      Exceptions.
-
-        if (userDataObject instanceof Uri) {
-            // State (1): query has not been executed yet
-
-            //create a dummy callerinfo, populate with what we know from URI.
-            cit = new CallerInfoToken();
-            cit.currentInfo = new CallerInfo();
-            cit.asyncQuery = CallerInfoAsyncQuery.startQuery(QUERY_TOKEN, context,
-                    (Uri) userDataObject, sCallerInfoQueryListener, c);
-            cit.asyncQuery.addQueryListener(QUERY_TOKEN, listener, cookie);
-            cit.isFinal = false;
-
-            c.setUserData(cit);
-
-            if (DBG) log("startGetCallerInfo: query based on Uri: " + userDataObject);
-
-        } else if (userDataObject == null) {
-            // No URI, or Existing CallerInfo, so we'll have to make do with
-            // querying a new CallerInfo using the connection's phone number.
-            String number = c.getAddress();
-
-            if (info != null && info != CallGatewayManager.EMPTY_INFO) {
-                // Gateway number, the connection number is actually the gateway number.
-                // need to lookup via dialed number.
-                number = info.trueNumber;
-            }
-
-            if (DBG) {
-                log("PhoneUtils.startGetCallerInfo: new query for phone number...");
-                log("- number (address): " + toLogSafePhoneNumber(number));
-                log("- c: " + c);
-                log("- phone: " + c.getCall().getPhone());
-                int phoneType = c.getCall().getPhone().getPhoneType();
-                log("- phoneType: " + phoneType);
-                switch (phoneType) {
-                    case PhoneConstants.PHONE_TYPE_NONE: log("  ==> PHONE_TYPE_NONE"); break;
-                    case PhoneConstants.PHONE_TYPE_GSM: log("  ==> PHONE_TYPE_GSM"); break;
-                    case PhoneConstants.PHONE_TYPE_IMS: log("  ==> PHONE_TYPE_IMS"); break;
-                    case PhoneConstants.PHONE_TYPE_CDMA: log("  ==> PHONE_TYPE_CDMA"); break;
-                    case PhoneConstants.PHONE_TYPE_SIP: log("  ==> PHONE_TYPE_SIP"); break;
-                    case PhoneConstants.PHONE_TYPE_THIRD_PARTY:
-                        log("  ==> PHONE_TYPE_THIRD_PARTY");
-                        break;
-                    default: log("  ==> Unknown phone type"); break;
-                }
-            }
-
-            cit = new CallerInfoToken();
-            cit.currentInfo = new CallerInfo();
-
-            // Store CNAP information retrieved from the Connection (we want to do this
-            // here regardless of whether the number is empty or not).
-            cit.currentInfo.cnapName =  c.getCnapName();
-            cit.currentInfo.setName(cit.currentInfo.cnapName); // This can still get overwritten
-                                                             // by ContactInfo later
-            cit.currentInfo.numberPresentation = c.getNumberPresentation();
-            cit.currentInfo.namePresentation = c.getCnapNamePresentation();
-
-            if (VDBG) {
-                log("startGetCallerInfo: number = " + number);
-                log("startGetCallerInfo: CNAP Info from FW(1): name="
-                    + cit.currentInfo.cnapName
-                    + ", Name/Number Pres=" + cit.currentInfo.numberPresentation);
-            }
-
-            // handling case where number is null (caller id hidden) as well.
-            if (!TextUtils.isEmpty(number)) {
-                // Check for special CNAP cases and modify the CallerInfo accordingly
-                // to be sure we keep the right information to display/log later
-                number = modifyForSpecialCnapCases(context, cit.currentInfo, number,
-                        cit.currentInfo.numberPresentation);
-
-                cit.currentInfo.setPhoneNumber(number);
-                // For scenarios where we may receive a valid number from the network but a
-                // restricted/unavailable presentation, we do not want to perform a contact query
-                // (see note on isFinal above). So we set isFinal to true here as well.
-                if (cit.currentInfo.numberPresentation != PhoneConstants.PRESENTATION_ALLOWED) {
-                    cit.isFinal = true;
-                } else {
-                    if (DBG) log("==> Actually starting CallerInfoAsyncQuery.startQuery()...");
-                    cit.asyncQuery = CallerInfoAsyncQuery.startQuery(QUERY_TOKEN, context,
-                            number, sCallerInfoQueryListener, c);
-                    cit.asyncQuery.addQueryListener(QUERY_TOKEN, listener, cookie);
-                    cit.isFinal = false;
-                }
-            } else {
-                // This is the case where we are querying on a number that
-                // is null or empty, like a caller whose caller id is
-                // blocked or empty (CLIR).  The previous behaviour was to
-                // throw a null CallerInfo object back to the user, but
-                // this departure is somewhat cleaner.
-                if (DBG) log("startGetCallerInfo: No query to start, send trivial reply.");
-                cit.isFinal = true; // please see note on isFinal, above.
-            }
-
-            c.setUserData(cit);
-
-            if (DBG) {
-                log("startGetCallerInfo: query based on number: " + toLogSafePhoneNumber(number));
-            }
-
-        } else if (userDataObject instanceof CallerInfoToken) {
-            // State (2): query is executing, but has not completed.
-
-            // just tack on this listener to the queue.
-            cit = (CallerInfoToken) userDataObject;
-
-            // handling case where number is null (caller id hidden) as well.
-            if (cit.asyncQuery != null) {
-                cit.asyncQuery.addQueryListener(QUERY_TOKEN, listener, cookie);
-
-                if (DBG) log("startGetCallerInfo: query already running, adding listener: " +
-                        listener.getClass().toString());
-            } else {
-                // handling case where number/name gets updated later on by the network
-                String updatedNumber = c.getAddress();
-
-                if (info != null) {
-                    // Gateway number, the connection number is actually the gateway number.
-                    // need to lookup via dialed number.
-                    updatedNumber = info.trueNumber;
-                }
-
-                if (DBG) {
-                    log("startGetCallerInfo: updatedNumber initially = "
-                            + toLogSafePhoneNumber(updatedNumber));
-                }
-                if (!TextUtils.isEmpty(updatedNumber)) {
-                    // Store CNAP information retrieved from the Connection
-                    cit.currentInfo.cnapName =  c.getCnapName();
-                    // This can still get overwritten by ContactInfo
-                    cit.currentInfo.setName(cit.currentInfo.cnapName);
-                    cit.currentInfo.numberPresentation = c.getNumberPresentation();
-                    cit.currentInfo.namePresentation = c.getCnapNamePresentation();
-
-                    updatedNumber = modifyForSpecialCnapCases(context, cit.currentInfo,
-                            updatedNumber, cit.currentInfo.numberPresentation);
-
-                    cit.currentInfo.setPhoneNumber(updatedNumber);
-                    if (DBG) {
-                        log("startGetCallerInfo: updatedNumber="
-                                + toLogSafePhoneNumber(updatedNumber));
-                    }
-                    if (VDBG) {
-                        log("startGetCallerInfo: CNAP Info from FW(2): name="
-                                + cit.currentInfo.cnapName
-                                + ", Name/Number Pres=" + cit.currentInfo.numberPresentation);
-                    } else if (DBG) {
-                        log("startGetCallerInfo: CNAP Info from FW(2)");
-                    }
-                    // For scenarios where we may receive a valid number from the network but a
-                    // restricted/unavailable presentation, we do not want to perform a contact query
-                    // (see note on isFinal above). So we set isFinal to true here as well.
-                    if (cit.currentInfo.numberPresentation != PhoneConstants.PRESENTATION_ALLOWED) {
-                        cit.isFinal = true;
-                    } else {
-                        cit.asyncQuery = CallerInfoAsyncQuery.startQuery(QUERY_TOKEN, context,
-                                updatedNumber, sCallerInfoQueryListener, c);
-                        cit.asyncQuery.addQueryListener(QUERY_TOKEN, listener, cookie);
-                        cit.isFinal = false;
-                    }
-                } else {
-                    if (DBG) log("startGetCallerInfo: No query to attach to, send trivial reply.");
-                    if (cit.currentInfo == null) {
-                        cit.currentInfo = new CallerInfo();
-                    }
-                    // Store CNAP information retrieved from the Connection
-                    cit.currentInfo.cnapName = c.getCnapName();  // This can still get
-                                                                 // overwritten by ContactInfo
-                    cit.currentInfo.setName(cit.currentInfo.cnapName);
-                    cit.currentInfo.numberPresentation = c.getNumberPresentation();
-                    cit.currentInfo.namePresentation = c.getCnapNamePresentation();
-
-                    if (VDBG) {
-                        log("startGetCallerInfo: CNAP Info from FW(3): name="
-                                + cit.currentInfo.cnapName
-                                + ", Name/Number Pres=" + cit.currentInfo.numberPresentation);
-                    } else if (DBG) {
-                        log("startGetCallerInfo: CNAP Info from FW(3)");
-                    }
-                    cit.isFinal = true; // please see note on isFinal, above.
-                }
-            }
-        } else {
-            // State (3): query is complete.
-
-            // The connection's userDataObject is a full-fledged
-            // CallerInfo instance.  Wrap it in a CallerInfoToken and
-            // return it to the user.
-
-            cit = new CallerInfoToken();
-            cit.currentInfo = (CallerInfo) userDataObject;
-            cit.asyncQuery = null;
-            cit.isFinal = true;
-            // since the query is already done, call the listener.
-            if (DBG) log("startGetCallerInfo: query already done, returning CallerInfo");
-            if (DBG) log("==> cit.currentInfo = " + cit.currentInfo);
-        }
-        return cit;
-    }
-
-    /**
-     * Static CallerInfoAsyncQuery.OnQueryCompleteListener instance that
-     * we use with all our CallerInfoAsyncQuery.startQuery() requests.
-     */
-    private static final int QUERY_TOKEN = -1;
-    static CallerInfoAsyncQuery.OnQueryCompleteListener sCallerInfoQueryListener =
-        new CallerInfoAsyncQuery.OnQueryCompleteListener () {
-            /**
-             * When the query completes, we stash the resulting CallerInfo
-             * object away in the Connection's "userData" (where it will
-             * later be retrieved by the in-call UI.)
-             */
-            public void onQueryComplete(int token, Object cookie, CallerInfo ci) {
-                if (DBG) log("query complete, updating connection.userdata");
-                Connection conn = (Connection) cookie;
-
-                // Added a check if CallerInfo is coming from ContactInfo or from Connection.
-                // If no ContactInfo, then we want to use CNAP information coming from network
-                if (DBG) log("- onQueryComplete: CallerInfo:" + ci);
-                if (ci.contactExists || ci.isEmergencyNumber() || ci.isVoiceMailNumber()) {
-                    // If the number presentation has not been set by
-                    // the ContactInfo, use the one from the
-                    // connection.
-
-                    // TODO: Need a new util method to merge the info
-                    // from the Connection in a CallerInfo object.
-                    // Here 'ci' is a new CallerInfo instance read
-                    // from the DB. It has lost all the connection
-                    // info preset before the query (see PhoneUtils
-                    // line 1334). We should have a method to merge
-                    // back into this new instance the info from the
-                    // connection object not set by the DB. If the
-                    // Connection already has a CallerInfo instance in
-                    // userData, then we could use this instance to
-                    // fill 'ci' in. The same routine could be used in
-                    // PhoneUtils.
-                    if (0 == ci.numberPresentation) {
-                        ci.numberPresentation = conn.getNumberPresentation();
-                    }
-                } else {
-                    // No matching contact was found for this number.
-                    // Return a new CallerInfo based solely on the CNAP
-                    // information from the network.
-
-                    CallerInfo newCi = getCallerInfo(null, conn);
-
-                    // ...but copy over the (few) things we care about
-                    // from the original CallerInfo object:
-                    if (newCi != null) {
-                        newCi.setPhoneNumber(ci.getPhoneNumber()); // To get formatted phone number
-                        newCi.geoDescription = ci.geoDescription; // To get geo description string
-                        ci = newCi;
-                    }
-                }
-
-                if (DBG) log("==> Stashing CallerInfo " + ci + " into the connection...");
-                conn.setUserData(ci);
-            }
-        };
-
-
-    /**
-     * Returns a single "name" for the specified given a CallerInfo object.
-     * If the name is null, return defaultString as the default value, usually
-     * context.getString(R.string.unknown).
-     */
-    static String getCompactNameFromCallerInfo(CallerInfo ci, Context context) {
-        if (DBG) log("getCompactNameFromCallerInfo: info = " + ci);
-
-        String compactName = null;
-        if (ci != null) {
-            if (TextUtils.isEmpty(ci.getName())) {
-                // Perform any modifications for special CNAP cases to
-                // the phone number being displayed, if applicable.
-                compactName = modifyForSpecialCnapCases(context, ci, ci.getPhoneNumber(),
-                                                        ci.numberPresentation);
-            } else {
-                // Don't call modifyForSpecialCnapCases on regular name. See b/2160795.
-                compactName = ci.getName();
-            }
-        }
-
-        if ((compactName == null) || (TextUtils.isEmpty(compactName))) {
-            // If we're still null/empty here, then check if we have a presentation
-            // string that takes precedence that we could return, otherwise display
-            // "unknown" string.
-            if (ci != null && ci.numberPresentation == PhoneConstants.PRESENTATION_RESTRICTED) {
-                compactName = context.getString(R.string.private_num);
-            } else if (ci != null && ci.numberPresentation == PhoneConstants.PRESENTATION_PAYPHONE) {
-                compactName = context.getString(R.string.payphone);
-            } else {
-                compactName = context.getString(R.string.unknown);
-            }
-        }
-        if (VDBG) log("getCompactNameFromCallerInfo: compactName=" + compactName);
-        return compactName;
-    }
-
-    static boolean isInEmergencyCall(CallManager cm) {
-        Call fgCall = cm.getActiveFgCall();
-        // isIdle includes checks for the DISCONNECTING/DISCONNECTED state.
-        if(!fgCall.isIdle()) {
-            for (Connection cn : fgCall.getConnections()) {
-                if (PhoneNumberUtils.isLocalEmergencyNumber(PhoneGlobals.getInstance(),
-                        cn.getAddress())) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
 
     //
     // Misc UI policy helper functions
     //
 
     /**
-     * Based on the input CNAP number string,
-     * @return _RESTRICTED or _UNKNOWN for all the special CNAP strings.
-     * Otherwise, return CNAP_SPECIAL_CASE_NO.
-     */
-    private static int checkCnapSpecialCases(String n) {
-        if (n.equals("PRIVATE") ||
-                n.equals("P") ||
-                n.equals("RES")) {
-            if (DBG) log("checkCnapSpecialCases, PRIVATE string: " + n);
-            return PhoneConstants.PRESENTATION_RESTRICTED;
-        } else if (n.equals("UNAVAILABLE") ||
-                n.equals("UNKNOWN") ||
-                n.equals("UNA") ||
-                n.equals("U")) {
-            if (DBG) log("checkCnapSpecialCases, UNKNOWN string: " + n);
-            return PhoneConstants.PRESENTATION_UNKNOWN;
-        } else {
-            if (DBG) log("checkCnapSpecialCases, normal str. number: " + n);
-            return CNAP_SPECIAL_CASE_NO;
-        }
-    }
-
-    /**
-     * Handles certain "corner cases" for CNAP. When we receive weird phone numbers
-     * from the network to indicate different number presentations, convert them to
-     * expected number and presentation values within the CallerInfo object.
-     * @param number number we use to verify if we are in a corner case
-     * @param presentation presentation value used to verify if we are in a corner case
-     * @return the new String that should be used for the phone number
-     */
-    /* package */ static String modifyForSpecialCnapCases(Context context, CallerInfo ci,
-            String number, int presentation) {
-        // Obviously we return number if ci == null, but still return number if
-        // number == null, because in these cases the correct string will still be
-        // displayed/logged after this function returns based on the presentation value.
-        if (ci == null || number == null) return number;
-
-        if (DBG) {
-            log("modifyForSpecialCnapCases: initially, number="
-                    + toLogSafePhoneNumber(number)
-                    + ", presentation=" + presentation + " ci " + ci);
-        }
-
-        // "ABSENT NUMBER" is a possible value we could get from the network as the
-        // phone number, so if this happens, change it to "Unknown" in the CallerInfo
-        // and fix the presentation to be the same.
-        final String[] absentNumberValues =
-                context.getResources().getStringArray(R.array.absent_num);
-        if (Arrays.asList(absentNumberValues).contains(number)
-                && presentation == PhoneConstants.PRESENTATION_ALLOWED) {
-            number = context.getString(R.string.unknown);
-            ci.numberPresentation = PhoneConstants.PRESENTATION_UNKNOWN;
-        }
-
-        // Check for other special "corner cases" for CNAP and fix them similarly. Corner
-        // cases only apply if we received an allowed presentation from the network, so check
-        // if we think we have an allowed presentation, or if the CallerInfo presentation doesn't
-        // match the presentation passed in for verification (meaning we changed it previously
-        // because it's a corner case and we're being called from a different entry point).
-        if (ci.numberPresentation == PhoneConstants.PRESENTATION_ALLOWED
-                || (ci.numberPresentation != presentation
-                        && presentation == PhoneConstants.PRESENTATION_ALLOWED)) {
-            int cnapSpecialCase = checkCnapSpecialCases(number);
-            if (cnapSpecialCase != CNAP_SPECIAL_CASE_NO) {
-                // For all special strings, change number & numberPresentation.
-                if (cnapSpecialCase == PhoneConstants.PRESENTATION_RESTRICTED) {
-                    number = context.getString(R.string.private_num);
-                } else if (cnapSpecialCase == PhoneConstants.PRESENTATION_UNKNOWN) {
-                    number = context.getString(R.string.unknown);
-                }
-                if (DBG) {
-                    log("SpecialCnap: number=" + toLogSafePhoneNumber(number)
-                            + "; presentation now=" + cnapSpecialCase);
-                }
-                ci.numberPresentation = cnapSpecialCase;
-            }
-        }
-        if (DBG) {
-            log("modifyForSpecialCnapCases: returning number string="
-                    + toLogSafePhoneNumber(number));
-        }
-        return number;
-    }
-
-    //
-    // Support for 3rd party phone service providers.
-    //
-
-    /**
      * Check if a phone number can be route through a 3rd party
      * gateway. The number must be a global phone number in numerical
      * form (1-800-666-SEXY won't work).
diff --git a/src/com/android/phone/otasp/OtaspActivationService.java b/src/com/android/phone/otasp/OtaspActivationService.java
index 7490880..6ed2ea8 100644
--- a/src/com/android/phone/otasp/OtaspActivationService.java
+++ b/src/com/android/phone/otasp/OtaspActivationService.java
@@ -150,11 +150,9 @@
         mPhone.registerForCdmaOtaStatusChange(mHandler, EVENT_CDMA_PROVISION_STATUS_UPDATE, null);
         mPhone.registerForPreciseCallStateChanged(mHandler, EVENT_CALL_STATE_CHANGED, null);
         logd("startNonInteractiveOtasp: placing call to '" + OTASP_NUMBER + "'...");
-        int callStatus = PhoneUtils.placeCall(this,
+        int callStatus = PhoneUtils.placeOtaspCall(this,
                 getPhone(),
-                OTASP_NUMBER,
-                null,   // contactRef
-                false); // isEmergencyCall
+                OTASP_NUMBER);
         if (callStatus == PhoneUtils.CALL_STATUS_DIALED) {
             if (DBG) logd("  ==> success return from placeCall(): callStatus = " + callStatus);
         } else {
diff --git a/tests/src/com/android/phone/CnapTest.java b/tests/src/com/android/phone/CnapTest.java
deleted file mode 100644
index 534d02a..0000000
--- a/tests/src/com/android/phone/CnapTest.java
+++ /dev/null
@@ -1,73 +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.
- */
-
-// Need to be in this package to access package methods.
-package com.android.phone;
-import android.content.Context;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.telephony.CallerInfo;
-
-import static com.android.internal.telephony.PhoneConstants.PRESENTATION_ALLOWED;
-import static com.android.internal.telephony.PhoneConstants.PRESENTATION_UNKNOWN;
-
-// Test suite for the Caller Name Presentation (CNAP) handling.
-// See AndroidManifest.xml how to run these tests.
-public class CnapTest extends AndroidTestCase {
-    private static final String TAG = "CnapTest";
-    private Context mContext;
-    private CallerInfo mCallerInfo;
-    // TODO: This string should be loaded from the phone package and
-    // not hardcoded.
-    private String mUnknown = "Unknown";
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mContext = getContext();
-        mCallerInfo = new CallerInfo();
-    }
-
-    // Checks the cnap 'ABSENT NUMBER' is mapped to the unknown presentation.
-    @SmallTest
-    public void testAbsentNumberIsMappedToUnknown() throws Exception {
-        String num = modifyForSpecialCnapCases("ABSENT NUMBER", PRESENTATION_ALLOWED);
-        assertIsUnknown(num);
-    }
-
-    // HELPERS
-
-    /**
-     * Checks the number and CallerInfo structure indicate the number
-     * is unknown.
-     */
-    private void assertIsUnknown(String number) {
-        assertEquals(mUnknown, number);
-        assertEquals(PRESENTATION_UNKNOWN, mCallerInfo.numberPresentation);
-        // TODO: cnapName and name presentation should be set to
-        // unknown. At least I cannot see why it shouldn't be the case
-        // assertEquals(mUnknown, mCallerInfo.cnapName);
-        // assertEquals(PRESENTATION_UNKNOWN, mCallerInfo.namePresentation);
-    }
-
-    /**
-     * Shorthand for PhoneUtils.modifyForSpecialCnapCases(mContext, mCallerInfo, ...)
-     */
-    private String modifyForSpecialCnapCases(String number, int presentation) {
-        return PhoneUtils.modifyForSpecialCnapCases(
-            mContext, mCallerInfo, number, presentation);
-    }
-}
