diff --git a/src/com/android/contacts/ContactsActivity.java b/src/com/android/contacts/ContactsActivity.java
index 06254d3..e270c35 100644
--- a/src/com/android/contacts/ContactsActivity.java
+++ b/src/com/android/contacts/ContactsActivity.java
@@ -96,7 +96,7 @@
 
         mTabHost.addTab(mTabHost.newTabSpec("social")
                 .setIndicator(getText(R.string.socialStreamIconLabel),
-                        getResources().getDrawable(R.drawable.ic_tab_contacts))
+                        getResources().getDrawable(R.drawable.ic_tab_friends))
                 .setContent(intent));
     }
 
diff --git a/src/com/android/contacts/FastTrackWindow.java b/src/com/android/contacts/FastTrackWindow.java
index 0cf9daf..ecff1bd 100644
--- a/src/com/android/contacts/FastTrackWindow.java
+++ b/src/com/android/contacts/FastTrackWindow.java
@@ -17,9 +17,9 @@
 package com.android.contacts;
 
 import com.android.contacts.NotifyingAsyncQueryHandler.QueryCompleteListener;
-import com.android.contacts.FloatyListView.FloatyWindow;
 import com.android.contacts.SocialStreamActivity.MappingCache;
-import com.android.contacts.SocialStreamActivity.MappingCache.Mapping;
+import com.android.contacts.SocialStreamActivity.Mapping;
+import com.android.internal.policy.PolicyManager;
 import com.android.providers.contacts2.ContactsContract;
 import com.android.providers.contacts2.ContactsContract.Aggregates;
 import com.android.providers.contacts2.ContactsContract.CommonDataKinds;
@@ -30,6 +30,7 @@
 import com.android.providers.contacts2.ContactsContract.CommonDataKinds.Photo;
 import com.android.providers.contacts2.ContactsContract.CommonDataKinds.Postal;
 
+import android.app.Activity;
 import android.content.ActivityNotFoundException;
 import android.content.ContentUris;
 import android.content.Context;
@@ -39,14 +40,24 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.net.Uri;
+import android.provider.Contacts.Phones;
 import android.util.Log;
+import android.view.ContextThemeWrapper;
 import android.view.Gravity;
+import android.view.KeyEvent;
 import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
+import android.view.Window;
+import android.view.WindowManager;
 import android.view.View.OnClickListener;
 import android.view.ViewTreeObserver.OnScrollChangedListener;
+import android.view.accessibility.AccessibilityEvent;
 import android.widget.AbsListView;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
@@ -59,135 +70,276 @@
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.PriorityQueue;
+import java.util.Set;
 
 /**
- * {@link PopupWindow} that shows fast-track details for a specific aggregate.
- * This window implements {@link FloatyWindow} so that it can be quickly
- * repositioned by someone like {@link FloatyListView}.
+ * Window that shows fast-track contact details for a specific
+ * {@link Aggregate#_ID}.
  */
-public class FastTrackWindow extends PopupWindow implements QueryCompleteListener, FloatyWindow {
+public class FastTrackWindow implements Window.Callback, QueryCompleteListener, OnClickListener {
     private static final String TAG = "FastTrackWindow";
 
-    private Context mContext;
-    private View mParent;
+    /**
+     * Interface used to allow the person showing a {@link FastTrackWindow} to
+     * know when the window has been dismissed.
+     */
+    interface OnDismissListener {
+        public void onDismiss(FastTrackWindow dialog);
+    }
+
+    final Context mContext;
+    final LayoutInflater mInflater;
+    final WindowManager mWindowManager;
+    Window mWindow;
+    View mDecor;
+
+    private boolean mQuerying = false;
+    private boolean mShowing = false;
 
     /** Mapping cache from mime-type to icons and actions */
     private MappingCache mMappingCache;
 
-    private ViewGroup mContent;
-
-    private Uri mDataUri;
     private NotifyingAsyncQueryHandler mHandler;
+    private OnDismissListener mDismissListener;
 
-    private boolean mShowing = false;
-    private boolean mHasPosition = false;
-    private boolean mHasDisplayName = false;
-    private boolean mHasData = false;
+    private long mAggId;
+    private int mRequestedY;
+    private int mSlop;
 
-    public static final int ICON_SIZE = 42;
-    public static final int ICON_PADDING = 3;
-    private static final int VERTICAL_OFFSET = 74;
+    private boolean mHasProfile = false;
+    private boolean mHasActions = false;
 
-    private int mFirstX;
-    private int mFirstY;
+    private ImageView mPhoto;
+    private ImageView mPresence;
+    private TextView mDisplayName;
+    private TextView mStatus;
+    private ViewGroup mTrack;
+
+    // TODO: read from a resource somewhere
+    private static final int mHeight = 150;
+    private static final int mAnchorHeight = 20;
+
+    /**
+     * Set of {@link ActionInfo} that are associated with the aggregate
+     * currently displayed by this fast-track window.
+     */
+    private ActionSet mActions = new ActionSet();
+
+    /**
+     * Specific mime-type for {@link Phone#CONTENT_ITEM_TYPE} entries that
+     * distinguishes actions that should initiate a text message.
+     */
+    public static final String MIME_SMS_ADDRESS = "vnd.android.cursor.item/sms-address";
+
+    /**
+     * Specific mime-types that should be bumped to the front of the fast-track.
+     * Other mime-types not appearing in this list follow in alphabetic order.
+     */
+    private static final String[] ORDERED_MIMETYPES = new String[] {
+        Aggregates.CONTENT_ITEM_TYPE,
+        Phones.CONTENT_ITEM_TYPE,
+        MIME_SMS_ADDRESS,
+        Email.CONTENT_ITEM_TYPE,
+    };
+
+//    public static final int ICON_SIZE = 42;
+//    public static final int ICON_PADDING = 3;
+
+    // TODO: read this status from actual query
+    private static final String STUB_STATUS = "has a really long random status message that would be far too long to read on a single device without the need for tiny reading glasses";
+
+    private static final boolean INCLUDE_PROFILE_ACTION = true;
 
     private static final int TOKEN_DISPLAY_NAME = 1;
     private static final int TOKEN_DATA = 2;
 
-    private static final int GRAVITY = Gravity.LEFT | Gravity.TOP;
-
     /** Message to show when no activity is found to perform an action */
     // TODO: move this value into a resources string
     private static final String NOT_FOUND = "Couldn't find an app to handle this action";
 
-    /** List of default mime-type icons */
-    private static HashMap<String, Integer> sMimeIcons = new HashMap<String, Integer>();
+    /**
+     * Prepare a fast-track window to show in the given {@link Context}.
+     */
+    public FastTrackWindow(Context context) {
+        mContext = new ContextThemeWrapper(context, R.style.FastTrack);
+        mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
 
-    /** List of mime-type sorting scores */
-    private static HashMap<String, Integer> sMimeScores = new HashMap<String, Integer>();
+        mSlop = ViewConfiguration.get(mContext).getScaledWindowTouchSlop();
 
-    static {
-        sMimeIcons.put(Phone.CONTENT_ITEM_TYPE, android.R.drawable.sym_action_call);
-        sMimeIcons.put(Email.CONTENT_ITEM_TYPE, android.R.drawable.sym_action_email);
-        sMimeIcons.put(Im.CONTENT_ITEM_TYPE, android.R.drawable.sym_action_chat);
-//        sMimeIcons.put(Phone.CONTENT_ITEM_TYPE, R.drawable.sym_action_sms);
-        sMimeIcons.put(Postal.CONTENT_ITEM_TYPE, R.drawable.sym_action_map);
+        mWindow = PolicyManager.makeNewWindow(mContext);
+        mWindow.setCallback(this);
+        mWindow.setWindowManager(mWindowManager, null, null);
 
-        // For scoring, put phone numbers and E-mail up front, and addresses last
-        sMimeScores.put(Phone.CONTENT_ITEM_TYPE, -200);
-        sMimeScores.put(Email.CONTENT_ITEM_TYPE, -100);
-        sMimeScores.put(Postal.CONTENT_ITEM_TYPE, 100);
+        mWindow.setContentView(R.layout.fasttrack);
+
+        mPhoto = (ImageView)mWindow.findViewById(R.id.photo);
+        mPresence = (ImageView)mWindow.findViewById(R.id.presence);
+        mDisplayName = (TextView)mWindow.findViewById(R.id.displayname);
+        mStatus = (TextView)mWindow.findViewById(R.id.status);
+        mTrack = (ViewGroup)mWindow.findViewById(R.id.fasttrack);
+
+        // TODO: move generation of mime-type cache to more-efficient place
+        generateMappingCache();
+
     }
 
     /**
-     * Create a new fast-track window for the given aggregate, using the
-     * provided {@link MappingCache} for icon as needed.
+     * Prepare a fast-track window to show in the given {@link Context}, and
+     * notify the given {@link OnDismissListener} each time this dialog is
+     * dismissed.
      */
-    public FastTrackWindow(Context context, View parent, Uri aggUri, MappingCache mappingCache) {
-        super(context);
+    public FastTrackWindow(Context context, OnDismissListener dismissListener) {
+        this(context);
+        mDismissListener = dismissListener;
+    }
 
-        final Resources resources = context.getResources();
+    /**
+     * Generate {@link MappingCache} specifically for fast-track windows. This
+     * cache knows how to display {@link CommonDataKinds#PACKAGE_COMMON} data
+     * types using generic icons.
+     */
+    private void generateMappingCache() {
+        mMappingCache = MappingCache.createAndFill(mContext);
 
-        mContext = context;
-        mParent = parent;
+        Resources res = mContext.getResources();
+        Mapping mapping;
 
-        mMappingCache = mappingCache;
+        mapping = new Mapping(CommonDataKinds.PACKAGE_COMMON, Aggregates.CONTENT_ITEM_TYPE);
+        mapping.icon = BitmapFactory.decodeResource(res, R.drawable.ic_contacts_details);
+        mMappingCache.addMapping(mapping);
 
-        // Inflate content view
-        LayoutInflater inflater = (LayoutInflater)context
-                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        mContent = (ViewGroup)inflater.inflate(R.layout.fasttrack, null, false);
+        mapping = new Mapping(CommonDataKinds.PACKAGE_COMMON, Phone.CONTENT_ITEM_TYPE);
+        mapping.summaryColumn = Phone.NUMBER;
+        mapping.icon = BitmapFactory.decodeResource(res, android.R.drawable.sym_action_call);
+        mMappingCache.addMapping(mapping);
 
-        setContentView(mContent);
-//        setAnimationStyle(android.R.style.Animation_LeftEdge);
+        mapping = new Mapping(CommonDataKinds.PACKAGE_COMMON, MIME_SMS_ADDRESS);
+        mapping.summaryColumn = Phone.NUMBER;
+        mapping.icon = BitmapFactory.decodeResource(res, R.drawable.sym_action_sms);
+        mMappingCache.addMapping(mapping);
 
-        setBackgroundDrawable(resources.getDrawable(R.drawable.fasttrack));
+        mapping = new Mapping(CommonDataKinds.PACKAGE_COMMON, Email.CONTENT_ITEM_TYPE);
+        mapping.summaryColumn = Email.DATA;
+        mapping.icon = BitmapFactory.decodeResource(res, android.R.drawable.sym_action_email);
+        mMappingCache.addMapping(mapping);
 
-        setWidth(LayoutParams.WRAP_CONTENT);
-        setHeight(LayoutParams.WRAP_CONTENT);
+    }
 
-        setClippingEnabled(false);
-        setFocusable(false);
+    /**
+     * Start showing a fast-track window for the given {@link Aggregate#_ID}
+     * pointing towards the given location.
+     */
+    public void show(Uri aggUri, int y) {
+        if (mShowing || mQuerying) {
+            Log.w(TAG, "already in process of showing");
+            return;
+        }
+
+        mAggId = ContentUris.parseId(aggUri);
+        mRequestedY = y;
+        mQuerying = true;
 
         // Start data query in background
-        mDataUri = Uri.withAppendedPath(aggUri, ContactsContract.Aggregates.Data.CONTENT_DIRECTORY);
+        Uri dataUri = Uri.withAppendedPath(aggUri,
+                ContactsContract.Aggregates.Data.CONTENT_DIRECTORY);
 
-        mHandler = new NotifyingAsyncQueryHandler(context, this);
+        // TODO: also query for latest status message
+        mHandler = new NotifyingAsyncQueryHandler(mContext, this);
         mHandler.startQuery(TOKEN_DISPLAY_NAME, null, aggUri, null, null, null, null);
-        mHandler.startQuery(TOKEN_DATA, null, mDataUri, null, null, null, null);
+        mHandler.startQuery(TOKEN_DATA, null, dataUri, null, null, null, null);
 
-        // TODO: poll around for latest status message or location details
     }
 
     /**
-     * Consider showing this window, which requires both a given position and
-     * completed query results.
+     * Actual internal method to show this fast-track window. Called only by
+     * {@link #considerShowing()} when all data requirements have been met.
      */
-    private synchronized void considerShowing() {
-        if (mHasData && mHasPosition && mHasDisplayName && !mShowing) {
-            mShowing = true;
-            showAtLocation(mParent, GRAVITY, mFirstX, mFirstY);
+    private void showInternal() {
+        mDecor = mWindow.getDecorView();
+        WindowManager.LayoutParams l = mWindow.getAttributes();
+
+        l.gravity = Gravity.TOP | Gravity.LEFT;
+        l.x = 0;
+        l.y = mRequestedY - mHeight;
+
+        l.width = WindowManager.LayoutParams.FILL_PARENT;
+        l.height = mHeight + mAnchorHeight;
+
+        l.dimAmount = 0.6f;
+        l.flags = WindowManager.LayoutParams.FLAG_DIM_BEHIND
+                | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
+
+        mWindowManager.addView(mDecor, l);
+        mShowing = true;
+        mQuerying = false;
+    }
+
+    /**
+     * Dismiss this fast-track window if showing.
+     */
+    public void dismiss() {
+        if (!mQuerying && !mShowing) {
+            Log.d(TAG, "not visible, ignore");
+            return;
+        }
+
+        // Cancel any pending queries
+        mHandler.cancelOperation(TOKEN_DISPLAY_NAME);
+        mHandler.cancelOperation(TOKEN_DATA);
+
+        // Reset all views to prepare for possible recycling
+        mPhoto.setImageResource(R.drawable.ic_contact_list_picture);
+        mPresence.setImageDrawable(null);
+        mDisplayName.setText(null);
+        mStatus.setText(null);
+
+        mActions.clear();
+        mTrack.removeAllViews();
+
+        mHasProfile = false;
+        mHasActions = false;
+
+        if (mDecor == null || !mShowing) {
+            Log.d(TAG, "not showing, ignore");
+            return;
+        }
+
+        mWindowManager.removeView(mDecor);
+        mDecor = null;
+        mWindow.closeAllPanels();
+        mShowing = false;
+
+        // Notify any listeners that we've been dismissed
+        if (mDismissListener != null) {
+            mDismissListener.onDismiss(this);
         }
     }
 
-    /** {@inheritDoc} */
-    public void showAt(int x, int y) {
-        // Adjust vertical position by height
-        y -= VERTICAL_OFFSET;
+    /**
+     * Returns true if this fast-track window is showing or querying.
+     */
+    public boolean isShowing() {
+        return mShowing || mQuerying;
+    }
 
-        // Show dialog or update existing location
-        if (!mShowing) {
-            mFirstX = x;
-            mFirstY = y;
-            mHasPosition = true;
-            considerShowing();
-        } else {
-            update(x, y, -1, -1, true);
+    /**
+     * Consider showing this window, which will only call through to
+     * {@link #showInternal()} when all data items are present.
+     */
+    private synchronized void considerShowing() {
+        if (mHasActions && mHasProfile && !mShowing) {
+            showInternal();
         }
     }
 
@@ -195,160 +347,305 @@
     public void onQueryComplete(int token, Object cookie, Cursor cursor) {
         if (cursor == null) {
             return;
+        } else if (token == TOKEN_DISPLAY_NAME) {
+            handleDisplayName(cursor);
+        } else if (token == TOKEN_DATA) {
+            handleData(cursor);
         }
-        switch (token) {
-            case TOKEN_DISPLAY_NAME:
-                handleDisplayName(cursor);
-                break;
-            case TOKEN_DATA:
-                handleData(cursor);
-                break;
-        }
-        considerShowing();
     }
 
     /**
      * Handle the result from the {@link TOKEN_DISPLAY_NAME} query.
      */
     private void handleDisplayName(Cursor cursor) {
-        final TextView displayname = (TextView)mContent.findViewById(R.id.displayname);
         final int COL_DISPLAY_NAME = cursor.getColumnIndex(Aggregates.DISPLAY_NAME);
 
         if (cursor.moveToNext()) {
             String foundName = cursor.getString(COL_DISPLAY_NAME);
-            displayname.setText(foundName);
+            mDisplayName.setText(foundName);
+            mStatus.setText(STUB_STATUS);
         }
 
-        mHasDisplayName = true;
+        mHasProfile = true;
+        considerShowing();
+    }
+
+    /**
+     * Description of a specific, actionable {@link Data#_ID} item. May have a
+     * {@link Mapping} associated with it to find {@link RemoteViews} or icon,
+     * and may have built a summary of itself for UI display.
+     */
+    private class ActionInfo {
+        long dataId;
+        String packageName;
+        String mimeType;
+
+        Mapping mapping;
+        String summaryValue;
+
+        /**
+         * Create an action from common {@link Data} elements.
+         */
+        public ActionInfo(long dataId, String packageName, String mimeType) {
+            this.dataId = dataId;
+            this.packageName = packageName;
+            this.mimeType = mimeType;
+        }
+
+        /**
+         * Attempt to find a {@link Mapping} for the package and mime-type
+         * defined by this action. Returns true if one was found.
+         */
+        public boolean findMapping(MappingCache cache) {
+            mapping = cache.findMapping(packageName, mimeType);
+            return (mapping != null);
+        }
+
+        /**
+         * Given a {@link Cursor} pointed at the {@link Data} row associated
+         * with this action, use the {@link Mapping} to build a text summary.
+         */
+        public void buildSummary(Cursor cursor) {
+            if (mapping == null || mapping.summaryColumn == null) return;
+            int index = cursor.getColumnIndex(mapping.summaryColumn);
+            if (index != -1) {
+                summaryValue = cursor.getString(index);
+            }
+        }
+
+        /**
+         * Build an {@link Intent} that will perform this action.
+         */
+        public Intent buildIntent() {
+            // Handle well-known mime-types with special care
+            if (CommonDataKinds.Phone.CONTENT_ITEM_TYPE.equals(mimeType)) {
+                Uri callUri = Uri.parse("tel:" + Uri.encode(summaryValue));
+                return new Intent(Intent.ACTION_DIAL, callUri);
+
+            } else if (MIME_SMS_ADDRESS.equals(mimeType)) {
+                Uri smsUri = Uri.fromParts("smsto", summaryValue, null);
+                return new Intent(Intent.ACTION_SENDTO, smsUri);
+
+            } else if (CommonDataKinds.Email.CONTENT_ITEM_TYPE.equals(mimeType)) {
+                Uri mailUri = Uri.fromParts("mailto", summaryValue, null);
+                return new Intent(Intent.ACTION_SENDTO, mailUri);
+
+            }
+
+            // Otherwise fall back to default VIEW action
+            Uri dataUri = ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, dataId);
+
+            Intent intent = new Intent(Intent.ACTION_VIEW);
+            intent.setData(dataUri);
+
+            return intent;
+        }
+    }
+
+    /**
+     * Provide a simple way of collecting one or more {@link ActionInfo} objects
+     * under a mime-type key.
+     */
+    private class ActionSet extends HashMap<String, LinkedList<ActionInfo>> {
+        private void collect(String mimeType, ActionInfo info) {
+            // Create mime-type set if needed
+            if (!containsKey(mimeType)) {
+                put(mimeType, new LinkedList<ActionInfo>());
+            }
+            LinkedList<ActionInfo> collectList = get(mimeType);
+            collectList.add(info);
+        }
     }
 
     /**
      * Handle the result from the {@link TOKEN_DATA} query.
      */
     private void handleData(Cursor cursor) {
-        final ImageView photo = (ImageView)mContent.findViewById(R.id.photo);
-        final ViewGroup fastTrack = (ViewGroup)mContent.findViewById(R.id.fasttrack);
-
-        // Build list of actions for this contact, this could be done better in
-        // the future using an Adapter
-        ArrayList<ImageView> list = new ArrayList<ImageView>(cursor.getCount());
-
         final int COL_ID = cursor.getColumnIndex(Data._ID);
         final int COL_PACKAGE = cursor.getColumnIndex(Data.PACKAGE);
         final int COL_MIMETYPE = cursor.getColumnIndex(Data.MIMETYPE);
         final int COL_PHOTO = cursor.getColumnIndex(Photo.PHOTO);
 
-        boolean foundDisplayName = false;
-        boolean foundPhoto = false;
+        ActionInfo info;
+
+        // Add the profile shortcut action if requested
+        if (INCLUDE_PROFILE_ACTION) {
+            final String mimeType = Aggregates.CONTENT_ITEM_TYPE;
+            info = new ActionInfo(mAggId, CommonDataKinds.PACKAGE_COMMON, mimeType);
+            if (info.findMapping(mMappingCache)) {
+                mActions.collect(mimeType, info);
+            }
+        }
 
         while (cursor.moveToNext()) {
             final long dataId = cursor.getLong(COL_ID);
             final String packageName = cursor.getString(COL_PACKAGE);
             final String mimeType = cursor.getString(COL_MIMETYPE);
 
-            // Handle finding the photo among various return rows
-            if (!foundPhoto && Photo.CONTENT_ITEM_TYPE.equals(mimeType)) {
+            // Handle when a photo appears in the various data items
+            // TODO: accept a photo only if its marked as primary
+            if (Photo.CONTENT_ITEM_TYPE.equals(mimeType)) {
                 byte[] photoBlob = cursor.getBlob(COL_PHOTO);
                 Bitmap photoBitmap = BitmapFactory.decodeByteArray(photoBlob, 0, photoBlob.length);
-                photo.setImageBitmap(photoBitmap);
-                photo.setVisibility(View.VISIBLE);
-                foundPhoto = true;
-            }
-
-            ImageView action;
-
-            // First, try looking in mapping cache for possible icon match
-            Mapping mapping = mMappingCache.getMapping(packageName, mimeType);
-            if (mapping != null && mapping.icon != null) {
-                action = new ImageView(mContext);
-                action.setImageBitmap(mapping.icon);
-
-            } else if (sMimeIcons.containsKey(mimeType)) {
-                // Otherwise fall back to generic icons
-                int icon = sMimeIcons.get(mimeType);
-                action = new ImageView(mContext);
-                action.setImageResource(icon);
-
-            } else {
-                // No icon found, so don't insert any action button
+                mPhoto.setImageBitmap(photoBitmap);
                 continue;
-
             }
 
-            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ICON_SIZE, ICON_SIZE);
-            params.rightMargin = ICON_PADDING;
-            action.setLayoutParams(params);
-
-            // Find the sorting score for this mime-type, otherwise allocate a
-            // new one to make sure the same types are grouped together.
-            if (!sMimeScores.containsKey(mimeType)) {
-                sMimeScores.put(mimeType, sMimeScores.size());
+            // Build an action for this data entry, find a mapping to a UI
+            // element, build its summary from the cursor, and collect it along
+            // with all others of this mime-type.
+            info = new ActionInfo(dataId, packageName, mimeType);
+            if (info.findMapping(mMappingCache)) {
+                info.buildSummary(cursor);
+                mActions.collect(info.mimeType, info);
             }
 
-            int mimeScore = sMimeScores.get(mimeType);
-            action.setTag(mimeScore);
-
-            final Intent intent = buildIntentForMime(dataId, mimeType, cursor);
-            action.setOnClickListener(new OnClickListener() {
-                public void onClick(View v) {
-                    try {
-                        mContext.startActivity(intent);
-                    } catch (ActivityNotFoundException e) {
-                        Log.w(TAG, NOT_FOUND, e);
-                        Toast.makeText(mContext, NOT_FOUND, Toast.LENGTH_SHORT).show();
-                    }
+            // If phone number, also insert as text message action
+            if (Phones.CONTENT_ITEM_TYPE.equals(mimeType)) {
+                info = new ActionInfo(dataId, packageName, MIME_SMS_ADDRESS);
+                if (info.findMapping(mMappingCache)) {
+                    info.buildSummary(cursor);
+                    mActions.collect(info.mimeType, info);
                 }
-            });
-
-            list.add(action);
+            }
         }
 
         cursor.close();
 
-        // Sort the final list based on mime-type scores
-        Collections.sort(list, new Comparator<ImageView>() {
-            public int compare(ImageView object1, ImageView object2) {
-                return (Integer)object1.getTag() - (Integer)object2.getTag();
+        // Turn our list of actions into UI elements, starting with common types
+        Set<String> containedTypes = mActions.keySet();
+        for (String mimeType : ORDERED_MIMETYPES) {
+            if (containedTypes.contains(mimeType)) {
+                mTrack.addView(inflateAction(mimeType));
+                containedTypes.remove(mimeType);
             }
-        });
-
-        for (ImageView action : list) {
-            fastTrack.addView(action);
         }
 
-        mHasData = true;
+        // Then continue with remaining mime-types in alphabetical order
+        String[] remainingTypes = containedTypes.toArray(new String[containedTypes.size()]);
+        Arrays.sort(remainingTypes);
+        for (String mimeType : remainingTypes) {
+            mTrack.addView(inflateAction(mimeType));
+        }
+
+        mHasActions = true;
+        considerShowing();
     }
 
     /**
-     * Build an {@link Intent} that will trigger the action described by the
-     * given {@link Cursor} and mime-type.
+     * Inflate the in-track view for the action of the given mime-type. Will use
+     * the icon provided by the {@link Mapping}.
      */
-    public Intent buildIntentForMime(long dataId, String mimeType, Cursor cursor) {
-        if (CommonDataKinds.Phone.CONTENT_ITEM_TYPE.equals(mimeType)) {
-            final String data = cursor.getString(cursor.getColumnIndex(Phone.NUMBER));
-            Uri callUri = Uri.parse("tel:" + Uri.encode(data));
-            return new Intent(Intent.ACTION_DIAL, callUri);
+    private View inflateAction(String mimeType) {
+        ImageView view = (ImageView)mInflater.inflate(R.layout.fasttrack_item, mTrack, false);
 
-        } else if (CommonDataKinds.Email.CONTENT_ITEM_TYPE.equals(mimeType)) {
-            final String data = cursor.getString(cursor.getColumnIndex(Email.DATA));
-            return new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto", data, null));
-
-//        } else if (CommonDataKinds.Im.CONTENT_ITEM_TYPE.equals(mimeType)) {
-//            return new Intent(Intent.ACTION_SENDTO, constructImToUrl(host, data));
-
-        } else if (CommonDataKinds.Postal.CONTENT_ITEM_TYPE.equals(mimeType)) {
-            final String data = cursor.getString(cursor.getColumnIndex(Postal.DATA));
-            Uri mapsUri = Uri.parse("geo:0,0?q=" + Uri.encode(data));
-            return new Intent(Intent.ACTION_VIEW, mapsUri);
-
+        // Add direct intent if single child, otherwise flag for multiple
+        LinkedList<ActionInfo> children = mActions.get(mimeType);
+        ActionInfo firstInfo = children.get(0);
+        if (children.size() == 1) {
+            view.setTag(firstInfo.buildIntent());
+        } else {
+            view.setTag(mimeType);
         }
 
-        // Otherwise fall back to default VIEW action
-        Uri dataUri = ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, dataId);
+        // Set icon and listen for clicks
+        view.setImageBitmap(firstInfo.mapping.icon);
+        view.setOnClickListener(this);
+        return view;
+    }
 
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.setData(dataUri);
+    /** {@inheritDoc} */
+    public void onClick(View v) {
+        final Object tag = v.getTag();
+        if (tag instanceof Intent) {
+            // Incoming tag is concrete intent, so launch
+            try {
+                mContext.startActivity((Intent)tag);
+            } catch (ActivityNotFoundException e) {
+                Log.w(TAG, NOT_FOUND);
+                Toast.makeText(mContext, NOT_FOUND, Toast.LENGTH_SHORT).show();
+            }
+        } else if (tag instanceof String) {
+            // Incoming tag is a mime-type, so show resolution list
+            LinkedList<ActionInfo> children = mActions.get(tag);
 
-        return intent;
+            // TODO: show drop-down resolution list
+            Log.d(TAG, "would show list between several options here");
+
+        }
+    }
+
+    /** {@inheritDoc} */
+    public boolean dispatchKeyEvent(KeyEvent event) {
+        return mWindow.superDispatchKeyEvent(event);
+    }
+
+    /** {@inheritDoc} */
+    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+        // TODO: make this window accessible
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    public boolean dispatchTouchEvent(MotionEvent event) {
+        if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
+            dismiss();
+            return true;
+        }
+        return mWindow.superDispatchTouchEvent(event);
+    }
+
+    /** {@inheritDoc} */
+    public boolean dispatchTrackballEvent(MotionEvent event) {
+        return mWindow.superDispatchTrackballEvent(event);
+    }
+
+    /** {@inheritDoc} */
+    public void onContentChanged() {
+    }
+
+    /** {@inheritDoc} */
+    public boolean onCreatePanelMenu(int featureId, Menu menu) {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    public View onCreatePanelView(int featureId) {
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    public boolean onMenuItemSelected(int featureId, MenuItem item) {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    public boolean onMenuOpened(int featureId, Menu menu) {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    public void onPanelClosed(int featureId, Menu menu) {
+    }
+
+    /** {@inheritDoc} */
+    public boolean onPreparePanel(int featureId, View view, Menu menu) {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    public boolean onSearchRequested() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    public void onWindowAttributesChanged(android.view.WindowManager.LayoutParams attrs) {
+        if (mDecor != null) {
+            mWindowManager.updateViewLayout(mDecor, attrs);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void onWindowFocusChanged(boolean hasFocus) {
     }
 }
diff --git a/src/com/android/contacts/FloatyListView.java b/src/com/android/contacts/FloatyListView.java
deleted file mode 100644
index 12a25e3..0000000
--- a/src/com/android/contacts/FloatyListView.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2009 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;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-import android.widget.ListView;
-
-/**
- * Simple extension to {@link ListView} that internally keeps track of scrolling
- * position and moves any currently displayed {@link FloatyWindow}.
- */
-public class FloatyListView extends ListView {
-
-    /**
-     * Interface over to some sort of floating window that allows repositioning
-     * to a specific screen location.
-     */
-    public static interface FloatyWindow {
-        void showAt(int x, int y);
-    }
-
-    public FloatyListView(Context context) {
-        super(context);
-    }
-
-    public FloatyListView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public FloatyListView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    private FloatyWindow mFloaty;
-    private int mPosition;
-    private int mAnchorY;
-
-    /**
-     * Show the given {@link FloatyWindow} around the given {@link ListView}
-     * position. Specifically, it will keep the window aligned with the top of
-     * that list position.
-     */
-    public void setFloatyWindow(FloatyWindow floaty, int position) {
-        mFloaty = floaty;
-        mPosition = position;
-
-        if (mFloaty != null) {
-            mAnchorY = getPositionY();
-            mFloaty.showAt(0, mAnchorY);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void offsetChildrenTopAndBottom(int offset) {
-        super.offsetChildrenTopAndBottom(offset);
-
-        if (mFloaty != null) {
-            mAnchorY += offset;
-            mFloaty.showAt(0, mAnchorY);
-        }
-    }
-
-    private int[] mLocation = new int[2];
-
-    /**
-     * Calculate the current Y location of the internally tracked position.
-     */
-    public int getPositionY() {
-        return getPositionY(mPosition);
-    }
-
-    /**
-     * Calculate the current Y location of the given list position, or -1 if
-     * that position is offscreen.
-     */
-    public int getPositionY(int position) {
-        final int firstVis = getFirstVisiblePosition();
-        final int lastVis = getLastVisiblePosition();
-
-        if (position >= firstVis && position < lastVis) {
-            // Vertical position is just above position location
-            View childView = getChildAt(position - firstVis);
-            childView.getLocationOnScreen(mLocation);
-            return mLocation[1];
-        }
-        return -1;
-    }
-}
diff --git a/src/com/android/contacts/ShowOrCreateActivity.java b/src/com/android/contacts/ShowOrCreateActivity.java
index c1a3ff9..645032b 100755
--- a/src/com/android/contacts/ShowOrCreateActivity.java
+++ b/src/com/android/contacts/ShowOrCreateActivity.java
@@ -17,7 +17,6 @@
 package com.android.contacts;
 
 import com.android.contacts.NotifyingAsyncQueryHandler.QueryCompleteListener;
-import com.android.contacts.SocialStreamActivity.MappingCache;
 import com.android.providers.contacts2.ContactsContract;
 import com.android.providers.contacts2.ContactsContract.Aggregates;
 
@@ -38,11 +37,8 @@
 import android.provider.Contacts.Intents;
 import android.provider.Contacts.People;
 import android.provider.Contacts.Phones;
-import android.util.Log;
 import android.view.View;
 
-import java.lang.ref.WeakReference;
-
 /**
  * Handle several edge cases around showing or possibly creating contacts in
  * connected with a specific E-mail address or phone number. Will search based
@@ -59,7 +55,7 @@
  * {@link Intent#ACTION_SEARCH}.
  * </ul>
  */
-public final class ShowOrCreateActivity extends Activity implements QueryCompleteListener {
+public final class ShowOrCreateActivity extends Activity implements QueryCompleteListener, FastTrackWindow.OnDismissListener {
     static final String TAG = "ShowOrCreateActivity";
     static final boolean LOGD = false;
 
@@ -71,10 +67,10 @@
         ContactsContract.Contacts.AGGREGATE_ID,
 //        People._ID,
     };
-    
+
     static final String SCHEME_MAILTO = "mailto";
     static final String SCHEME_TEL = "tel";
-    
+
     static final int AGGREGATE_ID_INDEX = 0;
 
     /**
@@ -83,7 +79,7 @@
      */
     static final String QUERY_KIND_EMAIL_OR_IM = ContactMethodsColumns.KIND +
             " IN (" + Contacts.KIND_EMAIL + "," + Contacts.KIND_IM + ")";
-    
+
     /**
      * Extra used to request a specific {@link FastTrackWindow} position.
      */
@@ -91,7 +87,7 @@
     private static final int DEFAULT_Y = 90;
 
     static final int QUERY_TOKEN = 42;
-    
+
     private NotifyingAsyncQueryHandler mQueryHandler;
 
     private Bundle mCreateExtras;
@@ -99,14 +95,11 @@
     private boolean mCreateForce;
 
     private FastTrackWindow mFastTrack;
-    
+
     @Override
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
 
-        // Throw an empty layout up so we have a window token later
-        setContentView(R.layout.empty);
-
         // Create handler if doesn't exist, otherwise cancel any running
         if (mQueryHandler == null) {
             mQueryHandler = new NotifyingAsyncQueryHandler(this, this);
@@ -133,7 +126,7 @@
         }
 
         // Read possible extra with specific title
-        String mCreateDescrip = intent.getStringExtra(Intents.EXTRA_CREATE_DESCRIPTION);
+        mCreateDescrip = intent.getStringExtra(Intents.EXTRA_CREATE_DESCRIPTION);
         if (mCreateDescrip == null) {
             mCreateDescrip = ssp;
         }
@@ -144,11 +137,9 @@
         // Handle specific query request
         if (SCHEME_MAILTO.equals(scheme)) {
             mCreateExtras.putString(Intents.Insert.EMAIL, ssp);
-//            Uri uri = Uri.withAppendedPath(People.WITH_EMAIL_OR_IM_FILTER_URI, Uri.encode(ssp));
-//            mQueryHandler.startQuery(QUERY_TOKEN, null, uri,
-//                    PEOPLE_PROJECTION, null, null, null);
 
-            Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_FILTER_EMAIL_URI, Uri.encode(ssp));
+            Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_FILTER_EMAIL_URI,
+                    Uri.encode(ssp));
             mQueryHandler.startQuery(QUERY_TOKEN, null, uri,
                     CONTACTS_PROJECTION, null, null, null);
 
@@ -183,13 +174,14 @@
      */
     private void showFastTrack(Uri aggUri, int y) {
         // Use our local window token for now
-        final IBinder windowToken = findViewById(android.R.id.empty).getWindowToken();
-        FakeView fakeView = new FakeView(this, windowToken);
+        mFastTrack = new FastTrackWindow(this, this);
+        mFastTrack.show(aggUri, y);
+    }
 
-        final MappingCache mappingCache = MappingCache.createAndFill(this);
-
-        mFastTrack = new FastTrackWindow(this, fakeView, aggUri, mappingCache);
-        mFastTrack.showAt(0, y);
+    /** {@inheritDoc} */
+    public void onDismiss(FastTrackWindow dialog) {
+        // When dismissed, finish this activity
+        finish();
     }
 
     public void onQueryComplete(int token, Object cookie, Cursor cursor) {
diff --git a/src/com/android/contacts/SocialStreamActivity.java b/src/com/android/contacts/SocialStreamActivity.java
index 31dc652..b429a53 100644
--- a/src/com/android/contacts/SocialStreamActivity.java
+++ b/src/com/android/contacts/SocialStreamActivity.java
@@ -17,9 +17,9 @@
 package com.android.contacts;
 
 import com.android.contacts.EdgeTriggerView.EdgeTriggerListener;
-import com.android.contacts.SocialStreamActivity.MappingCache.Mapping;
 import com.android.providers.contacts2.ContactsContract;
 import com.android.providers.contacts2.ContactsContract.Aggregates;
+import com.android.providers.contacts2.ContactsContract.CommonDataKinds;
 import com.android.providers.contacts2.ContactsContract.Contacts;
 import com.android.providers.contacts2.ContactsContract.Data;
 import com.android.providers.contacts2.ContactsContract.CommonDataKinds.Photo;
@@ -36,6 +36,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.database.Cursor;
 import android.graphics.Bitmap;
@@ -53,9 +54,11 @@
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Xml;
+import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.View.OnClickListener;
 import android.widget.CursorAdapter;
 import android.widget.ImageView;
 import android.widget.ListAdapter;
@@ -63,11 +66,12 @@
 import android.widget.TextView;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 
-public class SocialStreamActivity extends ListActivity implements EdgeTriggerListener {
+public class SocialStreamActivity extends ListActivity implements OnClickListener, EdgeTriggerListener {
     private static final String TAG = "SocialStreamActivity";
 
     private static final String[] PROJ_ACTIVITIES = new String[] {
@@ -101,14 +105,16 @@
     public static final int PHOTO_SIZE = 54;
     public static final int THUMBNAIL_SIZE = 54;
 
-    private ListAdapter mAdapter;
+    private SocialAdapter mAdapter;
 
-    private FloatyListView mListView;
+    private ListView mListView;
     private EdgeTriggerView mEdgeTrigger;
     private FastTrackWindow mFastTrack;
+    private MappingCache mMappingCache;
+
+    private static final boolean USE_GESTURE = false;
 
     private ContactsCache mContactsCache;
-    private MappingCache mMappingCache;
 
     @Override
     protected void onCreate(Bundle icicle) {
@@ -121,36 +127,66 @@
 
         Cursor cursor = managedQuery(Activities.CONTENT_URI, PROJ_ACTIVITIES, null, null);
         mAdapter = new SocialAdapter(this, cursor, mContactsCache, mMappingCache);
+        mAdapter.setPhotoListener(this);
 
         setListAdapter(mAdapter);
 
-        mListView = (FloatyListView)findViewById(android.R.id.list);
+        mListView = getListView();
+        mFastTrack = new FastTrackWindow(this);
 
-        // Find and listen for edge triggers
-        mEdgeTrigger = (EdgeTriggerView)findViewById(R.id.edge_trigger);
-        mEdgeTrigger.setOnEdgeTriggerListener(this);
+        if (USE_GESTURE) {
+            // Find and listen for edge triggers
+            mEdgeTrigger = (EdgeTriggerView)findViewById(R.id.edge_trigger);
+            mEdgeTrigger.setOnEdgeTriggerListener(this);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void onClick(View v) {
+        // Clicked on photo, so show fast-track
+        View listItem = (View)v.getParent();
+        showFastTrack(listItem, (Long)v.getTag());
     }
 
     /** {@inheritDoc} */
     public void onTrigger(float downX, float downY, int edge) {
         // Find list item user triggered over
-        int position = mListView.pointToPosition((int)downX, (int)downY);
+        final int position = mListView.pointToPosition((int)downX, (int)downY);
+        if (position == ListView.INVALID_POSITION) return;
+
+        // Reverse to find the exact top of the triggered entry
+        final int index = position - mListView.getFirstVisiblePosition();
+        final View anchor = mListView.getChildAt(index);
 
         Cursor cursor = (Cursor)mAdapter.getItem(position);
         long aggId = cursor.getLong(COL_AGGREGATE_ID);
 
-        Log.d(TAG, "onTrigger found position=" + position + ", contactId=" + aggId);
+        showFastTrack(anchor, aggId);
 
+    }
+
+    private int[] mLocation = new int[2];
+
+    private void showFastTrack(View anchor, long aggId) {
         Uri aggUri = ContentUris.withAppendedId(ContactsContract.Aggregates.CONTENT_URI, aggId);
 
-        // Dismiss any existing window first
-        if (mFastTrack != null) {
+        anchor.getLocationInWindow(mLocation);
+        final int entryTop = mLocation[1];
+
+        mFastTrack.dismiss();
+        mFastTrack.show(aggUri, entryTop);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        // Back key dismisses fast-track when its visible
+        if (keyCode == KeyEvent.KEYCODE_BACK && mFastTrack.isShowing()) {
             mFastTrack.dismiss();
+            return true;
         }
 
-        mFastTrack = new FastTrackWindow(this, mListView, aggUri, mMappingCache);
-        mListView.setFloatyWindow(mFastTrack, position);
-
+        return super.onKeyDown(keyCode, event);
     }
 
     @Override
@@ -177,6 +213,8 @@
         private final MappingCache mMappingCache;
         private final StyleSpan mTextStyleName;
         private final UnderlineSpan mTextStyleLink;
+        private OnClickListener mPhotoListener;
+        private SpannableStringBuilder mBuilder = new SpannableStringBuilder();
 
         private static class SocialHolder {
             ImageView photo;
@@ -200,6 +238,10 @@
             mTextStyleLink = new UnderlineSpan();
         }
 
+        public void setPhotoListener(OnClickListener listener) {
+            mPhotoListener = listener;
+        }
+
         @Override
         public int getViewTypeCount() {
             return 2;
@@ -215,6 +257,7 @@
         public void bindView(View view, Context context, Cursor cursor) {
             SocialHolder holder = (SocialHolder)view.getTag();
 
+            long aggId = cursor.getLong(COL_AGGREGATE_ID);
             long contactId = cursor.getLong(COL_AUTHOR_CONTACT_ID);
             String name = cursor.getString(COL_DISPLAY_NAME);
             String title = cursor.getString(COL_TITLE);
@@ -230,12 +273,14 @@
             } else {
                 holder.photo.setImageResource(R.drawable.ic_contact_list_picture);
             }
-            holder.contentBuilder.clear();
-            holder.contentBuilder.append(name);
-            holder.contentBuilder.append(" ");
-            holder.contentBuilder.append(title);
-            holder.contentBuilder.setSpan(mTextStyleName, 0, name.length(), 0);
-            holder.content.setText(holder.contentBuilder);
+            holder.photo.setTag(aggId);
+
+            mBuilder.clear();
+            mBuilder.append(name);
+            mBuilder.append(" ");
+            mBuilder.append(title);
+            mBuilder.setSpan(mTextStyleName, 0, name.length(), 0);
+            holder.content.setText(mBuilder);
 
             if (summary == null) {
                 holder.summary.setVisibility(View.GONE);
@@ -263,7 +308,7 @@
             if (holder.sourceIcon != null) {
                 String packageName = cursor.getString(COL_PACKAGE);
                 String mimeType = cursor.getString(COL_MIMETYPE);
-                Mapping mapping = mMappingCache.getMapping(packageName, mimeType);
+                Mapping mapping = mMappingCache.findMapping(packageName, mimeType);
                 if (mapping != null && mapping.icon != null) {
                     holder.sourceIcon.setImageBitmap(mapping.icon);
                 } else {
@@ -287,6 +332,10 @@
             holder.published = (TextView) view.findViewById(R.id.published);
             view.setTag(holder);
 
+            if (!USE_GESTURE) {
+                holder.photo.setOnClickListener(mPhotoListener);
+            }
+
             return view;
         }
 
@@ -354,10 +403,32 @@
     }
 
     /**
-     * Store a parsed <code>RemoteViewsMapping</code> object, which maps
-     * mime-types to <code>RemoteViews</code> XML resources and possible icons.
+     * Store a mapping from a package name and mime-type pair to a set of
+     * {@link RemoteViews}, default icon, and column to use from the
+     * {@link Data} table to use as a summary.
      */
-    public static class MappingCache {
+    public static class Mapping {
+        String packageName;
+        String mimeType;
+        String summaryColumn;
+        int remoteViewsRes;
+        Bitmap icon;
+
+        public Mapping() {
+        }
+
+        public Mapping(String packageName, String mimeType) {
+            this.packageName = packageName;
+            this.mimeType = mimeType;
+        }
+    }
+
+    /**
+     * Store a parsed <code>Mapping</code> object, which maps package and
+     * mime-type combinations to {@link RemoteViews} XML resources, default
+     * icons, and summary columns in the {@link Data} table.
+     */
+    public static class MappingCache extends HashMap<String, Mapping> {
         private static final String TAG = "MappingCache";
 
         private static final String TAG_MAPPINGSET = "MappingSet";
@@ -365,33 +436,45 @@
 
         private static final String MAPPING_METADATA = "com.android.contacts.stylemap";
 
-        private LinkedList<Mapping> mappings = new LinkedList<Mapping>();
 
+        /**
+         * Only allow inflating through
+         * {@link MappingCache#createAndFill(Context)}.
+         */
         private MappingCache() {
         }
 
-        public static class Mapping {
-            String packageName;
-            String mimeType;
-            int remoteViewsRes;
-            Bitmap icon;
-        }
-
+        /**
+         * Add a {@link Mapping} instance to this cache, correctly using
+         * {@link #generateKey(String, String)} when storing.
+         */
         public void addMapping(Mapping mapping) {
-            mappings.add(mapping);
+            String hashKey = generateKey(mapping.packageName, mapping.mimeType);
+            put(hashKey, mapping);
         }
 
         /**
-         * Find matching <code>RemoteViews</code> XML resource for requested
-         * package and mime-type. Returns -1 if no mapping found.
+         * Generate a key used internally for mapping a specific package name
+         * and mime-type to a {@link Mapping}.
          */
-        public Mapping getMapping(String packageName, String mimeType) {
-            for (Mapping mapping : mappings) {
-                if (mapping.packageName.equals(packageName) && mapping.mimeType.equals(mimeType)) {
-                    return mapping;
-                }
+        private String generateKey(String packageName, String mimeType) {
+            return packageName + ";" + mimeType;
+        }
+
+        /**
+         * Find matching mapping for requested package and mime-type. Returns
+         * null if no mapping found.
+         */
+        public Mapping findMapping(String packageName, String mimeType) {
+            // Search for common mapping first
+            final String commonMapping = generateKey(CommonDataKinds.PACKAGE_COMMON, mimeType);
+            if (containsKey(commonMapping)) {
+                return get(commonMapping);
             }
-            return null;
+
+            // Otherwise search for package-specific mapping
+            final String specificMapping = generateKey(packageName, mimeType);
+            return get(specificMapping);
         }
 
         /**
@@ -399,7 +482,7 @@
          * all packages to find those that provide mappings.
          */
         public static MappingCache createAndFill(Context context) {
-            Log.d(TAG, "searching for mimetype mappings...");
+            Log.d(TAG, "building mime-type mapping cache...");
             final PackageManager pm = context.getPackageManager();
             MappingCache building = new MappingCache();
             List<ApplicationInfo> installed = pm
@@ -440,6 +523,7 @@
         public void inflateMappings(Context context, int uid, String packageName,
                 XmlPullParser parser) throws InflateException {
             final AttributeSet attrs = Xml.asAttributeSet(parser);
+            final Resources res = context.getResources();
 
             try {
                 int type;
@@ -474,15 +558,13 @@
                     Mapping mapping = new Mapping();
                     mapping.packageName = packageName;
                     mapping.mimeType = a.getString(R.styleable.Mapping_mimeType);
+                    mapping.summaryColumn = a.getString(R.styleable.Mapping_summaryColumn);
                     mapping.remoteViewsRes = a.getResourceId(R.styleable.Mapping_remoteViews, -1);
 
                     // Read and resize icon if provided
                     int iconRes = a.getResourceId(R.styleable.Mapping_icon, -1);
                     if (iconRes != -1) {
-                        mapping.icon = BitmapFactory
-                                .decodeResource(context.getResources(), iconRes);
-                        mapping.icon = Utilities.createBitmapThumbnail(mapping.icon, context,
-                                FastTrackWindow.ICON_SIZE);
+                        mapping.icon = BitmapFactory.decodeResource(res, iconRes);
                     }
 
                     addMapping(mapping);
