diff --git a/src/com/android/telecomm/CallServiceFinder.java b/src/com/android/telecomm/CallServiceFinder.java
index aa9f058..360c503 100644
--- a/src/com/android/telecomm/CallServiceFinder.java
+++ b/src/com/android/telecomm/CallServiceFinder.java
@@ -19,17 +19,23 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
+import android.os.IBinder;
 import android.telecomm.ICallService;
 import android.telecomm.ICallServiceProvider;
 import android.util.Log;
 
-import com.android.telecomm.CallServiceProviderProxy.CallServiceProviderConnectionCallback;
+import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 
 import java.util.List;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
 
 /**
  * Finds {@link ICallService} and {@link ICallServiceProvider} implementations on the device.
@@ -38,94 +44,282 @@
  * 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.
+     * Helper class to register/unregister call-service providers.
      */
-    interface CallServiceSearchCallback {
+    private class ProviderRegistrar {
+
         /**
-         * Method called after search has completed.
-         *
-         * @param callServices List of {@link ICallServices} found in the search.
+         * The name of the call-service provider that is expected to register with this finder.
          */
-        public void onSearchComplete(List<ICallService> callServices);
+        private ComponentName mProviderName;
+
+        /**
+         * A unique identifier for a given lookup cycle, see nextLookupId.
+         * TODO(gilad): Potentially unnecessary, consider removing.
+         */
+        int mLookupId;
+
+        /**
+         * Persists the specified parameters.
+         *
+         * @param providerName The component name of the relevant provider.
+         * @param lookupId The lookup-cycle ID.
+         */
+        ProviderRegistrar(ComponentName providerName, int lookupId) {
+            this.mProviderName = providerName;
+            this.mLookupId = lookupId;
+        }
+
+        ComponentName getProviderName() {
+            return mProviderName;
+        }
+
+        /**
+         * Registers the specified call-service provider.
+         *
+         * @param provider The provider object to register.
+         */
+        void register(ICallServiceProvider provider) {
+            registerProvider(mLookupId, mProviderName, provider);
+        }
+
+        /** Unregisters this provider. */
+        void unregister() {
+            unregisterProvider(mProviderName);
+        }
+    }
+
+    /**
+     * Wrapper around ICallServiceProvider, mostly used for binding etc.
+     *
+     * TODO(gilad): Consider making this wrapper unnecessary.
+     */
+    private class ProviderWrapper {
+
+        /**
+         * Persists the specified parameters and attempts to bind the specified provider.
+         *
+         * TODO(gilad): Consider embedding ProviderRegistrar into this class and do away
+         * with the former, or vice versa.
+         *
+         * @param context The relevant application context.
+         * @param registrar The registrar with which to register and unregister this provider.
+         */
+        ProviderWrapper(Context context, final ProviderRegistrar registrar) {
+          ComponentName name = registrar.getProviderName();
+          Preconditions.checkNotNull(name);
+          Preconditions.checkNotNull(context);
+
+          Intent serviceIntent = new Intent(CALL_SERVICE_PROVIDER_CLASS_NAME).setComponent(name);
+          Log.i(TAG, "Binding to ICallServiceProvider through " + serviceIntent);
+
+          // Connection object for the service binding.
+          ServiceConnection connection = new ServiceConnection() {
+              @Override
+              public void onServiceConnected(ComponentName className, IBinder service) {
+                  registrar.register(ICallServiceProvider.Stub.asInterface(service));
+              }
+
+              @Override
+              public void onServiceDisconnected(ComponentName className) {
+                  registrar.unregister();
+              }
+          };
+
+          if (!context.bindService(serviceIntent, connection, Context.BIND_AUTO_CREATE)) {
+              // TODO(santoscordon): Handle error.
+          }
+        }
+    }
+
+    /**
+     * A timer task to ensure each lookup cycle is time-bound, see LOOKUP_TIMEOUT.
+     */
+    private class LookupTerminator extends TimerTask {
+        @Override
+        public void run() {
+          terminateLookup();
+        }
     }
 
     /** Used to identify log entries by this class */
-    static final String TAG = CallServiceFinder.class.getSimpleName();
-
-    /** Private constructor to prevent instances being made. */
-    private CallServiceFinder() {}
+    private static final String TAG = CallServiceFinder.class.getSimpleName();
 
     /**
-     * Asynchronously finds {@link ICallService} implementations and returns them asynchronously
-     * through the callback parameter.
-     *
-     * @param searchCallback The callback executed when the search is complete.
+     * The longest period in milliseconds each lookup cycle is allowed to span over, see mTimer.
+     * TODO(gilad): Likely requires tuning.
      */
-    public static void findCallServices(Context context,
-            final CallServiceSearchCallback searchCallback) {
-        List<ComponentName> components = getAllProviderComponents(context);
+    private static final int LOOKUP_TIMEOUT = 100;
 
-        Log.i(TAG, "Found " + components.size() + " implementations for ICallServiceProvider");
+    /**
+     * Used to retrieve all known ICallServiceProvider implementations from the framework.
+     * TODO(gilad): Move to a more logical place for this to be shared.
+     */
+    static final String CALL_SERVICE_PROVIDER_CLASS_NAME = ICallServiceProvider.class.getName();
 
-        for (ComponentName componentName : components) {
-            CallServiceProviderProxy proxy = new CallServiceProviderProxy(componentName, context);
-            CallServiceProviderConnectionCallback onProviderFoundCallback =
-                    new CallServiceProviderConnectionCallback() {
-                        @Override public void onConnected(ICallServiceProvider serviceProvider) {
-                            onProviderFound(serviceProvider, searchCallback);
-                        }
-                    };
+    /**
+     * Determines whether or not a lookup cycle is already running.
+     */
+    private boolean mIsLookupInProgress = false;
 
-            proxy.connect(onProviderFoundCallback);
+    /**
+     * Used to generate unique lookup-cycle identifiers. Incremented upon initiateLookup calls.
+     */
+    private int mNextLookupId = 0;
+
+    /**
+     * The set of bound call-service providers.  Only populated via initiateLookup scenarios.
+     * Providers should only be removed upon unbinding.
+     */
+    private Set<ICallServiceProvider> mProviderRegistry = Sets.newHashSet();
+
+    /**
+     * Stores the names of the providers to bind to in one lookup cycle.  The set size represents
+     * the number of call-service providers this finder expects to hear back from upon initiating
+     * call-service lookups, see initiateLookup. Whenever all providers respond before the lookup
+     * timeout occurs, the complete set of (available) call services is passed to the switchboard
+     * for further processing of outgoing calls etc.  When the timeout occurs before all responds
+     * are received, the partial (potentially empty) set gets passed (to the switchboard) instead.
+     * Note that cached providers do not require finding and hence are excluded from this count.
+     * Also noteworthy is that providers are dynamically removed from this set as they register.
+     */
+    private Set<ComponentName> mUnregisteredProviders;
+
+    /**
+     * Used to interrupt lookup cycles that didn't terminate naturally within the allowed
+     * period, see LOOKUP_TIMEOUT.
+     */
+    private Timer mTimer;
+
+    /**
+     * Initiates a lookup cycle for call-service providers.
+     * TODO(gilad): Expand this comment to describe the lookup flow in more detail.
+     *
+     * @param context The relevant application context.
+     */
+    public synchronized void initiateLookup(Context context) {
+        if (mIsLookupInProgress) {
+            // At most one active lookup is allowed at any given time, bail out.
+            return;
+        }
+
+        List<ComponentName> providerNames = getProviderNames(context);
+        if (providerNames.isEmpty()) {
+            Log.i(TAG, "No ICallServiceProvider implementations found.");
+            updateSwitchboard();
+            return;
+        }
+
+        mIsLookupInProgress = true;
+        mUnregisteredProviders = Sets.newHashSet();
+
+        int lookupId = mNextLookupId++;
+        for (ComponentName name : providerNames) {
+            if (!mProviderRegistry.contains(name)) {
+                // The provider is either not yet registered or has been unregistered
+                // due to unbinding etc.
+                ProviderRegistrar registrar = new ProviderRegistrar(name, lookupId);
+                new ProviderWrapper(context, registrar);
+                mUnregisteredProviders.add(name);
+            }
+        }
+
+        int providerCount = providerNames.size();
+        int unregisteredProviderCount = mUnregisteredProviders.size();
+
+        Log.i(TAG, "Found " + providerCount + " implementations for ICallServiceProvider, "
+                + unregisteredProviderCount + " of which are not currently registered.");
+
+        if (unregisteredProviderCount == 0) {
+            // All known (provider) implementations are already registered, pass control
+            // back to the switchboard.
+            updateSwitchboard();
+        } else {
+            // Start the timeout for this lookup cycle.
+            // TODO(gilad): Consider reusing the same timer instead of creating new ones.
+            if (mTimer != null) {
+                // Shouldn't be running but better safe than sorry.
+                mTimer.cancel();
+            }
+            mTimer = new Timer();
+            mTimer.schedule(new LookupTerminator(), LOOKUP_TIMEOUT);
         }
     }
 
     /**
-     * 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.
+     * Returns the all-inclusive list of call-service-provider names.
      *
-     * @param serviceProvider The instance of ICallServiceProvider.
+     * @param context The relevant/application context to query against.
+     * @return The list containing the (component) names of all known ICallServiceProvider
+     *     implementations or the empty list upon no available providers.
      */
-    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();
+    private List<ComponentName> getProviderNames(Context context) {
+        // The list of provider names to return to the caller, may be populated below.
+        List<ComponentName> providerNames = Lists.newArrayList();
 
         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;
+        Intent intent = new Intent(CALL_SERVICE_PROVIDER_CLASS_NAME);
+        for (ResolveInfo entry : packageManager.queryIntentServices(intent, 0)) {
+            ServiceInfo serviceInfo = entry.serviceInfo;
+            if (serviceInfo != null) {
+                // The entry resolves to a proper service, add it to the list of provider names.
+                providerNames.add(
+                        new ComponentName(serviceInfo.packageName, serviceInfo.name));
             }
-
-            ComponentName componentName = new ComponentName(serviceInfo.packageName,
-                    serviceInfo.name);
-            components.add(componentName);
         }
 
-        return components;
+        return providerNames;
     }
 
     /**
-     * Returns the intent used to resolve all registered {@link ICallService}s.
+     * Registers the specified provider and performs the necessary bookkeeping to potentially
+     * return control to the switchboard before the timeout for the current lookup cycle.
+     *
+     * @param lookupId The lookup-cycle ID.
+     * @param providerName The component name of the relevant provider.
+     * @param provider The provider object to register.
      */
-    private static Intent getICallServiceProviderIntent() {
-       return new Intent(ICallServiceProvider.class.getName());
+    private void registerProvider(
+            int lookupId, ComponentName providerName, ICallServiceProvider provider) {
+
+      if (mUnregisteredProviders.remove(providerName)) {
+          mProviderRegistry.add(provider);
+          if (mUnregisteredProviders.size() < 1) {
+              terminateLookup();  // No other providers to wait for.
+          }
+      }
+    }
+
+    /**
+     * Unregisters the specified provider.
+     *
+     * @param providerName The component name of the relevant provider.
+     */
+    private void unregisterProvider(ComponentName providerName) {
+        mProviderRegistry.remove(providerName);
+    }
+
+    /**
+     * Timeouts the current lookup cycle, see LookupTerminator.
+     */
+    private void terminateLookup() {
+        if (mTimer != null) {
+            mTimer.cancel();  // Terminate the timer thread.
+        }
+
+        updateSwitchboard();
+        mIsLookupInProgress = false;
+    }
+
+    /**
+     * Updates the switchboard passing the relevant call services (as opposed
+     * to call-service providers).
+     */
+    private void updateSwitchboard() {
+        synchronized (mProviderRegistry) {
+            // TODO(gilad): More here.
+        }
     }
 }
diff --git a/src/com/android/telecomm/CallServiceProviderProxy.java b/src/com/android/telecomm/CallServiceProviderProxy.java
deleted file mode 100644
index b515850..0000000
--- a/src/com/android/telecomm/CallServiceProviderProxy.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.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 71c666d..ce8674f 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -22,7 +22,6 @@
 import com.android.telecomm.exceptions.RestrictedCallException;
 import com.google.common.collect.Lists;
 
-import java.util.ArrayList;
 import java.util.List;
 
 /**
diff --git a/src/com/android/telecomm/Switchboard.java b/src/com/android/telecomm/Switchboard.java
index 6ee4d22..b33df50 100644
--- a/src/com/android/telecomm/Switchboard.java
+++ b/src/com/android/telecomm/Switchboard.java
@@ -23,7 +23,6 @@
 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;
 
@@ -35,98 +34,97 @@
  * considered a different transport type).
  * TODO(santoscordon): Need to add comments on the switchboard optimizer once that it is place.
  */
-class Switchboard {
+final class Switchboard {
     /** Used to identify log entries by this class */
     private static final String TAG = Switchboard.class.getSimpleName();
 
+    private CallServiceFinder callServiceFinder = new CallServiceFinder();
+
     /**
      * 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 handle The handle to dial.  Marked as final so it can be used in the inner class.
+     * @param contactInfo Information about the entity being called. Marked as final so it can
+     *     be used in the inner class.
      * @param context The application context.
      */
-    void placeOutgoingCall(final String handle, final ContactInfo contactInfo,
-            final Context context) {
+    void placeOutgoingCall(String handle, ContactInfo contactInfo, Context context) {
+        callServiceFinder.initiateLookup(context);
 
-        CallServiceFinder.findCallServices(context, new CallServiceSearchCallback() {
-            @Override
-            public void onSearchComplete(List<ICallService> callServices) {
-                try {
-                    placeOutgoingCallInternal(handle, contactInfo, callServices);
-                } catch (CallServiceUnavailableException e) {
-                    // TODO(santoscordon): Handle error
-                }
-            }
-        });
+        // TODO(gilad): Persist the necessary parameters to attempt putting the call through
+        // once the call services become available (likely using some sort of closure).
     }
 
     /**
      * 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?
+     * TODO(gilad): Wire this logic from CallServiceFinder.updateSwitchboard.
      *
      * @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()?
-        }
-    }
+//    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()?
+//        }
+//    }
 
     /**
-     * Sorts a list of {@link ICallService} ordered by the prefered service for dialing the call.
+     * Sorts a list of {@link ICallService} ordered by the preferred service for dialing the call.
      *
      * @param callServices The list to order.
      */
