diff --git a/src/com/android/contacts/GroupingListAdapter.java b/src/com/android/contacts/GroupingListAdapter.java
deleted file mode 100644
index 5937a6d..0000000
--- a/src/com/android/contacts/GroupingListAdapter.java
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts;
-
-import com.android.internal.util.ArrayUtils;
-
-import android.content.Context;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.database.DataSetObserver;
-import android.os.Handler;
-import android.util.SparseIntArray;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-
-/**
- * Maintains a list that groups adjacent items sharing the same value of
- * a "group-by" field.  The list has three types of elements: stand-alone, group header and group
- * child. Groups are collapsible and collapsed by default.
- */
-public abstract class GroupingListAdapter extends BaseAdapter {
-
-    private static final int GROUP_METADATA_ARRAY_INITIAL_SIZE = 16;
-    private static final int GROUP_METADATA_ARRAY_INCREMENT = 128;
-    private static final long GROUP_OFFSET_MASK    = 0x00000000FFFFFFFFL;
-    private static final long GROUP_SIZE_MASK     = 0x7FFFFFFF00000000L;
-    private static final long EXPANDED_GROUP_MASK = 0x8000000000000000L;
-
-    public static final int ITEM_TYPE_STANDALONE = 0;
-    public static final int ITEM_TYPE_GROUP_HEADER = 1;
-    public static final int ITEM_TYPE_IN_GROUP = 2;
-
-    /**
-     * Information about a specific list item: is it a group, if so is it expanded.
-     * Otherwise, is it a stand-alone item or a group member.
-     */
-    protected static class PositionMetadata {
-        int itemType;
-        boolean isExpanded;
-        int cursorPosition;
-        int childCount;
-        private int groupPosition;
-        private int listPosition = -1;
-    }
-
-    private Context mContext;
-    private Cursor mCursor;
-
-    /**
-     * Count of list items.
-     */
-    private int mCount;
-
-    private int mRowIdColumnIndex;
-
-    /**
-     * Count of groups in the list.
-     */
-    private int mGroupCount;
-
-    /**
-     * Information about where these groups are located in the list, how large they are
-     * and whether they are expanded.
-     */
-    private long[] mGroupMetadata;
-
-    private SparseIntArray mPositionCache = new SparseIntArray();
-    private int mLastCachedListPosition;
-    private int mLastCachedCursorPosition;
-    private int mLastCachedGroup;
-
-    /**
-     * A reusable temporary instance of PositionMetadata
-     */
-    private PositionMetadata mPositionMetadata = new PositionMetadata();
-
-    protected ContentObserver mChangeObserver = new ContentObserver(new Handler()) {
-
-        @Override
-        public boolean deliverSelfNotifications() {
-            return true;
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            onContentChanged();
-        }
-    };
-
-    protected DataSetObserver mDataSetObserver = new DataSetObserver() {
-
-        @Override
-        public void onChanged() {
-            notifyDataSetChanged();
-        }
-
-        @Override
-        public void onInvalidated() {
-            notifyDataSetInvalidated();
-        }
-    };
-
-    public GroupingListAdapter(Context context) {
-        mContext = context;
-        resetCache();
-    }
-
-    /**
-     * Finds all groups of adjacent items in the cursor and calls {@link #addGroup} for
-     * each of them.
-     */
-    protected abstract void addGroups(Cursor cursor);
-
-    protected abstract View newStandAloneView(Context context, ViewGroup parent);
-    protected abstract void bindStandAloneView(View view, Context context, Cursor cursor);
-
-    protected abstract View newGroupView(Context context, ViewGroup parent);
-    protected abstract void bindGroupView(View view, Context context, Cursor cursor, int groupSize,
-            boolean expanded);
-
-    protected abstract View newChildView(Context context, ViewGroup parent);
-    protected abstract void bindChildView(View view, Context context, Cursor cursor);
-
-    /**
-     * Cache should be reset whenever the cursor changes or groups are expanded or collapsed.
-     */
-    private void resetCache() {
-        mCount = -1;
-        mLastCachedListPosition = -1;
-        mLastCachedCursorPosition = -1;
-        mLastCachedGroup = -1;
-        mPositionMetadata.listPosition = -1;
-        mPositionCache.clear();
-    }
-
-    protected void onContentChanged() {
-    }
-
-    public void changeCursor(Cursor cursor) {
-        if (cursor == mCursor) {
-            return;
-        }
-
-        if (mCursor != null) {
-            mCursor.unregisterContentObserver(mChangeObserver);
-            mCursor.unregisterDataSetObserver(mDataSetObserver);
-            mCursor.close();
-        }
-        mCursor = cursor;
-        resetCache();
-        findGroups();
-
-        if (cursor != null) {
-            cursor.registerContentObserver(mChangeObserver);
-            cursor.registerDataSetObserver(mDataSetObserver);
-            mRowIdColumnIndex = cursor.getColumnIndexOrThrow("_id");
-            notifyDataSetChanged();
-        } else {
-            // notify the observers about the lack of a data set
-            notifyDataSetInvalidated();
-        }
-
-    }
-
-    public Cursor getCursor() {
-        return mCursor;
-    }
-
-    /**
-     * Scans over the entire cursor looking for duplicate phone numbers that need
-     * to be collapsed.
-     */
-    private void findGroups() {
-        mGroupCount = 0;
-        mGroupMetadata = new long[GROUP_METADATA_ARRAY_INITIAL_SIZE];
-
-        if (mCursor == null) {
-            return;
-        }
-
-        addGroups(mCursor);
-    }
-
-    /**
-     * Records information about grouping in the list.  Should be called by the overridden
-     * {@link #addGroups} method.
-     */
-    protected void addGroup(int cursorPosition, int size, boolean expanded) {
-        if (mGroupCount >= mGroupMetadata.length) {
-            int newSize = ArrayUtils.idealLongArraySize(
-                    mGroupMetadata.length + GROUP_METADATA_ARRAY_INCREMENT);
-            long[] array = new long[newSize];
-            System.arraycopy(mGroupMetadata, 0, array, 0, mGroupCount);
-            mGroupMetadata = array;
-        }
-
-        long metadata = ((long)size << 32) | cursorPosition;
-        if (expanded) {
-            metadata |= EXPANDED_GROUP_MASK;
-        }
-        mGroupMetadata[mGroupCount++] = metadata;
-    }
-
-    public int getCount() {
-        if (mCursor == null) {
-            return 0;
-        }
-
-        if (mCount != -1) {
-            return mCount;
-        }
-
-        int cursorPosition = 0;
-        int count = 0;
-        for (int i = 0; i < mGroupCount; i++) {
-            long metadata = mGroupMetadata[i];
-            int offset = (int)(metadata & GROUP_OFFSET_MASK);
-            boolean expanded = (metadata & EXPANDED_GROUP_MASK) != 0;
-            int size = (int)((metadata & GROUP_SIZE_MASK) >> 32);
-
-            count += (offset - cursorPosition);
-
-            if (expanded) {
-                count += size + 1;
-            } else {
-                count++;
-            }
-
-            cursorPosition = offset + size;
-        }
-
-        mCount = count + mCursor.getCount() - cursorPosition;
-        return mCount;
-    }
-
-    /**
-     * Figures out whether the item at the specified position represents a
-     * stand-alone element, a group or a group child. Also computes the
-     * corresponding cursor position.
-     */
-    public void obtainPositionMetadata(PositionMetadata metadata, int position) {
-
-        // If the description object already contains requested information, just return
-        if (metadata.listPosition == position) {
-            return;
-        }
-
-        int listPosition = 0;
-        int cursorPosition = 0;
-        int firstGroupToCheck = 0;
-
-        // Check cache for the supplied position.  What we are looking for is
-        // the group descriptor immediately preceding the supplied position.
-        // Once we have that, we will be able to tell whether the position
-        // is the header of the group, a member of the group or a standalone item.
-        if (mLastCachedListPosition != -1) {
-            if (position <= mLastCachedListPosition) {
-
-                // Have SparceIntArray do a binary search for us.
-                int index = mPositionCache.indexOfKey(position);
-
-                // If we get back a positive number, the position corresponds to
-                // a group header.
-                if (index < 0) {
-
-                    // We had a cache miss, but we did obtain valuable information anyway.
-                    // The negative number will allow us to compute the location of
-                    // the group header immediately preceding the supplied position.
-                    index = ~index - 1;
-
-                    if (index >= mPositionCache.size()) {
-                        index--;
-                    }
-                }
-
-                // A non-negative index gives us the position of the group header
-                // corresponding or preceding the position, so we can
-                // search for the group information at the supplied position
-                // starting with the cached group we just found
-                if (index >= 0) {
-                    listPosition = mPositionCache.keyAt(index);
-                    firstGroupToCheck = mPositionCache.valueAt(index);
-                    long descriptor = mGroupMetadata[firstGroupToCheck];
-                    cursorPosition = (int)(descriptor & GROUP_OFFSET_MASK);
-                }
-            } else {
-
-                // If we haven't examined groups beyond the supplied position,
-                // we will start where we left off previously
-                firstGroupToCheck = mLastCachedGroup;
-                listPosition = mLastCachedListPosition;
-                cursorPosition = mLastCachedCursorPosition;
-            }
-        }
-
-        for (int i = firstGroupToCheck; i < mGroupCount; i++) {
-            long group = mGroupMetadata[i];
-            int offset = (int)(group & GROUP_OFFSET_MASK);
-
-            // Move pointers to the beginning of the group
-            listPosition += (offset - cursorPosition);
-            cursorPosition = offset;
-
-            if (i > mLastCachedGroup) {
-                mPositionCache.append(listPosition, i);
-                mLastCachedListPosition = listPosition;
-                mLastCachedCursorPosition = cursorPosition;
-                mLastCachedGroup = i;
-            }
-
-            // Now we have several possibilities:
-            // A) The requested position precedes the group
-            if (position < listPosition) {
-                metadata.itemType = ITEM_TYPE_STANDALONE;
-                metadata.cursorPosition = cursorPosition - (listPosition - position);
-                return;
-            }
-
-            boolean expanded = (group & EXPANDED_GROUP_MASK) != 0;
-            int size = (int) ((group & GROUP_SIZE_MASK) >> 32);
-
-            // B) The requested position is a group header
-            if (position == listPosition) {
-                metadata.itemType = ITEM_TYPE_GROUP_HEADER;
-                metadata.groupPosition = i;
-                metadata.isExpanded = expanded;
-                metadata.childCount = size;
-                metadata.cursorPosition = offset;
-                return;
-            }
-
-            if (expanded) {
-                // C) The requested position is an element in the expanded group
-                if (position < listPosition + size + 1) {
-                    metadata.itemType = ITEM_TYPE_IN_GROUP;
-                    metadata.cursorPosition = cursorPosition + (position - listPosition) - 1;
-                    return;
-                }
-
-                // D) The element is past the expanded group
-                listPosition += size + 1;
-            } else {
-
-                // E) The element is past the collapsed group
-                listPosition++;
-            }
-
-            // Move cursor past the group
-            cursorPosition += size;
-        }
-
-        // The required item is past the last group
-        metadata.itemType = ITEM_TYPE_STANDALONE;
-        metadata.cursorPosition = cursorPosition + (position - listPosition);
-    }
-
-    /**
-     * Returns true if the specified position in the list corresponds to a
-     * group header.
-     */
-    public boolean isGroupHeader(int position) {
-        obtainPositionMetadata(mPositionMetadata, position);
-        return mPositionMetadata.itemType == ITEM_TYPE_GROUP_HEADER;
-    }
-
-    /**
-     * Given a position of a groups header in the list, returns the size of
-     * the corresponding group.
-     */
-    public int getGroupSize(int position) {
-        obtainPositionMetadata(mPositionMetadata, position);
-        return mPositionMetadata.childCount;
-    }
-
-    /**
-     * Mark group as expanded if it is collapsed and vice versa.
-     */
-    public void toggleGroup(int position) {
-        obtainPositionMetadata(mPositionMetadata, position);
-        if (mPositionMetadata.itemType != ITEM_TYPE_GROUP_HEADER) {
-            throw new IllegalArgumentException("Not a group at position " + position);
-        }
-
-
-        if (mPositionMetadata.isExpanded) {
-            mGroupMetadata[mPositionMetadata.groupPosition] &= ~EXPANDED_GROUP_MASK;
-        } else {
-            mGroupMetadata[mPositionMetadata.groupPosition] |= EXPANDED_GROUP_MASK;
-        }
-        resetCache();
-        notifyDataSetChanged();
-    }
-
-    @Override
-    public int getViewTypeCount() {
-        return 3;
-    }
-
-    @Override
-    public int getItemViewType(int position) {
-        obtainPositionMetadata(mPositionMetadata, position);
-        return mPositionMetadata.itemType;
-    }
-
-    public Object getItem(int position) {
-        if (mCursor == null) {
-            return null;
-        }
-
-        obtainPositionMetadata(mPositionMetadata, position);
-        if (mCursor.moveToPosition(mPositionMetadata.cursorPosition)) {
-            return mCursor;
-        } else {
-            return null;
-        }
-    }
-
-    public long getItemId(int position) {
-        Object item = getItem(position);
-        if (item != null) {
-            return mCursor.getLong(mRowIdColumnIndex);
-        } else {
-            return -1;
-        }
-    }
-
-    public View getView(int position, View convertView, ViewGroup parent) {
-        obtainPositionMetadata(mPositionMetadata, position);
-        View view = convertView;
-        if (view == null) {
-            switch (mPositionMetadata.itemType) {
-                case ITEM_TYPE_STANDALONE:
-                    view = newStandAloneView(mContext, parent);
-                    break;
-                case ITEM_TYPE_GROUP_HEADER:
-                    view = newGroupView(mContext, parent);
-                    break;
-                case ITEM_TYPE_IN_GROUP:
-                    view = newChildView(mContext, parent);
-                    break;
-            }
-        }
-
-        mCursor.moveToPosition(mPositionMetadata.cursorPosition);
-        switch (mPositionMetadata.itemType) {
-            case ITEM_TYPE_STANDALONE:
-                bindStandAloneView(view, mContext, mCursor);
-                break;
-            case ITEM_TYPE_GROUP_HEADER:
-                bindGroupView(view, mContext, mCursor, mPositionMetadata.childCount,
-                        mPositionMetadata.isExpanded);
-                break;
-            case ITEM_TYPE_IN_GROUP:
-                bindChildView(view, mContext, mCursor);
-                break;
-
-        }
-        return view;
-    }
-}
diff --git a/src/com/android/contacts/RecentCallsListActivity.java b/src/com/android/contacts/RecentCallsListActivity.java
index d29be6c..9275e52 100644
--- a/src/com/android/contacts/RecentCallsListActivity.java
+++ b/src/com/android/contacts/RecentCallsListActivity.java
@@ -16,6 +16,7 @@
 
 package com.android.contacts;
 
+import com.android.common.widget.GroupingListAdapter;
 import com.android.internal.telephony.CallerInfo;
 import com.android.internal.telephony.ITelephony;
 
diff --git a/tests/src/com/android/contacts/GroupingListAdapterTests.java b/tests/src/com/android/contacts/GroupingListAdapterTests.java
deleted file mode 100644
index 1877fac..0000000
--- a/tests/src/com/android/contacts/GroupingListAdapterTests.java
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts;
-
-import android.content.Context;
-import android.database.CharArrayBuffer;
-import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.provider.CallLog.Calls;
-import android.test.AndroidTestCase;
-import android.text.TextUtils;
-import android.view.View;
-import android.view.ViewGroup;
-
-import static com.android.contacts.GroupingListAdapter.ITEM_TYPE_STANDALONE;
-import static com.android.contacts.GroupingListAdapter.ITEM_TYPE_IN_GROUP;
-import static com.android.contacts.GroupingListAdapter.ITEM_TYPE_GROUP_HEADER;
-
-/**
- * Tests for the contact call list adapter.
- *
- * Running all tests:
- *
- *   runtest contacts
- * or
- *   adb shell am instrument \
- *     -w com.android.contacts.tests/android.test.InstrumentationTestRunner
- */
-public class GroupingListAdapterTests extends AndroidTestCase {
-
-    static private final String[] CALL_LOG_PROJECTION = new String[] {
-        Calls._ID,
-        Calls.NUMBER,
-        Calls.DATE,
-    };
-
-    private static final int CALLS_NUMBER_COLUMN_INDEX = 1;
-
-    private MatrixCursor mCursor;
-    private long mNextCall;
-
-    private GroupingListAdapter mAdapter = new GroupingListAdapter(null) {
-
-        @Override
-        protected void addGroups(Cursor cursor) {
-            int count = cursor.getCount();
-            int groupItemCount = 1;
-            cursor.moveToFirst();
-            String currentValue = cursor.getString(CALLS_NUMBER_COLUMN_INDEX);
-            for (int i = 1; i < count; i++) {
-                cursor.moveToNext();
-                String value = cursor.getString(CALLS_NUMBER_COLUMN_INDEX);
-                if (TextUtils.equals(value, currentValue)) {
-                    groupItemCount++;
-                } else {
-                    if (groupItemCount > 1) {
-                        addGroup(i - groupItemCount, groupItemCount, false);
-                    }
-
-                    groupItemCount = 1;
-                    currentValue = value;
-                }
-            }
-            if (groupItemCount > 1) {
-                addGroup(count - groupItemCount, groupItemCount, false);
-            }
-        }
-
-        @Override
-        protected void bindChildView(View view, Context context, Cursor cursor) {
-        }
-
-        @Override
-        protected void bindGroupView(View view, Context context, Cursor cursor, int groupSize,
-                boolean expanded) {
-        }
-
-        @Override
-        protected void bindStandAloneView(View view, Context context, Cursor cursor) {
-        }
-
-        @Override
-        protected View newChildView(Context context, ViewGroup parent) {
-            return null;
-        }
-
-        @Override
-        protected View newGroupView(Context context, ViewGroup parent) {
-            return null;
-        }
-
-        @Override
-        protected View newStandAloneView(Context context, ViewGroup parent) {
-            return null;
-        }
-    };
-
-    private void buildCursor(String... numbers) {
-        mCursor = new MatrixCursor(CALL_LOG_PROJECTION);
-        mNextCall = 1;
-        for (String number : numbers) {
-            mCursor.addRow(new Object[]{mNextCall, number, 1000 - mNextCall});
-            mNextCall++;
-        }
-    }
-
-    public void testGroupingWithoutGroups() {
-        buildCursor("1", "2", "3");
-        mAdapter.changeCursor(mCursor);
-
-        assertEquals(3, mAdapter.getCount());
-        assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
-        assertPositionMetadata(1, ITEM_TYPE_STANDALONE, false, 1);
-        assertPositionMetadata(2, ITEM_TYPE_STANDALONE, false, 2);
-    }
-
-    public void testGroupingWithCollapsedGroupAtTheBeginning() {
-        buildCursor("1", "1", "2");
-        mAdapter.changeCursor(mCursor);
-
-        assertEquals(2, mAdapter.getCount());
-        assertPositionMetadata(0, ITEM_TYPE_GROUP_HEADER, false, 0);
-        assertPositionMetadata(1, ITEM_TYPE_STANDALONE, false, 2);
-    }
-
-    public void testGroupingWithExpandedGroupAtTheBeginning() {
-        buildCursor("1", "1", "2");
-        mAdapter.changeCursor(mCursor);
-        mAdapter.toggleGroup(0);
-
-        assertEquals(4, mAdapter.getCount());
-        assertPositionMetadata(0, ITEM_TYPE_GROUP_HEADER, true, 0);
-        assertPositionMetadata(1, ITEM_TYPE_IN_GROUP, false, 0);
-        assertPositionMetadata(2, ITEM_TYPE_IN_GROUP, false, 1);
-        assertPositionMetadata(3, ITEM_TYPE_STANDALONE, false, 2);
-    }
-
-    public void testGroupingWithExpandCollapseCycleAtTheBeginning() {
-        buildCursor("1", "1", "2");
-        mAdapter.changeCursor(mCursor);
-        mAdapter.toggleGroup(0);
-        mAdapter.toggleGroup(0);
-
-        assertEquals(2, mAdapter.getCount());
-        assertPositionMetadata(0, ITEM_TYPE_GROUP_HEADER, false, 0);
-        assertPositionMetadata(1, ITEM_TYPE_STANDALONE, false, 2);
-    }
-
-    public void testGroupingWithCollapsedGroupInTheMiddle() {
-        buildCursor("1", "2", "2", "2", "3");
-        mAdapter.changeCursor(mCursor);
-
-        assertEquals(3, mAdapter.getCount());
-        assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
-        assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, false, 1);
-        assertPositionMetadata(2, ITEM_TYPE_STANDALONE, false, 4);
-    }
-
-    public void testGroupingWithExpandedGroupInTheMiddle() {
-        buildCursor("1", "2", "2", "2", "3");
-        mAdapter.changeCursor(mCursor);
-        mAdapter.toggleGroup(1);
-
-        assertEquals(6, mAdapter.getCount());
-        assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
-        assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, true, 1);
-        assertPositionMetadata(2, ITEM_TYPE_IN_GROUP, false, 1);
-        assertPositionMetadata(3, ITEM_TYPE_IN_GROUP, false, 2);
-        assertPositionMetadata(4, ITEM_TYPE_IN_GROUP, false, 3);
-        assertPositionMetadata(5, ITEM_TYPE_STANDALONE, false, 4);
-    }
-
-    public void testGroupingWithCollapsedGroupAtTheEnd() {
-        buildCursor("1", "2", "3", "3", "3");
-        mAdapter.changeCursor(mCursor);
-
-        assertEquals(3, mAdapter.getCount());
-        assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
-        assertPositionMetadata(1, ITEM_TYPE_STANDALONE, false, 1);
-        assertPositionMetadata(2, ITEM_TYPE_GROUP_HEADER, false, 2);
-    }
-
-    public void testGroupingWithExpandedGroupAtTheEnd() {
-        buildCursor("1", "2", "3", "3", "3");
-        mAdapter.changeCursor(mCursor);
-        mAdapter.toggleGroup(2);
-
-        assertEquals(6, mAdapter.getCount());
-        assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
-        assertPositionMetadata(1, ITEM_TYPE_STANDALONE, false, 1);
-        assertPositionMetadata(2, ITEM_TYPE_GROUP_HEADER, true, 2);
-        assertPositionMetadata(3, ITEM_TYPE_IN_GROUP, false, 2);
-        assertPositionMetadata(4, ITEM_TYPE_IN_GROUP, false, 3);
-        assertPositionMetadata(5, ITEM_TYPE_IN_GROUP, false, 4);
-    }
-
-    public void testGroupingWithMultipleCollapsedGroups() {
-        buildCursor("1", "2", "2", "3", "4", "4", "5", "5", "6");
-        mAdapter.changeCursor(mCursor);
-
-        assertEquals(6, mAdapter.getCount());
-        assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
-        assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, false, 1);
-        assertPositionMetadata(2, ITEM_TYPE_STANDALONE, false, 3);
-        assertPositionMetadata(3, ITEM_TYPE_GROUP_HEADER, false, 4);
-        assertPositionMetadata(4, ITEM_TYPE_GROUP_HEADER, false, 6);
-        assertPositionMetadata(5, ITEM_TYPE_STANDALONE, false, 8);
-    }
-
-    public void testGroupingWithMultipleExpandedGroups() {
-        buildCursor("1", "2", "2", "3", "4", "4", "5", "5", "6");
-        mAdapter.changeCursor(mCursor);
-        mAdapter.toggleGroup(1);
-
-        // Note that expanding the group of 2's shifted the group of 5's down from the
-        // 4th to the 6th position
-        mAdapter.toggleGroup(6);
-
-        assertEquals(10, mAdapter.getCount());
-        assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
-        assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, true, 1);
-        assertPositionMetadata(2, ITEM_TYPE_IN_GROUP, false, 1);
-        assertPositionMetadata(3, ITEM_TYPE_IN_GROUP, false, 2);
-        assertPositionMetadata(4, ITEM_TYPE_STANDALONE, false, 3);
-        assertPositionMetadata(5, ITEM_TYPE_GROUP_HEADER, false, 4);
-        assertPositionMetadata(6, ITEM_TYPE_GROUP_HEADER, true, 6);
-        assertPositionMetadata(7, ITEM_TYPE_IN_GROUP, false, 6);
-        assertPositionMetadata(8, ITEM_TYPE_IN_GROUP, false, 7);
-        assertPositionMetadata(9, ITEM_TYPE_STANDALONE, false, 8);
-    }
-
-    public void testPositionCache() {
-        buildCursor("1", "2", "2", "3", "4", "4", "5", "5", "6");
-        mAdapter.changeCursor(mCursor);
-
-        // First pass - building up cache
-        assertEquals(6, mAdapter.getCount());
-        assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
-        assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, false, 1);
-        assertPositionMetadata(2, ITEM_TYPE_STANDALONE, false, 3);
-        assertPositionMetadata(3, ITEM_TYPE_GROUP_HEADER, false, 4);
-        assertPositionMetadata(4, ITEM_TYPE_GROUP_HEADER, false, 6);
-        assertPositionMetadata(5, ITEM_TYPE_STANDALONE, false, 8);
-
-        // Second pass - using cache
-        assertEquals(6, mAdapter.getCount());
-        assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
-        assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, false, 1);
-        assertPositionMetadata(2, ITEM_TYPE_STANDALONE, false, 3);
-        assertPositionMetadata(3, ITEM_TYPE_GROUP_HEADER, false, 4);
-        assertPositionMetadata(4, ITEM_TYPE_GROUP_HEADER, false, 6);
-        assertPositionMetadata(5, ITEM_TYPE_STANDALONE, false, 8);
-
-        // Invalidate cache by expanding a group
-        mAdapter.toggleGroup(1);
-
-        // First pass - building up cache
-        assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
-        assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, true, 1);
-        assertPositionMetadata(2, ITEM_TYPE_IN_GROUP, false, 1);
-        assertPositionMetadata(3, ITEM_TYPE_IN_GROUP, false, 2);
-        assertPositionMetadata(4, ITEM_TYPE_STANDALONE, false, 3);
-        assertPositionMetadata(5, ITEM_TYPE_GROUP_HEADER, false, 4);
-        assertPositionMetadata(6, ITEM_TYPE_GROUP_HEADER, false, 6);
-        assertPositionMetadata(7, ITEM_TYPE_STANDALONE, false, 8);
-
-        // Second pass - using cache
-        assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
-        assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, true, 1);
-        assertPositionMetadata(2, ITEM_TYPE_IN_GROUP, false, 1);
-        assertPositionMetadata(3, ITEM_TYPE_IN_GROUP, false, 2);
-        assertPositionMetadata(4, ITEM_TYPE_STANDALONE, false, 3);
-        assertPositionMetadata(5, ITEM_TYPE_GROUP_HEADER, false, 4);
-        assertPositionMetadata(6, ITEM_TYPE_GROUP_HEADER, false, 6);
-        assertPositionMetadata(7, ITEM_TYPE_STANDALONE, false, 8);
-    }
-
-    public void testGroupDescriptorArrayGrowth() {
-        String[] numbers = new String[500];
-        for (int i = 0; i < numbers.length; i++) {
-
-            // Make groups of 2
-            numbers[i] = String.valueOf((i / 2) * 2);
-        }
-
-        buildCursor(numbers);
-        mAdapter.changeCursor(mCursor);
-
-        assertEquals(250, mAdapter.getCount());
-    }
-
-    private void assertPositionMetadata(int position, int itemType, boolean isExpanded,
-            int cursorPosition) {
-        GroupingListAdapter.PositionMetadata metadata = new GroupingListAdapter.PositionMetadata();
-        mAdapter.obtainPositionMetadata(metadata, position);
-        assertEquals(itemType, metadata.itemType);
-        if (metadata.itemType == ITEM_TYPE_GROUP_HEADER) {
-            assertEquals(isExpanded, metadata.isExpanded);
-        }
-        assertEquals(cursorPosition, metadata.cursorPosition);
-    }
-}
