diff --git a/src/com/android/phone/CallGatewayManager.java b/src/com/android/phone/CallGatewayManager.java
index bdac983..1dd75c4 100644
--- a/src/com/android/phone/CallGatewayManager.java
+++ b/src/com/android/phone/CallGatewayManager.java
@@ -16,184 +16,19 @@
 
 package com.android.phone;
 
-import android.content.Intent;
 import android.net.Uri;
-import android.telecom.PhoneAccount;
-import android.telephony.PhoneNumberUtils;
 import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.telephony.Connection;
-
-import java.util.concurrent.ConcurrentHashMap;
 
 /**
- * This class manages gateway information for outgoing calls. When calls are made, they may contain
- * gateway information for services which route phone calls through their own service/numbers.
- * The data consists of a number to call and the package name of the service. This data is used in
- * two ways:<br/>
- * 1. Call the appropriate routing number<br/>
- * 2. Display information about the routing to the user<br/>
- *
- * <p>When an outgoing call is finally placed in PhoneUtils.placeCall, it uses this class to get the
- * proper number to dial. It also saves an association between the connection object and the gateway
- * data into this class.
+ * TODO: Not much of this class is even used any more.  Need to unwind the RawGatewayInfo class as
+ * it is used in part of the placeCall method used in OTASP.
  */
 public class CallGatewayManager {
-    private static final String LOG_TAG = CallGatewayManager.class.getSimpleName();
-
-    /**
-     * Intent extra to specify the package name of the gateway
-     * provider.  Used to get the name displayed in the in-call screen
-     * during the call setup. The value is a string.
-     */
-    // TODO: This extra is currently set by the gateway application as
-    // a temporary measure. Ultimately, the framework will securely
-    // set it.
-    /* package */ static final String EXTRA_GATEWAY_PROVIDER_PACKAGE =
-            "com.android.phone.extra.GATEWAY_PROVIDER_PACKAGE";
-
-    /**
-     * Intent extra to specify the URI of the provider to place the
-     * call. The value is a string. It holds the gateway address
-     * (phone gateway URL should start with the 'tel:' scheme) that
-     * will actually be contacted to call the number passed in the
-     * intent URL or in the EXTRA_PHONE_NUMBER extra.
-     */
-    // TODO: Should the value be a Uri (Parcelable)? Need to make sure
-    // MMI code '#' don't get confused as URI fragments.
-    /* package */ static final String EXTRA_GATEWAY_URI =
-            "com.android.phone.extra.GATEWAY_URI";
-
     public static final RawGatewayInfo EMPTY_INFO = new RawGatewayInfo(null, null, null);
 
-    private final ConcurrentHashMap<Connection, RawGatewayInfo> mMap =
-        new ConcurrentHashMap<Connection, RawGatewayInfo>(4, 0.9f, 1);
-
-    private static CallGatewayManager sSingleton;
-
-    public static synchronized CallGatewayManager getInstance() {
-        if (sSingleton == null) {
-            sSingleton = new CallGatewayManager();
-        }
-        return sSingleton;
-    }
-
     private CallGatewayManager() {
     }
 
-    /**
-     * Static method returns an object containing the gateway data stored in the extras of the
-     * Intent parameter.  If no such data exists, returns a Null-Object RawGatewayInfo.
-     * @param intent The intent from which to read gateway data.
-     * @return A populated or empty RawGatewayInfo object.
-     */
-    public static RawGatewayInfo getRawGatewayInfo(Intent intent, String number) {
-        if (hasPhoneProviderExtras(intent)) {
-            return new RawGatewayInfo(intent.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE),
-                    getProviderGatewayUri(intent), number);
-        }
-        return EMPTY_INFO;
-    }
-
-    /**
-     * This function sets the current mapping from connection to gatewayInfo.
-     * @param connection The connection object for the placed outgoing call.
-     * @param gatewayInfo Gateway info gathered using getRawGatewayInfo.
-     */
-    public void setGatewayInfoForConnection(Connection connection, RawGatewayInfo gatewayInfo) {
-        if (!gatewayInfo.isEmpty()) {
-            mMap.put(connection, gatewayInfo);
-        } else {
-            mMap.remove(connection);
-        }
-    }
-
-    /**
-     * Clears the gateway information previously stored via setGatewayInfoForConnection.
-     */
-    public void clearGatewayData(Connection connection) {
-        setGatewayInfoForConnection(connection, EMPTY_INFO);
-    }
-
-    /**
-     * If the parameter matches the connection object we previously saved through
-     * setGatewayInfoForConnection, return the associated raw gateway info data. If not, then
-     * return an empty raw gateway info.
-     */
-    public RawGatewayInfo getGatewayInfo(Connection connection) {
-        final RawGatewayInfo info = mMap.get(connection);
-        if (info != null) {
-            return info;
-        }
-
-        return EMPTY_INFO;
-    }
-
-    /**
-     * Check if all the provider's info is present in the intent.
-     * @param intent Expected to have the provider's extra.
-     * @return true if the intent has all the extras to build the
-     * in-call screen's provider info overlay.
-     */
-    public static boolean hasPhoneProviderExtras(Intent intent) {
-        if (null == intent) {
-            return false;
-        }
-        final String name = intent.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE);
-        final String gatewayUri = intent.getStringExtra(EXTRA_GATEWAY_URI);
-
-        return !TextUtils.isEmpty(name) && !TextUtils.isEmpty(gatewayUri);
-    }
-
-    /**
-     * Copy all the expected extras set when a 3rd party provider is
-     * used from the source intent to the destination one.  Checks all
-     * the required extras are present, if any is missing, none will
-     * be copied.
-     * @param src Intent which may contain the provider's extras.
-     * @param dst Intent where a copy of the extras will be added if applicable.
-     */
-    public static void checkAndCopyPhoneProviderExtras(Intent src, Intent dst) {
-        if (!hasPhoneProviderExtras(src)) {
-            Log.d(LOG_TAG, "checkAndCopyPhoneProviderExtras: some or all extras are missing.");
-            return;
-        }
-
-        dst.putExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE,
-                     src.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE));
-        dst.putExtra(EXTRA_GATEWAY_URI,
-                     src.getStringExtra(EXTRA_GATEWAY_URI));
-    }
-
-    /**
-     * Return the gateway uri from the intent.
-     * @param intent With the gateway uri extra.
-     * @return The gateway URI or null if not found.
-     */
-    public static Uri getProviderGatewayUri(Intent intent) {
-        final String uri = intent.getStringExtra(EXTRA_GATEWAY_URI);
-        return TextUtils.isEmpty(uri) ? null : Uri.parse(uri);
-    }
-
-    /**
-     * Return a formatted version of the uri's scheme specific
-     * part. E.g for 'tel:12345678', return '1-234-5678'.
-     * @param uri A 'tel:' URI with the gateway phone number.
-     * @return the provider's address (from the gateway uri) formatted
-     * for user display. null if uri was null or its scheme was not 'tel:'.
-     */
-    public static String formatProviderUri(Uri uri) {
-        if (uri != null) {
-            if (PhoneAccount.SCHEME_TEL.equals(uri.getScheme())) {
-                return PhoneNumberUtils.formatNumber(uri.getSchemeSpecificPart());
-            } else {
-                return uri.toString();
-            }
-        }
-        return null;
-    }
-
     public static class RawGatewayInfo {
         public String packageName;
         public Uri gatewayUri;
@@ -206,10 +41,6 @@
             this.trueNumber = trueNumber;
         }
 
-        public String getFormattedGatewayNumber() {
-            return formatProviderUri(gatewayUri);
-        }
-
         public boolean isEmpty() {
             return TextUtils.isEmpty(packageName) || gatewayUri == null;
         }
diff --git a/src/com/android/phone/CallLogger.java b/src/com/android/phone/CallLogger.java
deleted file mode 100644
index 60a2590..0000000
--- a/src/com/android/phone/CallLogger.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone;
-
-import android.net.Uri;
-import android.os.SystemProperties;
-import android.provider.CallLog.Calls;
-import android.telephony.DisconnectCause;
-import android.telephony.PhoneNumberUtils;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.telephony.CallerInfo;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyCapabilities;
-import com.android.phone.common.CallLogAsync;
-
-/**
- * Helper class for interacting with the call log.
- */
-class CallLogger {
-    private static final String LOG_TAG = CallLogger.class.getSimpleName();
-    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 1) &&
-        (SystemProperties.getInt("ro.debuggable", 0) == 1);
-    private static final boolean VDBG = (PhoneGlobals.DBG_LEVEL >= 2);
-
-    private PhoneGlobals mApplication;
-    private CallLogAsync mCallLog;
-
-    public CallLogger(PhoneGlobals application, CallLogAsync callLogAsync) {
-        mApplication = application;
-        mCallLog = callLogAsync;
-    }
-
-    /**
-     * Logs a call to the call log based on the connection object passed in.
-     *
-     * @param c The connection object for the call being logged.
-     * @param callLogType The type of call log entry.
-     */
-    public void logCall(Connection c, int callLogType) {
-        final String number = c.getAddress();
-        final long date = c.getCreateTime();
-        final long duration = c.getDurationMillis();
-        final Phone phone = c.getCall().getPhone();
-
-        final CallerInfo ci = getCallerInfoFromConnection(c);  // May be null.
-        final String logNumber = getLogNumber(c, ci);
-
-        if (DBG) {
-            log("- onDisconnect(): logNumber set to:" + PhoneUtils.toLogSafePhoneNumber(logNumber) +
-                ", number set to: " + PhoneUtils.toLogSafePhoneNumber(number));
-        }
-
-        // TODO: In getLogNumber we use the presentation from
-        // the connection for the CNAP. Should we use the one
-        // below instead? (comes from caller info)
-
-        // For international calls, 011 needs to be logged as +
-        final int presentation = getPresentation(c, ci);
-
-        final boolean isOtaspNumber = TelephonyCapabilities.supportsOtasp(phone)
-                && phone.isOtaSpNumber(number);
-
-        // Don't log OTASP calls.
-        if (!isOtaspNumber) {
-            logCall(ci, logNumber, presentation, callLogType, date, duration);
-        }
-    }
-
-    /**
-     * Came as logCall(Connection,int) but calculates the call type from the connection object.
-     */
-    public void logCall(Connection c) {
-        final int cause = c.getDisconnectCause();
-
-        // Set the "type" to be displayed in the call log (see constants in CallLog.Calls)
-        final int callLogType;
-
-        if (c.isIncoming()) {
-            callLogType = (cause == DisconnectCause.INCOMING_MISSED ?
-                           Calls.MISSED_TYPE : Calls.INCOMING_TYPE);
-        } else {
-            callLogType = Calls.OUTGOING_TYPE;
-        }
-        if (VDBG) log("- callLogType: " + callLogType + ", UserData: " + c.getUserData());
-
-        logCall(c, callLogType);
-    }
-
-    /**
-     * Logs a call to the call from the parameters passed in.
-     */
-    public void logCall(CallerInfo ci, String number, int presentation, int callType, long start,
-                        long duration) {
-        // no-op
-    }
-
-    /**
-     * Get the caller info.
-     *
-     * @param conn The phone connection.
-     * @return The CallerInfo associated with the connection. Maybe null.
-     */
-    private CallerInfo getCallerInfoFromConnection(Connection conn) {
-        CallerInfo ci = null;
-        Object o = conn.getUserData();
-
-        if ((o == null) || (o instanceof CallerInfo)) {
-            ci = (CallerInfo) o;
-        } else if (o instanceof Uri) {
-            ci = CallerInfo.getCallerInfo(mApplication.getApplicationContext(), (Uri) o);
-        } else {
-            ci = ((PhoneUtils.CallerInfoToken) o).currentInfo;
-        }
-        return ci;
-    }
-
-    /**
-     * Retrieve the phone number from the caller info or the connection.
-     *
-     * For incoming call the number is in the Connection object. For
-     * outgoing call we use the CallerInfo phoneNumber field if
-     * present. All the processing should have been done already (CDMA vs GSM numbers).
-     *
-     * If CallerInfo is missing the phone number, get it from the connection.
-     * Apply the Call Name Presentation (CNAP) transform in the connection on the number.
-     *
-     * @param conn The phone connection.
-     * @param callerInfo The CallerInfo. Maybe null.
-     * @return the phone number.
-     */
-    private String getLogNumber(Connection conn, CallerInfo callerInfo) {
-        String number = null;
-
-        if (conn.isIncoming()) {
-            number = conn.getAddress();
-        } else {
-            // For emergency and voicemail calls,
-            // CallerInfo.phoneNumber does *not* contain a valid phone
-            // number.  Instead it contains an I18N'd string such as
-            // "Emergency Number" or "Voice Mail" so we get the number
-            // from the connection.
-            if (null == callerInfo || TextUtils.isEmpty(callerInfo.phoneNumber) ||
-                callerInfo.isEmergencyNumber() || callerInfo.isVoiceMailNumber()) {
-                if (conn.getCall().getPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
-                    // In cdma getAddress() is not always equals to getOrigDialString().
-                    number = conn.getOrigDialString();
-                } else {
-                    number = conn.getAddress();
-                }
-            } else {
-                number = callerInfo.phoneNumber;
-            }
-        }
-
-        if (null == number) {
-            return null;
-        } else {
-            int presentation = conn.getNumberPresentation();
-
-            // Do final CNAP modifications.
-            String newNumber = PhoneUtils.modifyForSpecialCnapCases(mApplication, callerInfo,
-                                                          number, presentation);
-
-            if (!PhoneNumberUtils.isUriNumber(number)) {
-                number = PhoneNumberUtils.stripSeparators(number);
-            }
-            if (VDBG) log("getLogNumber: " + number);
-            return number;
-        }
-    }
-
-    /**
-     * Get the presentation from the callerinfo if not null otherwise,
-     * get it from the connection.
-     *
-     * @param conn The phone connection.
-     * @param callerInfo The CallerInfo. Maybe null.
-     * @return The presentation to use in the logs.
-     */
-    private int getPresentation(Connection conn, CallerInfo callerInfo) {
-        int presentation;
-
-        if (null == callerInfo) {
-            presentation = conn.getNumberPresentation();
-        } else {
-            presentation = callerInfo.numberPresentation;
-            if (DBG) log("- getPresentation(): ignoring connection's presentation: " +
-                         conn.getNumberPresentation());
-        }
-        if (DBG) log("- getPresentation: presentation: " + presentation);
-        return presentation;
-    }
-
-    private void log(String msg) {
-        Log.d(LOG_TAG, msg);
-    }
-}
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index 6e55c13..bd97b69 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -253,23 +253,6 @@
     }
 
     /**
-     * Resets the audio mode and speaker state when a call ends.
-     */
-    private void resetAudioStateAfterDisconnect() {
-        if (VDBG) log("resetAudioStateAfterDisconnect()...");
-
-        if (mBluetoothHeadset != null) {
-            mBluetoothHeadset.disconnectAudio();
-        }
-
-        // call turnOnSpeaker() with state=false and store=true even if speaker
-        // is already off to reset user requested speaker state.
-        PhoneUtils.turnOnSpeaker(mApplication, false, true);
-
-        PhoneUtils.setAudioMode(mCM);
-    }
-
-    /**
      * Helper class to play tones through the earpiece (or speaker / BT)
      * during a call, using the ToneGenerator.
      *
@@ -493,23 +476,6 @@
                     mState = TONE_OFF;
                 }
             }
-
-            // Finally, do the same cleanup we otherwise would have done
-            // in onDisconnect().
-            //
-            // (But watch out: do NOT do this if the phone is in use,
-            // since some of our tones get played *during* a call (like
-            // CALL_WAITING) and we definitely *don't*
-            // want to reset the audio mode / speaker / bluetooth after
-            // playing those!
-            // This call is really here for use with tones that get played
-            // *after* a call disconnects, like "busy" or "congestion" or
-            // "call ended", where the phone has already become idle but
-            // we need to defer the resetAudioStateAfterDisconnect() call
-            // till the tone finishes playing.)
-            if (mCM.getState() == PhoneConstants.State.IDLE) {
-                resetAudioStateAfterDisconnect();
-            }
         }
     }
 
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 67ec932..3f679ed 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -50,7 +50,6 @@
 import android.util.Log;
 import android.widget.Toast;
 
-import com.android.internal.telephony.Call;
 import com.android.internal.telephony.CallManager;
 import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.telephony.MmiCode;
@@ -142,7 +141,6 @@
     public PhoneInterfaceManager phoneMgr;
     CarrierConfigLoader configLoader;
 
-    private CallGatewayManager callGatewayManager;
     private Phone phoneInEcm;
 
     static boolean sVoiceCapable = true;
@@ -321,10 +319,6 @@
 
             if (DBG) Log.d(LOG_TAG, "onCreate: mUpdateLock: " + mUpdateLock);
 
-            CallLogger callLogger = new CallLogger(this, new CallLogAsync());
-
-            callGatewayManager = CallGatewayManager.getInstance();
-
             // Create the CallerInfoCache singleton, which remembers custom ring tone and
             // send-to-voicemail settings.
             //
@@ -346,9 +340,6 @@
             // register for MMI/USSD
             mCM.registerForMmiComplete(mHandler, MMI_COMPLETE, null);
 
-            // register connection tracking to PhoneUtils
-            PhoneUtils.initializeConnectionHandler(mCM);
-
             // Register for misc other intent broadcasts.
             IntentFilter intentFilter =
                     new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
@@ -372,11 +363,6 @@
             PreferenceManager.setDefaultValues(this, R.xml.network_setting_fragment, false);
 
             PreferenceManager.setDefaultValues(this, R.xml.call_feature_setting, false);
-
-            // Make sure the audio mode (along with some
-            // audio-mode-related state of our own) is initialized
-            // correctly, given the current state of the phone.
-            PhoneUtils.setAudioMode(mCM);
         }
 
         // XXX pre-load the SimProvider so that it's ready
@@ -409,14 +395,6 @@
     }
 
     /**
-     * Returns the singleton instance of the PhoneApp if running as the
-     * primary user, otherwise null.
-     */
-    static PhoneGlobals getInstanceIfPrimary() {
-        return sMe;
-    }
-
-    /**
      * Returns the default phone.
      *
      * WARNING: This method should be used carefully, now that there may be multiple phones.
@@ -496,52 +474,6 @@
     }
 
     /**
-     * Controls whether or not the screen is allowed to sleep.
-     *
-     * Once sleep is allowed (WakeState is SLEEP), it will rely on the
-     * settings for the poke lock to determine when to timeout and let
-     * the device sleep {@link PhoneGlobals#setScreenTimeout}.
-     *
-     * @param ws tells the device to how to wake.
-     */
-    /* package */ void requestWakeState(WakeState ws) {
-        if (VDBG) Log.d(LOG_TAG, "requestWakeState(" + ws + ")...");
-        synchronized (this) {
-            if (mWakeState != ws) {
-                switch (ws) {
-                    case PARTIAL:
-                        // acquire the processor wake lock, and release the FULL
-                        // lock if it is being held.
-                        mPartialWakeLock.acquire();
-                        if (mWakeLock.isHeld()) {
-                            mWakeLock.release();
-                        }
-                        break;
-                    case FULL:
-                        // acquire the full wake lock, and release the PARTIAL
-                        // lock if it is being held.
-                        mWakeLock.acquire();
-                        if (mPartialWakeLock.isHeld()) {
-                            mPartialWakeLock.release();
-                        }
-                        break;
-                    case SLEEP:
-                    default:
-                        // release both the PARTIAL and FULL locks.
-                        if (mWakeLock.isHeld()) {
-                            mWakeLock.release();
-                        }
-                        if (mPartialWakeLock.isHeld()) {
-                            mPartialWakeLock.release();
-                        }
-                        break;
-                }
-                mWakeState = ws;
-            }
-        }
-    }
-
-    /**
      * If we are not currently keeping the screen on, then poke the power
      * manager to wake up the screen for the user activity timeout duration.
      */
@@ -554,52 +486,6 @@
         }
     }
 
-    /**
-     * Sets the wake state and screen timeout based on the current state
-     * of the phone, and the current state of the in-call UI.
-     *
-     * This method is a "UI Policy" wrapper around
-     * {@link PhoneGlobals#requestWakeState} and {@link PhoneGlobals#setScreenTimeout}.
-     *
-     * It's safe to call this method regardless of the state of the Phone
-     * (e.g. whether or not it's idle), and regardless of the state of the
-     * Phone UI (e.g. whether or not the InCallScreen is active.)
-     */
-    /* package */ void updateWakeState() {
-        PhoneConstants.State state = mCM.getState();
-
-        // True if the speakerphone is in use.  (If so, we *always* use
-        // the default timeout.  Since the user is obviously not holding
-        // the phone up to his/her face, we don't need to worry about
-        // false touches, and thus don't need to turn the screen off so
-        // aggressively.)
-        // Note that we need to make a fresh call to this method any
-        // time the speaker state changes.  (That happens in
-        // PhoneUtils.turnOnSpeaker().)
-        boolean isSpeakerInUse = (state == PhoneConstants.State.OFFHOOK) && PhoneUtils.isSpeakerOn(this);
-
-        // TODO (bug 1440854): The screen timeout *might* also need to
-        // depend on the bluetooth state, but this isn't as clear-cut as
-        // the speaker state (since while using BT it's common for the
-        // user to put the phone straight into a pocket, in which case the
-        // timeout should probably still be short.)
-
-        // Decide whether to force the screen on or not.
-        //
-        // Force the screen to be on if the phone is ringing or dialing,
-        // or if we're displaying the "Call ended" UI for a connection in
-        // the "disconnected" state.
-        // However, if the phone is disconnected while the user is in the
-        // middle of selecting a quick response message, we should not force
-        // the screen to be on.
-        //
-        boolean isRinging = (state == PhoneConstants.State.RINGING);
-        boolean isDialing = (mCM.getFgPhone().getForegroundCall().getState() == Call.State.DIALING);
-        boolean keepScreenOn = isRinging || isDialing;
-        // keepScreenOn == true means we'll hold a full wake lock:
-        requestWakeState(keepScreenOn ? WakeState.FULL : WakeState.SLEEP);
-    }
-
     KeyguardManager getKeyguardManager() {
         return mKeyguardManager;
     }
@@ -879,41 +765,6 @@
     }
 
     /**
-     * Dismisses the message waiting (voicemail) indicator.
-     *
-     * @param subId the subscription id we should dismiss the notification for.
-     */
-    public void clearMwiIndicator(int subId) {
-        // Setting voiceMessageCount to 0 will remove the current notification and clear the system
-        // cached value.
-        Phone phone = getPhone(subId);
-        if (phone == null) {
-            Log.w(LOG_TAG, "clearMwiIndicator on null phone, subId:" + subId);
-        } else {
-            phone.setVoiceMessageCount(0);
-        }
-    }
-
-    /**
-     * Enables or disables the visual voicemail check for message waiting indicator. Default value
-     * is true. MWI is the traditional voicemail notification which should be suppressed if visual
-     * voicemail is active. {@link NotificationMgr#updateMwi(int, boolean, boolean)} currently
-     * checks the {@link android.provider.VoicemailContract.Status#CONFIGURATION_STATE} to suppress
-     * the MWI, but there are several issues. b/31229016 is a bug that when the device boots the
-     * configuration state will be cleared and the MWI for voicemail that arrives when the device
-     * is offline will be cleared, even if the account cannot be activated. A full solution will be
-     * adding a setMwiEnabled() method and stop checking the configuration state, but that is too
-     * risky at this moment. This is a temporary workaround to shut down the configuration state
-     * check if visual voicemail cannot be activated.
-     * <p>TODO(twyen): implement the setMwiEnabled() mentioned above.
-     *
-     * @param subId the account to set the enabled state
-     */
-    public void setShouldCheckVisualVoicemailConfigurationForMwi(int subId, boolean enabled) {
-        notificationMgr.setShouldCheckVisualVoicemailConfigurationForMwi(subId, enabled);
-    }
-
-    /**
      * Dump the state of the object, add calls to other objects as desired.
      *
      * @param fd File descriptor
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index dfc7382..a39024f 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -1255,112 +1255,6 @@
         }
     }
 
-    /**
-     * End a call based on call state
-     * @return true is a call was ended
-     */
-    public boolean endCall() {
-        return false;
-    }
-
-    /**
-     * End a call based on the call state of the subId
-     * @return true is a call was ended
-     */
-    public boolean endCallForSubscriber(int subId) {
-        return false;
-    }
-
-    public void answerRingingCall() {
-        // Deprecated.
-    }
-
-    public void answerRingingCallForSubscriber(int subId) {
-        // Deprecated
-    }
-
-    /**
-     * This method is no longer used and can be removed once TelephonyManager stops referring to it.
-     */
-    public void silenceRinger() {
-        Log.e(LOG_TAG, "silenseRinger not supported");
-    }
-
-    @Override
-    public boolean isOffhook(String callingPackage) {
-        return isOffhookForSubscriber(getDefaultSubscription(), callingPackage);
-    }
-
-    @Override
-    public boolean isOffhookForSubscriber(int subId, String callingPackage) {
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "isOffhookForSubscriber")) {
-            return false;
-        }
-
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            final Phone phone = getPhone(subId);
-            if (phone != null) {
-                return (phone.getState() == PhoneConstants.State.OFFHOOK);
-            } else {
-                return false;
-            }
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    @Override
-    public boolean isRinging(String callingPackage) {
-        return (isRingingForSubscriber(getDefaultSubscription(), callingPackage));
-    }
-
-    @Override
-    public boolean isRingingForSubscriber(int subId, String callingPackage) {
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "isRingingForSubscriber")) {
-            return false;
-        }
-
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            final Phone phone = getPhone(subId);
-            if (phone != null) {
-                return (phone.getState() == PhoneConstants.State.RINGING);
-            } else {
-                return false;
-            }
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    @Override
-    public boolean isIdle(String callingPackage) {
-        return isIdleForSubscriber(getDefaultSubscription(), callingPackage);
-    }
-
-    @Override
-    public boolean isIdleForSubscriber(int subId, String callingPackage) {
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "isIdleForSubscriber")) {
-            return false;
-        }
-
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            final Phone phone = getPhone(subId);
-            if (phone != null) {
-                return (phone.getState() == PhoneConstants.State.IDLE);
-            } else {
-                return false;
-            }
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
     public boolean supplyPin(String pin) {
         return supplyPinForSubscriber(getDefaultSubscription(), pin);
     }
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index 9ede914..c1bd1b6 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -23,9 +23,6 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.media.AudioManager;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Message;
@@ -56,7 +53,6 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.TelephonyCapabilities;
-import com.android.internal.telephony.sip.SipPhone;
 import com.android.phone.CallGatewayManager.RawGatewayInfo;
 
 import java.util.Arrays;
@@ -73,43 +69,15 @@
     // Do not check in with VDBG = true, since that may write PII to the system log.
     private static final boolean VDBG = false;
 
-    /** Control stack trace for Audio Mode settings */
-    private static final boolean DBG_SETAUDIOMODE_STACK = false;
-
-    /** Identifier for the "Add Call" intent extra. */
-    static final String ADD_CALL_MODE_KEY = "add_call_mode";
-
     // Return codes from placeCall()
     public static final int CALL_STATUS_DIALED = 0;  // The number was successfully dialed
     public static final int CALL_STATUS_DIALED_MMI = 1;  // The specified number was an MMI code
     public static final int CALL_STATUS_FAILED = 2;  // The call failed
 
-    // State of the Phone's audio modes
-    // Each state can move to the other states, but within the state only certain
-    //  transitions for AudioManager.setMode() are allowed.
-    static final int AUDIO_IDLE = 0;  /** audio behaviour at phone idle */
-    static final int AUDIO_RINGING = 1;  /** audio behaviour while ringing */
-    static final int AUDIO_OFFHOOK = 2;  /** audio behaviour while in call. */
-
     // USSD string length for MMI operations
     static final int MIN_USSD_LEN = 1;
     static final int MAX_USSD_LEN = 160;
 
-    /** Speaker state, persisting between wired headset connection events */
-    private static boolean sIsSpeakerEnabled = false;
-
-    /** Static handler for the connection/mute tracking */
-    private static ConnectionHandler mConnectionHandler;
-
-    /** Phone state changed event*/
-    private static final int PHONE_STATE_CHANGED = -1;
-
-    /** poll phone DISCONNECTING status interval */
-    private static final int DISCONNECTING_POLLING_INTERVAL_MS = 200;
-
-    /** poll phone DISCONNECTING status times limit */
-    private static final int DISCONNECTING_POLLING_TIMES_LIMIT = 8;
-
     /** Define for not a special CNAP string */
     private static final int CNAP_SPECIAL_CASE_NO = -1;
 
@@ -128,26 +96,6 @@
             new ComponentName("com.android.phone",
                     "com.android.services.telephony.TelephonyConnectionService");
 
-    /**
-     * Handler that tracks the connections and updates the value of the
-     * Mute settings for each connection as needed.
-     */
-    private static class ConnectionHandler extends Handler {
-    }
-
-    /**
-     * Register the ConnectionHandler with the phone, to receive connection events
-     */
-    public static void initializeConnectionHandler(CallManager cm) {
-        if (mConnectionHandler == null) {
-            mConnectionHandler = new ConnectionHandler();
-        }
-
-        // pass over cm as user.obj
-        cm.registerForPreciseCallStateChanged(mConnectionHandler, PHONE_STATE_CHANGED, cm);
-
-    }
-
     /** This class is never instantiated. */
     private PhoneUtils() {
     }
@@ -255,10 +203,6 @@
             numberToDial = number;
         }
 
-        // Remember if the phone state was in IDLE state before this call.
-        // After calling CallManager#dial(), getState() will return different state.
-        final boolean initiallyIdle = app.mCM.getState() == PhoneConstants.State.IDLE;
-
         try {
             connection = app.mCM.dial(phone, numberToDial, VideoProfile.STATE_AUDIO_ONLY);
         } catch (CallStateException ex) {
@@ -279,11 +223,6 @@
         if (null == connection) {
             status = CALL_STATUS_FAILED;
         } else {
-            // Now that the call is successful, we can save the gateway info for the call
-            if (callGateway != null) {
-                callGateway.setGatewayInfoForConnection(connection, gatewayInfo);
-            }
-
             if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
                 updateCdmaCallStateOnNewOutgoingCall(app, connection);
             }
@@ -314,8 +253,6 @@
             }
 
             startGetCallerInfo(context, connection, null, null, gatewayInfo);
-
-            setAudioMode();
         }
 
         return status;
@@ -346,15 +283,6 @@
         return builder.toString();
     }
 
-    static void separateCall(Connection c) {
-        try {
-            if (DBG) log("separateCall: " + toLogSafePhoneNumber(c.getAddress()));
-            c.separate();
-        } catch (CallStateException ex) {
-            Log.w(LOG_TAG, "separateCall: caught " + ex, ex);
-        }
-    }
-
     /**
      * Handle the MMIInitiate message and put up an alert that lets
      * the user cancel the operation, if applicable.
@@ -688,64 +616,6 @@
         return canceled;
     }
 
-    public static class VoiceMailNumberMissingException extends Exception {
-        VoiceMailNumberMissingException() {
-            super();
-        }
-
-        VoiceMailNumberMissingException(String msg) {
-            super(msg);
-        }
-    }
-
-    /**
-     * Gets the phone number to be called from an intent.  Requires a Context
-     * to access the contacts database, and a Phone to access the voicemail
-     * number.
-     *
-     * <p>If <code>phone</code> is <code>null</code>, the function will return
-     * <code>null</code> for <code>voicemail:</code> URIs;
-     * if <code>context</code> is <code>null</code>, the function will return
-     * <code>null</code> for person/phone URIs.</p>
-     *
-     * <p>If the intent contains a <code>sip:</code> URI, the returned
-     * "number" is actually the SIP address.
-     *
-     * @param context a context to use (or
-     * @param intent the intent
-     *
-     * @throws VoiceMailNumberMissingException if <code>intent</code> contains
-     *         a <code>voicemail:</code> URI, but <code>phone</code> does not
-     *         have a voicemail number set.
-     *
-     * @return the phone number (or SIP address) that would be called by the intent,
-     *         or <code>null</code> if the number cannot be found.
-     */
-    private static String getNumberFromIntent(Context context, Intent intent)
-            throws VoiceMailNumberMissingException {
-        Uri uri = intent.getData();
-        String scheme = uri.getScheme();
-
-        // The sip: scheme is simple: just treat the rest of the URI as a
-        // SIP address.
-        if (PhoneAccount.SCHEME_SIP.equals(scheme)) {
-            return uri.getSchemeSpecificPart();
-        }
-
-        // Otherwise, let PhoneNumberUtils.getNumberFromIntent() handle
-        // the other cases (i.e. tel: and voicemail: and contact: URIs.)
-
-        final String number = PhoneNumberUtils.getNumberFromIntent(intent, context);
-
-        // Check for a voicemail-dialing request.  If the voicemail number is
-        // empty, throw a VoiceMailNumberMissingException.
-        if (PhoneAccount.SCHEME_VOICEMAIL.equals(scheme) &&
-                (number == null || TextUtils.isEmpty(number)))
-            throw new VoiceMailNumberMissingException();
-
-        return number;
-    }
-
     /**
      * Returns the caller-id info corresponding to the specified Connection.
      * (This is just a simple wrapper around CallerInfo.getCallerInfo(): we
@@ -816,32 +686,6 @@
     }
 
     /**
-     * Start a CallerInfo Query based on the earliest connection in the call.
-     */
-    static CallerInfoToken startGetCallerInfo(Context context, Call call,
-            CallerInfoAsyncQuery.OnQueryCompleteListener listener, Object cookie) {
-        Connection conn = null;
-        int phoneType = call.getPhone().getPhoneType();
-        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-            conn = call.getLatestConnection();
-        } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
-                || (phoneType == PhoneConstants.PHONE_TYPE_SIP)
-                || (phoneType == PhoneConstants.PHONE_TYPE_IMS)
-                || (phoneType == PhoneConstants.PHONE_TYPE_THIRD_PARTY)) {
-            conn = call.getEarliestConnection();
-        } else {
-            throw new IllegalStateException("Unexpected phone type: " + phoneType);
-        }
-
-        return startGetCallerInfo(context, conn, listener, cookie);
-    }
-
-    static CallerInfoToken startGetCallerInfo(Context context, Connection c,
-            CallerInfoAsyncQuery.OnQueryCompleteListener listener, Object cookie) {
-        return startGetCallerInfo(context, c, listener, cookie, null);
-    }
-
-    /**
      * place a temporary callerinfo object in the hands of the caller and notify
      * caller when the actual query is done.
      */
@@ -1191,188 +1035,15 @@
         return compactName;
     }
 
-    /**
-     * Returns true if the specified Call is a "conference call", meaning
-     * that it owns more than one Connection object.  This information is
-     * used to trigger certain UI changes that appear when a conference
-     * call is active (like displaying the label "Conference call", and
-     * enabling the "Manage conference" UI.)
-     *
-     * Watch out: This method simply checks the number of Connections,
-     * *not* their states.  So if a Call has (for example) one ACTIVE
-     * connection and one DISCONNECTED connection, this method will return
-     * true (which is unintuitive, since the Call isn't *really* a
-     * conference call any more.)
-     *
-     * @return true if the specified call has more than one connection (in any state.)
-     */
-    static boolean isConferenceCall(Call call) {
-        // CDMA phones don't have the same concept of "conference call" as
-        // GSM phones do; there's no special "conference call" state of
-        // the UI or a "manage conference" function.  (Instead, when
-        // you're in a 3-way call, all we can do is display the "generic"
-        // state of the UI.)  So as far as the in-call UI is concerned,
-        // Conference corresponds to generic display.
-        final PhoneGlobals app = PhoneGlobals.getInstance();
-        int phoneType = call.getPhone().getPhoneType();
-        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-            CdmaPhoneCallState.PhoneCallState state = app.cdmaPhoneCallState.getCurrentCallState();
-            if ((state == CdmaPhoneCallState.PhoneCallState.CONF_CALL)
-                    || ((state == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
-                    && !app.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing())) {
-                return true;
-            }
-        } else {
-            List<Connection> connections = call.getConnections();
-            if (connections != null && connections.size() > 1) {
-                return true;
-            }
-        }
-        return false;
-
-        // TODO: We may still want to change the semantics of this method
-        // to say that a given call is only really a conference call if
-        // the number of ACTIVE connections, not the total number of
-        // connections, is greater than one.  (See warning comment in the
-        // javadoc above.)
-        // Here's an implementation of that:
-        //        if (connections == null) {
-        //            return false;
-        //        }
-        //        int numActiveConnections = 0;
-        //        for (Connection conn : connections) {
-        //            if (DBG) log("  - CONN: " + conn + ", state = " + conn.getState());
-        //            if (conn.getState() == Call.State.ACTIVE) numActiveConnections++;
-        //            if (numActiveConnections > 1) {
-        //                return true;
-        //            }
-        //        }
-        //        return false;
-    }
-
-    /**
-     * Launch the Dialer to start a new call.
-     * This is just a wrapper around the ACTION_DIAL intent.
-     */
-    /* package */ static boolean startNewCall(final CallManager cm) {
-        final PhoneGlobals app = PhoneGlobals.getInstance();
-
-        // Sanity-check that this is OK given the current state of the phone.
-        if (!okToAddCall(cm)) {
-            Log.w(LOG_TAG, "startNewCall: can't add a new call in the current state");
-            dumpCallManager();
-            return false;
-        }
-
-        Intent intent = new Intent(Intent.ACTION_DIAL);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        // when we request the dialer come up, we also want to inform
-        // it that we're going through the "add call" option from the
-        // InCallScreen / PhoneUtils.
-        intent.putExtra(ADD_CALL_MODE_KEY, true);
-        try {
-            app.startActivity(intent);
-        } catch (ActivityNotFoundException e) {
-            // This is rather rare but possible.
-            // Note: this method is used even when the phone is encrypted. At that moment
-            // the system may not find any Activity which can accept this Intent.
-            Log.e(LOG_TAG, "Activity for adding calls isn't found.");
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Turns on/off speaker.
-     *
-     * @param context Context
-     * @param flag True when speaker should be on. False otherwise.
-     * @param store True when the settings should be stored in the device.
-     */
-    /* package */ static void turnOnSpeaker(Context context, boolean flag, boolean store) {
-        if (DBG) log("turnOnSpeaker(flag=" + flag + ", store=" + store + ")...");
-        final PhoneGlobals app = PhoneGlobals.getInstance();
-
-        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
-        audioManager.setSpeakerphoneOn(flag);
-
-        // record the speaker-enable value
-        if (store) {
-            sIsSpeakerEnabled = flag;
-        }
-
-        // We also need to make a fresh call to PhoneApp.updateWakeState()
-        // any time the speaker state changes, since the screen timeout is
-        // sometimes different depending on whether or not the speaker is
-        // in use.
-        app.updateWakeState();
-
-        app.mCM.setEchoSuppressionEnabled();
-    }
-
-    /**
-     * Restore the speaker mode, called after a wired headset disconnect
-     * event.
-     */
-    static void restoreSpeakerMode(Context context) {
-        if (DBG) log("restoreSpeakerMode, restoring to: " + sIsSpeakerEnabled);
-
-        // change the mode if needed.
-        if (isSpeakerOn(context) != sIsSpeakerEnabled) {
-            turnOnSpeaker(context, sIsSpeakerEnabled, false);
-        }
-    }
-
-    static boolean isSpeakerOn(Context context) {
-        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
-        return audioManager.isSpeakerphoneOn();
-    }
-
-    /**
-     * Get the mute state of foreground phone, which has the current
-     * foreground call
-     */
-    static boolean getMute() {
-        return false;
-    }
-
-    /* package */ static void setAudioMode() {
-    }
-
-    /**
-     * Sets the audio mode per current phone state.
-     */
-    /* package */ static void setAudioMode(CallManager cm) {
-    }
-
-    /**
-     * Look for ANY connections on the phone that qualify as being
-     * disconnected.
-     *
-     * @return true if we find a connection that is disconnected over
-     * all the phone's call objects.
-     */
-    /* package */ static boolean hasDisconnectedConnections(Phone phone) {
-        return hasDisconnectedConnections(phone.getForegroundCall()) ||
-                hasDisconnectedConnections(phone.getBackgroundCall()) ||
-                hasDisconnectedConnections(phone.getRingingCall());
-    }
-
-    /**
-     * Iterate over all connections in a call to see if there are any
-     * that are not alive (disconnected or idle).
-     *
-     * @return true if we find a connection that is disconnected, and
-     * pending removal via
-     * {@link com.android.internal.telephony.Call#clearDisconnected()}.
-     */
-    private static final boolean hasDisconnectedConnections(Call call) {
-        // look through all connections for non-active ones.
-        for (Connection c : call.getConnections()) {
-            if (!c.isAlive()) {
-                return true;
+    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;
@@ -1383,147 +1054,6 @@
     //
 
     /**
-     * @return true if we're allowed to hold calls, given the current
-     * state of the Phone.
-     */
-    /* package */ static boolean okToHoldCall(CallManager cm) {
-        final Call fgCall = cm.getActiveFgCall();
-        final boolean hasHoldingCall = cm.hasActiveBgCall();
-        final Call.State fgCallState = fgCall.getState();
-
-        // The "Hold" control is disabled entirely if there's
-        // no way to either hold or unhold in the current state.
-        final boolean okToHold = (fgCallState == Call.State.ACTIVE) && !hasHoldingCall;
-        final boolean okToUnhold = cm.hasActiveBgCall() && (fgCallState == Call.State.IDLE);
-        final boolean canHold = okToHold || okToUnhold;
-
-        return canHold;
-    }
-
-    /**
-     * @return true if we support holding calls, given the current
-     * state of the Phone.
-     */
-    /* package */ static boolean okToSupportHold(CallManager cm) {
-        boolean supportsHold = false;
-
-        final Call fgCall = cm.getActiveFgCall();
-        final boolean hasHoldingCall = cm.hasActiveBgCall();
-        final Call.State fgCallState = fgCall.getState();
-
-        if (TelephonyCapabilities.supportsHoldAndUnhold(fgCall.getPhone())) {
-            // This phone has the concept of explicit "Hold" and "Unhold" actions.
-            supportsHold = true;
-        } else if (hasHoldingCall && (fgCallState == Call.State.IDLE)) {
-            // Even when foreground phone device doesn't support hold/unhold, phone devices
-            // for background holding calls may do.
-            final Call bgCall = cm.getFirstActiveBgCall();
-            if (bgCall != null &&
-                    TelephonyCapabilities.supportsHoldAndUnhold(bgCall.getPhone())) {
-                supportsHold = true;
-            }
-        }
-        return supportsHold;
-    }
-
-    /**
-     * @return true if we're allowed to swap calls, given the current
-     * state of the Phone.
-     */
-    /* package */ static boolean okToSwapCalls(CallManager cm) {
-        int phoneType = cm.getDefaultPhone().getPhoneType();
-        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-            // CDMA: "Swap" is enabled only when the phone reaches a *generic*.
-            // state by either accepting a Call Waiting or by merging two calls
-            PhoneGlobals app = PhoneGlobals.getInstance();
-            return (app.cdmaPhoneCallState.getCurrentCallState()
-                    == CdmaPhoneCallState.PhoneCallState.CONF_CALL);
-        } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
-                || (phoneType == PhoneConstants.PHONE_TYPE_SIP)
-                || (phoneType == PhoneConstants.PHONE_TYPE_IMS)
-                || (phoneType == PhoneConstants.PHONE_TYPE_THIRD_PARTY)) {
-            // GSM: "Swap" is available if both lines are in use and there's no
-            // incoming call.  (Actually we need to verify that the active
-            // call really is in the ACTIVE state and the holding call really
-            // is in the HOLDING state, since you *can't* actually swap calls
-            // when the foreground call is DIALING or ALERTING.)
-            return !cm.hasActiveRingingCall()
-                    && (cm.getActiveFgCall().getState() == Call.State.ACTIVE)
-                    && (cm.getFirstActiveBgCall().getState() == Call.State.HOLDING);
-        } else {
-            throw new IllegalStateException("Unexpected phone type: " + phoneType);
-        }
-    }
-
-    /**
-     * @return true if we're allowed to merge calls, given the current
-     * state of the Phone.
-     */
-    /* package */ static boolean okToMergeCalls(CallManager cm) {
-        int phoneType = cm.getFgPhone().getPhoneType();
-        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-            // CDMA: "Merge" is enabled only when the user is in a 3Way call.
-            PhoneGlobals app = PhoneGlobals.getInstance();
-            return ((app.cdmaPhoneCallState.getCurrentCallState()
-                    == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
-                    && !app.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing());
-        } else {
-            // GSM: "Merge" is available if both lines are in use and there's no
-            // incoming call, *and* the current conference isn't already
-            // "full".
-            // TODO: shall move all okToMerge logic to CallManager
-            return !cm.hasActiveRingingCall() && cm.hasActiveFgCall()
-                    && cm.hasActiveBgCall()
-                    && cm.canConference(cm.getFirstActiveBgCall());
-        }
-    }
-
-    /**
-     * @return true if the UI should let you add a new call, given the current
-     * state of the Phone.
-     */
-    /* package */ static boolean okToAddCall(CallManager cm) {
-        Phone phone = cm.getActiveFgCall().getPhone();
-
-        // "Add call" is never allowed in emergency callback mode (ECM).
-        if (isPhoneInEcm(phone)) {
-            return false;
-        }
-
-        int phoneType = phone.getPhoneType();
-        final Call.State fgCallState = cm.getActiveFgCall().getState();
-        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-           // CDMA: "Add call" button is only enabled when:
-           // - ForegroundCall is in ACTIVE state
-           // - After 30 seconds of user Ignoring/Missing a Call Waiting call.
-            PhoneGlobals app = PhoneGlobals.getInstance();
-            return ((fgCallState == Call.State.ACTIVE)
-                    && (app.cdmaPhoneCallState.getAddCallMenuStateAfterCallWaiting()));
-        } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
-                || (phoneType == PhoneConstants.PHONE_TYPE_SIP)
-                || (phoneType == PhoneConstants.PHONE_TYPE_IMS)
-                || (phoneType == PhoneConstants.PHONE_TYPE_THIRD_PARTY)) {
-            // GSM: "Add call" is available only if ALL of the following are true:
-            // - There's no incoming ringing call
-            // - There's < 2 lines in use
-            // - The foreground call is ACTIVE or IDLE or DISCONNECTED.
-            //   (We mainly need to make sure it *isn't* DIALING or ALERTING.)
-            final boolean hasRingingCall = cm.hasActiveRingingCall();
-            final boolean hasActiveCall = cm.hasActiveFgCall();
-            final boolean hasHoldingCall = cm.hasActiveBgCall();
-            final boolean allLinesTaken = hasActiveCall && hasHoldingCall;
-
-            return !hasRingingCall
-                    && !allLinesTaken
-                    && ((fgCallState == Call.State.ACTIVE)
-                        || (fgCallState == Call.State.IDLE)
-                        || (fgCallState == Call.State.DISCONNECTED));
-        } else {
-            throw new IllegalStateException("Unexpected phone type: " + phoneType);
-        }
-    }
-
-    /**
      * Based on the input CNAP number string,
      * @return _RESTRICTED or _UNKNOWN for all the special CNAP strings.
      * Otherwise, return CNAP_SPECIAL_CASE_NO.
@@ -1646,47 +1176,6 @@
     }
 
     /**
-     * Returns the most appropriate Phone object to handle a call
-     * to the specified number.
-     *
-     * @param cm the CallManager.
-     * @param scheme the scheme from the data URI that the number originally came from.
-     * @param number the phone number, or SIP address.
-     */
-    public static Phone pickPhoneBasedOnNumber(CallManager cm, String scheme, String number,
-            String primarySipUri, ComponentName thirdPartyCallComponent) {
-        if (DBG) {
-            log("pickPhoneBasedOnNumber: scheme " + scheme
-                    + ", number " + toLogSafePhoneNumber(number)
-                    + ", sipUri "
-                    + (primarySipUri != null ? Uri.parse(primarySipUri).toSafeString() : "null")
-                    + ", thirdPartyCallComponent: " + thirdPartyCallComponent);
-        }
-
-        if (primarySipUri != null) {
-            Phone phone = getSipPhoneFromUri(cm, primarySipUri);
-            if (phone != null) return phone;
-        }
-
-        return cm.getDefaultPhone();
-    }
-
-    public static Phone getSipPhoneFromUri(CallManager cm, String target) {
-        for (Phone phone : cm.getAllPhones()) {
-            if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_SIP) {
-                String sipUri = ((SipPhone) phone).getSipUri();
-                if (target.equals(sipUri)) {
-                    if (DBG) log("- pickPhoneBasedOnNumber:" +
-                            "found SipPhone! obj = " + phone + ", "
-                            + phone.getClass());
-                    return phone;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
      * Returns true when the given call is in INCOMING state and there's no foreground phone call,
      * meaning the call is the first real incoming call the phone is having.
      */
@@ -1694,166 +1183,14 @@
         return (state == Call.State.INCOMING && !PhoneGlobals.getInstance().mCM.hasActiveFgCall());
     }
 
-    public static String getPresentationString(Context context, int presentation) {
-        String name = context.getString(R.string.unknown);
-        if (presentation == PhoneConstants.PRESENTATION_RESTRICTED) {
-            name = context.getString(R.string.private_num);
-        } else if (presentation == PhoneConstants.PRESENTATION_PAYPHONE) {
-            name = context.getString(R.string.payphone);
-        }
-        return name;
-    }
-
-    public static void sendViewNotificationAsync(Context context, Uri contactUri) {
-        if (DBG) Log.d(LOG_TAG, "Send view notification to Contacts (uri: " + contactUri + ")");
-        Intent intent = new Intent("com.android.contacts.VIEW_NOTIFICATION", contactUri);
-        intent.setClassName("com.android.contacts",
-                "com.android.contacts.ViewNotificationService");
-        context.startService(intent);
-    }
-
     //
     // General phone and call state debugging/testing code
     //
 
-    /* package */ static void dumpCallState(Phone phone) {
-        PhoneGlobals app = PhoneGlobals.getInstance();
-        Log.d(LOG_TAG, "dumpCallState():");
-        Log.d(LOG_TAG, "- Phone: " + phone + ", name = " + phone.getPhoneName()
-              + ", state = " + phone.getState());
-
-        StringBuilder b = new StringBuilder(128);
-
-        Call call = phone.getForegroundCall();
-        b.setLength(0);
-        b.append("  - FG call: ").append(call.getState());
-        b.append(" isAlive ").append(call.getState().isAlive());
-        b.append(" isRinging ").append(call.getState().isRinging());
-        b.append(" isDialing ").append(call.getState().isDialing());
-        b.append(" isIdle ").append(call.isIdle());
-        b.append(" hasConnections ").append(call.hasConnections());
-        Log.d(LOG_TAG, b.toString());
-
-        call = phone.getBackgroundCall();
-        b.setLength(0);
-        b.append("  - BG call: ").append(call.getState());
-        b.append(" isAlive ").append(call.getState().isAlive());
-        b.append(" isRinging ").append(call.getState().isRinging());
-        b.append(" isDialing ").append(call.getState().isDialing());
-        b.append(" isIdle ").append(call.isIdle());
-        b.append(" hasConnections ").append(call.hasConnections());
-        Log.d(LOG_TAG, b.toString());
-
-        call = phone.getRingingCall();
-        b.setLength(0);
-        b.append("  - RINGING call: ").append(call.getState());
-        b.append(" isAlive ").append(call.getState().isAlive());
-        b.append(" isRinging ").append(call.getState().isRinging());
-        b.append(" isDialing ").append(call.getState().isDialing());
-        b.append(" isIdle ").append(call.isIdle());
-        b.append(" hasConnections ").append(call.hasConnections());
-        Log.d(LOG_TAG, b.toString());
-
-
-        final boolean hasRingingCall = !phone.getRingingCall().isIdle();
-        final boolean hasActiveCall = !phone.getForegroundCall().isIdle();
-        final boolean hasHoldingCall = !phone.getBackgroundCall().isIdle();
-        final boolean allLinesTaken = hasActiveCall && hasHoldingCall;
-        b.setLength(0);
-        b.append("  - hasRingingCall ").append(hasRingingCall);
-        b.append(" hasActiveCall ").append(hasActiveCall);
-        b.append(" hasHoldingCall ").append(hasHoldingCall);
-        b.append(" allLinesTaken ").append(allLinesTaken);
-        Log.d(LOG_TAG, b.toString());
-
-        // On CDMA phones, dump out the CdmaPhoneCallState too:
-        if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
-            if (app.cdmaPhoneCallState != null) {
-                Log.d(LOG_TAG, "  - CDMA call state: "
-                      + app.cdmaPhoneCallState.getCurrentCallState());
-            } else {
-                Log.d(LOG_TAG, "  - CDMA device, but null cdmaPhoneCallState!");
-            }
-        }
-    }
-
     private static void log(String msg) {
         Log.d(LOG_TAG, msg);
     }
 
-    static void dumpCallManager() {
-        Call call;
-        CallManager cm = PhoneGlobals.getInstance().mCM;
-        StringBuilder b = new StringBuilder(128);
-
-
-
-        Log.d(LOG_TAG, "############### dumpCallManager() ##############");
-        // TODO: Don't log "cm" itself, since CallManager.toString()
-        // already spews out almost all this same information.
-        // We should fix CallManager.toString() to be more minimal, and
-        // use an explicit dumpState() method for the verbose dump.
-        // Log.d(LOG_TAG, "CallManager: " + cm
-        //         + ", state = " + cm.getState());
-        Log.d(LOG_TAG, "CallManager: state = " + cm.getState());
-        b.setLength(0);
-        call = cm.getActiveFgCall();
-        b.append(" - FG call: ").append(cm.hasActiveFgCall()? "YES ": "NO ");
-        b.append(call);
-        b.append( "  State: ").append(cm.getActiveFgCallState());
-        b.append( "  Conn: ").append(cm.getFgCallConnections());
-        Log.d(LOG_TAG, b.toString());
-        b.setLength(0);
-        call = cm.getFirstActiveBgCall();
-        b.append(" - BG call: ").append(cm.hasActiveBgCall()? "YES ": "NO ");
-        b.append(call);
-        b.append( "  State: ").append(cm.getFirstActiveBgCall().getState());
-        b.append( "  Conn: ").append(cm.getBgCallConnections());
-        Log.d(LOG_TAG, b.toString());
-        b.setLength(0);
-        call = cm.getFirstActiveRingingCall();
-        b.append(" - RINGING call: ").append(cm.hasActiveRingingCall()? "YES ": "NO ");
-        b.append(call);
-        b.append( "  State: ").append(cm.getFirstActiveRingingCall().getState());
-        Log.d(LOG_TAG, b.toString());
-
-
-
-        for (Phone phone : CallManager.getInstance().getAllPhones()) {
-            if (phone != null) {
-                Log.d(LOG_TAG, "Phone: " + phone + ", name = " + phone.getPhoneName()
-                        + ", state = " + phone.getState());
-                b.setLength(0);
-                call = phone.getForegroundCall();
-                b.append(" - FG call: ").append(call);
-                b.append( "  State: ").append(call.getState());
-                b.append( "  Conn: ").append(call.hasConnections());
-                Log.d(LOG_TAG, b.toString());
-                b.setLength(0);
-                call = phone.getBackgroundCall();
-                b.append(" - BG call: ").append(call);
-                b.append( "  State: ").append(call.getState());
-                b.append( "  Conn: ").append(call.hasConnections());
-                Log.d(LOG_TAG, b.toString());b.setLength(0);
-                call = phone.getRingingCall();
-                b.append(" - RINGING call: ").append(call);
-                b.append( "  State: ").append(call.getState());
-                b.append( "  Conn: ").append(call.hasConnections());
-                Log.d(LOG_TAG, b.toString());
-            }
-        }
-
-        Log.d(LOG_TAG, "############## END dumpCallManager() ###############");
-    }
-
-    /**
-     * @return if the context is in landscape orientation.
-     */
-    public static boolean isLandscape(Context context) {
-        return context.getResources().getConfiguration().orientation
-                == Configuration.ORIENTATION_LANDSCAPE;
-    }
-
     public static PhoneAccountHandle makePstnPhoneAccountHandle(String id) {
         return makePstnPhoneAccountHandleWithPrefix(id, "", false);
     }
@@ -1904,7 +1241,6 @@
         return null;
     }
 
-
     /**
      * Determine if a given phone account corresponds to an active SIM
      *
