diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
index 2be3355..3d4771b 100644
--- a/src/com/android/telecomm/Call.java
+++ b/src/com/android/telecomm/Call.java
@@ -23,9 +23,9 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.provider.ContactsContract.Contacts;
-import android.telecomm.CallInfo;
 import android.telecomm.CallServiceDescriptor;
 import android.telecomm.CallState;
+import android.telecomm.ConnectionRequest;
 import android.telecomm.GatewayInfo;
 import android.telecomm.PhoneAccount;
 import android.telecomm.Response;
@@ -63,7 +63,7 @@
         void onSuccessfulOutgoingCall(Call call);
         void onFailedOutgoingCall(Call call, int errorCode, String errorMsg);
         void onCancelledOutgoingCall(Call call);
-        void onSuccessfulIncomingCall(Call call, CallInfo callInfo);
+        void onSuccessfulIncomingCall(Call call);
         void onFailedIncomingCall(Call call);
         void onRequestingRingback(Call call, boolean requestingRingback);
         void onPostDialWait(Call call, String remaining);
@@ -86,7 +86,7 @@
         @Override
         public void onCancelledOutgoingCall(Call call) {}
         @Override
-        public void onSuccessfulIncomingCall(Call call, CallInfo callInfo) {}
+        public void onSuccessfulIncomingCall(Call call) {}
         @Override
         public void onFailedIncomingCall(Call call) {}
         @Override
@@ -166,15 +166,9 @@
     private Uri mHandle;
 
     /**
-     * The call service which is attempted or already connecting this call.
+     * The connection service which is attempted or already connecting this call.
      */
-    private CallServiceWrapper mCallService;
-
-    /**
-     * The set of call services that were attempted in the process of placing/switching this call
-     * but turned out unsuitable.  Only used in the context of call switching.
-     */
-    private Set<CallServiceWrapper> mIncompatibleCallServices;
+    private ConnectionServiceWrapper mConnectionService;
 
     private boolean mIsEmergencyCall;
 
@@ -187,11 +181,11 @@
     private int mDisconnectCause = DisconnectCause.NOT_VALID;
 
     /**
-     * Additional disconnect information provided by the call service.
+     * Additional disconnect information provided by the connection service.
      */
     private String mDisconnectMessage;
 
-    /** Info used by the call services. */
+    /** Info used by the connection services. */
     private Bundle mExtras = Bundle.EMPTY;
 
     /** Set of listeners on this call. */
@@ -211,8 +205,8 @@
     /** Whether this call is requesting that Telecomm play the ringback tone on its behalf. */
     private boolean mRequestingRingback = false;
 
-    /** Incoming call-info to use when direct-to-voicemail query finishes. */
-    private CallInfo mPendingDirectToVoicemailCallInfo;
+    /** Whether direct-to-voicemail query is pending. */
+    private boolean mDirectToVoicemailQueryPending;
 
     private boolean mIsConferenceCapable = false;
 
@@ -272,8 +266,8 @@
     /** {@inheritDoc} */
     @Override public String toString() {
         String component = null;
-        if (mCallService != null && mCallService.getComponentName() != null) {
-            component = mCallService.getComponentName().flattenToShortString();
+        if (mConnectionService != null && mConnectionService.getComponentName() != null) {
+            component = mConnectionService.getComponentName().flattenToShortString();
         }
         return String.format(Locale.US, "[%s, %s, %s]", mState, component, Log.piiHandle(mHandle));
     }
@@ -435,48 +429,36 @@
         return mChildCalls;
     }
 
-    CallServiceWrapper getCallService() {
-        return mCallService;
+    ConnectionServiceWrapper getConnectionService() {
+        return mConnectionService;
     }
 
-    void setCallService(CallServiceWrapper callService) {
-        setCallService(callService, null);
+    void setConnectionService(ConnectionServiceWrapper service) {
+        Preconditions.checkNotNull(service);
+
+        clearConnectionService();
+
+        service.incrementAssociatedCallCount();
+        mConnectionService = service;
+        mConnectionService.addCall(this);
     }
 
     /**
-     * Changes the call service this call is associated with. If callToReplace is non-null then this
-     * call takes its place within the call service.
+     * Clears the associated connection service.
      */
-    void setCallService(CallServiceWrapper callService, Call callToReplace) {
-        Preconditions.checkNotNull(callService);
-
-        clearCallService();
-
-        callService.incrementAssociatedCallCount();
-        mCallService = callService;
-        if (callToReplace == null) {
-            mCallService.addCall(this);
-        } else {
-            mCallService.replaceCall(this, callToReplace);
-        }
-    }
-
-    /**
-     * Clears the associated call service.
-     */
-    void clearCallService() {
-        if (mCallService != null) {
-            CallServiceWrapper callServiceTemp = mCallService;
-            mCallService = null;
-            callServiceTemp.removeCall(this);
+    void clearConnectionService() {
+        if (mConnectionService != null) {
+            ConnectionServiceWrapper serviceTemp = mConnectionService;
+            mConnectionService = null;
+            serviceTemp.removeCall(this);
 
             // Decrementing the count can cause the service to unbind, which itself can trigger the
             // service-death code.  Since the service death code tries to clean up any associated
             // calls, we need to make sure to remove that information (e.g., removeCall()) before
             // we decrement. Technically, invoking removeCall() prior to decrementing is all that is
-            // necessary, but cleaning up mCallService prior to triggering an unbind is good to do.
-            // If you change this, make sure to update {@link clearCallServiceSelector} as well.
-            decrementAssociatedCallCount(callServiceTemp);
+            // necessary, but cleaning up mConnectionService prior to triggering an unbind is good
+            // to do.
+            decrementAssociatedCallCount(serviceTemp);
         }
     }
 
@@ -498,17 +480,15 @@
      * the result of the query will determine if the call is rejected or passed through to the
      * in-call UI.
      */
-    void handleVerifiedIncoming(CallInfo callInfo) {
-        Preconditions.checkState(callInfo.getState() == CallState.RINGING);
-
-        // We do not handle incoming calls immediately when they are verified by the call service.
-        // We allow the caller-info-query code to execute first so that we can read the
+    void handleVerifiedIncoming(ConnectionRequest request) {
+        // 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.
-        mPendingDirectToVoicemailCallInfo = callInfo;
+        mDirectToVoicemailQueryPending = true;
 
         // Setting the handle triggers the caller info lookup code.
-        setHandle(callInfo.getHandle());
+        setHandle(request.getHandle());
 
         // Timeout the direct-to-voicemail lookup execution so that we dont wait too long before
         // showing the user the incoming call screen.
@@ -521,7 +501,7 @@
     }
 
     void processDirectToVoicemail() {
-        if (mPendingDirectToVoicemailCallInfo != null) {
+        if (mDirectToVoicemailQueryPending) {
             if (mCallerInfo != null && mCallerInfo.shouldSendToVoicemail) {
                 Log.i(this, "Directing call to voicemail: %s.", this);
                 // TODO(santoscordon): Once we move State handling from CallsManager to Call, we
@@ -534,16 +514,16 @@
 
                 // TODO(santoscordon): Replace this with state transition to RINGING.
                 for (Listener l : mListeners) {
-                    l.onSuccessfulIncomingCall(this, mPendingDirectToVoicemailCallInfo);
+                    l.onSuccessfulIncomingCall(this);
                 }
             }
 
-            mPendingDirectToVoicemailCallInfo = null;
+            mDirectToVoicemailQueryPending = false;
         }
     }
 
     void handleFailedIncoming() {
-        clearCallService();
+        clearConnectionService();
 
         // TODO: Needs more specific disconnect error for this case.
         setDisconnectCause(DisconnectCause.ERROR_UNSPECIFIED, null);
@@ -557,7 +537,7 @@
 
     /**
      * Starts the outgoing call sequence.  Upon completion, there should exist an active connection
-     * through a call service (or the call will have failed).
+     * through a connection service (or the call will have failed).
      */
     void startOutgoing() {
         Preconditions.checkState(mOutgoingCallProcessor == null);
@@ -583,7 +563,7 @@
             l.onFailedOutgoingCall(this, code, msg);
         }
 
-        clearCallService();
+        clearConnectionService();
         mOutgoingCallProcessor = null;
     }
 
@@ -594,45 +574,19 @@
             l.onCancelledOutgoingCall(this);
         }
 
-        clearCallService();
+        clearConnectionService();
         mOutgoingCallProcessor = null;
     }
 
     /**
-     * Adds the specified call service to the list of incompatible services.  The set is used when
-     * attempting to switch a phone call between call services such that incompatible services can
-     * be avoided.
-     *
-     * @param callService The incompatible call service.
-     */
-    void addIncompatibleCallService(CallServiceWrapper callService) {
-        if (mIncompatibleCallServices == null) {
-            mIncompatibleCallServices = Sets.newHashSet();
-        }
-        mIncompatibleCallServices.add(callService);
-    }
-
-    /**
-     * Checks whether or not the specified callService was identified as incompatible in the
-     * context of this call.
-     *
-     * @param callService The call service to evaluate.
-     * @return True upon incompatible call services and false otherwise.
-     */
-    boolean isIncompatibleCallService(CallServiceWrapper callService) {
-        return mIncompatibleCallServices != null &&
-                mIncompatibleCallServices.contains(callService);
-    }
-
-    /**
      * Plays the specified DTMF tone.
      */
     void playDtmfTone(char digit) {
-        if (mCallService == null) {
-            Log.w(this, "playDtmfTone() request on a call without a call service.");
+        if (mConnectionService == null) {
+            Log.w(this, "playDtmfTone() request on a call without a connection service.");
         } else {
-            Log.i(this, "Send playDtmfTone to call service for call %s", this);
-            mCallService.playDtmfTone(this, digit);
+            Log.i(this, "Send playDtmfTone to connection service for call %s", this);
+            mConnectionService.playDtmfTone(this, digit);
         }
     }
 
@@ -640,29 +594,29 @@
      * Stops playing any currently playing DTMF tone.
      */
     void stopDtmfTone() {
-        if (mCallService == null) {
-            Log.w(this, "stopDtmfTone() request on a call without a call service.");
+        if (mConnectionService == null) {
+            Log.w(this, "stopDtmfTone() request on a call without a connectino service.");
         } else {
-            Log.i(this, "Send stopDtmfTone to call service for call %s", this);
-            mCallService.stopDtmfTone(this);
+            Log.i(this, "Send stopDtmfTone to connection service for call %s", this);
+            mConnectionService.stopDtmfTone(this);
         }
     }
 
     /**
-     * Attempts to disconnect the call through the call service.
+     * Attempts to disconnect the call through the connection service.
      */
     void disconnect() {
         if (mState == CallState.NEW) {
             Log.v(this, "Aborting call %s", this);
             abort();
         } else if (mState != CallState.ABORTED && mState != CallState.DISCONNECTED) {
-            Preconditions.checkNotNull(mCallService);
+            Preconditions.checkNotNull(mConnectionService);
 
-            Log.i(this, "Send disconnect to call service for call: %s", this);
-            // The call isn't officially disconnected until the call service confirms that the call
-            // was actually disconnected. Only then is the association between call and call service
-            // severed, see {@link CallsManager#markCallAsDisconnected}.
-            mCallService.disconnect(this);
+            Log.i(this, "Send disconnect to connection service for call: %s", this);
+            // The call isn't officially disconnected until the connection service confirms that the
+            // call was actually disconnected. Only then is the association between call and
+            // connection service severed, see {@link CallsManager#markCallAsDisconnected}.
+            mConnectionService.disconnect(this);
         }
     }
 
@@ -676,16 +630,16 @@
      * Answers the call if it is ringing.
      */
     void answer() {
-        Preconditions.checkNotNull(mCallService);
+        Preconditions.checkNotNull(mConnectionService);
 
         // Check to verify that the call is still in the ringing state. A call can change states
         // between the time the user hits 'answer' and Telecomm receives the command.
         if (isRinging("answer")) {
-            // At this point, we are asking the call service to answer but we don't assume that
-            // it will work. Instead, we wait until confirmation from the call service that the
-            // call is in a non-RINGING state before changing the UI. See
-            // {@link CallServiceAdapter#setActive} and other set* methods.
-            mCallService.answer(this);
+            // At this point, we are asking the connection service to answer but we don't assume
+            // that it will work. Instead, we wait until confirmation from the connectino service
+            // that the call is in a non-RINGING state before changing the UI. See
+            // {@link ConnectionServiceAdapter#setActive} and other set* methods.
+            mConnectionService.answer(this);
         }
     }
 
@@ -696,12 +650,12 @@
      * @param textMessage An optional text message to send as part of the rejection.
      */
     void reject(boolean rejectWithMessage, String textMessage) {
-        Preconditions.checkNotNull(mCallService);
+        Preconditions.checkNotNull(mConnectionService);
 
         // Check to verify that the call is still in the ringing state. A call can change states
         // between the time the user hits 'reject' and Telecomm receives the command.
         if (isRinging("reject")) {
-            mCallService.reject(this);
+            mConnectionService.reject(this);
         }
     }
 
@@ -709,10 +663,10 @@
      * Puts the call on hold if it is currently active.
      */
     void hold() {
-        Preconditions.checkNotNull(mCallService);
+        Preconditions.checkNotNull(mConnectionService);
 
         if (mState == CallState.ACTIVE) {
-            mCallService.hold(this);
+            mConnectionService.hold(this);
         }
     }
 
@@ -720,37 +674,13 @@
      * Releases the call from hold if it is currently active.
      */
     void unhold() {
-        Preconditions.checkNotNull(mCallService);
+        Preconditions.checkNotNull(mConnectionService);
 
         if (mState == CallState.ON_HOLD) {
-            mCallService.unhold(this);
+            mConnectionService.unhold(this);
         }
     }
 
-    /**
-     * @return An object containing read-only information about this call.
-     */
-    CallInfo toCallInfo(String callId) {
-        CallServiceDescriptor descriptor = null;
-        if (mCallService != null) {
-            descriptor = mCallService.getDescriptor();
-        }
-        Bundle extras = mExtras;
-        if (mGatewayInfo != null && mGatewayInfo.getGatewayProviderPackageName() != null &&
-                mGatewayInfo.getOriginalHandle() != null) {
-            extras = (Bundle) mExtras.clone();
-            extras.putString(
-                    NewOutgoingCallIntentBroadcaster.EXTRA_GATEWAY_PROVIDER_PACKAGE,
-                    mGatewayInfo.getGatewayProviderPackageName());
-            extras.putParcelable(
-                    NewOutgoingCallIntentBroadcaster.EXTRA_GATEWAY_ORIGINAL_URI,
-                    mGatewayInfo.getOriginalHandle());
-
-        }
-        return new CallInfo(callId, mState, mHandle, mGatewayInfo, mAccount,
-                extras, descriptor);
-    }
-
     /** Checks if this is a live call or not. */
     boolean isAlive() {
         switch (mState) {
@@ -794,25 +724,25 @@
     }
 
     void postDialContinue(boolean proceed) {
-        getCallService().onPostDialContinue(this, proceed);
+        mConnectionService.onPostDialContinue(this, proceed);
     }
 
     void phoneAccountClicked() {
-        getCallService().onPhoneAccountClicked(this);
+        mConnectionService.onPhoneAccountClicked(this);
     }
 
     void conferenceInto(Call conferenceCall) {
-        if (mCallService == null) {
-            Log.w(this, "conference requested on a call without a call service.");
+        if (mConnectionService == null) {
+            Log.w(this, "conference requested on a call without a connection service.");
         } else {
-            mCallService.conference(conferenceCall, this);
+            mConnectionService.conference(conferenceCall, this);
         }
     }
 
     void expireConference() {
         // The conference call expired before we got a confirmation of the conference from the
-        // call service...so start shutting down.
-        clearCallService();
+        // connection service...so start shutting down.
+        clearConnectionService();
         for (Listener l : mListeners) {
             l.onExpiredConferenceCall(this);
         }
diff --git a/src/com/android/telecomm/CallActivity.java b/src/com/android/telecomm/CallActivity.java
index 2868216..0e66d32 100644
--- a/src/com/android/telecomm/CallActivity.java
+++ b/src/com/android/telecomm/CallActivity.java
@@ -97,8 +97,8 @@
     }
 
     /**
-     * Processes INCOMING_CALL intents. Grabs the call service informations from the intent extra
-     * and forwards that to the CallsManager to start the incoming call flow.
+     * Processes INCOMING_CALL intents. Grabs the connection service informations from the intent
+     * extra and forwards that to the CallsManager to start the incoming call flow.
      *
      * @param intent The incoming call intent.
      */
@@ -115,7 +115,7 @@
             clientExtras = intent.getBundleExtra(TelecommConstants.EXTRA_INCOMING_CALL_EXTRAS);
         }
 
-        Log.d(this, "Processing incoming call from call service [%s]", descriptor);
+        Log.d(this, "Processing incoming call from connection service [%s]", descriptor);
         mCallsManager.processIncomingCallIntent(descriptor, clientExtras);
     }
 }
diff --git a/src/com/android/telecomm/CallAudioManager.java b/src/com/android/telecomm/CallAudioManager.java
index 865e3ca..35de0cc 100644
--- a/src/com/android/telecomm/CallAudioManager.java
+++ b/src/com/android/telecomm/CallAudioManager.java
@@ -396,8 +396,8 @@
 
     private void updateAudioForForegroundCall() {
         Call call = CallsManager.getInstance().getForegroundCall();
-        if (call != null && call.getCallService() != null) {
-            call.getCallService().onAudioStateChanged(call, mAudioState);
+        if (call != null && call.getConnectionService() != null) {
+            call.getConnectionService().onAudioStateChanged(call, mAudioState);
         }
     }
 
diff --git a/src/com/android/telecomm/CallIdMapper.java b/src/com/android/telecomm/CallIdMapper.java
index 9f803c6..2366343 100644
--- a/src/com/android/telecomm/CallIdMapper.java
+++ b/src/com/android/telecomm/CallIdMapper.java
@@ -85,8 +85,8 @@
     void checkValidCallId(String callId) {
         // Note, no need for thread check, this method is thread safe.
         if (!isValidCallId(callId)) {
-            // TODO(santoscordon): Re-enable this once we stop getting updates to CallServiceWrapper
-            // for remote connections.
+            // TODO(santoscordon): Re-enable this once we stop getting updates to
+            // ConnectionServiceWrapper for remote connections.
             //throw new IllegalArgumentException(
             //        "Invalid call ID for " + mCallIdPrefix + ": " + callId);
         }
diff --git a/src/com/android/telecomm/CallServiceRepository.java b/src/com/android/telecomm/CallServiceRepository.java
index af4098c..e1feb0f 100644
--- a/src/com/android/telecomm/CallServiceRepository.java
+++ b/src/com/android/telecomm/CallServiceRepository.java
@@ -33,19 +33,19 @@
 import java.util.Set;
 
 /**
- * Searches for and returns call services.
+ * Searches for and returns connection services.
  */
-class CallServiceRepository extends BaseRepository<CallServiceWrapper> {
+class CallServiceRepository extends BaseRepository<ConnectionServiceWrapper> {
     /**
      * The representation of a single lookup. Maintains lookup state and invokes the "complete"
      * callback when finished.
      */
     private final class CallServiceLookup {
         final Set<ComponentName> mOutstandingProviders = Sets.newHashSet();
-        final Set<CallServiceWrapper> mServices = Sets.newHashSet();
-        final LookupCallback<CallServiceWrapper> mCallback;
+        final Set<ConnectionServiceWrapper> mServices = Sets.newHashSet();
+        final LookupCallback<ConnectionServiceWrapper> mCallback;
 
-        CallServiceLookup(LookupCallback<CallServiceWrapper> callback) {
+        CallServiceLookup(LookupCallback<ConnectionServiceWrapper> callback) {
             mCallback = callback;
         }
 
@@ -141,7 +141,8 @@
             ComponentName providerName = provider.getComponentName();
             if (mOutstandingProviders.remove(providerName)) {
                 if (callServiceDescriptors != null) {
-                    // Add all the call services from this provider to the call-service cache.
+                    // Add all the connection services from this provider to the connection-service
+                    // cache.
                     for (CallServiceDescriptor descriptor : callServiceDescriptors) {
                         mServices.add(getService(descriptor.getServiceComponent(), descriptor));
                     }
@@ -151,7 +152,7 @@
                     finishLookup();
                 }
             } else {
-                Log.i(this, "Unexpected call services from %s in lookup.", providerName);
+                Log.i(this, "Unexpected connection services from %s in lookup.", providerName);
             }
         }
 
@@ -169,23 +170,24 @@
     }
 
     /**
-     * Returns the call service implementation specified by the descriptor.
+     * Returns the connection service implementation specified by the descriptor.
      *
      * @param descriptor The call-service descriptor.
      */
-    CallServiceWrapper getService(CallServiceDescriptor descriptor) {
+    ConnectionServiceWrapper getService(CallServiceDescriptor descriptor) {
         return getService(descriptor.getServiceComponent(), descriptor);
     }
 
     /** {@inheritDoc} */
     @Override
-    protected void onLookupServices(LookupCallback<CallServiceWrapper> callback) {
+    protected void onLookupServices(LookupCallback<ConnectionServiceWrapper> callback) {
         new CallServiceLookup(callback).start();
     }
 
     @Override
-    protected CallServiceWrapper onCreateNewServiceWrapper(ComponentName componentName,
+    protected ConnectionServiceWrapper onCreateNewServiceWrapper(ComponentName componentName,
             Object param) {
-        return new CallServiceWrapper((CallServiceDescriptor) param, mIncomingCallsManager, this);
+        return new ConnectionServiceWrapper(
+                (CallServiceDescriptor) param, mIncomingCallsManager, this);
     }
 }
diff --git a/src/com/android/telecomm/CallServiceWrapper.java b/src/com/android/telecomm/CallServiceWrapper.java
deleted file mode 100644
index 1414e0a..0000000
--- a/src/com/android/telecomm/CallServiceWrapper.java
+++ /dev/null
@@ -1,878 +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.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.RemoteException;
-import android.telecomm.CallAudioState;
-import android.telecomm.CallInfo;
-import android.telecomm.CallService;
-import android.telecomm.CallServiceDescriptor;
-import android.telecomm.ConnectionRequest;
-import android.telecomm.TelecommConstants;
-import android.telephony.DisconnectCause;
-
-import com.android.internal.os.SomeArgs;
-
-import com.android.internal.telecomm.ICallService;
-import com.android.internal.telecomm.ICallServiceAdapter;
-import com.android.internal.telecomm.ICallServiceProvider;
-import com.android.internal.telecomm.ICallVideoProvider;
-import com.android.internal.telecomm.RemoteServiceCallback;
-import com.android.telecomm.BaseRepository.LookupCallback;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-
-import org.apache.http.conn.ClientConnectionRequest;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Wrapper for {@link ICallService}s, handles binding to {@link ICallService} and keeps track of
- * when the object can safely be unbound. Other classes should not use {@link ICallService} directly
- * and instead should use this class to invoke methods of {@link ICallService}.
- */
-final class CallServiceWrapper extends ServiceBinder<ICallService> {
-    private static final String TAG = CallServiceWrapper.class.getSimpleName();
-
-    private final class Adapter extends ICallServiceAdapter.Stub {
-        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_ON_POST_DIAL_WAIT = 11;
-        private static final int MSG_CAN_CONFERENCE = 12;
-        private static final int MSG_SET_IS_CONFERENCED = 13;
-        private static final int MSG_ADD_CONFERENCE_CALL = 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_FEATURES = 17;
-
-        private final Handler mHandler = new Handler() {
-            @Override
-            public void handleMessage(Message msg) {
-                Call call;
-                switch (msg.what) {
-                    case MSG_NOTIFY_INCOMING_CALL:
-                        CallInfo clientCallInfo = (CallInfo) msg.obj;
-                        call = mCallIdMapper.getCall(clientCallInfo.getId());
-                        if (call != null && mPendingIncomingCalls.remove(call) &&
-                                call.isIncoming()) {
-                            CallInfo callInfo = new CallInfo(null, clientCallInfo.getState(),
-                                    clientCallInfo.getHandle());
-                            mIncomingCallsManager.handleSuccessfulIncomingCall(call, callInfo);
-                        } else {
-                            // TODO(santoscordon): For this an the other commented logging, we need
-                            // to reenable it.  At the moment all CallServiceAdapters 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, clientCallInfo.getId());
-                        }
-                        break;
-                    case MSG_HANDLE_SUCCESSFUL_OUTGOING_CALL: {
-                        String callId = (String) msg.obj;
-                        if (mPendingOutgoingCalls.containsKey(callId)) {
-                            mPendingOutgoingCalls.remove(callId).onOutgoingCallSuccess();
-                        } else {
-                            //Log.w(this, "handleSuccessfulOutgoingCall, unknown call: %s", callId);
-                        }
-                        break;
-                    }
-                    case MSG_HANDLE_FAILED_OUTGOING_CALL: {
-                        SomeArgs args = (SomeArgs) msg.obj;
-                        try {
-                            String callId = (String) 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(callId)) {
-                                mPendingOutgoingCalls.remove(callId).onOutgoingCallFailure(
-                                        statusCode, statusMsg);
-                                mCallIdMapper.removeCall(callId);
-                            } else {
-                                //Log.w(this, "handleFailedOutgoingCall, unknown call: %s", callId);
-                            }
-                        } finally {
-                            args.recycle();
-                        }
-                        break;
-                    }
-                    case MSG_CANCEL_OUTGOING_CALL: {
-                        String callId = (String) msg.obj;
-                        if (mPendingOutgoingCalls.containsKey(callId)) {
-                            mPendingOutgoingCalls.remove(callId).onOutgoingCallCancel();
-                        } else {
-                            //Log.w(this, "cancelOutgoingCall, unknown call: %s", callId);
-                        }
-                        break;
-                    }
-                    case MSG_SET_ACTIVE:
-                        call = mCallIdMapper.getCall(msg.obj);
-                        if (call != null) {
-                            mCallsManager.markCallAsActive(call);
-                        } else {
-                            //Log.w(this, "setActive, unknown call id: %s", msg.obj);
-                        }
-                        break;
-                    case MSG_SET_RINGING:
-                        call = mCallIdMapper.getCall(msg.obj);
-                        if (call != null) {
-                            mCallsManager.markCallAsRinging(call);
-                        } else {
-                            //Log.w(this, "setRinging, unknown call id: %s", msg.obj);
-                        }
-                        break;
-                    case MSG_SET_DIALING:
-                        call = mCallIdMapper.getCall(msg.obj);
-                        if (call != null) {
-                            mCallsManager.markCallAsDialing(call);
-                        } else {
-                            //Log.w(this, "setDialing, unknown call id: %s", msg.obj);
-                        }
-                        break;
-                    case MSG_SET_DISCONNECTED: {
-                        SomeArgs args = (SomeArgs) msg.obj;
-                        try {
-                            call = mCallIdMapper.getCall(args.arg1);
-                            String disconnectMessage = (String) args.arg2;
-                            int disconnectCause = args.argi1;
-                            if (call != null) {
-                                mCallsManager.markCallAsDisconnected(call, disconnectCause,
-                                        disconnectMessage);
-                            } else {
-                                //Log.w(this, "setDisconnected, unknown call id: %s", args.arg1);
-                            }
-                        } finally {
-                            args.recycle();
-                        }
-                        break;
-                    }
-                    case MSG_SET_ON_HOLD:
-                        call = mCallIdMapper.getCall(msg.obj);
-                        if (call != null) {
-                            mCallsManager.markCallAsOnHold(call);
-                        } else {
-                            //Log.w(this, "setOnHold, unknown call id: %s", msg.obj);
-                        }
-                        break;
-                    case MSG_SET_REQUESTING_RINGBACK: {
-                        SomeArgs args = (SomeArgs) msg.obj;
-                        try {
-                            call = mCallIdMapper.getCall(args.arg1);
-                            boolean ringback = (boolean) args.arg2;
-                            if (call != null) {
-                                call.setRequestingRingback(ringback);
-                            } else {
-                                //Log.w(this, "setRingback, unknown call id: %s", args.arg1);
-                            }
-                        } finally {
-                            args.recycle();
-                        }
-                        break;
-                    }
-                    case MSG_ON_POST_DIAL_WAIT: {
-                        SomeArgs args = (SomeArgs) msg.obj;
-                        try {
-                            call = mCallIdMapper.getCall(args.arg1);
-                            if (call != null) {
-                                String remaining = (String) args.arg2;
-                                call.onPostDialWait(remaining);
-                            } else {
-                                //Log.w(this, "onPostDialWait, unknown call id: %s", args.arg1);
-                            }
-                        } finally {
-                            args.recycle();
-                        }
-                        break;
-                    }
-                    case MSG_CAN_CONFERENCE: {
-                        call = mCallIdMapper.getCall(msg.obj);
-                        if (call != null) {
-                            call.setIsConferenceCapable(msg.arg1 == 1);
-                        } else {
-                            //Log.w(CallServiceWrapper.this, "canConference, unknown call id: %s",
-                            //        msg.obj);
-                        }
-                        break;
-                    }
-                    case MSG_SET_IS_CONFERENCED: {
-                        SomeArgs args = (SomeArgs) msg.obj;
-                        try {
-                            Call childCall = mCallIdMapper.getCall(args.arg1);
-                            if (childCall != null) {
-                                String conferenceCallId = (String) args.arg2;
-                                if (conferenceCallId == null) {
-                                    childCall.setParentCall(null);
-                                } else {
-                                    Call conferenceCall = mCallIdMapper.getCall(conferenceCallId);
-                                    if (conferenceCall != null &&
-                                            !mPendingConferenceCalls.contains(conferenceCall)) {
-                                        childCall.setParentCall(conferenceCall);
-                                    } else {
-                                        //Log.w(this, "setIsConferenced, unknown conference id %s",
-                                        //        conferenceCallId);
-                                    }
-                                }
-                            } else {
-                                //Log.w(this, "setIsConferenced, unknown call id: %s", args.arg1);
-                            }
-                        } finally {
-                            args.recycle();
-                        }
-                        break;
-                    }
-                    case MSG_ADD_CONFERENCE_CALL: {
-                        SomeArgs args = (SomeArgs) msg.obj;
-                        try {
-                            String callId = (String) args.arg1;
-                            Call conferenceCall = mCallIdMapper.getCall(callId);
-                            if (mPendingConferenceCalls.remove(conferenceCall)) {
-                                Log.v(this, "confirming conf call %s", conferenceCall);
-                                conferenceCall.confirmConference();
-                            } else {
-                                //Log.w(this, "addConference, unknown call id: %s", callId);
-                            }
-                        } finally {
-                            args.recycle();
-                        }
-                        break;
-                    }
-                    case MSG_QUERY_REMOTE_CALL_SERVICES: {
-                        CallServiceWrapper.this.queryRemoteConnectionServices(
-                                (RemoteServiceCallback) msg.obj);
-                        break;
-                    }
-                    case MSG_SET_CALL_VIDEO_PROVIDER: {
-                        SomeArgs args = (SomeArgs) msg.obj;
-                        try {
-                            call = mCallIdMapper.getCall(args.arg1);
-                            ICallVideoProvider callVideoProvider = (ICallVideoProvider) args.arg2;
-                            if (call != null) {
-                                call.setCallVideoProvider(callVideoProvider);
-                            }
-                        } finally {
-                            args.recycle();
-                        }
-                        break;
-                    }
-                    case MSG_SET_FEATURES: {
-                        SomeArgs args = (SomeArgs) msg.obj;
-                        try {
-                            call = mCallIdMapper.getCall(args.arg1);
-                            int features = (int) args.arg2;
-                            if (call != null) {
-                                call.setFeatures(features);
-                            }
-                        } finally {
-                            args.recycle();
-                        }
-                        break;
-                    }
-                }
-            }
-        };
-
-        /** {@inheritDoc} */
-        @Override
-        public void notifyIncomingCall(CallInfo callInfo) {
-            logIncoming("notifyIncomingCall %s", callInfo);
-            mCallIdMapper.checkValidCallId(callInfo.getId());
-            mHandler.obtainMessage(MSG_NOTIFY_INCOMING_CALL, callInfo).sendToTarget();
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void handleSuccessfulOutgoingCall(String callId) {
-            logIncoming("handleSuccessfulOutgoingCall %s", callId);
-            mCallIdMapper.checkValidCallId(callId);
-            mHandler.obtainMessage(MSG_HANDLE_SUCCESSFUL_OUTGOING_CALL, callId).sendToTarget();
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void handleFailedOutgoingCall(
-                ConnectionRequest request,
-                int errorCode,
-                String errorMsg) {
-            logIncoming("handleFailedOutgoingCall %s %d %s", request, errorCode, errorMsg);
-            mCallIdMapper.checkValidCallId(request.getCallId());
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = request.getCallId();
-            args.argi1 = errorCode;
-            args.arg2 = errorMsg;
-            mHandler.obtainMessage(MSG_HANDLE_FAILED_OUTGOING_CALL, args).sendToTarget();
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void cancelOutgoingCall(String callId) {
-            logIncoming("cancelOutgoingCall %s", callId);
-            mCallIdMapper.checkValidCallId(callId);
-            mHandler.obtainMessage(MSG_CANCEL_OUTGOING_CALL, callId).sendToTarget();
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void setActive(String callId) {
-            logIncoming("setActive %s", callId);
-            mCallIdMapper.checkValidCallId(callId);
-            mHandler.obtainMessage(MSG_SET_ACTIVE, callId).sendToTarget();
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void setRinging(String callId) {
-            logIncoming("setRinging %s", callId);
-            mCallIdMapper.checkValidCallId(callId);
-            mHandler.obtainMessage(MSG_SET_RINGING, callId).sendToTarget();
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void setCallVideoProvider(String callId, ICallVideoProvider callVideoProvider) {
-            logIncoming("setCallVideoProvider %s", callId);
-            mCallIdMapper.checkValidCallId(callId);
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = callId;
-            args.arg2 = callVideoProvider;
-            mHandler.obtainMessage(MSG_SET_CALL_VIDEO_PROVIDER, args).sendToTarget();
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void setDialing(String callId) {
-            logIncoming("setDialing %s", callId);
-            mCallIdMapper.checkValidCallId(callId);
-            mHandler.obtainMessage(MSG_SET_DIALING, callId).sendToTarget();
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void setDisconnected(
-                String callId, int disconnectCause, String disconnectMessage) {
-            logIncoming("setDisconnected %s %d %s", callId, disconnectCause, disconnectMessage);
-            mCallIdMapper.checkValidCallId(callId);
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = callId;
-            args.arg2 = disconnectMessage;
-            args.argi1 = disconnectCause;
-            mHandler.obtainMessage(MSG_SET_DISCONNECTED, args).sendToTarget();
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void setOnHold(String callId) {
-            logIncoming("setOnHold %s", callId);
-            mCallIdMapper.checkValidCallId(callId);
-            mHandler.obtainMessage(MSG_SET_ON_HOLD, callId).sendToTarget();
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void setRequestingRingback(String callId, boolean ringback) {
-            logIncoming("setRequestingRingback %s %b", callId, ringback);
-            mCallIdMapper.checkValidCallId(callId);
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = callId;
-            args.arg2 = ringback;
-            mHandler.obtainMessage(MSG_SET_REQUESTING_RINGBACK, args).sendToTarget();
-        }
-
-        /** ${inheritDoc} */
-        @Override
-        public void removeCall(String callId) {
-            logIncoming("removeCall %s", callId);
-        }
-
-        /** ${inheritDoc} */
-        @Override
-        public void setCanConference(String callId, boolean canConference) {
-            logIncoming("setCanConference %s %b", callId, canConference);
-            mHandler.obtainMessage(MSG_CAN_CONFERENCE, canConference ? 1 : 0, 0, callId)
-                    .sendToTarget();
-        }
-
-        /** ${inheritDoc} */
-        @Override
-        public void setIsConferenced(String callId, String conferenceCallId) {
-            logIncoming("setIsConferenced %s %s", callId, conferenceCallId);
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = callId;
-            args.arg2 = conferenceCallId;
-            mHandler.obtainMessage(MSG_SET_IS_CONFERENCED, args).sendToTarget();
-        }
-
-        /** ${InheritDoc} */
-        @Override
-        public void addConferenceCall(String callId, CallInfo callInfo) {
-            logIncoming("addConferenceCall %s %s", callId, callInfo);
-            mCallIdMapper.checkValidCallId(callId);
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = callId;
-            args.arg2 = callInfo;
-            mHandler.obtainMessage(MSG_ADD_CONFERENCE_CALL, args).sendToTarget();
-        }
-
-        @Override
-        public void onPostDialWait(String callId, String remaining) throws RemoteException {
-            logIncoming("onPostDialWait %s %s", callId, remaining);
-            mCallIdMapper.checkValidCallId(callId);
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = callId;
-            args.arg2 = remaining;
-            mHandler.obtainMessage(MSG_ON_POST_DIAL_WAIT, args).sendToTarget();
-        }
-
-        /** ${inheritDoc} */
-        @Override
-        public void queryRemoteConnectionServices(RemoteServiceCallback callback) {
-            logIncoming("queryRemoteCSs");
-            mHandler.obtainMessage(MSG_QUERY_REMOTE_CALL_SERVICES, callback).sendToTarget();
-        }
-
-        @Override
-        public void setFeatures(String callId, int features) {
-            logIncoming("setFeatures %s %d", callId, features);
-            mCallIdMapper.checkValidCallId(callId);
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = callId;
-            args.arg2 = features;
-            mHandler.obtainMessage(MSG_SET_FEATURES, args).sendToTarget();
-        }
-    }
-
-    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 CallServiceDescriptor mDescriptor;
-    private final CallIdMapper mCallIdMapper = new CallIdMapper("CallService");
-    private final IncomingCallsManager mIncomingCallsManager;
-    private final Map<String, OutgoingCallResponse> mPendingOutgoingCalls = new HashMap<>();
-    private final Handler mHandler = new Handler();
-
-    private Binder mBinder = new Binder();
-    private ICallService mServiceInterface;
-    private final CallServiceRepository mCallServiceRepository;
-
-    /**
-     * Creates a call-service for the specified descriptor.
-     *
-     * @param descriptor The call-service descriptor from
-     *            {@link ICallServiceProvider#lookupCallServices}.
-     * @param incomingCallsManager Manages the incoming call initialization flow.
-     * @param callServiceRepository Call service repository.
-     */
-    CallServiceWrapper(
-            CallServiceDescriptor descriptor,
-            IncomingCallsManager incomingCallsManager,
-            CallServiceRepository callServiceRepository) {
-        super(TelecommConstants.ACTION_CALL_SERVICE, descriptor.getServiceComponent());
-        mDescriptor = descriptor;
-        mIncomingCallsManager = incomingCallsManager;
-        mCallServiceRepository = callServiceRepository;
-    }
-
-    CallServiceDescriptor getDescriptor() {
-        return mDescriptor;
-    }
-
-    /** See {@link ICallService#setCallServiceAdapter}. */
-    private void setCallServiceAdapter(ICallServiceAdapter callServiceAdapter) {
-        if (isServiceValid("setCallServiceAdapter")) {
-            try {
-                logOutgoing("setCallServiceAdapter %s", callServiceAdapter);
-                mServiceInterface.setCallServiceAdapter(callServiceAdapter);
-            } catch (RemoteException e) {
-            }
-        }
-    }
-
-    /**
-     * Attempts to place the specified call, see {@link ICallService#call}. Returns the result
-     * asynchronously through the specified callback.
-     */
-    void call(final Call call, final OutgoingCallResponse callResponse) {
-        Log.d(this, "call(%s) via %s.", call, getComponentName());
-        BindCallback callback = new BindCallback() {
-            @Override
-            public void onSuccess() {
-                String callId = mCallIdMapper.getCallId(call);
-                mPendingOutgoingCalls.put(callId, callResponse);
-
-                try {
-                    CallInfo callInfo = call.toCallInfo(callId);
-                    logOutgoing("call %s", callInfo);
-                    mServiceInterface.call(callInfo);
-                } catch (RemoteException e) {
-                    Log.e(this, e, "Failure to call -- %s", getDescriptor());
-                    mPendingOutgoingCalls.remove(callId).onOutgoingCallFailure(
-                            DisconnectCause.ERROR_UNSPECIFIED, e.toString());
-                }
-            }
-
-            @Override
-            public void onFailure() {
-                Log.e(this, new Exception(), "Failure to call %s", getDescriptor());
-                callResponse.onOutgoingCallFailure(DisconnectCause.ERROR_UNSPECIFIED, null);
-            }
-        };
-
-        mBinder.bind(callback);
-    }
-
-    /** @see CallService#abort(String) */
-    void abort(Call call) {
-        // Clear out any pending outgoing call data
-        String callId = mCallIdMapper.getCallId(call);
-
-        // If still bound, tell the call service to abort.
-        if (isServiceValid("abort")) {
-            try {
-                logOutgoing("abort %s", callId);
-                mServiceInterface.abort(callId);
-            } catch (RemoteException e) {
-            }
-        }
-
-        removeCall(call);
-    }
-
-    /** @see CallService#hold(String) */
-    void hold(Call call) {
-        if (isServiceValid("hold")) {
-            try {
-                logOutgoing("hold %s", mCallIdMapper.getCallId(call));
-                mServiceInterface.hold(mCallIdMapper.getCallId(call));
-            } catch (RemoteException e) {
-            }
-        }
-    }
-
-    /** @see CallService#unhold(String) */
-    void unhold(Call call) {
-        if (isServiceValid("unhold")) {
-            try {
-                logOutgoing("unhold %s", mCallIdMapper.getCallId(call));
-                mServiceInterface.unhold(mCallIdMapper.getCallId(call));
-            } catch (RemoteException e) {
-            }
-        }
-    }
-
-    /** @see CallService#onAudioStateChanged(String,CallAudioState) */
-    void onAudioStateChanged(Call activeCall, CallAudioState audioState) {
-        if (isServiceValid("onAudioStateChanged")) {
-            try {
-                logOutgoing("onAudioStateChanged %s %s",
-                        mCallIdMapper.getCallId(activeCall), audioState);
-                mServiceInterface.onAudioStateChanged(mCallIdMapper.getCallId(activeCall),
-                        audioState);
-            } catch (RemoteException e) {
-            }
-        }
-    }
-
-    /**
-     * Starts retrieval of details for an incoming call. Details are returned through the
-     * call-service adapter using the specified call ID. Upon failure, the specified error callback
-     * is invoked. Can be invoked even when the call service is unbound. See
-     * {@link ICallService#setIncomingCallId}.
-     *
-     * @param call The call used for the incoming call.
-     * @param extras The {@link CallService}-provided extras which need to be sent back.
-     * @param errorCallback The callback to invoke upon failure.
-     */
-    void setIncomingCallId(final Call call, final Bundle extras, final Runnable errorCallback) {
-        Log.d(this, "setIncomingCall(%s) via %s.", call, getComponentName());
-        BindCallback callback = new BindCallback() {
-            @Override
-            public void onSuccess() {
-                if (isServiceValid("setIncomingCallId")) {
-                    mPendingIncomingCalls.add(call);
-                    try {
-                        logOutgoing("setIncomingCallId %s %s",
-                                mCallIdMapper.getCallId(call), extras);
-                        mServiceInterface.setIncomingCallId(mCallIdMapper.getCallId(call),
-                                extras);
-                    } catch (RemoteException e) {
-                    }
-                }
-            }
-
-            @Override
-            public void onFailure() {
-                errorCallback.run();
-            }
-        };
-
-        mBinder.bind(callback);
-    }
-
-    /** @see CallService#disconnect(String) */
-    void disconnect(Call call) {
-        if (isServiceValid("disconnect")) {
-            try {
-                logOutgoing("disconnect %s", mCallIdMapper.getCallId(call));
-                mServiceInterface.disconnect(mCallIdMapper.getCallId(call));
-            } catch (RemoteException e) {
-            }
-        }
-    }
-
-    /** @see CallService#answer(String) */
-    void answer(Call call) {
-        if (isServiceValid("answer")) {
-            try {
-                logOutgoing("answer %s", mCallIdMapper.getCallId(call));
-                mServiceInterface.answer(mCallIdMapper.getCallId(call));
-            } catch (RemoteException e) {
-            }
-        }
-    }
-
-    /** @see CallService#reject(String) */
-    void reject(Call call) {
-        if (isServiceValid("reject")) {
-            try {
-                logOutgoing("reject %s", mCallIdMapper.getCallId(call));
-                mServiceInterface.reject(mCallIdMapper.getCallId(call));
-            } catch (RemoteException e) {
-            }
-        }
-    }
-
-    /** @see CallService#playDtmfTone(String,char) */
-    void playDtmfTone(Call call, char digit) {
-        if (isServiceValid("playDtmfTone")) {
-            try {
-                logOutgoing("playDtmfTone %s %c", mCallIdMapper.getCallId(call), digit);
-                mServiceInterface.playDtmfTone(mCallIdMapper.getCallId(call), digit);
-            } catch (RemoteException e) {
-            }
-        }
-    }
-
-    /** @see CallService#stopDtmfTone(String) */
-    void stopDtmfTone(Call call) {
-        if (isServiceValid("stopDtmfTone")) {
-            try {
-                logOutgoing("stopDtmfTone %s", mCallIdMapper.getCallId(call));
-                mServiceInterface.stopDtmfTone(mCallIdMapper.getCallId(call));
-            } catch (RemoteException e) {
-            }
-        }
-    }
-
-    void addCall(Call call) {
-        if (mCallIdMapper.getCallId(call) == null) {
-            mCallIdMapper.addCall(call);
-        }
-    }
-
-    /**
-     * Associates newCall with this call service by replacing callToReplace.
-     */
-    void replaceCall(Call newCall, Call callToReplace) {
-        Preconditions.checkState(callToReplace.getCallService() == this);
-        mCallIdMapper.replaceCall(newCall, callToReplace);
-    }
-
-    void removeCall(Call call) {
-        mPendingIncomingCalls.remove(call);
-
-        OutgoingCallResponse outgoingResultCallback =
-                mPendingOutgoingCalls.remove(mCallIdMapper.getCallId(call));
-        if (outgoingResultCallback != null) {
-            outgoingResultCallback.onOutgoingCallFailure(DisconnectCause.ERROR_UNSPECIFIED, null);
-        }
-
-        mCallIdMapper.removeCall(call);
-    }
-
-    void onPostDialContinue(Call call, boolean proceed) {
-        if (isServiceValid("onPostDialContinue")) {
-            try {
-                logOutgoing("onPostDialContinue %s %b", mCallIdMapper.getCallId(call), proceed);
-                mServiceInterface.onPostDialContinue(mCallIdMapper.getCallId(call), proceed);
-            } catch (RemoteException ignored) {
-            }
-        }
-    }
-
-    void onPhoneAccountClicked(Call call) {
-        if (isServiceValid("onPhoneAccountClicked")) {
-            try {
-                logOutgoing("onPhoneAccountClicked %s", mCallIdMapper.getCallId(call));
-                mServiceInterface.onPhoneAccountClicked(mCallIdMapper.getCallId(call));
-            } catch (RemoteException ignored) {
-            }
-        }
-    }
-
-    void conference(final Call conferenceCall, Call call) {
-        if (isServiceValid("conference")) {
-            try {
-                conferenceCall.setCallService(this);
-                mPendingConferenceCalls.add(conferenceCall);
-                mHandler.postDelayed(new Runnable() {
-                    @Override public void run() {
-                        if (mPendingConferenceCalls.remove(conferenceCall)) {
-                            conferenceCall.expireConference();
-                            Log.i(this, "Conference call expired: %s", conferenceCall);
-                        }
-                    }
-                }, Timeouts.getConferenceCallExpireMillis());
-
-                logOutgoing("conference %s %s",
-                        mCallIdMapper.getCallId(conferenceCall),
-                        mCallIdMapper.getCallId(call));
-                mServiceInterface.conference(
-                        mCallIdMapper.getCallId(conferenceCall),
-                        mCallIdMapper.getCallId(call));
-            } catch (RemoteException ignored) {
-            }
-        }
-    }
-
-    void splitFromConference(Call call) {
-        if (isServiceValid("splitFromConference")) {
-            try {
-                logOutgoing("splitFromConference %s", mCallIdMapper.getCallId(call));
-                mServiceInterface.splitFromConference(mCallIdMapper.getCallId(call));
-            } catch (RemoteException ignored) {
-            }
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void setServiceInterface(IBinder binder) {
-        if (binder == null) {
-            // We have lost our service connection. Notify the world that this call service is done.
-            // We must notify the adapter before CallsManager. The adapter will force any pending
-            // outgoing calls to try the next call service. This needs to happen before CallsManager
-            // tries to clean up any calls still associated with this call service.
-            handleCallServiceDeath();
-            CallsManager.getInstance().handleCallServiceDeath(this);
-            mServiceInterface = null;
-        } else {
-            mServiceInterface = ICallService.Stub.asInterface(binder);
-            setCallServiceAdapter(mAdapter);
-        }
-    }
-
-    /**
-     * Called when the associated call service dies.
-     */
-    private void handleCallServiceDeath() {
-        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();
-            }
-        }
-
-        mCallIdMapper.clear();
-    }
-
-    private void logIncoming(String msg, Object... params) {
-        Log.d(this, "CallService -> Telecomm: " + msg, params);
-    }
-
-    private void logOutgoing(String msg, Object... params) {
-        Log.d(this, "Telecomm -> CallService: " + msg, params);
-    }
-
-    private void queryRemoteConnectionServices(final RemoteServiceCallback callback) {
-        final List<IBinder> callServices = new ArrayList<>();
-        final List<ComponentName> components = new ArrayList<>();
-
-        mCallServiceRepository.lookupServices(new LookupCallback<CallServiceWrapper>() {
-            private int mRemainingResponses;
-
-            /** ${inheritDoc} */
-            @Override
-            public void onComplete(Collection<CallServiceWrapper> services) {
-                mRemainingResponses = services.size() - 1;
-                for (CallServiceWrapper cs : services) {
-                    if (cs != CallServiceWrapper.this) {
-                        final CallServiceWrapper currentCallService = cs;
-                        cs.mBinder.bind(new BindCallback() {
-                            @Override
-                            public void onSuccess() {
-                                Log.d(this, "Adding ***** %s", currentCallService.getDescriptor());
-                                callServices.add(currentCallService.mServiceInterface.asBinder());
-                                components.add(currentCallService.getComponentName());
-                                maybeComplete();
-                            }
-
-                            @Override
-                            public void onFailure() {
-                                // add null so that we always add up to totalExpected even if
-                                // some of the call services fail to bind.
-                                maybeComplete();
-                            }
-
-                            private void maybeComplete() {
-                                if (--mRemainingResponses == 0) {
-                                    try {
-                                        callback.onResult(components, callServices);
-                                    } catch (RemoteException ignored) {
-                                    }
-                                }
-                            }
-                        });
-                    }
-                }
-            }
-        });
-    }
-}
diff --git a/src/com/android/telecomm/CallsManager.java b/src/com/android/telecomm/CallsManager.java
index 28e264a..f78fb7c 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -19,7 +19,6 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.telecomm.CallAudioState;
-import android.telecomm.CallInfo;
 import android.telecomm.CallServiceDescriptor;
 import android.telecomm.CallState;
 import android.telecomm.GatewayInfo;
@@ -51,10 +50,10 @@
         void onCallAdded(Call call);
         void onCallRemoved(Call call);
         void onCallStateChanged(Call call, CallState oldState, CallState newState);
-        void onCallServiceChanged(
+        void onConnectionServiceChanged(
                 Call call,
-                CallServiceWrapper oldCallService,
-                CallServiceWrapper newCallService);
+                ConnectionServiceWrapper oldService,
+                ConnectionServiceWrapper newService);
         void onIncomingCallAnswered(Call call);
         void onIncomingCallRejected(Call call, boolean rejectWithMessage, String textMessage);
         void onForegroundCallChanged(Call oldForegroundCall, Call newForegroundCall);
@@ -123,9 +122,9 @@
     public void onSuccessfulOutgoingCall(Call call) {
         Log.v(this, "onSuccessfulOutgoingCall, %s", call);
         if (mCalls.contains(call)) {
-            // The call's CallService has been updated.
+            // The call's ConnectionService has been updated.
             for (CallsManagerListener listener : mListeners) {
-                listener.onCallServiceChanged(call, null, call.getCallService());
+                listener.onConnectionServiceChanged(call, null, call.getConnectionService());
             }
         } else {
             Log.wtf(this, "unexpected successful call notification: %s", call);
@@ -150,9 +149,9 @@
     }
 
     @Override
-    public void onSuccessfulIncomingCall(Call call, CallInfo callInfo) {
+    public void onSuccessfulIncomingCall(Call call) {
         Log.d(this, "onSuccessfulIncomingCall");
-        setCallState(call, callInfo.getState());
+        setCallState(call, CallState.RINGING);
         addCall(call);
     }
 
@@ -264,13 +263,13 @@
      * specified call; using the specified call service descriptor. Upon success, execution returns
      * to {@link #onSuccessfulIncomingCall} to start the in-call UI.
      *
-     * @param descriptor The descriptor of the call service to use for this incoming call.
+     * @param descriptor The descriptor of the connection service to use for this incoming call.
      * @param extras The optional extras Bundle passed with the intent used for the incoming call.
      */
     void processIncomingCallIntent(CallServiceDescriptor descriptor, Bundle extras) {
         Log.d(this, "processIncomingCallIntent");
         // Create a call with no handle. Eventually, switchboard will update the call with
-        // additional information from the call service, but for now we just need one to pass
+        // additional information from the connection service, but for now we just need one to pass
         // around.
         Call call = new Call(true /* isIncoming */, false /* isConference */);
         // TODO(santoscordon): Move this to be a part of addCall()
@@ -516,15 +515,15 @@
     }
 
     /**
-     * Cleans up any calls currently associated with the specified call service when the
+     * Cleans up any calls currently associated with the specified connection service when the
      * call-service binder disconnects unexpectedly.
      *
-     * @param callService The call service that disconnected.
+     * @param service The connection service that disconnected.
      */
-    void handleCallServiceDeath(CallServiceWrapper callService) {
-        Preconditions.checkNotNull(callService);
+    void handleConnectionServiceDeath(ConnectionServiceWrapper service) {
+        Preconditions.checkNotNull(service);
         for (Call call : ImmutableList.copyOf(mCalls)) {
-            if (call.getCallService() == callService) {
+            if (call.getConnectionService() == service) {
                 markCallAsDisconnected(call, DisconnectCause.ERROR_UNSPECIFIED, null);
             }
         }
@@ -630,7 +629,7 @@
         Log.v(this, "removeCall(%s)", call);
 
         call.removeListener(this);
-        call.clearCallService();
+        call.clearConnectionService();
 
         boolean shouldNotify = false;
         if (mCalls.contains(call)) {
@@ -684,8 +683,8 @@
         Call newForegroundCall = null;
         for (Call call : mCalls) {
             // TODO(santoscordon): Foreground-ness needs to be explicitly set. No call, regardless
-            // of its state will be foreground by default and instead the call service should be
-            // notified when its calls enter and exit foreground state. Foreground will mean that
+            // of its state will be foreground by default and instead the connection service should
+            // be notified when its calls enter and exit foreground state. Foreground will mean that
             // the call should play audio and listen to microphone if it wants.
 
             // Active calls have priority.
diff --git a/src/com/android/telecomm/CallsManagerListenerBase.java b/src/com/android/telecomm/CallsManagerListenerBase.java
index a5320a4..f34bdad 100644
--- a/src/com/android/telecomm/CallsManagerListenerBase.java
+++ b/src/com/android/telecomm/CallsManagerListenerBase.java
@@ -38,10 +38,10 @@
     }
 
     @Override
-    public void onCallServiceChanged(
+    public void onConnectionServiceChanged(
             Call call,
-            CallServiceWrapper oldCallServiceWrapper,
-            CallServiceWrapper newCallService) {
+            ConnectionServiceWrapper oldService,
+            ConnectionServiceWrapper newService) {
     }
 
     @Override
diff --git a/src/com/android/telecomm/ConnectionServiceWrapper.java b/src/com/android/telecomm/ConnectionServiceWrapper.java
new file mode 100644
index 0000000..0ae8d20
--- /dev/null
+++ b/src/com/android/telecomm/ConnectionServiceWrapper.java
@@ -0,0 +1,886 @@
+/*
+ * 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.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.RemoteException;
+import android.telecomm.CallAudioState;
+import android.telecomm.ConnectionService;
+import android.telecomm.CallServiceDescriptor;
+import android.telecomm.ConnectionRequest;
+import android.telecomm.GatewayInfo;
+import android.telecomm.TelecommConstants;
+import android.telephony.DisconnectCause;
+
+import com.android.internal.os.SomeArgs;
+
+import com.android.internal.telecomm.IConnectionService;
+import com.android.internal.telecomm.IConnectionServiceAdapter;
+import com.android.internal.telecomm.ICallServiceProvider;
+import com.android.internal.telecomm.ICallVideoProvider;
+import com.android.internal.telecomm.RemoteServiceCallback;
+import com.android.telecomm.BaseRepository.LookupCallback;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+import org.apache.http.conn.ClientConnectionRequest;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Wrapper for {@link IConnectionService}s, handles binding to {@link IConnectionService} and keeps
+ * track of when the object can safely be unbound. Other classes should not use
+ * {@link IConnectionService} directly and instead should use this class to invoke methods of
+ * {@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_CAN_CONFERENCE = 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_FEATURES = 18;
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            Call call;
+            switch (msg.what) {
+                case MSG_NOTIFY_INCOMING_CALL: {
+                    ConnectionRequest request = (ConnectionRequest) msg.obj;
+                    call = mCallIdMapper.getCall(request.getCallId());
+                    if (call != null && mPendingIncomingCalls.remove(call) &&
+                            call.isIncoming()) {
+                        mIncomingCallsManager.handleSuccessfulIncomingCall(call, 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());
+                    }
+                    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: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        ConnectionRequest request = (ConnectionRequest) msg.obj;
+                        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);
+                            mCallIdMapper.removeCall(request.getCallId());
+                        } else {
+                            //Log.w(this, "handleFailedOutgoingCall, unknown call: %s", callId);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_CANCEL_OUTGOING_CALL: {
+                    ConnectionRequest request = (ConnectionRequest) msg.obj;
+                    if (mPendingOutgoingCalls.containsKey(request.getCallId())) {
+                        mPendingOutgoingCalls.remove(
+                                request.getCallId()).onOutgoingCallCancel();
+                    } else {
+                        //Log.w(this, "cancelOutgoingCall, unknown call: %s", callId);
+                    }
+                    break;
+                }
+                case MSG_SET_ACTIVE:
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        mCallsManager.markCallAsActive(call);
+                    } else {
+                        //Log.w(this, "setActive, unknown call id: %s", msg.obj);
+                    }
+                    break;
+                case MSG_SET_RINGING:
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        mCallsManager.markCallAsRinging(call);
+                    } else {
+                        //Log.w(this, "setRinging, unknown call id: %s", msg.obj);
+                    }
+                    break;
+                case MSG_SET_DIALING:
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        mCallsManager.markCallAsDialing(call);
+                    } else {
+                        //Log.w(this, "setDialing, unknown call id: %s", msg.obj);
+                    }
+                    break;
+                case MSG_SET_DISCONNECTED: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        call = mCallIdMapper.getCall(args.arg1);
+                        String disconnectMessage = (String) args.arg2;
+                        int disconnectCause = args.argi1;
+                        if (call != null) {
+                            mCallsManager.markCallAsDisconnected(call, disconnectCause,
+                                    disconnectMessage);
+                        } else {
+                            //Log.w(this, "setDisconnected, unknown call id: %s", args.arg1);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_SET_ON_HOLD:
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        mCallsManager.markCallAsOnHold(call);
+                    } else {
+                        //Log.w(this, "setOnHold, unknown call id: %s", msg.obj);
+                    }
+                    break;
+                case MSG_SET_REQUESTING_RINGBACK: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        call = mCallIdMapper.getCall(args.arg1);
+                        boolean ringback = (boolean) args.arg2;
+                        if (call != null) {
+                            call.setRequestingRingback(ringback);
+                        } else {
+                            //Log.w(this, "setRingback, unknown call id: %s", args.arg1);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_CAN_CONFERENCE: {
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        call.setIsConferenceCapable(msg.arg1 == 1);
+                    } else {
+                        //Log.w(ConnectionServiceWrapper.this,
+                        //      "canConference, unknown call id: %s", msg.obj);
+                    }
+                    break;
+                }
+                case MSG_SET_IS_CONFERENCED: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        Call childCall = mCallIdMapper.getCall(args.arg1);
+                        if (childCall != null) {
+                            String conferenceCallId = (String) args.arg2;
+                            if (conferenceCallId == null) {
+                                childCall.setParentCall(null);
+                            } else {
+                                Call conferenceCall = mCallIdMapper.getCall(conferenceCallId);
+                                if (conferenceCall != null &&
+                                        !mPendingConferenceCalls.contains(conferenceCall)) {
+                                    childCall.setParentCall(conferenceCall);
+                                } else {
+                                    //Log.w(this, "setIsConferenced, unknown conference id %s",
+                                    //        conferenceCallId);
+                                }
+                            }
+                        } else {
+                            //Log.w(this, "setIsConferenced, unknown call id: %s", args.arg1);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_ADD_CONFERENCE_CALL: {
+                    Call conferenceCall = mCallIdMapper.getCall(msg.obj);
+                    if (mPendingConferenceCalls.remove(conferenceCall)) {
+                        Log.v(this, "confirming conf call %s", conferenceCall);
+                        conferenceCall.confirmConference();
+                    } else {
+                        //Log.w(this, "addConference, unknown call id: %s", callId);
+                    }
+                    break;
+                }
+                case MSG_REMOVE_CALL:
+                    break;
+                case MSG_ON_POST_DIAL_WAIT: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        call = mCallIdMapper.getCall(args.arg1);
+                        if (call != null) {
+                            String remaining = (String) args.arg2;
+                            call.onPostDialWait(remaining);
+                        } else {
+                            //Log.w(this, "onPostDialWait, unknown call id: %s", args.arg1);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_QUERY_REMOTE_CALL_SERVICES: {
+                    ConnectionServiceWrapper.this.queryRemoteConnectionServices(
+                            (RemoteServiceCallback) msg.obj);
+                    break;
+                }
+                case MSG_SET_CALL_VIDEO_PROVIDER: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        call = mCallIdMapper.getCall(args.arg1);
+                        ICallVideoProvider callVideoProvider = (ICallVideoProvider) args.arg2;
+                        if (call != null) {
+                            call.setCallVideoProvider(callVideoProvider);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_SET_FEATURES: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        call = mCallIdMapper.getCall(args.arg1);
+                        int features = (int) args.arg2;
+                        if (call != null) {
+                            call.setFeatures(features);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+            }
+        }
+    };
+
+    private final class Adapter extends IConnectionServiceAdapter.Stub {
+        /** {@inheritDoc} */
+        @Override
+        public void notifyIncomingCall(ConnectionRequest request) {
+            logIncoming("notifyIncomingCall %s", request);
+            mCallIdMapper.checkValidCallId(request.getCallId());
+            mHandler.obtainMessage(MSG_NOTIFY_INCOMING_CALL, request).sendToTarget();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void handleSuccessfulOutgoingCall(ConnectionRequest request) {
+            logIncoming("handleSuccessfulOutgoingCall %s", request);
+            mCallIdMapper.checkValidCallId(request.getCallId());
+            mHandler.obtainMessage(MSG_HANDLE_SUCCESSFUL_OUTGOING_CALL, request).sendToTarget();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void handleFailedOutgoingCall(
+                ConnectionRequest request,
+                int errorCode,
+                String errorMsg) {
+            logIncoming("handleFailedOutgoingCall %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();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void cancelOutgoingCall(ConnectionRequest request) {
+            logIncoming("cancelOutgoingCall %s", request);
+            mCallIdMapper.checkValidCallId(request.getCallId());
+            mHandler.obtainMessage(MSG_CANCEL_OUTGOING_CALL, request).sendToTarget();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void setActive(String callId) {
+            logIncoming("setActive %s", callId);
+            mCallIdMapper.checkValidCallId(callId);
+            mHandler.obtainMessage(MSG_SET_ACTIVE, callId).sendToTarget();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void setRinging(String callId) {
+            logIncoming("setRinging %s", callId);
+            mCallIdMapper.checkValidCallId(callId);
+            mHandler.obtainMessage(MSG_SET_RINGING, callId).sendToTarget();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void setCallVideoProvider(String callId, ICallVideoProvider callVideoProvider) {
+            logIncoming("setCallVideoProvider %s", callId);
+            mCallIdMapper.checkValidCallId(callId);
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.arg2 = callVideoProvider;
+            mHandler.obtainMessage(MSG_SET_CALL_VIDEO_PROVIDER, args).sendToTarget();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void setDialing(String callId) {
+            logIncoming("setDialing %s", callId);
+            mCallIdMapper.checkValidCallId(callId);
+            mHandler.obtainMessage(MSG_SET_DIALING, callId).sendToTarget();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void setDisconnected(
+                String callId, int disconnectCause, String disconnectMessage) {
+            logIncoming("setDisconnected %s %d %s", callId, disconnectCause, disconnectMessage);
+            mCallIdMapper.checkValidCallId(callId);
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.arg2 = disconnectMessage;
+            args.argi1 = disconnectCause;
+            mHandler.obtainMessage(MSG_SET_DISCONNECTED, args).sendToTarget();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void setOnHold(String callId) {
+            logIncoming("setOnHold %s", callId);
+            mCallIdMapper.checkValidCallId(callId);
+            mHandler.obtainMessage(MSG_SET_ON_HOLD, callId).sendToTarget();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void setRequestingRingback(String callId, boolean ringback) {
+            logIncoming("setRequestingRingback %s %b", callId, ringback);
+            mCallIdMapper.checkValidCallId(callId);
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.arg2 = ringback;
+            mHandler.obtainMessage(MSG_SET_REQUESTING_RINGBACK, args).sendToTarget();
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void removeCall(String callId) {
+            logIncoming("removeCall %s", callId);
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void setCanConference(String callId, boolean canConference) {
+            logIncoming("setCanConference %s %b", callId, canConference);
+            mHandler.obtainMessage(MSG_CAN_CONFERENCE, canConference ? 1 : 0, 0, callId)
+                    .sendToTarget();
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void setIsConferenced(String callId, String conferenceCallId) {
+            logIncoming("setIsConferenced %s %s", callId, conferenceCallId);
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.arg2 = conferenceCallId;
+            mHandler.obtainMessage(MSG_SET_IS_CONFERENCED, args).sendToTarget();
+        }
+
+        /** ${InheritDoc} */
+        @Override
+        public void addConferenceCall(String callId) {
+            logIncoming("addConferenceCall %s", callId);
+            mCallIdMapper.checkValidCallId(callId);
+            mHandler.obtainMessage(MSG_ADD_CONFERENCE_CALL, callId).sendToTarget();
+        }
+
+        @Override
+        public void onPostDialWait(String callId, String remaining) throws RemoteException {
+            logIncoming("onPostDialWait %s %s", callId, remaining);
+            mCallIdMapper.checkValidCallId(callId);
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.arg2 = remaining;
+            mHandler.obtainMessage(MSG_ON_POST_DIAL_WAIT, args).sendToTarget();
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void queryRemoteConnectionServices(RemoteServiceCallback callback) {
+            logIncoming("queryRemoteCSs");
+            mHandler.obtainMessage(MSG_QUERY_REMOTE_CALL_SERVICES, callback).sendToTarget();
+        }
+
+        @Override
+        public void setFeatures(String callId, int features) {
+            logIncoming("setFeatures %s %d", callId, features);
+            mCallIdMapper.checkValidCallId(callId);
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.arg2 = features;
+            mHandler.obtainMessage(MSG_SET_FEATURES, args).sendToTarget();
+        }
+    }
+
+    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 CallServiceDescriptor mDescriptor;
+    private final CallIdMapper mCallIdMapper = new CallIdMapper("ConnectionService");
+    private final IncomingCallsManager mIncomingCallsManager;
+    private final Map<String, OutgoingCallResponse> mPendingOutgoingCalls = new HashMap<>();
+
+    private Binder mBinder = new Binder();
+    private IConnectionService mServiceInterface;
+    private final CallServiceRepository mCallServiceRepository;
+
+    /**
+     * Creates a call-service for the specified descriptor.
+     *
+     * @param descriptor The call-service descriptor from
+     *            {@link ICallServiceProvider#lookupCallServices}.
+     * @param incomingCallsManager Manages the incoming call initialization flow.
+     * @param callServiceRepository Connection service repository.
+     */
+    ConnectionServiceWrapper(
+            CallServiceDescriptor descriptor,
+            IncomingCallsManager incomingCallsManager,
+            CallServiceRepository callServiceRepository) {
+        super(TelecommConstants.ACTION_CONNECTION_SERVICE, descriptor.getServiceComponent());
+        mDescriptor = descriptor;
+        mIncomingCallsManager = incomingCallsManager;
+        mCallServiceRepository = callServiceRepository;
+    }
+
+    CallServiceDescriptor getDescriptor() {
+        return mDescriptor;
+    }
+
+    /** See {@link IConnectionService#addConnectionServiceAdapter}. */
+    private void addConnectionServiceAdapter(IConnectionServiceAdapter adapter) {
+        if (isServiceValid("addConnectionServiceAdapter")) {
+            try {
+                logOutgoing("addConnectionServiceAdapter%s", adapter);
+                mServiceInterface.addConnectionServiceAdapter(adapter);
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    /**
+     * Attempts to place the specified call, see {@link IConnectionService#call}. Returns the result
+     * asynchronously through the specified callback.
+     */
+    void call(final Call call, final OutgoingCallResponse callResponse) {
+        Log.d(this, "call(%s) via %s.", call, getComponentName());
+        BindCallback callback = new BindCallback() {
+            @Override
+            public void onSuccess() {
+                String callId = mCallIdMapper.getCallId(call);
+                mPendingOutgoingCalls.put(callId, callResponse);
+
+                GatewayInfo gatewayInfo = call.getGatewayInfo();
+                Bundle extras = call.getExtras();
+                if (gatewayInfo != null && gatewayInfo.getGatewayProviderPackageName() != null &&
+                        gatewayInfo.getOriginalHandle() != null) {
+                    extras = (Bundle) extras.clone();
+                    extras.putString(
+                            NewOutgoingCallIntentBroadcaster.EXTRA_GATEWAY_PROVIDER_PACKAGE,
+                            gatewayInfo.getGatewayProviderPackageName());
+                    extras.putParcelable(
+                            NewOutgoingCallIntentBroadcaster.EXTRA_GATEWAY_ORIGINAL_URI,
+                            gatewayInfo.getOriginalHandle());
+                }
+                ConnectionRequest request = new ConnectionRequest(callId, call.getHandle(), extras);
+
+                try {
+                    mServiceInterface.call(request);
+                } catch (RemoteException e) {
+                    Log.e(this, e, "Failure to call -- %s", getDescriptor());
+                    mPendingOutgoingCalls.remove(callId).onOutgoingCallFailure(
+                            DisconnectCause.ERROR_UNSPECIFIED, e.toString());
+                }
+            }
+
+            @Override
+            public void onFailure() {
+                Log.e(this, new Exception(), "Failure to call %s", getDescriptor());
+                callResponse.onOutgoingCallFailure(DisconnectCause.ERROR_UNSPECIFIED, null);
+            }
+        };
+
+        mBinder.bind(callback);
+    }
+
+    /** @see ConnectionService#abort(String) */
+    void abort(Call call) {
+        // Clear out any pending outgoing call data
+        String callId = mCallIdMapper.getCallId(call);
+
+        // If still bound, tell the connection service to abort.
+        if (isServiceValid("abort")) {
+            try {
+                logOutgoing("abort %s", callId);
+                mServiceInterface.abort(callId);
+            } catch (RemoteException e) {
+            }
+        }
+
+        removeCall(call);
+    }
+
+    /** @see ConnectionService#hold(String) */
+    void hold(Call call) {
+        if (isServiceValid("hold")) {
+            try {
+                logOutgoing("hold %s", mCallIdMapper.getCallId(call));
+                mServiceInterface.hold(mCallIdMapper.getCallId(call));
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    /** @see ConnectionService#unhold(String) */
+    void unhold(Call call) {
+        if (isServiceValid("unhold")) {
+            try {
+                logOutgoing("unhold %s", mCallIdMapper.getCallId(call));
+                mServiceInterface.unhold(mCallIdMapper.getCallId(call));
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    /** @see ConnectionService#onAudioStateChanged(String,CallAudioState) */
+    void onAudioStateChanged(Call activeCall, CallAudioState audioState) {
+        if (isServiceValid("onAudioStateChanged")) {
+            try {
+                logOutgoing("onAudioStateChanged %s %s",
+                        mCallIdMapper.getCallId(activeCall), audioState);
+                mServiceInterface.onAudioStateChanged(mCallIdMapper.getCallId(activeCall),
+                        audioState);
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    /**
+     * Starts retrieval of details for an incoming call. Details are returned through the
+     * call-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 extras The {@link ConnectionService}-provided extras which need to be sent back.
+     * @param errorCallback The callback to invoke upon failure.
+     */
+    void createIncomingCall(final Call call, final Bundle extras, 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 %s", callId, extras);
+                    ConnectionRequest request = new ConnectionRequest(
+                            callId, call.getHandle(), extras);
+                    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")) {
+            try {
+                logOutgoing("disconnect %s", mCallIdMapper.getCallId(call));
+                mServiceInterface.disconnect(mCallIdMapper.getCallId(call));
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    /** @see ConnectionService#answer(String) */
+    void answer(Call call) {
+        if (isServiceValid("answer")) {
+            try {
+                logOutgoing("answer %s", mCallIdMapper.getCallId(call));
+                mServiceInterface.answer(mCallIdMapper.getCallId(call));
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    /** @see ConnectionService#reject(String) */
+    void reject(Call call) {
+        if (isServiceValid("reject")) {
+            try {
+                logOutgoing("reject %s", mCallIdMapper.getCallId(call));
+                mServiceInterface.reject(mCallIdMapper.getCallId(call));
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    /** @see ConnectionService#playDtmfTone(String,char) */
+    void playDtmfTone(Call call, char digit) {
+        if (isServiceValid("playDtmfTone")) {
+            try {
+                logOutgoing("playDtmfTone %s %c", mCallIdMapper.getCallId(call), digit);
+                mServiceInterface.playDtmfTone(mCallIdMapper.getCallId(call), digit);
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    /** @see ConnectionService#stopDtmfTone(String) */
+    void stopDtmfTone(Call call) {
+        if (isServiceValid("stopDtmfTone")) {
+            try {
+                logOutgoing("stopDtmfTone %s", mCallIdMapper.getCallId(call));
+                mServiceInterface.stopDtmfTone(mCallIdMapper.getCallId(call));
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    void addCall(Call call) {
+        if (mCallIdMapper.getCallId(call) == null) {
+            mCallIdMapper.addCall(call);
+        }
+    }
+
+    /**
+     * Associates newCall with this connection service by replacing callToReplace.
+     */
+    void replaceCall(Call newCall, Call callToReplace) {
+        Preconditions.checkState(callToReplace.getConnectionService() == this);
+        mCallIdMapper.replaceCall(newCall, callToReplace);
+    }
+
+    void removeCall(Call call) {
+        mPendingIncomingCalls.remove(call);
+
+        OutgoingCallResponse outgoingResultCallback =
+                mPendingOutgoingCalls.remove(mCallIdMapper.getCallId(call));
+        if (outgoingResultCallback != null) {
+            outgoingResultCallback.onOutgoingCallFailure(DisconnectCause.ERROR_UNSPECIFIED, null);
+        }
+
+        mCallIdMapper.removeCall(call);
+    }
+
+    void onPostDialContinue(Call call, boolean proceed) {
+        if (isServiceValid("onPostDialContinue")) {
+            try {
+                logOutgoing("onPostDialContinue %s %b", mCallIdMapper.getCallId(call), proceed);
+                mServiceInterface.onPostDialContinue(mCallIdMapper.getCallId(call), proceed);
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+
+    void onPhoneAccountClicked(Call call) {
+        if (isServiceValid("onPhoneAccountClicked")) {
+            try {
+                logOutgoing("onPhoneAccountClicked %s", mCallIdMapper.getCallId(call));
+                mServiceInterface.onPhoneAccountClicked(mCallIdMapper.getCallId(call));
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+
+    void conference(final Call conferenceCall, Call call) {
+        if (isServiceValid("conference")) {
+            try {
+                conferenceCall.setConnectionService(this);
+                mPendingConferenceCalls.add(conferenceCall);
+                mHandler.postDelayed(new Runnable() {
+                    @Override public void run() {
+                        if (mPendingConferenceCalls.remove(conferenceCall)) {
+                            conferenceCall.expireConference();
+                            Log.i(this, "Conference call expired: %s", conferenceCall);
+                        }
+                    }
+                }, Timeouts.getConferenceCallExpireMillis());
+
+                logOutgoing("conference %s %s",
+                        mCallIdMapper.getCallId(conferenceCall),
+                        mCallIdMapper.getCallId(call));
+                mServiceInterface.conference(
+                        mCallIdMapper.getCallId(conferenceCall),
+                        mCallIdMapper.getCallId(call));
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+
+    void splitFromConference(Call call) {
+        if (isServiceValid("splitFromConference")) {
+            try {
+                logOutgoing("splitFromConference %s", mCallIdMapper.getCallId(call));
+                mServiceInterface.splitFromConference(mCallIdMapper.getCallId(call));
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void setServiceInterface(IBinder binder) {
+        if (binder == null) {
+            // We have lost our service connection. Notify the world that this service is done.
+            // We must notify the adapter before CallsManager. The adapter will force any pending
+            // outgoing calls to try the next service. This needs to happen before CallsManager
+            // tries to clean up any calls still associated with this service.
+            handleConnectionServiceDeath();
+            CallsManager.getInstance().handleConnectionServiceDeath(this);
+            mServiceInterface = null;
+        } else {
+            mServiceInterface = IConnectionService.Stub.asInterface(binder);
+            addConnectionServiceAdapter(mAdapter);
+        }
+    }
+
+    /**
+     * 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();
+            }
+        }
+
+        mCallIdMapper.clear();
+    }
+
+    private void logIncoming(String msg, Object... params) {
+        Log.d(this, "ConnectionService -> Telecomm: " + msg, params);
+    }
+
+    private void logOutgoing(String msg, Object... params) {
+        Log.d(this, "Telecomm -> ConnectionService: " + msg, params);
+    }
+
+    private void queryRemoteConnectionServices(final RemoteServiceCallback callback) {
+        final List<IBinder> connectionServices = new ArrayList<>();
+        final List<ComponentName> components = new ArrayList<>();
+
+        mCallServiceRepository.lookupServices(new LookupCallback<ConnectionServiceWrapper>() {
+            private int mRemainingResponses;
+
+            /** ${inheritDoc} */
+            @Override
+            public void onComplete(Collection<ConnectionServiceWrapper> services) {
+                mRemainingResponses = services.size() - 1;
+                for (ConnectionServiceWrapper cs : services) {
+                    if (cs != ConnectionServiceWrapper.this) {
+                        final ConnectionServiceWrapper currentConnectionService = cs;
+                        cs.mBinder.bind(new BindCallback() {
+                            @Override
+                            public void onSuccess() {
+                                Log.d(this, "Adding ***** %s",
+                                        currentConnectionService.getDescriptor());
+                                connectionServices.add(
+                                        currentConnectionService.mServiceInterface.asBinder());
+                                components.add(currentConnectionService.getComponentName());
+                                maybeComplete();
+                            }
+
+                            @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) {
+                                    try {
+                                        callback.onResult(components, connectionServices);
+                                    } catch (RemoteException ignored) {
+                                    }
+                                }
+                            }
+                        });
+                    }
+                }
+            }
+        });
+    }
+}
diff --git a/src/com/android/telecomm/InCallController.java b/src/com/android/telecomm/InCallController.java
index c1c8eaf..d1215ae 100644
--- a/src/com/android/telecomm/InCallController.java
+++ b/src/com/android/telecomm/InCallController.java
@@ -103,10 +103,10 @@
     }
 
     @Override
-    public void onCallServiceChanged(
+    public void onConnectionServiceChanged(
             Call call,
-            CallServiceWrapper oldCallServiceWrapper,
-            CallServiceWrapper newCallService) {
+            ConnectionServiceWrapper oldService,
+            ConnectionServiceWrapper newService) {
         updateCall(call);
     }
 
@@ -261,8 +261,8 @@
 
     private InCallCall toInCallCall(Call call) {
         String callId = mCallIdMapper.getCallId(call);
-        CallServiceDescriptor descriptor =
-                call.getCallService() != null ? call.getCallService().getDescriptor() : null;
+        CallServiceDescriptor descriptor = call.getConnectionService() != null ?
+                call.getConnectionService().getDescriptor() : null;
 
         int capabilities = CallCapabilities.HOLD | CallCapabilities.MUTE;
         if (CallsManager.getInstance().isAddCallCapable(call)) {
diff --git a/src/com/android/telecomm/IncomingCallsManager.java b/src/com/android/telecomm/IncomingCallsManager.java
index 5a874ea..197f699 100644
--- a/src/com/android/telecomm/IncomingCallsManager.java
+++ b/src/com/android/telecomm/IncomingCallsManager.java
@@ -17,8 +17,8 @@
 package com.android.telecomm;
 
 import android.os.Bundle;
-import android.telecomm.CallInfo;
-import android.telecomm.CallService;
+import android.telecomm.ConnectionService;
+import android.telecomm.ConnectionRequest;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Maps;
@@ -34,11 +34,12 @@
     private final Set<Call> mPendingIncomingCalls = Sets.newLinkedHashSet();
 
     /**
-     * Retrieves details of an incoming call through its associated call service.
+     * Retrieves details of an incoming call through its associated connection service.
      *
      * @param call The call object.
      * @param extras The optional extras passed with the incoming call intent (to be returned to
-     *     the call service via {@link CallService#setIncomingCallId(String, android.os.Bundle)}).
+     *     the connection service via
+     *     {@link ConnectionService#createIncomingCall(ConnectionRequest)}.
      */
     void retrieveIncomingCall(final Call call, Bundle extras) {
         ThreadUtil.checkOnMainThread();
@@ -55,22 +56,22 @@
             }
         };
 
-        call.getCallService().setIncomingCallId(call, extras, errorCallback);
+        call.getConnectionService().createIncomingCall(call, extras, errorCallback);
     }
 
     /**
      * Notifies the incoming call of success after removing it from the pending
      * list.
      *
-     * @param callInfo The details of the call.
+     * @param request The details of the call.
      */
-    void handleSuccessfulIncomingCall(Call call, CallInfo callInfo) {
+    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(callInfo);
+            call.handleVerifiedIncoming(request);
         }
     }
 
diff --git a/src/com/android/telecomm/OutgoingCallProcessor.java b/src/com/android/telecomm/OutgoingCallProcessor.java
index 9d1f008..c33b17e 100644
--- a/src/com/android/telecomm/OutgoingCallProcessor.java
+++ b/src/com/android/telecomm/OutgoingCallProcessor.java
@@ -35,11 +35,9 @@
 import java.util.Set;
 
 /**
- * Utility class to place a call using the specified set of call-services and ordered selectors.
- * Iterates through the selectors and gets a sorted list of supported call-service descriptors
- * for each selector. Upon receiving each sorted list (one list per selector), each of the
- * corresponding call services is then attempted until either the outgoing call is placed, the
- * attempted call is aborted, or the list is exhausted -- whichever occurs first.
+ * Utility class to place a call using the specified set of call-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.
@@ -54,13 +52,13 @@
     /**
      * The map of currently-available call-service implementations keyed by call-service ID.
      */
-    private final Map<String, CallServiceWrapper> mCallServicesById = Maps.newHashMap();
+    private final Map<String, ConnectionServiceWrapper> mConnectionServicesById = Maps.newHashMap();
 
     /**
-     * The set of attempted call services, used to ensure services are attempted at most once per
-     * outgoing-call attempt.
+     * The set of attempted connection services, used to ensure services are attempted at most once
+     * per outgoing-call attempt.
      */
-    private final Set<CallServiceWrapper> mAttemptedCallServices = Sets.newHashSet();
+    private final Set<ConnectionServiceWrapper> mAttemptedConnectionServices = Sets.newHashSet();
 
     private final CallServiceRepository mCallServiceRepository;
 
@@ -84,8 +82,8 @@
 
     /**
      * Persists the specified parameters and iterates through the prioritized list of call
-     * services. Stops once a matching call service is found. Calls with no matching
-     * call service will eventually be killed by the cleanup/monitor switchboard handler.
+     * 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 callServiceRepository
@@ -109,11 +107,11 @@
     void process() {
         Log.v(this, "process, mIsAborted: %b", mIsAborted);
         if (!mIsAborted) {
-            // Lookup call services
-            mCallServiceRepository.lookupServices(new LookupCallback<CallServiceWrapper>() {
+            // Lookup connection services
+            mCallServiceRepository.lookupServices(new LookupCallback<ConnectionServiceWrapper>() {
                 @Override
-                public void onComplete(Collection<CallServiceWrapper> services) {
-                    setCallServices(services);
+                public void onComplete(Collection<ConnectionServiceWrapper> services) {
+                    setConnectionServices(services);
                 }
             });
         }
@@ -129,14 +127,15 @@
         if (!mIsAborted && mResultCallback != null) {
             mIsAborted = true;
 
-            // On an abort, we need to check if we already told the call service to place the
+            // 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 call service is saved with the call and so we have to query
-            // the call to get it, which is a bit backwards.  Ideally, the call service would be
-            // saved inside this class until the whole thing is complete and then set on the call.
-            CallServiceWrapper callService = mCall.getCallService();
-            if (callService != null) {
-                callService.abort(mCall);
+            // 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
@@ -150,17 +149,16 @@
     }
 
     /**
-     * Completes the outgoing call sequence by setting the call service on the call object. This is
-     * invoked when the call service adapter receives positive confirmation that the call service
-     * placed the call.
+     * 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(CallServiceWrapper callService) {
+    void handleSuccessfulCallAttempt(ConnectionServiceWrapper service) {
         Log.v(this, "handleSuccessfulCallAttempt");
         ThreadUtil.checkOnMainThread();
 
         if (mIsAborted) {
-            // TODO(gilad): Ask the call service to drop the call?
-            callService.abort(mCall);
+            service.abort(mCall);
             return;
         }
 
@@ -168,8 +166,8 @@
     }
 
     /**
-     * Attempts the next call service if the specified call service is the one currently being
-     * attempted.
+     * 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.
@@ -182,91 +180,90 @@
         mLastErrorMsg = errorMsg;
         if (!mIsAborted) {
             ThreadUtil.checkOnMainThread();
-            attemptNextCallService();
+            attemptNextConnectionService();
         }
     }
 
     /**
-     * Sets the call services to attempt for this outgoing call.
+     * Sets the connection services to attempt for this outgoing call.
      *
-     * @param callServices The call services.
+     * @param services The connection services.
      */
-    private void setCallServices(Collection<CallServiceWrapper> callServices) {
+    private void setConnectionServices(Collection<ConnectionServiceWrapper> services) {
         mCallServiceDescriptors = new ArrayList<>();
 
-        // Populate the list and map of call-service descriptors.  The list is needed since
-        // it's being passed down to selectors.
-        for (CallServiceWrapper callService : callServices) {
-            CallServiceDescriptor descriptor = callService.getDescriptor();
+        // Populate the list and map of call-service descriptors.
+        for (ConnectionServiceWrapper service : services) {
+            CallServiceDescriptor descriptor = service.getDescriptor();
             // TODO(sail): Remove once there's a way to pick the service.
             if (descriptor.getServiceComponent().getPackageName().equals(
                     "com.google.android.talk")) {
-                Log.i(this, "Moving call service %s to top of list", descriptor);
+                Log.i(this, "Moving connection service %s to top of list", descriptor);
                 mCallServiceDescriptors.add(0, descriptor);
             } else {
                 mCallServiceDescriptors.add(descriptor);
             }
-            mCallServicesById.put(descriptor.getCallServiceId(), callService);
+            mConnectionServicesById.put(descriptor.getConnectionServiceId(), service);
         }
 
         adjustCallServiceDescriptorsForEmergency();
 
         mCallServiceDescriptorIterator = mCallServiceDescriptors.iterator();
-        attemptNextCallService();
+        attemptNextConnectionService();
     }
 
     /**
-     * Attempts to place the call using the call service specified by the next call-service
+     * Attempts to place the call using the connection service specified by the next call-service
      * descriptor of mCallServiceDescriptorIterator.
      */
-    private void attemptNextCallService() {
-        Log.v(this, "attemptNextCallService, mIsAborted: %b", mIsAborted);
+    private void attemptNextConnectionService() {
+        Log.v(this, "attemptNextConnectionService, mIsAborted: %b", mIsAborted);
         if (mIsAborted) {
             return;
         }
 
         if (mCallServiceDescriptorIterator != null && mCallServiceDescriptorIterator.hasNext()) {
             CallServiceDescriptor descriptor = mCallServiceDescriptorIterator.next();
-            final CallServiceWrapper callService =
-                    mCallServicesById.get(descriptor.getCallServiceId());
+            final ConnectionServiceWrapper service =
+                    mConnectionServicesById.get(descriptor.getConnectionServiceId());
 
-            if (callService == null || mAttemptedCallServices.contains(callService)) {
-                // The next call service is either null or has already been attempted, fast forward
-                // to the next.
-                attemptNextCallService();
+            if (service == null || mAttemptedConnectionServices.contains(service)) {
+                // The next connection service is either null or has already been attempted, fast
+                // forward to the next.
+                attemptNextConnectionService();
             } else {
-                mAttemptedCallServices.add(callService);
-                mCall.setCallService(callService);
+                mAttemptedConnectionServices.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.
-                callService.incrementAssociatedCallCount();
+                service.incrementAssociatedCallCount();
 
-                Log.i(this, "Attempting to call from %s", callService.getDescriptor());
-                callService.call(mCall, new OutgoingCallResponse() {
+                Log.i(this, "Attempting to call from %s", service.getDescriptor());
+                service.call(mCall, new OutgoingCallResponse() {
                     @Override
                     public void onOutgoingCallSuccess() {
-                        handleSuccessfulCallAttempt(callService);
-                        callService.decrementAssociatedCallCount();
+                        handleSuccessfulCallAttempt(service);
+                        service.decrementAssociatedCallCount();
                     }
 
                     @Override
                     public void onOutgoingCallFailure(int code, String msg) {
                         handleFailedCallAttempt(code, msg);
-                        callService.decrementAssociatedCallCount();
+                        service.decrementAssociatedCallCount();
                     }
 
                     @Override
                     public void onOutgoingCallCancel() {
                         abort();
-                        callService.decrementAssociatedCallCount();
+                        service.decrementAssociatedCallCount();
                     }
                 });
             }
         } else {
-            Log.v(this, "attemptNextCallService, no more service descriptors, failing");
+            Log.v(this, "attemptNextConnectionService, no more service descriptors, failing");
             mCallServiceDescriptorIterator = null;
-            mCall.clearCallService();
+            mCall.clearConnectionService();
             sendResult(false, mLastErrorCode, mLastErrorMsg);
         }
     }
@@ -287,11 +284,11 @@
     }
 
     // If we are possibly attempting to call a local emergency number, ensure that the
-    // plain PSTN call service, if it exists, is attempted first.
+    // plain PSTN connection service, if it exists, is attempted first.
     private void adjustCallServiceDescriptorsForEmergency()  {
         for (int i = 0; i < mCallServiceDescriptors.size(); i++) {
             if (shouldProcessAsEmergency(mCall.getHandle())) {
-                if (TelephonyUtil.isPstnCallService(mCallServiceDescriptors.get(i))) {
+                if (TelephonyUtil.isPstnConnectionService(mCallServiceDescriptors.get(i))) {
                     mCallServiceDescriptors.add(0, mCallServiceDescriptors.remove(i));
                     return;
                 }
diff --git a/src/com/android/telecomm/PhoneStateBroadcaster.java b/src/com/android/telecomm/PhoneStateBroadcaster.java
index d6f1a38..4dee4bb 100644
--- a/src/com/android/telecomm/PhoneStateBroadcaster.java
+++ b/src/com/android/telecomm/PhoneStateBroadcaster.java
@@ -18,8 +18,8 @@
 
 import android.Manifest;
 import android.content.Intent;
-import android.telecomm.CallService;
 import android.telecomm.CallState;
+import android.telecomm.ConnectionService;
 import android.telecomm.TelecommConstants;
 import android.telephony.DisconnectCause;
 import android.telephony.TelephonyManager;
@@ -68,9 +68,11 @@
         }
 
         // TODO: Replace these with real constants once this API has been vetted.
-        CallServiceWrapper callService = call.getCallService();
-        if (callService != null) {
-            intent.putExtra(CallService.class.getName(), callService.getComponentName());
+        ConnectionServiceWrapper connectionService = call.getConnectionService();
+        if (connectionService != null) {
+            intent.putExtra(
+                    TelecommConstants.EXTRA_CONNECTION_SERVICE,
+                    connectionService.getComponentName());
         }
 
         // TODO: Replace these with real constants once this API has been vetted.
diff --git a/src/com/android/telecomm/RingbackPlayer.java b/src/com/android/telecomm/RingbackPlayer.java
index 8fd6697..bfd5f62 100644
--- a/src/com/android/telecomm/RingbackPlayer.java
+++ b/src/com/android/telecomm/RingbackPlayer.java
@@ -60,16 +60,15 @@
     }
 
     @Override
-    public void onCallServiceChanged(
+    public void onConnectionServiceChanged(
             Call call,
-            CallServiceWrapper oldCallServiceWrapper,
-            CallServiceWrapper newCallService) {
+            ConnectionServiceWrapper oldService,
+            ConnectionServiceWrapper newService) {
 
-        super.onCallServiceChanged(call, oldCallServiceWrapper, newCallService);
         // Treat as ending or begining dialing based on the state transition.
         if (shouldStartRinging(call)) {
             startRingbackForCall(call);
-        } else if (newCallService == null) {
+        } else if (newService == null) {
             stopRingbackForCall(call);
         }
     }
diff --git a/src/com/android/telecomm/ServiceBinder.java b/src/com/android/telecomm/ServiceBinder.java
index 55e39f0..e918593 100644
--- a/src/com/android/telecomm/ServiceBinder.java
+++ b/src/com/android/telecomm/ServiceBinder.java
@@ -81,7 +81,7 @@
                 Intent serviceIntent = new Intent(mServiceAction).setComponent(mComponentName);
                 ServiceConnection connection = new ServiceBinderConnection();
 
-                Log.d(ServiceBinder.this, "Binding to call service with intent: %s", serviceIntent);
+                Log.d(ServiceBinder.this, "Binding to service with intent: %s", serviceIntent);
                 if (!mContext.bindService(serviceIntent, connection, Context.BIND_AUTO_CREATE)) {
                     handleFailedConnection();
                     return;
diff --git a/src/com/android/telecomm/Switchboard.java b/src/com/android/telecomm/Switchboard.java
index 7c6d44d..b7a7e9e 100644
--- a/src/com/android/telecomm/Switchboard.java
+++ b/src/com/android/telecomm/Switchboard.java
@@ -20,7 +20,6 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
-import android.telecomm.CallInfo;
 import android.telecomm.CallServiceDescriptor;
 import android.telecomm.TelecommConstants;
 
@@ -34,7 +33,7 @@
 import java.util.Set;
 
 /**
- * Switchboard is responsible for gathering the {@link CallServiceWrapper}s through
+ * Switchboard is responsible for gathering the {@link ConnectionServiceWrapper}s through
  *       which to place outgoing calls
  */
 final class Switchboard {
@@ -75,8 +74,8 @@
      */
     void retrieveIncomingCall(Call call, CallServiceDescriptor descriptor, Bundle extras) {
         Log.d(this, "retrieveIncomingCall");
-        CallServiceWrapper callService = mCallServiceRepository.getService(descriptor);
-        call.setCallService(callService);
+        ConnectionServiceWrapper service = mCallServiceRepository.getService(descriptor);
+        call.setConnectionService(service);
         mIncomingCallsManager.retrieveIncomingCall(call, extras);
     }
 }
diff --git a/src/com/android/telecomm/TelephonyUtil.java b/src/com/android/telecomm/TelephonyUtil.java
index 83303c7..783b427 100644
--- a/src/com/android/telecomm/TelephonyUtil.java
+++ b/src/com/android/telecomm/TelephonyUtil.java
@@ -35,7 +35,7 @@
 
     private TelephonyUtil() {}
 
-    static boolean isPstnCallService(CallServiceDescriptor descriptor) {
+    static boolean isPstnConnectionService(CallServiceDescriptor descriptor) {
         final ComponentName pstnComponentName = new ComponentName(
                 TELEPHONY_PACKAGE_NAME, PSTN_CALL_SERVICE_CLASS_NAME);
         return pstnComponentName.equals(descriptor.getServiceComponent());
@@ -47,26 +47,27 @@
      */
     static boolean isCurrentlyPSTNCall(Call call) {
         if (Log.DEBUG) {
-            verifyCallServiceExists(PSTN_CALL_SERVICE_CLASS_NAME);
+            verifyConnectionServiceExists(PSTN_CALL_SERVICE_CLASS_NAME);
         }
 
-        CallServiceWrapper callService = call.getCallService();
-        if (callService == null) {
+        ConnectionServiceWrapper service = call.getConnectionService();
+        if (service == null) {
             return false;
         }
-        return isPstnCallService(callService.getDescriptor());
+        return isPstnConnectionService(service.getDescriptor());
     }
 
-    private static void verifyCallServiceExists(String serviceName) {
+    private static void verifyConnectionServiceExists(String serviceName) {
         PackageManager packageManager = TelecommApp.getInstance().getPackageManager();
         try {
             ServiceInfo info = packageManager.getServiceInfo(
                     new ComponentName(TELEPHONY_PACKAGE_NAME, serviceName), 0);
             if (info == null) {
-                Log.wtf(TAG, "Error, unable to find call service: %s", serviceName);
+                Log.wtf(TAG, "Error, unable to find connection service: %s", serviceName);
             }
         } catch (PackageManager.NameNotFoundException e) {
-            Log.wtf(TAG, e, "Error, exception while trying to find call service: %s", serviceName);
+            Log.wtf(TAG, e, "Error, exception while trying to find connection service: %s",
+                    serviceName);
         }
     }
 }
