diff --git a/src/com/android/telecomm/CallActivity.java b/src/com/android/telecomm/CallActivity.java
index 54424e4..7258ef0 100644
--- a/src/com/android/telecomm/CallActivity.java
+++ b/src/com/android/telecomm/CallActivity.java
@@ -17,6 +17,7 @@
 package com.android.telecomm;
 
 import android.app.Activity;
+import android.content.Context;
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.os.Bundle;
@@ -95,12 +96,17 @@
         String handle = intent.getDataString();
         ContactInfo contactInfo = null;
         try {
-          mCallsManager.processOutgoingCallIntent(handle, contactInfo);
+            // we use the application context because the lifetime of the call services bound on
+            // this context extends beyond the life of this activity.
+            Context context = getApplicationContext();
+
+            mCallsManager.processOutgoingCallIntent(handle, contactInfo, context);
         } catch (RestrictedCallException e) {
-          // TODO(gilad): Handle or explicitly state to be ignored.
+            // TODO(gilad): Handle or explicitly state to be ignored.
         } catch (CallServiceUnavailableException e) {
-          // TODO(gilad): Handle or explicitly state to be ignored. If both should be ignored, consider
-          // extending from the same base class and simplify the handling code to a single catch clause.
+            // TODO(gilad): Handle or explicitly state to be ignored. If both should be ignored,
+            // consider extending from the same base class and simplify the handling code to a
+            // single catch clause.
         }
     }
 }
diff --git a/src/com/android/telecomm/CallServiceFinder.java b/src/com/android/telecomm/CallServiceFinder.java
new file mode 100644
index 0000000..aa9f058
--- /dev/null
+++ b/src/com/android/telecomm/CallServiceFinder.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telecomm;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.telecomm.ICallService;
+import android.telecomm.ICallServiceProvider;
+import android.util.Log;
+
+import com.android.telecomm.CallServiceProviderProxy.CallServiceProviderConnectionCallback;
+import com.google.common.collect.Lists;
+
+import java.util.List;
+
+/**
+ * Finds {@link ICallService} and {@link ICallServiceProvider} implementations on the device.
+ * Uses binder APIs to find ICallServiceProviders and calls method on ICallServiceProvider to
+ * find ICallService implementations.
+ * TODO(santoscordon): Add performance timing to async calls.
+ */
+final class CallServiceFinder {
+    /**
+     * Implemented by classes which want to receive the final list of {@link CallService}s found.
+     */
+    interface CallServiceSearchCallback {
+        /**
+         * Method called after search has completed.
+         *
+         * @param callServices List of {@link ICallServices} found in the search.
+         */
+        public void onSearchComplete(List<ICallService> callServices);
+    }
+
+    /** Used to identify log entries by this class */
+    static final String TAG = CallServiceFinder.class.getSimpleName();
+
+    /** Private constructor to prevent instances being made. */
+    private CallServiceFinder() {}
+
+    /**
+     * Asynchronously finds {@link ICallService} implementations and returns them asynchronously
+     * through the callback parameter.
+     *
+     * @param searchCallback The callback executed when the search is complete.
+     */
+    public static void findCallServices(Context context,
+            final CallServiceSearchCallback searchCallback) {
+        List<ComponentName> components = getAllProviderComponents(context);
+
+        Log.i(TAG, "Found " + components.size() + " implementations for ICallServiceProvider");
+
+        for (ComponentName componentName : components) {
+            CallServiceProviderProxy proxy = new CallServiceProviderProxy(componentName, context);
+            CallServiceProviderConnectionCallback onProviderFoundCallback =
+                    new CallServiceProviderConnectionCallback() {
+                        @Override public void onConnected(ICallServiceProvider serviceProvider) {
+                            onProviderFound(serviceProvider, searchCallback);
+                        }
+                    };
+
+            proxy.connect(onProviderFoundCallback);
+        }
+    }
+
+    /**
+     * Called after a {@link CallServiceProviderProxy} attempts to bind to its
+     * {@link ICallServiceProvider} counterpart. When this method is called, the proxy should
+     * have either made a successful connection or an error occurred.
+     *
+     * @param serviceProvider The instance of ICallServiceProvider.
+     */
+    private static void onProviderFound(ICallServiceProvider serviceProvider,
+            CallServiceSearchCallback searchCallback) {
+        if (serviceProvider == null) {
+            // TODO(santoscordon): Handle error.
+        }
+
+        Log.i(TAG, "Found a service Provider: " + serviceProvider);
+
+        // TODO(santoscordon): asynchronously retrieve ICallService interfaces.
+        // TODO(santoscordon): Filter the list by only those which the user has allowed.
+    }
+
+    private static List<ComponentName> getAllProviderComponents(Context context) {
+        Intent serviceIntent = getICallServiceProviderIntent();
+
+        PackageManager packageManager = context.getPackageManager();
+        List<ResolveInfo> resolveInfos = packageManager.queryIntentServices(serviceIntent, 0);
+
+        List<ComponentName> components = Lists.newArrayList();
+        for (ResolveInfo resolveInfo : resolveInfos) {
+            ServiceInfo serviceInfo = resolveInfo.serviceInfo;
+            // Ignore anything that didn't resolve to a proper service.
+            if (serviceInfo == null) {
+                continue;
+            }
+
+            ComponentName componentName = new ComponentName(serviceInfo.packageName,
+                    serviceInfo.name);
+            components.add(componentName);
+        }
+
+        return components;
+    }
+
+    /**
+     * Returns the intent used to resolve all registered {@link ICallService}s.
+     */
+    private static Intent getICallServiceProviderIntent() {
+       return new Intent(ICallServiceProvider.class.getName());
+    }
+}
diff --git a/src/com/android/telecomm/CallServiceProviderProxy.java b/src/com/android/telecomm/CallServiceProviderProxy.java
new file mode 100644
index 0000000..b515850
--- /dev/null
+++ b/src/com/android/telecomm/CallServiceProviderProxy.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telecomm;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.telecomm.ICallServiceProvider;
+import android.util.Log;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * A proxy to a bound CallServiceProvider implementation. Given a {@link ComponentName}, this class
+ * will bind, maintain and unbind a connection with a CallServiceProvider.
+ */
+class CallServiceProviderProxy {
+    /**
+     * Interface used for notifying when the {@link ICallServiceProvider} is bound.
+     */
+    public interface CallServiceProviderConnectionCallback {
+        public void onConnected(ICallServiceProvider provider);
+    }
+
+    /** Used to identify log entries by this class */
+    static final String TAG = CallServiceFinder.class.getSimpleName();
+
+    /** Context used to bind with ICallServiceProvider. */
+    private final Context mContext;
+
+    /**
+     * Explicit component name of of the ICallServiceProvider implementation with which to bind.
+     */
+    private final ComponentName mComponentName;
+
+    /**
+     * Persists the specified parameters.
+     */
+    public CallServiceProviderProxy(ComponentName componentName, Context context) {
+        mComponentName = Preconditions.checkNotNull(componentName);
+        mContext = Preconditions.checkNotNull(context);
+    }
+
+    /**
+     * Binds with the {@link ICallServiceProvider} implementation specified by
+     * {@link #mComponentName}.
+     */
+    public void connect(final CallServiceProviderConnectionCallback connectionCallback) {
+        // TODO(santoscordon): Are there cases where we are already connected and should return
+        // early with a saved instance?
+
+        Intent serviceIntent = getServiceIntent();
+        Log.i(TAG, "Binding to ICallService through " + serviceIntent);
+
+        // Connection object for the service binding.
+        ServiceConnection connection = new ServiceConnection() {
+            @Override
+            public void onServiceConnected(ComponentName className, IBinder service) {
+                onConnected(ICallServiceProvider.Stub.asInterface(service), this,
+                        connectionCallback);
+            }
+
+            @Override
+            public void onServiceDisconnected(ComponentName className) {
+                onDisconnected(this);
+            }
+        };
+
+        if (!mContext.bindService(serviceIntent, connection, Context.BIND_AUTO_CREATE)) {
+            // TODO(santoscordon): Handle error
+        }
+
+        // At this point, we should get called on onServiceConnected asynchronously
+    }
+
+    /**
+     * Returns the service {@link Intent} used to bind to {@link ICallServiceProvider} instances.
+     */
+    private Intent getServiceIntent() {
+        Intent serviceIntent = new Intent(ICallServiceProvider.class.getName());
+        serviceIntent.setComponent(mComponentName);
+        return serviceIntent;
+    }
+
+    /**
+     * Called when an instance of ICallServiceProvider is bound to this process.
+     *
+     * @param serviceProvider The {@link ICallServiceProvider} instance that was bound.
+     * @param connection The service connection used to bind to serviceProvider.
+     */
+    private void onConnected(ICallServiceProvider serviceProvider, ServiceConnection connection,
+            CallServiceProviderConnectionCallback connectionCallback) {
+        // TODO(santoscordon): add some error conditions
+
+        connectionCallback.onConnected(serviceProvider);
+    }
+
+    /**
+     * Called when ICallServiceProvider is disconnected.  This could be for any reason including
+     * the host process dying.
+     *
+     * @param connection The service connection used to bind initially.
+     */
+    private void onDisconnected(ServiceConnection connection) {
+        // TODO(santoscordon): How to handle disconnection?
+    }
+}
diff --git a/src/com/android/telecomm/CallsManager.java b/src/com/android/telecomm/CallsManager.java
index a5fdcf7..71c666d 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -1,7 +1,26 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.android.telecomm;
 
+import android.content.Context;
+
 import com.android.telecomm.exceptions.CallServiceUnavailableException;
 import com.android.telecomm.exceptions.RestrictedCallException;
+import com.google.common.collect.Lists;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -13,64 +32,58 @@
  * access from other packages specifically refraining from passing the CallsManager instance
  * beyond the com.android.telecomm package boundary.
  */
-public class CallsManager {
+public final class CallsManager {
 
-  private static final CallsManager INSTANCE = new CallsManager();
+    private static final CallsManager INSTANCE = new CallsManager();
 
-  /**
-   * May be unnecessary per off-line discussions (between santoscordon and gilad) since the set
-   * of CallsManager APIs that need to be exposed to the dialer (or any application firing call
-   * intents) may be empty.
-   */
-  private DialerAdapter dialerAdapter;
+    /**
+     * May be unnecessary per off-line discussions (between santoscordon and gilad) since the set
+     * of CallsManager APIs that need to be exposed to the dialer (or any application firing call
+     * intents) may be empty.
+     */
+    private DialerAdapter mDialerAdapter;
 
-  private InCallAdapter inCallAdapter;
+    private InCallAdapter mInCallAdapter;
 
-  private Switchboard switchboard;
+    private Switchboard mSwitchboard;
 
-  private CallLogManager callLogManager;
+    private CallLogManager mCallLogManager;
 
-  private VoicemailManager voicemailManager;
+    private VoicemailManager mVoicemailManager;
 
-  private List<OutgoingCallFilter> outgoingCallFilters =
-      new ArrayList<OutgoingCallFilter>();
+    private List<OutgoingCallFilter> mOutgoingCallFilters = Lists.newArrayList();
 
-  private List<IncomingCallFilter> incomingCallFilters =
-      new ArrayList<IncomingCallFilter>();
+    private List<IncomingCallFilter> mIncomingCallFilters = Lists.newArrayList();
 
-  // Singleton, private constructor (see getInstance).
-  private CallsManager() {
-    switchboard = new Switchboard();
-    callLogManager = new CallLogManager();
-    voicemailManager = new VoicemailManager();  // As necessary etc.
-  }
-
-  static CallsManager getInstance() {
-    return INSTANCE;
-  }
-
-  // TODO(gilad): Circle back to how we'd want to do this.
-  void addCallService(CallService callService) {
-    if (callService != null) {
-      switchboard.addCallService(callService);
-      callService.setCallServiceAdapter(new CallServiceAdapter(this));
-    }
-  }
-
-  /**
-   * Attempts to issue/connect the specified call.  From an (arbitrary) application standpoint,
-   * all that is required to initiate this flow is to fire either of the CALL, CALL_PRIVILEGED,
-   * and CALL_EMERGENCY intents. These are listened to by CallActivity.java which then invokes
-   * this method.
-   */
-  void processOutgoingCallIntent(String handle, ContactInfo contactInfo)
-      throws RestrictedCallException, CallServiceUnavailableException {
-
-    for (OutgoingCallFilter policy : outgoingCallFilters) {
-      policy.validate(handle, contactInfo);
+    static CallsManager getInstance() {
+        return INSTANCE;
     }
 
-    // No objection to issue the call, proceed with trying to put it through.
-    switchboard.placeOutgoingCall(handle, contactInfo);
-  }
+    /**
+     * Private constructor initializes main components of telecomm.
+     */
+    private CallsManager() {
+        mSwitchboard = new Switchboard();
+    }
+
+    /**
+     * Attempts to issue/connect the specified call.  From an (arbitrary) application standpoint,
+     * all that is required to initiate this flow is to fire either of the CALL, CALL_PRIVILEGED,
+     * and CALL_EMERGENCY intents. These are listened to by CallActivity.java which then invokes
+     * this method.
+     *
+     * @param handle The handle to dial.
+     * @param contactInfo Information about the entity being called.
+     * @param context The application context.
+     */
+    void processOutgoingCallIntent(String handle, ContactInfo contactInfo, Context context)
+            throws RestrictedCallException, CallServiceUnavailableException {
+
+        for (OutgoingCallFilter policy : mOutgoingCallFilters) {
+            policy.validate(handle, contactInfo);
+        }
+
+        // No objection to issue the call, proceed with trying to put it through.
+        mSwitchboard.placeOutgoingCall(handle, contactInfo, context);
+    }
 }
diff --git a/src/com/android/telecomm/Switchboard.java b/src/com/android/telecomm/Switchboard.java
index 4d735b1..cb0d46a 100644
--- a/src/com/android/telecomm/Switchboard.java
+++ b/src/com/android/telecomm/Switchboard.java
@@ -1,68 +1,139 @@
+/*
+ * Copyright 2013, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.android.telecomm;
 
+import com.google.android.collect.Lists;
+
+import android.content.Context;
+import android.os.RemoteException;
+import android.telecomm.ICallService;
+import android.util.Log;
+
+import com.android.telecomm.CallServiceFinder.CallServiceSearchCallback;
 import com.android.telecomm.exceptions.CallServiceUnavailableException;
 import com.android.telecomm.exceptions.OutgoingCallException;
 
-import java.util.ArrayList;
 import java.util.List;
 
-/** Package private */
+/**
+ * Switchboard is responsible for (1) selecting the {@link ICallService} through which to make
+ * outgoing calls and (2) switching active calls between transports (each ICallService is
+ * considered a different transport type).
+ * TODO(santoscordon): Need to add comments on the switchboard optimizer once that it is place.
+ */
 class Switchboard {
+    /** Used to identify log entries by this class */
+    private static final String TAG = Switchboard.class.getSimpleName();
 
-  private List<CallService> callServices = new ArrayList<CallService>();
+    /**
+     * Places an outgoing call to the handle passed in. Method asynchronously collects
+     * {@link ICallService} implementations and passes them along with the handle and contactInfo
+     * to {@link #placeOutgoingCallInternal} to actually place the call.
+     *
+     * @param handle The handle to dial.
+     * @param contactInfo Information about the entity being called.
+     * @param context The application context.
+     */
+    void placeOutgoingCall(final String handle, final ContactInfo contactInfo,
+            final Context context) {
 
-  /** Package private */
-  void addCallService(CallService callService) {
-    if (callService != null && !callServices.contains(callService)) {
-      callServices.add(callService);
-    }
-  }
-
-  /** Package private */
-  void placeOutgoingCall(String userInput, ContactInfo contactInfo)
-      throws CallServiceUnavailableException {
-
-    if (callServices.isEmpty()) {
-      // No call services, bail out.
-      // TODO(contacts-team): Add logging?
-      throw new CallServiceUnavailableException();
+        CallServiceFinder.findCallServices(context, new CallServiceSearchCallback() {
+            @Override
+            public void onSearchComplete(List<ICallService> callServices) {
+                try {
+                    placeOutgoingCallInternal(handle, contactInfo, callServices);
+                } catch (CallServiceUnavailableException e) {
+                    // TODO(santoscordon): Handle error
+                }
+            }
+        });
     }
 
-    List<CallService> compatibleCallServices = new ArrayList<CallService>();
-    for (CallService service : callServices) {
-      if (service.isCompatibleWith(userInput, contactInfo)) {
-        // NOTE(android-contacts): If we end up taking the liberty to issue
-        // calls not using the explicit user input (in case one is provided)
-        // and instead pull an alternative method of communication from the
-        // specified user-info object, it may be desirable to give precedence
-        // to services that can in fact respect the user's intent.
-        compatibleCallServices.add(service);
-      }
+    /**
+     * Places an outgoing call to the handle passed in. Given a list of {@link ICallServices},
+     * select one and place a call to the handle.
+     * TODO(santoscordon): How does the CallService selection process work?
+     *
+     * @param handle The handle to dial.
+     * @param contactInfo Information about the entity being called.
+     * @param callServices The list of available {@link ICallService}s.
+     */
+    private void placeOutgoingCallInternal(String handle, ContactInfo contactInfo,
+            List<ICallService> callServices) throws CallServiceUnavailableException {
+        Log.i(TAG, "Placing and outgoing call.");
+
+        if (callServices.isEmpty()) {
+            // No call services, bail out.
+            // TODO(contacts-team): Add logging?
+            // TODO(santoscordon): Does this actually go anywhere considering this method is now
+            // asynchronous?
+            throw new CallServiceUnavailableException("No CallService found.");
+        }
+
+        List<ICallService> compatibleCallServices = Lists.newArrayList();
+        for (ICallService service : callServices) {
+            // TODO(santoscordon): This code needs to be updated to an asynchronous response
+            // callback from isCompatibleWith().
+            /* if (service.isCompatibleWith(handle)) {
+                // NOTE(android-contacts): If we end up taking the liberty to issue
+                // calls not using the explicit user input (in case one is provided)
+                // and instead pull an alternative method of communication from the
+                // specified user-info object, it may be desirable to give precedence
+                // to services that can in fact respect the user's intent.
+                compatibleCallServices.add(service);
+            }
+            */
+        }
+
+        if (compatibleCallServices.isEmpty()) {
+            // None of the available call services is suitable for making this call.
+            // TODO(contacts-team): Same here re logging.
+            throw new CallServiceUnavailableException("No compatible CallService found.");
+        }
+
+        // NOTE(android-team): At this point we can also prompt the user for
+        // preference, i.e. instead of the logic just below.
+        if (compatibleCallServices.size() > 1) {
+            compatibleCallServices = sort(compatibleCallServices);
+        }
+        for (ICallService service : compatibleCallServices) {
+            try {
+                service.call(handle);
+                return;
+            } catch (RemoteException e) {
+                // TODO(santoscordon): Need some proxy for ICallService so that we don't have to
+                // avoid RemoteExceptionHandling everywhere. Take a look at how InputMethodService
+                // handles this.
+            }
+            // catch (OutgoingCallException ignored) {
+            // TODO(santoscordon): Figure out how OutgoingCallException falls into this. Should
+            // RemoteExceptions also be converted to OutgoingCallExceptions thrown by call()?
+        }
     }
 
-    if (compatibleCallServices.isEmpty()) {
-      // None of the available call services is suitable for making this call.
-      // TODO(contacts-team): Same here re logging.
-      throw new CallServiceUnavailableException();
+    /**
+     * Sorts a list of {@link ICallService} ordered by the prefered service for dialing the call.
+     *
+     * @param callServices The list to order.
+     */
+    private List<ICallService> sort(List<ICallService> callServices) {
+        // TODO(android-contacts): Sort by reliability, cost, and ultimately
+        // the desirability to issue a given call over each of the specified
+        // call services.
+        return callServices;
     }
-
-    // NOTE(android-team): At this point we can also prompt the user for
-    // preference, i.e. instead of the logic just below.
-    if (compatibleCallServices.size() > 1) {
-      compatibleCallServices = sort(compatibleCallServices);
-    }
-    for (CallService service : compatibleCallServices) {
-      try {
-        service.placeOutgoingCall(userInput, contactInfo);
-        return;
-      } catch (OutgoingCallException ignored) { }
-    }
-  }
-  
-  private List<CallService> sort(List<CallService> callServices) {
-    // TODO(android-contacts): Sort by reliability, cost, and ultimately
-    // the desirability to issue a given call over each of the specified
-    // call services.
-    return callServices;
-  }
 }
