diff --git a/src/com/android/contacts/Collapser.java b/src/com/android/contacts/Collapser.java
index d072dce..5b5d5a0 100644
--- a/src/com/android/contacts/Collapser.java
+++ b/src/com/android/contacts/Collapser.java
@@ -17,7 +17,7 @@
 package com.android.contacts;
 
 import java.util.Iterator;
-import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Class used for collapsing data items into groups of similar items. The data items that should be
@@ -46,9 +46,9 @@
      * if {@link Collapsible#shouldCollapseWith(Object)} returns strue, and are collapsed
      * through the {@Link Collapsible#collapseWith(Object)} function implemented by the data item.
      *
-     * @param list ArrayList of Objects of type <T extends Collapsible<T>> to be collapsed.
+     * @param list List of Objects of type <T extends Collapsible<T>> to be collapsed.
      */
-    public static <T extends Collapsible<T>> void collapseList(ArrayList<T> list) {
+    public static <T extends Collapsible<T>> void collapseList(List<T> list) {
 
         int listSize = list.size();
 
diff --git a/src/com/android/contacts/quickcontact/Action.java b/src/com/android/contacts/quickcontact/Action.java
new file mode 100644
index 0000000..c9823b7
--- /dev/null
+++ b/src/com/android/contacts/quickcontact/Action.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010 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.contacts.quickcontact;
+
+import com.android.contacts.Collapser;
+
+import android.content.Intent;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+
+/**
+ * Abstract definition of an action that could be performed, along with
+ * string description and icon.
+ */
+public interface Action extends Collapser.Collapsible<Action> {
+    public CharSequence getHeader();
+    public CharSequence getBody();
+
+    public String getMimeType();
+    public Drawable getFallbackIcon();
+
+    /**
+     * Build an {@link Intent} that will perform this action.
+     */
+    public Intent getIntent();
+
+    /**
+     * Checks if the contact data for this action is primary.
+     */
+    public Boolean isPrimary();
+
+    /**
+     * Returns a lookup (@link Uri) for the contact data item.
+     */
+    public Uri getDataUri();
+}
diff --git a/src/com/android/contacts/quickcontact/ActionMultiMap.java b/src/com/android/contacts/quickcontact/ActionMultiMap.java
new file mode 100644
index 0000000..21234ce
--- /dev/null
+++ b/src/com/android/contacts/quickcontact/ActionMultiMap.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2010 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.contacts.quickcontact;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * Provide a simple way of collecting one or more {@link Action} objects
+ * under a MIME-type key.
+ */
+public class ActionMultiMap extends HashMap<String, ArrayList<Action>> {
+    public void put(String mimeType, Action info) {
+        // Create list for this MIME-type when needed
+        ArrayList<Action> collectList = get(mimeType);
+        if (collectList == null) {
+            collectList = new ArrayList<Action>();
+            put(mimeType, collectList);
+        }
+        collectList.add(info);
+    }
+}
diff --git a/src/com/android/contacts/quickcontact/DataAction.java b/src/com/android/contacts/quickcontact/DataAction.java
new file mode 100644
index 0000000..b4d5454
--- /dev/null
+++ b/src/com/android/contacts/quickcontact/DataAction.java
@@ -0,0 +1,267 @@
+package com.android.contacts.quickcontact;
+
+import com.android.contacts.ContactsUtils;
+import com.android.contacts.R;
+import com.android.contacts.model.AccountType.DataKind;
+import com.android.contacts.util.Constants;
+import com.android.contacts.util.PhoneCapabilityTester;
+
+import android.content.ContentUris;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.Im;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.SipAddress;
+import android.provider.ContactsContract.CommonDataKinds.Website;
+import android.text.TextUtils;
+import android.util.Log;
+
+/**
+ * Description of a specific {@link Data#_ID} item, with style information
+ * defined by a {@link DataKind}.
+ */
+public class DataAction implements Action {
+    private static final String TAG = "DataAction";
+
+    private final Context mContext;
+    private final DataKind mKind;
+    private final String mMimeType;
+
+    private CharSequence mHeader;
+    private CharSequence mBody;
+    private Intent mIntent;
+
+    private boolean mAlternate;
+    private Uri mDataUri;
+    private boolean mIsPrimary;
+
+    /**
+     * Create an action from common {@link Data} elements.
+     */
+    public DataAction(Context context, String mimeType, DataKind kind,
+            long dataId, Cursor cursor) {
+        mContext = context;
+        mKind = kind;
+        mMimeType = mimeType;
+
+        // Inflate strings from cursor
+        mAlternate = Constants.MIME_SMS_ADDRESS.equals(mimeType);
+        if (mAlternate && mKind.actionAltHeader != null) {
+            mHeader = mKind.actionAltHeader.inflateUsing(context, cursor);
+        } else if (mKind.actionHeader != null) {
+            mHeader = mKind.actionHeader.inflateUsing(context, cursor);
+        }
+
+        if (getAsInt(cursor, Data.IS_SUPER_PRIMARY) != 0) {
+            mIsPrimary = true;
+        }
+
+        if (mKind.actionBody != null) {
+            mBody = mKind.actionBody.inflateUsing(context, cursor);
+        }
+
+        mDataUri = ContentUris.withAppendedId(Data.CONTENT_URI, dataId);
+
+        // Handle well-known MIME-types with special care
+        if (Phone.CONTENT_ITEM_TYPE.equals(mimeType)) {
+            if (PhoneCapabilityTester.isPhone(mContext)) {
+                final String number = getAsString(cursor, Phone.NUMBER);
+                if (!TextUtils.isEmpty(number)) {
+                    final Uri callUri = Uri.fromParts(Constants.SCHEME_TEL, number, null);
+                    mIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED, callUri);
+                }
+            }
+        } else if (SipAddress.CONTENT_ITEM_TYPE.equals(mimeType)) {
+            if (PhoneCapabilityTester.isSipPhone(mContext)) {
+                final String address = getAsString(cursor, SipAddress.SIP_ADDRESS);
+                if (!TextUtils.isEmpty(address)) {
+                    final Uri callUri = Uri.fromParts(Constants.SCHEME_SIP, address, null);
+                    mIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED, callUri);
+                    // Note that this item will get a SIP-specific variant
+                    // of the "call phone" icon, rather than the standard
+                    // app icon for the Phone app (which we show for
+                    // regular phone numbers.)  That's because the phone
+                    // app explicitly specifies an android:icon attribute
+                    // for the SIP-related intent-filters in its manifest.
+                }
+            }
+        } else if (Constants.MIME_SMS_ADDRESS.equals(mimeType)) {
+            if (PhoneCapabilityTester.isSmsIntentRegistered(mContext)) {
+                final String number = getAsString(cursor, Phone.NUMBER);
+                if (!TextUtils.isEmpty(number)) {
+                    final Uri smsUri = Uri.fromParts(Constants.SCHEME_SMSTO, number, null);
+                    mIntent = new Intent(Intent.ACTION_SENDTO, smsUri);
+                }
+            }
+        } else if (Email.CONTENT_ITEM_TYPE.equals(mimeType)) {
+            final String address = getAsString(cursor, Email.DATA);
+            if (!TextUtils.isEmpty(address)) {
+                final Uri mailUri = Uri.fromParts(Constants.SCHEME_MAILTO, address, null);
+                mIntent = new Intent(Intent.ACTION_SENDTO, mailUri);
+            }
+
+        } else if (Website.CONTENT_ITEM_TYPE.equals(mimeType)) {
+            final String url = getAsString(cursor, Website.URL);
+            if (!TextUtils.isEmpty(url)) {
+                mIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+            }
+
+        } else if (Im.CONTENT_ITEM_TYPE.equals(mimeType)) {
+            final boolean isEmail = Email.CONTENT_ITEM_TYPE.equals(
+                    getAsString(cursor, Data.MIMETYPE));
+            if (isEmail || isProtocolValid(cursor)) {
+                final int protocol = isEmail ? Im.PROTOCOL_GOOGLE_TALK :
+                    getAsInt(cursor, Im.PROTOCOL);
+
+                if (isEmail) {
+                    // Use Google Talk string when using Email, and clear data
+                    // Uri so we don't try saving Email as primary.
+                    mHeader = context.getText(R.string.chat_gtalk);
+                    mDataUri = null;
+                }
+
+                String host = getAsString(cursor, Im.CUSTOM_PROTOCOL);
+                String data = getAsString(cursor,
+                        isEmail ? Email.DATA : Im.DATA);
+                if (protocol != Im.PROTOCOL_CUSTOM) {
+                    // Try bringing in a well-known host for specific protocols
+                    host = ContactsUtils.lookupProviderNameFromId(protocol);
+                }
+
+                if (!TextUtils.isEmpty(host) && !TextUtils.isEmpty(data)) {
+                    final String authority = host.toLowerCase();
+                    final Uri imUri = new Uri.Builder().scheme(Constants.SCHEME_IMTO).authority(
+                            authority).appendPath(data).build();
+                    mIntent = new Intent(Intent.ACTION_SENDTO, imUri);
+                }
+            }
+        }
+
+        if (mIntent == null) {
+            // Otherwise fall back to default VIEW action
+            mIntent = new Intent(Intent.ACTION_VIEW, mDataUri);
+        }
+
+        // Always launch as new task, since we're like a launcher
+        mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+    }
+
+    /** Read {@link String} from the given {@link Cursor}. */
+    private static String getAsString(Cursor cursor, String columnName) {
+        final int index = cursor.getColumnIndex(columnName);
+        return cursor.getString(index);
+    }
+
+    /** Read {@link Integer} from the given {@link Cursor}. */
+    private static int getAsInt(Cursor cursor, String columnName) {
+        final int index = cursor.getColumnIndex(columnName);
+        return cursor.getInt(index);
+    }
+
+    private boolean isProtocolValid(Cursor cursor) {
+        final int columnIndex = cursor.getColumnIndex(Im.PROTOCOL);
+        if (cursor.isNull(columnIndex)) {
+            return false;
+        }
+        try {
+            Integer.valueOf(cursor.getString(columnIndex));
+        } catch (NumberFormatException e) {
+            return false;
+        }
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public CharSequence getHeader() {
+        return mHeader;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public CharSequence getBody() {
+        return mBody;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String getMimeType() {
+        return mMimeType;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Uri getDataUri() {
+        return mDataUri;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Boolean isPrimary() {
+        return mIsPrimary;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Drawable getFallbackIcon() {
+        // Bail early if no valid resources
+        final String resPackageName = mKind.resPackageName;
+        if (resPackageName == null) return null;
+
+        final PackageManager pm = mContext.getPackageManager();
+        if (mAlternate && mKind.iconAltRes != -1) {
+            return pm.getDrawable(resPackageName, mKind.iconAltRes, null);
+        } else if (mKind.iconRes != -1) {
+            return pm.getDrawable(resPackageName, mKind.iconRes, null);
+        } else {
+            return null;
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Intent getIntent() {
+        return mIntent;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean collapseWith(Action other) {
+        if (!shouldCollapseWith(other)) {
+            return false;
+        }
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean shouldCollapseWith(Action t) {
+        if (t == null) {
+            return false;
+        }
+        if (!(t instanceof DataAction)) {
+            Log.e(TAG, "t must be DataAction");
+            return false;
+        }
+        DataAction other = (DataAction)t;
+        if (!ContactsUtils.areObjectsEqual(mKind, other.mKind)) {
+            return false;
+        }
+        if (!ContactsUtils.shouldCollapse(mContext, mMimeType, mBody, other.mMimeType,
+                other.mBody)) {
+            return false;
+        }
+        if (!TextUtils.equals(mMimeType, other.mMimeType)
+                || !ContactsUtils.areIntentActionEqual(mIntent, other.mIntent)
+                ) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/src/com/android/contacts/quickcontact/PackageIntentReceiver.java b/src/com/android/contacts/quickcontact/PackageIntentReceiver.java
new file mode 100644
index 0000000..7af4005
--- /dev/null
+++ b/src/com/android/contacts/quickcontact/PackageIntentReceiver.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2010 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.contacts.quickcontact;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+/**
+ * Package intent receiver that flushes the {@link ResolveCache} so that Packages are rescanned next
+ * time
+ */
+public class PackageIntentReceiver extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        ResolveCache.flush();
+    }
+}
diff --git a/src/com/android/contacts/quickcontact/ProfileAction.java b/src/com/android/contacts/quickcontact/ProfileAction.java
new file mode 100644
index 0000000..47102a5
--- /dev/null
+++ b/src/com/android/contacts/quickcontact/ProfileAction.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2010 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.contacts.quickcontact;
+
+import com.android.contacts.R;
+
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.provider.ContactsContract.Contacts;
+
+/**
+ * Specific action that launches the profile card.
+ */
+public class ProfileAction implements Action {
+    private final Context mContext;
+    private final Uri mLookupUri;
+
+    public ProfileAction(Context context, Uri lookupUri) {
+        mContext = context;
+        mLookupUri = lookupUri;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public CharSequence getHeader() {
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public CharSequence getBody() {
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String getMimeType() {
+        return Contacts.CONTENT_ITEM_TYPE;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Drawable getFallbackIcon() {
+        return mContext.getResources().getDrawable(R.drawable.ic_contacts_details);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Intent getIntent() {
+        final Intent intent = new Intent(Intent.ACTION_VIEW, mLookupUri);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        return intent;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Boolean isPrimary() {
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Uri getDataUri() {
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean collapseWith(Action t) {
+        return false; // Never dup.
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean shouldCollapseWith(Action t) {
+        return false; // Never dup.
+    }
+}
diff --git a/src/com/android/contacts/quickcontact/QuickContactBackgroundDrawable.java b/src/com/android/contacts/quickcontact/QuickContactBackgroundDrawable.java
index ef970d5..fb87bfe 100644
--- a/src/com/android/contacts/quickcontact/QuickContactBackgroundDrawable.java
+++ b/src/com/android/contacts/quickcontact/QuickContactBackgroundDrawable.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 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.contacts.quickcontact;
 
 import com.android.contacts.R;
diff --git a/src/com/android/contacts/quickcontact/QuickContactWindow.java b/src/com/android/contacts/quickcontact/QuickContactWindow.java
index e773759..cf7f126 100644
--- a/src/com/android/contacts/quickcontact/QuickContactWindow.java
+++ b/src/com/android/contacts/quickcontact/QuickContactWindow.java
@@ -18,7 +18,6 @@
 
 import com.android.contacts.Collapser;
 import com.android.contacts.ContactPresenceIconUtil;
-import com.android.contacts.ContactsUtils;
 import com.android.contacts.R;
 import com.android.contacts.model.AccountType;
 import com.android.contacts.model.AccountType.DataKind;
@@ -26,9 +25,7 @@
 import com.android.contacts.util.Constants;
 import com.android.contacts.util.DataStatus;
 import com.android.contacts.util.NotifyingAsyncQueryHandler;
-import com.android.contacts.util.PhoneCapabilityTester;
 import com.android.internal.policy.PolicyManager;
-import com.google.android.collect.Sets;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -37,11 +34,7 @@
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -89,10 +82,8 @@
 import android.widget.TextView;
 import android.widget.Toast;
 
-import java.lang.ref.SoftReference;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
@@ -133,7 +124,6 @@
 
     private NotifyingAsyncQueryHandler mHandler;
     private OnDismissListener mDismissListener;
-    private ResolveCache mResolveCache;
 
     private Uri mLookupUri;
     private Rect mAnchor;
@@ -163,9 +153,9 @@
     /**
      * Set of {@link Action} that are associated with the aggregate currently
      * displayed by this dialog, represented as a map from {@link String}
-     * MIME-type to {@link ActionList}.
+     * MIME-type to a list of {@link Action}.
      */
-    private ActionMap mActions = new ActionMap();
+    private ActionMultiMap mActions = new ActionMultiMap();
 
     /**
      * Pool of unused {@link CheckableImageView} that have previously been
@@ -202,25 +192,8 @@
             Website.CONTENT_ITEM_TYPE,
     };
 
-    /**
-     * Specific list {@link ApplicationInfo#packageName} of apps that are
-     * prefered <strong>only</strong> for the purposes of default icons when
-     * multiple {@link ResolveInfo} are found to match. This only happens when
-     * the user has not selected a default app yet, and they will still be
-     * presented with the system disambiguation dialog.
-     */
-    private static final HashSet<String> sPreferResolve = Sets.newHashSet(
-            "com.android.email",
-            "com.android.calendar",
-            "com.android.contacts",
-            "com.android.mms",
-            "com.android.phone",
-            "com.android.browser");
-
     private static final int TOKEN_DATA = 1;
 
-    static final boolean LOGD = false;
-
     static final boolean TRACE_LAUNCH = false;
     static final String TRACE_TAG = "quickcontact";
 
@@ -248,11 +221,9 @@
         mBackground = new QuickContactBackgroundDrawable();
         mRootView.setBackgroundDrawable(mBackground);
 
-        mResolveCache = new ResolveCache(mContext);
-
         mScreenWidth = mWindowManager.getDefaultDisplay().getWidth();
         // Status bar height
-        int screenMarginBottom = context.getResources().getDimensionPixelSize(
+        final int screenMarginBottom = context.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.screen_margin_bottom);
         mUseableScreenHeight = mWindowManager.getDefaultDisplay().getHeight() - screenMarginBottom;
 
@@ -537,7 +508,6 @@
         mLastAction = null;
 
         // Clear track actions and scroll to hard left
-        mResolveCache.clear();
         mActions.clear();
 
         // Recycle any chiclets in use
@@ -618,501 +588,6 @@
         }
     }
 
-    /** Read {@link String} from the given {@link Cursor}. */
-    private static String getAsString(Cursor cursor, String columnName) {
-        final int index = cursor.getColumnIndex(columnName);
-        return cursor.getString(index);
-    }
-
-    /** Read {@link Integer} from the given {@link Cursor}. */
-    private static int getAsInt(Cursor cursor, String columnName) {
-        final int index = cursor.getColumnIndex(columnName);
-        return cursor.getInt(index);
-    }
-
-    /**
-     * Abstract definition of an action that could be performed, along with
-     * string description and icon.
-     */
-    private interface Action extends Collapser.Collapsible<Action> {
-        public CharSequence getHeader();
-        public CharSequence getBody();
-
-        public String getMimeType();
-        public Drawable getFallbackIcon();
-
-        /**
-         * Build an {@link Intent} that will perform this action.
-         */
-        public Intent getIntent();
-
-        /**
-         * Checks if the contact data for this action is primary.
-         */
-        public Boolean isPrimary();
-
-        /**
-         * Returns a lookup (@link Uri) for the contact data item.
-         */
-        public Uri getDataUri();
-    }
-
-    /**
-     * Description of a specific {@link Data#_ID} item, with style information
-     * defined by a {@link DataKind}.
-     */
-    private static class DataAction implements Action {
-        private final Context mContext;
-        private final DataKind mKind;
-        private final String mMimeType;
-
-        private CharSequence mHeader;
-        private CharSequence mBody;
-        private Intent mIntent;
-
-        private boolean mAlternate;
-        private Uri mDataUri;
-        private boolean mIsPrimary;
-
-        /**
-         * Create an action from common {@link Data} elements.
-         */
-        public DataAction(Context context, String mimeType, DataKind kind,
-                long dataId, Cursor cursor) {
-            mContext = context;
-            mKind = kind;
-            mMimeType = mimeType;
-
-            // Inflate strings from cursor
-            mAlternate = Constants.MIME_SMS_ADDRESS.equals(mimeType);
-            if (mAlternate && mKind.actionAltHeader != null) {
-                mHeader = mKind.actionAltHeader.inflateUsing(context, cursor);
-            } else if (mKind.actionHeader != null) {
-                mHeader = mKind.actionHeader.inflateUsing(context, cursor);
-            }
-
-            if (getAsInt(cursor, Data.IS_SUPER_PRIMARY) != 0) {
-                mIsPrimary = true;
-            }
-
-            if (mKind.actionBody != null) {
-                mBody = mKind.actionBody.inflateUsing(context, cursor);
-            }
-
-            mDataUri = ContentUris.withAppendedId(Data.CONTENT_URI, dataId);
-
-            // Handle well-known MIME-types with special care
-            if (Phone.CONTENT_ITEM_TYPE.equals(mimeType)) {
-                if (PhoneCapabilityTester.isPhone(mContext)) {
-                    final String number = getAsString(cursor, Phone.NUMBER);
-                    if (!TextUtils.isEmpty(number)) {
-                        final Uri callUri = Uri.fromParts(Constants.SCHEME_TEL, number, null);
-                        mIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED, callUri);
-                    }
-                }
-            } else if (SipAddress.CONTENT_ITEM_TYPE.equals(mimeType)) {
-                if (PhoneCapabilityTester.isSipPhone(mContext)) {
-                    final String address = getAsString(cursor, SipAddress.SIP_ADDRESS);
-                    if (!TextUtils.isEmpty(address)) {
-                        final Uri callUri = Uri.fromParts(Constants.SCHEME_SIP, address, null);
-                        mIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED, callUri);
-                        // Note that this item will get a SIP-specific variant
-                        // of the "call phone" icon, rather than the standard
-                        // app icon for the Phone app (which we show for
-                        // regular phone numbers.)  That's because the phone
-                        // app explicitly specifies an android:icon attribute
-                        // for the SIP-related intent-filters in its manifest.
-                    }
-                }
-            } else if (Constants.MIME_SMS_ADDRESS.equals(mimeType)) {
-                if (PhoneCapabilityTester.isSmsIntentRegistered(mContext)) {
-                    final String number = getAsString(cursor, Phone.NUMBER);
-                    if (!TextUtils.isEmpty(number)) {
-                        final Uri smsUri = Uri.fromParts(Constants.SCHEME_SMSTO, number, null);
-                        mIntent = new Intent(Intent.ACTION_SENDTO, smsUri);
-                    }
-                }
-            } else if (Email.CONTENT_ITEM_TYPE.equals(mimeType)) {
-                final String address = getAsString(cursor, Email.DATA);
-                if (!TextUtils.isEmpty(address)) {
-                    final Uri mailUri = Uri.fromParts(Constants.SCHEME_MAILTO, address, null);
-                    mIntent = new Intent(Intent.ACTION_SENDTO, mailUri);
-                }
-
-            } else if (Website.CONTENT_ITEM_TYPE.equals(mimeType)) {
-                final String url = getAsString(cursor, Website.URL);
-                if (!TextUtils.isEmpty(url)) {
-                    mIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
-                }
-
-            } else if (Im.CONTENT_ITEM_TYPE.equals(mimeType)) {
-                final boolean isEmail = Email.CONTENT_ITEM_TYPE.equals(
-                        getAsString(cursor, Data.MIMETYPE));
-                if (isEmail || isProtocolValid(cursor)) {
-                    final int protocol = isEmail ? Im.PROTOCOL_GOOGLE_TALK :
-                            getAsInt(cursor, Im.PROTOCOL);
-
-                    if (isEmail) {
-                        // Use Google Talk string when using Email, and clear data
-                        // Uri so we don't try saving Email as primary.
-                        mHeader = context.getText(R.string.chat_gtalk);
-                        mDataUri = null;
-                    }
-
-                    String host = getAsString(cursor, Im.CUSTOM_PROTOCOL);
-                    String data = getAsString(cursor, isEmail ? Email.DATA : Im.DATA);
-                    if (protocol != Im.PROTOCOL_CUSTOM) {
-                        // Try bringing in a well-known host for specific protocols
-                        host = ContactsUtils.lookupProviderNameFromId(protocol);
-                    }
-
-                    if (!TextUtils.isEmpty(host) && !TextUtils.isEmpty(data)) {
-                        final String authority = host.toLowerCase();
-                        final Uri imUri = new Uri.Builder().scheme(Constants.SCHEME_IMTO).authority(
-                                authority).appendPath(data).build();
-                        mIntent = new Intent(Intent.ACTION_SENDTO, imUri);
-                    }
-                }
-            }
-
-            if (mIntent == null) {
-                // Otherwise fall back to default VIEW action
-                mIntent = new Intent(Intent.ACTION_VIEW, mDataUri);
-            }
-
-            // Always launch as new task, since we're like a launcher
-            mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        }
-
-        private boolean isProtocolValid(Cursor cursor) {
-            final int columnIndex = cursor.getColumnIndex(Im.PROTOCOL);
-            if (cursor.isNull(columnIndex)) {
-                return false;
-            }
-            try {
-                Integer.valueOf(cursor.getString(columnIndex));
-            } catch (NumberFormatException e) {
-                return false;
-            }
-            return true;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public CharSequence getHeader() {
-            return mHeader;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public CharSequence getBody() {
-            return mBody;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public String getMimeType() {
-            return mMimeType;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public Uri getDataUri() {
-            return mDataUri;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public Boolean isPrimary() {
-            return mIsPrimary;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public Drawable getFallbackIcon() {
-            // Bail early if no valid resources
-            final String resPackageName = mKind.resPackageName;
-            if (resPackageName == null) return null;
-
-            final PackageManager pm = mContext.getPackageManager();
-            if (mAlternate && mKind.iconAltRes != -1) {
-                return pm.getDrawable(resPackageName, mKind.iconAltRes, null);
-            } else if (mKind.iconRes != -1) {
-                return pm.getDrawable(resPackageName, mKind.iconRes, null);
-            } else {
-                return null;
-            }
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public Intent getIntent() {
-            return mIntent;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public boolean collapseWith(Action other) {
-            if (!shouldCollapseWith(other)) {
-                return false;
-            }
-            return true;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public boolean shouldCollapseWith(Action t) {
-            if (t == null) {
-                return false;
-            }
-            if (!(t instanceof DataAction)) {
-                Log.e(TAG, "t must be DataAction");
-                return false;
-            }
-            DataAction other = (DataAction)t;
-            if (!ContactsUtils.areObjectsEqual(mKind, other.mKind)) {
-                return false;
-            }
-            if (!ContactsUtils.shouldCollapse(mContext, mMimeType, mBody, other.mMimeType,
-                    other.mBody)) {
-                return false;
-            }
-            if (!TextUtils.equals(mMimeType, other.mMimeType)
-                    || !ContactsUtils.areIntentActionEqual(mIntent, other.mIntent)
-                    ) {
-                return false;
-            }
-            return true;
-        }
-    }
-
-    /**
-     * Specific action that launches the profile card.
-     */
-    private static class ProfileAction implements Action {
-        private final Context mContext;
-        private final Uri mLookupUri;
-
-        public ProfileAction(Context context, Uri lookupUri) {
-            mContext = context;
-            mLookupUri = lookupUri;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public CharSequence getHeader() {
-            return null;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public CharSequence getBody() {
-            return null;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public String getMimeType() {
-            return Contacts.CONTENT_ITEM_TYPE;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public Drawable getFallbackIcon() {
-            return mContext.getResources().getDrawable(R.drawable.ic_contacts_details);
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public Intent getIntent() {
-            final Intent intent = new Intent(Intent.ACTION_VIEW, mLookupUri);
-            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-            return intent;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public Boolean isPrimary() {
-            return null;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public Uri getDataUri() {
-            return null;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public boolean collapseWith(Action t) {
-            return false; // Never dup.
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public boolean shouldCollapseWith(Action t) {
-            return false; // Never dup.
-        }
-    }
-
-    /**
-     * Internally hold a cache of scaled icons based on {@link PackageManager}
-     * queries, keyed internally on MIME-type.
-     */
-    private static class ResolveCache {
-        private PackageManager mPackageManager;
-
-        /**
-         * Cached entry holding the best {@link ResolveInfo} for a specific
-         * MIME-type, along with a {@link SoftReference} to its icon.
-         */
-        private static class Entry {
-            public ResolveInfo bestResolve;
-            public Drawable icon;
-        }
-
-        private HashMap<String, Entry> mCache = new HashMap<String, Entry>();
-
-        public ResolveCache(Context context) {
-            mPackageManager = context.getPackageManager();
-        }
-
-        /**
-         * Get the {@link Entry} best associated with the given {@link Action},
-         * or create and populate a new one if it doesn't exist.
-         */
-        protected Entry getEntry(Action action) {
-            final String mimeType = action.getMimeType();
-            Entry entry = mCache.get(mimeType);
-            if (entry != null) return entry;
-            entry = new Entry();
-
-            final Intent intent = action.getIntent();
-            if (intent != null) {
-                final List<ResolveInfo> matches = mPackageManager.queryIntentActivities(intent,
-                        PackageManager.MATCH_DEFAULT_ONLY);
-
-                // Pick first match, otherwise best found
-                ResolveInfo bestResolve = null;
-                final int size = matches.size();
-                if (size == 1) {
-                    bestResolve = matches.get(0);
-                } else if (size > 1) {
-                    bestResolve = getBestResolve(intent, matches);
-                }
-
-                if (bestResolve != null) {
-                    final Drawable icon = bestResolve.loadIcon(mPackageManager);
-
-                    entry.bestResolve = bestResolve;
-                    entry.icon = icon;
-                }
-            }
-
-            mCache.put(mimeType, entry);
-            return entry;
-        }
-
-        /**
-         * Best {@link ResolveInfo} when multiple found. Ties are broken by
-         * selecting first from the {QuickContactWindow#sPreferResolve} list of
-         * preferred packages, second by apps that live on the system partition,
-         * otherwise the app from the top of the list. This is
-         * <strong>only</strong> used for selecting a default icon for
-         * displaying in the track, and does not shortcut the system
-         * {@link Intent} disambiguation dialog.
-         */
-        protected ResolveInfo getBestResolve(Intent intent, List<ResolveInfo> matches) {
-            // Try finding preferred activity, otherwise detect disambig
-            final ResolveInfo foundResolve = mPackageManager.resolveActivity(intent,
-                    PackageManager.MATCH_DEFAULT_ONLY);
-            final boolean foundDisambig = (foundResolve.match &
-                    IntentFilter.MATCH_CATEGORY_MASK) == 0;
-
-            if (!foundDisambig) {
-                // Found concrete match, so return directly
-                return foundResolve;
-            }
-
-            // Accept any package from prefer list, otherwise first system app
-            ResolveInfo firstSystem = null;
-            for (ResolveInfo info : matches) {
-                final boolean isSystem = (info.activityInfo.applicationInfo.flags
-                        & ApplicationInfo.FLAG_SYSTEM) != 0;
-                final boolean isPrefer = QuickContactWindow.sPreferResolve
-                        .contains(info.activityInfo.applicationInfo.packageName);
-
-
-
-                if (isPrefer) return info;
-                if (isSystem && firstSystem == null) firstSystem = info;
-            }
-
-            // Return first system found, otherwise first from list
-            return firstSystem != null ? firstSystem : matches.get(0);
-        }
-
-        /**
-         * Check {@link PackageManager} to see if any apps offer to handle the
-         * given {@link Action}.
-         */
-        public boolean hasResolve(Action action) {
-            return getEntry(action).bestResolve != null;
-        }
-
-        /**
-         * Find the best description for the given {@link Action}, usually used
-         * for accessibility purposes.
-         */
-        public CharSequence getDescription(Action action) {
-            final CharSequence actionHeader = action.getHeader();
-            final ResolveInfo info = getEntry(action).bestResolve;
-            if (!TextUtils.isEmpty(actionHeader)) {
-                return actionHeader;
-            } else if (info != null) {
-                return info.loadLabel(mPackageManager);
-            } else {
-                return null;
-            }
-        }
-
-        /**
-         * Return the best icon for the given {@link Action}, which is usually
-         * based on the {@link ResolveInfo} found through a
-         * {@link PackageManager} query.
-         */
-        public Drawable getIcon(Action action) {
-            return getEntry(action).icon;
-        }
-
-        public void clear() {
-            mCache.clear();
-        }
-    }
-
-    /**
-     * Provide a strongly-typed {@link LinkedList} that holds a list of
-     * {@link Action} objects.
-     */
-    private class ActionList extends ArrayList<Action> {
-    }
-
-    /**
-     * Provide a simple way of collecting one or more {@link Action} objects
-     * under a MIME-type key.
-     */
-    private class ActionMap extends HashMap<String, ActionList> {
-        private void collect(String mimeType, Action info) {
-            // Create list for this MIME-type when needed
-            ActionList collectList = get(mimeType);
-            if (collectList == null) {
-                collectList = new ActionList();
-                put(mimeType, collectList);
-            }
-            collectList.add(info);
-        }
-    }
-
     /**
      * Check if the given MIME-type appears in the list of excluded MIME-types
      * that the most-recent caller requested.
@@ -1131,6 +606,7 @@
      * Handle the result from the {@link #TOKEN_DATA} query.
      */
     private void handleData(Cursor cursor) {
+        final ResolveCache cache = ResolveCache.getInstance(mContext.getPackageManager());
         if (cursor == null) return;
         if (cursor.getCount() == 0) {
             Toast.makeText(mContext, R.string.invalidContactMessage, Toast.LENGTH_LONG).show();
@@ -1141,7 +617,7 @@
         if (!isMimeExcluded(Contacts.CONTENT_ITEM_TYPE)) {
             // Add the profile shortcut action
             final Action action = new ProfileAction(mContext, mLookupUri);
-            mActions.collect(Contacts.CONTENT_ITEM_TYPE, action);
+            mActions.put(Contacts.CONTENT_ITEM_TYPE, action);
         }
 
         final DataStatus status = new DataStatus();
@@ -1178,14 +654,14 @@
                 // element, build its summary from the cursor, and collect it
                 // along with all others of this MIME-type.
                 final Action action = new DataAction(mContext, mimeType, kind, dataId, cursor);
-                considerAdd(action, mimeType);
+                considerAdd(action, mimeType, cache);
             }
 
             // If phone number, also insert as text message action
             if (Phone.CONTENT_ITEM_TYPE.equals(mimeType) && kind != null) {
                 final Action action = new DataAction(mContext, Constants.MIME_SMS_ADDRESS,
                         kind, dataId, cursor);
-                considerAdd(action, Constants.MIME_SMS_ADDRESS);
+                considerAdd(action, Constants.MIME_SMS_ADDRESS, cache);
             }
 
             // Handle Email rows with presence data as Im entry
@@ -1196,7 +672,7 @@
                 if (imKind != null) {
                     final Action action = new DataAction(mContext, Im.CONTENT_ITEM_TYPE, imKind,
                             dataId, cursor);
-                    considerAdd(action, Im.CONTENT_ITEM_TYPE);
+                    considerAdd(action, Im.CONTENT_ITEM_TYPE, cache);
                 }
             }
         }
@@ -1238,7 +714,7 @@
         for (String mimeType : PRECEDING_MIMETYPES) {
             if (containedTypes.contains(mimeType)) {
                 hasData = true;
-                mTrack.addView(inflateAction(mimeType), index++);
+                mTrack.addView(inflateAction(mimeType, cache), index++);
                 containedTypes.remove(mimeType);
             }
         }
@@ -1250,7 +726,7 @@
         for (String mimeType : FOLLOWING_MIMETYPES) {
             if (containedTypes.contains(mimeType)) {
                 hasData = true;
-                mTrack.addView(inflateAction(mimeType), index++);
+                mTrack.addView(inflateAction(mimeType, cache), index++);
                 containedTypes.remove(mimeType);
             }
         }
@@ -1261,7 +737,7 @@
         if (remainingTypes.length > 0) hasData = true;
         Arrays.sort(remainingTypes);
         for (String mimeType : remainingTypes) {
-            mTrack.addView(inflateAction(mimeType), index++);
+            mTrack.addView(inflateAction(mimeType, cache), index++);
         }
 
         // When there is no data to display, add a TextView to show the user there's no data
@@ -1276,9 +752,9 @@
      * {@link PackageManager} finds an application to handle
      * {@link Action#getIntent()}.
      */
-    private void considerAdd(Action action, String mimeType) {
-        if (mResolveCache.hasResolve(action)) {
-            mActions.collect(mimeType, action);
+    private void considerAdd(Action action, String mimeType, ResolveCache resolveCache) {
+        if (resolveCache.hasResolve(action)) {
+            mActions.put(mimeType, action);
         }
     }
 
@@ -1313,12 +789,12 @@
      * Inflate the in-track view for the action of the given MIME-type, collapsing duplicate values.
      * Will use the icon provided by the {@link DataKind}.
      */
-    private View inflateAction(String mimeType) {
+    private View inflateAction(String mimeType, ResolveCache resolveCache) {
         final CheckableImageView view = (CheckableImageView)obtainView();
         boolean isActionSet = false;
 
         // Add direct intent if single child, otherwise flag for multiple
-        ActionList children = mActions.get(mimeType);
+        List<Action> children = mActions.get(mimeType);
         if (children.size() > 1) {
             Collapser.collapseList(children);
         }
@@ -1339,8 +815,8 @@
         }
 
         // Set icon and listen for clicks
-        final CharSequence descrip = mResolveCache.getDescription(firstInfo);
-        final Drawable icon = mResolveCache.getIcon(firstInfo);
+        final CharSequence descrip = resolveCache.getDescription(firstInfo);
+        final Drawable icon = resolveCache.getIcon(firstInfo);
         view.setChecked(false);
         view.setContentDescription(descrip);
         view.setImageDrawable(icon);
@@ -1459,7 +935,7 @@
                 // Defer the action to make the window properly repaint
                 new Handler().post(startAppRunnable);
             }
-        } else if (tag instanceof ActionList) {
+        } else if (tag instanceof ArrayList<?>) {
             // Don't do anything if already open
             if (actionView != mLastAction) {
                 final Runnable configureListRunnable = new Runnable() {
@@ -1469,7 +945,7 @@
                         setNewActionViewChecked(actionView);
 
                         // Incoming tag is a MIME-type, so show resolution list
-                        final ActionList children = (ActionList)tag;
+                        final ArrayList<?> children = (ArrayList<?>)tag;
 
                         mResolveList.setOnItemClickListener(QuickContactWindow.this);
                         mResolveList.setAdapter(new BaseAdapter() {
diff --git a/src/com/android/contacts/quickcontact/ResolveCache.java b/src/com/android/contacts/quickcontact/ResolveCache.java
new file mode 100644
index 0000000..5d84253
--- /dev/null
+++ b/src/com/android/contacts/quickcontact/ResolveCache.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2010 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.contacts.quickcontact;
+
+import com.google.android.collect.Sets;
+
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
+
+import java.lang.ref.SoftReference;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+
+/**
+ * Internally hold a cache of scaled icons based on {@link PackageManager}
+ * queries, keyed internally on MIME-type.
+ */
+public class ResolveCache {
+    /**
+     * Specific list {@link ApplicationInfo#packageName} of apps that are
+     * prefered <strong>only</strong> for the purposes of default icons when
+     * multiple {@link ResolveInfo} are found to match. This only happens when
+     * the user has not selected a default app yet, and they will still be
+     * presented with the system disambiguation dialog.
+     */
+    private static final HashSet<String> sPreferResolve = Sets.newHashSet(
+            "com.android.email",
+            "com.android.calendar",
+            "com.android.contacts",
+            "com.android.mms",
+            "com.android.phone",
+            "com.android.browser");
+
+    private final PackageManager mPackageManager;
+
+    private static ResolveCache sInstance;
+
+    /**
+     * Returns an instance of the ResolveCache. Only one internal instance is kept, so
+     * the argument packageManagers is ignored for all but the first call
+     */
+    public synchronized static ResolveCache getInstance(PackageManager packageManager) {
+        if (sInstance == null) {
+            return sInstance = new ResolveCache(packageManager);
+        }
+        return sInstance;
+    }
+
+    public synchronized static void flush() {
+        sInstance = null;
+    }
+
+    /**
+     * Cached entry holding the best {@link ResolveInfo} for a specific
+     * MIME-type, along with a {@link SoftReference} to its icon.
+     */
+    private static class Entry {
+        public ResolveInfo bestResolve;
+        public Drawable icon;
+    }
+
+    private HashMap<String, Entry> mCache = new HashMap<String, Entry>();
+
+    private ResolveCache(PackageManager packageManager) {
+        mPackageManager = packageManager;
+    }
+
+    /**
+     * Get the {@link Entry} best associated with the given {@link Action},
+     * or create and populate a new one if it doesn't exist.
+     */
+    protected Entry getEntry(Action action) {
+        final String mimeType = action.getMimeType();
+        Entry entry = mCache.get(mimeType);
+        if (entry != null) return entry;
+        entry = new Entry();
+
+        final Intent intent = action.getIntent();
+        if (intent != null) {
+            final List<ResolveInfo> matches = mPackageManager.queryIntentActivities(intent,
+                    PackageManager.MATCH_DEFAULT_ONLY);
+
+            // Pick first match, otherwise best found
+            ResolveInfo bestResolve = null;
+            final int size = matches.size();
+            if (size == 1) {
+                bestResolve = matches.get(0);
+            } else if (size > 1) {
+                bestResolve = getBestResolve(intent, matches);
+            }
+
+            if (bestResolve != null) {
+                final Drawable icon = bestResolve.loadIcon(mPackageManager);
+
+                entry.bestResolve = bestResolve;
+                entry.icon = icon;
+            }
+        }
+
+        mCache.put(mimeType, entry);
+        return entry;
+    }
+
+    /**
+     * Best {@link ResolveInfo} when multiple found. Ties are broken by
+     * selecting first from the {QuickContactWindow#sPreferResolve} list of
+     * preferred packages, second by apps that live on the system partition,
+     * otherwise the app from the top of the list. This is
+     * <strong>only</strong> used for selecting a default icon for
+     * displaying in the track, and does not shortcut the system
+     * {@link Intent} disambiguation dialog.
+     */
+    protected ResolveInfo getBestResolve(Intent intent, List<ResolveInfo> matches) {
+        // Try finding preferred activity, otherwise detect disambig
+        final ResolveInfo foundResolve = mPackageManager.resolveActivity(intent,
+                PackageManager.MATCH_DEFAULT_ONLY);
+        final boolean foundDisambig = (foundResolve.match &
+                IntentFilter.MATCH_CATEGORY_MASK) == 0;
+
+        if (!foundDisambig) {
+            // Found concrete match, so return directly
+            return foundResolve;
+        }
+
+        // Accept any package from prefer list, otherwise first system app
+        ResolveInfo firstSystem = null;
+        for (ResolveInfo info : matches) {
+            final boolean isSystem = (info.activityInfo.applicationInfo.flags
+                    & ApplicationInfo.FLAG_SYSTEM) != 0;
+            final boolean isPrefer = sPreferResolve
+                    .contains(info.activityInfo.applicationInfo.packageName);
+
+            if (isPrefer) return info;
+            if (isSystem && firstSystem == null) firstSystem = info;
+        }
+
+        // Return first system found, otherwise first from list
+        return firstSystem != null ? firstSystem : matches.get(0);
+    }
+
+    /**
+     * Check {@link PackageManager} to see if any apps offer to handle the
+     * given {@link Action}.
+     */
+    public boolean hasResolve(Action action) {
+        return getEntry(action).bestResolve != null;
+    }
+
+    /**
+     * Find the best description for the given {@link Action}, usually used
+     * for accessibility purposes.
+     */
+    public CharSequence getDescription(Action action) {
+        final CharSequence actionHeader = action.getHeader();
+        final ResolveInfo info = getEntry(action).bestResolve;
+        if (!TextUtils.isEmpty(actionHeader)) {
+            return actionHeader;
+        } else if (info != null) {
+            return info.loadLabel(mPackageManager);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Return the best icon for the given {@link Action}, which is usually
+     * based on the {@link ResolveInfo} found through a
+     * {@link PackageManager} query.
+     */
+    public Drawable getIcon(Action action) {
+        return getEntry(action).icon;
+    }
+
+    public void clear() {
+        mCache.clear();
+    }
+}
