diff --git a/src/com/android/contacts/ContactsListActivity.java b/src/com/android/contacts/ContactsListActivity.java
index 438133e..482f671 100644
--- a/src/com/android/contacts/ContactsListActivity.java
+++ b/src/com/android/contacts/ContactsListActivity.java
@@ -16,6 +16,8 @@
 
 package com.android.contacts;
 
+import com.android.contacts.DisplayGroupsActivity.Prefs;
+
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.ListActivity;
@@ -83,8 +85,8 @@
 /**
  * Displays a list of contacts. Usually is embedded into the ContactsActivity.
  */
-public final class ContactsListActivity extends ListActivity
-        implements View.OnCreateContextMenuListener, DialogInterface.OnClickListener {
+public final class ContactsListActivity extends ListActivity implements
+        View.OnCreateContextMenuListener {
     private static final String TAG = "ContactsListActivity";
 
     private static final String LIST_STATE_KEY = "liststate";
@@ -106,6 +108,7 @@
 
     private static final int SUBACTIVITY_NEW_CONTACT = 1;
     private static final int SUBACTIVITY_VIEW_CONTACT = 2;
+    private static final int SUBACTIVITY_DISPLAY_GROUP = 3;
 
     /**
      * The action for the join contact activity.
@@ -140,12 +143,10 @@
 
     /** Unknown mode */
     static final int MODE_UNKNOWN = 0;
-//    /** Show members of the "Contacts" group */
-//    static final int MODE_GROUP = 5;
-    /** Show all contacts sorted alphabetically */
-    static final int MODE_ALL_CONTACTS = 10;
-    /** Show all contacts with phone numbers, sorted alphabetically */
-    static final int MODE_WITH_PHONES = 15;
+    /** Default mode */
+    static final int MODE_DEFAULT = 4;
+    /** Custom mode */
+    static final int MODE_CUSTOM = 8;
     /** Show all starred contacts */
     static final int MODE_STARRED = 20;
     /** Show frequently contacted contacts */
@@ -173,35 +174,9 @@
     static final int MODE_JOIN_AGGREGATE = 70 | MODE_MASK_PICKER | MODE_MASK_NO_PRESENCE
             | MODE_MASK_NO_DATA;
 
-    static final int DEFAULT_MODE = MODE_ALL_CONTACTS;
-
     /** Maximum number of suggestions shown for joining aggregates */
     static final int MAX_SUGGESTIONS = 4;
 
-    /**
-     * The type of data to display in the main contacts list.
-     */
-    static final String PREF_DISPLAY_TYPE = "display_system_group";
-
-    /** Unknown display type. */
-    static final int DISPLAY_TYPE_UNKNOWN = -1;
-    /** Display all contacts */
-    static final int DISPLAY_TYPE_ALL = 0;
-    /** Display all contacts that have phone numbers */
-    static final int DISPLAY_TYPE_ALL_WITH_PHONES = 1;
-    /** Display a system group */
-    static final int DISPLAY_TYPE_SYSTEM_GROUP = 2;
-    /** Display a user group */
-    static final int DISPLAY_TYPE_USER_GROUP = 3;
-
-    /**
-     * Info about what to display. If {@link #PREF_DISPLAY_TYPE}
-     * is {@link #DISPLAY_TYPE_SYSTEM_GROUP} then this will be the system id.
-     * If {@link #PREF_DISPLAY_TYPE} is {@link #DISPLAY_TYPE_USER_GROUP} then this will
-     * be the group name.
-     */
-    static final String PREF_DISPLAY_INFO = "display_group";
-
     static final String NAME_COLUMN = Aggregates.DISPLAY_NAME;
     //static final String SORT_STRING = People.SORT_STRING;
 
@@ -260,44 +235,22 @@
     static final int POSTAL_ADDRESS_COLUMN_INDEX = 3;
     static final int POSTAL_DISPLAY_NAME_COLUMN_INDEX = 4;
 
-    static final int DISPLAY_GROUP_INDEX_ALL_CONTACTS = 0;
-    static final int DISPLAY_GROUP_INDEX_ALL_CONTACTS_WITH_PHONES = 1;
-    static final int DISPLAY_GROUP_INDEX_MY_CONTACTS = 2;
-
     private static final int QUERY_TOKEN = 42;
 
     /*
-    static final String[] GROUPS_PROJECTION = new String[] {
-        Groups.SYSTEM_ID, // 0
-        Groups.NAME, // 1
-    };
-    static final int GROUPS_COLUMN_INDEX_SYSTEM_ID = 0;
-    static final int GROUPS_COLUMN_INDEX_NAME = 1;
     */
-
-    static final String GROUP_WITH_PHONES = "android_smartgroup_phone";
-
     ContactItemListAdapter mAdapter;
 
-    int mMode = DEFAULT_MODE;
-    // The current display group
-    private String mDisplayInfo;
-    private int mDisplayType;
-    // The current list of display groups, during selection from menu
-    private CharSequence[] mDisplayGroups;
-    // If true position 2 in mDisplayGroups is the MyContacts group
-    private boolean mDisplayGroupsIncludesMyContacts = false;
-
-    private int mDisplayGroupOriginalSelection;
-    private int mDisplayGroupCurrentSelection;
+    int mMode = MODE_DEFAULT;
 
     private QueryHandler mQueryHandler;
     private String mQuery;
-    private Uri mGroupFilterUri;
-    private Uri mGroupUri;
     private boolean mJustCreated;
     private boolean mSyncEnabled;
 
+    private boolean mDisplayAll;
+    private boolean mDisplayOnlyPhones;
+
     /**
      * Cursor row index that holds reference back to {@link People#_ID}, such as
      * {@link ContactMethods#PERSON_ID}. Used when responding to a
@@ -314,7 +267,6 @@
     private boolean mListHasFocus;
 
     private boolean mCreateShortcut;
-    private boolean mDefaultMode = false;
 
     /**
      * Internal query type when in mode {@link #MODE_QUERY_PICK_TO_VIEW}.
@@ -331,6 +283,9 @@
      */
     private String mQueryData;
 
+    private static final String CLAUSE_ONLY_VISIBLE = Aggregates.IN_VISIBLE_GROUP + "=1";
+    private static final String CLAUSE_ONLY_PHONES = Aggregates.PRIMARY_PHONE_ID + " IS NOT NULL";
+
     private class DeleteClickListener implements DialogInterface.OnClickListener {
         private Uri mUri;
 
@@ -363,7 +318,7 @@
 
         Log.i(TAG, "Called with action: " + action);
         if (UI.LIST_DEFAULT.equals(action)) {
-            mDefaultMode = true;
+            mMode = MODE_DEFAULT;
             // When mDefaultMode is true the mode is set in onResume(), since the preferneces
             // activity may change it whenever this activity isn't running
         } /* else if (UI.LIST_GROUP_ACTION.equals(action)) {
@@ -375,7 +330,9 @@
             }
             buildUserGroupUris(groupName);
         }*/ else if (UI.LIST_ALL_CONTACTS_ACTION.equals(action)) {
-            mMode = MODE_ALL_CONTACTS;
+            mMode = MODE_CUSTOM;
+            mDisplayAll = true;
+            mDisplayOnlyPhones = false;
         } else if (UI.LIST_STARRED_ACTION.equals(action)) {
             mMode = MODE_STARRED;
         } else if (UI.LIST_FREQUENT_ACTION.equals(action)) {
@@ -383,7 +340,9 @@
         } else if (UI.LIST_STREQUENT_ACTION.equals(action)) {
             mMode = MODE_STREQUENT;
         } else if (UI.LIST_CONTACTS_WITH_PHONES_ACTION.equals(action)) {
-            mMode = MODE_WITH_PHONES;
+            mMode = MODE_CUSTOM;
+            mDisplayAll = true;
+            mDisplayOnlyPhones = true;
         } else if (Intent.ACTION_PICK.equals(action)) {
             // XXX These should be showing the data from the URI given in
             // the Intent.
@@ -481,7 +440,7 @@
         }
 
         if (mMode == MODE_UNKNOWN) {
-            mMode = DEFAULT_MODE;
+            mMode = MODE_DEFAULT;
         }
 
         // Setup the UI
@@ -542,124 +501,32 @@
         TextView empty = (TextView) findViewById(R.id.emptyText);
         // Center the text by default
         int gravity = Gravity.CENTER;
-        switch (mMode) {/*
-            case MODE_GROUP:
-                if (Groups.GROUP_MY_CONTACTS.equals(mDisplayInfo)) {
-                    if (mSyncEnabled) {
-                        empty.setText(getText(R.string.noContactsHelpTextWithSync));
-                    } else {
-                        empty.setText(getText(R.string.noContactsHelpText));
-                    }
-                    gravity = Gravity.NO_GRAVITY;
-                } else {
-                    empty.setText(getString(R.string.groupEmpty, mDisplayInfo));
-                }
-                break;
-            */
-            case MODE_STARRED:
-            case MODE_STREQUENT:
-            case MODE_FREQUENT:
-                empty.setText(getText(R.string.noFavorites));
-                break;
-            case MODE_WITH_PHONES:
-                empty.setText(getText(R.string.noContactsWithPhoneNumbers));
-                break;
 
-            default:
-                empty.setText(getText(R.string.noContacts));
-                break;
+        if (mDisplayOnlyPhones) {
+            empty.setText(getText(R.string.noContactsWithPhoneNumbers));
+        } else if (mDisplayAll) {
+            empty.setText(getText(R.string.noContacts));
+        } else {
+            if (mSyncEnabled) {
+                empty.setText(getText(R.string.noContactsHelpTextWithSync));
+            } else {
+                empty.setText(getText(R.string.noContactsHelpText));
+            }
+            gravity = Gravity.NO_GRAVITY;
         }
         empty.setGravity(gravity);
     }
 
     /**
-     * Builds the URIs to query when displaying a user group
-     *
-     * @param groupName the group being displayed
-     */
-    private void buildUserGroupUris(String groupName) {
-        mGroupFilterUri = Uri.parse("content://contacts/groups/name/" + groupName
-                + "/members/filter/");
-        mGroupUri = Uri.parse("content://contacts/groups/name/" + groupName + "/members");
-    }
-
-    /**
-     * Builds the URIs to query when displaying a system group
-     *
-     * @param systemId the system group's ID
-     */
-    private void buildSystemGroupUris(String systemId) {
-        mGroupFilterUri = Uri.parse("content://contacts/groups/system_id/" + systemId
-                + "/members/filter/");
-        mGroupUri = Uri.parse("content://contacts/groups/system_id/" + systemId + "/members");
-    }
-
-    /**
      * Sets the mode when the request is for "default"
      */
     private void setDefaultMode() {
         // Load the preferences
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
 
-        // Lookup the group to display
-        mDisplayType = prefs.getInt(PREF_DISPLAY_TYPE, DISPLAY_TYPE_UNKNOWN);
-        switch (mDisplayType) {
-            case DISPLAY_TYPE_ALL_WITH_PHONES: {
-                mMode = MODE_WITH_PHONES;
-                mDisplayInfo = null;
-                break;
-            }
-
-            /*case DISPLAY_TYPE_SYSTEM_GROUP: {
-                String systemId = prefs.getString(
-                        PREF_DISPLAY_INFO, null);
-                if (!TextUtils.isEmpty(systemId)) {
-                    // Display the selected system group
-                    mMode = MODE_GROUP;
-                    buildSystemGroupUris(systemId);
-                    mDisplayInfo = systemId;
-                } else {
-                    // No valid group is present, display everything
-                    mMode = MODE_WITH_PHONES;
-                    mDisplayInfo = null;
-                    mDisplayType = DISPLAY_TYPE_ALL;
-                }
-                break;
-            }
-
-            case DISPLAY_TYPE_USER_GROUP: {
-                String displayGroup = prefs.getString(
-                        PREF_DISPLAY_INFO, null);
-                if (!TextUtils.isEmpty(displayGroup)) {
-                    // Display the selected user group
-                    mMode = MODE_GROUP;
-                    buildUserGroupUris(displayGroup);
-                    mDisplayInfo = displayGroup;
-                } else {
-                    // No valid group is present, display everything
-                    mMode = MODE_WITH_PHONES;
-                    mDisplayInfo = null;
-                    mDisplayType = DISPLAY_TYPE_ALL;
-                }
-                break;
-            } */
-
-            case DISPLAY_TYPE_ALL:
-            default: {
-                mMode = MODE_ALL_CONTACTS;
-                mDisplayInfo = null;
-                break;
-            }
-
-            /* default: {
-                // We don't know what to display, default to My Contacts
-                mMode = MODE_GROUP;
-                mDisplayType = DISPLAY_TYPE_SYSTEM_GROUP;
-                buildSystemGroupUris(Groups.GROUP_MY_CONTACTS);
-                mDisplayInfo = Groups.GROUP_MY_CONTACTS;
-                break;
-            } */
-        }
+        mDisplayAll = prefs.getBoolean(Prefs.DISPLAY_ALL, Prefs.DISPLAY_ALL_DEFAULT);
+        mDisplayOnlyPhones = prefs.getBoolean(Prefs.DISPLAY_ONLY_PHONES,
+                Prefs.DISPLAY_ONLY_PHONES_DEFAULT);
 
         // Update the empty text view with the proper string, as the group may have changed
         setEmptyText();
@@ -674,7 +541,7 @@
 
         // Do this before setting the filter. The filter thread relies
         // on some state that is initialized in setDefaultMode
-        if (mDefaultMode) {
+        if (mMode == MODE_DEFAULT) {
             // If we're in default mode we need to possibly reset the mode due to a change
             // in the preferences activity while we weren't running
             setDefaultMode();
@@ -715,15 +582,6 @@
         }
     }
 
-    private void updateGroup() {
-        if (mDefaultMode) {
-            setDefaultMode();
-        }
-
-        // Calling requery here may cause an ANR, so always do the async query
-        startQuery();
-    }
-
     @Override
     protected void onSaveInstanceState(Bundle icicle) {
         super.onSaveInstanceState(icicle);
@@ -779,7 +637,7 @@
                 */
 
         // Display group
-        if (mDefaultMode) {
+        if (mMode == MODE_DEFAULT) {
             menu.add(0, MENU_DISPLAY_GROUP, 0, R.string.menu_displayGroup)
                     .setIcon(com.android.internal.R.drawable.ic_menu_allfriends);
         }
@@ -804,61 +662,13 @@
         return super.onCreateOptionsMenu(menu);
     }
 
-    /*
-     * Implements the handler for display group selection.
-     */
-    public void onClick(DialogInterface dialogInterface, int which) {
-        if (which == DialogInterface.BUTTON_POSITIVE) {
-            // The OK button was pressed
-            if (mDisplayGroupOriginalSelection != mDisplayGroupCurrentSelection) {
-                // Set the group to display
-                if (mDisplayGroupCurrentSelection == DISPLAY_GROUP_INDEX_ALL_CONTACTS) {
-                    // Display all
-                    mDisplayType = DISPLAY_TYPE_ALL;
-                    mDisplayInfo = null;
-                } else if (mDisplayGroupCurrentSelection
-                        == DISPLAY_GROUP_INDEX_ALL_CONTACTS_WITH_PHONES) {
-                    // Display all with phone numbers
-                    mDisplayType = DISPLAY_TYPE_ALL_WITH_PHONES;
-                    mDisplayInfo = null;
-                } /*else if (mDisplayGroupsIncludesMyContacts &&
-                        mDisplayGroupCurrentSelection == DISPLAY_GROUP_INDEX_MY_CONTACTS) {
-                    mDisplayType = DISPLAY_TYPE_SYSTEM_GROUP;
-                    mDisplayInfo = Groups.GROUP_MY_CONTACTS;
-                } */else {
-                    mDisplayType = DISPLAY_TYPE_USER_GROUP;
-                    mDisplayInfo = mDisplayGroups[mDisplayGroupCurrentSelection].toString();
-                }
-
-                // Save the changes to the preferences
-                SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
-                prefs.edit()
-                        .putInt(PREF_DISPLAY_TYPE, mDisplayType)
-                        .putString(PREF_DISPLAY_INFO, mDisplayInfo)
-                        .commit();
-
-                // Update the display state
-                updateGroup();
-            }
-        } else {
-            // A list item was selected, cache the position
-            mDisplayGroupCurrentSelection = which;
-        }
-    }
-
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
-            /*case MENU_DISPLAY_GROUP:
-                AlertDialog.Builder builder = new AlertDialog.Builder(this)
-                    .setTitle(R.string.select_group_title)
-                    .setPositiveButton(android.R.string.ok, this)
-                    .setNegativeButton(android.R.string.cancel, null);
-
-                setGroupEntries(builder);
-
-                builder.show();
-                return true;*/
+            case MENU_DISPLAY_GROUP:
+                final Intent intent = new Intent(this, DisplayGroupsActivity.class);
+                startActivityForResult(intent, SUBACTIVITY_DISPLAY_GROUP);
+                return true;
 
             case MENU_SEARCH:
                 startSearch(null, false, null, false);
@@ -884,6 +694,11 @@
                     mAdapter.notifyDataSetChanged();
                 }
                 break;
+
+            case SUBACTIVITY_DISPLAY_GROUP:
+                // Mark as just created so we re-run the view query
+                mJustCreated = true;
+                break;
         }
     }
 
@@ -1128,25 +943,15 @@
 
     String[] getProjection() {
         switch (mMode) {
-            /* case MODE_GROUP: */
-            case MODE_ALL_CONTACTS:
-            case MODE_WITH_PHONES:
-            case MODE_PICK_AGGREGATE:
-            case MODE_PICK_OR_CREATE_AGGREGATE:
-            case MODE_QUERY:
-            case MODE_STARRED:
-            case MODE_FREQUENT:
-            case MODE_STREQUENT:
-            case MODE_INSERT_OR_EDIT_CONTACT:
-                return AGGREGATES_SUMMARY_PROJECTION;
-
             case MODE_PICK_PHONE:
                 return PHONES_PROJECTION;
 
             case MODE_PICK_POSTAL:
                 return POSTALS_PROJECTION;
         }
-        return null;
+
+        // Default to normal aggregate projection
+        return AGGREGATES_SUMMARY_PROJECTION;
     }
 
     private Bitmap loadContactPhoto(long dataId, BitmapFactory.Options options) {
@@ -1166,6 +971,21 @@
         return bm;
     }
 
+    /**
+     * Return the selection arguments for a default query based on
+     * {@link #mDisplayAll} and {@link #mDisplayOnlyPhones} flags.
+     */
+    private String getAggregateSelection() {
+        if (!mDisplayAll && mDisplayOnlyPhones) {
+            return CLAUSE_ONLY_VISIBLE + " AND " + CLAUSE_ONLY_PHONES;
+        } else if (!mDisplayAll) {
+            return CLAUSE_ONLY_VISIBLE;
+        } else if (mDisplayOnlyPhones) {
+            return CLAUSE_ONLY_PHONES;
+        }
+        return null;
+    }
+
     private Uri getAggregateFilterUri(String filter) {
         if (!TextUtils.isEmpty(filter)) {
             return Uri.withAppendedPath(Aggregates.CONTENT_SUMMARY_FILTER_URI, Uri.encode(filter));
@@ -1199,20 +1019,12 @@
                         getSortOrder(CONTACTS_PROJECTION));
                 break; */
 
-            case MODE_ALL_CONTACTS:
+            case MODE_DEFAULT:
             case MODE_PICK_AGGREGATE:
             case MODE_PICK_OR_CREATE_AGGREGATE:
             case MODE_INSERT_OR_EDIT_CONTACT:
                 mQueryHandler.startQuery(QUERY_TOKEN, null, Aggregates.CONTENT_SUMMARY_URI,
-                        AGGREGATES_SUMMARY_PROJECTION, null, null,
-                        getSortOrder(AGGREGATES_SUMMARY_PROJECTION));
-
-                break;
-
-            case MODE_WITH_PHONES:
-                mQueryHandler.startQuery(QUERY_TOKEN, null, Aggregates.CONTENT_SUMMARY_URI,
-                        AGGREGATES_SUMMARY_PROJECTION,
-                        Aggregates.PRIMARY_PHONE_ID + " IS NOT NULL", null,
+                        AGGREGATES_SUMMARY_PROJECTION, getAggregateSelection(), null,
                         getSortOrder(AGGREGATES_SUMMARY_PROJECTION));
                 break;
 
@@ -1298,29 +1110,12 @@
         final ContentResolver resolver = getContentResolver();
 
         switch (mMode) {
-            /* case MODE_GROUP: {
-                Uri uri;
-                if (TextUtils.isEmpty(filter)) {
-                    uri = mGroupUri;
-                } else {
-                    uri = Uri.withAppendedPath(mGroupFilterUri, Uri.encode(filter));
-                }
-                return resolver.query(uri, CONTACTS_PROJECTION, null, null,
-                        getSortOrder(CONTACTS_PROJECTION));
-            } */
-
-            case MODE_ALL_CONTACTS:
+            case MODE_DEFAULT:
             case MODE_PICK_AGGREGATE:
             case MODE_PICK_OR_CREATE_AGGREGATE:
             case MODE_INSERT_OR_EDIT_CONTACT: {
                 return resolver.query(getAggregateFilterUri(filter), AGGREGATES_SUMMARY_PROJECTION,
-                        null, null, getSortOrder(AGGREGATES_SUMMARY_PROJECTION));
-            }
-
-             case MODE_WITH_PHONES: {
-                return resolver.query(getAggregateFilterUri(filter), AGGREGATES_SUMMARY_PROJECTION,
-                        Aggregates.PRIMARY_PHONE_ID + " IS NOT NULL", null,
-                        getSortOrder(AGGREGATES_SUMMARY_PROJECTION));
+                        getAggregateSelection(), null, getSortOrder(AGGREGATES_SUMMARY_PROJECTION));
             }
 
             case MODE_STARRED: {
@@ -1402,84 +1197,6 @@
         return (Cursor) listView.getAdapter().getItem(index);
     }
 
-    /*
-    private void setGroupEntries(AlertDialog.Builder builder) {
-        boolean syncEverything;
-        // For now we only support a single account and the UI doesn't know what
-        // the account name is, so we're using a global setting for SYNC_EVERYTHING.
-        // Some day when we add multiple accounts to the UI this should use the per
-        // account setting.
-        String value = Contacts.Settings.getSetting(getContentResolver(), null,
-                Contacts.Settings.SYNC_EVERYTHING);
-        if (value == null) {
-            // If nothing is set yet we default to syncing everything
-            syncEverything = true;
-        } else {
-            syncEverything = !TextUtils.isEmpty(value) && !"0".equals(value);
-        }
-
-        Cursor cursor;
-        if (!syncEverything) {
-            cursor = getContentResolver().query(Groups.CONTENT_URI, GROUPS_PROJECTION,
-                    Groups.SHOULD_SYNC + " != 0", null, Groups.DEFAULT_SORT_ORDER);
-        } else {
-            cursor = getContentResolver().query(Groups.CONTENT_URI, GROUPS_PROJECTION,
-                    null, null, Groups.DEFAULT_SORT_ORDER);
-        }
-        try {
-            ArrayList<CharSequence> groups = new ArrayList<CharSequence>();
-            ArrayList<CharSequence> prefStrings = new ArrayList<CharSequence>();
-
-            // Add All Contacts
-            groups.add(DISPLAY_GROUP_INDEX_ALL_CONTACTS, getString(R.string.showAllGroups));
-            prefStrings.add("");
-
-            // Add Contacts with phones
-            groups.add(DISPLAY_GROUP_INDEX_ALL_CONTACTS_WITH_PHONES,
-                    getString(R.string.groupNameWithPhones));
-            prefStrings.add(GROUP_WITH_PHONES);
-
-            int currentIndex = DISPLAY_GROUP_INDEX_ALL_CONTACTS;
-            while (cursor.moveToNext()) {
-                String systemId = cursor.getString(GROUPS_COLUMN_INDEX_SYSTEM_ID);
-                String name = cursor.getString(GROUPS_COLUMN_INDEX_NAME);
-                if (cursor.isNull(GROUPS_COLUMN_INDEX_SYSTEM_ID)
-                        && !Groups.GROUP_MY_CONTACTS.equals(systemId)) {
-                    // All groups that aren't My Contacts, since that one is localized on the phone
-
-                    // Localize the "Starred in Android" string which we get from the server side.
-                    if (Groups.GROUP_ANDROID_STARRED.equals(name)) {
-                        name = getString(R.string.starredInAndroid);
-                    }
-                    groups.add(name);
-                    if (name.equals(mDisplayInfo)) {
-                        currentIndex = groups.size() - 1;
-                    }
-                } else {
-                    // The My Contacts group
-                    groups.add(DISPLAY_GROUP_INDEX_MY_CONTACTS,
-                            getString(R.string.groupNameMyContacts));
-                    if (mDisplayType == DISPLAY_TYPE_SYSTEM_GROUP
-                            && Groups.GROUP_MY_CONTACTS.equals(mDisplayInfo)) {
-                        currentIndex = DISPLAY_GROUP_INDEX_MY_CONTACTS;
-                    }
-                    mDisplayGroupsIncludesMyContacts = true;
-                }
-            }
-            if (mMode == MODE_ALL_CONTACTS) {
-                currentIndex = DISPLAY_GROUP_INDEX_ALL_CONTACTS;
-            } else if (mMode == MODE_WITH_PHONES) {
-                currentIndex = DISPLAY_GROUP_INDEX_ALL_CONTACTS_WITH_PHONES;
-            }
-            mDisplayGroups = groups.toArray(new CharSequence[groups.size()]);
-            builder.setSingleChoiceItems(mDisplayGroups, currentIndex, this);
-            mDisplayGroupOriginalSelection = currentIndex;
-        } finally {
-            cursor.close();
-        }
-    }
-    */
-
     private static class QueryHandler extends AsyncQueryHandler {
         protected final WeakReference<ContactsListActivity> mActivity;
 
diff --git a/src/com/android/contacts/DisplayGroupsActivity.java b/src/com/android/contacts/DisplayGroupsActivity.java
new file mode 100644
index 0000000..c468655
--- /dev/null
+++ b/src/com/android/contacts/DisplayGroupsActivity.java
@@ -0,0 +1,635 @@
+/*
+ * 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 com.android.contacts.NotifyingAsyncQueryHandler.QueryCompleteListener;
+
+import android.app.ExpandableListActivity;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources;
+import android.database.CharArrayBuffer;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.database.DataSetObserver;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.preference.PreferenceManager;
+import android.provider.ContactsContract.Groups;
+import android.provider.ContactsContract.GroupsColumns;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.BaseExpandableListAdapter;
+import android.widget.CheckBox;
+import android.widget.ExpandableListView;
+import android.widget.SectionIndexer;
+import android.widget.TextView;
+import android.widget.AdapterView.OnItemClickListener;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Shows a list of all available {@link Groups} available, letting the user
+ * select which ones they want to be visible.
+ */
+public final class DisplayGroupsActivity extends ExpandableListActivity implements
+        QueryCompleteListener, OnItemClickListener {
+    private static final String TAG = "DisplayGroupsActivity";
+
+    public interface Prefs {
+        public static final String DISPLAY_ALL = "display_all";
+        public static final boolean DISPLAY_ALL_DEFAULT = true;
+
+        public static final String DISPLAY_ONLY_PHONES = "only_phones";
+        public static final boolean DISPLAY_ONLY_PHONES_DEFAULT = true;
+
+    }
+
+    private ExpandableListView mList;
+    private DisplayGroupsAdapter mAdapter;
+
+    private SharedPreferences mPrefs;
+    private NotifyingAsyncQueryHandler mHandler;
+
+    private static final int QUERY_TOKEN = 42;
+
+    private View mHeaderAll;
+    private View mHeaderPhones;
+    private View mHeaderSeparator;
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        setContentView(android.R.layout.expandable_list_content);
+
+        mList = getExpandableListView();
+        mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
+
+        boolean displayAll = mPrefs.getBoolean(Prefs.DISPLAY_ALL, Prefs.DISPLAY_ALL_DEFAULT);
+        boolean displayOnlyPhones = mPrefs.getBoolean(Prefs.DISPLAY_ONLY_PHONES,
+                Prefs.DISPLAY_ONLY_PHONES_DEFAULT);
+
+        final LayoutInflater inflater = getLayoutInflater();
+
+        // Add the "All contacts" header modifier.
+        mHeaderAll = inflater.inflate(R.layout.display_header, mList, false);
+        mHeaderAll.setId(R.id.header_all);
+        {
+            CheckBox checkbox = (CheckBox)mHeaderAll.findViewById(android.R.id.checkbox);
+            TextView text1 = (TextView)mHeaderAll.findViewById(android.R.id.text1);
+            checkbox.setChecked(displayAll);
+            text1.setText(R.string.showAllGroups);
+        }
+        mList.addHeaderView(mHeaderAll, null, true);
+
+
+        // Add the "Only contacts with phones" header modifier.
+        mHeaderPhones = inflater.inflate(R.layout.display_header, mList, false);
+        mHeaderPhones.setId(R.id.header_phones);
+        {
+            CheckBox checkbox = (CheckBox)mHeaderPhones.findViewById(android.R.id.checkbox);
+            TextView text1 = (TextView)mHeaderPhones.findViewById(android.R.id.text1);
+            TextView text2 = (TextView)mHeaderPhones.findViewById(android.R.id.text2);
+            checkbox.setChecked(displayOnlyPhones);
+            text1.setText(R.string.showFilterPhones);
+            text2.setText(R.string.showFilterPhonesDescrip);
+        }
+        mList.addHeaderView(mHeaderPhones, null, true);
+
+
+        // Add the separator before showing the detailed group list.
+        mHeaderSeparator = inflater.inflate(R.layout.list_separator, mList, false);
+        {
+            TextView text1 = (TextView)mHeaderSeparator;
+            text1.setText(R.string.headerContactGroups);
+        }
+        mList.addHeaderView(mHeaderSeparator, null, false);
+
+
+        final TextView allContactsView = (TextView)mHeaderAll.findViewById(android.R.id.text2);
+
+        mAdapter = new DisplayGroupsAdapter(this);
+        mAdapter.setAllContactsView(allContactsView);
+
+        mAdapter.setEnabled(!displayAll);
+        mAdapter.setChildDescripWithPhones(displayOnlyPhones);
+
+        setListAdapter(mAdapter);
+
+        // Catch clicks on the header views
+        mList.setOnItemClickListener(this);
+
+        mHandler = new NotifyingAsyncQueryHandler(this, this);
+        startQuery();
+
+    }
+
+    @Override
+    protected void onRestart() {
+        super.onRestart();
+        startQuery();
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        mHandler.cancelOperation(QUERY_TOKEN);
+    }
+
+
+    private void startQuery() {
+        mHandler.cancelOperation(QUERY_TOKEN);
+        mHandler.startQuery(QUERY_TOKEN, null, Groups.CONTENT_SUMMARY_URI,
+                Projections.PROJ_SUMMARY, null, null, Projections.SORT_ORDER);
+    }
+
+    public void onQueryComplete(int token, Object cookie, Cursor cursor) {
+        mAdapter.changeCursor(cursor);
+
+        // Expand all data sources
+        final int groupCount = mAdapter.getGroupCount();
+        for (int i = 0; i < groupCount; i++) {
+            mList.expandGroup(i);
+        }
+    }
+
+    /**
+     * Handle any clicks on header views added to our {@link #mAdapter}, which
+     * are usually the global modifier checkboxes.
+     */
+    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+        final CheckBox checkbox = (CheckBox)view.findViewById(android.R.id.checkbox);
+        switch (view.getId()) {
+            case R.id.header_all: {
+                checkbox.toggle();
+                final boolean displayAll = checkbox.isChecked();
+
+                Editor editor = mPrefs.edit();
+                editor.putBoolean(Prefs.DISPLAY_ALL, displayAll);
+                editor.commit();
+
+                mAdapter.setEnabled(!displayAll);
+                mAdapter.notifyDataSetChanged();
+
+                break;
+            }
+            case R.id.header_phones: {
+                checkbox.toggle();
+                final boolean displayOnlyPhones = checkbox.isChecked();
+
+                Editor editor = mPrefs.edit();
+                editor.putBoolean(Prefs.DISPLAY_ONLY_PHONES, displayOnlyPhones);
+                editor.commit();
+
+                mAdapter.setChildDescripWithPhones(displayOnlyPhones);
+                mAdapter.notifyDataSetChanged();
+
+                break;
+            }
+        }
+    }
+
+    /**
+     * Handle any clicks on {@link ExpandableListAdapter} children, which
+     * usually mean toggling its visible state.
+     */
+    @Override
+    public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
+            int childPosition, long id) {
+        if (!mAdapter.isEnabled()) {
+            return false;
+        }
+
+        final CheckBox checkbox = (CheckBox)v.findViewById(android.R.id.checkbox);
+        checkbox.toggle();
+
+        // Build visibility update and send down to database
+        final ContentResolver resolver = getContentResolver();
+        final ContentValues values = new ContentValues();
+
+        values.put(Groups.GROUP_VISIBLE, checkbox.isChecked() ? 1 : 0);
+
+        final long groupId = mAdapter.getChildId(groupPosition, childPosition);
+        final Uri groupUri = ContentUris.withAppendedId(Groups.CONTENT_URI, groupId);
+
+        resolver.update(groupUri, values, null, null);
+
+        return true;
+    }
+
+    /**
+     * Helper for obtaining {@link Resources} instances that are based in an
+     * external package. Maintains internal cache to remain fast.
+     */
+    private static class ExternalResources {
+        private Context mContext;
+        private HashMap<String, Context> mCache = new HashMap<String, Context>();
+
+        public ExternalResources(Context context) {
+            mContext = context;
+        }
+
+        private Context getPackageContext(String packageName) throws NameNotFoundException {
+            Context theirContext = mCache.get(packageName);
+            if (theirContext == null) {
+                theirContext = mContext.createPackageContext(packageName, 0);
+                mCache.put(packageName, theirContext);
+            }
+            return theirContext;
+        }
+
+        public Resources getResources(String packageName) throws NameNotFoundException {
+            return getPackageContext(packageName).getResources();
+        }
+
+        public CharSequence getText(String packageName, int stringRes)
+                throws NameNotFoundException {
+            return getResources(packageName).getText(stringRes);
+        }
+    }
+
+    /**
+     * Adapter that shows all display groups as returned by a {@link Cursor}
+     * over {@link Groups#CONTENT_SUMMARY_URI}, along with their current visible
+     * status. Splits groups into sections based on {@link Groups#PACKAGE}.
+     */
+    private static class DisplayGroupsAdapter extends BaseExpandableListAdapter {
+        private boolean mDataValid;
+        private Cursor mCursor;
+        private Context mContext;
+        private Resources mResources;
+        private ExternalResources mExternalRes;
+        private LayoutInflater mInflater;
+        private int mRowIDColumn;
+
+        private TextView mAllContactsView;
+
+        private boolean mEnabled = true;
+        private boolean mChildWithPhones = false;
+
+        private ContentObserver mContentObserver = new MyChangeObserver();
+        private DataSetObserver mDataSetObserver = new MyDataSetObserver();
+
+        /**
+         * A single group in our expandable list.
+         */
+        private static class Group {
+            public long packageId = -1;
+            public String packageName = null;
+            public int firstPos;
+            public int lastPos;
+            public CharSequence label;
+        }
+
+        /**
+         * Maintain a list of all groups that need to be displayed by this
+         * adapter, usually built by walking across a single {@link Cursor} and
+         * finding the {@link Groups#PACKAGE} boundaries.
+         */
+        private static final ArrayList<Group> mGroups = new ArrayList<Group>();
+
+        public DisplayGroupsAdapter(Context context) {
+            mContext = context;
+            mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+            mResources = context.getResources();
+            mExternalRes = new ExternalResources(mContext);
+        }
+
+        /**
+         * In group descriptions, show the number of contacts with phone
+         * numbers, in addition to the total contacts.
+         */
+        public void setChildDescripWithPhones(boolean withPhones) {
+            mChildWithPhones = withPhones;
+        }
+
+        /**
+         * Set a {@link TextView} to be filled with the total number of contacts
+         * across all available groups.
+         */
+        public void setAllContactsView(TextView allContactsView) {
+            mAllContactsView = allContactsView;
+        }
+
+        /**
+         * Set the {@link View#setEnabled(boolean)} state of any views
+         * constructed by this adapter.
+         */
+        public void setEnabled(boolean enabled) {
+            mEnabled = enabled;
+        }
+
+        /**
+         * Returns the {@link View#setEnabled(boolean)} value being set for any
+         * children views of this adapter.
+         */
+        public boolean isEnabled() {
+            return mEnabled;
+        }
+
+        /**
+         * Used internally to build the {@link #mGroups} mapping. Call when you
+         * have a valid cursor and are ready to rebuild the mapping.
+         */
+        private void buildInternalMapping() {
+            final PackageManager pm = mContext.getPackageManager();
+            int totalContacts = 0;
+            Group group = null;
+
+            mGroups.clear();
+            mCursor.moveToPosition(-1);
+            while (mCursor.moveToNext()) {
+                final int position = mCursor.getPosition();
+                final long packageId = mCursor.getLong(Projections.COL_PACKAGE_ID);
+                totalContacts += mCursor.getInt(Projections.COL_SUMMARY_COUNT);
+                if (group == null || packageId != group.packageId) {
+                    group = new Group();
+                    group.packageId = packageId;
+                    group.packageName = mCursor.getString(Projections.COL_PACKAGE);
+                    group.firstPos = position;
+                    group.label = group.packageName;
+
+                    try {
+                        group.label = pm.getApplicationInfo(group.packageName, 0).loadLabel(pm);
+                    } catch (NameNotFoundException e) {
+                        Log.w(TAG, "couldn't find label for package " + group.packageName);
+                    }
+
+                    mGroups.add(group);
+                }
+                group.lastPos = position;
+            }
+
+            if (mAllContactsView != null) {
+                mAllContactsView.setText(mResources.getQuantityString(R.plurals.groupDescrip,
+                        totalContacts, totalContacts));
+            }
+
+        }
+
+        /**
+         * Map the given group and child position into a flattened position on
+         * our single {@link Cursor}.
+         */
+        public int getCursorPosition(int groupPosition, int childPosition) {
+            // The actual cursor position for a child is simply stepping from
+            // the first position for that group.
+            final Group group = mGroups.get(groupPosition);
+            final int position = group.firstPos + childPosition;
+            return position;
+        }
+
+        public boolean hasStableIds() {
+            return true;
+        }
+
+        public boolean isChildSelectable(int groupPosition, int childPosition) {
+            return true;
+        }
+
+        public Object getChild(int groupPosition, int childPosition) {
+            if (mDataValid && mCursor != null) {
+                final int position = getCursorPosition(groupPosition, childPosition);
+                mCursor.moveToPosition(position);
+                return mCursor;
+            } else {
+                return null;
+            }
+        }
+
+        public long getChildId(int groupPosition, int childPosition) {
+            if (mDataValid && mCursor != null) {
+                final int position = getCursorPosition(groupPosition, childPosition);
+                if (mCursor.moveToPosition(position)) {
+                    return mCursor.getLong(mRowIDColumn);
+                } else {
+                    return 0;
+                }
+            } else {
+                return 0;
+            }
+        }
+
+        public int getChildrenCount(int groupPosition) {
+            if (mDataValid && mCursor != null) {
+                final Group group = mGroups.get(groupPosition);
+                final int size = group.lastPos - group.firstPos + 1;
+                return size;
+            } else {
+                return 0;
+            }
+        }
+
+        public Object getGroup(int groupPosition) {
+            if (mDataValid && mCursor != null) {
+                return mGroups.get(groupPosition);
+            } else {
+                return null;
+            }
+        }
+
+        public int getGroupCount() {
+            if (mDataValid && mCursor != null) {
+                return mGroups.size();
+            } else {
+                return 0;
+            }
+        }
+
+        public long getGroupId(int groupPosition) {
+            if (mDataValid && mCursor != null) {
+                final Group group = mGroups.get(groupPosition);
+                return group.packageId;
+            } else {
+                return 0;
+            }
+        }
+
+        public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
+                ViewGroup parent) {
+            if (!mDataValid) {
+                throw new IllegalStateException("called with invalid cursor");
+            }
+
+            final Group group = mGroups.get(groupPosition);
+
+            if (convertView == null) {
+                convertView = mInflater.inflate(R.layout.display_group, parent, false);
+            }
+
+            final TextView text1 = (TextView)convertView.findViewById(android.R.id.text1);
+
+            text1.setText(group.label);
+
+            convertView.setEnabled(mEnabled);
+
+            return convertView;
+        }
+
+        public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
+                View convertView, ViewGroup parent) {
+            if (!mDataValid) {
+                throw new IllegalStateException("called with invalid cursor");
+            }
+
+            final int position = getCursorPosition(groupPosition, childPosition);
+            if (!mCursor.moveToPosition(position)) {
+                throw new IllegalStateException("couldn't move cursor to position " + position);
+            }
+
+            if (convertView == null) {
+                convertView = mInflater.inflate(R.layout.display_child, parent, false);
+            }
+
+            final TextView text1 = (TextView)convertView.findViewById(android.R.id.text1);
+            final TextView text2 = (TextView)convertView.findViewById(android.R.id.text2);
+            final CheckBox checkbox = (CheckBox)convertView.findViewById(android.R.id.checkbox);
+
+            final int count = mCursor.getInt(Projections.COL_SUMMARY_COUNT);
+            final int withPhones = mCursor.getInt(Projections.COL_SUMMARY_WITH_PHONES);
+            final int membersVisible = mCursor.getInt(Projections.COL_GROUP_VISIBLE);
+
+            // Read title, but override with string resource when present
+            CharSequence title = mCursor.getString(Projections.COL_TITLE);
+            if (!mCursor.isNull(Projections.COL_TITLE_RESOURCE)) {
+                final String packageName = mCursor.getString(Projections.COL_PACKAGE);
+                final int titleRes = mCursor.getInt(Projections.COL_TITLE_RESOURCE);
+                try {
+                    title = mExternalRes.getText(packageName, titleRes);
+                } catch (NameNotFoundException e) {
+                    Log.w(TAG, "couldn't load group title resource for " + packageName);
+                }
+            }
+
+            final int descripString = mChildWithPhones ? R.plurals.groupDescripPhones
+                    : R.plurals.groupDescrip;
+
+            text1.setText(title);
+            text2.setText(mResources.getQuantityString(descripString, count, count, withPhones));
+            checkbox.setChecked((membersVisible == 1));
+
+            convertView.setEnabled(mEnabled);
+
+            return convertView;
+        }
+
+        public void changeCursor(Cursor cursor) {
+            if (cursor == mCursor) {
+                return;
+            }
+            if (mCursor != null) {
+                mCursor.unregisterContentObserver(mContentObserver);
+                mCursor.unregisterDataSetObserver(mDataSetObserver);
+                mCursor.close();
+            }
+            mCursor = cursor;
+            if (cursor != null) {
+                cursor.registerContentObserver(mContentObserver);
+                cursor.registerDataSetObserver(mDataSetObserver);
+                mRowIDColumn = cursor.getColumnIndexOrThrow("_id");
+                mDataValid = true;
+                buildInternalMapping();
+                // notify the observers about the new cursor
+                notifyDataSetChanged();
+            } else {
+                mRowIDColumn = -1;
+                mDataValid = false;
+                // notify the observers about the lack of a data set
+                notifyDataSetInvalidated();
+            }
+        }
+
+        protected void onContentChanged() {
+            if (mCursor != null && !mCursor.isClosed()) {
+                mDataValid = mCursor.requery();
+            }
+        }
+
+        private class MyChangeObserver extends ContentObserver {
+            public MyChangeObserver() {
+                super(new Handler());
+            }
+
+            @Override
+            public boolean deliverSelfNotifications() {
+                return true;
+            }
+
+            @Override
+            public void onChange(boolean selfChange) {
+                onContentChanged();
+            }
+        }
+
+        private class MyDataSetObserver extends DataSetObserver {
+            @Override
+            public void onChanged() {
+                mDataValid = true;
+                notifyDataSetChanged();
+            }
+
+            @Override
+            public void onInvalidated() {
+                mDataValid = false;
+                notifyDataSetInvalidated();
+            }
+        }
+
+    }
+
+    /**
+     * Database projections used locally.
+     */
+    private interface Projections {
+
+        public static final String[] PROJ_SUMMARY = new String[] {
+            Groups._ID,
+            Groups.PACKAGE_ID,
+            Groups.PACKAGE,
+            Groups.TITLE,
+            Groups.TITLE_RESOURCE,
+            Groups.GROUP_VISIBLE,
+            Groups.SUMMARY_COUNT,
+            Groups.SUMMARY_WITH_PHONES,
+        };
+
+        public static final String SORT_ORDER = Groups.PACKAGE + " ASC";
+
+        public static final int COL_ID = 0;
+        public static final int COL_PACKAGE_ID = 1;
+        public static final int COL_PACKAGE = 2;
+        public static final int COL_TITLE = 3;
+        public static final int COL_TITLE_RESOURCE = 4;
+        public static final int COL_GROUP_VISIBLE = 5;
+        public static final int COL_SUMMARY_COUNT = 6;
+        public static final int COL_SUMMARY_WITH_PHONES = 7;
+
+    }
+
+}
