diff --git a/src/com/android/phone/BluetoothManager.java b/src/com/android/phone/BluetoothManager.java
index 443c950..3f0ce6f 100644
--- a/src/com/android/phone/BluetoothManager.java
+++ b/src/com/android/phone/BluetoothManager.java
@@ -16,413 +16,43 @@
 
 package com.android.phone;
 
-import com.google.android.collect.Lists;
-import com.google.common.base.Preconditions;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothHeadset;
-import android.bluetooth.BluetoothProfile;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.util.Log;
-
-import com.android.internal.telephony.CallManager;
-import com.android.internal.telephony.Connection;
-import com.android.services.telephony.common.Call;
-
-import java.util.List;
-
-/**
- * Listens to and caches bluetooth headset state.  Used By the AudioRouter for maintaining
- * overall audio state for use in the UI layer. Also provides method for connecting the bluetooth
- * headset to the phone call.
- */
-public class BluetoothManager implements CallModeler.Listener {
-    private static final String LOG_TAG = BluetoothManager.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 final BluetoothAdapter mBluetoothAdapter;
-    private final CallManager mCallManager;
-    private final Context mContext;
-    private final CallModeler mCallModeler;
-
-    private BluetoothHeadset mBluetoothHeadset;
-    private int mBluetoothHeadsetState = BluetoothProfile.STATE_DISCONNECTED;
-    private int mBluetoothHeadsetAudioState = BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
-    private boolean mShowBluetoothIndication = false;
-    private boolean mBluetoothConnectionPending = false;
-    private long mBluetoothConnectionRequestTime;
-
-    // Broadcast receiver for various intent broadcasts (see onCreate())
-    private final BroadcastReceiver mReceiver = new BluetoothBroadcastReceiver();
-
-    private final List<BluetoothIndicatorListener> mListeners = Lists.newArrayList();
-
-    public BluetoothManager(Context context, CallManager callManager, CallModeler callModeler) {
-        mContext = context;
-        mCallManager = callManager;
-        mCallModeler = callModeler;
-        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
-
-        init(mContext);
+public class BluetoothManager {
+    public BluetoothManager() {
     }
 
     /* package */ boolean isBluetoothHeadsetAudioOn() {
-        return (mBluetoothHeadsetAudioState != BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
-    }
-
-    //
-    // Bluetooth helper methods.
-    //
-    // - BluetoothAdapter is the Bluetooth system service.  If
-    //   getDefaultAdapter() returns null
-    //   then the device is not BT capable.  Use BluetoothDevice.isEnabled()
-    //   to see if BT is enabled on the device.
-    //
-    // - BluetoothHeadset is the API for the control connection to a
-    //   Bluetooth Headset.  This lets you completely connect/disconnect a
-    //   headset (which we don't do from the Phone UI!) but also lets you
-    //   get the address of the currently active headset and see whether
-    //   it's currently connected.
-
-    /**
-     * @return true if the Bluetooth on/off switch in the UI should be
-     *         available to the user (i.e. if the device is BT-capable
-     *         and a headset is connected.)
-     */
-    /* package */ boolean isBluetoothAvailable() {
-        if (VDBG) log("isBluetoothAvailable()...");
-
-        // There's no need to ask the Bluetooth system service if BT is enabled:
-        //
-        //    BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-        //    if ((adapter == null) || !adapter.isEnabled()) {
-        //        if (DBG) log("  ==> FALSE (BT not enabled)");
-        //        return false;
-        //    }
-        //    if (DBG) log("  - BT enabled!  device name " + adapter.getName()
-        //                 + ", address " + adapter.getAddress());
-        //
-        // ...since we already have a BluetoothHeadset instance.  We can just
-        // call isConnected() on that, and assume it'll be false if BT isn't
-        // enabled at all.
-
-        // Check if there's a connected headset, using the BluetoothHeadset API.
-        boolean isConnected = false;
-        if (mBluetoothHeadset != null) {
-            List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
-
-            if (deviceList.size() > 0) {
-                BluetoothDevice device = deviceList.get(0);
-                isConnected = true;
-
-                if (VDBG) log("  - headset state = " +
-                              mBluetoothHeadset.getConnectionState(device));
-                if (VDBG) log("  - headset address: " + device);
-                if (VDBG) log("  - isConnected: " + isConnected);
-            }
-        }
-
-        if (VDBG) log("  ==> " + isConnected);
-        return isConnected;
-    }
-
-    /**
-     * @return true if a BT Headset is available, and its audio is currently connected.
-     */
-    /* package */ boolean isBluetoothAudioConnected() {
-        if (mBluetoothHeadset == null) {
-            if (VDBG) log("isBluetoothAudioConnected: ==> FALSE (null mBluetoothHeadset)");
-            return false;
-        }
-        List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
-
-        if (deviceList.isEmpty()) {
-            return false;
-        }
-        BluetoothDevice device = deviceList.get(0);
-        boolean isAudioOn = mBluetoothHeadset.isAudioConnected(device);
-        if (VDBG) log("isBluetoothAudioConnected: ==> isAudioOn = " + isAudioOn);
-        return isAudioOn;
-    }
-
-    /**
-     * Helper method used to control the onscreen "Bluetooth" indication;
-     * see InCallControlState.bluetoothIndicatorOn.
-     *
-     * @return true if a BT device is available and its audio is currently connected,
-     *              <b>or</b> if we issued a BluetoothHeadset.connectAudio()
-     *              call within the last 5 seconds (which presumably means
-     *              that the BT audio connection is currently being set
-     *              up, and will be connected soon.)
-     */
-    /* package */ boolean isBluetoothAudioConnectedOrPending() {
-        if (isBluetoothAudioConnected()) {
-            if (VDBG) log("isBluetoothAudioConnectedOrPending: ==> TRUE (really connected)");
-            return true;
-        }
-
-        // If we issued a connectAudio() call "recently enough", even
-        // if BT isn't actually connected yet, let's still pretend BT is
-        // on.  This makes the onscreen indication more responsive.
-        if (mBluetoothConnectionPending) {
-            long timeSinceRequest =
-                    SystemClock.elapsedRealtime() - mBluetoothConnectionRequestTime;
-            if (timeSinceRequest < 5000 /* 5 seconds */) {
-                if (VDBG) log("isBluetoothAudioConnectedOrPending: ==> TRUE (requested "
-                             + timeSinceRequest + " msec ago)");
-                return true;
-            } else {
-                if (VDBG) log("isBluetoothAudioConnectedOrPending: ==> FALSE (request too old: "
-                             + timeSinceRequest + " msec ago)");
-                mBluetoothConnectionPending = false;
-                return false;
-            }
-        }
-
-        if (VDBG) log("isBluetoothAudioConnectedOrPending: ==> FALSE");
         return false;
     }
 
-    /**
-     * @return true if the onscreen UI should currently be showing the
-     * special "bluetooth is active" indication in a couple of places (in
-     * which UI elements turn blue and/or show the bluetooth logo.)
-     *
-     * This depends on the BluetoothHeadset state *and* the current
-     * telephony state; see shouldShowBluetoothIndication().
-     *
-     * @see CallCard
-     * @see NotificationMgr.updateInCallNotification
-     */
-    /* package */ boolean showBluetoothIndication() {
-        return mShowBluetoothIndication;
+    /* package */ boolean isBluetoothAvailable() {
+        return false;
     }
 
-    /**
-     * Recomputes the mShowBluetoothIndication flag based on the current
-     * bluetooth state and current telephony state.
-     *
-     * This needs to be called any time the bluetooth headset state or the
-     * telephony state changes.
-     */
-    /* package */ void updateBluetoothIndication() {
-        mShowBluetoothIndication = shouldShowBluetoothIndication(mBluetoothHeadsetState,
-                                                                 mBluetoothHeadsetAudioState,
-                                                                 mCallManager);
+    /* package */ boolean isBluetoothAudioConnected() {
+        return false;
+    }
 
-        notifyListeners(mShowBluetoothIndication);
+    /* package */ boolean isBluetoothAudioConnectedOrPending() {
+        return false;
+    }
+
+    /* package */ boolean showBluetoothIndication() {
+        return false;
+    }
+
+    /* package */ void updateBluetoothIndication() {
     }
 
     public void addBluetoothIndicatorListener(BluetoothIndicatorListener listener) {
-        if (!mListeners.contains(listener)) {
-            mListeners.add(listener);
-        }
     }
 
     public void removeBluetoothIndicatorListener(BluetoothIndicatorListener listener) {
-        if (mListeners.contains(listener)) {
-            mListeners.remove(listener);
-        }
-    }
-
-    private void notifyListeners(boolean showBluetoothOn) {
-        for (int i = 0; i < mListeners.size(); i++) {
-            mListeners.get(i).onBluetoothIndicationChange(showBluetoothOn, this);
-        }
-    }
-
-    private void init(Context context) {
-        Preconditions.checkNotNull(context);
-
-        if (mBluetoothAdapter != null) {
-            mBluetoothAdapter.getProfileProxy(context, mBluetoothProfileServiceListener,
-                                    BluetoothProfile.HEADSET);
-        }
-
-        // Register for misc other intent broadcasts.
-        IntentFilter intentFilter =
-                new IntentFilter(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
-        intentFilter.addAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
-        context.registerReceiver(mReceiver, intentFilter);
-
-        mCallModeler.addListener(this);
-    }
-
-    private void tearDown() {
-        if (mBluetoothHeadset != null) {
-            mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
-            mBluetoothHeadset = null;
-        }
-    }
-
-    private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
-             new BluetoothProfile.ServiceListener() {
-         @Override
-         public void onServiceConnected(int profile, BluetoothProfile proxy) {
-             mBluetoothHeadset = (BluetoothHeadset) proxy;
-             if (VDBG) log("- Got BluetoothHeadset: " + mBluetoothHeadset);
-         }
-
-         @Override
-         public void onServiceDisconnected(int profile) {
-             mBluetoothHeadset = null;
-         }
-    };
-
-    /**
-     * UI policy helper function for the couple of places in the UI that
-     * have some way of indicating that "bluetooth is in use."
-     *
-     * @return true if the onscreen UI should indicate that "bluetooth is in use",
-     *         based on the specified bluetooth headset state, and the
-     *         current state of the phone.
-     * @see showBluetoothIndication()
-     */
-    private static boolean shouldShowBluetoothIndication(int bluetoothState,
-                                                         int bluetoothAudioState,
-                                                         CallManager cm) {
-        // We want the UI to indicate that "bluetooth is in use" in two
-        // slightly different cases:
-        //
-        // (a) The obvious case: if a bluetooth headset is currently in
-        //     use for an ongoing call.
-        //
-        // (b) The not-so-obvious case: if an incoming call is ringing,
-        //     and we expect that audio *will* be routed to a bluetooth
-        //     headset once the call is answered.
-
-        switch (cm.getState()) {
-            case OFFHOOK:
-                // This covers normal active calls, and also the case if
-                // the foreground call is DIALING or ALERTING.  In this
-                // case, bluetooth is considered "active" if a headset
-                // is connected *and* audio is being routed to it.
-                return ((bluetoothState == BluetoothHeadset.STATE_CONNECTED)
-                        && (bluetoothAudioState == BluetoothHeadset.STATE_AUDIO_CONNECTED));
-
-            case RINGING:
-                // If an incoming call is ringing, we're *not* yet routing
-                // audio to the headset (since there's no in-call audio
-                // yet!)  In this case, if a bluetooth headset is
-                // connected at all, we assume that it'll become active
-                // once the user answers the phone.
-                return (bluetoothState == BluetoothHeadset.STATE_CONNECTED);
-
-            default:  // Presumably IDLE
-                return false;
-        }
-    }
-
-    private void dumpBluetoothState() {
-        log("============== dumpBluetoothState() =============");
-        log("= isBluetoothAvailable: " + isBluetoothAvailable());
-        log("= isBluetoothAudioConnected: " + isBluetoothAudioConnected());
-        log("= isBluetoothAudioConnectedOrPending: " + isBluetoothAudioConnectedOrPending());
-        log("= PhoneApp.showBluetoothIndication: "
-            + showBluetoothIndication());
-        log("=");
-        if (mBluetoothAdapter != null) {
-            if (mBluetoothHeadset != null) {
-                List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
-
-                if (deviceList.size() > 0) {
-                    BluetoothDevice device = deviceList.get(0);
-                    log("= BluetoothHeadset.getCurrentDevice: " + device);
-                    log("= BluetoothHeadset.State: "
-                        + mBluetoothHeadset.getConnectionState(device));
-                    log("= BluetoothHeadset audio connected: " +
-                        mBluetoothHeadset.isAudioConnected(device));
-                }
-            } else {
-                log("= mBluetoothHeadset is null");
-            }
-        } else {
-            log("= mBluetoothAdapter is null; device is not BT capable");
-        }
     }
 
     /* package */ void connectBluetoothAudio() {
-        if (VDBG) log("connectBluetoothAudio()...");
-        if (mBluetoothHeadset != null) {
-            // TODO(BT) check return
-            mBluetoothHeadset.connectAudio();
-        }
-
-        // Watch out: The bluetooth connection doesn't happen instantly;
-        // the connectAudio() call returns instantly but does its real
-        // work in another thread.  The mBluetoothConnectionPending flag
-        // is just a little trickery to ensure that the onscreen UI updates
-        // instantly. (See isBluetoothAudioConnectedOrPending() above.)
-        mBluetoothConnectionPending = true;
-        mBluetoothConnectionRequestTime = SystemClock.elapsedRealtime();
     }
 
     /* package */ void disconnectBluetoothAudio() {
-        if (VDBG) log("disconnectBluetoothAudio()...");
-        if (mBluetoothHeadset != null) {
-            mBluetoothHeadset.disconnectAudio();
-        }
-        mBluetoothConnectionPending = false;
-    }
-
-    /**
-     * Receiver for misc intent broadcasts the BluetoothManager cares about.
-     */
-    private class BluetoothBroadcastReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-
-            if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
-                mBluetoothHeadsetState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
-                                                          BluetoothHeadset.STATE_DISCONNECTED);
-                if (VDBG) Log.d(LOG_TAG, "mReceiver: HEADSET_STATE_CHANGED_ACTION");
-                if (VDBG) Log.d(LOG_TAG, "==> new state: " + mBluetoothHeadsetState);
-                // Also update any visible UI if necessary
-                updateBluetoothIndication();
-            } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
-                mBluetoothHeadsetAudioState =
-                        intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
-                                           BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
-                if (VDBG) Log.d(LOG_TAG, "mReceiver: HEADSET_AUDIO_STATE_CHANGED_ACTION");
-                if (VDBG) Log.d(LOG_TAG, "==> new state: " + mBluetoothHeadsetAudioState);
-                updateBluetoothIndication();
-            }
-        }
-    }
-
-    @Override
-    public void onDisconnect(Call call) {
-        updateBluetoothIndication();
-    }
-
-    @Override
-    public void onIncoming(Call call) {
-        // An incoming call can affect bluetooth indicator, so we update it whenever there is
-        // a change to any of the calls.
-        updateBluetoothIndication();
-    }
-
-    @Override
-    public void onUpdate(List<Call> calls) {
-        updateBluetoothIndication();
-    }
-
-    @Override
-    public void onPostDialAction(Connection.PostDialState state, int callId, String chars, char c) {
-        // no-op
-    }
-
-    private void log(String msg) {
-        Log.d(LOG_TAG, msg);
     }
 
     /* package */ interface BluetoothIndicatorListener {
diff --git a/src/com/android/phone/CallController.java b/src/com/android/phone/CallController.java
index 0b9482d..c517343 100644
--- a/src/com/android/phone/CallController.java
+++ b/src/com/android/phone/CallController.java
@@ -141,7 +141,8 @@
                     // Reset the mThreeWayCallOrigStateDialing state
                     mApp.cdmaPhoneCallState.setThreeWayCallOrigState(false);
 
-                    mApp.getCallModeler().setCdmaOutgoing3WayCall(null);
+                    // TODO(sail): Remove this code.
+                    //mApp.getCallModeler().setCdmaOutgoing3WayCall(null);
                 }
                 break;
 
diff --git a/src/com/android/phone/CallGatewayManager.java b/src/com/android/phone/CallGatewayManager.java
index 81bee07..893070b 100644
--- a/src/com/android/phone/CallGatewayManager.java
+++ b/src/com/android/phone/CallGatewayManager.java
@@ -37,8 +37,7 @@
  *
  * <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.  This association is later used in CallModeler when building Call objects
- * to send to the UI which require the gateway data to show an alert to users.
+ * data into this class.
  */
 public class CallGatewayManager {
     private static final String LOG_TAG = CallGatewayManager.class.getSimpleName();
@@ -98,8 +97,7 @@
     }
 
     /**
-     * This function sets the current mapping from connection to gatewayInfo so that CallModeler
-     * can request this data when creating Call objects.
+     * 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.
      */
diff --git a/src/com/android/phone/CallModeler.java b/src/com/android/phone/CallModeler.java
deleted file mode 100644
index ae8d251..0000000
--- a/src/com/android/phone/CallModeler.java
+++ /dev/null
@@ -1,879 +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.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.telephony.DisconnectCause;
-import android.telephony.PhoneNumberUtils;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.telephony.CallManager;
-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.internal.telephony.cdma.CdmaCallWaitingNotification;
-import com.android.phone.CallGatewayManager.RawGatewayInfo;
-import com.android.services.telephony.common.Call;
-import com.android.services.telephony.common.Call.Capabilities;
-import com.android.services.telephony.common.Call.State;
-
-import com.google.android.collect.Maps;
-import com.google.android.collect.Sets;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.common.collect.Lists;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Creates a Call model from Call state and data received from the telephony
- * layer. The telephony layer maintains 3 conceptual objects: Phone, Call,
- * Connection.
- *
- * Phone represents the radio and there is an implementation per technology
- * type such as GSMPhone, SipPhone, CDMAPhone, etc. Generally, we will only ever
- * deal with one instance of this object for the lifetime of this class.
- *
- * There are 3 Call instances that exist for the lifetime of this class which
- * are created by CallTracker. The three are RingingCall, ForegroundCall, and
- * BackgroundCall.
- *
- * A Connection most closely resembles what the layperson would consider a call.
- * A Connection is created when a user dials and it is "owned" by one of the
- * three Call instances.  Which of the three Calls owns the Connection changes
- * as the Connection goes between ACTIVE, HOLD, RINGING, and other states.
- *
- * This class models a new Call class from Connection objects received from
- * the telephony layer. We use Connection references as identifiers for a call;
- * new reference = new call.
- *
- * TODO: Create a new Call class to replace the simple call Id ints
- * being used currently.
- */
-public class CallModeler extends Handler {
-
-    private static final String TAG = CallModeler.class.getSimpleName();
-    private static final boolean DBG =
-            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
-
-    private static final int CALL_ID_START_VALUE = 1;
-
-    private final CallStateMonitor mCallStateMonitor;
-    private final CallManager mCallManager;
-    private final CallGatewayManager mCallGatewayManager;
-    private final HashMap<Connection, Call> mCallMap = Maps.newHashMap();
-    private final HashMap<Connection, Call> mConfCallMap = Maps.newHashMap();
-    private final AtomicInteger mNextCallId = new AtomicInteger(CALL_ID_START_VALUE);
-    private final ArrayList<Listener> mListeners = new ArrayList<Listener>();
-    private Connection mCdmaIncomingConnection;
-    private Connection mCdmaOutgoingConnection;
-
-    public CallModeler(CallStateMonitor callStateMonitor, CallManager callManager,
-            CallGatewayManager callGatewayManager) {
-        mCallStateMonitor = callStateMonitor;
-        mCallManager = callManager;
-        mCallGatewayManager = callGatewayManager;
-
-        mCallStateMonitor.addListener(this);
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-        switch(msg.what) {
-            case CallStateMonitor.PHONE_NEW_RINGING_CONNECTION:
-                // We let the CallNotifier handle the new ringing connection first. When the custom
-                // ringtone and send_to_voicemail settings are retrieved, CallNotifier will directly
-                // call CallModeler's onNewRingingConnection.
-                break;
-            case CallStateMonitor.PHONE_DISCONNECT:
-                onDisconnect((Connection) ((AsyncResult) msg.obj).result);
-                break;
-            case CallStateMonitor.PHONE_UNKNOWN_CONNECTION_APPEARED:
-                // fall through
-            case CallStateMonitor.PHONE_STATE_CHANGED:
-                onPhoneStateChanged((AsyncResult) msg.obj);
-                break;
-            case CallStateMonitor.PHONE_ON_DIAL_CHARS:
-                onPostDialChars((AsyncResult) msg.obj, (char) msg.arg1);
-                break;
-            default:
-                break;
-        }
-    }
-
-    public void addListener(Listener listener) {
-        Preconditions.checkNotNull(listener);
-        Preconditions.checkNotNull(mListeners);
-        if (!mListeners.contains(listener)) {
-            mListeners.add(listener);
-        }
-    }
-
-    public List<Call> getFullList() {
-        final List<Call> calls =
-                Lists.newArrayListWithCapacity(mCallMap.size() + mConfCallMap.size());
-        calls.addAll(mCallMap.values());
-        calls.addAll(mConfCallMap.values());
-        return calls;
-    }
-
-    public CallResult getCallWithId(int callId) {
-        // max 8 connections, so this should be fast even through we are traversing the entire map.
-        for (Entry<Connection, Call> entry : mCallMap.entrySet()) {
-            if (entry.getValue().getCallId() == callId) {
-                return new CallResult(entry.getValue(), entry.getKey());
-            }
-        }
-
-        for (Entry<Connection, Call> entry : mConfCallMap.entrySet()) {
-            if (entry.getValue().getCallId() == callId) {
-                return new CallResult(entry.getValue(), entry.getKey());
-            }
-        }
-        return null;
-    }
-
-    public boolean hasLiveCall() {
-        return hasLiveCallInternal(mCallMap) ||
-            hasLiveCallInternal(mConfCallMap);
-    }
-
-    public void onCdmaCallWaiting(CdmaCallWaitingNotification callWaitingInfo) {
-        // We dont get the traditional onIncomingCall notification for cdma call waiting,
-        // but the Connection does actually exist.  We need to find it in the set of ringing calls
-        // and pass it through our normal incoming logic.
-        final com.android.internal.telephony.Call teleCall =
-            mCallManager.getFirstActiveRingingCall();
-
-        if (teleCall.getState() == com.android.internal.telephony.Call.State.WAITING) {
-            Connection connection = teleCall.getLatestConnection();
-
-            if (connection != null) {
-                String number = connection.getAddress();
-                if (number != null && number.equals(callWaitingInfo.number)) {
-                    Call call = onNewRingingConnection(connection);
-                    mCdmaIncomingConnection = connection;
-                    return;
-                }
-            }
-        }
-
-        Log.e(TAG, "CDMA Call waiting notification without a matching connection.");
-    }
-
-    public void onCdmaCallWaitingReject() {
-        // Cdma call was rejected...
-        if (mCdmaIncomingConnection != null) {
-            onDisconnect(mCdmaIncomingConnection);
-            mCdmaIncomingConnection = null;
-        } else {
-            Log.e(TAG, "CDMA Call waiting rejection without an incoming call.");
-        }
-    }
-
-    /**
-     * CDMA Calls have no sense of "dialing" state. For outgoing calls 3way calls we want to
-     * mimick this state so that the the UI can notify the user that there is a "dialing"
-     * call.
-     */
-    public void setCdmaOutgoing3WayCall(Connection connection) {
-        boolean wasSet = mCdmaOutgoingConnection != null;
-
-        mCdmaOutgoingConnection = connection;
-
-        // If we reset the connection, that mean we can now tell the user that the call is actually
-        // part of the conference call and move it out of the dialing state. To do this, issue a
-        // new update completely.
-        if (wasSet && mCdmaOutgoingConnection == null) {
-            onPhoneStateChanged(null);
-        }
-    }
-
-    private boolean hasLiveCallInternal(HashMap<Connection, Call> map) {
-        for (Call call : map.values()) {
-            final int state = call.getState();
-            if (state == Call.State.ACTIVE ||
-                    state == Call.State.CALL_WAITING ||
-                    state == Call.State.CONFERENCED ||
-                    state == Call.State.DIALING ||
-                    state == Call.State.REDIALING ||
-                    state == Call.State.INCOMING ||
-                    state == Call.State.ONHOLD ||
-                    state == Call.State.DISCONNECTING) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public boolean hasOutstandingActiveOrDialingCall() {
-        return hasOutstandingActiveOrDialingCallInternal(mCallMap) ||
-                hasOutstandingActiveOrDialingCallInternal(mConfCallMap);
-    }
-
-    private static boolean hasOutstandingActiveOrDialingCallInternal(
-            HashMap<Connection, Call> map) {
-        for (Call call : map.values()) {
-            final int state = call.getState();
-            if (state == Call.State.ACTIVE || Call.State.isDialing(state)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-
-    /**
-     * Handles the POST_ON_DIAL_CHARS message from the Phone (see our call to
-     * mPhone.setOnPostDialCharacter() above.)
-     *
-     * TODO: NEED TO TEST THIS SEQUENCE now that we no longer handle "dialable" key events here in
-     * the InCallScreen: we do directly to the Dialer UI instead.  Similarly, we may now need to go
-     * directly to the Dialer to handle POST_ON_DIAL_CHARS too.
-     */
-    private void onPostDialChars(AsyncResult r, char ch) {
-        final Connection c = (Connection) r.result;
-
-        if (c != null) {
-            final Connection.PostDialState state = (Connection.PostDialState) r.userObj;
-
-            switch (state) {
-                case WAIT:
-                    final Call call = getCallFromMap(mCallMap, c, false);
-                    if (call == null) {
-                        Log.i(TAG, "Call no longer exists. Skipping onPostDialWait().");
-                    } else {
-                        for (Listener mListener : mListeners) {
-                            mListener.onPostDialAction(state, call.getCallId(),
-                                    c.getRemainingPostDialString(), ch);
-                        }
-                    }
-                    break;
-                default:
-                    // This is primarily to cause the DTMFTonePlayer to play local tones.
-                    // Other listeners simply perform no-ops.
-                    for (Listener mListener : mListeners) {
-                        mListener.onPostDialAction(state, 0, "", ch);
-                    }
-                    break;
-            }
-        }
-    }
-
-    /* package */ Call onNewRingingConnection(Connection conn) {
-        Log.i(TAG, "onNewRingingConnection");
-        final Call call = getCallFromMap(mCallMap, conn, true);
-
-        if (call != null) {
-            updateCallFromConnection(call, conn, false);
-
-            for (int i = 0; i < mListeners.size(); ++i) {
-                mListeners.get(i).onIncoming(call);
-            }
-        }
-
-        PhoneGlobals.getInstance().updateWakeState();
-        return call;
-    }
-
-    private void onDisconnect(Connection conn) {
-        Log.i(TAG, "onDisconnect");
-        final Call call = getCallFromMap(mCallMap, conn, false);
-
-        if (call != null) {
-            final boolean wasConferenced = call.getState() == State.CONFERENCED;
-
-            updateCallFromConnection(call, conn, false);
-
-            for (int i = 0; i < mListeners.size(); ++i) {
-                mListeners.get(i).onDisconnect(call);
-            }
-
-            // If it was a conferenced call, we need to run the entire update
-            // to make the proper changes to parent conference calls.
-            if (wasConferenced) {
-                onPhoneStateChanged(null);
-            }
-
-            mCallMap.remove(conn);
-        }
-
-        mCallManager.clearDisconnected();
-        PhoneGlobals.getInstance().updateWakeState();
-    }
-
-    /**
-     * Called when the phone state changes.
-     */
-    private void onPhoneStateChanged(AsyncResult r) {
-        Log.i(TAG, "onPhoneStateChanged: ");
-        final List<Call> updatedCalls = Lists.newArrayList();
-        doUpdate(false, updatedCalls);
-
-        if (updatedCalls.size() > 0) {
-            for (int i = 0; i < mListeners.size(); ++i) {
-                mListeners.get(i).onUpdate(updatedCalls);
-            }
-        }
-
-        PhoneGlobals.getInstance().updateWakeState();
-    }
-
-    /**
-     * Go through the Calls from CallManager and return the list of calls that were updated.
-     * Method also finds any orphaned Calls (Connection objects no longer returned by telephony as
-     * either ringing, foreground, or background).  For each orphaned call, it sets the call state
-     * to IDLE and adds it to the list of calls to update.
-     *
-     * @param fullUpdate Add all calls to out parameter including those that have no updates.
-     * @param out List to populate with Calls that have been updated.
-     */
-    private void doUpdate(boolean fullUpdate, List<Call> out) {
-        final List<com.android.internal.telephony.Call> telephonyCalls = Lists.newArrayList();
-        telephonyCalls.addAll(mCallManager.getRingingCalls());
-        telephonyCalls.addAll(mCallManager.getForegroundCalls());
-        telephonyCalls.addAll(mCallManager.getBackgroundCalls());
-
-        // orphanedConnections starts out including all connections we know about.
-        // As we iterate through the connections we get from the telephony layer we
-        // prune this Set down to only the connections we have but telephony no longer
-        // recognizes.
-        final Set<Connection> orphanedConnections = Sets.newHashSet();
-        orphanedConnections.addAll(mCallMap.keySet());
-        orphanedConnections.addAll(mConfCallMap.keySet());
-
-        // Cycle through all the Connections on all the Calls. Update our Call objects
-        // to reflect any new state and send the updated Call objects to the handler service.
-        for (com.android.internal.telephony.Call telephonyCall : telephonyCalls) {
-
-            for (Connection connection : telephonyCall.getConnections()) {
-                if (DBG) Log.d(TAG, "connection: " + connection + connection.getState());
-
-                if (orphanedConnections.contains(connection)) {
-                    orphanedConnections.remove(connection);
-                }
-
-                // We only send updates for live calls which are not incoming (ringing).
-                // Disconnected and incoming calls are handled by onDisconnect and
-                // onNewRingingConnection.
-                final boolean shouldUpdate =
-                        connection.getState() !=
-                                com.android.internal.telephony.Call.State.DISCONNECTED &&
-                        connection.getState() !=
-                                com.android.internal.telephony.Call.State.IDLE &&
-                        !connection.getState().isRinging();
-
-                final boolean isDisconnecting = connection.getState() ==
-                                com.android.internal.telephony.Call.State.DISCONNECTING;
-
-                // For disconnecting calls, we still need to send the update to the UI but we do
-                // not create a new call if the call did not exist.
-                final boolean shouldCreate = shouldUpdate && !isDisconnecting;
-
-                // New connections return a Call with INVALID state, which does not translate to
-                // a state in the internal.telephony.Call object.  This ensures that staleness
-                // check below fails and we always add the item to the update list if it is new.
-                final Call call = getCallFromMap(mCallMap, connection, shouldCreate /* create */);
-
-                if (call == null || !shouldUpdate) {
-                    if (DBG) Log.d(TAG, "update skipped");
-                    continue;
-                }
-
-                boolean changed = updateCallFromConnection(call, connection, false);
-
-                if (fullUpdate || changed) {
-                    out.add(call);
-                }
-            }
-
-            // We do a second loop to address conference call scenarios.  We do this as a separate
-            // loop to ensure all child calls are up to date before we start updating the parent
-            // conference calls.
-            for (Connection connection : telephonyCall.getConnections()) {
-                updateForConferenceCalls(connection, out);
-            }
-        }
-
-        // Iterate through orphaned connections, set them to idle, and remove
-        // them from our internal structures.
-        for (Connection orphanedConnection : orphanedConnections) {
-            if (mCallMap.containsKey(orphanedConnection)) {
-                final Call call = mCallMap.get(orphanedConnection);
-                call.setState(Call.State.IDLE);
-                out.add(call);
-
-                mCallMap.remove(orphanedConnection);
-            }
-
-            if (mConfCallMap.containsKey(orphanedConnection)) {
-                final Call call = mCallMap.get(orphanedConnection);
-                call.setState(Call.State.IDLE);
-                out.add(call);
-
-                mConfCallMap.remove(orphanedConnection);
-            }
-        }
-    }
-
-    /**
-     * Checks to see if the connection is the first connection in a conference call.
-     * If it is a conference call, we will create a new Conference Call object or
-     * update the existing conference call object for that connection.
-     * If it is not a conference call but a previous associated conference call still exists,
-     * we mark it as idle and remove it from the map.
-     * In both cases above, we add the Calls to be updated to the UI.
-     * @param connection The connection object to check.
-     * @param updatedCalls List of 'updated' calls that will be sent to the UI.
-     */
-    private boolean updateForConferenceCalls(Connection connection, List<Call> updatedCalls) {
-        // We consider this connection a conference connection if the call it
-        // belongs to is a multiparty call AND it is the first live connection.
-        final boolean isConferenceCallConnection = isPartOfLiveConferenceCall(connection) &&
-                getEarliestLiveConnection(connection.getCall()) == connection;
-
-        boolean changed = false;
-
-        // If this connection is the main connection for the conference call, then create or update
-        // a Call object for that conference call.
-        if (isConferenceCallConnection) {
-            final Call confCall = getCallFromMap(mConfCallMap, connection, true);
-            changed = updateCallFromConnection(confCall, connection, true);
-
-            if (changed) {
-                updatedCalls.add(confCall);
-            }
-
-            if (DBG) Log.d(TAG, "Updating a conference call: " + confCall);
-
-        // It is possible that through a conference call split, there may be lingering conference
-        // calls where this connection was the main connection.  We clean those up here.
-        } else {
-            final Call oldConfCall = getCallFromMap(mConfCallMap, connection, false);
-
-            // We found a conference call for this connection, which is no longer a conference call.
-            // Kill it!
-            if (oldConfCall != null) {
-                if (DBG) Log.d(TAG, "Cleaning up an old conference call: " + oldConfCall);
-                mConfCallMap.remove(connection);
-                oldConfCall.setState(State.IDLE);
-                changed = true;
-
-                // add to the list of calls to update
-                updatedCalls.add(oldConfCall);
-            }
-        }
-
-        return changed;
-    }
-
-    private Connection getEarliestLiveConnection(com.android.internal.telephony.Call call) {
-        final List<Connection> connections = call.getConnections();
-        final int size = connections.size();
-        Connection earliestConn = null;
-        long earliestTime = Long.MAX_VALUE;
-        for (int i = 0; i < size; i++) {
-            final Connection connection = connections.get(i);
-            if (!connection.isAlive()) continue;
-            final long time = connection.getCreateTime();
-            if (time < earliestTime) {
-                earliestTime = time;
-                earliestConn = connection;
-            }
-        }
-        return earliestConn;
-    }
-
-    /**
-     * Sets the new call state onto the call and performs some additional logic
-     * associated with setting the state.
-     */
-    private void setNewState(Call call, int newState, Connection connection) {
-        Preconditions.checkState(call.getState() != newState);
-
-        // When starting an outgoing call, we need to grab gateway information
-        // for the call, if available, and set it.
-        final RawGatewayInfo info = mCallGatewayManager.getGatewayInfo(connection);
-
-        if (Call.State.isDialing(newState)) {
-            if (!info.isEmpty()) {
-                call.setGatewayNumber(info.getFormattedGatewayNumber());
-                call.setGatewayPackage(info.packageName);
-            }
-        } else if (!Call.State.isConnected(newState)) {
-            mCallGatewayManager.clearGatewayData(connection);
-        }
-
-        call.setState(newState);
-    }
-
-    /**
-     * Updates the Call properties to match the state of the connection object
-     * that it represents.
-     * @param call The call object to update.
-     * @param connection The connection object from which to update call.
-     * @param isForConference There are slight differences in how we populate data for conference
-     *     calls. This boolean tells us which method to use.
-     */
-    private boolean updateCallFromConnection(Call call, Connection connection,
-            boolean isForConference) {
-        boolean changed = false;
-
-        final int newState = translateStateFromTelephony(connection, isForConference);
-
-        if (call.getState() != newState) {
-            setNewState(call, newState, connection);
-            changed = true;
-        }
-
-        final boolean isWifiCall = connection.getCall().getPhone().getPhoneType() ==
-                PhoneConstants.PHONE_TYPE_THIRD_PARTY;
-        if (call.isWifiCall() != isWifiCall) {
-            call.setIsWifiCall(isWifiCall);
-            changed = true;
-        }
-
-        final int newDisconnectCause = connection.getDisconnectCause();
-        if (call.getDisconnectCause() != newDisconnectCause) {
-            call.setDisconnectCause(newDisconnectCause);
-            changed = true;
-        }
-
-        final long oldConnectTime = call.getConnectTime();
-        if (oldConnectTime != connection.getConnectTime()) {
-            call.setConnectTime(connection.getConnectTime());
-            changed = true;
-        }
-
-        if (!isForConference) {
-            // Number
-            final String oldNumber = call.getNumber();
-            String newNumber = connection.getAddress();
-            RawGatewayInfo info = mCallGatewayManager.getGatewayInfo(connection);
-            if (!info.isEmpty()) {
-                newNumber = info.trueNumber;
-            }
-            if (TextUtils.isEmpty(oldNumber) || !oldNumber.equals(newNumber)) {
-                call.setNumber(newNumber);
-                changed = true;
-            }
-
-            // Number presentation
-            final int newNumberPresentation = connection.getNumberPresentation();
-            if (call.getNumberPresentation() != newNumberPresentation) {
-                call.setNumberPresentation(newNumberPresentation);
-                changed = true;
-            }
-
-            // Name
-            final String oldCnapName = call.getCnapName();
-            if (TextUtils.isEmpty(oldCnapName) || !oldCnapName.equals(connection.getCnapName())) {
-                call.setCnapName(connection.getCnapName());
-                changed = true;
-            }
-
-            // Name Presentation
-            final int newCnapNamePresentation = connection.getCnapNamePresentation();
-            if (call.getCnapNamePresentation() != newCnapNamePresentation) {
-                call.setCnapNamePresentation(newCnapNamePresentation);
-                changed = true;
-            }
-        } else {
-
-            // update the list of children by:
-            // 1) Saving the old set
-            // 2) Removing all children
-            // 3) Adding the correct children into the Call
-            // 4) Comparing the new children set with the old children set
-            ImmutableSortedSet<Integer> oldSet = call.getChildCallIds();
-            call.removeAllChildren();
-
-            if (connection.getCall() != null) {
-                for (Connection childConn : connection.getCall().getConnections()) {
-                    final Call childCall = getCallFromMap(mCallMap, childConn, false);
-                    if (childCall != null && childConn.isAlive()) {
-                        call.addChildId(childCall.getCallId());
-                    }
-                }
-            }
-            changed |= !oldSet.equals(call.getChildCallIds());
-        }
-
-        /**
-         * !!! Uses values from connection and call collected above so this part must be last !!!
-         */
-        final int newCapabilities = getCapabilitiesFor(connection, call, isForConference);
-        if (call.getCapabilities() != newCapabilities) {
-            call.setCapabilities(newCapabilities);
-            changed = true;
-        }
-
-        return changed;
-    }
-
-    /**
-     * Returns a mask of capabilities for the connection such as merge, hold, etc.
-     */
-    private int getCapabilitiesFor(Connection connection, Call call, boolean isForConference) {
-        final boolean callIsActive = (call.getState() == Call.State.ACTIVE);
-        final Phone phone = connection.getCall().getPhone();
-
-        boolean canAddCall = false;
-        boolean canMergeCall = false;
-        boolean canSwapCall = false;
-        boolean canRespondViaText = false;
-        boolean canMute = false;
-
-        final boolean supportHold = PhoneUtils.okToSupportHold(mCallManager);
-        final boolean canHold = (supportHold ? PhoneUtils.okToHoldCall(mCallManager) : false);
-        final boolean genericConf = isForConference &&
-                (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA);
-
-        // only applies to active calls
-        if (callIsActive) {
-            canMergeCall = PhoneUtils.okToMergeCalls(mCallManager);
-            canSwapCall = PhoneUtils.okToSwapCalls(mCallManager);
-        }
-
-        canAddCall = PhoneUtils.okToAddCall(mCallManager);
-
-        // "Mute": only enabled when the foreground call is ACTIVE.
-        // (It's meaningless while on hold, or while DIALING/ALERTING.)
-        // It's also explicitly disabled during emergency calls or if
-        // emergency callback mode (ECM) is active.
-        boolean isEmergencyCall = false;
-        if (connection != null) {
-            isEmergencyCall = PhoneNumberUtils.isLocalEmergencyNumber(phone.getContext(),
-                    connection.getAddress());
-        }
-        boolean isECM = PhoneUtils.isPhoneInEcm(phone);
-        if (isEmergencyCall || isECM) {  // disable "Mute" item
-            canMute = false;
-        } else {
-            canMute = callIsActive;
-        }
-
-        canRespondViaText = false /* RejectWithTextMessageManager.allowRespondViaSmsForCall(call,
-                connection) */;
-
-        // special rules section!
-        // CDMA always has Add
-        if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
-            canAddCall = true;
-        }
-
-        int retval = 0x0;
-        if (canHold) {
-            retval |= Capabilities.HOLD;
-        }
-        if (supportHold) {
-            retval |= Capabilities.SUPPORT_HOLD;
-        }
-        if (canAddCall) {
-            retval |= Capabilities.ADD_CALL;
-        }
-        if (canMergeCall) {
-            retval |= Capabilities.MERGE_CALLS;
-        }
-        if (canSwapCall) {
-            retval |= Capabilities.SWAP_CALLS;
-        }
-        if (canRespondViaText) {
-            retval |= Capabilities.RESPOND_VIA_TEXT;
-        }
-        if (canMute) {
-            retval |= Capabilities.MUTE;
-        }
-        if (genericConf) {
-            retval |= Capabilities.GENERIC_CONFERENCE;
-        }
-
-        return retval;
-    }
-
-    /**
-     * Returns true if the Connection is part of a multiparty call.
-     * We do this by checking the isMultiparty() method of the telephony.Call object and also
-     * checking to see if more than one of it's children is alive.
-     */
-    private boolean isPartOfLiveConferenceCall(Connection connection) {
-        if (connection.getCall() != null && connection.getCall().isMultiparty()) {
-            int count = 0;
-            for (Connection currConn : connection.getCall().getConnections()) {
-
-                // Only count connections which are alive and never cound the special
-                // "dialing" 3way call for CDMA calls.
-                if (currConn.isAlive() && currConn != mCdmaOutgoingConnection) {
-                    count++;
-                    if (count >= 2) {
-                        return true;
-                    }
-                }
-            }
-        }
-        return false;
-    }
-
-    private int translateStateFromTelephony(Connection connection, boolean isForConference) {
-
-        com.android.internal.telephony.Call.State connState = connection.getState();
-
-        // For the "fake" outgoing CDMA call, we need to always treat it as an outgoing call.
-        if (mCdmaOutgoingConnection == connection) {
-            connState = com.android.internal.telephony.Call.State.DIALING;
-        }
-
-        int retval = State.IDLE;
-        switch (connState) {
-            case ACTIVE:
-                retval = State.ACTIVE;
-                break;
-            case INCOMING:
-                retval = State.INCOMING;
-                break;
-            case DIALING:
-            case ALERTING:
-                if (PhoneGlobals.getInstance().notifier.getIsCdmaRedialCall()) {
-                    retval = State.REDIALING;
-                } else {
-                    retval = State.DIALING;
-                }
-                break;
-            case WAITING:
-                retval = State.CALL_WAITING;
-                break;
-            case HOLDING:
-                retval = State.ONHOLD;
-                break;
-            case DISCONNECTING:
-                retval = State.DISCONNECTING;
-                break;
-            case DISCONNECTED:
-                retval = State.DISCONNECTED;
-            default:
-        }
-
-        // If we are dealing with a potential child call (not the parent conference call),
-        // the check to see if we have to set the state to CONFERENCED.
-        if (!isForConference) {
-            // if the connection is part of a multiparty call, and it is live,
-            // annotate it with CONFERENCED state instead.
-            if (isPartOfLiveConferenceCall(connection) && connection.isAlive()) {
-                return State.CONFERENCED;
-            }
-        }
-
-        return retval;
-    }
-
-    /**
-     * Gets an existing callId for a connection, or creates one if none exists.
-     * This function does NOT set any of the Connection data onto the Call class.
-     * A separate call to updateCallFromConnection must be made for that purpose.
-     */
-    private Call getCallFromMap(HashMap<Connection, Call> map, Connection conn,
-            boolean createIfMissing) {
-        Call call = null;
-
-        // Find the call id or create if missing and requested.
-        if (conn != null) {
-            if (map.containsKey(conn)) {
-                call = map.get(conn);
-            } else if (createIfMissing) {
-                call = createNewCall();
-                map.put(conn, call);
-            }
-        }
-        return call;
-    }
-
-    /**
-     * Creates a brand new connection for the call.
-     */
-    private Call createNewCall() {
-        int callId;
-        int newNextCallId;
-        do {
-            callId = mNextCallId.get();
-
-            // protect against overflow
-            newNextCallId = (callId == Integer.MAX_VALUE ?
-                    CALL_ID_START_VALUE : callId + 1);
-
-            // Keep looping if the change was not atomic OR the value is already taken.
-            // The call to containsValue() is linear, however, most devices support a
-            // maximum of 7 connections so it's not expensive.
-        } while (!mNextCallId.compareAndSet(callId, newNextCallId));
-
-        return new Call(callId);
-    }
-
-    /**
-     * Listener interface for changes to Calls.
-     */
-    public interface Listener {
-        void onDisconnect(Call call);
-        void onIncoming(Call call);
-        void onUpdate(List<Call> calls);
-        void onPostDialAction(Connection.PostDialState state, int callId, String remainingChars,
-                char c);
-    }
-
-    /**
-     * Result class for accessing a call by connection.
-     */
-    public static class CallResult {
-        public Call mCall;
-        public Call mActionableCall;
-        public Connection mConnection;
-
-        private CallResult(Call call, Connection connection) {
-            this(call, call, connection);
-        }
-
-        private CallResult(Call call, Call actionableCall, Connection connection) {
-            mCall = call;
-            mActionableCall = actionableCall;
-            mConnection = connection;
-        }
-
-        public Call getCall() {
-            return mCall;
-        }
-
-        // The call that should be used for call actions like hanging up.
-        public Call getActionableCall() {
-            return mActionableCall;
-        }
-
-        public Connection getConnection() {
-            return mConnection;
-        }
-    }
-}
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index babae74..bc19568 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -140,7 +140,6 @@
     private Ringer mRinger;
     private BluetoothHeadset mBluetoothHeadset;
     private CallLogger mCallLogger;
-    private CallModeler mCallModeler;
     private boolean mSilentRingerRequested;
 
     // ToneGenerator instance for playing SignalInfo tones
@@ -175,11 +174,11 @@
      */
     /* package */ static CallNotifier init(PhoneGlobals app, Phone phone, Ringer ringer,
             CallLogger callLogger, CallStateMonitor callStateMonitor,
-            BluetoothManager bluetoothManager, CallModeler callModeler) {
+            BluetoothManager bluetoothManager) {
         synchronized (CallNotifier.class) {
             if (sInstance == null) {
                 sInstance = new CallNotifier(app, phone, ringer, callLogger, callStateMonitor,
-                        bluetoothManager, callModeler);
+                        bluetoothManager);
             } else {
                 Log.wtf(LOG_TAG, "init() called multiple times!  sInstance = " + sInstance);
             }
@@ -189,13 +188,11 @@
 
     /** Private constructor; @see init() */
     private CallNotifier(PhoneGlobals app, Phone phone, Ringer ringer, CallLogger callLogger,
-            CallStateMonitor callStateMonitor, BluetoothManager bluetoothManager,
-            CallModeler callModeler) {
+            CallStateMonitor callStateMonitor, BluetoothManager bluetoothManager) {
         mApplication = app;
         mCM = app.mCM;
         mCallLogger = callLogger;
         mBluetoothManager = bluetoothManager;
-        mCallModeler = callModeler;
 
         mAudioManager = (AudioManager) mApplication.getSystemService(Context.AUDIO_SERVICE);
 
@@ -631,7 +628,7 @@
         }
 
         // If the ringing call still does not have any connection anymore, do not send the
-        // notification to the CallModeler.
+        // notification.
         final Call ringingCall = mCM.getFirstActiveRingingCall();
 
         if (ringingCall != null && ringingCall.getLatestConnection() == c) {
@@ -650,7 +647,6 @@
     }
 
     /**
-     * Notifies the Call Modeler that there is a new ringing connection.
      * If it is not a waiting call (there is no other active call in foreground), we will ring the
      * ringtone. Otherwise we will play the call waiting tone instead.
      * @param c The new ringing connection.
@@ -665,7 +661,6 @@
                 mCallWaitingTonePlayer.start();
             }
         }
-        mCallModeler.onNewRingingConnection(c);
     }
 
     /**
@@ -706,11 +701,8 @@
         // There's no need to force a UI update since we update the
         // in-call notification ourselves (below), and the InCallScreen
         // listens for phone state changes itself.
-        // TODO: Have BluetoothManager listen to CallModeler instead of relying on
-        // CallNotifier
         mBluetoothManager.updateBluetoothIndication();
 
-
         // Update the phone state and other sensor/lock.
         mApplication.updatePhoneState(state);
 
@@ -1588,7 +1580,8 @@
             new SignalInfoTonePlayer(toneID).start();
         }
 
-        mCallModeler.onCdmaCallWaiting(infoCW);
+        // TODO(sail): Remove this.
+        //mCallModeler.onCdmaCallWaiting(infoCW);
     }
 
     /**
@@ -1641,7 +1634,8 @@
 
         // Call modeler needs to know about this event regardless of the
         // state conditionals in the previous code.
-        mCallModeler.onCdmaCallWaitingReject();
+        // TODO(sail): Remove this.
+        //mCallModeler.onCdmaCallWaitingReject();
     }
 
     /**
diff --git a/src/com/android/phone/CallStateMonitor.java b/src/com/android/phone/CallStateMonitor.java
index b93d7e1..c978e26 100644
--- a/src/com/android/phone/CallStateMonitor.java
+++ b/src/com/android/phone/CallStateMonitor.java
@@ -98,9 +98,8 @@
                 Log.d(LOG_TAG, "Adding Handler: " + handler);
             }
 
-            // Commented out so that the two listeners do not get phone events:
-            // 1) CallModeler - drives in-call UI, DTMF sessions, Bluetooth.
-            // 2) CallNotifier - Incoming-call sequence (ringer, etc.)
+            // Commented out so that the listener does not get phone events:
+            // 1) CallNotifier - Incoming-call sequence (ringer, etc.)
             //
             // NOTE: This can be deleted, but is left here for documentation purposes until this
             // entire file can be deleted (once we are sure we've addressed each of the events we
diff --git a/src/com/android/phone/DTMFTonePlayer.java b/src/com/android/phone/DTMFTonePlayer.java
deleted file mode 100644
index 2b04415..0000000
--- a/src/com/android/phone/DTMFTonePlayer.java
+++ /dev/null
@@ -1,408 +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 com.google.common.collect.ImmutableMap;
-
-import android.content.Context;
-import android.media.AudioManager;
-import android.media.ToneGenerator;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.Settings;
-import android.util.Log;
-
-import com.android.internal.telephony.CallManager;
-import com.android.internal.telephony.Connection.PostDialState;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.services.telephony.common.Call;
-
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Queue;
-
-/**
- * Playing DTMF tones through the CallManager.
- */
-public class DTMFTonePlayer implements CallModeler.Listener {
-    private static final String LOG_TAG = DTMFTonePlayer.class.getSimpleName();
-    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
-
-    private static final int DTMF_SEND_CNF = 100;
-    private static final int DTMF_STOP = 101;
-
-    /** Hash Map to map a character to a tone*/
-    private static final Map<Character, Integer> mToneMap =
-            ImmutableMap.<Character, Integer>builder()
-                    .put('1', ToneGenerator.TONE_DTMF_1)
-                    .put('2', ToneGenerator.TONE_DTMF_2)
-                    .put('3', ToneGenerator.TONE_DTMF_3)
-                    .put('4', ToneGenerator.TONE_DTMF_4)
-                    .put('5', ToneGenerator.TONE_DTMF_5)
-                    .put('6', ToneGenerator.TONE_DTMF_6)
-                    .put('7', ToneGenerator.TONE_DTMF_7)
-                    .put('8', ToneGenerator.TONE_DTMF_8)
-                    .put('9', ToneGenerator.TONE_DTMF_9)
-                    .put('0', ToneGenerator.TONE_DTMF_0)
-                    .put('#', ToneGenerator.TONE_DTMF_P)
-                    .put('*', ToneGenerator.TONE_DTMF_S)
-                    .build();
-
-    private final CallManager mCallManager;
-    private final CallModeler mCallModeler;
-    private final Object mToneGeneratorLock = new Object();
-    private ToneGenerator mToneGenerator;
-    private boolean mLocalToneEnabled;
-
-    // indicates that we are using automatically shortened DTMF tones
-    boolean mShortTone;
-
-    // indicate if the confirmation from TelephonyFW is pending.
-    private boolean mDTMFBurstCnfPending = false;
-
-    // Queue to queue the short dtmf characters.
-    private Queue<Character> mDTMFQueue = new LinkedList<Character>();
-
-    //  Short Dtmf tone duration
-    private static final int DTMF_DURATION_MS = 120;
-
-    /**
-     * Our own handler to take care of the messages from the phone state changes
-     */
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case DTMF_SEND_CNF:
-                    logD("dtmf confirmation received from FW.");
-                    // handle burst dtmf confirmation
-                    handleBurstDtmfConfirmation();
-                    break;
-                case DTMF_STOP:
-                    logD("dtmf stop received");
-                    stopDtmfTone();
-                    break;
-            }
-        }
-    };
-
-    public DTMFTonePlayer(CallManager callManager, CallModeler callModeler) {
-        mCallManager = callManager;
-        mCallModeler = callModeler;
-        mCallModeler.addListener(this);
-    }
-
-    @Override
-    public void onDisconnect(Call call) {
-        logD("Call disconnected");
-        checkCallState();
-    }
-
-    @Override
-    public void onIncoming(Call call) {
-    }
-
-    @Override
-    public void onUpdate(List<Call> calls) {
-        logD("Call updated");
-        checkCallState();
-    }
-
-    @Override
-    public void onPostDialAction(PostDialState state, int callId, String remainingChars,
-            char currentChar) {
-        switch (state) {
-            case STARTED:
-                stopLocalToneIfNeeded();
-                if (!mToneMap.containsKey(currentChar)) {
-                    return;
-                }
-                startLocalToneIfNeeded(currentChar);
-                break;
-            case PAUSE:
-            case WAIT:
-            case WILD:
-            case COMPLETE:
-                stopLocalToneIfNeeded();
-                break;
-            default:
-                break;
-        }
-    }
-
-    /**
-     * Allocates some resources we keep around during a "dialer session".
-     *
-     * (Currently, a "dialer session" just means any situation where we
-     * might need to play local DTMF tones, which means that we need to
-     * keep a ToneGenerator instance around.  A ToneGenerator instance
-     * keeps an AudioTrack resource busy in AudioFlinger, so we don't want
-     * to keep it around forever.)
-     *
-     * Call {@link stopDialerSession} to release the dialer session
-     * resources.
-     */
-    public void startDialerSession() {
-        logD("startDialerSession()... this = " + this);
-
-        // see if we need to play local tones.
-        if (PhoneGlobals.getInstance().getResources().getBoolean(R.bool.allow_local_dtmf_tones)) {
-            mLocalToneEnabled = Settings.System.getInt(
-                    PhoneGlobals.getInstance().getContentResolver(),
-                    Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;
-        } else {
-            mLocalToneEnabled = false;
-        }
-        logD("- startDialerSession: mLocalToneEnabled = " + mLocalToneEnabled);
-
-        // create the tone generator
-        // if the mToneGenerator creation fails, just continue without it.  It is
-        // a local audio signal, and is not as important as the dtmf tone itself.
-        if (mLocalToneEnabled) {
-            synchronized (mToneGeneratorLock) {
-                if (mToneGenerator == null) {
-                    try {
-                        mToneGenerator = new ToneGenerator(AudioManager.STREAM_DTMF, 80);
-                    } catch (RuntimeException e) {
-                        Log.e(LOG_TAG, "Exception caught while creating local tone generator", e);
-                        mToneGenerator = null;
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Releases resources we keep around during a "dialer session"
-     * (see {@link startDialerSession}).
-     *
-     * It's safe to call this even without a corresponding
-     * startDialerSession call.
-     */
-    public void stopDialerSession() {
-        // release the tone generator.
-        synchronized (mToneGeneratorLock) {
-            if (mToneGenerator != null) {
-                mToneGenerator.release();
-                mToneGenerator = null;
-            }
-        }
-
-        mHandler.removeMessages(DTMF_SEND_CNF);
-        synchronized (mDTMFQueue) {
-            mDTMFBurstCnfPending = false;
-            mDTMFQueue.clear();
-        }
-    }
-
-    /**
-     * Starts playback of the dtmf tone corresponding to the parameter.
-     */
-    public void playDtmfTone(char c, boolean timedShortTone) {
-        // Only play the tone if it exists.
-        if (!mToneMap.containsKey(c)) {
-            return;
-        }
-
-        if (!okToDialDtmfTones()) {
-            return;
-        }
-
-        PhoneGlobals.getInstance().pokeUserActivity();
-
-        // Read the settings as it may be changed by the user during the call
-        Phone phone = mCallManager.getFgPhone();
-
-        // Before we go ahead and start a tone, we need to make sure that any pending
-        // stop-tone message is processed.
-        if (mHandler.hasMessages(DTMF_STOP)) {
-            mHandler.removeMessages(DTMF_STOP);
-            stopDtmfTone();
-        }
-
-        mShortTone = useShortDtmfTones(phone, phone.getContext());
-        logD("startDtmfTone()...");
-
-        // For Short DTMF we need to play the local tone for fixed duration
-        if (mShortTone) {
-            sendShortDtmfToNetwork(c);
-        } else {
-            // Pass as a char to be sent to network
-            logD("send long dtmf for " + c);
-            mCallManager.startDtmf(c);
-
-            // If it is a timed tone, queue up the stop command in DTMF_DURATION_MS.
-            if (timedShortTone) {
-                mHandler.sendMessageDelayed(mHandler.obtainMessage(DTMF_STOP), DTMF_DURATION_MS);
-            }
-        }
-
-        startLocalToneIfNeeded(c);
-    }
-
-    /**
-     * Sends the dtmf character over the network for short DTMF settings
-     * When the characters are entered in quick succession,
-     * the characters are queued before sending over the network.
-     */
-    private void sendShortDtmfToNetwork(char dtmfDigit) {
-        synchronized (mDTMFQueue) {
-            if (mDTMFBurstCnfPending == true) {
-                // Insert the dtmf char to the queue
-                mDTMFQueue.add(new Character(dtmfDigit));
-            } else {
-                String dtmfStr = Character.toString(dtmfDigit);
-                mCallManager.sendBurstDtmf(dtmfStr, 0, 0, mHandler.obtainMessage(DTMF_SEND_CNF));
-                // Set flag to indicate wait for Telephony confirmation.
-                mDTMFBurstCnfPending = true;
-            }
-        }
-    }
-
-    /**
-     * Handles Burst Dtmf Confirmation from the Framework.
-     */
-    void handleBurstDtmfConfirmation() {
-        Character dtmfChar = null;
-        synchronized (mDTMFQueue) {
-            mDTMFBurstCnfPending = false;
-            if (!mDTMFQueue.isEmpty()) {
-                dtmfChar = mDTMFQueue.remove();
-                Log.i(LOG_TAG, "The dtmf character removed from queue" + dtmfChar);
-            }
-        }
-        if (dtmfChar != null) {
-            sendShortDtmfToNetwork(dtmfChar);
-        }
-    }
-
-    public void stopDtmfTone() {
-        if (!mShortTone) {
-            mCallManager.stopDtmf();
-            stopLocalToneIfNeeded();
-        }
-    }
-
-    /**
-     * Plays the local tone based the phone type, optionally forcing a short
-     * tone.
-     */
-    private void startLocalToneIfNeeded(char c) {
-        if (mLocalToneEnabled) {
-            synchronized (mToneGeneratorLock) {
-                if (mToneGenerator == null) {
-                    logD("startDtmfTone: mToneGenerator == null, tone: " + c);
-                } else {
-                    logD("starting local tone " + c);
-                    int toneDuration = -1;
-                    if (mShortTone) {
-                        toneDuration = DTMF_DURATION_MS;
-                    }
-                    mToneGenerator.startTone(mToneMap.get(c), toneDuration);
-                }
-            }
-        }
-    }
-
-    /**
-     * Stops the local tone based on the phone type.
-     */
-    public void stopLocalToneIfNeeded() {
-        if (!mShortTone) {
-            // if local tone playback is enabled, stop it.
-            logD("trying to stop local tone...");
-            if (mLocalToneEnabled) {
-                synchronized (mToneGeneratorLock) {
-                    if (mToneGenerator == null) {
-                        logD("stopLocalTone: mToneGenerator == null");
-                    } else {
-                        logD("stopping local tone.");
-                        mToneGenerator.stopTone();
-                    }
-                }
-            }
-        }
-    }
-
-    private boolean okToDialDtmfTones() {
-        boolean hasActiveCall = false;
-        boolean hasIncomingCall = false;
-
-        final List<Call> calls = mCallModeler.getFullList();
-        final int len = calls.size();
-
-        for (int i = 0; i < len; i++) {
-            // We can also dial while in DIALING state because there are
-            // some connections that never update to an ACTIVE state (no
-            // indication from the network).
-            hasActiveCall |= (calls.get(i).getState() == Call.State.ACTIVE)
-                    || (calls.get(i).getState() == Call.State.DIALING);
-            hasIncomingCall |= (calls.get(i).getState() == Call.State.INCOMING);
-        }
-
-        return hasActiveCall && !hasIncomingCall;
-    }
-
-    /**
-     * On GSM devices, we never use short tones.
-     * On CDMA devices, it depends upon the settings.
-     */
-    private static boolean useShortDtmfTones(Phone phone, Context context) {
-        int phoneType = phone.getPhoneType();
-        if (phoneType == PhoneConstants.PHONE_TYPE_GSM
-                || phoneType == PhoneConstants.PHONE_TYPE_SIP
-                || phoneType == PhoneConstants.PHONE_TYPE_THIRD_PARTY) {
-            return false;
-        } else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-            int toneType = android.provider.Settings.System.getInt(
-                    context.getContentResolver(),
-                    Settings.System.DTMF_TONE_TYPE_WHEN_DIALING,
-                    Constants.DTMF_TONE_TYPE_NORMAL);
-            if (toneType == Constants.DTMF_TONE_TYPE_NORMAL) {
-                return true;
-            } else {
-                return false;
-            }
-        } else {
-            throw new IllegalStateException("Unexpected phone type: " + phoneType);
-        }
-    }
-
-    /**
-     * Checks to see if there are any active calls. If there are, then we want to allocate the tone
-     * resources for playing DTMF tone, otherwise release them.
-     */
-    private void checkCallState() {
-        logD("checkCallState");
-        if (mCallModeler.hasOutstandingActiveOrDialingCall()) {
-            startDialerSession();
-        } else {
-            stopDialerSession();
-        }
-    }
-
-    /**
-     * static logging method
-     */
-    private static void logD(String msg) {
-        if (DBG) {
-            Log.d(LOG_TAG, msg);
-        }
-    }
-}
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 7e26c0e..0c29bc9 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -148,9 +148,7 @@
     private AudioRouter audioRouter;
     private BluetoothManager bluetoothManager;
     private CallGatewayManager callGatewayManager;
-    private CallModeler callModeler;
     private CallStateMonitor callStateMonitor;
-    private DTMFTonePlayer dtmfTonePlayer;
     private IBluetoothHeadsetPhone mBluetoothPhone;
     private Ringer ringer;
     private WiredHeadsetManager wiredHeadsetManager;
@@ -436,18 +434,12 @@
             // Monitors call activity from the telephony layer
             callStateMonitor = new CallStateMonitor(mCM);
 
-            // Creates call models.
-            callModeler = new CallModeler(callStateMonitor, mCM, callGatewayManager);
-
-            // Plays DTMF Tones
-            dtmfTonePlayer = new DTMFTonePlayer(mCM, callModeler);
-
             // Manages wired headset state
             wiredHeadsetManager = new WiredHeadsetManager(this);
             wiredHeadsetManager.addWiredHeadsetListener(this);
 
             // Bluetooth manager
-            bluetoothManager = new BluetoothManager(this, mCM, callModeler);
+            bluetoothManager = new BluetoothManager();
 
             ringer = Ringer.init(this, bluetoothManager);
 
@@ -461,7 +453,7 @@
             // launching the incoming-call UI when an incoming call comes
             // in.)
             notifier = CallNotifier.init(this, phone, ringer, callLogger, callStateMonitor,
-                    bluetoothManager, callModeler);
+                    bluetoothManager);
 
             // register for ICC status
             IccCard sim = phone.getIccCard();
@@ -589,10 +581,6 @@
         return audioRouter;
     }
 
-    public CallModeler getCallModeler() {
-        return callModeler;
-    }
-
     /* package */ CallManager getCallManager() {
         return mCM;
     }
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index c90d833..507cbcb 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -60,7 +60,6 @@
 import com.android.internal.telephony.uicc.IccUtils;
 import com.android.internal.telephony.uicc.UiccController;
 import com.android.internal.util.HexDump;
-import com.android.services.telephony.common.Call;
 
 import static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY;
 
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index 291789d..f446d36 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -629,7 +629,8 @@
             app.cdmaPhoneCallState.setCurrentCallState(
                 CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE);
 
-            app.getCallModeler().setCdmaOutgoing3WayCall(connection);
+            // TODO(sail): Remove this code.
+            //app.getCallModeler().setCdmaOutgoing3WayCall(connection);
         }
     }
 
