diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
index e6a3dbc..5f28df8 100644
--- a/src/com/android/telecomm/Call.java
+++ b/src/com/android/telecomm/Call.java
@@ -57,7 +57,7 @@
  *  from the time the call intent was received by Telecomm (vs. the time the call was
  *  connected etc).
  */
-final class Call implements OutgoingCallResponse {
+final class Call implements CreateConnectionResponse {
     /**
      * Listener for events on the call.
      */
@@ -147,14 +147,19 @@
                 }
             };
 
+    private final Runnable mDirectToVoicemailRunnable = new Runnable() {
+        @Override
+        public void run() {
+            processDirectToVoicemail();
+        }
+    };
+
     /** True if this is an incoming call. */
     private final boolean mIsIncoming;
 
     /**
-     * The time this call was created, typically also the time this call was added to the set
-     * of pending outgoing calls (mPendingOutgoingCalls) that's maintained by the switchboard.
-     * Beyond logging and such, may also be used for bookkeeping and specifically for marking
-     * certain call attempts as failed attempts.
+     * The time this call was created. Beyond logging and such, may also be used for bookkeeping
+     * and specifically for marking certain call attempts as failed attempts.
      */
     private final long mCreationTimeMillis = System.currentTimeMillis();
 
@@ -213,7 +218,7 @@
     /** Set of listeners on this call. */
     private Set<Listener> mListeners = Sets.newHashSet();
 
-    private OutgoingCallProcessor mOutgoingCallProcessor;
+    private CreateConnectionProcessor mCreateConnectionProcessor;
 
     /** Caller information retrieved from the latest contact query. */
     private CallerInfo mCallerInfo;
@@ -245,6 +250,7 @@
 
     private boolean mAudioModeIsVoip;
     private StatusHints mStatusHints;
+    private final ConnectionServiceRepository mRepository;
 
     /**
      * Persists the specified parameters and initializes the new instance.
@@ -254,9 +260,15 @@
      * @param account Account information to use for the call.
      * @param isIncoming True if this is an incoming call.
      */
-    Call(Uri handle, GatewayInfo gatewayInfo, PhoneAccount account,
-            boolean isIncoming, boolean isConference) {
+    Call(
+            ConnectionServiceRepository repository,
+            Uri handle,
+            GatewayInfo gatewayInfo,
+            PhoneAccount account,
+            boolean isIncoming,
+            boolean isConference) {
         mState = isConference ? CallState.ACTIVE : CallState.NEW;
+        mRepository = repository;
         setHandle(handle, CallPropertyPresentation.ALLOWED);
         mGatewayInfo = gatewayInfo;
         mPhoneAccount = account;
@@ -499,43 +511,7 @@
         }
     }
 
-    /**
-     * Starts the incoming call flow through the switchboard. When switchboard completes, it will
-     * invoke handle[Un]SuccessfulIncomingCall.
-     */
-    void startIncoming() {
-        Switchboard.getInstance().retrieveIncomingCall(this);
-    }
-
-    /**
-     * Takes a verified incoming call and uses the handle to lookup direct-to-voicemail property
-     * from the contacts provider. The call is not yet exposed to the user at this point and
-     * the result of the query will determine if the call is rejected or passed through to the
-     * in-call UI.
-     */
-    void handleVerifiedIncoming(ConnectionRequest request) {
-        mPhoneAccount = request.getAccount();
-
-        // We do not handle incoming calls immediately when they are verified by the connection
-        // service. We allow the caller-info-query code to execute first so that we can read the
-        // direct-to-voicemail property before deciding if we want to show the incoming call to the
-        // user or if we want to reject the call.
-        mDirectToVoicemailQueryPending = true;
-
-        // Setting the handle triggers the caller info lookup code.
-        setHandle(request.getHandle(), CallPropertyPresentation.ALLOWED);
-
-        // Timeout the direct-to-voicemail lookup execution so that we dont wait too long before
-        // showing the user the incoming call screen.
-        mHandler.postDelayed(new Runnable() {
-            @Override
-            public void run() {
-                processDirectToVoicemail();
-            }
-        }, Timeouts.getDirectToVoicemailMillis());
-    }
-
-    void processDirectToVoicemail() {
+    private void processDirectToVoicemail() {
         if (mDirectToVoicemailQueryPending) {
             if (mCallerInfo != null && mCallerInfo.shouldSendToVoicemail) {
                 Log.i(this, "Directing call to voicemail: %s.", this);
@@ -557,60 +533,81 @@
         }
     }
 
-    void handleFailedIncoming() {
-        clearConnectionService();
-
-        // TODO: Needs more specific disconnect error for this case.
-        setDisconnectCause(DisconnectCause.ERROR_UNSPECIFIED, null);
-        setState(CallState.DISCONNECTED);
-
-        // TODO(santoscordon): Replace this with state transitions related to "connecting".
-        for (Listener l : mListeners) {
-            l.onFailedIncomingCall(this);
-        }
-    }
-
     /**
-     * Starts the outgoing call sequence.  Upon completion, there should exist an active connection
-     * through a connection service (or the call will have failed).
+     * Starts the create connection sequence. Upon completion, there should exist an active
+     * connection through a connection service (or the call will have failed).
      */
-    void startOutgoing() {
-        Preconditions.checkState(mOutgoingCallProcessor == null);
-
-        mOutgoingCallProcessor = new OutgoingCallProcessor(
-                this, Switchboard.getInstance().getConnectionServiceRepository(), this);
-        mOutgoingCallProcessor.process();
+    void startCreateConnection() {
+        Preconditions.checkState(mCreateConnectionProcessor == null);
+        mCreateConnectionProcessor = new CreateConnectionProcessor(this, mRepository, this);
+        mCreateConnectionProcessor.process();
     }
 
     @Override
-    public void onOutgoingCallSuccess() {
-        // TODO(santoscordon): Replace this with state transitions related to "connecting".
-        for (Listener l : mListeners) {
-            l.onSuccessfulOutgoingCall(this);
+    public void handleCreateConnectionSuccessful(ConnectionRequest request) {
+        mCreateConnectionProcessor = null;
+        mPhoneAccount = request.getAccount();
+
+        if (mIsIncoming) {
+            // We do not handle incoming calls immediately when they are verified by the connection
+            // service. We allow the caller-info-query code to execute first so that we can read the
+            // direct-to-voicemail property before deciding if we want to show the incoming call to
+            // the user or if we want to reject the call.
+            mDirectToVoicemailQueryPending = true;
+
+            // Setting the handle triggers the caller info lookup code.
+            setHandle(request.getHandle(), request.getHandlePresentation());
+
+            // Timeout the direct-to-voicemail lookup execution so that we dont wait too long before
+            // showing the user the incoming call screen.
+            mHandler.postDelayed(mDirectToVoicemailRunnable, Timeouts.getDirectToVoicemailMillis());
+        } else {
+            for (Listener l : mListeners) {
+                l.onSuccessfulOutgoingCall(this);
+            }
         }
-        mOutgoingCallProcessor = null;
     }
 
     @Override
-    public void onOutgoingCallFailure(int code, String msg) {
-        // TODO(santoscordon): Replace this with state transitions related to "connecting".
-        for (Listener l : mListeners) {
-            l.onFailedOutgoingCall(this, code, msg);
-        }
+    public void handleCreateConnectionFailed(int code, String msg) {
+        mCreateConnectionProcessor = null;
+        if (mIsIncoming) {
+            clearConnectionService();
+            setDisconnectCause(code, null);
+            setState(CallState.DISCONNECTED);
 
-        clearConnectionService();
-        mOutgoingCallProcessor = null;
+            Listener[] listeners = mListeners.toArray(new Listener[mListeners.size()]);
+            for (int i = 0; i < listeners.length; i++) {
+                listeners[i].onFailedIncomingCall(this);
+            }
+        } else {
+            Listener[] listeners = mListeners.toArray(new Listener[mListeners.size()]);
+            for (int i = 0; i < listeners.length; i++) {
+                listeners[i].onFailedOutgoingCall(this, code, msg);
+            }
+            clearConnectionService();
+        }
     }
 
     @Override
-    public void onOutgoingCallCancel() {
-        // TODO(santoscordon): Replace this with state transitions related to "connecting".
-        for (Listener l : mListeners) {
-            l.onCancelledOutgoingCall(this);
-        }
+    public void handleCreateConnectionCancelled() {
+        mCreateConnectionProcessor = null;
+        if (mIsIncoming) {
+            clearConnectionService();
+            setDisconnectCause(DisconnectCause.ERROR_UNSPECIFIED, null);
+            setState(CallState.DISCONNECTED);
 
-        clearConnectionService();
-        mOutgoingCallProcessor = null;
+            Listener[] listeners = mListeners.toArray(new Listener[mListeners.size()]);
+            for (int i = 0; i < listeners.length; i++) {
+                listeners[i].onFailedIncomingCall(this);
+            }
+        } else {
+            Listener[] listeners = mListeners.toArray(new Listener[mListeners.size()]);
+            for (int i = 0; i < listeners.length; i++) {
+                listeners[i].onCancelledOutgoingCall(this);
+            }
+            clearConnectionService();
+        }
     }
 
     /**
@@ -656,8 +653,8 @@
     }
 
     void abort() {
-        if (mOutgoingCallProcessor != null) {
-            mOutgoingCallProcessor.abort();
+        if (mCreateConnectionProcessor != null) {
+            mCreateConnectionProcessor.abort();
         }
     }
 
diff --git a/src/com/android/telecomm/CallActivity.java b/src/com/android/telecomm/CallActivity.java
index 0086c99..0f625c7 100644
--- a/src/com/android/telecomm/CallActivity.java
+++ b/src/com/android/telecomm/CallActivity.java
@@ -113,10 +113,13 @@
             return;
         }
 
-        Bundle clientExtras = Bundle.EMPTY;
+        Bundle clientExtras = null;
         if (intent.hasExtra(TelecommConstants.EXTRA_INCOMING_CALL_EXTRAS)) {
             clientExtras = intent.getBundleExtra(TelecommConstants.EXTRA_INCOMING_CALL_EXTRAS);
         }
+        if (clientExtras == null) {
+            clientExtras = Bundle.EMPTY;
+        }
 
         Log.d(this, "Processing incoming call from connection service [%s]",
                 phoneAccount.getComponentName());
diff --git a/src/com/android/telecomm/CallsManager.java b/src/com/android/telecomm/CallsManager.java
index 2d5d5c0..5d07176 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -67,6 +67,8 @@
      */
     private final Set<Call> mCalls = new CopyOnWriteArraySet<Call>();
 
+    private final ConnectionServiceRepository mConnectionServiceRepository =
+            new ConnectionServiceRepository();
     private final DtmfLocalTonePlayer mDtmfLocalTonePlayer = new DtmfLocalTonePlayer();
     private final InCallController mInCallController = new InCallController();
     private final CallAudioManager mCallAudioManager;
@@ -230,9 +232,7 @@
     }
 
     /**
-     * Starts the incoming call sequence by having switchboard gather more information about the
-     * specified call; using the specified connection service component name. Upon success,
-     * execution returns to {@link #onSuccessfulIncomingCall} to start the in-call UI.
+     * Starts the process to attach the call to a connection service.
      *
      * @param phoneAccount The phone account which contains the component name of the connection
      *                     serivce to use for this call.
@@ -240,16 +240,20 @@
      */
     void processIncomingCallIntent(PhoneAccount phoneAccount, Bundle extras) {
         Log.d(this, "processIncomingCallIntent");
-        // Create a call with no handle. Eventually, switchboard will update the call with
-        // additional information from the connection service, but for now we just need one to pass
-        // around.
+        // Create a call with no handle. The handle is eventually set when the call is attached
+        // to a connection service.
         Call call = new Call(
-                null, null, phoneAccount, true /* isIncoming */, false /* isConference */);
+                mConnectionServiceRepository,
+                null /* handle */,
+                null /* gatewayInfo */,
+                phoneAccount,
+                true /* isIncoming */,
+                false /* isConference */);
+
         call.setExtras(extras);
         // TODO(santoscordon): Move this to be a part of addCall()
         call.addListener(this);
-
-        call.startIncoming();
+        call.startCreateConnection();
     }
 
     /**
@@ -275,15 +279,19 @@
         }
 
         Call call = new Call(
-                uriHandle, gatewayInfo, account, false /* isIncoming */, false /* isConference */);
+                mConnectionServiceRepository,
+                uriHandle,
+                gatewayInfo,
+                account,
+                false /* isIncoming */,
+                false /* isConference */);
         call.setStartWithSpeakerphoneOn(speakerphoneOn);
         call.setVideoState(videoState);
 
         // TODO(santoscordon): Move this to be a part of addCall()
         call.addListener(this);
         addCall(call);
-
-        call.startOutgoing();
+        call.startCreateConnection();
     }
 
     /**
@@ -293,7 +301,12 @@
      */
     void conference(Call call) {
         Call conferenceCall = new Call(
-                null, null, null, false /* isIncoming */, true /* isConference */);
+                mConnectionServiceRepository,
+                null /* handle */,
+                null /* gatewayInfo */,
+                null /* phoneAccount */,
+                false /* isIncoming */,
+                true /* isConference */);
         conferenceCall.addListener(this);
         call.conferenceInto(conferenceCall);
     }
diff --git a/src/com/android/telecomm/ConnectionServiceRepository.java b/src/com/android/telecomm/ConnectionServiceRepository.java
index 7672e30..598bdd1 100644
--- a/src/com/android/telecomm/ConnectionServiceRepository.java
+++ b/src/com/android/telecomm/ConnectionServiceRepository.java
@@ -32,12 +32,10 @@
  */
 final class ConnectionServiceRepository
         implements ServiceBinder.Listener<ConnectionServiceWrapper> {
-    private final IncomingCallsManager mIncomingCallsManager;
     private final HashMap<ComponentName, ConnectionServiceWrapper> mServiceCache =
             new HashMap<ComponentName, ConnectionServiceWrapper>();
 
-    ConnectionServiceRepository(IncomingCallsManager incomingCallsManager) {
-        mIncomingCallsManager = incomingCallsManager;
+    ConnectionServiceRepository() {
     }
 
     Collection<ConnectionServiceWrapper> lookupServices() {
@@ -58,7 +56,7 @@
     ConnectionServiceWrapper getService(ComponentName componentName) {
         ConnectionServiceWrapper service = mServiceCache.get(componentName);
         if (service == null) {
-            service = new ConnectionServiceWrapper(componentName, mIncomingCallsManager, this);
+            service = new ConnectionServiceWrapper(componentName, this);
             service.addListener(this);
             mServiceCache.put(componentName, service);
         }
diff --git a/src/com/android/telecomm/ConnectionServiceWrapper.java b/src/com/android/telecomm/ConnectionServiceWrapper.java
index 1b0dcdf..870d61c 100644
--- a/src/com/android/telecomm/ConnectionServiceWrapper.java
+++ b/src/com/android/telecomm/ConnectionServiceWrapper.java
@@ -56,87 +56,67 @@
  * {@link IConnectionService}.
  */
 final class ConnectionServiceWrapper extends ServiceBinder<IConnectionService> {
-    private static final int MSG_NOTIFY_INCOMING_CALL = 1;
-    private static final int MSG_HANDLE_SUCCESSFUL_OUTGOING_CALL = 2;
-    private static final int MSG_HANDLE_FAILED_OUTGOING_CALL = 3;
-    private static final int MSG_CANCEL_OUTGOING_CALL = 4;
-    private static final int MSG_SET_ACTIVE = 5;
-    private static final int MSG_SET_RINGING = 6;
-    private static final int MSG_SET_DIALING = 7;
-    private static final int MSG_SET_DISCONNECTED = 8;
-    private static final int MSG_SET_ON_HOLD = 9;
-    private static final int MSG_SET_REQUESTING_RINGBACK = 10;
-    private static final int MSG_SET_CALL_CAPABILITIES = 11;
-    private static final int MSG_SET_IS_CONFERENCED = 12;
-    private static final int MSG_ADD_CONFERENCE_CALL = 13;
-    private static final int MSG_REMOVE_CALL = 14;
-    private static final int MSG_ON_POST_DIAL_WAIT = 15;
-    private static final int MSG_QUERY_REMOTE_CALL_SERVICES = 16;
-    private static final int MSG_SET_CALL_VIDEO_PROVIDER = 17;
-    private static final int MSG_SET_AUDIO_MODE_IS_VOIP = 18;
-    private static final int MSG_SET_STATUS_HINTS = 19;
-    private static final int MSG_SET_HANDLE = 20;
-    private static final int MSG_SET_CALLER_DISPLAY_NAME = 21;
+    private static final int MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL = 1;
+    private static final int MSG_HANDLE_CREATE_CONNECTION_FAILED = 2;
+    private static final int MSG_HANDLE_CREATE_CONNECTION_CANCELLED = 3;
+    private static final int MSG_SET_ACTIVE = 4;
+    private static final int MSG_SET_RINGING = 5;
+    private static final int MSG_SET_DIALING = 6;
+    private static final int MSG_SET_DISCONNECTED = 7;
+    private static final int MSG_SET_ON_HOLD = 8;
+    private static final int MSG_SET_REQUESTING_RINGBACK = 9;
+    private static final int MSG_SET_CALL_CAPABILITIES = 10;
+    private static final int MSG_SET_IS_CONFERENCED = 11;
+    private static final int MSG_ADD_CONFERENCE_CALL = 12;
+    private static final int MSG_REMOVE_CALL = 13;
+    private static final int MSG_ON_POST_DIAL_WAIT = 14;
+    private static final int MSG_QUERY_REMOTE_CALL_SERVICES = 15;
+    private static final int MSG_SET_CALL_VIDEO_PROVIDER = 16;
+    private static final int MSG_SET_AUDIO_MODE_IS_VOIP = 17;
+    private static final int MSG_SET_STATUS_HINTS = 18;
+    private static final int MSG_SET_HANDLE = 19;
+    private static final int MSG_SET_CALLER_DISPLAY_NAME = 20;
 
     private final Handler mHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
             Call call;
             switch (msg.what) {
-                case MSG_NOTIFY_INCOMING_CALL: {
+                case MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL: {
                     ConnectionRequest request = (ConnectionRequest) msg.obj;
-                    call = mCallIdMapper.getCall(request.getCallId());
-                    if (call != null && mPendingIncomingCalls.remove(call) &&
-                            call.isIncoming()) {
-                        mIncomingCallsManager.handleSuccessfulIncomingCall(call, request);
+                    if (mPendingResponses.containsKey(request.getCallId())) {
+                        mPendingResponses.remove(
+                                request.getCallId()).handleCreateConnectionSuccessful(request);
                     } else {
-                        // TODO(santoscordon): For this an the other commented logging, we need
-                        // to reenable it.  At the moment all ConnectionServiceAdapters receive
-                        // notification of changes to all calls, even calls which it may not own
-                        // (ala remote connections). We need to fix that and then uncomment the
-                        // logging calls here.
-                        //Log.w(this, "notifyIncomingCall, unknown incoming call: %s, id: %s",
-                        //        call, request.getId());
+                        //Log.w(this, "handleCreateConnectionSuccessful, unknown call: %s", callId);
                     }
                     break;
                 }
-                case MSG_HANDLE_SUCCESSFUL_OUTGOING_CALL: {
-                    ConnectionRequest request = (ConnectionRequest) msg.obj;
-                    if (mPendingOutgoingCalls.containsKey(request.getCallId())) {
-                        mPendingOutgoingCalls.remove(
-                                request.getCallId()).onOutgoingCallSuccess();
-                    } else {
-                        //Log.w(this, "handleSuccessfulOutgoingCall, unknown call: %s", callId);
-                    }
-                    break;
-                }
-                case MSG_HANDLE_FAILED_OUTGOING_CALL: {
+                case MSG_HANDLE_CREATE_CONNECTION_FAILED: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
                         ConnectionRequest request = (ConnectionRequest) args.arg1;
                         int statusCode = args.argi1;
                         String statusMsg = (String) args.arg2;
-                        // TODO(santoscordon): Do something with 'reason' or get rid of it.
-
-                        if (mPendingOutgoingCalls.containsKey(request.getCallId())) {
-                            mPendingOutgoingCalls.remove(request.getCallId())
-                                    .onOutgoingCallFailure(statusCode, statusMsg);
+                        if (mPendingResponses.containsKey(request.getCallId())) {
+                            mPendingResponses.remove(request.getCallId())
+                                    .handleCreateConnectionFailed(statusCode, statusMsg);
                             mCallIdMapper.removeCall(request.getCallId());
                         } else {
-                            //Log.w(this, "handleFailedOutgoingCall, unknown call: %s", callId);
+                            //Log.w(this, "handleCreateConnectionFailed, unknown call: %s", callId);
                         }
                     } finally {
                         args.recycle();
                     }
                     break;
                 }
-                case MSG_CANCEL_OUTGOING_CALL: {
+                case MSG_HANDLE_CREATE_CONNECTION_CANCELLED: {
                     ConnectionRequest request = (ConnectionRequest) msg.obj;
-                    if (mPendingOutgoingCalls.containsKey(request.getCallId())) {
-                        mPendingOutgoingCalls.remove(
-                                request.getCallId()).onOutgoingCallCancel();
+                    if (mPendingResponses.containsKey(request.getCallId())) {
+                        mPendingResponses.remove(
+                                request.getCallId()).handleCreateConnectionCancelled();
                     } else {
-                        //Log.w(this, "cancelOutgoingCall, unknown call: %s", callId);
+                        //Log.w(this, "handleCreateConnectionCancelled, unknown call: %s", callId);
                     }
                     break;
                 }
@@ -268,8 +248,7 @@
                     break;
                 }
                 case MSG_QUERY_REMOTE_CALL_SERVICES: {
-                    ConnectionServiceWrapper.this.queryRemoteConnectionServices(
-                            (RemoteServiceCallback) msg.obj);
+                    queryRemoteConnectionServices((RemoteServiceCallback) msg.obj);
                     break;
                 }
                 case MSG_SET_CALL_VIDEO_PROVIDER: {
@@ -335,38 +314,29 @@
 
     private final class Adapter extends IConnectionServiceAdapter.Stub {
         @Override
-        public void notifyIncomingCall(ConnectionRequest request) {
-            logIncoming("notifyIncomingCall %s", request);
+        public void handleCreateConnectionSuccessful(ConnectionRequest request) {
+            logIncoming("handleCreateConnectionSuccessful %s", request);
             mCallIdMapper.checkValidCallId(request.getCallId());
-            mHandler.obtainMessage(MSG_NOTIFY_INCOMING_CALL, request).sendToTarget();
+            mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL, request).sendToTarget();
         }
 
         @Override
-        public void handleSuccessfulOutgoingCall(ConnectionRequest request) {
-            logIncoming("handleSuccessfulOutgoingCall %s", request);
-            mCallIdMapper.checkValidCallId(request.getCallId());
-            mHandler.obtainMessage(MSG_HANDLE_SUCCESSFUL_OUTGOING_CALL, request).sendToTarget();
-        }
-
-        @Override
-        public void handleFailedOutgoingCall(
-                ConnectionRequest request,
-                int errorCode,
-                String errorMsg) {
-            logIncoming("handleFailedOutgoingCall %s %d %s", request, errorCode, errorMsg);
+        public void handleCreateConnectionFailed(
+                ConnectionRequest request, int errorCode, String errorMsg) {
+            logIncoming("handleCreateConnectionFailed %s %d %s", request, errorCode, errorMsg);
             mCallIdMapper.checkValidCallId(request.getCallId());
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = request;
             args.argi1 = errorCode;
             args.arg2 = errorMsg;
-            mHandler.obtainMessage(MSG_HANDLE_FAILED_OUTGOING_CALL, args).sendToTarget();
+            mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_FAILED, args).sendToTarget();
         }
 
         @Override
-        public void cancelOutgoingCall(ConnectionRequest request) {
-            logIncoming("cancelOutgoingCall %s", request);
+        public void handleCreateConnectionCancelled(ConnectionRequest request) {
+            logIncoming("handleCreateConnectionCancelled %s", request);
             mCallIdMapper.checkValidCallId(request.getCallId());
-            mHandler.obtainMessage(MSG_CANCEL_OUTGOING_CALL, request).sendToTarget();
+            mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_CANCELLED, request).sendToTarget();
         }
 
         @Override
@@ -517,11 +487,9 @@
 
     private final Adapter mAdapter = new Adapter();
     private final CallsManager mCallsManager = CallsManager.getInstance();
-    private final Set<Call> mPendingIncomingCalls = new HashSet<>();
     private final Set<Call> mPendingConferenceCalls = new HashSet<>();
     private final CallIdMapper mCallIdMapper = new CallIdMapper("ConnectionService");
-    private final IncomingCallsManager mIncomingCallsManager;
-    private final Map<String, OutgoingCallResponse> mPendingOutgoingCalls = new HashMap<>();
+    private final Map<String, CreateConnectionResponse> mPendingResponses = new HashMap<>();
 
     private Binder mBinder = new Binder();
     private IConnectionService mServiceInterface;
@@ -531,15 +499,11 @@
      * Creates a connection service.
      *
      * @param componentName The component name of the service with which to bind.
-     * @param incomingCallsManager Manages the incoming call initialization flow.
      * @param connectionServiceRepository Connection service repository.
      */
     ConnectionServiceWrapper(
-            ComponentName componentName,
-            IncomingCallsManager incomingCallsManager,
-            ConnectionServiceRepository connectionServiceRepository) {
+            ComponentName componentName, ConnectionServiceRepository connectionServiceRepository) {
         super(TelecommConstants.ACTION_CONNECTION_SERVICE, componentName);
-        mIncomingCallsManager = incomingCallsManager;
         mConnectionServiceRepository = connectionServiceRepository;
     }
 
@@ -555,16 +519,15 @@
     }
 
     /**
-     * Attempts to place the specified call, see {@link IConnectionService#call}. Returns the result
-     * asynchronously through the specified callback.
+     * Creates a new connection for a new outgoing call or to attach to an existing incoming call.
      */
-    void call(final Call call, final OutgoingCallResponse callResponse) {
-        Log.d(this, "call(%s) via %s.", call, getComponentName());
+    void createConnection(final Call call, final CreateConnectionResponse response) {
+        Log.d(this, "createConnection(%s) via %s.", call, getComponentName());
         BindCallback callback = new BindCallback() {
             @Override
             public void onSuccess() {
                 String callId = mCallIdMapper.getCallId(call);
-                mPendingOutgoingCalls.put(callId, callResponse);
+                mPendingResponses.put(callId, response);
 
                 GatewayInfo gatewayInfo = call.getGatewayInfo();
                 Bundle extras = call.getExtras();
@@ -587,10 +550,10 @@
                         call.getVideoState());
 
                 try {
-                    mServiceInterface.call(request);
+                    mServiceInterface.createConnection(request, call.isIncoming());
                 } catch (RemoteException e) {
-                    Log.e(this, e, "Failure to call -- %s", getComponentName());
-                    mPendingOutgoingCalls.remove(callId).onOutgoingCallFailure(
+                    Log.e(this, e, "Failure to createConnection -- %s", getComponentName());
+                    mPendingResponses.remove(callId).handleCreateConnectionFailed(
                             DisconnectCause.ERROR_UNSPECIFIED, e.toString());
                 }
             }
@@ -598,7 +561,7 @@
             @Override
             public void onFailure() {
                 Log.e(this, new Exception(), "Failure to call %s", getComponentName());
-                callResponse.onOutgoingCallFailure(DisconnectCause.ERROR_UNSPECIFIED, null);
+                response.handleCreateConnectionFailed(DisconnectCause.ERROR_UNSPECIFIED, null);
             }
         };
 
@@ -657,47 +620,6 @@
         }
     }
 
-    /**
-     * Starts retrieval of details for an incoming call. Details are returned through the connection
-     * service adapter using the specified call ID. Upon failure, the specified error callback is
-     * invoked. Can be invoked even when the connection service is unbound. See
-     * {@link IConnectionService#createIncomingCall}.
-     *
-     * @param call The call used for the incoming call.
-     * @param errorCallback The callback to invoke upon failure.
-     */
-    void createIncomingCall(final Call call, final Runnable errorCallback) {
-        Log.d(this, "createIncomingCall(%s) via %s.", call, getComponentName());
-        BindCallback callback = new BindCallback() {
-            @Override
-            public void onSuccess() {
-                if (isServiceValid("createIncomingCall")) {
-                    mPendingIncomingCalls.add(call);
-                    String callId = mCallIdMapper.getCallId(call);
-                    logOutgoing("createIncomingCall %s", callId);
-                    ConnectionRequest request = new ConnectionRequest(
-                            call.getPhoneAccount(),
-                            callId,
-                            call.getHandle(),
-                            call.getHandlePresentation(),
-                            call.getExtras(),
-                            call.getVideoState());
-                    try {
-                        mServiceInterface.createIncomingCall(request);
-                    } catch (RemoteException e) {
-                    }
-                }
-            }
-
-            @Override
-            public void onFailure() {
-                errorCallback.run();
-            }
-        };
-
-        mBinder.bind(callback);
-    }
-
     /** @see ConnectionService#disconnect(String) */
     void disconnect(Call call) {
         if (isServiceValid("disconnect")) {
@@ -768,12 +690,9 @@
     }
 
     void removeCall(Call call) {
-        mPendingIncomingCalls.remove(call);
-
-        OutgoingCallResponse outgoingResultCallback =
-                mPendingOutgoingCalls.remove(mCallIdMapper.getCallId(call));
-        if (outgoingResultCallback != null) {
-            outgoingResultCallback.onOutgoingCallFailure(DisconnectCause.ERROR_UNSPECIFIED, null);
+        CreateConnectionResponse response = mPendingResponses.remove(mCallIdMapper.getCallId(call));
+        if (response != null) {
+            response.handleCreateConnectionFailed(DisconnectCause.ERROR_UNSPECIFIED, null);
         }
 
         mCallIdMapper.removeCall(call);
@@ -865,27 +784,14 @@
      * Called when the associated connection service dies.
      */
     private void handleConnectionServiceDeath() {
-        if (!mPendingOutgoingCalls.isEmpty()) {
-            for (OutgoingCallResponse callback : mPendingOutgoingCalls.values()) {
-                callback.onOutgoingCallFailure(DisconnectCause.ERROR_UNSPECIFIED, null);
-            }
-            mPendingOutgoingCalls.clear();
-        }
-
-        if (!mPendingIncomingCalls.isEmpty()) {
-            // Iterate through a copy because the code inside the loop will modify the original
-            // list.
-            for (Call call : ImmutableList.copyOf(mPendingIncomingCalls)) {
-                Preconditions.checkState(call.isIncoming());
-                mIncomingCallsManager.handleFailedIncomingCall(call);
-            }
-
-            if (!mPendingIncomingCalls.isEmpty()) {
-                Log.wtf(this, "Pending calls did not get cleared.");
-                mPendingIncomingCalls.clear();
+        if (!mPendingResponses.isEmpty()) {
+            CreateConnectionResponse[] responses = mPendingResponses.values().toArray(
+                    new CreateConnectionResponse[mPendingResponses.values().size()]);
+            mPendingResponses.clear();
+            for (int i = 0; i < responses.length; i++) {
+                responses[i].handleCreateConnectionFailed(DisconnectCause.ERROR_UNSPECIFIED, null);
             }
         }
-
         mCallIdMapper.clear();
     }
 
@@ -900,15 +806,16 @@
     private void queryRemoteConnectionServices(final RemoteServiceCallback callback) {
         final List<IBinder> connectionServices = new ArrayList<>();
         final List<ComponentName> components = new ArrayList<>();
+        final List<ConnectionServiceWrapper> servciesAttempted = new ArrayList<>();
         final Collection<ConnectionServiceWrapper> services =
                 mConnectionServiceRepository.lookupServices();
 
+        Log.v(this, "queryRemoteConnectionServices, services: " + services.size());
+
         for (ConnectionServiceWrapper cs : services) {
             if (cs != this) {
                 final ConnectionServiceWrapper currentConnectionService = cs;
                 cs.mBinder.bind(new BindCallback() {
-                    private int mRemainingResponses = services.size() - 1;
-
                     @Override
                     public void onSuccess() {
                         Log.d(this, "Adding ***** %s", currentConnectionService.getComponentName());
@@ -920,13 +827,12 @@
 
                     @Override
                     public void onFailure() {
-                        // add null so that we always add up to totalExpected even if
-                        // some of the connection services fail to bind.
                         maybeComplete();
                     }
 
                     private void maybeComplete() {
-                        if (--mRemainingResponses == 0) {
+                        servciesAttempted.add(currentConnectionService);
+                        if (servciesAttempted.size() == services.size() - 1) {
                             try {
                                 callback.onResult(components, connectionServices);
                             } catch (RemoteException ignored) {
diff --git a/src/com/android/telecomm/CreateConnectionProcessor.java b/src/com/android/telecomm/CreateConnectionProcessor.java
new file mode 100644
index 0000000..631d6fe
--- /dev/null
+++ b/src/com/android/telecomm/CreateConnectionProcessor.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telecomm;
+
+import android.content.ComponentName;
+import android.net.Uri;
+import android.telephony.DisconnectCause;
+import android.telephony.PhoneNumberUtils;
+import android.telecomm.ConnectionRequest;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This class creates connections to place new outgoing calls to attached to an existing incoming
+ * call. In either case, this class cycles through a set of connection services until:
+ *   - a connection service returns a newly created connection in which case the call is displayed
+ *     to the user
+ *   - a connection service cancels the process, in which case the call is aborted
+ */
+final class CreateConnectionProcessor {
+    private final Call mCall;
+    private final ConnectionServiceRepository mRepository;
+    private List<ComponentName> mServiceComponentNames;
+    private Iterator<ComponentName> mServiceComponentNameIterator;
+    private CreateConnectionResponse mResponse;
+    private int mLastErrorCode = DisconnectCause.ERROR_UNSPECIFIED;
+    private String mLastErrorMsg;
+
+    CreateConnectionProcessor(
+            Call call, ConnectionServiceRepository repository, CreateConnectionResponse response) {
+        mCall = call;
+        mRepository = repository;
+        mResponse = response;
+    }
+
+    void process() {
+        Log.v(this, "process");
+
+        mServiceComponentNames = new ArrayList<>();
+
+        // TODO(sail): Remove once there's a way to pick the service.
+        ArrayList<ComponentName> priorityComponents = new ArrayList<>();
+        priorityComponents.add(new ComponentName("com.android.phone",
+                "com.android.services.telephony.sip.SipConnectionService"));
+        priorityComponents.add(new ComponentName("com.google.android.talk",
+                "com.google.android.apps.babel.telephony.TeleConnectionService"));
+        priorityComponents.add(new ComponentName("com.android.telecomm.tests",
+                "com.android.telecomm.testapps.TestConnectionService"));
+
+        for (ConnectionServiceWrapper service : mRepository.lookupServices()) {
+            ComponentName serviceName = service.getComponentName();
+            if (priorityComponents.contains(serviceName)) {
+                Log.i(this, "Moving connection service %s to top of list", serviceName);
+                mServiceComponentNames .add(0, serviceName);
+            } else {
+                mServiceComponentNames.add(serviceName);
+            }
+        }
+
+        adjustComponentNamesForEmergency();
+        mServiceComponentNameIterator = mServiceComponentNames.iterator();
+        attemptNextConnectionService();
+    }
+
+    void abort() {
+        Log.v(this, "abort");
+
+        // Clear the response first to prevent attemptNextConnectionService from attempting any
+        // more services.
+        CreateConnectionResponse response = mResponse;
+        mResponse = null;
+
+        ConnectionServiceWrapper service = mCall.getConnectionService();
+        if (service != null) {
+            service.abort(mCall);
+            mCall.clearConnectionService();
+        }
+        if (response != null) {
+            response.handleCreateConnectionCancelled();
+        }
+    }
+
+    private void attemptNextConnectionService() {
+        Log.v(this, "attemptNextConnectionService");
+
+        if (mResponse != null && mServiceComponentNameIterator.hasNext()) {
+            ComponentName component = mServiceComponentNameIterator.next();
+            ConnectionServiceWrapper service = mRepository.getService(component);
+            if (service == null) {
+                attemptNextConnectionService();
+            } else {
+                mCall.setConnectionService(service);
+                Log.i(this, "Attempting to call from %s", service.getComponentName());
+                service.createConnection(mCall, new Response(service));
+            }
+        } else {
+            Log.v(this, "attemptNextConnectionService, no more services, failing");
+            if (mResponse != null) {
+                mResponse.handleCreateConnectionFailed(mLastErrorCode, mLastErrorMsg);
+                mResponse = null;
+                mCall.clearConnectionService();
+            }
+        }
+    }
+
+    // If we are possibly attempting to call a local emergency number, ensure that the
+    // plain PSTN connection service, if it exists, is attempted first.
+    private void adjustComponentNamesForEmergency()  {
+        if (shouldProcessAsEmergency(mCall.getHandle())) {
+            for (int i = 0; i < mServiceComponentNames.size(); i++) {
+                if (TelephonyUtil.isPstnComponentName(mServiceComponentNames.get(i))) {
+                    mServiceComponentNames.add(0, mServiceComponentNames.remove(i));
+                    return;
+                }
+            }
+        }
+    }
+
+    private boolean shouldProcessAsEmergency(Uri handle) {
+        return handle != null && PhoneNumberUtils.isPotentialLocalEmergencyNumber(
+                TelecommApp.getInstance(), handle.getSchemeSpecificPart());
+    }
+
+    private class Response implements CreateConnectionResponse {
+        private final ConnectionServiceWrapper mService;
+
+        Response(ConnectionServiceWrapper service) {
+            mService = service;
+        }
+
+        @Override
+        public void handleCreateConnectionSuccessful(ConnectionRequest request) {
+            if (mResponse == null) {
+                mService.abort(mCall);
+            } else {
+                mResponse.handleCreateConnectionSuccessful(request);
+                mResponse= null;
+            }
+        }
+
+        @Override
+        public void handleCreateConnectionFailed(int code, String msg) {
+            mLastErrorCode = code;
+            mLastErrorMsg = msg;
+            attemptNextConnectionService();
+        }
+
+        @Override
+        public void handleCreateConnectionCancelled() {
+            if (mResponse != null) {
+                mResponse.handleCreateConnectionCancelled();
+                mResponse = null;
+            }
+        }
+    }
+}
diff --git a/src/com/android/telecomm/OutgoingCallResponse.java b/src/com/android/telecomm/CreateConnectionResponse.java
similarity index 67%
rename from src/com/android/telecomm/OutgoingCallResponse.java
rename to src/com/android/telecomm/CreateConnectionResponse.java
index 3d5c393..caf2c1a 100644
--- a/src/com/android/telecomm/OutgoingCallResponse.java
+++ b/src/com/android/telecomm/CreateConnectionResponse.java
@@ -16,11 +16,13 @@
 
 package com.android.telecomm;
 
+import android.telecomm.ConnectionRequest;
+
 /**
- * A callback for providing the result of placing an outgoing call.
+ * A callback for providing the result of creating a connection.
  */
-interface OutgoingCallResponse {
-    void onOutgoingCallSuccess();
-    void onOutgoingCallFailure(int code, String msg);
-    void onOutgoingCallCancel();
+interface CreateConnectionResponse {
+    void handleCreateConnectionSuccessful(ConnectionRequest request);
+    void handleCreateConnectionFailed(int code, String msg);
+    void handleCreateConnectionCancelled();
 }
diff --git a/src/com/android/telecomm/IncomingCallsManager.java b/src/com/android/telecomm/IncomingCallsManager.java
deleted file mode 100644
index 5fa80f5..0000000
--- a/src/com/android/telecomm/IncomingCallsManager.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright 2014, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.telecomm;
-
-import android.os.Bundle;
-import android.telecomm.ConnectionService;
-import android.telecomm.ConnectionRequest;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
-import java.util.Set;
-
-/**
- * Used to retrieve details about an incoming call. This is invoked after an incoming call intent.
- */
-final class IncomingCallsManager {
-
-    private final Set<Call> mPendingIncomingCalls = Sets.newLinkedHashSet();
-
-    /**
-     * Retrieves details of an incoming call through its associated connection service.
-     *
-     * @param call The call object.
-     */
-    void retrieveIncomingCall(final Call call) {
-        ThreadUtil.checkOnMainThread();
-        Log.d(this, "retrieveIncomingCall");
-
-        // Just to be safe, lets make sure we're not already processing this call.
-        Preconditions.checkState(!mPendingIncomingCalls.contains(call));
-
-        mPendingIncomingCalls.add(call);
-
-        Runnable errorCallback = new Runnable() {
-            @Override public void run() {
-                handleFailedIncomingCall(call);
-            }
-        };
-
-        call.getConnectionService().createIncomingCall(call, errorCallback);
-    }
-
-    /**
-     * Notifies the incoming call of success after removing it from the pending
-     * list.
-     *
-     * @param request The details of the call.
-     */
-    void handleSuccessfulIncomingCall(Call call, ConnectionRequest request) {
-        ThreadUtil.checkOnMainThread();
-
-        if (mPendingIncomingCalls.contains(call)) {
-            Log.d(this, "Incoming call %s found.", call);
-            mPendingIncomingCalls.remove(call);
-            call.handleVerifiedIncoming(request);
-        }
-    }
-
-    /**
-     * Notifies  incoming call of failure after removing it from the pending list.
-     */
-    void handleFailedIncomingCall(Call call) {
-        ThreadUtil.checkOnMainThread();
-
-        if (mPendingIncomingCalls.contains(call)) {
-            Log.i(this, "Failed to get details for incoming call %s", call);
-            mPendingIncomingCalls.remove(call);
-            // The call was found still waiting for details. Consider it failed.
-            call.handleFailedIncoming();
-        }
-    }
-}
diff --git a/src/com/android/telecomm/MissedCallNotifier.java b/src/com/android/telecomm/MissedCallNotifier.java
index bb2f092..ed79f5a 100644
--- a/src/com/android/telecomm/MissedCallNotifier.java
+++ b/src/com/android/telecomm/MissedCallNotifier.java
@@ -279,7 +279,7 @@
                         }
 
                         // Convert the data to a call object
-                        Call call = new Call(null, null, null, true, false);
+                        Call call = new Call(null, null, null, null, true, false);
                         call.setDisconnectCause(DisconnectCause.INCOMING_MISSED, "");
                         call.setState(CallState.DISCONNECTED);
 
diff --git a/src/com/android/telecomm/OutgoingCallProcessor.java b/src/com/android/telecomm/OutgoingCallProcessor.java
deleted file mode 100644
index c24a83b..0000000
--- a/src/com/android/telecomm/OutgoingCallProcessor.java
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Copyright 2014, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.telecomm;
-
-import android.content.ComponentName;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Message;
-import android.telephony.DisconnectCause;
-import android.telephony.PhoneNumberUtils;
-
-import com.google.android.collect.Sets;
-import com.google.common.collect.Maps;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Utility class to place a call using the specified set of connection services. Each of the
- * connection services is then attempted until either the outgoing call is placed, the attempted
- * call is aborted, or the list is exhausted -- whichever occurs first.
- *
- * Except for the abort case, all other scenarios should terminate with the call notified
- * of the result.
- */
-final class OutgoingCallProcessor {
-
-    /**
-     * The outgoing call this processor is tasked with placing.
-     */
-    private final Call mCall;
-
-    /**
-     * The set of attempted connection services, used to ensure services are attempted at most once
-     * per outgoing-call attempt.
-     */
-    private final Set<ConnectionServiceWrapper> mAttemptedServices = Sets.newHashSet();
-
-    private final ConnectionServiceRepository mConnectionServiceRepository;
-
-    /**
-     * The duplicate-free list of currently-available connection service component names.
-     */
-    private List<ComponentName> mServiceComponentNames;
-
-    /**
-     * The iterator over the currently-selected ordered list of connection service component names.
-     */
-    private Iterator<ComponentName> mServiceComponentNameIterator;
-
-    private OutgoingCallResponse mResultCallback;
-
-    private boolean mIsAborted = false;
-
-    private int mLastErrorCode = 0;
-
-    private String mLastErrorMsg = null;
-
-    /**
-     * Persists the specified parameters and iterates through the prioritized list of call
-     * services. Stops once a matching connection service is found. Calls with no matching
-     * connection service will eventually be killed by the cleanup/monitor switchboard handler.
-     *
-     * @param call The call to place.
-     * @param resultCallback The callback on which to return the result.
-     */
-    OutgoingCallProcessor(
-            Call call,
-            ConnectionServiceRepository connectionServiceRepository,
-            OutgoingCallResponse resultCallback) {
-
-        ThreadUtil.checkOnMainThread();
-
-        mCall = call;
-        mResultCallback = resultCallback;
-        mConnectionServiceRepository = connectionServiceRepository;
-    }
-
-    /**
-     * Initiates the attempt to place the call.  No-op beyond the first invocation.
-     */
-    void process() {
-        Log.v(this, "process, mIsAborted: %b", mIsAborted);
-        if (!mIsAborted) {
-            setConnectionServices(mConnectionServiceRepository.lookupServices());
-        }
-    }
-
-    /**
-     * Aborts the attempt to place the relevant call.  Intended to be invoked by
-     * switchboard through the outgoing-calls manager.
-     */
-    void abort() {
-        Log.v(this, "abort");
-        ThreadUtil.checkOnMainThread();
-        if (!mIsAborted && mResultCallback != null) {
-            mIsAborted = true;
-
-            // On an abort, we need to check if we already told the connection service to place the
-            // call. If so, we need to tell it to abort.
-            // TODO(santoscordon): The conneciton service is saved with the call and so we have to
-            // query the call to get it, which is a bit backwards.  Ideally, the connection service
-            // would be saved inside this class until the whole thing is complete and then set on
-            // the call.
-            ConnectionServiceWrapper service = mCall.getConnectionService();
-            if (service != null) {
-                service.abort(mCall);
-            }
-
-            // We consider a deliberate abort to be a "normal" disconnect, not
-            // requiring special reporting.
-            sendResult(false, DisconnectCause.LOCAL, null);
-        }
-    }
-
-    boolean isAborted() {
-        return mIsAborted;
-    }
-
-    /**
-     * Completes the outgoing call sequence by setting the connection service on the call object.
-     * This is invoked when the connection service adapter receives positive confirmation that the
-     * connection service placed the call.
-     */
-    void handleSuccessfulCallAttempt(ConnectionServiceWrapper service) {
-        Log.v(this, "handleSuccessfulCallAttempt");
-        ThreadUtil.checkOnMainThread();
-
-        if (mIsAborted) {
-            service.abort(mCall);
-            return;
-        }
-
-        sendResult(true, DisconnectCause.NOT_DISCONNECTED, null);
-    }
-
-    /**
-     * Attempts the next connection service if the specified connection service is the one currently
-    * being attempted.
-     *
-     * @param errorCode The reason for the failure, one of {@link DisconnectCause}.
-     * @param errorMsg Optional text reason for the failure.
-     */
-    void handleFailedCallAttempt(int errorCode, String errorMsg) {
-        Log.v(this, "handleFailedCallAttempt %s %s", DisconnectCause.toString(errorCode), errorMsg);
-        // Store latest error code and message. If this is our last available attempt at placing
-        // a call, these error details will be considered "the" cause of the failure.
-        mLastErrorCode = errorCode;
-        mLastErrorMsg = errorMsg;
-        if (!mIsAborted) {
-            ThreadUtil.checkOnMainThread();
-            attemptNextConnectionService();
-        }
-    }
-
-    /**
-     * Sets the connection services to attempt for this outgoing call.
-     *
-     * @param services The connection services.
-     */
-    private void setConnectionServices(Collection<ConnectionServiceWrapper> services) {
-        mServiceComponentNames = new ArrayList<>();
-
-        // TODO(sail): Remove once there's a way to pick the service.
-        ArrayList<ComponentName> priorityComponents = new ArrayList<>();
-        priorityComponents.add(new ComponentName("com.android.phone",
-                "com.android.services.telephony.sip.SipConnectionService"));
-        priorityComponents.add(new ComponentName("com.google.android.talk",
-                "com.google.android.apps.babel.telephony.TeleConnectionService"));
-        priorityComponents.add(new ComponentName("com.android.telecomm.tests",
-                "com.android.telecomm.testapps.TestConnectionService"));
-
-        for (ConnectionServiceWrapper service : services) {
-            ComponentName serviceName = service.getComponentName();
-            if (priorityComponents.contains(serviceName)) {
-                Log.i(this, "Moving connection service %s to top of list", serviceName);
-                mServiceComponentNames .add(0, serviceName);
-            } else {
-                mServiceComponentNames.add(serviceName);
-            }
-        }
-
-        adjustComponentNamesForEmergency();
-
-        mServiceComponentNameIterator = mServiceComponentNames.iterator();
-        attemptNextConnectionService();
-    }
-
-    /**
-     * Attempts to place the call using the connection service specified by the next connection
-     * service component name of mServiceComponentNameIterator.
-     */
-    private void attemptNextConnectionService() {
-        Log.v(this, "attemptNextConnectionService, mIsAborted: %b", mIsAborted);
-        if (mIsAborted) {
-            return;
-        }
-
-        if (mServiceComponentNameIterator != null && mServiceComponentNameIterator.hasNext()) {
-            ComponentName component = mServiceComponentNameIterator.next();
-            final ConnectionServiceWrapper service =
-                    mConnectionServiceRepository.getService(component);
-
-            if (service == null || mAttemptedServices.contains(service)) {
-                // The next connection service is either null or has already been attempted, fast
-                // forward to the next.
-                attemptNextConnectionService();
-            } else {
-                mAttemptedServices.add(service);
-                mCall.setConnectionService(service);
-
-                // Increment the associated call count until we get a result. This prevents the call
-                // service from unbinding while we are using it.
-                service.incrementAssociatedCallCount();
-
-                Log.i(this, "Attempting to call from %s", service.getComponentName());
-                service.call(mCall, new OutgoingCallResponse() {
-                    @Override
-                    public void onOutgoingCallSuccess() {
-                        handleSuccessfulCallAttempt(service);
-                        service.decrementAssociatedCallCount();
-                    }
-
-                    @Override
-                    public void onOutgoingCallFailure(int code, String msg) {
-                        handleFailedCallAttempt(code, msg);
-                        service.decrementAssociatedCallCount();
-                    }
-
-                    @Override
-                    public void onOutgoingCallCancel() {
-                        abort();
-                        service.decrementAssociatedCallCount();
-                    }
-                });
-            }
-        } else {
-            Log.v(this, "attemptNextConnectionService, no more services, failing");
-            mServiceComponentNameIterator = null;
-            mCall.clearConnectionService();
-            sendResult(false, mLastErrorCode, mLastErrorMsg);
-        }
-    }
-
-    private void sendResult(boolean wasCallPlaced, int errorCode, String errorMsg) {
-        if (mResultCallback != null) {
-            if (mIsAborted) {
-                mResultCallback.onOutgoingCallCancel();
-            } else if (wasCallPlaced) {
-                mResultCallback.onOutgoingCallSuccess();
-            } else {
-                mResultCallback.onOutgoingCallFailure(errorCode, errorMsg);
-            }
-            mResultCallback = null;
-        } else {
-            Log.wtf(this, "Attempting to return outgoing result twice for call %s", mCall);
-        }
-    }
-
-    // If we are possibly attempting to call a local emergency number, ensure that the
-    // plain PSTN connection service, if it exists, is attempted first.
-    private void adjustComponentNamesForEmergency()  {
-        for (int i = 0; i < mServiceComponentNames.size(); i++) {
-            if (shouldProcessAsEmergency(mCall.getHandle())) {
-                if (TelephonyUtil.isPstnComponentName(mServiceComponentNames.get(i))) {
-                    mServiceComponentNames.add(0, mServiceComponentNames.remove(i));
-                    return;
-                }
-            }
-        }
-    }
-
-    private boolean shouldProcessAsEmergency(Uri handle) {
-        return PhoneNumberUtils.isPotentialLocalEmergencyNumber(
-                TelecommApp.getInstance(), handle.getSchemeSpecificPart());
-    }
-}
diff --git a/src/com/android/telecomm/Switchboard.java b/src/com/android/telecomm/Switchboard.java
deleted file mode 100644
index 2dfcfea..0000000
--- a/src/com/android/telecomm/Switchboard.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright 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.telecomm;
-
-import android.content.ComponentName;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.telecomm.TelecommConstants;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableCollection;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Sets;
-
-import java.util.Collection;
-import java.util.Set;
-
-/**
- * Switchboard is responsible for gathering the {@link ConnectionServiceWrapper}s through
- *       which to place outgoing calls
- */
-final class Switchboard {
-    private final static Switchboard sInstance = new Switchboard();
-
-    /** Used to retrieve incoming call details. */
-    private final IncomingCallsManager mIncomingCallsManager;
-
-    private final ConnectionServiceRepository mConnectionServiceRepository;
-
-    /** Singleton accessor. */
-    static Switchboard getInstance() {
-        return sInstance;
-    }
-
-    /**
-     * Persists the specified parameters and initializes Switchboard.
-     */
-    private Switchboard() {
-        ThreadUtil.checkOnMainThread();
-
-        mIncomingCallsManager = new IncomingCallsManager();
-        mConnectionServiceRepository =
-                new ConnectionServiceRepository(mIncomingCallsManager);
-    }
-
-    ConnectionServiceRepository getConnectionServiceRepository() {
-        return mConnectionServiceRepository;
-    }
-
-    /**
-     * Retrieves details about the incoming call through the incoming call manager.
-     *
-     * @param call The call object.
-     */
-    void retrieveIncomingCall(Call call) {
-        Log.d(this, "retrieveIncomingCall");
-        ConnectionServiceWrapper service = mConnectionServiceRepository.getService(
-                call.getPhoneAccount().getComponentName());
-        call.setConnectionService(service);
-        mIncomingCallsManager.retrieveIncomingCall(call);
-    }
-}
