diff --git a/src/com/android/contacts/AlphabetIndexer.java b/src/com/android/contacts/AlphabetIndexer.java
new file mode 100644
index 0000000..4e5fb0f
--- /dev/null
+++ b/src/com/android/contacts/AlphabetIndexer.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2008 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.database.Cursor;
+import android.database.DataSetObserver;
+import android.util.SparseIntArray;
+
+/**
+ * This class essentially helps in building an index of section boundaries of a
+ * sorted column of a cursor. For instance, if a cursor contains a data set 
+ * sorted by first name of a person or the title of a song, this class will 
+ * perform a binary search to identify the first row that begins with a 
+ * particular letter. The search is case-insensitive. The class caches the index 
+ * such that subsequent queries for the same letter will return right away.
+ */
+public class AlphabetIndexer extends DataSetObserver {
+
+    protected Cursor mDataCursor;
+    protected int mColumnIndex;
+    protected Object[] mAlphabetArray;
+    private SparseIntArray mAlphaMap;
+    private java.text.Collator mCollator;
+
+    /**
+     * Constructs the indexer.
+     * @param cursor the cursor containing the data set
+     * @param columnIndex the column number in the cursor that is sorted 
+     *        alphabetically
+     * @param sections the array of objects that represent the sections. The
+     * toString() method of each item is called and the first letter of the 
+     * String is used as the letter to search for.
+     */
+    public AlphabetIndexer(Cursor cursor, int columnIndex, Object[] sections) {
+        mDataCursor = cursor;
+        mColumnIndex = columnIndex;
+        mAlphabetArray = sections;
+        mAlphaMap = new SparseIntArray(26 /* Optimize for English */);
+        if (cursor != null) {
+            cursor.registerDataSetObserver(this);
+        }
+        // Get a Collator for the current locale for string comparisons.
+        mCollator = java.text.Collator.getInstance();
+        mCollator.setStrength(java.text.Collator.PRIMARY);
+    }
+
+    /**
+     * Sets a new cursor as the data set and resets the cache of indices.
+     * @param cursor the new cursor to use as the data set
+     */
+    public void setCursor(Cursor cursor) {
+        if (mDataCursor != null) {
+            mDataCursor.unregisterDataSetObserver(this);
+        }
+        mDataCursor = cursor;
+        if (cursor != null) {
+            mDataCursor.registerDataSetObserver(this);
+        }
+        mAlphaMap.clear();
+    }
+
+    /**
+     * Performs a binary search or cache lookup to find the first row that
+     * matches a given section's starting letter.
+     * @param sectionIndex the section to search for
+     * @return the row index of the first occurrence, or the nearest next letter.
+     * For instance, if searching for "T" and no "T" is found, then the first
+     * row starting with "U" or any higher letter is returned. If there is no
+     * data following "T" at all, then the list size is returned.
+     */
+    public int indexOf(int sectionIndex) {
+        final SparseIntArray alphaMap = mAlphaMap;
+        final Cursor cursor = mDataCursor;
+
+        if (cursor == null || mAlphabetArray == null) {
+            return 0;
+        }
+        
+        // Check bounds
+        if (sectionIndex <= 0) {
+            return 0;
+        }
+        if (sectionIndex >= mAlphabetArray.length) {
+            sectionIndex = mAlphabetArray.length - 1;
+        }
+
+        int savedCursorPos = cursor.getPosition();
+
+        int count = cursor.getCount();
+        int start = 0;
+        int end = count;
+        int pos;
+
+        String letter = mAlphabetArray[sectionIndex].toString();
+        letter = letter.toUpperCase();
+        int key = letter.charAt(0);
+        // Check map
+        if (Integer.MIN_VALUE != (pos = alphaMap.get(key, Integer.MIN_VALUE))) {
+            // Is it approximate? Using negative value to indicate that it's 
+            // an approximation and positive value when it is the accurate
+            // position.
+            if (pos < 0) {
+                pos = -pos;
+                end = pos;
+            } else {
+                // Not approximate, this is the confirmed start of section, return it
+                return pos;
+            }
+        }
+
+        // Do we have the position of the previous section?
+        if (sectionIndex > 0) {
+            int prevLetter =
+                    mAlphabetArray[sectionIndex - 1].toString().charAt(0);
+            int prevLetterPos = alphaMap.get(prevLetter, Integer.MIN_VALUE);
+            if (prevLetterPos != Integer.MIN_VALUE) {
+                start = Math.abs(prevLetterPos);
+            }
+        }
+
+        // Now that we have a possibly optimized start and end, let's binary search
+
+        pos = (end + start) / 2;
+
+        while (pos < end) {
+            // Get letter at pos
+            cursor.moveToPosition(pos);
+            String curName = cursor.getString(mColumnIndex);
+            if (curName == null) {
+                if (pos == 0) {
+                    break;
+                } else {
+                    pos--;
+                    continue;
+                }
+            }
+            int curLetter = Character.toUpperCase(curName.charAt(0));
+
+            if (curLetter != key) {
+                // Enter approximation in hash if a better solution doesn't exist
+                int curPos = alphaMap.get(curLetter, Integer.MIN_VALUE);
+                if (curPos == Integer.MIN_VALUE || Math.abs(curPos) > pos) {
+                    // Negative pos indicates that it is an approximation
+                    alphaMap.put(curLetter, -pos);
+                }
+                if (mCollator.compare(curName, letter) < 0) {
+                    start = pos + 1;
+                    if (start >= count) {
+                        pos = count;
+                        break;
+                    }
+                } else {
+                    end = pos;
+                }
+            } else {
+                // They're the same, but that doesn't mean it's the start
+                if (start == pos) {
+                    // This is it
+                    break;
+                } else {
+                    // Need to go further lower to find the starting row
+                    end = pos;
+                }
+            }
+            pos = (start + end) / 2;
+        }
+        alphaMap.put(key, pos);
+        cursor.moveToPosition(savedCursorPos);
+        return pos;
+    }
+
+    @Override
+    public void onChanged() {
+        super.onChanged();
+        mAlphaMap.clear();
+    }
+
+    @Override
+    public void onInvalidated() {
+        super.onInvalidated();
+        mAlphaMap.clear();
+    }
+}
diff --git a/src/com/android/contacts/AttachImage.java b/src/com/android/contacts/AttachImage.java
new file mode 100644
index 0000000..6346031
--- /dev/null
+++ b/src/com/android/contacts/AttachImage.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2006 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.app.Activity;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.Contacts;
+import android.provider.Contacts.People;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Provides an external interface for other applications to attach images
+ * to contacts. It will first present a contact picker and then run the 
+ * image that is handed to it through the cropper to make the image the proper
+ * size and give the user a chance to use the face detector.
+ */
+class AttachImage extends Activity {
+    private static final int REQUEST_PICK_CONTACT = 1;
+    private static final int REQUEST_CROP_PHOTO = 2;
+
+    private static final String CONTACT_URI_KEY = "contact_uri";
+
+    public AttachImage() {
+        
+    }
+
+    Uri mContactUri;
+    
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        if (icicle != null) {
+            mContactUri = icicle.getParcelable(CONTACT_URI_KEY);
+        } else {
+            Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
+            intent.setType(People.CONTENT_ITEM_TYPE);
+            startActivityForResult(intent, REQUEST_PICK_CONTACT);
+        }
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+
+        if (mContactUri != null) {
+            outState.putParcelable(CONTACT_URI_KEY, mContactUri);
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent result) {
+        if (resultCode != RESULT_OK) {
+            finish();
+            return;
+        }
+
+        if (requestCode == REQUEST_PICK_CONTACT) {
+            mContactUri = result.getData();
+            // A contact was picked. Launch the cropper to get face detection, the right size, etc.
+            // TODO: get these values from constants somewhere
+            Intent myIntent = getIntent();
+            Intent intent = new Intent("com.android.camera.action.CROP", myIntent.getData());
+            if (myIntent.getStringExtra("mimeType") != null) {
+                intent.setDataAndType(myIntent.getData(), myIntent.getStringExtra("mimeType"));
+            }
+            intent.putExtra("crop", "true");
+            intent.putExtra("aspectX", 1);
+            intent.putExtra("aspectY", 1);
+            intent.putExtra("outputX", 96);
+            intent.putExtra("outputY", 96);
+            intent.putExtra("return-data", true);
+            startActivityForResult(intent, REQUEST_CROP_PHOTO);
+        } else if (requestCode == REQUEST_CROP_PHOTO) {
+            final Bundle extras = result.getExtras();
+            if (extras != null) {
+                Bitmap photo = extras.getParcelable("data");
+                if (photo != null) {
+                    ByteArrayOutputStream stream = new ByteArrayOutputStream();
+                    photo.compress(Bitmap.CompressFormat.JPEG, 75, stream);
+                    Contacts.People.setPhotoData(getContentResolver(), mContactUri,
+                            stream.toByteArray());
+                }
+            }
+            finish();
+        }
+    }
+}
diff --git a/src/com/android/contacts/ButtonGridLayout.java b/src/com/android/contacts/ButtonGridLayout.java
new file mode 100644
index 0000000..e3431b1
--- /dev/null
+++ b/src/com/android/contacts/ButtonGridLayout.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2008 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.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.MeasureSpec;
+
+public class ButtonGridLayout extends ViewGroup {
+
+    private final int mColumns = 3;
+    
+    public ButtonGridLayout(Context context) {
+        super(context);
+    }
+
+    public ButtonGridLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public ButtonGridLayout(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+    
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        int y = mPaddingTop;
+        final int rows = getRows();
+        final View child0 = getChildAt(0);
+        final int yInc = (getHeight() - mPaddingTop - mPaddingBottom) / rows;
+        final int xInc = (getWidth() - mPaddingLeft - mPaddingRight) / mColumns;
+        final int childWidth = child0.getMeasuredWidth();
+        final int childHeight = child0.getMeasuredHeight();
+        final int xOffset = (xInc - childWidth) / 2;
+        final int yOffset = (yInc - childHeight) / 2;
+        
+        for (int row = 0; row < rows; row++) {
+            int x = mPaddingLeft;
+            for (int col = 0; col < mColumns; col++) {
+                int cell = row * mColumns + col;
+                if (cell >= getChildCount()) {
+                    break;
+                }
+                View child = getChildAt(cell);
+                child.layout(x + xOffset, y + yOffset, 
+                        x + xOffset + childWidth, 
+                        y + yOffset + childHeight);
+                x += xInc;
+            }
+            y += yInc;
+        }
+    }
+
+    private int getRows() {
+        return (getChildCount() + mColumns - 1) / mColumns; 
+    }
+    
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int width = mPaddingLeft + mPaddingRight;
+        int height = mPaddingTop + mPaddingBottom;
+        
+        // Measure the first child and get it's size
+        View child = getChildAt(0);
+        child.measure(MeasureSpec.UNSPECIFIED , MeasureSpec.UNSPECIFIED);
+        int childWidth = child.getMeasuredWidth();
+        int childHeight = child.getMeasuredHeight();
+        // Make sure the other children are measured as well, to initialize
+        for (int i = 1; i < getChildCount(); i++) {
+            getChildAt(0).measure(MeasureSpec.UNSPECIFIED , MeasureSpec.UNSPECIFIED);
+        }
+        // All cells are going to be the size of the first child
+        width += mColumns * childWidth;
+        height += getRows() * childHeight;
+        
+        width = resolveSize(width, widthMeasureSpec);
+        height = resolveSize(height, heightMeasureSpec);
+        setMeasuredDimension(width, height);
+    }
+
+}
diff --git a/src/com/android/contacts/ContactEntryAdapter.java b/src/com/android/contacts/ContactEntryAdapter.java
new file mode 100644
index 0000000..981b4bc
--- /dev/null
+++ b/src/com/android/contacts/ContactEntryAdapter.java
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 2007 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.net.Uri;
+import android.os.Parcel;
+import android.provider.Contacts.Organizations;
+import android.provider.Contacts.People;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+
+import java.util.ArrayList;
+
+public abstract class ContactEntryAdapter<E extends ContactEntryAdapter.Entry>
+        extends BaseAdapter {
+
+    public static final String[] CONTACT_PROJECTION = new String[] {
+        People._ID, // 0
+        People.NAME, // 1
+        People.NOTES, // 2
+        People.PRIMARY_PHONE_ID, // 3
+        People.PRESENCE_STATUS, // 4
+        People.STARRED, // 5
+        People.CUSTOM_RINGTONE, // 6
+        People.SEND_TO_VOICEMAIL, // 7
+    };
+    public static final int CONTACT_ID_COLUMN = 0;
+    public static final int CONTACT_NAME_COLUMN = 1;
+    public static final int CONTACT_NOTES_COLUMN = 2;
+    public static final int CONTACT_PREFERRED_PHONE_COLUMN = 3;
+    public static final int CONTACT_SERVER_STATUS_COLUMN = 4;
+    public static final int CONTACT_STARRED_COLUMN = 5;
+    public static final int CONTACT_CUSTOM_RINGTONE_COLUMN = 6;
+    public static final int CONTACT_SEND_TO_VOICEMAIL_COLUMN = 7;
+
+    public static final String[] PHONES_PROJECTION = new String[] {
+        People.Phones._ID, // 0
+        People.Phones.NUMBER, // 1
+        People.Phones.TYPE, // 2
+        People.Phones.LABEL, // 3
+        People.Phones.ISPRIMARY, // 4
+    };
+    public static final int PHONES_ID_COLUMN = 0;
+    public static final int PHONES_NUMBER_COLUMN = 1;
+    public static final int PHONES_TYPE_COLUMN = 2;
+    public static final int PHONES_LABEL_COLUMN = 3;
+    public static final int PHONES_ISPRIMARY_COLUMN = 4;
+
+    public static final String[] METHODS_PROJECTION = new String[] {
+        People.ContactMethods._ID, // 0
+        People.ContactMethods.KIND, // 1
+        People.ContactMethods.DATA, // 2
+        People.ContactMethods.TYPE, // 3
+        People.ContactMethods.LABEL, // 4
+        People.ContactMethods.ISPRIMARY, // 5
+        People.ContactMethods.AUX_DATA, // 6
+    };
+    public static final String[] METHODS_WITH_PRESENCE_PROJECTION = new String[] {
+        People.ContactMethods._ID, // 0
+        People.ContactMethods.KIND, // 1
+        People.ContactMethods.DATA, // 2
+        People.ContactMethods.TYPE, // 3
+        People.ContactMethods.LABEL, // 4
+        People.ContactMethods.ISPRIMARY, // 5
+        People.ContactMethods.AUX_DATA, // 6
+        People.PRESENCE_STATUS, // 7
+    };
+    public static final int METHODS_ID_COLUMN = 0;
+    public static final int METHODS_KIND_COLUMN = 1;
+    public static final int METHODS_DATA_COLUMN = 2;
+    public static final int METHODS_TYPE_COLUMN = 3;
+    public static final int METHODS_LABEL_COLUMN = 4;
+    public static final int METHODS_ISPRIMARY_COLUMN = 5;
+    public static final int METHODS_AUX_DATA_COLUMN = 6;
+    public static final int METHODS_STATUS_COLUMN = 7;
+
+    public static final String[] ORGANIZATIONS_PROJECTION = new String[] {
+        Organizations._ID, // 0
+        Organizations.TYPE, // 1
+        Organizations.LABEL, // 2
+        Organizations.COMPANY, // 3
+        Organizations.TITLE, // 4
+        Organizations.ISPRIMARY, // 5
+    };
+    public static final int ORGANIZATIONS_ID_COLUMN = 0;
+    public static final int ORGANIZATIONS_TYPE_COLUMN = 1;
+    public static final int ORGANIZATIONS_LABEL_COLUMN = 2;
+    public static final int ORGANIZATIONS_COMPANY_COLUMN = 3;
+    public static final int ORGANIZATIONS_TITLE_COLUMN = 4;
+    public static final int ORGANIZATIONS_ISPRIMARY_COLUMN = 5;
+    
+    protected ArrayList<ArrayList<E>> mSections;
+    protected LayoutInflater mInflater;
+    protected Context mContext;
+    protected boolean mSeparators;
+
+    /**
+     * Base class for adapter entries.
+     */
+    public static class Entry {
+        /** Details from the person table */
+        public static final int KIND_CONTACT = -1;
+        /** Synthesized phone entry that will send an SMS instead of call the number */
+        public static final int KIND_SMS = -2;
+        /** A section separator */
+        public static final int KIND_SEPARATOR = -3; 
+
+        public String label;
+        public String data;
+        public Uri uri;
+        public long id = 0;
+        public int maxLines = 1;
+        public int kind;
+        
+        /**
+         * Helper for making subclasses parcelable.
+         */
+        protected void writeToParcel(Parcel p) {
+            p.writeString(label);
+            p.writeString(data);
+            p.writeParcelable(uri, 0);
+            p.writeLong(id);
+            p.writeInt(maxLines);
+            p.writeInt(kind);
+        }
+        
+        /**
+         * Helper for making subclasses parcelable.
+         */
+        protected void readFromParcel(Parcel p) {
+            label = p.readString();
+            data = p.readString();
+            uri = p.readParcelable(null);
+            id = p.readLong();
+            maxLines = p.readInt();
+            kind = p.readInt();
+        }
+    }
+
+    ContactEntryAdapter(Context context, ArrayList<ArrayList<E>> sections, boolean separators) {
+        mContext = context;
+        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        mSections = sections;
+        mSeparators = separators;
+    }
+
+    /**
+     * Resets the section data.
+     * 
+     * @param sections the section data
+     */
+    public final void setSections(ArrayList<ArrayList<E>> sections, boolean separators) {
+        mSections = sections;
+        mSeparators = separators;
+        notifyDataSetChanged();
+    }
+
+    /**
+     * Resets the section data and returns the position of the given entry.
+     * 
+     * @param sections the section data
+     * @param entry the entry to return the position for
+     * @return the position of entry, or -1 if it isn't found
+     */
+    public final int setSections(ArrayList<ArrayList<E>> sections, E entry) {
+        mSections = sections;
+        notifyDataSetChanged();
+
+        int numSections = mSections.size();
+        int position = 0;
+        for (int i = 0; i < numSections; i++) {
+            ArrayList<E> section = mSections.get(i);
+            int sectionSize = section.size();
+            for (int j = 0; j < sectionSize; j++) {
+                E e = section.get(j);
+                if (e.equals(entry)) {
+                    position += j;
+                    return position;
+                }
+            }
+            position += sectionSize;
+        }
+        return -1;
+    }
+
+    /**
+     * @see android.widget.ListAdapter#getCount()
+     */
+    public final int getCount() {
+        return countEntries(mSections, mSeparators);
+    }
+
+    /**
+     * @see android.widget.ListAdapter#hasSeparators()
+     */
+    @Override
+    public final boolean areAllItemsEnabled() {
+        return mSeparators == false;
+    }
+
+    /**
+     * @see android.widget.ListAdapter#isSeparator(int)
+     */
+    @Override
+    public final boolean isEnabled(int position) {
+        if (!mSeparators) {
+            return true;
+        }
+
+        int numSections = mSections.size();
+        for (int i = 0; i < numSections; i++) {
+            ArrayList<E> section = mSections.get(i);
+            int sectionSize = section.size();
+            if (sectionSize == 1) {
+                // The section only contains a separator and nothing else, skip it
+                continue;
+            }
+            if (position == 0) {
+                // The first item in a section is always the separator
+                return false;
+            }
+            position -= sectionSize;
+        }
+        return true;
+    }
+
+    /**
+     * @see android.widget.ListAdapter#getItem(int)
+     */
+    public final Object getItem(int position) {
+        return getEntry(mSections, position, mSeparators);
+    }
+
+    /**
+     * Get the entry for the given position.
+     * 
+     * @param sections the list of sections
+     * @param position the position for the desired entry
+     * @return the ContactEntry for the given position
+     */
+    public final static <T extends Entry> T getEntry(ArrayList<ArrayList<T>> sections,
+            int position, boolean separators) {
+        int numSections = sections.size();
+        for (int i = 0; i < numSections; i++) {
+            ArrayList<T> section = sections.get(i);
+            int sectionSize = section.size();
+            if (separators && sectionSize == 1) {
+                // The section only contains a separator and nothing else, skip it
+                continue;
+            }
+            if (position < section.size()) {
+                return section.get(position);
+            }
+            position -= section.size();
+        }
+        return null;
+    }
+
+    /**
+     * Get the count of entries in all sections
+     * 
+     * @param sections the list of sections
+     * @return the count of entries in all sections
+     */
+    public static <T extends Entry> int countEntries(ArrayList<ArrayList<T>> sections,
+            boolean separators) {
+        int count = 0;
+        int numSections = sections.size();
+        for (int i = 0; i < numSections; i++) {
+            ArrayList<T> section = sections.get(i);
+            int sectionSize = section.size();
+            if (separators && sectionSize == 1) {
+                // The section only contains a separator and nothing else, skip it
+                continue;
+            }
+            count += sections.get(i).size();
+        }
+        return count;
+    }
+
+    /**
+     * @see android.widget.ListAdapter#getItemId(int)
+     */
+    public final long getItemId(int position) {
+        Entry entry = getEntry(mSections, position, mSeparators);
+        if (entry != null) {
+            return entry.id;
+        } else {
+            return -1;
+        }
+    }
+
+    /**
+     * @see android.widget.ListAdapter#getView(int, View, ViewGroup)
+     */
+    public View getView(int position, View convertView, ViewGroup parent) {
+        View v;
+        if (convertView == null) {
+            v = newView(position, parent);
+        } else {
+            v = convertView;
+        }
+        bindView(v, getEntry(mSections, position, mSeparators));
+        return v;
+    }
+
+    /**
+     * Create a new view for an entry.
+     * 
+     * @parent the parent ViewGroup
+     * @return the newly created view
+     */
+    protected abstract View newView(int position, ViewGroup parent);
+
+    /**
+     * Binds the data from an entry to a view.
+     * 
+     * @param view the view to display the entry in
+     * @param entry the data to bind
+     */
+    protected abstract void bindView(View view, E entry);
+}
diff --git a/src/com/android/contacts/ContactsGroupSyncSelector.java b/src/com/android/contacts/ContactsGroupSyncSelector.java
new file mode 100644
index 0000000..1043299
--- /dev/null
+++ b/src/com/android/contacts/ContactsGroupSyncSelector.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2008 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.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.DialogInterface;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.provider.Contacts;
+import android.provider.Contacts.Groups;
+import android.provider.Contacts.Settings;
+import android.text.TextUtils;
+import android.view.ContextThemeWrapper;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+import com.android.internal.app.AlertActivity;
+import com.android.internal.app.AlertController;
+
+public final class ContactsGroupSyncSelector extends AlertActivity implements 
+        ListView.OnItemClickListener, DialogInterface.OnClickListener {
+
+    private static final String[] PROJECTION = new String[] {
+            Groups._ID, // 0
+            Groups.NAME, // 1
+            Groups.SHOULD_SYNC, // 2
+            Groups.SYSTEM_ID, // 3
+    };
+    private static final int COLUMN_INDEX_ID = 0;
+    private static final int COLUMN_INDEX_NAME = 1;
+    private static final int COLUMN_INDEX_SHOULD_SYNC = 2;
+    private static final int COLUMN_INDEX_SYSTEM_ID = 3;
+
+    private ContentResolver mResolver;
+    private ListView mListView;
+    private GroupsAdapter mAdapter;
+
+    boolean[] mChecked;
+    boolean mSyncAllGroups;
+    long[] mGroupIds;
+    
+    private final class GroupsAdapter extends ArrayAdapter<CharSequence> {
+        public GroupsAdapter(CharSequence[] items) {
+            super(new ContextThemeWrapper(ContactsGroupSyncSelector.this,
+                    android.R.style.Theme_Light),
+                    android.R.layout.simple_list_item_checked,
+                    android.R.id.text1, items);
+        }
+
+        @Override
+        public boolean areAllItemsEnabled() {
+            return mSyncAllGroups; 
+        }
+
+        @Override
+        public boolean isEnabled(int pos) {
+            if (mSyncAllGroups && pos != 0) {
+                return false;
+            } else {
+                return true;
+            }
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            View v = super.getView(position, convertView, parent);
+            if (mSyncAllGroups && position != 0) {
+                v.setEnabled(false);
+            } else {
+                v.setEnabled(true);
+            }
+            return v;
+        }
+    }
+
+    /**
+     * Handles clicks on the list items
+     */
+    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+        boolean isChecked = mListView.isItemChecked(position);
+        mChecked[position] = isChecked;
+        if (position == 0) {
+            mSyncAllGroups = isChecked;
+            adjustChecks();
+        }
+    }
+
+    /**
+     * Handles clicks on the OK button
+     */
+    public void onClick(DialogInterface dialog, int which) {
+        if (mSyncAllGroups) {
+            // 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.
+            Settings.setSetting(mResolver, null, Settings.SYNC_EVERYTHING, "1");
+        } else {
+            final ContentResolver resolver = mResolver;
+            ContentValues values = new ContentValues();
+            int count = mChecked.length;
+            for (int i = 1; i < count; i++) {
+                values.clear();
+                values.put(Groups.SHOULD_SYNC, mChecked[i]);
+                resolver.update(ContentUris.withAppendedId(Groups.CONTENT_URI, mGroupIds[i]),
+                        values, null, null);
+            }
+            // 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.
+            Settings.setSetting(resolver, null, Settings.SYNC_EVERYTHING, "0");
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedState) {
+        super.onCreate(savedState);
+        mResolver = getContentResolver();
+
+        // Set the alert parameters
+        AlertController.AlertParams params = mAlertParams;
+        params.mTitle = getText(R.string.syncGroupChooserTitle);
+        params.mIcon = getResources().getDrawable(R.drawable.ic_tab_unselected_contacts);
+        params.mPositiveButtonText = getText(R.string.okButtonText);
+        params.mPositiveButtonListener = this;
+        params.mNegativeButtonText = getText(R.string.cancelButtonText);
+        buildItems(params);
+
+        // Takes the info in mAlertParams and creates the layout
+        setupAlert();
+
+        mListView = mAlert.getListView();
+        mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
+        mListView.setOnItemClickListener(this);
+        adjustChecks();
+    }
+
+    private void buildItems(AlertController.AlertParams params) {
+        Cursor cursor = mResolver.query(Groups.CONTENT_URI, PROJECTION, null, null, Groups.NAME);
+        if (cursor != null) {
+            try {
+                int count = cursor.getCount() + 1;
+                CharSequence[] items = new String[count];
+                boolean[] checked = new boolean[count];
+                long[] groupIds = new long[count];
+    
+                int i = 0;
+                items[i++] = getString(R.string.syncAllGroups);
+                items[i++] = getString(R.string.groupNameMyContacts);
+    
+                while (cursor.moveToNext()) {
+                    String name = cursor.getString(COLUMN_INDEX_NAME);
+                    String systemId = cursor.isNull(COLUMN_INDEX_SYSTEM_ID) ?
+                            null : cursor.getString(COLUMN_INDEX_SYSTEM_ID);
+                    if (systemId == null || !Groups.GROUP_MY_CONTACTS.equals(systemId)) {
+                        items[i] = name;
+                        checked[i] = cursor.getInt(COLUMN_INDEX_SHOULD_SYNC) != 0;
+                        groupIds[i] = cursor.getLong(COLUMN_INDEX_ID);
+                        i++;
+                    } else {
+                        checked[1] = cursor.getInt(COLUMN_INDEX_SHOULD_SYNC) != 0;
+                        groupIds[1] = cursor.getLong(COLUMN_INDEX_ID);
+                    }
+                }
+                mChecked = checked;
+                mSyncAllGroups = getShouldSyncEverything(mResolver);
+                checked[0] = mSyncAllGroups;
+                mGroupIds = groupIds;
+    
+                // Setup the adapter
+                mAdapter = new GroupsAdapter(items);
+                params.mAdapter = mAdapter;
+            } finally {
+                cursor.close();
+            }
+        }
+    }
+
+    private void adjustChecks() {
+        ListView list = mListView;
+        if (mSyncAllGroups) {
+            int count = list.getCount();
+            for (int i = 0; i < count; i++) {
+                list.setItemChecked(i, true);
+            }
+        } else {
+            boolean[] checked = mChecked;
+            int count = list.getCount();
+            for (int i = 0; i < count; i++) {
+                list.setItemChecked(i, checked[i]);
+            }
+        }
+    }
+
+    private static boolean getShouldSyncEverything(ContentResolver cr) {
+        // 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(cr, null, Contacts.Settings.SYNC_EVERYTHING);
+        if (value == null) {
+            // If nothing is set yet we default to syncing everything
+            return true;
+        }
+        return !TextUtils.isEmpty(value) && !"0".equals(value);
+    }
+}
diff --git a/src/com/android/contacts/ContactsListActivity.java b/src/com/android/contacts/ContactsListActivity.java
new file mode 100644
index 0000000..0ffa786
--- /dev/null
+++ b/src/com/android/contacts/ContactsListActivity.java
@@ -0,0 +1,1407 @@
+/*
+ * Copyright (C) 2007 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.app.Activity;
+import android.app.AlertDialog;
+import android.app.ListActivity;
+import android.app.SearchManager;
+import android.content.AsyncQueryHandler;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.database.Cursor;
+import android.database.CharArrayBuffer;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.preference.PreferenceManager;
+import android.provider.Contacts;
+import android.provider.Contacts.ContactMethods;
+import android.provider.Contacts.Groups;
+import android.provider.Contacts.Intents;
+import android.provider.Contacts.People;
+import android.provider.Contacts.Phones;
+import android.provider.Contacts.Presence;
+import android.provider.Contacts.Intents.UI;
+import android.telephony.PhoneNumberUtils;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import android.widget.ResourceCursorAdapter;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+
+/**
+ * Displays a list of contacts. Usually is embedded into the ContactsActivity.
+ */
+public final class ContactsListActivity extends ListActivity
+        implements View.OnCreateContextMenuListener, DialogInterface.OnClickListener {
+    private static final String TAG = "ContactsListActivity";
+
+    private static final String LIST_STATE_KEY = "liststate";
+    private static final String FOCUS_KEY = "focused";
+
+    static final int MENU_ITEM_VIEW_CONTACT = 1;
+    static final int MENU_ITEM_CALL = 2;
+    static final int MENU_ITEM_EDIT_BEFORE_CALL = 3;
+    static final int MENU_ITEM_SEND_SMS = 4;
+    static final int MENU_ITEM_SEND_IM = 5;
+    static final int MENU_ITEM_EDIT = 6;
+    static final int MENU_ITEM_DELETE = 7;
+    static final int MENU_ITEM_TOGGLE_STAR = 8;
+
+    public static final int MENU_DIALER = 9;
+    public static final int MENU_NEW_CONTACT = 10;
+    public static final int MENU_DISPLAY_GROUP = 11;
+
+    private static final int SUBACTIVITY_NEW_CONTACT = 1;
+    
+    /** Mask for picker mode */
+    static final int MODE_MASK_PICKER = 0x80000000;
+    /** Mask for no presence mode */
+    static final int MODE_MASK_NO_PRESENCE = 0x40000000;
+    /** Mask for enabling list filtering */
+    static final int MODE_MASK_NO_FILTER = 0x20000000;
+    /** Mask for having a "create new contact" header in the list */
+    static final int MODE_MASK_CREATE_NEW = 0x10000000;
+
+    /** 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;
+    /** Show all starred contacts */
+    static final int MODE_STARRED = 20;
+    /** Show frequently contacted contacts */
+    static final int MODE_FREQUENT = 30;
+    /** Show starred and the frequent */
+    static final int MODE_STREQUENT = 35;
+    /** Show all contacts and pick them when clicking */
+    static final int MODE_PICK_CONTACT = 40 | MODE_MASK_PICKER;
+    /** Show all contacts as well as the option to create a new one */
+    static final int MODE_PICK_OR_CREATE_CONTACT = 42 | MODE_MASK_PICKER | MODE_MASK_CREATE_NEW;
+    /** Show all contacts and pick them when clicking, and allow creating a new contact */
+    static final int MODE_INSERT_OR_EDIT_CONTACT = 45 | MODE_MASK_PICKER | MODE_MASK_CREATE_NEW;
+    /** Show all phone numbers and pick them when clicking */
+    static final int MODE_PICK_PHONE = 50 | MODE_MASK_PICKER | MODE_MASK_NO_PRESENCE;
+    /** Show all postal addresses and pick them when clicking */
+    static final int MODE_PICK_POSTAL =
+            55 | MODE_MASK_PICKER | MODE_MASK_NO_PRESENCE | MODE_MASK_NO_FILTER;
+    /** Run a search query */
+    static final int MODE_QUERY = 60 | MODE_MASK_NO_FILTER;
+
+    static final int DEFAULT_MODE = MODE_ALL_CONTACTS;
+
+    static final String NAME_COLUMN = People.DISPLAY_NAME;
+    
+    static final String[] CONTACTS_PROJECTION = new String[] {
+        People._ID, // 0
+        NAME_COLUMN, // 1
+        People.NUMBER, // 2
+        People.TYPE, // 3
+        People.LABEL, // 4
+        People.STARRED, // 5
+        People.PRIMARY_PHONE_ID, // 6
+        People.PRIMARY_EMAIL_ID, // 7
+        People.PRESENCE_STATUS, // 8
+    };
+
+    static final String[] STREQUENT_PROJECTION = new String[] {
+        People._ID, // 0
+        NAME_COLUMN, // 1
+        People.NUMBER, // 2
+        People.TYPE, // 3
+        People.LABEL, // 4
+        People.STARRED, // 5
+        People.PRIMARY_PHONE_ID, // 6
+        People.PRIMARY_EMAIL_ID, // 7
+        People.PRESENCE_STATUS, // 8
+        People.TIMES_CONTACTED, // 9 (not displayed, but required for the order by to work)
+    };
+
+    static final String[] PHONES_PROJECTION = new String[] {
+        Phones._ID, // 0
+        NAME_COLUMN, // 1
+        Phones.NUMBER, // 2
+        Phones.TYPE, // 3
+        Phones.LABEL, // 4
+        Phones.STARRED, // 5
+    };
+
+    static final String[] CONTACT_METHODS_PROJECTION = new String[] {
+        ContactMethods._ID, // 0
+        NAME_COLUMN, // 1
+        ContactMethods.DATA, // 2
+        ContactMethods.TYPE, // 3
+        ContactMethods.LABEL, // 4
+        ContactMethods.STARRED, // 5
+    };
+
+    static final int ID_COLUMN_INDEX = 0;
+    static final int NAME_COLUMN_INDEX = 1;
+    static final int NUMBER_COLUMN_INDEX = 2;
+    static final int DATA_COLUMN_INDEX = 2;
+    static final int TYPE_COLUMN_INDEX = 3;
+    static final int LABEL_COLUMN_INDEX = 4;
+    static final int STARRED_COLUMN_INDEX = 5;
+    static final int PRIMARY_PHONE_ID_COLUMN_INDEX = 6;
+    static final int PRIMARY_EMAIL_ID_COLUMN_INDEX = 7;
+    static final int SERVER_STATUS_COLUMN_INDEX = 8;
+
+    
+    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;
+    
+    static final String SORT_ORDER = NAME_COLUMN + " COLLATE LOCALIZED ASC";
+    
+    private static final int QUERY_TOKEN = 42;
+
+    private static final String[] GROUPS_PROJECTION = new String[] {
+        Groups.SYSTEM_ID, // 0
+        Groups.NAME, // 1
+    };
+    private static final int GROUPS_COLUMN_INDEX_SYSTEM_ID = 0;
+    private static final int GROUPS_COLUMN_INDEX_NAME = 1;
+    
+    static final String GROUP_WITH_PHONES = "android_smartgroup_phone";
+
+    ContactItemListAdapter mAdapter;
+
+    private 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;
+    
+    private QueryHandler mQueryHandler;
+    private String mQuery;
+    private Uri mGroupFilterUri;
+    private Uri mGroupUri;
+    private boolean mJustCreated;
+
+    /**
+     * Used to keep track of the scroll state of the list.
+     */
+    private Parcelable mListState = null;
+    private boolean mListHasFocus;
+
+    private boolean mCreateShortcut;
+    private boolean mDefaultMode = false;
+
+    private class DeleteClickListener implements DialogInterface.OnClickListener {
+        private Uri mUri;
+
+        public DeleteClickListener(Uri uri) {
+            mUri = uri;
+        }
+
+        public void onClick(DialogInterface dialog, int which) {
+            getContentResolver().delete(mUri, null, null);
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        // Make sure the preferences are setup
+        PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
+
+        // Resolve the intent
+        final Intent intent = getIntent();
+
+        // Allow the title to be set to a custom String using an extra on the intent
+        String title = intent.getStringExtra(Contacts.Intents.UI.TITLE_EXTRA_KEY);
+        if (title != null) {
+            setTitle(title);
+        }
+
+        final String action = intent.getAction();
+        mMode = MODE_UNKNOWN;
+        
+        setContentView(R.layout.contacts_list_content);
+
+        if (UI.LIST_DEFAULT.equals(action)) {
+            mDefaultMode = true;
+            // 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)) {
+            mMode = MODE_GROUP;
+            String groupName = intent.getStringExtra(UI.GROUP_NAME_EXTRA_KEY);
+            if (TextUtils.isEmpty(groupName)) {
+                finish();
+                return;
+            }
+            buildUserGroupUris(groupName);
+        } else if (UI.LIST_ALL_CONTACTS_ACTION.equals(action)) {
+            mMode = MODE_ALL_CONTACTS;
+        } else if (UI.LIST_STARRED_ACTION.equals(action)) {
+            mMode = MODE_STARRED;
+        } else if (UI.LIST_FREQUENT_ACTION.equals(action)) {
+            mMode = MODE_FREQUENT;
+        } 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;
+        } else if (Intent.ACTION_PICK.equals(action)) {
+            // XXX These should be showing the data from the URI given in
+            // the Intent.
+            final String type = intent.resolveType(this);
+            if (People.CONTENT_TYPE.equals(type)) {
+                mMode = MODE_PICK_CONTACT;
+            } else if (Phones.CONTENT_TYPE.equals(type)) {
+                mMode = MODE_PICK_PHONE;
+            } else if (ContactMethods.CONTENT_POSTAL_TYPE.equals(type)) {
+                mMode = MODE_PICK_POSTAL;
+            }
+        } else if (Intent.ACTION_CREATE_SHORTCUT.equals(action)) {
+            mMode = MODE_PICK_OR_CREATE_CONTACT;
+            mCreateShortcut = true;
+        } else if (Intent.ACTION_GET_CONTENT.equals(action)) {
+            final String type = intent.resolveType(this);
+            if (People.CONTENT_ITEM_TYPE.equals(type)) {
+                mMode = MODE_PICK_OR_CREATE_CONTACT;
+            } else if (Phones.CONTENT_ITEM_TYPE.equals(type)) {
+                mMode = MODE_PICK_PHONE;
+            } else if (ContactMethods.CONTENT_POSTAL_ITEM_TYPE.equals(type)) {
+                mMode = MODE_PICK_POSTAL;
+            }
+        } else if (Intent.ACTION_INSERT_OR_EDIT.equals(action)) {
+            mMode = MODE_INSERT_OR_EDIT_CONTACT;
+        } else if (Intent.ACTION_SEARCH.equals(action)) {
+            // See if the suggestion was clicked with a search action key (call button)
+            if ("call".equals(intent.getStringExtra(SearchManager.ACTION_MSG))) {
+                String query = intent.getStringExtra(SearchManager.QUERY);
+                if (!TextUtils.isEmpty(query)) {
+                    Intent newIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
+                            Uri.fromParts("tel", query, null));
+                    startActivity(newIntent);
+                }
+                finish();
+                return;
+            }
+            // Otherwise handle the more normal search case
+            mMode = MODE_QUERY;
+
+        // Since this is the filter activity it receives all intents
+        // dispatched from the SearchManager for security reasons
+        // so we need to re-dispatch from here to the intended target.
+        } else if (Intents.SEARCH_SUGGESTION_CLICKED.equals(action)) {
+            // See if the suggestion was clicked with a search action key (call button)
+            Intent newIntent;
+            if ("call".equals(intent.getStringExtra(SearchManager.ACTION_MSG))) {
+                newIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED, intent.getData());
+            } else {
+                newIntent = new Intent(Intent.ACTION_VIEW, intent.getData());
+            }
+            startActivity(newIntent);
+            finish();
+            return;
+        } else if (Intents.SEARCH_SUGGESTION_DIAL_NUMBER_CLICKED.equals(action)) {
+            Intent newIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED, intent.getData());
+            startActivity(newIntent);
+            finish();
+            return;
+        } else if (Intents.SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED.equals(action)) {
+            String number = intent.getData().getSchemeSpecificPart();
+            Intent newIntent = new Intent(Intent.ACTION_INSERT, People.CONTENT_URI);
+            newIntent.putExtra(Intents.Insert.PHONE, number);
+            startActivity(newIntent);
+            finish();
+            return;
+        }
+
+        if (mMode == MODE_UNKNOWN) {
+            mMode = DEFAULT_MODE;
+        }
+
+/*
+        if (!mDefaultMode) {
+            findViewById(R.id.contact_group).banner.setVisibility(View.GONE);
+        }
+*/
+
+        // Setup the UI
+        final ListView list = getListView();
+        list.setFocusable(true);
+        list.setOnCreateContextMenuListener(this);
+        if ((mMode & MODE_MASK_NO_FILTER) != MODE_MASK_NO_FILTER) {
+            list.setTextFilterEnabled(true);
+        }
+
+        if ((mMode & MODE_MASK_CREATE_NEW) != 0) {
+            // Add the header for creating a new contact
+            final LayoutInflater inflater = getLayoutInflater();
+            View header = inflater.inflate(android.R.layout.simple_list_item_1, list, false);
+            TextView text = (TextView) header.findViewById(android.R.id.text1);
+            text.setText(R.string.pickerNewContactHeader);
+            list.addHeaderView(header);
+        }
+
+        // Set the proper empty string
+        setEmptyText();
+        
+        mAdapter = new ContactItemListAdapter(this, R.layout.contacts_list_item, null);
+        setListAdapter(mAdapter);
+
+        // We manually save/restore the listview state
+        list.setSaveEnabled(false);
+
+        mQueryHandler = new QueryHandler(this);
+        mJustCreated = true;
+    }
+
+    private void setEmptyText() {
+        TextView empty = (TextView) findViewById(android.R.id.empty);
+        switch (mMode) {
+            case MODE_GROUP:
+                if (Groups.GROUP_MY_CONTACTS.equals(mDisplayInfo)) {
+                    empty.setText(getString(R.string.groupEmpty,
+                            getText(R.string.groupNameMyContacts)));
+                } 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;
+        }
+    }
+
+    /**
+     * 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(ContactsPreferenceActivity.PREF_DISPLAY_TYPE,
+                ContactsPreferenceActivity.DISPLAY_TYPE_UNKNOWN);
+        switch (mDisplayType) {
+            case ContactsPreferenceActivity.DISPLAY_TYPE_ALL_WITH_PHONES: {
+                mMode = MODE_WITH_PHONES;
+                mDisplayInfo = null;
+                break;
+            }
+
+            case ContactsPreferenceActivity.DISPLAY_TYPE_SYSTEM_GROUP: {
+                String systemId = prefs.getString(
+                        ContactsPreferenceActivity.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 = ContactsPreferenceActivity.DISPLAY_TYPE_ALL;
+                }
+                break;
+            }
+
+            case ContactsPreferenceActivity.DISPLAY_TYPE_USER_GROUP: {
+                String displayGroup = prefs.getString(
+                        ContactsPreferenceActivity.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 = ContactsPreferenceActivity.DISPLAY_TYPE_ALL;
+                }
+                break;
+            }
+
+            case ContactsPreferenceActivity.DISPLAY_TYPE_ALL: {
+                mMode = MODE_ALL_CONTACTS;
+                mDisplayInfo = null;
+                break;
+            }
+
+            default: {
+                // We don't know what to display, default to My Contacts
+                mMode = MODE_GROUP;
+                mDisplayType = ContactsPreferenceActivity.DISPLAY_TYPE_SYSTEM_GROUP;
+                buildSystemGroupUris(Groups.GROUP_MY_CONTACTS);
+                mDisplayInfo = Groups.GROUP_MY_CONTACTS;
+                break;
+            }
+        }
+
+        // Update the empty text view with the proper string, as the group may have changed
+        setEmptyText();
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        boolean runQuery = true;
+        Activity parent = getParent();
+        
+        // Do this before setting the filter. The filter thread relies
+        // on some state that is initialized in setDefaultMode
+        if (mDefaultMode) {
+            // 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();
+        }
+        
+        // See if we were invoked with a filter
+        if (parent != null && parent instanceof DialtactsActivity) {
+            String filterText = ((DialtactsActivity) parent).getAndClearFilterText();
+            if (filterText != null && filterText.length() > 0) {
+                getListView().setFilterText(filterText);
+                // Don't start a new query since it will conflict with the filter
+                runQuery = false;
+            } else if (mJustCreated) {
+                getListView().clearTextFilter();
+            }
+        }
+
+        if (runQuery) {
+            // Calling requery here may cause an ANR, so always do the async query
+            startQuery();
+        }
+        mJustCreated = false;
+    }
+    
+    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);
+        // Save list state in the bundle so we can restore it after the QueryHandler has run
+        icicle.putParcelable(LIST_STATE_KEY, mList.onSaveInstanceState());
+        icicle.putBoolean(FOCUS_KEY, mList.hasFocus());
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Bundle icicle) {
+        super.onRestoreInstanceState(icicle);
+        // Retrieve list state. This will be applied after the QueryHandler has run
+        mListState = icicle.getParcelable(LIST_STATE_KEY);
+        mListHasFocus = icicle.getBoolean(FOCUS_KEY);
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+
+        // We don't want the list to display the empty state, since when we resume it will still
+        // be there and show up while the new query is happening. After the async query finished
+        // in response to onResume() setLoading(false) will be called.
+        mAdapter.setLoading(true);
+        mAdapter.changeCursor(null);
+
+        if (mMode == MODE_QUERY) {
+            // Make sure the search box is closed
+            SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
+            searchManager.stopSearch();
+        }
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        // If Contacts was invoked by another Activity simply as a way of
+        // picking a contact, don't show the options menu
+        if ((mMode & MODE_MASK_PICKER) == MODE_MASK_PICKER) {
+            return false;
+        }
+
+        menu.add(0, MENU_NEW_CONTACT, 0, R.string.menu_newContact)
+                .setIcon(android.R.drawable.ic_menu_add)
+                .setIntent(new Intent(Intents.Insert.ACTION, People.CONTENT_URI))
+                .setAlphabeticShortcut('n');
+        if (isChild()) {
+            menu.add(0, 0, 0, R.string.menu_preferences)
+                    .setIcon(android.R.drawable.ic_menu_preferences)
+                    .setIntent(new Intent(this, ContactsPreferenceActivity.class));
+        }
+        if (mDefaultMode) {
+            menu.add(0, MENU_DISPLAY_GROUP, 0, R.string.menu_displayGroup)
+                    .setIcon(R.drawable.ic_menu_allfriends);
+        }
+        return super.onCreateOptionsMenu(menu);
+    }
+
+    /*
+     * Implements the handler for display group selection.
+     */
+    public void onClick(DialogInterface dialogInterface, int which) {
+        if (which == DialogInterface.BUTTON1) {
+            // The OK button was pressed
+            if (mDisplayGroupOriginalSelection != mDisplayGroupCurrentSelection) {
+                // Set the group to display
+                if (mDisplayGroupCurrentSelection == DISPLAY_GROUP_INDEX_ALL_CONTACTS) {
+                    // Display all
+                    mDisplayType = ContactsPreferenceActivity.DISPLAY_TYPE_ALL;
+                    mDisplayInfo = null;
+                } else if (mDisplayGroupCurrentSelection
+                        == DISPLAY_GROUP_INDEX_ALL_CONTACTS_WITH_PHONES) {
+                    // Display all with phone numbers
+                    mDisplayType = ContactsPreferenceActivity.DISPLAY_TYPE_ALL_WITH_PHONES;
+                    mDisplayInfo = null;
+                } else if (mDisplayGroupsIncludesMyContacts &&
+                        mDisplayGroupCurrentSelection == DISPLAY_GROUP_INDEX_MY_CONTACTS) {
+                    mDisplayType = ContactsPreferenceActivity.DISPLAY_TYPE_SYSTEM_GROUP;
+                    mDisplayInfo = Groups.GROUP_MY_CONTACTS;
+                } else {
+                    mDisplayType = ContactsPreferenceActivity.DISPLAY_TYPE_USER_GROUP;
+                    mDisplayInfo = mDisplayGroups[mDisplayGroupCurrentSelection].toString();
+                }
+
+                // Save the changes to the preferences
+                SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+                prefs.edit()
+                        .putInt(ContactsPreferenceActivity.PREF_DISPLAY_TYPE, mDisplayType)
+                        .putString(ContactsPreferenceActivity.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) {
+        if (item.getItemId() == 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;
+        }
+        return false;
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode,
+            Intent data) {
+        switch (requestCode) {
+            case SUBACTIVITY_NEW_CONTACT:
+                if (resultCode == RESULT_OK) {
+                    // Contact was created, pass it back
+                    returnPickerResult(data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME),
+                            data.getData());
+                }
+        }
+    }
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
+        // If Contacts was invoked by another Activity simply as a way of
+        // picking a contact, don't show the context menu
+        if ((mMode & MODE_MASK_PICKER) == MODE_MASK_PICKER) {
+            return;
+        }
+
+        AdapterView.AdapterContextMenuInfo info;
+        try {
+             info = (AdapterView.AdapterContextMenuInfo) menuInfo;
+        } catch (ClassCastException e) {
+            Log.e(TAG, "bad menuInfo", e);
+            return;
+        }
+
+        Cursor cursor = (Cursor) getListAdapter().getItem(info.position);
+        if (cursor == null) {
+            // For some reason the requested item isn't available, do nothing
+            return;
+        }
+        long id = info.id;
+        Uri personUri = ContentUris.withAppendedId(People.CONTENT_URI, id);
+
+        // Setup the menu header
+        menu.setHeaderTitle(cursor.getString(NAME_COLUMN_INDEX));
+
+        // View contact details
+        menu.add(0, MENU_ITEM_VIEW_CONTACT, 0, R.string.menu_viewContact)
+                .setIntent(new Intent(Intent.ACTION_VIEW, personUri));
+
+        // Calling contact
+        long phoneId = cursor.getLong(PRIMARY_PHONE_ID_COLUMN_INDEX);
+        if (phoneId > 0) {
+            // Get the display label for the number
+            CharSequence label = cursor.getString(LABEL_COLUMN_INDEX);
+            int type = cursor.getInt(TYPE_COLUMN_INDEX);
+            label = Phones.getDisplayLabel(this, type, label);
+            Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
+                    ContentUris.withAppendedId(Phones.CONTENT_URI, phoneId));
+            menu.add(0, MENU_ITEM_CALL, 0, String.format(getString(R.string.menu_callNumber), label))
+                    .setIntent(intent);
+
+            // Send SMS item
+            menu.add(0, MENU_ITEM_SEND_SMS, 0, R.string.menu_sendSMS)
+                    .setIntent(new Intent(Intent.ACTION_SENDTO,
+                            Uri.fromParts("sms", cursor.getString(NUMBER_COLUMN_INDEX), null)));
+        }
+
+        // Star toggling
+        int starState = cursor.getInt(STARRED_COLUMN_INDEX);
+        if (starState == 0) {
+            menu.add(0, MENU_ITEM_TOGGLE_STAR, 0, R.string.menu_addStar);
+        } else {
+            menu.add(0, MENU_ITEM_TOGGLE_STAR, 0, R.string.menu_removeStar);
+        }
+
+        // Contact editing
+        menu.add(0, MENU_ITEM_EDIT, 0, R.string.menu_editContact)
+                .setIntent(new Intent(Intent.ACTION_EDIT, personUri));
+        menu.add(0, MENU_ITEM_DELETE, 0, R.string.menu_deleteContact);
+    }
+
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        AdapterView.AdapterContextMenuInfo info;
+        try {
+             info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
+        } catch (ClassCastException e) {
+            Log.e(TAG, "bad menuInfo", e);
+            return false;
+        }
+
+        Cursor cursor = (Cursor) getListAdapter().getItem(info.position);
+
+        switch (item.getItemId()) {
+            case MENU_ITEM_TOGGLE_STAR: {
+                // Toggle the star
+                ContentValues values = new ContentValues(1);
+                values.put(People.STARRED, cursor.getInt(STARRED_COLUMN_INDEX) == 0 ? 1 : 0);
+                Uri personUri = ContentUris.withAppendedId(People.CONTENT_URI,
+                        cursor.getInt(ID_COLUMN_INDEX));
+                getContentResolver().update(personUri, values, null, null);
+                return true;
+            }
+
+            case MENU_ITEM_DELETE: {
+                // Get confirmation
+                Uri uri = ContentUris.withAppendedId(People.CONTENT_URI,
+                        cursor.getLong(ID_COLUMN_INDEX));
+                //TODO make this dialog persist across screen rotations
+                new AlertDialog.Builder(ContactsListActivity.this)
+                    .setTitle(R.string.deleteConfirmation_title)
+                    .setIcon(android.R.drawable.ic_dialog_alert)
+                    .setMessage(R.string.deleteConfirmation)
+                    .setNegativeButton(R.string.noButton, null)
+                    .setPositiveButton(R.string.yesButton, new DeleteClickListener(uri))
+                    .setCancelable(false)
+                    .show();
+                return true;
+            }
+        }
+
+        return super.onContextItemSelected(item);
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_CALL: {
+                if (callSelection()) {
+                    return true;
+                }
+                break;
+            }
+
+            case KeyEvent.KEYCODE_DEL: {
+                Object o = getListView().getSelectedItem();
+                if (o != null) {
+                    Cursor cursor = (Cursor) o;
+                    Uri uri = ContentUris.withAppendedId(People.CONTENT_URI,
+                            cursor.getLong(ID_COLUMN_INDEX));
+                    //TODO make this dialog persist across screen rotations
+                    new AlertDialog.Builder(ContactsListActivity.this)
+                        .setTitle(R.string.deleteConfirmation_title)
+                        .setIcon(android.R.drawable.ic_dialog_alert)
+                        .setMessage(R.string.deleteConfirmation)
+                        .setNegativeButton(R.string.noButton, null)
+                        .setPositiveButton(R.string.yesButton, new DeleteClickListener(uri))
+                        .setCancelable(false)
+                        .show();
+                    return true;
+                }
+                break;
+            }
+        }
+
+        return super.onKeyDown(keyCode, event);
+    }
+
+    @Override
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+        if (mMode == MODE_INSERT_OR_EDIT_CONTACT) {
+            Intent intent;
+            if (position == 0) {
+                // Insert
+                intent = new Intent(Intent.ACTION_INSERT, People.CONTENT_URI);
+            } else {
+                // Edit
+                intent = new Intent(Intent.ACTION_EDIT,
+                        ContentUris.withAppendedId(People.CONTENT_URI, id));
+            }
+            intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+            final Bundle extras = getIntent().getExtras();
+            if (extras != null) {
+                intent.putExtras(extras);
+            }
+            startActivity(intent);
+            finish();
+        } else if (id != -1) {
+            if ((mMode & MODE_MASK_PICKER) == 0) {
+                Intent intent = new Intent(Intent.ACTION_VIEW,
+                        ContentUris.withAppendedId(People.CONTENT_URI, id));
+                startActivity(intent);
+            } else if (mMode == MODE_PICK_CONTACT 
+                    || mMode == MODE_PICK_OR_CREATE_CONTACT) {
+                Uri uri = ContentUris.withAppendedId(People.CONTENT_URI, id);
+                if (mCreateShortcut) {
+                    // Subtract one if we have Create Contact at the top
+                    Cursor c = (Cursor) mAdapter.getItem(position
+                            - (mMode == MODE_PICK_OR_CREATE_CONTACT? 1:0));
+                    returnPickerResult(c.getString(NAME_COLUMN_INDEX), uri);
+                } else {
+                    returnPickerResult(null, uri);
+                }
+            } else if (mMode == MODE_PICK_PHONE) {
+                setResult(RESULT_OK, new Intent().setData(
+                        ContentUris.withAppendedId(Phones.CONTENT_URI, id)));
+                finish();
+            } else if (mMode == MODE_PICK_POSTAL) {
+                setResult(RESULT_OK, new Intent().setData(
+                        ContentUris.withAppendedId(ContactMethods.CONTENT_URI, id)));
+                finish();
+            }
+        } else if ((mMode & MODE_MASK_CREATE_NEW) == MODE_MASK_CREATE_NEW
+                && position == 0) {
+            Intent newContact = new Intent(Intents.Insert.ACTION, People.CONTENT_URI);
+            startActivityForResult(newContact, SUBACTIVITY_NEW_CONTACT);
+        } else {
+            signalError();
+        }
+    }
+
+    private void returnPickerResult(String name, Uri uri) {
+        final Intent intent = new Intent();
+    
+        if (mCreateShortcut) {
+            Intent shortcutIntent = new Intent(Intent.ACTION_VIEW, uri);
+            shortcutIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+            intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
+            intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);
+            final Bitmap icon = People.loadContactPhoto(this, uri, 0, null);
+            if (icon != null) {
+                intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, icon);
+            } else {
+                intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
+                        Intent.ShortcutIconResource.fromContext(this,
+                                R.drawable.ic_launcher_contacts));
+            }
+            setResult(RESULT_OK, intent);
+        } else {
+            setResult(RESULT_OK, intent.setData(uri));
+        }
+        finish();
+    }
+
+    String[] getProjection() {
+        switch (mMode) {
+            case MODE_GROUP:
+            case MODE_ALL_CONTACTS:
+            case MODE_WITH_PHONES:
+            case MODE_PICK_CONTACT:
+            case MODE_PICK_OR_CREATE_CONTACT:
+            case MODE_QUERY:
+            case MODE_STARRED:
+            case MODE_FREQUENT:
+            case MODE_INSERT_OR_EDIT_CONTACT:
+                return CONTACTS_PROJECTION;
+
+            case MODE_STREQUENT:
+                return STREQUENT_PROJECTION;
+
+            case MODE_PICK_PHONE:
+                return PHONES_PROJECTION;
+
+            case MODE_PICK_POSTAL:
+                return CONTACT_METHODS_PROJECTION;
+        }
+        return null;
+    }
+
+    private Uri getPeopleFilterUri(String filter) {
+        if (!TextUtils.isEmpty(filter)) {
+            return Uri.withAppendedPath(People.CONTENT_FILTER_URI, Uri.encode(filter));
+        } else {
+            return People.CONTENT_URI;
+        }
+    }
+
+    void startQuery() {
+        mAdapter.setLoading(true);
+        
+        // Cancel any pending queries
+        mQueryHandler.cancelOperation(QUERY_TOKEN);
+
+        // Kick off the new query
+        switch (mMode) {
+            case MODE_GROUP:
+                mQueryHandler.startQuery(QUERY_TOKEN, null,
+                        mGroupUri, CONTACTS_PROJECTION, null, null, SORT_ORDER);
+                break;
+
+            case MODE_ALL_CONTACTS:
+            case MODE_PICK_CONTACT:
+            case MODE_PICK_OR_CREATE_CONTACT:
+            case MODE_INSERT_OR_EDIT_CONTACT:
+                mQueryHandler.startQuery(QUERY_TOKEN, null, People.CONTENT_URI, CONTACTS_PROJECTION,
+                        null, null, SORT_ORDER);
+                break;
+
+            case MODE_WITH_PHONES:
+                mQueryHandler.startQuery(QUERY_TOKEN, null, People.CONTENT_URI, CONTACTS_PROJECTION,
+                        People.PRIMARY_PHONE_ID + " IS NOT NULL", null, People.DEFAULT_SORT_ORDER);
+                break;
+
+            case MODE_QUERY: {
+                mQuery = getIntent().getStringExtra(SearchManager.QUERY);
+                mQueryHandler.startQuery(QUERY_TOKEN, null, getPeopleFilterUri(mQuery),
+                        CONTACTS_PROJECTION, null, null, SORT_ORDER);
+                break;
+            }
+
+            case MODE_STARRED:
+                mQueryHandler.startQuery(QUERY_TOKEN, null, People.CONTENT_URI, CONTACTS_PROJECTION,
+                        People.STARRED + "=1", null, SORT_ORDER);
+                break;
+
+            case MODE_FREQUENT:
+                mQueryHandler.startQuery(QUERY_TOKEN, null, People.CONTENT_URI, CONTACTS_PROJECTION,
+                        People.TIMES_CONTACTED + " > 0", null,
+                        People.TIMES_CONTACTED + " DESC, " + NAME_COLUMN + " ASC");
+                break;
+
+            case MODE_STREQUENT:
+                mQueryHandler.startQuery(QUERY_TOKEN, null,
+                        Uri.withAppendedPath(People.CONTENT_URI, "strequent"), STREQUENT_PROJECTION,
+                        null, null, null);
+                break;
+
+            case MODE_PICK_PHONE:
+                mQueryHandler.startQuery(QUERY_TOKEN, null, Phones.CONTENT_URI, PHONES_PROJECTION,
+                        null, null, SORT_ORDER);
+                break;
+
+            case MODE_PICK_POSTAL:
+                mQueryHandler.startQuery(QUERY_TOKEN, null, ContactMethods.CONTENT_URI,
+                        CONTACT_METHODS_PROJECTION,
+                        ContactMethods.KIND + "=" + Contacts.KIND_POSTAL, null, SORT_ORDER);
+                break;
+        }
+    }
+
+    /**
+     * Called from a background thread to do the filter and return the resulting cursor.
+     * 
+     * @param filter the text that was entered to filter on
+     * @return a cursor with the results of the filter
+     */
+    Cursor doFilter(String filter) {
+        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,
+                        People.DEFAULT_SORT_ORDER);
+            }
+
+            case MODE_ALL_CONTACTS:
+            case MODE_PICK_CONTACT:
+            case MODE_PICK_OR_CREATE_CONTACT:
+            case MODE_INSERT_OR_EDIT_CONTACT: {
+                return resolver.query(getPeopleFilterUri(filter), CONTACTS_PROJECTION, null, null,
+                        SORT_ORDER);
+            }
+
+            case MODE_WITH_PHONES: {
+                return resolver.query(getPeopleFilterUri(filter), CONTACTS_PROJECTION,
+                        People.PRIMARY_PHONE_ID + " IS NOT NULL", null, SORT_ORDER);
+            }
+
+            case MODE_STARRED: {
+                return resolver.query(getPeopleFilterUri(filter), CONTACTS_PROJECTION,
+                        People.STARRED + "=1", null, SORT_ORDER);
+            }
+
+            case MODE_FREQUENT: {
+                return resolver.query(getPeopleFilterUri(filter), CONTACTS_PROJECTION,
+                        People.TIMES_CONTACTED + " > 0", null,
+                        People.TIMES_CONTACTED + " DESC, " + NAME_COLUMN + " ASC");
+            }
+
+            case MODE_STREQUENT: {
+                Uri uri;
+                if (!TextUtils.isEmpty(filter)) {
+                    uri = Uri.withAppendedPath(People.CONTENT_URI, "strequent/filter/"
+                            + Uri.encode(filter));
+                } else {
+                    uri = Uri.withAppendedPath(People.CONTENT_URI, "strequent");
+                }
+                return resolver.query(uri, STREQUENT_PROJECTION, null, null, null);
+            }
+
+            case MODE_PICK_PHONE: {
+                Uri uri;
+                if (!TextUtils.isEmpty(filter)) {
+                    uri = Uri.withAppendedPath(Phones.CONTENT_URI, "filter_name/"
+                            + Uri.encode(filter));
+                } else {
+                    uri = Phones.CONTENT_URI;
+                }
+                return resolver.query(uri, PHONES_PROJECTION, null, null, SORT_ORDER);
+            }
+        }
+        throw new UnsupportedOperationException("filtering not allowed in mode " + mMode);
+    }
+
+    /**
+     * Calls the currently selected list item.
+     * @return true if the call was initiated, false otherwise
+     */
+    boolean callSelection() {
+        ListView list = getListView();
+        if (list.hasFocus()) {
+            Cursor cursor = (Cursor) list.getSelectedItem();
+            if (cursor != null) {
+                long phoneId = cursor.getLong(PRIMARY_PHONE_ID_COLUMN_INDEX);
+                if (phoneId == 0) {
+                    // There is no phone number.
+                    signalError();
+                    return false;
+                }
+                Uri uri = ContentUris.withAppendedId(Phones.CONTENT_URI, phoneId);
+                Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED, uri);
+                startActivity(intent);
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Signal an error to the user.
+     */
+    void signalError() {
+        //TODO play an error beep or something...
+    }
+
+    Cursor getItemForView(View view) {
+        ListView listView = getListView();
+        int index = listView.getPositionForView(view);
+        if (index < 0) {
+            return null;
+        }
+        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 i = 3;
+            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
+                    groups.add(name);
+                    if (name.equals(mDisplayInfo)) {
+                        currentIndex = i;
+                    }
+                    i++;
+                } else {
+                    // The My Contacts group
+                    groups.add(DISPLAY_GROUP_INDEX_MY_CONTACTS,
+                            getString(R.string.groupNameMyContacts));
+                    if (mDisplayType == ContactsPreferenceActivity.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 final class QueryHandler extends AsyncQueryHandler {
+        public QueryHandler(Context context) {
+            super(context.getContentResolver());
+        }
+
+        @Override
+        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
+            if (!isFinishing()) {
+                mAdapter.setLoading(false);
+                mAdapter.changeCursor(cursor);
+    
+                // Now that the cursor is populated again, it's possible to restore the list state
+                if (mListState != null) {
+                    mList.onRestoreInstanceState(mListState);
+                    if (mListHasFocus) {
+                        mList.requestFocus();
+                    }
+                    mListHasFocus = false;
+                    mListState = null;
+                }
+            } else {
+                cursor.close();
+            }
+        }
+    }
+
+    final static class ContactListItemCache {
+        public TextView nameView;
+        public CharArrayBuffer nameBuffer = new CharArrayBuffer(128);
+        public TextView labelView;
+        public CharArrayBuffer labelBuffer = new CharArrayBuffer(128);
+        public TextView numberView;
+        public CharArrayBuffer numberBuffer = new CharArrayBuffer(128);
+    }
+
+    private final class ContactItemListAdapter extends ResourceCursorAdapter 
+            implements FastScrollView.SectionIndexer {
+        
+        private String [] mAlphabet;
+        private AlphabetIndexer mIndexer;
+        private boolean mLoading = true;
+        private CharSequence mUnknownNameText;
+        private CharSequence[] mLocalizedLabels;
+
+        public ContactItemListAdapter(Context context, int resource, Cursor cursor) {
+            super(context, resource, cursor);
+            getAlphabet(context);
+            if (cursor != null) {
+                mIndexer = new AlphabetIndexer(cursor, NAME_COLUMN_INDEX, mAlphabet);
+            }
+            mUnknownNameText = context.getText(android.R.string.unknownName);
+            switch (mMode) {
+                case MODE_PICK_POSTAL:
+                    mLocalizedLabels = EditContactActivity.getLabelsForKind(mContext,
+                            Contacts.KIND_POSTAL);
+                    break;
+                default:
+                    mLocalizedLabels = EditContactActivity.getLabelsForKind(mContext,
+                            Contacts.KIND_PHONE);
+                    break;
+            }
+        }
+
+        public void setLoading(boolean loading) {
+            mLoading = loading;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            if (mLoading) {
+                // We don't want the empty state to show when loading.
+                return false;
+            } else {
+                return super.isEmpty();
+            }
+        }
+        
+        private void getAlphabet(Context context) {
+            String alphabetString = context.getResources().getString(R.string.alphabet);
+            mAlphabet = new String[alphabetString.length()];
+            for (int i = 0; i < mAlphabet.length; i++) {
+                mAlphabet[i] = String.valueOf(alphabetString.charAt(i));
+            }
+        }
+
+        @Override
+        public View newView(Context context, Cursor cursor, ViewGroup parent) {
+            final View view = super.newView(context, cursor, parent);
+
+            final ContactListItemCache cache = new ContactListItemCache();
+            cache.nameView = (TextView) view.findViewById(R.id.name);
+            cache.labelView = (TextView) view.findViewById(R.id.label);
+            cache.labelView.setCompoundDrawablePadding(3);
+            cache.numberView = (TextView) view.findViewById(R.id.number);
+            view.setTag(cache);
+
+            return view;
+        }
+
+        @Override
+        public void bindView(View view, Context context, Cursor cursor) {
+            final ContactListItemCache cache = (ContactListItemCache) view.getTag();
+            
+            // Set the name           
+            cursor.copyStringToBuffer(NAME_COLUMN_INDEX, cache.nameBuffer);
+            int size = cache.nameBuffer.sizeCopied;
+            if (size != 0) {
+                cache.nameView.setText(cache.nameBuffer.data, 0, size);
+            } else {
+                cache.nameView.setText(mUnknownNameText);
+            }
+            
+            // Set the phone number
+            TextView numberView = cache.numberView;
+            cursor.copyStringToBuffer(NUMBER_COLUMN_INDEX, cache.numberBuffer);
+            size = cache.numberBuffer.sizeCopied;
+            if (size != 0) {
+                numberView.setText(cache.numberBuffer.data, 0, size);
+                numberView.setVisibility(View.VISIBLE);
+            } else {
+                numberView.setVisibility(View.GONE);
+            }
+
+            // Set the label
+            TextView labelView = cache.labelView;
+            if (!cursor.isNull(TYPE_COLUMN_INDEX)) {
+                int type = cursor.getInt(TYPE_COLUMN_INDEX);
+
+                if (type != People.Phones.TYPE_CUSTOM) {
+                    try {
+                        labelView.setText(mLocalizedLabels[type - 1]);
+                    } catch (ArrayIndexOutOfBoundsException e) {
+                        labelView.setText(mLocalizedLabels[People.Phones.TYPE_HOME - 1]);
+                    }
+                } else {
+                    cursor.copyStringToBuffer(LABEL_COLUMN_INDEX, cache.labelBuffer);
+                    // Don't check size, if it's zero just don't show anything
+                    labelView.setText(cache.labelBuffer.data, 0, cache.labelBuffer.sizeCopied);
+                }
+            } else {
+                // Set the text to a length of 0
+                labelView.setText(cache.labelBuffer.data, 0, 0);
+            }
+            // Set the proper icon in the label view
+            if (mMode != MODE_STREQUENT) {
+                if ((mMode & MODE_MASK_NO_PRESENCE) == 0) {
+                    int serverStatus;
+                    if (!cursor.isNull(SERVER_STATUS_COLUMN_INDEX)) {
+                        serverStatus = cursor.getInt(SERVER_STATUS_COLUMN_INDEX);
+                        labelView.setCompoundDrawablesWithIntrinsicBounds(
+                                getResources().getDrawable(
+                                        Presence.getPresenceIconResourceId(serverStatus)),
+                                null, null, null);
+                    } else {
+                        labelView.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
+                    }
+                } else {
+                    labelView.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
+                }
+            } else {
+                if (cursor.getInt(STARRED_COLUMN_INDEX) != 0) {
+                    labelView.setCompoundDrawablesWithIntrinsicBounds(
+                            getResources().getDrawable(R.drawable.star_on),
+                            null, null, null);
+                } else {
+                    labelView.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
+                }
+            }
+        }
+
+        @Override
+        public void changeCursor(Cursor cursor) {
+            super.changeCursor(cursor);
+            updateIndexer(cursor);
+        }
+        
+        private void updateIndexer(Cursor cursor) {
+            if (mIndexer == null) {
+                mIndexer = new AlphabetIndexer(cursor, NAME_COLUMN_INDEX, mAlphabet);
+            } else {
+                mIndexer.setCursor(cursor);
+            }
+        }
+        
+        /**
+         * Run the query on a helper thread. Beware that this code does not run
+         * on the main UI thread!
+         */
+        @Override
+        public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
+            return doFilter(constraint.toString());
+        }
+        
+        public Object [] getSections() {
+            if (mMode == MODE_STREQUENT) {
+                return new String[] { " " };
+            } else {
+                return mAlphabet;
+            }
+        }
+        
+        public int getPositionForSection(int sectionIndex) {
+            if (mMode == MODE_STREQUENT) {
+                return 0;
+            }
+
+            if (mIndexer == null) {
+                Cursor cursor = mAdapter.getCursor();
+                if (cursor == null) {
+                    // No cursor, the section doesn't exist so just return 0
+                    return 0;
+                }
+                mIndexer = new AlphabetIndexer(cursor, NAME_COLUMN_INDEX, mAlphabet);
+            }
+
+            return mIndexer.indexOf(sectionIndex);
+        }
+        
+        public int getSectionForPosition(int position) {
+            return 0;
+        }        
+    }
+}
+
+
diff --git a/src/com/android/contacts/ContactsPreferenceActivity.java b/src/com/android/contacts/ContactsPreferenceActivity.java
new file mode 100644
index 0000000..b625fe5
--- /dev/null
+++ b/src/com/android/contacts/ContactsPreferenceActivity.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 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.os.Bundle;
+import android.preference.PreferenceActivity;
+
+public final class ContactsPreferenceActivity extends PreferenceActivity {
+    /**
+     * 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";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        // Load the preferences from an XML resource
+        addPreferencesFromResource(R.xml.preferences);
+    }
+
+}
diff --git a/src/com/android/contacts/DialtactsActivity.java b/src/com/android/contacts/DialtactsActivity.java
new file mode 100644
index 0000000..00df1c1
--- /dev/null
+++ b/src/com/android/contacts/DialtactsActivity.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2008 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.app.TabActivity;
+import android.content.Intent;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.provider.Contacts;
+import android.provider.CallLog.Calls;
+import android.provider.Contacts.Intents.UI;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.Window;
+import android.widget.TabHost;
+import com.android.internal.telephony.ITelephony;
+
+/**
+ * The dialer activity that has one tab with the virtual 12key dialer,
+ * and another tab with recent calls in it. This is the container and the tabs
+ * are embedded using intents.
+ */
+public class DialtactsActivity extends TabActivity {
+    private static final String TAG = "Dailtacts";
+
+    public static final String EXTRA_IGNORE_STATE = "ignore-state";
+
+    private static final int FAVORITES_STARRED = 1;
+    private static final int FAVORITES_FREQUENT = 2;
+    private static final int FAVORITES_STREQUENT = 3;
+    
+    /** Defines what is displayed in the right tab */
+    private static final int FAVORITES_TAB_MODE = FAVORITES_STREQUENT;
+
+    protected TabHost mTabHost;
+    
+    private String mFilterText;
+    
+    private Uri mDialUri;
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        final Intent intent = getIntent();
+        fixIntent(intent);
+        
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+        setContentView(R.layout.dialer_activity);
+
+        mTabHost = getTabHost();
+
+        // Setup the tabs
+        setupDialerTab();
+        setupCallLogTab();
+        setupContactsTab();
+        setupFavoritesTab();
+
+        setCurrentTab(intent);
+        
+        if (intent.getAction().equals(Contacts.Intents.UI.FILTER_CONTACTS_ACTION) 
+                && icicle == null) {
+            setupFilterText(intent);
+        }
+    }
+
+    private void fixIntent(Intent intent) {
+        // This should be cleaned up: the call key used to send an Intent
+        // that just said to go to the recent calls list.  It now sends this
+        // abstract action, but this class hasn't been rewritten to deal with it.
+        if (Intent.ACTION_CALL_BUTTON.equals(intent.getAction())) {
+            intent.setDataAndType(Calls.CONTENT_URI, Calls.CONTENT_TYPE);
+            intent.putExtra("call_key", true);
+            setIntent(intent);
+        }
+    }
+    
+    private void setupCallLogTab() {
+        mTabHost.addTab(mTabHost.newTabSpec("call_log")
+                .setIndicator(getString(R.string.recentCallsIconLabel),
+                        getResources().getDrawable(R.drawable.ic_tab_recent))
+                .setContent(new Intent("com.android.phone.action.RECENT_CALLS")));
+    }
+
+    private void setupDialerTab() {
+        mTabHost.addTab(mTabHost.newTabSpec("dialer")
+                .setIndicator(getString(R.string.dialerIconLabel),
+                        getResources().getDrawable(R.drawable.ic_tab_dialer))
+                .setContent(new Intent("com.android.phone.action.TOUCH_DIALER")));
+    }
+
+    private void setupContactsTab() {
+        mTabHost.addTab(mTabHost.newTabSpec("contacts")
+                .setIndicator(getText(R.string.contactsIconLabel),
+                        getResources().getDrawable(R.drawable.ic_tab_contacts))
+                .setContent(new Intent(UI.LIST_DEFAULT)));
+    }
+
+    private void setupFavoritesTab() {
+        Intent tab2Intent;
+        switch (FAVORITES_TAB_MODE) {
+            case FAVORITES_STARRED:
+                tab2Intent = new Intent(UI.LIST_STARRED_ACTION);
+                break;
+
+            case FAVORITES_FREQUENT:
+                tab2Intent = new Intent(UI.LIST_FREQUENT_ACTION);
+                break;
+
+            case FAVORITES_STREQUENT:
+                tab2Intent = new Intent(UI.LIST_STREQUENT_ACTION);
+                break;
+
+            default:
+                throw new UnsupportedOperationException("unknown default mode");
+        }
+        Drawable tab2Icon = getResources().getDrawable(R.drawable.ic_tab_starred);
+
+        mTabHost.addTab(mTabHost.newTabSpec("favorites")
+                .setIndicator(getString(R.string.contactsFavoritesLabel), tab2Icon)
+                .setContent(tab2Intent));
+    }
+
+    /**
+     * Returns true if the intent is due to hitting the green send key while in a call.
+     * 
+     * @param intent the intent that launched this activity
+     * @param recentCallsRequest true if the intent is requesting to view recent calls
+     * @return true if the intent is due to hitting the green send key while in a call 
+     */
+    private boolean isSendKeyWhileInCall(final Intent intent, final boolean recentCallsRequest) {
+        // If there is a call in progress go to the call screen
+        if (recentCallsRequest) {
+            final boolean callKey = intent.getBooleanExtra("call_key", false);
+
+            try {
+                ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
+                if (callKey && phone != null && phone.showCallScreen()) {
+                    return true;
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to handle send while in call", e);
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Sets the current tab based on the intent's request type
+     * 
+     * @param recentCallsRequest true is the recent calls tab is desired, false oltherwise
+     */
+    private void setCurrentTab(Intent intent) {
+        final boolean recentCallsRequest = Calls.CONTENT_TYPE.equals(intent.getType());
+        if (isSendKeyWhileInCall(intent, recentCallsRequest)) {
+            finish();
+            return;
+        }
+        intent.putExtra(EXTRA_IGNORE_STATE, true);
+        if (intent.getComponent().getClassName().equals(getClass().getName())) {
+            if (recentCallsRequest) {
+                mTabHost.setCurrentTab(1);
+            } else {
+                mTabHost.setCurrentTab(0);
+            }
+        } else {
+            mTabHost.setCurrentTab(2);
+        }
+        intent.putExtra(EXTRA_IGNORE_STATE, false);
+    }
+
+    @Override
+    public void onNewIntent(Intent newIntent) {
+        setIntent(newIntent);
+        fixIntent(newIntent);
+        setCurrentTab(newIntent);
+        final String action = newIntent.getAction();
+        if (action.equals(Contacts.Intents.UI.FILTER_CONTACTS_ACTION)) {
+            setupFilterText(newIntent);
+        } else if (isDialIntent(newIntent)) {
+            setupDialUri(newIntent);
+        }
+    }
+    
+    private boolean isDialIntent(Intent intent) {
+        final String action = intent.getAction();
+        if (Intent.ACTION_DIAL.equals(action)) {
+            return true;
+        }
+        if (Intent.ACTION_VIEW.equals(action)) {
+            final Uri data = intent.getData();
+            if (data != null && "tel".equals(data.getScheme())) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    /**
+     * Retrieves the filter text stored in {@link #setupFilterText(Intent)}.
+     * This text originally came from a FILTER_CONTACTS_ACTION intent received
+     * by this activity. The stored text will then be cleared after after this
+     * method returns.
+     * 
+     * @return The stored filter text
+     */
+    public String getAndClearFilterText() {
+        String filterText = mFilterText;
+        mFilterText = null;
+        return filterText;
+    }
+
+    /**
+     * Stores the filter text associated with a FILTER_CONTACTS_ACTION intent.
+     * This is so child activities can check if they are supposed to display a filter.
+     * 
+     * @param intent The intent received in {@link #onNewIntent(Intent)}
+     */
+    private void setupFilterText(Intent intent) {
+        // If the intent was relaunched from history, don't apply the filter text.
+        if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
+            return;
+        }
+        String filter = intent.getStringExtra(Contacts.Intents.UI.FILTER_TEXT_EXTRA_KEY);
+        if (filter != null && filter.length() > 0) {
+            mFilterText = filter;
+        }
+    }
+
+    /**
+     * Retrieves the uri stored in {@link #setupDialUri(Intent)}. This uri
+     * originally came from a dial intent received by this activity. The stored
+     * uri will then be cleared after after this method returns.
+     * 
+     * @return The stored uri
+     */
+    public Uri getAndClearDialUri() {
+        Uri dialUri = mDialUri;
+        mDialUri = null;
+        return dialUri;
+    }
+
+    /**
+     * Stores the uri associated with a dial intent. This is so child activities can
+     * check if they are supposed to display new dial info.
+     * 
+     * @param intent The intent received in {@link #onNewIntent(Intent)}
+     */
+    private void setupDialUri(Intent intent) {
+        // If the intent was relaunched from history, don't reapply the intent.
+        if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
+            return;
+        }
+        mDialUri = intent.getData();
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        // Handle BACK
+        if (keyCode == KeyEvent.KEYCODE_BACK && isTaskRoot()) {
+            // Instead of stopping, simply push this to the back of the stack.
+            // This is only done when running at the top of the stack;
+            // otherwise, we have been launched by someone else so need to
+            // allow the user to go back to the caller.
+            moveTaskToBack(false);
+            return true;
+        }
+        
+        return super.onKeyDown(keyCode, event);
+    }
+}
diff --git a/src/com/android/contacts/EditContactActivity.java b/src/com/android/contacts/EditContactActivity.java
new file mode 100644
index 0000000..c301473
--- /dev/null
+++ b/src/com/android/contacts/EditContactActivity.java
@@ -0,0 +1,1976 @@
+/*
+ * Copyright (C) 2007 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.google.android.collect.Lists;
+
+import static com.android.contacts.ContactEntryAdapter.CONTACT_CUSTOM_RINGTONE_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.CONTACT_NAME_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.CONTACT_NOTES_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.CONTACT_PROJECTION;
+import static com.android.contacts.ContactEntryAdapter.CONTACT_SEND_TO_VOICEMAIL_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.METHODS_AUX_DATA_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.METHODS_DATA_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.METHODS_ID_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.METHODS_ISPRIMARY_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.METHODS_KIND_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.METHODS_LABEL_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.METHODS_PROJECTION;
+import static com.android.contacts.ContactEntryAdapter.METHODS_TYPE_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.ORGANIZATIONS_COMPANY_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.ORGANIZATIONS_ID_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.ORGANIZATIONS_ISPRIMARY_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.ORGANIZATIONS_LABEL_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.ORGANIZATIONS_PROJECTION;
+import static com.android.contacts.ContactEntryAdapter.ORGANIZATIONS_TITLE_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.ORGANIZATIONS_TYPE_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.PHONES_ID_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.PHONES_ISPRIMARY_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.PHONES_LABEL_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.PHONES_NUMBER_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.PHONES_PROJECTION;
+import static com.android.contacts.ContactEntryAdapter.PHONES_TYPE_COLUMN;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.ActivityNotFoundException;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.media.Ringtone;
+import android.media.RingtoneManager;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.preference.PreferenceManager;
+import android.provider.Contacts;
+import android.provider.Contacts.ContactMethods;
+import android.provider.Contacts.Intents.Insert;
+import android.provider.Contacts.Organizations;
+import android.provider.Contacts.People;
+import android.provider.Contacts.Phones;
+import android.telephony.PhoneNumberFormattingTextWatcher;
+import android.text.TextUtils;
+import android.text.method.DialerKeyListener;
+import android.text.method.TextKeyListener;
+import android.text.method.TextKeyListener.Capitalize;
+import android.util.Log;
+import android.view.ContextThemeWrapper;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.ExpandableListView;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.SimpleExpandableListAdapter;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Activity for editing or inserting a contact. Note that if the contact data changes in the
+ * background while this activity is running, the updates will be overwritten.
+ */
+public final class EditContactActivity extends Activity implements View.OnClickListener,
+        ExpandableListView.OnChildClickListener {
+    private static final String TAG = "EditContactActivity";
+
+    private static final int STATE_UNKNOWN = 0;
+    /** Editing an existing contact */
+    private static final int STATE_EDIT = 1;
+    /** The full insert mode */
+    private static final int STATE_INSERT = 2;
+
+    /** The launch code when picking a photo and the raw data is returned */
+    private static final int PHOTO_PICKED_WITH_DATA = 3021;
+
+    /** The launch code when picking a ringtone */
+    private static final int RINGTONE_PICKED = 3023;
+    
+    // Label picker position info
+    final static int LABEL_PICKER_PHONES_POSITION = 0;
+    final static int LABEL_PICKER_EMAIL_POSITION = 1;
+    final static int LABEL_PICKER_IM_POSITION = 2;
+    final static int LABEL_PICKER_POSTAL_POSITION = 3;
+    final static int LABEL_PICKER_OTHER_POSITION = 4;
+
+    // These correspond to the string array in resources for picker "other" items
+    final static int OTHER_ORGANIZATION = 0;
+    final static int OTHER_NOTE = 1;
+    
+    // Dialog IDs
+    final static int LABEL_PICKER_ALL_TYPES_DIALOG = 1;
+    final static int DELETE_CONFIRMATION_DIALOG = 2;
+
+    // Menu item IDs
+    public static final int MENU_ITEM_SAVE = 1;
+    public static final int MENU_ITEM_DONT_SAVE = 2;
+    public static final int MENU_ITEM_DELETE = 3;
+    public static final int MENU_ITEM_ADD = 5;
+    public static final int MENU_ITEM_PHOTO = 6;
+    
+    // Key listener types
+    final static int INPUT_TEXT = 1;
+    final static int INPUT_TEXT_WORDS = 2;
+    final static int INPUT_TEXT_SENTENCES = 3;
+    final static int INPUT_DIALER = 4;
+
+    /** Used to represent an invalid type for a contact entry */
+    private static final int INVALID_TYPE = -1;
+    
+    /** The default type for a phone that is added via an intent */
+    private static final int DEFAULT_PHONE_TYPE = Phones.TYPE_MOBILE;
+
+    /** The default type for an email that is added via an intent */
+    private static final int DEFAULT_EMAIL_TYPE = ContactMethods.TYPE_HOME;
+
+    /** The default type for a postal address that is added via an intent */
+    private static final int DEFAULT_POSTAL_TYPE = ContactMethods.TYPE_HOME;
+
+    private int mState; // saved across instances
+    private boolean mInsert; // saved across instances
+    private Uri mUri; // saved across instances
+    /** In insert mode this is the photo */
+    private Bitmap mPhoto; // saved across instances
+    private boolean mPhotoChanged = false; // saved across instances
+    
+    private EditText mNameView;
+    private ImageView mPhotoImageView;
+    private Button mPhotoButton;
+    private CheckBox mSendToVoicemailCheckBox;
+    private LinearLayout mLayout;
+    private LayoutInflater mInflater;
+    private MenuItem mPhotoMenuItem;
+    private boolean mPhotoPresent = false;
+
+    // These are accessed by inner classes. They're package scoped to make access more efficient.
+    /* package */ ContentResolver mResolver;
+    /* package */ ArrayList<EditEntry> mPhoneEntries = new ArrayList<EditEntry>();
+    /* package */ ArrayList<EditEntry> mEmailEntries = new ArrayList<EditEntry>();
+    /* package */ ArrayList<EditEntry> mImEntries = new ArrayList<EditEntry>();
+    /* package */ ArrayList<EditEntry> mPostalEntries = new ArrayList<EditEntry>();
+    /* package */ ArrayList<EditEntry> mOtherEntries = new ArrayList<EditEntry>();
+    /* package */ ArrayList<ArrayList<EditEntry>> mSections = new ArrayList<ArrayList<EditEntry>>();
+
+    /* package */ static final int MSG_DELETE = 1;
+    /* package */ static final int MSG_CHANGE_LABEL = 2;
+    /* package */ static final int MSG_ADD_PHONE = 3;
+    /* package */ static final int MSG_ADD_EMAIL = 4;
+    /* package */ static final int MSG_ADD_POSTAL = 5;
+
+    public void onClick(View v) {
+        switch (v.getId()) {
+            case R.id.photoButton:
+            case R.id.photoImage: {
+                doPickPhotoAction();
+                break;
+            }
+
+            case R.id.addMore:
+                doAddAction();
+                break;
+
+            case R.id.saveButton:
+                doSaveAction();
+                break;
+
+            case R.id.discardButton:
+                doRevertAction();
+                break;
+
+            case R.id.delete:
+            case R.id.delete2: {
+                EditEntry entry = findEntryForView(v);
+                if (entry != null) {
+                    // Clear the text and hide the view so it gets saved properly
+                    ((TextView) entry.view.findViewById(R.id.data)).setText(null);
+                    entry.view.setVisibility(View.GONE);
+                    entry.isDeleted = true;
+                }
+                break;
+            }
+
+            case R.id.label: {
+                EditEntry entry = findEntryForView(v);
+                if (entry != null) {
+                    String[] labels = getLabelsForKind(this, entry.kind);
+                    LabelPickedListener listener = new LabelPickedListener(entry, labels);
+                    new AlertDialog.Builder(EditContactActivity.this)
+                            .setItems(labels, listener)
+                            .setTitle(R.string.selectLabel)
+                            .show();
+                }
+                break;
+            }
+                
+            case R.id.data: {
+                EditEntry entry = findEntryForView(v);
+                if (isRingtoneEntry(entry)) {
+                    doPickRingtone(entry);
+                }
+                break;
+            }
+        }
+    }
+
+    private void setPhotoPresent(boolean present) {
+        mPhotoImageView.setVisibility(present ? View.VISIBLE : View.GONE);
+        mPhotoButton.setVisibility(present ? View.GONE : View.VISIBLE);
+        mPhotoPresent = present;
+        if (mPhotoMenuItem != null) {
+            if (present) {
+                mPhotoMenuItem.setTitle(R.string.removePicture);
+                mPhotoMenuItem.setIcon(android.R.drawable.ic_menu_delete);
+            } else {
+                mPhotoMenuItem.setTitle(R.string.addPicture);
+                mPhotoMenuItem.setIcon(android.R.drawable.ic_menu_add);
+            }
+        }
+    }
+    
+    private EditEntry findEntryForView(View v) {
+        // Try to find the entry for this view
+        EditEntry entry = null;
+        do {
+            Object tag = v.getTag();
+            if (tag != null && tag instanceof EditEntry) {
+                entry = (EditEntry) tag;
+                break;
+            } else {
+                ViewParent parent = v.getParent();
+                if (parent != null && parent instanceof View) {
+                    v = (View) parent;
+                } else {
+                    v = null;
+                }
+            }
+        } while (v != null);
+        return entry;
+    }
+
+    private DialogInterface.OnClickListener mDeleteContactDialogListener =
+            new DialogInterface.OnClickListener() {
+        public void onClick(DialogInterface dialog, int button) {
+            mResolver.delete(mUri, null, null);
+            finish();
+        }
+    };
+
+    private boolean mMobilePhoneAdded = false;
+    private boolean mPrimaryEmailAdded = false;
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        mResolver = getContentResolver();
+
+        // Build the list of sections
+        setupSections();
+
+        // Load the UI
+        setContentView(R.layout.edit_contact);
+        mLayout = (LinearLayout) findViewById(R.id.list);
+        mNameView = (EditText) findViewById(R.id.name);
+        mPhotoImageView = (ImageView) findViewById(R.id.photoImage);
+        mPhotoImageView.setOnClickListener(this);
+        mPhotoImageView.setVisibility(View.GONE);
+        mPhotoButton = (Button) findViewById(R.id.photoButton);
+        mPhotoButton.setOnClickListener(this);
+        mSendToVoicemailCheckBox = (CheckBox) findViewById(R.id.send_to_voicemail);
+
+        // Setup the bottom buttons 
+        View view = findViewById(R.id.addMore);
+        view.setOnClickListener(this);
+        view = findViewById(R.id.saveButton);
+        view.setOnClickListener(this);
+        view = findViewById(R.id.discardButton);
+        view.setOnClickListener(this);
+
+        mInflater = getLayoutInflater();
+
+        // Resolve the intent
+        mState = STATE_UNKNOWN;
+        Intent intent = getIntent();
+        String action = intent.getAction();
+        mUri = intent.getData();
+        if (mUri != null) {
+            if (action.equals(Intent.ACTION_EDIT)) {
+                if (icicle == null) {
+                    // Build the entries & views
+                    buildEntriesForEdit(getIntent().getExtras());
+                    buildViews();
+                }
+                mState = STATE_EDIT;
+            } else if (action.equals(Intent.ACTION_INSERT)) {
+                if (icicle == null) {
+                    // Build the entries & views
+                    buildEntriesForInsert(getIntent().getExtras());
+                    buildViews();
+                }
+                mState = STATE_INSERT;
+                mInsert = true;
+            }
+        }
+
+        if (mState == STATE_UNKNOWN) {
+            Log.e(TAG, "Cannot resolve intent: " + intent);
+            finish();
+            return;
+        }
+
+        if (mState == STATE_EDIT) {
+            setTitle(getResources().getText(R.string.editContact_title_edit));
+        } else {
+            setTitle(getResources().getText(R.string.editContact_title_insert));
+        }
+    }
+
+    private void setupSections() {
+        mSections.add(mPhoneEntries);
+        mSections.add(mEmailEntries);
+        mSections.add(mImEntries);
+        mSections.add(mPostalEntries);
+        mSections.add(mOtherEntries);
+    }
+    
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        outState.putParcelableArrayList("phoneEntries", mPhoneEntries);
+        outState.putParcelableArrayList("emailEntries", mEmailEntries);
+        outState.putParcelableArrayList("imEntries", mImEntries);
+        outState.putParcelableArrayList("postalEntries", mPostalEntries);
+        outState.putParcelableArrayList("otherEntries", mOtherEntries);
+        outState.putInt("state", mState);
+        outState.putBoolean("insert", mInsert);
+        outState.putParcelable("uri", mUri);
+        outState.putString("name", mNameView.getText().toString());
+        outState.putParcelable("photo", mPhoto);
+        outState.putBoolean("photoChanged", mPhotoChanged);
+        outState.putBoolean("sendToVoicemail", mSendToVoicemailCheckBox.isChecked());
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Bundle inState) {
+        mPhoneEntries = inState.getParcelableArrayList("phoneEntries");
+        mEmailEntries = inState.getParcelableArrayList("emailEntries");
+        mImEntries = inState.getParcelableArrayList("imEntries");
+        mPostalEntries = inState.getParcelableArrayList("postalEntries");
+        mOtherEntries = inState.getParcelableArrayList("otherEntries");
+        setupSections();
+
+        mState = inState.getInt("state");
+        mInsert = inState.getBoolean("insert");
+        mUri = inState.getParcelable("uri");
+        mNameView.setText(inState.getString("name"));
+        mPhoto = inState.getParcelable("photo");
+        if (mPhoto != null) {
+            mPhotoImageView.setImageBitmap(mPhoto);
+            setPhotoPresent(true);
+        } else {
+            mPhotoImageView.setImageResource(R.drawable.ic_contact_picture);
+            setPhotoPresent(false);
+        }
+        mPhotoChanged = inState.getBoolean("photoChanged");
+        mSendToVoicemailCheckBox.setChecked(inState.getBoolean("sendToVoicemail"));
+        
+        // Now that everything is restored, build the view
+        buildViews();
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (resultCode != RESULT_OK) {
+            return;
+        }
+
+        switch (requestCode) {
+            case PHOTO_PICKED_WITH_DATA: {
+                final Bundle extras = data.getExtras();
+                if (extras != null) {
+                    Bitmap photo = extras.getParcelable("data");
+                    mPhoto = photo;
+                    mPhotoChanged = true;
+                    mPhotoImageView.setImageBitmap(photo);
+                    setPhotoPresent(true);
+                }
+                break;
+            }
+
+            case RINGTONE_PICKED: {
+                Uri pickedUri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
+                handleRingtonePicked(pickedUri);
+                break;
+            }
+        }
+    }
+    
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_BACK: {
+                doSaveAction();
+                return true;
+            }
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        menu.add(0, MENU_ITEM_SAVE, 0, R.string.menu_done)
+                .setIcon(android.R.drawable.ic_menu_save)
+                .setAlphabeticShortcut('\n');
+        menu.add(0, MENU_ITEM_DONT_SAVE, 0, R.string.menu_doNotSave)
+                .setIcon(android.R.drawable.ic_menu_close_clear_cancel)
+                .setAlphabeticShortcut('q');
+        if (!mInsert) {
+            menu.add(0, MENU_ITEM_DELETE, 0, R.string.menu_deleteContact)
+                    .setIcon(android.R.drawable.ic_menu_delete);
+        }
+
+        menu.add(0, MENU_ITEM_ADD, 0, R.string.menu_addItem)
+                .setIcon(android.R.drawable.ic_menu_add)
+                .setAlphabeticShortcut('n');
+
+        mPhotoMenuItem = menu.add(0, MENU_ITEM_PHOTO, 0, null);
+        // Updates the state of the menu item
+        setPhotoPresent(mPhotoPresent);
+
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case MENU_ITEM_SAVE:
+                doSaveAction();
+                return true;
+    
+            case MENU_ITEM_DONT_SAVE:
+                doRevertAction();
+                return true;
+    
+            case MENU_ITEM_DELETE:
+                // Get confirmation
+                showDialog(DELETE_CONFIRMATION_DIALOG);
+                return true;
+    
+            case MENU_ITEM_ADD:
+                doAddAction();
+                return true;
+
+            case MENU_ITEM_PHOTO:
+                if (!mPhotoPresent) {
+                    doPickPhotoAction();
+                } else {
+                    doRemovePhotoAction();
+                }
+                return true;
+        }
+
+        return false;
+    }
+
+    private void doAddAction() {
+        showDialog(LABEL_PICKER_ALL_TYPES_DIALOG);
+    }
+
+    private void doRevertAction() {
+        finish();
+    }
+
+    private void doPickPhotoAction() {
+        Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
+        // TODO: get these values from constants somewhere
+        intent.setType("image/*");
+        intent.putExtra("crop", "true");
+        intent.putExtra("aspectX", 1);
+        intent.putExtra("aspectY", 1);
+        intent.putExtra("outputX", 96);
+        intent.putExtra("outputY", 96);
+        try {
+            intent.putExtra("return-data", true);
+            startActivityForResult(intent, PHOTO_PICKED_WITH_DATA);
+        } catch (ActivityNotFoundException e) {
+            new AlertDialog.Builder(EditContactActivity.this)
+                .setTitle(R.string.errorDialogTitle)
+                .setMessage(R.string.photoPickerNotFoundText)
+                .setPositiveButton(R.string.okButtonText, null)
+                .show();
+        }
+    }
+
+    private void doRemovePhotoAction() {
+        mPhoto = null;
+        mPhotoChanged = true;
+        mPhotoImageView.setImageResource(R.drawable.ic_contact_picture);
+        setPhotoPresent(false);
+    }
+    
+    private void doPickRingtone(EditEntry entry) {
+        Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
+        // Allow user to pick 'Default'
+        intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true);
+        // Show only ringtones
+        intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_RINGTONE);
+        // Don't show 'Silent'
+        intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false);
+        if (entry.data != null) {
+            Uri ringtoneUri = Uri.parse(entry.data);
+            // Put checkmark next to the current ringtone for this contact
+            intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, ringtoneUri);
+        }
+        // Launch!
+        startActivityForResult(intent, RINGTONE_PICKED);
+    }
+    
+    private void handleRingtonePicked(Uri pickedUri) {
+        EditEntry entry = getRingtoneEntry();
+        if (entry == null) {
+            Log.w(TAG, "Ringtone picked but could not find ringtone entry");
+            return;
+        }
+        
+        if (pickedUri == null || RingtoneManager.isDefault(pickedUri)) {
+            entry.data = null;
+        } else {
+            entry.data = pickedUri.toString();
+        }
+        
+        updateRingtoneView(entry);
+    }
+
+    private void updateRingtoneView(EditEntry entry) {
+        if (entry.data == null) {
+            updateDataView(entry, getString(R.string.default_ringtone));
+        } else {
+            Uri ringtoneUri = Uri.parse(entry.data);
+            Ringtone ringtone = RingtoneManager.getRingtone(this, ringtoneUri);
+            if (ringtone == null) {
+                Log.w(TAG, "ringtone's URI doesn't resolve to a Ringtone");
+                return;
+            }
+            updateDataView(entry, ringtone.getTitle(this));
+        }
+    }
+    
+    private void updateDataView(EditEntry entry, String text) {
+        TextView dataView = (TextView) entry.view.findViewById(R.id.data);
+        dataView.setText(text);
+    }
+    
+    @Override
+    protected Dialog onCreateDialog(int id) {
+        switch (id) {
+            case LABEL_PICKER_ALL_TYPES_DIALOG:
+                return createAllTypesPicker();
+
+            case DELETE_CONFIRMATION_DIALOG:
+                return new AlertDialog.Builder(EditContactActivity.this)
+                        .setTitle(R.string.deleteConfirmation_title)
+                        .setIcon(android.R.drawable.ic_dialog_alert)
+                        .setMessage(R.string.deleteConfirmation)
+                        .setNegativeButton(R.string.noButton, null)
+                        .setPositiveButton(R.string.yesButton, mDeleteContactDialogListener)
+                        .setCancelable(false)
+                        .create();
+        }
+        return super.onCreateDialog(id);
+    }
+    
+    static String[] getLabelsForKind(Context context, int kind) {
+        final Resources resources = context.getResources();
+        switch (kind) {
+            case Contacts.KIND_PHONE:
+                return resources.getStringArray(android.R.array.phoneTypes);
+            case Contacts.KIND_EMAIL:
+                return resources.getStringArray(android.R.array.emailAddressTypes);
+            case Contacts.KIND_POSTAL:
+                return resources.getStringArray(android.R.array.postalAddressTypes);
+            case Contacts.KIND_IM:
+                return resources.getStringArray(android.R.array.imProtocols);
+            case Contacts.KIND_ORGANIZATION:
+                return resources.getStringArray(android.R.array.organizationTypes);
+            case EditEntry.KIND_CONTACT:
+                return resources.getStringArray(R.array.otherLabels);
+        }
+        return null;
+    }
+
+    int getTypeFromLabelPosition(CharSequence[] labels, int labelPosition) {
+        // In the UI Custom... comes last, but it is uses the constant 0
+        // so it is in the same location across the various kinds. Fix up the
+        // position to a valid type here.
+        if (labelPosition == labels.length - 1) {
+            return ContactMethods.TYPE_CUSTOM;
+        } else {
+            return labelPosition + 1;
+        }
+    }
+
+    public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
+            int childPosition, long id) {
+        EditEntry entry = null;
+
+        // Make the dialog go away
+        dismissDialog(LABEL_PICKER_ALL_TYPES_DIALOG);
+
+        // Create the new entry
+        switch (groupPosition) {
+            case LABEL_PICKER_PHONES_POSITION: {
+                String[] labels = getLabelsForKind(this, Contacts.KIND_PHONE);
+                final int type = getTypeFromLabelPosition(labels, childPosition);
+                entry = EditEntry.newPhoneEntry(EditContactActivity.this,
+                        labels[childPosition], type,
+                        null, Uri.withAppendedPath(mUri, People.Phones.CONTENT_DIRECTORY), 0);
+                if (type == Phones.TYPE_CUSTOM) {
+                    createCustomPicker(entry, mPhoneEntries);
+                    return true;
+                } else {
+                    mPhoneEntries.add(entry);
+                }
+                break;
+            }
+
+            case LABEL_PICKER_EMAIL_POSITION: {
+                String[] labels = getLabelsForKind(this, Contacts.KIND_EMAIL);
+                final int type = getTypeFromLabelPosition(labels, childPosition);
+                entry = EditEntry.newEmailEntry(EditContactActivity.this,
+                        labels[childPosition], type, null,
+                        Uri.withAppendedPath(mUri, People.ContactMethods.CONTENT_DIRECTORY), 0);
+                if (type == ContactMethods.TYPE_CUSTOM) {
+                    createCustomPicker(entry, mEmailEntries);
+                    return true;
+                } else {
+                    mEmailEntries.add(entry);
+                }
+                break;
+            }
+            
+            case LABEL_PICKER_IM_POSITION: {
+                String[] labels = getLabelsForKind(this, Contacts.KIND_IM);
+                entry = EditEntry.newImEntry(EditContactActivity.this,
+                        labels[childPosition], childPosition, null,
+                        Uri.withAppendedPath(mUri, People.ContactMethods.CONTENT_DIRECTORY), 0);
+                mImEntries.add(entry);
+                break;
+            }
+
+            case LABEL_PICKER_POSTAL_POSITION: {
+                String[] labels = getLabelsForKind(this, Contacts.KIND_POSTAL);
+                final int type = getTypeFromLabelPosition(labels, childPosition);
+                entry = EditEntry.newPostalEntry(EditContactActivity.this,
+                        labels[childPosition], type, null,
+                        Uri.withAppendedPath(mUri, People.ContactMethods.CONTENT_DIRECTORY), 0);
+                if (type == ContactMethods.TYPE_CUSTOM) {
+                    createCustomPicker(entry, mPostalEntries);
+                    return true;
+                } else {
+                    mPostalEntries.add(entry);
+                }
+                break;
+            }
+            
+            case LABEL_PICKER_OTHER_POSITION: {
+                switch (childPosition) {
+                    case OTHER_ORGANIZATION:
+                        entry = EditEntry.newOrganizationEntry(EditContactActivity.this,
+                                Uri.withAppendedPath(mUri, Organizations.CONTENT_DIRECTORY),
+                                ContactMethods.TYPE_WORK);
+                        mOtherEntries.add(entry);
+                        break;
+
+                    case OTHER_NOTE:
+                        entry = EditEntry.newNotesEntry(EditContactActivity.this, null, mUri);
+                        mOtherEntries.add(entry);
+                        break;
+                        
+                    default:
+                        entry = null;
+                }
+                break;
+            }
+
+            default:
+                entry = null;
+        }
+
+        // Rebuild the views if needed
+        if (entry != null) {
+            buildViews();
+
+            View dataView = entry.view.findViewById(R.id.data);
+            if (dataView == null) {
+                entry.view.requestFocus();
+            } else {
+                dataView.requestFocus();
+            }
+        }
+        return true;
+    }
+
+    private EditEntry getRingtoneEntry() {
+        for (int i = mOtherEntries.size() - 1; i >= 0; i--) {
+            EditEntry entry = mOtherEntries.get(i);
+            if (isRingtoneEntry(entry)) {
+                return entry;
+            }
+        }
+        return null;
+    }
+    
+    private static boolean isRingtoneEntry(EditEntry entry) {
+        return entry != null && entry.column != null && entry.column.equals(People.CUSTOM_RINGTONE);
+    }
+    
+    private Dialog createAllTypesPicker() {
+        // Setup the adapter
+        List<Map<String, ?>> groupData = Lists.newArrayList();
+        List<List<Map<String, ?>>> childData = Lists.newArrayList();
+        List<Map<String, ?>> children;
+        HashMap<String, CharSequence> curGroupMap;
+        CharSequence[] labels;
+        int labelsSize;
+
+        // Phones
+        curGroupMap = new HashMap<String, CharSequence>();
+        groupData.add(curGroupMap);
+        curGroupMap.put("data", getText(R.string.phoneLabelsGroup));
+
+        labels = getLabelsForKind(this, Contacts.KIND_PHONE);
+        labelsSize = labels.length;
+        children = Lists.newArrayList();
+        for (int i = 0; i < labelsSize; i++) {
+            HashMap<String, CharSequence> curChildMap = new HashMap<String, CharSequence>();
+            children.add(curChildMap);
+            curChildMap.put("data", labels[i]);
+        }
+        childData.add(LABEL_PICKER_PHONES_POSITION, children);
+
+        // Email
+        curGroupMap = new HashMap<String, CharSequence>();
+        groupData.add(curGroupMap);
+        curGroupMap.put("data", getText(R.string.emailLabelsGroup));
+
+        labels = getLabelsForKind(this, Contacts.KIND_EMAIL);
+        labelsSize = labels.length;
+        children = Lists.newArrayList();
+        for (int i = 0; i < labelsSize; i++) {
+            HashMap<String, CharSequence> curChildMap = new HashMap<String, CharSequence>();
+            children.add(curChildMap);
+            curChildMap.put("data", labels[i]);
+        }
+        childData.add(LABEL_PICKER_EMAIL_POSITION, children);
+
+        // IM
+        curGroupMap = new HashMap<String, CharSequence>();
+        groupData.add(curGroupMap);
+        curGroupMap.put("data", getText(R.string.imLabelsGroup));
+
+        labels = getLabelsForKind(this, Contacts.KIND_IM);
+        labelsSize = labels.length;
+        children = Lists.newArrayList();
+        for (int i = 0; i < labelsSize; i++) {
+            HashMap<String, CharSequence> curChildMap = new HashMap<String, CharSequence>();
+            children.add(curChildMap);
+            curChildMap.put("data", labels[i]);
+        }
+        childData.add(LABEL_PICKER_IM_POSITION, children);
+        
+        // Postal
+        curGroupMap = new HashMap<String, CharSequence>();
+        groupData.add(curGroupMap);
+        curGroupMap.put("data", getText(R.string.postalLabelsGroup));
+
+        labels = getLabelsForKind(this, Contacts.KIND_POSTAL);
+        labelsSize = labels.length;
+        children = Lists.newArrayList();
+        for (int i = 0; i < labelsSize; i++) {
+            HashMap<String, CharSequence> curChildMap = new HashMap<String, CharSequence>();
+            children.add(curChildMap);
+            curChildMap.put("data", labels[i]);
+        }
+        childData.add(LABEL_PICKER_POSTAL_POSITION, children);
+
+        // Other
+        curGroupMap = new HashMap<String, CharSequence>();
+        groupData.add(curGroupMap);
+        curGroupMap.put("data", getText(R.string.otherLabelsGroup));
+
+        labels = getLabelsForKind(this, EditEntry.KIND_CONTACT);
+        labelsSize = labels.length;
+        children = Lists.newArrayList();
+        for (int i = 0; i < labelsSize; i++) {
+            HashMap<String, CharSequence> curChildMap = new HashMap<String, CharSequence>();
+            children.add(curChildMap);
+            curChildMap.put("data", labels[i]);
+        }
+        childData.add(LABEL_PICKER_OTHER_POSITION, children);
+
+        // Create the expandable list view
+        ExpandableListView list = new ExpandableListView(new ContextThemeWrapper(this,
+                android.R.style.Theme_Light));
+        list.setOnChildClickListener(this);
+        list.setAdapter(new SimpleExpandableListAdapter(
+                new ContextThemeWrapper(this, android.R.style.Theme_Light),
+                groupData,
+                android.R.layout.simple_expandable_list_item_1,
+                new String[] { "data" },
+                new int[] { android.R.id.text1 },
+                childData,
+                android.R.layout.simple_expandable_list_item_1,
+                new String[] { "data" },
+                new int[] { android.R.id.text1 }
+                ));
+        // This list shouldn't have a color hint since the dialog may be transparent
+        list.setCacheColorHint(0);
+
+        // Create the dialog
+        return new AlertDialog.Builder(this).setView(list).setInverseBackgroundForced(true)
+                .setTitle(R.string.selectLabel).create();
+    }
+
+    private void createCustomPicker(final EditEntry entry, final ArrayList<EditEntry> addTo) {
+        final EditText label = new EditText(this);
+        label.setKeyListener(TextKeyListener.getInstance(false, Capitalize.WORDS));
+        label.requestFocus();
+        new AlertDialog.Builder(this)
+                .setView(label)
+                .setTitle(R.string.customLabelPickerTitle)
+                .setPositiveButton(R.string.okButtonText, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int which) {
+                        entry.setLabel(EditContactActivity.this, ContactMethods.TYPE_CUSTOM,
+                                label.getText().toString());
+                        if (addTo != null) {
+                            addTo.add(entry);
+                            buildViews();
+                            entry.view.requestFocus(View.FOCUS_DOWN);
+                        }
+                    }
+                })
+                .setNegativeButton(R.string.cancelButtonText, null)
+                .show();
+    }
+    
+    /**
+     * Saves or creates the contact based on the mode, and if sucessful finishes the activity.
+     */
+    private void doSaveAction() {
+        // Save or create the contact if needed
+        switch (mState) {
+            case STATE_EDIT:
+                save();
+                break;
+
+            case STATE_INSERT:
+                create();
+                break;
+
+            default:
+                Log.e(TAG, "Unknown state in doSaveOrCreate: " + mState);
+                break;
+        }
+        finish();
+    }
+    
+    /**
+     * Save the various fields to the existing contact.
+     */
+    private void save() {
+        ContentValues values = new ContentValues();
+        String data;
+        int numValues = 0;
+
+        // Handle the name and send to voicemail specially
+        final String name = mNameView.getText().toString();
+        if (name != null && TextUtils.isGraphic(name)) {
+            numValues++;
+        }
+        values.put(People.NAME, name);
+        values.put(People.SEND_TO_VOICEMAIL, mSendToVoicemailCheckBox.isChecked() ? 1 : 0);
+        mResolver.update(mUri, values, null, null);
+
+        if (mPhotoChanged) {
+            // Only write the photo if it's changed, since we don't initially load mPhoto
+            if (mPhoto != null) {
+                ByteArrayOutputStream stream = new ByteArrayOutputStream();
+                mPhoto.compress(Bitmap.CompressFormat.JPEG, 75, stream);
+                Contacts.People.setPhotoData(mResolver, mUri, stream.toByteArray());
+            } else {
+                Contacts.People.setPhotoData(mResolver, mUri, null);
+            }
+        }
+
+        int entryCount = ContactEntryAdapter.countEntries(mSections, false);
+        for (int i = 0; i < entryCount; i++) {
+            EditEntry entry = ContactEntryAdapter.getEntry(mSections, i, false);
+            int kind = entry.kind;
+            data = entry.getData();
+            boolean empty = data == null || !TextUtils.isGraphic(data);
+            if (kind == EditEntry.KIND_CONTACT) {
+                values.clear();
+                if (!empty) {
+                    values.put(entry.column, data);
+                    mResolver.update(entry.uri, values, null, null);
+                    numValues++;
+                } else {
+                    values.put(entry.column, (String) null);
+                    mResolver.update(entry.uri, values, null, null);
+                }
+            } else {
+                if (!empty) {
+                    values.clear();
+                    entry.toValues(values);
+                    if (entry.id != 0) {
+                        mResolver.update(entry.uri, values, null, null);
+                    } else {
+                        mResolver.insert(entry.uri, values);
+                    }
+                    numValues++;
+                } else if (entry.id != 0) {
+                    mResolver.delete(entry.uri, null, null);
+                }
+            }
+        }
+
+        if (numValues == 0) {
+            // The contact is completely empty, delete it
+            mResolver.delete(mUri, null, null);
+            mUri = null;
+            setResult(RESULT_CANCELED);
+        } else {
+            // Add the entry to the my contacts group if it isn't there already
+            People.addToMyContactsGroup(mResolver, ContentUris.parseId(mUri));
+            setResult(RESULT_OK, new Intent().setData(mUri));
+            Toast.makeText(this, R.string.contactSavedToast, Toast.LENGTH_SHORT).show();
+        }
+    }
+
+    /**
+     * Takes the entered data and saves it to a new contact.
+     */
+    private void create() {
+        ContentValues values = new ContentValues();
+        String data;
+        int numValues = 0;
+
+        // Create the contact itself
+        final String name = mNameView.getText().toString();
+        if (name != null && TextUtils.isGraphic(name)) {
+            numValues++;
+        }
+        values.put(People.NAME, name);
+        values.put(People.SEND_TO_VOICEMAIL, mSendToVoicemailCheckBox.isChecked() ? 1 : 0);
+
+        // Add the contact to the My Contacts group
+        Uri contactUri = People.createPersonInMyContactsGroup(mResolver, values);
+
+        // Add the contact to the group that is being displayed in the contact list
+        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+        int displayType = prefs.getInt(ContactsPreferenceActivity.PREF_DISPLAY_TYPE,
+                ContactsPreferenceActivity.DISPLAY_TYPE_UNKNOWN);
+        if (displayType == ContactsPreferenceActivity.DISPLAY_TYPE_USER_GROUP) {
+            String displayGroup = prefs.getString(ContactsPreferenceActivity.PREF_DISPLAY_INFO,
+                    null);
+            if (!TextUtils.isEmpty(displayGroup)) {
+                People.addToGroup(mResolver, ContentUris.parseId(contactUri), displayGroup);
+            }
+        }
+
+        // Handle the photo
+        if (mPhoto != null) {
+            ByteArrayOutputStream stream = new ByteArrayOutputStream();
+            mPhoto.compress(Bitmap.CompressFormat.JPEG, 75, stream);
+            Contacts.People.setPhotoData(getContentResolver(), contactUri, stream.toByteArray());
+        }
+
+        // Create the contact methods
+        int entryCount = ContactEntryAdapter.countEntries(mSections, false);
+        for (int i = 0; i < entryCount; i++) {
+            EditEntry entry = ContactEntryAdapter.getEntry(mSections, i, false);
+            if (entry.kind != EditEntry.KIND_CONTACT) {
+                values.clear();
+                if (entry.toValues(values)) {
+                    // Only create the entry if there is data
+                    entry.uri = mResolver.insert(
+                            Uri.withAppendedPath(contactUri, entry.contentDirectory), values);
+                    entry.id = ContentUris.parseId(entry.uri);
+                    numValues++;
+                }
+            } else {
+                // Update the contact with any straggling data, like notes
+                data = entry.getData();
+                values.clear();
+                if (data != null && TextUtils.isGraphic(data)) {
+                    values.put(entry.column, data);
+                    mResolver.update(contactUri, values, null, null);
+                    numValues++;
+                }
+            }
+        }
+
+        if (numValues == 0) {
+            mResolver.delete(contactUri, null, null);
+            setResult(RESULT_CANCELED);
+        } else {
+            mUri = contactUri;
+            Intent resultIntent = new Intent()
+                    .setData(mUri)
+                    .putExtra(Intent.EXTRA_SHORTCUT_NAME, name);
+            setResult(RESULT_OK, resultIntent);
+            Toast.makeText(this, R.string.contactCreatedToast, Toast.LENGTH_SHORT).show();
+        }
+    }
+
+    /**
+     * Build up the entries to display on the screen.
+     *
+     * @param extras the extras used to start this activity, may be null
+     */
+    private void buildEntriesForEdit(Bundle extras) {
+        Cursor personCursor = mResolver.query(mUri, CONTACT_PROJECTION, null, null, null);
+        if (personCursor == null) {
+            Log.e(TAG, "invalid contact uri: " + mUri);
+            finish();
+            return;
+        } else if (!personCursor.moveToFirst()) {
+            Log.e(TAG, "invalid contact uri: " + mUri);
+            finish();
+            personCursor.close();
+            return;
+        }
+
+        // Clear out the old entries
+        int numSections = mSections.size();
+        for (int i = 0; i < numSections; i++) {
+            mSections.get(i).clear();
+        }
+
+        EditEntry entry;
+
+        // Name
+        mNameView.setText(personCursor.getString(CONTACT_NAME_COLUMN));
+
+        // Photo
+        mPhoto = People.loadContactPhoto(this, mUri, 0, null);
+        if (mPhoto == null) {
+            setPhotoPresent(false);
+        } else {
+            setPhotoPresent(true);
+            mPhotoImageView.setImageBitmap(mPhoto);
+        }
+
+        // Send to voicemail
+        mSendToVoicemailCheckBox
+                .setChecked(personCursor.getInt(CONTACT_SEND_TO_VOICEMAIL_COLUMN) == 1);
+
+        // Organizations
+        Uri organizationsUri = Uri.withAppendedPath(mUri, Organizations.CONTENT_DIRECTORY);
+        Cursor organizationsCursor = mResolver.query(organizationsUri, ORGANIZATIONS_PROJECTION,
+                null, null, null);
+
+        if (organizationsCursor != null) {
+            while (organizationsCursor.moveToNext()) {
+                int type = organizationsCursor.getInt(ORGANIZATIONS_TYPE_COLUMN);
+                String label = organizationsCursor.getString(ORGANIZATIONS_LABEL_COLUMN);
+                String company = organizationsCursor.getString(ORGANIZATIONS_COMPANY_COLUMN);
+                String title = organizationsCursor.getString(ORGANIZATIONS_TITLE_COLUMN);
+                long id = organizationsCursor.getLong(ORGANIZATIONS_ID_COLUMN);
+                Uri uri = ContentUris.withAppendedId(Organizations.CONTENT_URI, id);
+
+                // Add an organization entry
+                entry = EditEntry.newOrganizationEntry(this, label, type, company, title, uri, id);
+                entry.isPrimary = organizationsCursor.getLong(ORGANIZATIONS_ISPRIMARY_COLUMN) != 0;
+                mOtherEntries.add(entry);
+            }
+            organizationsCursor.close();
+        }
+
+        // Notes
+        if (!personCursor.isNull(CONTACT_NOTES_COLUMN)) {
+            entry = EditEntry.newNotesEntry(this, personCursor.getString(CONTACT_NOTES_COLUMN),
+                    mUri);
+            mOtherEntries.add(entry);
+        }
+
+        // Ringtone
+        entry = EditEntry.newRingtoneEntry(this,
+                personCursor.getString(CONTACT_CUSTOM_RINGTONE_COLUMN), mUri);
+        mOtherEntries.add(entry);
+        personCursor.close();
+
+        // Build up the phone entries
+        Uri phonesUri = Uri.withAppendedPath(mUri, People.Phones.CONTENT_DIRECTORY);
+        Cursor phonesCursor = mResolver.query(phonesUri, PHONES_PROJECTION,
+                null, null, null);
+
+        if (phonesCursor != null) {
+            while (phonesCursor.moveToNext()) {
+                int type = phonesCursor.getInt(PHONES_TYPE_COLUMN);
+                String label = phonesCursor.getString(PHONES_LABEL_COLUMN);
+                String number = phonesCursor.getString(PHONES_NUMBER_COLUMN);
+                long id = phonesCursor.getLong(PHONES_ID_COLUMN);
+                boolean isPrimary = phonesCursor.getLong(PHONES_ISPRIMARY_COLUMN) != 0;
+                Uri uri = ContentUris.withAppendedId(phonesUri, id);
+
+                // Add a phone number entry
+                entry = EditEntry.newPhoneEntry(this, label, type, number, uri, id);
+                entry.isPrimary = isPrimary;
+                mPhoneEntries.add(entry);
+
+                // Keep track of which primary types have been added
+                if (type == Phones.TYPE_MOBILE) {
+                    mMobilePhoneAdded = true;
+                }
+            }
+
+            phonesCursor.close();
+        }
+
+        // Build the contact method entries
+        Uri methodsUri = Uri.withAppendedPath(mUri, People.ContactMethods.CONTENT_DIRECTORY);
+        Cursor methodsCursor = mResolver.query(methodsUri, METHODS_PROJECTION, null, null, null);
+
+        if (methodsCursor != null) {
+            while (methodsCursor.moveToNext()) {
+                int kind = methodsCursor.getInt(METHODS_KIND_COLUMN);
+                String label = methodsCursor.getString(METHODS_LABEL_COLUMN);
+                String data = methodsCursor.getString(METHODS_DATA_COLUMN);
+                String auxData = methodsCursor.getString(METHODS_AUX_DATA_COLUMN);
+                int type = methodsCursor.getInt(METHODS_TYPE_COLUMN);
+                long id = methodsCursor.getLong(METHODS_ID_COLUMN);
+                boolean isPrimary = methodsCursor.getLong(METHODS_ISPRIMARY_COLUMN) != 0;
+                Uri uri = ContentUris.withAppendedId(methodsUri, id);
+
+                switch (kind) {
+                    case Contacts.KIND_EMAIL: {
+                        entry = EditEntry.newEmailEntry(this, label, type, data, uri, id);
+                        entry.isPrimary = isPrimary;
+                        mEmailEntries.add(entry);
+    
+                        if (isPrimary) {
+                            mPrimaryEmailAdded = true;
+                        }
+                        break;
+                    }
+
+                    case Contacts.KIND_POSTAL: {
+                        entry = EditEntry.newPostalEntry(this, label, type, data, uri, id);
+                        entry.isPrimary = isPrimary;
+                        mPostalEntries.add(entry);
+                        break;
+                    }
+
+                    case Contacts.KIND_IM: {
+                        Object protocolObj = ContactMethods.decodeImProtocol(auxData);
+                        if (protocolObj == null) {
+                            // Invalid IM protocol, log it then ignore.
+                            Log.e(TAG, "Couldn't decode IM protocol: " + auxData);
+                            continue;
+                        } else {
+                            if (protocolObj instanceof Number) {
+                                int protocol = ((Number) protocolObj).intValue();
+                                entry = EditEntry.newImEntry(this,
+                                        getLabelsForKind(this, Contacts.KIND_IM)[protocol], protocol, 
+                                        data, uri, id);
+                            } else {
+                                entry = EditEntry.newImEntry(this, protocolObj.toString(), -1, data,
+                                        uri, id);
+                            }
+                            mImEntries.add(entry);
+                        }
+                        break;
+                    }
+                }
+            }
+
+            methodsCursor.close();
+        }
+
+        // Add values from the extras, if there are any
+        if (extras != null) {
+            addFromExtras(extras, phonesUri, methodsUri);
+        }
+
+        // Add the base types if needed
+        if (!mMobilePhoneAdded) {
+            entry = EditEntry.newPhoneEntry(this,
+                    Uri.withAppendedPath(mUri, People.Phones.CONTENT_DIRECTORY),
+                    DEFAULT_PHONE_TYPE);
+            mPhoneEntries.add(entry);
+        }
+
+        if (!mPrimaryEmailAdded) {
+            entry = EditEntry.newEmailEntry(this,
+                    Uri.withAppendedPath(mUri, People.ContactMethods.CONTENT_DIRECTORY),
+                    DEFAULT_EMAIL_TYPE);
+            entry.isPrimary = true;
+            mEmailEntries.add(entry);
+        }
+    }
+
+    /**
+     * Build the list of EditEntries for full mode insertions.
+     * 
+     * @param extras the extras used to start this activity, may be null
+     */
+    private void buildEntriesForInsert(Bundle extras) {
+        // Clear out the old entries
+        int numSections = mSections.size();
+        for (int i = 0; i < numSections; i++) {
+            mSections.get(i).clear();
+        }
+
+        EditEntry entry;
+
+        // Check the intent extras
+        if (extras != null) {
+            addFromExtras(extras, null, null);
+        }
+
+        // Photo
+        mPhotoImageView.setImageResource(R.drawable.ic_contact_picture);
+
+        // Add the base entries if they're not already present
+        if (!mMobilePhoneAdded) {
+            entry = EditEntry.newPhoneEntry(this, null, Phones.TYPE_MOBILE);
+            entry.isPrimary = true;
+            mPhoneEntries.add(entry);
+        }
+
+        if (!mPrimaryEmailAdded) {
+            entry = EditEntry.newEmailEntry(this, null, DEFAULT_EMAIL_TYPE);
+            entry.isPrimary = true;
+            mEmailEntries.add(entry);
+        }
+
+        // Ringtone
+        entry = EditEntry.newRingtoneEntry(this, null, mUri);
+        mOtherEntries.add(entry);
+        
+    }
+
+    private void addFromExtras(Bundle extras, Uri phonesUri, Uri methodsUri) {
+        EditEntry entry;
+
+        // Read the name from the bundle
+        CharSequence name = extras.getCharSequence(Insert.NAME);
+        if (name != null && TextUtils.isGraphic(name)) {
+            mNameView.setText(name);
+        }
+        
+        // Postal entries from extras
+        CharSequence postal = extras.getCharSequence(Insert.POSTAL);
+        int postalType = extras.getInt(Insert.POSTAL_TYPE, INVALID_TYPE);
+        if (!TextUtils.isEmpty(postal) && postalType == INVALID_TYPE) {
+            postalType = DEFAULT_POSTAL_TYPE;
+        }
+        
+        if (postalType != INVALID_TYPE) {
+            entry = EditEntry.newPostalEntry(this, null, postalType, postal.toString(),
+                    methodsUri, 0);
+            entry.isPrimary = extras.getBoolean(Insert.POSTAL_ISPRIMARY);
+            mPostalEntries.add(entry);
+        }
+
+        // Email entries from extras
+        CharSequence email = extras.getCharSequence(Insert.EMAIL);
+        int emailType = extras.getInt(Insert.EMAIL_TYPE, INVALID_TYPE);
+        if (!TextUtils.isEmpty(email) && emailType == INVALID_TYPE) {
+            emailType = DEFAULT_EMAIL_TYPE;
+            mPrimaryEmailAdded = true;
+        }
+   
+        if (emailType != INVALID_TYPE) {
+            entry = EditEntry.newEmailEntry(this, null, emailType, email.toString(), methodsUri, 0);
+            entry.isPrimary = extras.getBoolean(Insert.EMAIL_ISPRIMARY);
+            mEmailEntries.add(entry);
+
+            // Keep track of which primary types have been added
+            if (entry.isPrimary) {
+                mPrimaryEmailAdded = true;
+            }
+        }
+   
+        // Phone entries from extras 
+        CharSequence phoneNumber = extras.getCharSequence(Insert.PHONE);
+        int phoneType = extras.getInt(Insert.PHONE_TYPE, INVALID_TYPE);
+        if (!TextUtils.isEmpty(phoneNumber) && phoneType == INVALID_TYPE) {
+            phoneType = DEFAULT_PHONE_TYPE;
+        }
+   
+        if (phoneType != INVALID_TYPE) {
+            entry = EditEntry.newPhoneEntry(this, null, phoneType,
+                    phoneNumber.toString(), phonesUri, 0);
+            entry.isPrimary = extras.getBoolean(Insert.PHONE_ISPRIMARY);
+            mPhoneEntries.add(entry);
+
+            // Keep track of which primary types have been added
+            if (phoneType == Phones.TYPE_MOBILE) {
+                mMobilePhoneAdded = true;
+            }
+        }
+
+        // IM entries from extras
+        CharSequence imHandle = extras.getCharSequence(Insert.IM_HANDLE);
+        CharSequence imProtocol = extras.getCharSequence(Insert.IM_PROTOCOL);
+   
+        if (imHandle != null && imProtocol != null) {
+            Object protocolObj = ContactMethods.decodeImProtocol(imProtocol.toString());
+            if (protocolObj instanceof Number) {
+                int protocol = ((Number) protocolObj).intValue();
+                entry = EditEntry.newImEntry(this,
+                        getLabelsForKind(this, Contacts.KIND_IM)[protocol], protocol, 
+                        imHandle.toString(), null, 0);
+            } else {
+                entry = EditEntry.newImEntry(this, protocolObj.toString(), -1, imHandle.toString(),
+                        null, 0);
+            }
+            entry.isPrimary = extras.getBoolean(Insert.IM_ISPRIMARY);
+            mImEntries.add(entry);
+        }
+    }
+
+    /**
+     * Removes all existing views, builds new ones for all the entries, and adds them.
+     */
+    private void buildViews() {
+        // Remove existing views
+        final LinearLayout layout = mLayout;
+        layout.removeAllViews();
+
+        buildViewsForSection(layout, mPhoneEntries, R.string.listSeparatorCallNumber);
+        buildViewsForSection(layout, mEmailEntries, R.string.listSeparatorSendEmail);
+        buildViewsForSection(layout, mImEntries, R.string.listSeparatorSendIm);
+        buildViewsForSection(layout, mPostalEntries, R.string.listSeparatorMapAddress);
+        buildViewsForSection(layout, mOtherEntries, R.string.listSeparatorOtherInformation);
+    }
+
+
+    /**
+     * Builds the views for a specific section.
+     * 
+     * @param layout the container
+     * @param section the section to build the views for
+     */
+    private void buildViewsForSection(final LinearLayout layout, ArrayList<EditEntry> section,
+            int separatorResource) {
+        // Build the separator if the section isn't empty
+        if (section.size() > 0) {
+            View separator = mInflater.inflate(R.layout.edit_separator, layout, false);
+            TextView text = (TextView) separator.findViewById(R.id.text);
+            text.setText(getText(separatorResource));
+            layout.addView(separator);
+        }
+
+        // Build views for the current section
+        for (EditEntry entry : section) {
+            entry.activity = this; // this could be null from when the state is restored
+            if (!entry.isDeleted) {
+                View view = buildViewForEntry(entry);
+                layout.addView(view);
+            }
+        }
+    }
+
+    /**
+     * Builds a view to display an EditEntry.
+     * 
+     * @param entry the entry to display
+     * @return a view that will display the given entry
+     */
+    /* package */ View buildViewForEntry(final EditEntry entry) {
+        // Look for any existing entered text, and save it if found
+        if (entry.view != null && entry.syncDataWithView) {
+            String enteredText = ((TextView) entry.view.findViewById(R.id.data))
+                    .getText().toString();
+            if (!TextUtils.isEmpty(enteredText)) {
+                entry.data = enteredText;
+            }
+        }
+
+        // Build a new view
+        final ViewGroup parent = mLayout;
+        View view;
+
+        if (entry.kind == Contacts.KIND_ORGANIZATION) {
+            view = mInflater.inflate(R.layout.edit_contact_entry_org, parent, false);
+        } else if (isRingtoneEntry(entry)) {
+            view = mInflater.inflate(R.layout.edit_contact_entry_ringtone, parent, false);
+        } else if (!entry.isStaticLabel) {
+            view = mInflater.inflate(R.layout.edit_contact_entry, parent, false);
+        } else {
+            view = mInflater.inflate(R.layout.edit_contact_entry_static_label, parent, false);
+        }
+        entry.view = view;
+        
+        // Set the entry as the tag so we can find it again later given just the view
+        view.setTag(entry);
+
+        // Bind the label
+        entry.bindLabel(this);
+
+        // Bind data
+        TextView data = (TextView) view.findViewById(R.id.data);
+        TextView data2 = (TextView) view.findViewById(R.id.data2);
+
+        if (data instanceof Button) {
+            data.setOnClickListener(this);
+        }
+        if (data.length() == 0) {
+            if (entry.syncDataWithView) {
+                // If there is already data entered don't overwrite it
+                data.setText(entry.data);
+            } else {
+                fillViewData(entry);
+            }
+        }
+        if (data2 != null && data2.length() == 0) {
+            // If there is already data entered don't overwrite it
+            data2.setText(entry.data2);
+        }
+        data.setHint(entry.hint);
+        if (data2 != null) data2.setHint(entry.hint2);
+        if (entry.lines > 1) {
+            data.setLines(entry.lines);
+            data.setMaxLines(entry.maxLines);
+            if (data2 != null) {
+                data2.setLines(entry.lines);
+                data2.setMaxLines(entry.maxLines);
+            }
+        } else if (entry.lines >= 0) {
+            data.setSingleLine();
+            if (data2 != null) {
+                data2.setSingleLine();
+            }
+        }
+        switch (entry.keyListener) {
+            case INPUT_TEXT:
+                data.setKeyListener(TextKeyListener.getInstance());
+                if (data2 != null) {
+                    data2.setKeyListener(TextKeyListener.getInstance());
+                }
+                break;
+                
+            case INPUT_TEXT_WORDS:
+                data.setKeyListener(TextKeyListener.getInstance(true, Capitalize.WORDS));
+                if (data2 != null) {
+                    data2.setKeyListener(TextKeyListener.getInstance(true, Capitalize.WORDS));
+                }
+                break;
+                
+            case INPUT_TEXT_SENTENCES:
+                data.setKeyListener(TextKeyListener.getInstance(true, Capitalize.SENTENCES));
+                if (data2 != null) {
+                    data2.setKeyListener(TextKeyListener.getInstance(true, Capitalize.SENTENCES));
+                }
+                break;
+                
+            case INPUT_DIALER:
+                data.setKeyListener(DialerKeyListener.getInstance());
+                data.addTextChangedListener(new PhoneNumberFormattingTextWatcher());
+                if (data2 != null) {
+                    data2.setKeyListener(DialerKeyListener.getInstance());
+                    data2.addTextChangedListener(new PhoneNumberFormattingTextWatcher());
+                }
+                break;
+        }
+
+        // Hook up the delete button
+        View delete = view.findViewById(R.id.delete);
+        if (delete != null) delete.setOnClickListener(this);
+        View delete2 = view.findViewById(R.id.delete2);
+        if (delete2 != null) delete2.setOnClickListener(this);
+        
+        return view;
+    }
+
+    private void fillViewData(final EditEntry entry) {
+        if (isRingtoneEntry(entry)) {
+            updateRingtoneView(entry);
+        }
+    }
+    
+    /**
+     * Handles the results from the label change picker.
+     */
+    private final class LabelPickedListener implements DialogInterface.OnClickListener {
+        EditEntry mEntry;
+        String[] mLabels;
+
+        public LabelPickedListener(EditEntry entry, String[] labels) {
+            mEntry = entry;
+            mLabels = labels;
+        }
+
+        public void onClick(DialogInterface dialog, int which) {
+            // TODO: Use a managed dialog
+            if (mEntry.kind != Contacts.KIND_IM) {
+                final int type = getTypeFromLabelPosition(mLabels, which);
+                if (type == ContactMethods.TYPE_CUSTOM) {
+                    createCustomPicker(mEntry, null);
+                } else {
+                    mEntry.setLabel(EditContactActivity.this, type, mLabels[which]);
+                }
+            } else {
+                mEntry.setLabel(EditContactActivity.this, which, mLabels[which]);
+            }
+        }
+    }
+
+    /**
+     * A basic structure with the data for a contact entry in the list.
+     */
+    private static final class EditEntry extends ContactEntryAdapter.Entry implements Parcelable {
+        // These aren't stuffed into the parcel
+        public EditContactActivity activity;
+        public View view;
+
+        // These are stuffed into the parcel
+        public String hint;
+        public String hint2;
+        public String column;
+        public String contentDirectory;
+        public String data2;
+        public int keyListener;
+        public int type;
+        /**
+         * If 0 or 1, setSingleLine will be called. If negative, setSingleLine
+         * will not be called.
+         */
+        public int lines = 1;
+        public boolean isPrimary;
+        public boolean isDeleted = false;
+        public boolean isStaticLabel = false;
+        public boolean syncDataWithView = true;
+
+        private EditEntry() {
+            // only used by CREATOR
+        }
+
+        public EditEntry(EditContactActivity activity) {
+            this.activity = activity;
+        }
+
+        public EditEntry(EditContactActivity activity, String label,
+                int type, String data, Uri uri, long id) {
+            this.activity = activity;
+            this.isPrimary = false;
+            this.label = label;
+            this.type = type;
+            this.data = data;
+            this.uri = uri;
+            this.id = id;
+        }
+
+        public int describeContents() {
+            return 0;
+        }
+
+        public void writeToParcel(Parcel parcel, int flags) {
+            // Make sure to read data from the input field, if anything is entered
+            data = getData();
+
+            // Write in our own fields.
+            parcel.writeString(hint);
+            parcel.writeString(hint2);
+            parcel.writeString(column);
+            parcel.writeString(contentDirectory);
+            parcel.writeString(data2);
+            parcel.writeInt(keyListener);
+            parcel.writeInt(type);
+            parcel.writeInt(lines);
+            parcel.writeInt(isPrimary ? 1 : 0);
+            parcel.writeInt(isDeleted ? 1 : 0);
+            parcel.writeInt(isStaticLabel ? 1 : 0);
+            parcel.writeInt(syncDataWithView ? 1 : 0);
+
+            // Write in the fields from Entry
+            super.writeToParcel(parcel);
+        }
+
+        public static final Parcelable.Creator<EditEntry> CREATOR =
+            new Parcelable.Creator<EditEntry>() {
+            public EditEntry createFromParcel(Parcel in) {
+                EditEntry entry = new EditEntry();
+
+                // Read out our own fields
+                entry.hint = in.readString();
+                entry.hint2 = in.readString();
+                entry.column = in.readString();
+                entry.contentDirectory = in.readString();
+                entry.data2 = in.readString();
+                entry.keyListener = in.readInt();
+                entry.type = in.readInt();
+                entry.lines = in.readInt();
+                entry.isPrimary = in.readInt() == 1;
+                entry.isDeleted = in.readInt() == 1;
+                entry.isStaticLabel = in.readInt() == 1;
+                entry.syncDataWithView = in.readInt() == 1;
+                
+                // Read out the fields from Entry
+                entry.readFromParcel(in);
+
+                return entry;
+            }
+            
+            public EditEntry[] newArray(int size) {
+                return new EditEntry[size];
+            }
+        };
+
+        public void setLabel(Context context, int typeIn, String labelIn) {
+            type = typeIn;
+            label = labelIn;
+            if (view != null) {
+                bindLabel(context);
+            }
+        }
+        
+        public void bindLabel(Context context) {
+            TextView v = (TextView) view.findViewById(R.id.label);
+            if (isStaticLabel) {
+                v.setText(label);
+                return;
+            }
+
+            switch (kind) {
+                case Contacts.KIND_PHONE: {
+                    v.setText(Phones.getDisplayLabel(context, type, label));
+                    break;
+                }
+
+                case Contacts.KIND_IM: {
+                    v.setText(getLabelsForKind(activity, kind)[type]);
+                    break;
+                }
+                
+                case Contacts.KIND_ORGANIZATION: {
+                    v.setText(Organizations.getDisplayLabel(activity, type, label));
+                    break;
+                }
+
+                default: {
+                    v.setText(Contacts.ContactMethods.getDisplayLabel(context, kind, type, label));
+                    if (kind == Contacts.KIND_POSTAL) {
+                        v.setMaxLines(3);
+                    }
+                    break;
+                }
+            }
+            v.setOnClickListener(activity);
+        }
+
+        /**
+         * Returns the data for the entry
+         * @return the data for the entry
+         */
+        public String getData() {
+            if (view != null && syncDataWithView) {
+                CharSequence text = ((TextView) view.findViewById(R.id.data)).getText();
+                if (text != null) {
+                    return text.toString();
+                }
+            }
+
+            if (data != null) {
+                return data.toString();
+            }
+
+            return null;
+        }
+
+        /**
+         * Dumps the entry into a HashMap suitable for passing to the database.
+         * 
+         * @param values the HashMap to fill in.
+         * @return true if the value should be saved, false otherwise
+         */
+        public boolean toValues(ContentValues values) {
+            boolean success = false;
+            String labelString = null;
+            // Save the type and label
+            if (view != null) {
+                // Read the possibly updated label from the text field
+                labelString = ((TextView) view.findViewById(R.id.label)).getText().toString();
+            }
+            switch (kind) {
+                case Contacts.KIND_PHONE:
+                    if (type != Phones.TYPE_CUSTOM) {
+                        labelString = null;
+                    }
+                    values.put(Phones.LABEL, labelString);
+                    values.put(Phones.TYPE, type);
+                    break;
+
+                case Contacts.KIND_EMAIL:
+                    if (type != ContactMethods.TYPE_CUSTOM) {
+                        labelString = null;
+                    }
+                    values.put(ContactMethods.LABEL, labelString);
+                    values.put(ContactMethods.KIND, kind);
+                    values.put(ContactMethods.TYPE, type);
+                    break;
+
+                case Contacts.KIND_IM:
+                    values.put(ContactMethods.KIND, kind);
+                    values.put(ContactMethods.TYPE, ContactMethods.TYPE_OTHER);
+                    values.putNull(ContactMethods.LABEL);
+                    if (type != -1) {
+                        values.put(ContactMethods.AUX_DATA,
+                                ContactMethods.encodePredefinedImProtocol(type));
+                    } else {
+                        values.put(ContactMethods.AUX_DATA,
+                                ContactMethods.encodeCustomImProtocol(label.toString()));
+                    }
+                    break;
+
+                case Contacts.KIND_POSTAL:
+                    if (type != ContactMethods.TYPE_CUSTOM) {
+                        labelString = null;
+                    }
+                    values.put(ContactMethods.LABEL, labelString);
+                    values.put(ContactMethods.KIND, kind);
+                    values.put(ContactMethods.TYPE, type);
+                    break;
+
+                case Contacts.KIND_ORGANIZATION:
+                    if (type != ContactMethods.TYPE_CUSTOM) {
+                        labelString = null;
+                    }
+                    values.put(ContactMethods.LABEL, labelString);
+                    values.put(ContactMethods.TYPE, type);
+                    // Save the title
+                    if (view != null) {
+                        // Read the possibly updated data from the text field
+                        data2 = ((TextView) view.findViewById(R.id.data2)).getText().toString();
+                    }
+                    if (!TextUtils.isGraphic(data2)) {
+                        values.putNull(Organizations.TITLE);
+                    } else {
+                        values.put(Organizations.TITLE, data2.toString());
+                        success = true;
+                    }
+                    break;
+
+                default:
+                    Log.w(TAG, "unknown kind " + kind);
+                    values.put(ContactMethods.LABEL, labelString);
+                    values.put(ContactMethods.KIND, kind);
+                    values.put(ContactMethods.TYPE, type);
+                    break;
+            }
+
+            values.put(ContactMethods.ISPRIMARY, isPrimary ? "1" : "0");
+
+            // Save the data
+            if (view != null && syncDataWithView) {
+                // Read the possibly updated data from the text field
+                data = ((TextView) view.findViewById(R.id.data)).getText().toString();
+            }
+            if (!TextUtils.isGraphic(data)) {
+                values.putNull(column);
+                return success;
+            } else {
+                values.put(column, data.toString());
+                return true;
+            }
+        }
+
+        /**
+         * Create a new empty organization entry
+         */
+        public static final EditEntry newOrganizationEntry(EditContactActivity activity,
+                Uri uri, int type) {
+            return newOrganizationEntry(activity, null, type, null, null, uri, 0);
+        }
+
+        /**
+         * Create a new company entry with the given data.
+         */
+        public static final EditEntry newOrganizationEntry(EditContactActivity activity,
+                String label, int type, String company, String title, Uri uri, long id) {
+            EditEntry entry = new EditEntry(activity, label, type, company, uri, id);
+            entry.hint = activity.getString(R.string.ghostData_company);
+            entry.hint2 = activity.getString(R.string.ghostData_title);
+            entry.data2 = title;
+            entry.column = Organizations.COMPANY;
+            entry.contentDirectory = Organizations.CONTENT_DIRECTORY;
+            entry.kind = Contacts.KIND_ORGANIZATION;
+            entry.keyListener = INPUT_TEXT_WORDS;
+            return entry;
+        }
+
+        /**
+         * Create a new notes entry with the given data.
+         */
+        public static final EditEntry newNotesEntry(EditContactActivity activity,
+                String data, Uri uri) {
+            EditEntry entry = new EditEntry(activity);
+            entry.label = activity.getString(R.string.label_notes);
+            entry.hint = activity.getString(R.string.ghostData_notes);
+            entry.data = data;
+            entry.uri = uri;
+            entry.column = People.NOTES;
+            entry.maxLines = 10;
+            entry.lines = 2;
+            entry.id = 0;
+            entry.kind = KIND_CONTACT;
+            entry.keyListener = INPUT_TEXT_SENTENCES;
+            entry.isStaticLabel = true;
+            return entry;
+        }
+
+        /**
+         * Create a new ringtone entry with the given data.
+         */
+        public static final EditEntry newRingtoneEntry(EditContactActivity activity,
+                String data, Uri uri) {
+            EditEntry entry = new EditEntry(activity);
+            entry.label = activity.getString(R.string.label_ringtone);
+            entry.data = data;
+            entry.uri = uri;
+            entry.column = People.CUSTOM_RINGTONE;
+            entry.kind = KIND_CONTACT;
+            entry.isStaticLabel = true;
+            entry.syncDataWithView = false;
+            entry.lines = -1;
+            return entry;
+        }
+
+        /**
+         * Create a new empty email entry
+         */
+        public static final EditEntry newPhoneEntry(EditContactActivity activity,
+                Uri uri, int type) {
+            return newPhoneEntry(activity, null, type, null, uri, 0);
+        }
+
+        /**
+         * Create a new phone entry with the given data.
+         */
+        public static final EditEntry newPhoneEntry(EditContactActivity activity,
+                String label, int type, String data, Uri uri,
+                long id) {
+            EditEntry entry = new EditEntry(activity, label, type, data, uri, id);
+            entry.hint = activity.getString(R.string.ghostData_phone);
+            entry.column = People.Phones.NUMBER;
+            entry.contentDirectory = People.Phones.CONTENT_DIRECTORY;
+            entry.kind = Contacts.KIND_PHONE;
+            entry.keyListener = INPUT_DIALER;
+            return entry;
+        }
+
+        /**
+         * Create a new empty email entry
+         */
+        public static final EditEntry newEmailEntry(EditContactActivity activity,
+                Uri uri, int type) {
+            return newEmailEntry(activity, null, type, null, uri, 0);
+        }
+
+        /**
+         * Create a new email entry with the given data.
+         */
+        public static final EditEntry newEmailEntry(EditContactActivity activity,
+                String label, int type, String data, Uri uri,
+                long id) {
+            EditEntry entry = new EditEntry(activity, label, type, data, uri, id);
+            entry.hint = activity.getString(R.string.ghostData_email);
+            entry.column = ContactMethods.DATA;
+            entry.contentDirectory = People.ContactMethods.CONTENT_DIRECTORY;
+            entry.kind = Contacts.KIND_EMAIL;
+            entry.keyListener = INPUT_TEXT;
+            return entry;
+        }
+
+        /**
+         * Create a new empty postal address entry
+         */
+        public static final EditEntry newPostalEntry(EditContactActivity activity,
+                Uri uri, int type) {
+            return newPostalEntry(activity, null, type, null, uri, 0);
+        }
+
+        /**
+         * Create a new postal address entry with the given data.
+         *
+         * @param label label for the item, from the db not the display label
+         * @param type the type of postal address
+         * @param data the starting data for the entry, may be null
+         * @param uri the uri for the entry if it already exists, may be null
+         * @param id the id for the entry if it already exists, 0 it it doesn't
+         * @return the new EditEntry
+         */
+        public static final EditEntry newPostalEntry(EditContactActivity activity,
+                String label, int type, String data, Uri uri, long id) {
+            EditEntry entry = new EditEntry(activity, label, type, data, uri, id);
+            entry.hint = activity.getString(R.string.ghostData_postal);
+            entry.column = ContactMethods.DATA;
+            entry.contentDirectory = People.ContactMethods.CONTENT_DIRECTORY;
+            entry.kind = Contacts.KIND_POSTAL;
+            entry.keyListener = INPUT_TEXT_WORDS;
+            entry.maxLines = 4;
+            entry.lines = 2;
+            return entry;
+        }
+
+        /**
+         * Create a new postal address entry with the given data.
+         *
+         * @param label label for the item, from the db not the display label
+         * @param protocol the type used
+         * @param data the starting data for the entry, may be null
+         * @param uri the uri for the entry if it already exists, may be null
+         * @param id the id for the entry if it already exists, 0 it it doesn't
+         * @return the new EditEntry
+         */
+        public static final EditEntry newImEntry(EditContactActivity activity,
+                String label, int protocol, String data, Uri uri, long id) {
+            EditEntry entry = new EditEntry(activity, label, protocol, data, uri, id);
+            entry.hint = activity.getString(R.string.ghostData_im);
+            entry.column = ContactMethods.DATA;
+            entry.contentDirectory = People.ContactMethods.CONTENT_DIRECTORY;
+            entry.kind = Contacts.KIND_IM;
+            entry.keyListener = INPUT_TEXT;
+            return entry;
+        }
+    }
+}
diff --git a/src/com/android/contacts/FastScrollView.java b/src/com/android/contacts/FastScrollView.java
new file mode 100644
index 0000000..f45e947
--- /dev/null
+++ b/src/com/android/contacts/FastScrollView.java
@@ -0,0 +1,450 @@
+/*
+ * Copyright (C) 2008 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.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup.OnHierarchyChangeListener;
+import android.widget.AbsListView;
+import android.widget.Adapter;
+import android.widget.BaseAdapter;
+import android.widget.FrameLayout;
+import android.widget.HeaderViewListAdapter;
+import android.widget.ListView;
+import android.widget.AbsListView.OnScrollListener;
+
+/**
+ * FastScrollView is meant for embedding {@link ListView}s that contain a large number of 
+ * items that can be indexed in some fashion. It displays a special scroll bar that allows jumping
+ * quickly to indexed sections of the list in touch-mode. Only one child can be added to this 
+ * view group and it must be a {@link ListView}, with an adapter that is derived from 
+ * {@link BaseAdapter}.
+ */
+public class FastScrollView extends FrameLayout 
+        implements OnScrollListener, OnHierarchyChangeListener {
+
+    private Drawable mCurrentThumb;
+    private Drawable mOverlayDrawable;
+
+    private int mThumbH;
+    private int mThumbW;
+    private int mThumbY;
+
+    private RectF mOverlayPos;
+    
+    // Hard coding these for now
+    private int mOverlaySize = 104;
+
+    private boolean mDragging;
+    private ListView mList;
+    private boolean mScrollCompleted;
+    private boolean mThumbVisible;
+    private int mVisibleItem;
+    private Paint mPaint;
+    private int mListOffset;
+    
+    private Object [] mSections;
+    private String mSectionText;
+    private boolean mDrawOverlay;
+    private ScrollFade mScrollFade;
+    
+    private Handler mHandler = new Handler();
+    
+    private BaseAdapter mListAdapter;
+
+    private boolean mChangedBounds;
+
+    interface SectionIndexer {
+        Object[] getSections();
+        
+        int getPositionForSection(int section);
+        
+        int getSectionForPosition(int position);
+    }
+    
+    public FastScrollView(Context context) {
+        super(context);
+
+        init(context);
+    }
+
+
+    public FastScrollView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        
+        init(context);
+    }
+
+    public FastScrollView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        init(context);
+    }
+
+    private void useThumbDrawable(Drawable drawable) {
+        mCurrentThumb = drawable;
+        mThumbW = 64; //mCurrentThumb.getIntrinsicWidth();
+        mThumbH = 52; //mCurrentThumb.getIntrinsicHeight();
+        mChangedBounds = true;
+    }
+
+    private void init(Context context) {
+        // Get both the scrollbar states drawables
+        final Resources res = context.getResources();
+        useThumbDrawable(res.getDrawable(
+                com.android.internal.R.drawable.scrollbar_handle_accelerated_anim2));
+        
+        mOverlayDrawable = res.getDrawable(R.drawable.dialog_full_dark);
+        
+        mScrollCompleted = true;
+        setWillNotDraw(false);
+        
+        // Need to know when the ListView is added
+        setOnHierarchyChangeListener(this);
+        
+        mOverlayPos = new RectF();
+        mScrollFade = new ScrollFade();
+        mPaint = new Paint();
+        mPaint.setAntiAlias(true);
+        mPaint.setTextAlign(Paint.Align.CENTER);
+        mPaint.setTextSize(mOverlaySize / 2);
+        mPaint.setColor(0xFFFFFFFF);
+        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
+    }
+    
+    private void removeThumb() {
+        
+        mThumbVisible = false;
+        // Draw one last time to remove thumb
+        invalidate();
+    }
+    
+    @Override
+    public void draw(Canvas canvas) {
+        super.draw(canvas);
+        
+        if (!mThumbVisible) {
+            // No need to draw the rest
+            return;
+        }
+
+        final int y = mThumbY;
+        final int viewWidth = getWidth();
+        final FastScrollView.ScrollFade scrollFade = mScrollFade;
+
+        int alpha = -1;
+        if (scrollFade.mStarted) {
+            alpha = scrollFade.getAlpha();
+            if (alpha < ScrollFade.ALPHA_MAX / 2) {
+                mCurrentThumb.setAlpha(alpha * 2);
+            }
+            int left = viewWidth - (mThumbW * alpha) / ScrollFade.ALPHA_MAX;
+            mCurrentThumb.setBounds(left, 0, viewWidth, mThumbH);
+            mChangedBounds = true;
+        }
+
+        canvas.translate(0, y);
+        mCurrentThumb.draw(canvas);
+        canvas.translate(0, -y);
+
+        // If user is dragging the scroll bar, draw the alphabet overlay
+        if (mDragging && mDrawOverlay) {
+            mOverlayDrawable.draw(canvas);
+            final Paint paint = mPaint;
+            float descent = paint.descent();
+            final RectF rectF = mOverlayPos;
+            canvas.drawText(mSectionText, (int) (rectF.left + rectF.right) / 2,
+                    (int) (rectF.bottom + rectF.top) / 2 + mOverlaySize / 4 - descent, paint);
+        } else if (alpha == 0) {
+            scrollFade.mStarted = false;
+            removeThumb();
+        } else {
+            invalidate(viewWidth - mThumbW, y, viewWidth, y + mThumbH);            
+        }
+    }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
+        if (mCurrentThumb != null) {
+            mCurrentThumb.setBounds(w - mThumbW, 0, w, mThumbH);
+        }
+        final RectF pos = mOverlayPos;
+        pos.left = (w - mOverlaySize) / 2;
+        pos.right = pos.left + mOverlaySize;
+        pos.top = h / 10; // 10% from top
+        pos.bottom = pos.top + mOverlaySize;
+        mOverlayDrawable.setBounds((int) pos.left, (int) pos.top,
+                (int) pos.right, (int) pos.bottom);
+    }
+    
+    public void onScrollStateChanged(AbsListView view, int scrollState) {
+    }
+    
+    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, 
+            int totalItemCount) {
+        
+        if (totalItemCount - visibleItemCount > 0 && !mDragging) {
+            mThumbY = ((getHeight() - mThumbH) * firstVisibleItem) / (totalItemCount - visibleItemCount);
+            if (mChangedBounds) {
+                final int viewWidth = getWidth();
+                mCurrentThumb.setBounds(viewWidth - mThumbW, 0, viewWidth, mThumbH);
+                mChangedBounds = false;
+            }
+        }
+        mScrollCompleted = true;
+        if (firstVisibleItem == mVisibleItem) {
+            return;
+        }
+        mVisibleItem = firstVisibleItem;
+        if (!mThumbVisible || mScrollFade.mStarted) {
+            mThumbVisible = true;
+            mCurrentThumb.setAlpha(ScrollFade.ALPHA_MAX);
+        }
+        mHandler.removeCallbacks(mScrollFade);
+        mScrollFade.mStarted = false;
+        if (!mDragging) {
+            mHandler.postDelayed(mScrollFade, 1500);
+        }
+    }
+
+    
+    private void getSections() {
+        Adapter adapter = mList.getAdapter();
+        if (adapter instanceof HeaderViewListAdapter) {
+            mListOffset = ((HeaderViewListAdapter)adapter).getHeadersCount();
+            adapter = ((HeaderViewListAdapter)adapter).getWrappedAdapter();
+        }
+        if (adapter instanceof SectionIndexer) {
+            mListAdapter = (BaseAdapter) adapter;
+            mSections = ((SectionIndexer) mListAdapter).getSections();
+        }
+    }
+    
+    public void onChildViewAdded(View parent, View child) {
+        if (child instanceof ListView) {
+            mList = (ListView)child;
+            
+            mList.setOnScrollListener(this);
+            getSections();
+        }
+    }
+
+    public void onChildViewRemoved(View parent, View child) {
+        if (child == mList) {
+            mList = null;
+            mListAdapter = null;
+            mSections = null;
+        }
+    }
+    
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        if (mThumbVisible && ev.getAction() == MotionEvent.ACTION_DOWN) {
+            if (ev.getX() > getWidth() - mThumbW && ev.getY() >= mThumbY &&
+                    ev.getY() <= mThumbY + mThumbH) {
+                mDragging = true;
+                return true;
+            }            
+        }
+        return false;
+    }
+
+    private void scrollTo(float position) {
+        int count = mList.getCount();
+        mScrollCompleted = false;
+        final Object[] sections = mSections;
+        int sectionIndex;
+        if (sections != null && sections.length > 1) {
+            final int nSections = sections.length;
+            int section = (int) (position * nSections);
+            if (section >= nSections) {
+                section = nSections - 1;
+            }
+            sectionIndex = section;
+            final SectionIndexer baseAdapter = (SectionIndexer) mListAdapter;
+            int index = baseAdapter.getPositionForSection(section);
+            
+            // Given the expected section and index, the following code will
+            // try to account for missing sections (no names starting with..)
+            // It will compute the scroll space of surrounding empty sections
+            // and interpolate the currently visible letter's range across the
+            // available space, so that there is always some list movement while
+            // the user moves the thumb.
+            int nextIndex = count;
+            int prevIndex = index;
+            int prevSection = section;
+            int nextSection = section + 1;
+            // Assume the next section is unique
+            if (section < nSections - 1) {
+                nextIndex = baseAdapter.getPositionForSection(section + 1);
+            }
+            
+            // Find the previous index if we're slicing the previous section
+            if (nextIndex == index) {
+                // Non-existent letter
+                while (section > 0) {
+                    section--;
+                     prevIndex = baseAdapter.getPositionForSection(section);
+                     if (prevIndex != index) {
+                         prevSection = section;
+                         sectionIndex = section;
+                         break;
+                     }
+                }
+            }
+            // Find the next index, in case the assumed next index is not
+            // unique. For instance, if there is no P, then request for P's 
+            // position actually returns Q's. So we need to look ahead to make
+            // sure that there is really a Q at Q's position. If not, move 
+            // further down...
+            int nextNextSection = nextSection + 1;
+            while (nextNextSection < nSections &&
+                    baseAdapter.getPositionForSection(nextNextSection) == nextIndex) {
+                nextNextSection++;
+                nextSection++;
+            }
+            // Compute the beginning and ending scroll range percentage of the
+            // currently visible letter. This could be equal to or greater than
+            // (1 / nSections). 
+            float fPrev = (float) prevSection / nSections;
+            float fNext = (float) nextSection / nSections;
+            index = prevIndex + (int) ((nextIndex - prevIndex) * (position - fPrev) 
+                    / (fNext - fPrev));
+            // Don't overflow
+            if (index > count - 1) index = count - 1;
+            
+            mList.setSelectionFromTop(index + mListOffset, 0);
+        } else {
+            int index = (int) (position * count);
+            mList.setSelectionFromTop(index + mListOffset, 0);
+            sectionIndex = -1;
+        }
+
+        if (sectionIndex >= 0) {
+            String text = mSectionText = sections[sectionIndex].toString();
+            mDrawOverlay = (text.length() != 1 || text.charAt(0) != ' ') &&
+                    sectionIndex < sections.length;
+        } else {
+            mDrawOverlay = false;
+        }
+    }
+
+    private void cancelFling() {
+        // Cancel the list fling
+        MotionEvent cancelFling = MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0, 0, 0);
+        mList.onTouchEvent(cancelFling);
+        cancelFling.recycle();
+    }
+    
+    @Override
+    public boolean onTouchEvent(MotionEvent me) {
+        if (me.getAction() == MotionEvent.ACTION_DOWN) {
+            if (me.getX() > getWidth() - mThumbW
+                    && me.getY() >= mThumbY 
+                    && me.getY() <= mThumbY + mThumbH) {
+                
+                mDragging = true;
+                if (mListAdapter == null && mList != null) {
+                    getSections();
+                }
+
+                cancelFling();
+                return true;
+            }
+        } else if (me.getAction() == MotionEvent.ACTION_UP) {
+            if (mDragging) {
+                mDragging = false;
+                final Handler handler = mHandler;
+                handler.removeCallbacks(mScrollFade);
+                handler.postDelayed(mScrollFade, 1000);
+                return true;
+            }
+        } else if (me.getAction() == MotionEvent.ACTION_MOVE) {
+            if (mDragging) {
+                final int viewHeight = getHeight();
+                mThumbY = (int) me.getY() - mThumbH + 10;
+                if (mThumbY < 0) {
+                    mThumbY = 0;
+                } else if (mThumbY + mThumbH > viewHeight) {
+                    mThumbY = viewHeight - mThumbH;
+                }
+                // If the previous scrollTo is still pending
+                if (mScrollCompleted) {
+                    scrollTo((float) mThumbY / (viewHeight - mThumbH));
+                }
+                return true;
+            }
+        }
+        
+        return super.onTouchEvent(me);
+    }
+    
+    public class ScrollFade implements Runnable {
+        
+        long mStartTime;
+        long mFadeDuration;
+        boolean mStarted;
+        static final int ALPHA_MAX = 255;
+        static final long FADE_DURATION = 200;
+        
+        void startFade() {
+            mFadeDuration = FADE_DURATION;
+            mStartTime = SystemClock.uptimeMillis();
+            mStarted = true;
+        }
+        
+        int getAlpha() {
+            if (!mStarted) {
+                return ALPHA_MAX;
+            }
+            int alpha;
+            long now = SystemClock.uptimeMillis();
+            if (now > mStartTime + mFadeDuration) {
+                alpha = 0;
+            } else {
+                alpha = (int) (ALPHA_MAX - ((now - mStartTime) * ALPHA_MAX) / mFadeDuration); 
+            }
+            return alpha;
+        }
+        
+        public void run() {
+            if (!mStarted) {
+                startFade();
+                invalidate();
+            }
+            
+            if (getAlpha() > 0) {
+                final int y = mThumbY;
+                final int viewWidth = getWidth();
+                invalidate(viewWidth - mThumbW, y, viewWidth, y + mThumbH);
+            } else {
+                mStarted = false;
+                removeThumb();
+            }
+        }
+    }
+}
diff --git a/src/com/android/contacts/RecentCallsListActivity.java b/src/com/android/contacts/RecentCallsListActivity.java
new file mode 100644
index 0000000..32ecd97
--- /dev/null
+++ b/src/com/android/contacts/RecentCallsListActivity.java
@@ -0,0 +1,790 @@
+/*
+ * Copyright (C) 2007 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.app.ListActivity;
+import android.content.ActivityNotFoundException;
+import android.content.AsyncQueryHandler;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.pim.DateUtils;
+import android.provider.CallLog.Calls;
+import android.provider.Contacts.People;
+import android.provider.Contacts.Phones;
+import android.provider.Contacts.Intents.Insert;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.widget.AdapterView;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.ResourceCursorAdapter;
+import android.widget.TextView;
+
+import com.android.internal.telephony.CallerInfo;
+import com.android.internal.telephony.ITelephony;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+
+/**
+ * Displays a list of call log entries.
+ */
+public class RecentCallsListActivity extends ListActivity 
+        implements View.OnCreateContextMenuListener {
+    private static final String TAG = "RecentCallsList";
+    
+    /** The projection to use when querying the call log table */
+    static final String[] CALL_LOG_PROJECTION = new String[] {
+            Calls._ID,
+            Calls.NUMBER,
+            Calls.DATE,
+            Calls.DURATION,
+            Calls.TYPE,
+            Calls.CACHED_NAME,
+            Calls.CACHED_NUMBER_TYPE,
+            Calls.CACHED_NUMBER_LABEL
+    };
+    
+    static final int ID_COLUMN_INDEX = 0;
+    static final int NUMBER_COLUMN_INDEX = 1;
+    static final int DATE_COLUMN_INDEX = 2;
+    static final int DURATION_COLUMN_INDEX = 3;
+    static final int CALL_TYPE_COLUMN_INDEX = 4;
+    static final int CALLER_NAME_COLUMN_INDEX = 5;
+    static final int CALLER_NUMBERTYPE_COLUMN_INDEX = 6;
+    static final int CALLER_NUMBERLABEL_COLUMN_INDEX = 7;
+
+    /** The projection to use when querying the phones table */
+    static final String[] PHONES_PROJECTION = new String[] {
+            Phones.PERSON_ID,
+            Phones.NAME,
+            Phones.TYPE,
+            Phones.LABEL,
+            Phones.NUMBER
+    };
+    
+    static final int PERSON_ID_COLUMN_INDEX = 0;
+    static final int NAME_COLUMN_INDEX = 1;
+    static final int PHONE_TYPE_COLUMN_INDEX = 2;
+    static final int LABEL_COLUMN_INDEX = 3;
+    static final int MATCHED_NUMBER_COLUMN_INDEX = 4;
+
+    private static final int MENU_ITEM_DELETE = 1;
+    private static final int MENU_ITEM_DELETE_ALL = 2;
+    private static final int MENU_ITEM_VIEW_CONTACTS = 3;
+    
+    private static final int QUERY_TOKEN = 53;
+    private static final int UPDATE_TOKEN = 54;
+
+    private RecentCallsAdapter mAdapter;
+    private QueryHandler mQueryHandler;
+    private String mVoiceMailNumber;
+    
+    private CharSequence[] mLabelArray;
+    
+    private Drawable mDrawableIncoming;
+    private Drawable mDrawableOutgoing;
+    private Drawable mDrawableMissed;    
+    
+    private static final class ContactInfo {
+        public long personId;
+        public String name;
+        public int type;
+        public String label;
+        public String number;
+
+        public static ContactInfo EMPTY = new ContactInfo();
+    }
+
+    public static final class RecentCallsListItemViews {
+        TextView line1View;
+        TextView line2View;
+        TextView durationView;
+        TextView dateView;
+        ImageView iconView;
+    }    
+    
+    private static final class CallerInfoQuery {
+        String number;
+        int position;
+        String name;
+        int numberType;
+        String numberLabel;
+    }
+
+    /** Adapter class to fill in data for the Call Log */
+    private final class RecentCallsAdapter extends ResourceCursorAdapter 
+            implements Runnable, ViewTreeObserver.OnPreDrawListener {
+        HashMap<String,ContactInfo> mContactInfo;
+        private LinkedList<CallerInfoQuery> mRequests;
+        private boolean mDone;
+        private boolean mLoading = true;
+        ViewTreeObserver.OnPreDrawListener mPreDrawListener;
+        private static final int REDRAW = 1;
+        private static final int START_THREAD = 2;
+        private boolean mFirst;
+        
+        public boolean onPreDraw() {
+            if (mFirst) {
+                mHandler.sendEmptyMessageDelayed(START_THREAD, 1000);
+                mFirst = false;
+            }
+            return true;            
+        }
+        
+        private Handler mHandler = new Handler() {
+            @Override
+            public void handleMessage(Message msg) {
+                switch (msg.what) {
+                    case REDRAW:
+                        notifyDataSetChanged();
+                        break;
+                    case START_THREAD:
+                        startRequestProcessing();
+                        break;
+                }
+            }
+        };
+        
+        public RecentCallsAdapter() {
+            super(RecentCallsListActivity.this, R.layout.recent_calls_list_item, null);
+
+            mContactInfo = new HashMap<String,ContactInfo>();
+            mRequests = new LinkedList<CallerInfoQuery>();
+            mPreDrawListener = null;
+        }
+
+        void setLoading(boolean loading) {
+            mLoading = loading;
+        }
+        
+        @Override
+        public boolean isEmpty() {
+            if (mLoading) {
+                // We don't want the empty state to show when loading.
+                return false;
+            } else {
+                return super.isEmpty();
+            }
+        }
+
+        public ContactInfo getContactInfo(String number) {
+            return mContactInfo.get(number);
+        }
+
+        public void startRequestProcessing() {
+            mDone = false;
+            Thread callerIdThread = new Thread(this);
+            callerIdThread.setPriority(Thread.MIN_PRIORITY);
+            callerIdThread.start();
+        }
+
+        public void stopRequestProcessing() {
+            mDone = true;
+        }
+
+        public void clearCache() {
+            synchronized (mContactInfo) {
+                mContactInfo.clear();
+            }
+        }
+
+        private void updateCallLog(CallerInfoQuery ciq, ContactInfo ci) {
+            // Check if they are different. If not, don't update.
+            if (TextUtils.equals(ciq.name, ci.name) 
+                    && TextUtils.equals(ciq.numberLabel, ci.label)
+                    && ciq.numberType == ci.type) {
+                return;
+            }
+            ContentValues values = new ContentValues(3);
+            values.put(Calls.CACHED_NAME, ci.name);
+            values.put(Calls.CACHED_NUMBER_TYPE, ci.type);
+            values.put(Calls.CACHED_NUMBER_LABEL, ci.label);
+            RecentCallsListActivity.this.getContentResolver().update(
+                    Calls.CONTENT_URI, 
+                    values, Calls.NUMBER + "='" + ciq.number + "'", null);
+        }
+        
+        private void enqueueRequest(String number, int position,
+                String name, int numberType, String numberLabel) {
+            CallerInfoQuery ciq = new CallerInfoQuery();
+            ciq.number = number;
+            ciq.position = position;
+            ciq.name = name;
+            ciq.numberType = numberType;
+            ciq.numberLabel = numberLabel;
+            synchronized (mRequests) {
+                mRequests.add(ciq);
+                mRequests.notifyAll();
+            }
+        }
+        
+        private void queryContactInfo(CallerInfoQuery ciq) {
+            // First check if there was a prior request for the same number
+            // that was already satisfied
+            ContactInfo info = mContactInfo.get(ciq.number);
+            if (info != null && info != ContactInfo.EMPTY) {
+                synchronized (mRequests) {
+                    if (mRequests.isEmpty()) {
+                        mHandler.sendEmptyMessage(REDRAW);
+                    }
+                }
+            } else {
+                Cursor phonesCursor = 
+                    RecentCallsListActivity.this.getContentResolver().query(
+                            Uri.withAppendedPath(Phones.CONTENT_FILTER_URL, 
+                                    ciq.number),
+                    PHONES_PROJECTION, null, null, null);
+                if (phonesCursor != null) {
+                    if (phonesCursor.moveToFirst()) {
+                        info = new ContactInfo();
+                        info.personId = phonesCursor.getLong(PERSON_ID_COLUMN_INDEX);
+                        info.name = phonesCursor.getString(NAME_COLUMN_INDEX);
+                        info.type = phonesCursor.getInt(PHONE_TYPE_COLUMN_INDEX);
+                        info.label = phonesCursor.getString(LABEL_COLUMN_INDEX);
+                        info.number = phonesCursor.getString(MATCHED_NUMBER_COLUMN_INDEX);
+                        
+                        mContactInfo.put(ciq.number, info);
+                        // Inform list to update this item, if in view
+                        synchronized (mRequests) {
+                            if (mRequests.isEmpty()) {
+                                mHandler.sendEmptyMessage(REDRAW);
+                            }
+                        }
+                    }
+                    phonesCursor.close();
+                }
+            }
+            if (info != null) {
+                updateCallLog(ciq, info);
+            }
+        }
+
+        /*
+         * Handles requests for contact name and number type
+         * @see java.lang.Runnable#run()
+         */
+        public void run() {
+            while (!mDone) {
+                CallerInfoQuery ciq = null;
+                synchronized (mRequests) {
+                    if (!mRequests.isEmpty()) {
+                        ciq = mRequests.removeFirst();
+                    } else {
+                        try {
+                            mRequests.wait(1000);
+                        } catch (InterruptedException ie) {
+                            // Ignore and continue processing requests
+                        }                        
+                    }
+                }
+                if (ciq != null) {
+                    queryContactInfo(ciq);
+                }
+            }
+        }
+        
+        @Override
+        public View newView(Context context, Cursor cursor, ViewGroup parent) {
+            View view = super.newView(context, cursor, parent);
+            
+            // Get the views to bind to
+            RecentCallsListItemViews views = new RecentCallsListItemViews();
+            views.line1View = (TextView) view.findViewById(R.id.line1);
+            views.line2View = (TextView) view.findViewById(R.id.line2);
+            views.durationView = (TextView) view.findViewById(R.id.duration);
+            views.dateView = (TextView) view.findViewById(R.id.date);
+            views.iconView = (ImageView) view.findViewById(R.id.call_type_icon);
+
+            view.setTag(views);
+
+            return view;
+        }
+
+        
+        @Override
+        public void bindView(View view, Context context, Cursor c) {
+            final RecentCallsListItemViews views = (RecentCallsListItemViews) view.getTag();
+
+            String number = c.getString(NUMBER_COLUMN_INDEX);
+            String callerName = c.getString(CALLER_NAME_COLUMN_INDEX);
+            int callerNumberType = c.getInt(CALLER_NUMBERTYPE_COLUMN_INDEX);
+            String callerNumberLabel = c.getString(CALLER_NUMBERLABEL_COLUMN_INDEX);
+            
+            // Lookup contacts with this number
+            ContactInfo info = mContactInfo.get(number);
+            if (info == null) {
+                // Mark it as empty and queue up a request to find the name
+                // The db request should happen on a non-UI thread
+                info = ContactInfo.EMPTY;
+                mContactInfo.put(number, info);
+                enqueueRequest(number, c.getPosition(),
+                        callerName, callerNumberType, callerNumberLabel);
+            } else if (info != ContactInfo.EMPTY) { // Has been queried
+                // Check if any data is different from the data cached in the
+                // calls db. If so, queue the request so that we can update
+                // the calls db.
+                if (!TextUtils.equals(info.name, callerName) 
+                        || info.type != callerNumberType
+                        || !TextUtils.equals(info.label, callerNumberLabel)) {
+                    // Something is amiss, so sync up.
+                    enqueueRequest(number, c.getPosition(), 
+                            callerName, callerNumberType, callerNumberLabel);
+                }
+            }
+
+            String name = info.name;
+            int ntype = info.type;
+            String label = info.label;
+            // If there's no name cached in our hashmap, but there's one in the
+            // calls db, use the one in the calls db. Otherwise the name in our
+            // hashmap is more recent, so it has precedence.
+            if (TextUtils.isEmpty(name) && !TextUtils.isEmpty(callerName)) {
+                name = callerName;
+                ntype = callerNumberType;
+                label = callerNumberLabel;
+            }
+            // Set the text lines
+            if (!TextUtils.isEmpty(name)) {
+                views.line1View.setText(name);
+                CharSequence numberLabel = Phones.getDisplayLabel(context, ntype, label, 
+                        mLabelArray);
+                if (!TextUtils.isEmpty(numberLabel)) {
+                    views.line2View.setText(numberLabel);
+                } else {
+                    views.line2View.setText(number);
+                }
+
+                // Set the presence icon
+/*
+                int serverStatus;
+                if (!c.isNull(SERVER_STATUS_COLUMN_INDEX)) {
+                    serverStatus = c.getInt(SERVER_STATUS_COLUMN_INDEX);
+                    views.line2View.setCompoundDrawablesWithIntrinsicBounds(
+                            getResources().getDrawable(
+                                    Presence.getPresenceIconResourceId(serverStatus)),
+                            null, null, null);
+                } else {
+                    views.line2View.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
+                }
+*/
+            } else {
+                if (number.equals(CallerInfo.UNKNOWN_NUMBER)) {
+                    number = getString(R.string.unknown);
+                } else if (number.equals(CallerInfo.PRIVATE_NUMBER)) {
+                    number = getString(R.string.private_num);
+                } else if (number.equals(mVoiceMailNumber)) {
+                    number = getString(R.string.voicemail);
+                }
+
+                views.line1View.setText(number);
+                views.line2View.setText(null);
+
+                // Clear the presence icon
+//                views.line2View.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
+            }
+
+            int type = c.getInt(CALL_TYPE_COLUMN_INDEX);
+            long date = c.getLong(DATE_COLUMN_INDEX);
+
+            // Set the duration
+            if (type == Calls.MISSED_TYPE) {
+                views.durationView.setVisibility(View.GONE);
+            } else {
+                views.durationView.setVisibility(View.VISIBLE);
+                views.durationView.setText(DateUtils.formatElapsedTime(c.getLong(DURATION_COLUMN_INDEX)));
+            }
+
+            // Set the time and date
+            views.dateView.setText(DateUtils.getRelativeTimeSpanString(date));
+
+            // Set the icon
+            switch (type) {
+                case Calls.INCOMING_TYPE:
+                    views.iconView.setImageDrawable(mDrawableIncoming);
+                    break;
+
+                case Calls.OUTGOING_TYPE:
+                    views.iconView.setImageDrawable(mDrawableOutgoing);
+                    break;
+
+                case Calls.MISSED_TYPE:
+                    views.iconView.setImageDrawable(mDrawableMissed);
+                    break;
+            }
+            // Listen for the first draw 
+            if (mPreDrawListener == null) {
+                mFirst = true;
+                mPreDrawListener = this;
+                view.getViewTreeObserver().addOnPreDrawListener(this);
+            }
+        }
+    }
+    
+    private final class QueryHandler extends AsyncQueryHandler {
+        public QueryHandler(Context context) {
+            super(context.getContentResolver());
+        }
+
+        @Override
+        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
+            if (!isFinishing()) {
+                mAdapter.setLoading(false);
+                mAdapter.changeCursor(cursor);    
+            } else {
+                cursor.close();
+            }
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle state) {
+        super.onCreate(state);
+
+        setContentView(R.layout.recent_calls);
+        
+        mDrawableIncoming = getResources().getDrawable(android.R.drawable.sym_call_incoming);
+        mDrawableOutgoing = getResources().getDrawable(android.R.drawable.sym_call_outgoing);
+        mDrawableMissed = getResources().getDrawable(android.R.drawable.sym_call_missed);
+        mLabelArray = getResources().getTextArray(com.android.internal.R.array.phoneTypes);
+        
+        // Typing here goes to the dialer
+        setDefaultKeyMode(DEFAULT_KEYS_DIALER);
+
+        mAdapter = new RecentCallsAdapter();
+        getListView().setOnCreateContextMenuListener(this);
+        setListAdapter(mAdapter);
+
+        mVoiceMailNumber = ((TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE))
+                .getVoiceMailNumber();
+        mQueryHandler = new QueryHandler(this);
+    }
+
+    @Override
+    protected void onResume() {
+        // The adapter caches looked up numbers, clear it so they will get
+        // looked up again.
+        if (mAdapter != null) {
+            mAdapter.clearCache();
+        }
+
+        startQuery();
+        resetNewCallsFlag();
+        
+        super.onResume();
+        try {
+            ITelephony.Stub.asInterface(ServiceManager.getService("phone"))
+                    .cancelMissedCallsNotification();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to clear missed calls notification due to remote excetpion");
+        }
+        mAdapter.mPreDrawListener = null; // Let it restart the thread after next draw
+    }
+    
+    @Override
+    protected void onPause() {
+        super.onPause();
+        
+        // Kill the requests thread
+        mAdapter.stopRequestProcessing();
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        Cursor cursor = mAdapter.getCursor();
+        if (cursor != null && !cursor.isClosed()) {
+            cursor.close();
+        }
+    }
+
+    private void resetNewCallsFlag() {
+        // Mark all "new" missed calls as not new anymore
+        StringBuilder where = new StringBuilder("type=");
+        where.append(Calls.MISSED_TYPE);
+        where.append(" AND new=1");
+
+        ContentValues values = new ContentValues(1);
+        values.put(Calls.NEW, "0");
+        mQueryHandler.startUpdate(UPDATE_TOKEN, null, Calls.CONTENT_URI, 
+                values, where.toString(), null);
+    }
+
+    private void startQuery() {
+        mAdapter.setLoading(true);
+        
+        // Cancel any pending queries
+        mQueryHandler.cancelOperation(QUERY_TOKEN);
+        mQueryHandler.startQuery(QUERY_TOKEN, null, Calls.CONTENT_URI, 
+                CALL_LOG_PROJECTION, null, null, Calls.DEFAULT_SORT_ORDER);
+    }
+    
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        menu.add(0, MENU_ITEM_DELETE_ALL, 0, R.string.recentCalls_deleteAll)
+                .setIcon(android.R.drawable.ic_menu_close_clear_cancel);
+        return true;
+    }
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfoIn) {
+        AdapterView.AdapterContextMenuInfo menuInfo;
+        try {
+             menuInfo = (AdapterView.AdapterContextMenuInfo) menuInfoIn;
+        } catch (ClassCastException e) {
+            Log.e(TAG, "bad menuInfoIn", e);
+            return;
+        }
+
+        Cursor cursor = (Cursor) mAdapter.getItem(menuInfo.position);
+
+        String number = cursor.getString(NUMBER_COLUMN_INDEX);
+        Uri numberUri = null;
+        boolean isVoicemail = false;
+        if (number.equals(CallerInfo.UNKNOWN_NUMBER)) {
+            number = getString(R.string.unknown);
+        } else if (number.equals(CallerInfo.PRIVATE_NUMBER)) {
+            number = getString(R.string.private_num);
+        } else if (number.equals(mVoiceMailNumber)) {
+            number = getString(R.string.voicemail);
+            numberUri = Uri.parse("voicemail:x");
+            isVoicemail = true;
+        } else {
+            numberUri = Uri.fromParts("tel", number, null);
+        }
+
+        ContactInfo info = mAdapter.getContactInfo(number);
+        boolean contactInfoPresent = (info != null && info != ContactInfo.EMPTY); 
+        if (contactInfoPresent) {
+            menu.setHeaderTitle(info.name);
+        } else {
+            menu.setHeaderTitle(number);
+        }
+
+        if (numberUri != null) {
+            Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED, numberUri);
+            menu.add(0, 0, 0, getResources().getString(R.string.recentCalls_callNumber, number))
+                    .setIntent(intent);
+        }
+
+        if (contactInfoPresent) {
+            menu.add(0, 0, 0, R.string.menu_viewContact)
+                    .setIntent(new Intent(Intent.ACTION_VIEW,
+                            ContentUris.withAppendedId(People.CONTENT_URI, info.personId)));
+        }
+
+        if (numberUri != null && !isVoicemail) {
+            menu.add(0, 0, 0, R.string.recentCalls_editNumberBeforeCall)
+                    .setIntent(new Intent(Intent.ACTION_DIAL, numberUri));
+            menu.add(0, 0, 0, R.string.menu_sendTextMessage)
+                    .setIntent(new Intent(Intent.ACTION_SENDTO,
+                            Uri.fromParts("sms", number, null)));
+        }
+        if (!contactInfoPresent && numberUri != null && !isVoicemail) {
+            Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
+            intent.setType(People.CONTENT_ITEM_TYPE);
+            intent.putExtra(Insert.PHONE, number);
+            menu.add(0, 0, 0, R.string.recentCalls_addToContact)
+                    .setIntent(intent);
+        }
+        menu.add(0, MENU_ITEM_DELETE, 0, R.string.recentCalls_removeFromRecentList);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case MENU_ITEM_DELETE_ALL: {
+                getContentResolver().delete(Calls.CONTENT_URI, null, null);
+                //TODO The change notification should do this automatically, but it isn't working
+                // right now. Remove this when the change notification is working properly. 
+                startQuery();
+                return true;
+            }
+
+            case MENU_ITEM_VIEW_CONTACTS: {
+                Intent intent = new Intent(Intent.ACTION_VIEW, People.CONTENT_URI);
+                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                startActivity(intent);
+                return true;
+            }
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        // Convert the menu info to the proper type
+        AdapterView.AdapterContextMenuInfo menuInfo;
+        try {
+             menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
+        } catch (ClassCastException e) {
+            Log.e(TAG, "bad menuInfoIn", e);
+            return false;
+        }
+
+        switch (item.getItemId()) {
+            case MENU_ITEM_DELETE: {
+                Cursor cursor = mAdapter.getCursor();
+                if (cursor != null) {
+                    cursor.moveToPosition(menuInfo.position);
+                    cursor.deleteRow();
+                }
+                return true;
+            }
+        }
+        return super.onContextItemSelected(item);
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_CALL: {
+                long callPressDiff = SystemClock.uptimeMillis() - event.getDownTime();
+                if (callPressDiff >= ViewConfiguration.getLongPressTimeout()) {
+                    // Launch voice dialer
+                    Intent intent = new Intent(Intent.ACTION_VOICE_COMMAND);
+                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                    try {
+                        startActivity(intent);
+                    } catch (ActivityNotFoundException e) {
+                    }
+                    return true;
+                }
+            }
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+
+    @Override
+    public boolean onKeyUp(int keyCode, KeyEvent event) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_CALL:
+                try {
+                    ITelephony phone = ITelephony.Stub.asInterface(
+                            ServiceManager.checkService("phone"));
+                    if (phone != null && !phone.isIdle()) {
+                        // Let the super class handle it
+                        break;
+                    }
+                } catch (RemoteException re) {
+                    // Fall through and try to call the contact
+                }
+                
+                callEntry(getListView().getSelectedItemPosition());
+                return true;
+        }
+        return super.onKeyUp(keyCode, event);
+    }
+    
+    /*
+     * Get the number from the Contacts, if available, since sometimes
+     * the number provided by caller id may not be formatted properly
+     * depending on the carrier (roaming) in use at the time of the 
+     * incoming call.
+     * Logic : If the caller-id number starts with a "+", use it
+     *         Else if the number in the contacts starts with a "+", use that one
+     *         Else if the number in the contacts is longer, use that one
+     */
+    private String getBetterNumberFromContacts(String number) {
+        String matchingNumber = null;
+        // Look in the cache first. If it's not found then query the Phones db
+        ContactInfo ci = mAdapter.mContactInfo.get(number);
+        if (ci != null && ci != ContactInfo.EMPTY) {
+            matchingNumber = ci.number;
+        } else {
+            try {
+                Cursor phonesCursor = 
+                    RecentCallsListActivity.this.getContentResolver().query(
+                            Uri.withAppendedPath(Phones.CONTENT_FILTER_URL, 
+                                    number),
+                    PHONES_PROJECTION, null, null, null);
+                if (phonesCursor != null) {
+                    if (phonesCursor.moveToFirst()) {
+                        matchingNumber = phonesCursor.getString(MATCHED_NUMBER_COLUMN_INDEX);
+                    }
+                    phonesCursor.close();
+                }
+            } catch (Exception e) {
+                // Use the number from the call log
+            }
+        }
+        if (!TextUtils.isEmpty(matchingNumber) && 
+                (matchingNumber.startsWith("+") 
+                        || matchingNumber.length() > number.length())) {
+            number = matchingNumber;
+        }
+        return number;
+    }
+    
+    private void callEntry(int position) {
+        if (position < 0) {
+            // In touch mode you may often not have something selected, so
+            // just call the first entry to make sure that [send] [send] calls the
+            // most recent entry.
+            position = 0;
+        }
+        final Cursor cursor = mAdapter.getCursor();
+        if (cursor != null && cursor.moveToPosition(position)) {
+            String number = cursor.getString(NUMBER_COLUMN_INDEX);
+            if (TextUtils.isEmpty(number)
+                    || number.equals(CallerInfo.UNKNOWN_NUMBER)
+                    || number.equals(CallerInfo.PRIVATE_NUMBER)) {
+                // This number can't be called, do nothing
+                return;
+            }
+
+            int callType = cursor.getInt(CALL_TYPE_COLUMN_INDEX);
+            if (!number.startsWith("+") && 
+                    (callType == Calls.INCOMING_TYPE 
+                            || callType == Calls.MISSED_TYPE)) {
+                // If the caller-id matches a contact with a better qualified number, use it
+                number = getBetterNumberFromContacts(number);
+            }
+            Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
+                    Uri.fromParts("tel", number, null));
+            intent.setFlags(
+                    Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+            startActivity(intent);
+        }
+    }
+
+    @Override
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+        callEntry(position);
+    }
+}
diff --git a/src/com/android/contacts/SpecialCharSequenceMgr.java b/src/com/android/contacts/SpecialCharSequenceMgr.java
new file mode 100644
index 0000000..e23d460
--- /dev/null
+++ b/src/com/android/contacts/SpecialCharSequenceMgr.java
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2006 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.telephony.ITelephony;
+
+import android.app.AlertDialog;
+import android.app.KeyguardManager;
+import android.app.ProgressDialog;
+import android.content.AsyncQueryHandler;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.provider.Telephony.Intents;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+import android.view.WindowManager;
+import android.widget.EditText;
+import android.widget.Toast;
+
+/**
+ * Helper class to listen for some magic character sequences
+ * that are handled specially by the dialer.
+ */
+public class SpecialCharSequenceMgr {
+    private static final String TAG = "SpecialCharSequenceMgr";
+    private static final String MMI_IMEI_DISPLAY = "*#06#";
+
+    /** This class is never instantiated. */
+    private SpecialCharSequenceMgr() {
+    }
+
+    static boolean handleChars(Context context, String input, EditText textField) {
+        return handleChars(context, input, false, textField);
+    }
+
+    static boolean handleChars(Context context, String input) {
+        return handleChars(context, input, false, null);
+    }
+
+    static boolean handleChars(Context context, String input, boolean useSystemWindow,
+            EditText textField) {
+
+        //get rid of the separators so that the string gets parsed correctly
+        String dialString = PhoneNumberUtils.stripSeparators(input);
+
+        if (handleIMEIDisplay(context, dialString, useSystemWindow)
+                || handlePinEntry(context, dialString)
+                || handleAdnEntry(context, dialString, textField)
+                || handleSecretCode(context, dialString)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Handles secret codes to launch arbitrary activities in the form of *#*#<code>#*#*.
+     * If a secret code is encountered an Intent is started with the android_secret_code://<code>
+     * URI.
+     *
+     * @param context the context to use
+     * @param input the text to check for a secret code in
+     * @return true if a secret code was encountered
+     */
+    static boolean handleSecretCode(Context context, String input) {
+        // Secret codes are in the form *#*#<code>#*#*
+        int len = input.length();
+        if (len > 8 && input.startsWith("*#*#") && input.endsWith("#*#*")) {
+            Intent intent = new Intent(Intents.SECRET_CODE_ACTION,
+                    Uri.parse("android_secret_code://" + input.substring(4, len - 4)));
+            context.sendBroadcast(intent);
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Handle ADN requests by filling in the SIM contact number into the requested
+     * EditText.
+     *
+     * This code works alongside the Asynchronous query handler {@link QueryHandler}
+     * and query cancel handler implemented in {@link SimContactQueryCookie}.
+     */
+    static boolean handleAdnEntry(Context context, String input, EditText textField) {
+        /* ADN entries are of the form "N(N)(N)#" */
+
+        // if the phone is keyguard-restricted, then just ignore this
+        // input.  We want to make sure that sim card contacts are NOT
+        // exposed unless the phone is unlocked, and this code can be
+        // accessed from the emergency dialer.
+        KeyguardManager keyguardManager =
+                (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
+        if (keyguardManager.inKeyguardRestrictedInputMode()) {
+            return false;
+        }
+
+        int len = input.length();
+        if ((len > 1) && (len < 5) && (input.endsWith("#"))) {
+            try {
+                // get the ordinal number of the sim contact
+                int index = Integer.parseInt(input.substring(0, len-1));
+
+                // The original code that navigated to a SIM Contacts list view did not
+                // highlight the requested contact correctly, a requirement for PTCRB
+                // certification.  This behaviour is consistent with the UI paradigm
+                // for touch-enabled lists, so it does not make sense to try to work
+                // around it.  Instead we fill in the the requested phone number into
+                // the dialer text field.
+
+                // create the async query handler
+                QueryHandler handler = new QueryHandler (context.getContentResolver());
+
+                // create the cookie object
+                SimContactQueryCookie sc = new SimContactQueryCookie(index - 1, handler,
+                        ADN_QUERY_TOKEN);
+
+                // setup the cookie fields
+                sc.contactNum = index - 1;
+                sc.setTextField(textField);
+
+                // create the progress dialog
+                sc.progressDialog = new ProgressDialog(context);
+                sc.progressDialog.setTitle(R.string.simContacts_title);
+                sc.progressDialog.setMessage(context.getText(R.string.simContacts_emptyLoading));
+                sc.progressDialog.setIndeterminate(true);
+                sc.progressDialog.setCancelable(true);
+                sc.progressDialog.setOnCancelListener(sc);
+                sc.progressDialog.getWindow().addFlags(
+                        WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
+
+                // display the progress dialog
+                sc.progressDialog.show();
+
+                // run the query.
+                handler.startQuery(ADN_QUERY_TOKEN, sc, Uri.parse("content://sim/adn"),
+                        new String[]{ADN_PHONE_NUMBER_COLUMN_NAME}, null, null, null);
+                return true;
+            } catch (NumberFormatException ex) {
+                // Ignore
+            }
+        }
+        return false;
+    }
+
+    static boolean handlePinEntry(Context context, String input) {
+        if ((input.startsWith("**04") || input.startsWith("**05")) && input.endsWith("#")) {
+            try {
+                return ITelephony.Stub.asInterface(ServiceManager.getService("phone"))
+                        .handlePinMmi(input);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to handlePinMmi due to remote exception");
+                return false;
+            }
+        }
+        return false;
+    }
+
+    static boolean handleIMEIDisplay(Context context, String input, boolean useSystemWindow) {
+        if (input.equals(MMI_IMEI_DISPLAY)) {
+            showIMEIPanel(context, useSystemWindow);
+            return true;
+        }
+
+        return false;
+    }
+
+    static void showIMEIPanel(Context context, boolean useSystemWindow) {
+        String imeiStr = ((TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE))
+                .getDeviceId();
+
+        AlertDialog alert = new AlertDialog.Builder(context)
+                .setTitle(R.string.imei)
+                .setMessage(imeiStr)
+                .setPositiveButton(R.string.ok, null)
+                .setCancelable(false)
+                .show();
+        alert.getWindow().setType(WindowManager.LayoutParams.TYPE_PRIORITY_PHONE);
+    }
+
+    /*******
+     * This code is used to handle SIM Contact queries
+     *******/
+    private static final String ADN_PHONE_NUMBER_COLUMN_NAME = "number";
+    private static final String ADN_NAME_COLUMN_NAME = "name";
+    private static final int ADN_QUERY_TOKEN = -1;
+
+    /**
+     * Cookie object that contains everything we need to communicate to the
+     * handler's onQuery Complete, as well as what we need in order to cancel
+     * the query (if requested).
+     *
+     * Note, access to the textField field is going to be synchronized, because
+     * the user can request a cancel at any time through the UI.
+     */
+    private static class SimContactQueryCookie implements DialogInterface.OnCancelListener{
+        public ProgressDialog progressDialog;
+        public int contactNum;
+
+        // Used to identify the query request.
+        private int mToken;
+        private QueryHandler mHandler;
+
+        // The text field we're going to update
+        private EditText textField;
+
+        public SimContactQueryCookie(int number, QueryHandler handler, int token) {
+            contactNum = number;
+            mHandler = handler;
+            mToken = token;
+        }
+
+        /**
+         * Synchronized getter for the EditText.
+         */
+        public synchronized EditText getTextField() {
+            return textField;
+        }
+
+        /**
+         * Synchronized setter for the EditText.
+         */
+        public synchronized void setTextField(EditText text) {
+            textField = text;
+        }
+
+        /**
+         * Cancel the ADN query by stopping the operation and signaling
+         * the cookie that a cancel request is made.
+         */
+        public synchronized void onCancel(DialogInterface dialog) {
+            // close the progress dialog
+            if (progressDialog != null) {
+                progressDialog.dismiss();
+            }
+
+            // setting the textfield to null ensures that the UI does NOT get
+            // updated.
+            textField = null;
+
+            // Cancel the operation if possible.
+            mHandler.cancelOperation(mToken);
+        }
+    }
+
+    /**
+     * Asynchronous query handler that services requests to look up ADNs
+     *
+     * Queries originate from {@link handleAdnEntry}.
+     */
+    private static class QueryHandler extends AsyncQueryHandler {
+
+        public QueryHandler(ContentResolver cr) {
+            super(cr);
+        }
+
+        /**
+         * Override basic onQueryComplete to fill in the textfield when
+         * we're handed the ADN cursor.
+         */
+        @Override
+        protected void onQueryComplete(int token, Object cookie, Cursor c) {
+            SimContactQueryCookie sc = (SimContactQueryCookie) cookie;
+
+            // close the progress dialog.
+            sc.progressDialog.dismiss();
+
+            // get the EditText to update or see if the request was cancelled.
+            EditText text = sc.getTextField();
+
+            // if the textview is valid, and the cursor is valid and postionable
+            // on the Nth number, then we update the text field and display a
+            // toast indicating the caller name.
+            if ((c != null) && (text != null) && (c.moveToPosition(sc.contactNum))) {
+                String name = c.getString(c.getColumnIndexOrThrow(ADN_NAME_COLUMN_NAME));
+                String number = c.getString(c.getColumnIndexOrThrow(ADN_PHONE_NUMBER_COLUMN_NAME));
+
+                // fill the text in.
+                text.getText().replace(0, 0, number);
+
+                // display the name as a toast
+                Context context = sc.progressDialog.getContext();
+                name = context.getString(R.string.menu_callNumber, name);
+                Toast.makeText(context, name, Toast.LENGTH_SHORT)
+                    .show();
+            }
+        }
+    }
+}
diff --git a/src/com/android/contacts/TwelveKeyDialer.java b/src/com/android/contacts/TwelveKeyDialer.java
new file mode 100644
index 0000000..caa77a1
--- /dev/null
+++ b/src/com/android/contacts/TwelveKeyDialer.java
@@ -0,0 +1,595 @@
+/*
+ * Copyright (C) 2007 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.app.Activity;
+import android.content.ActivityNotFoundException;
+
+import android.content.Intent;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.graphics.drawable.Drawable;
+import android.media.AudioManager;
+import android.media.ToneGenerator;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.provider.Contacts.People;
+import android.provider.Contacts.Phones;
+import android.provider.Contacts.PhonesColumns;
+import android.provider.Contacts.Intents.Insert;
+import android.telephony.PhoneNumberFormattingTextWatcher;
+import android.telephony.PhoneNumberUtils;
+import android.text.Editable;
+import android.text.Selection;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.text.method.DialerKeyListener;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.widget.EditText;
+
+/**
+ * Dialer activity that displays the typical twelve key interface.
+ */
+public class TwelveKeyDialer extends Activity implements View.OnClickListener,
+        View.OnLongClickListener, View.OnKeyListener, TextWatcher {
+
+    private static final String TAG = "TwelveKeyDialer";
+    
+    private static final int STOP_TONE = 1;
+
+    /** The length of DTMF tones in milliseconds */
+    private static final int TONE_LENGTH_MS = 150;
+    
+    /** The DTMF tone volume relative to other sounds in the stream */
+    private static final int TONE_RELATIVE_VOLUME = 50;
+
+    private EditText mDigits;
+    private View mDelete;
+    private MenuItem mAddToContactMenuItem;
+    private ToneGenerator mToneGenerator;
+    private Object mToneGeneratorLock = new Object();
+    private Drawable mDigitsBackground;
+    private Drawable mDigitsEmptyBackground;
+    private Drawable mDeleteBackground;
+    private Drawable mDeleteEmptyBackground;
+    
+    // determines if we want to playback local DTMF tones.
+    private boolean mDTMFToneEnabled;
+    
+    /** Identifier for the "Add Call" intent extra. */
+    static final String ADD_CALL_MODE_KEY = "add_call_mode";
+    /** Indicates if we are opening this dialer to add a call from the InCallScreen. */
+    private boolean mIsAddCallMode;
+
+    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+        // Do nothing
+    }
+
+    public void onTextChanged(CharSequence input, int start, int before, int changeCount) {
+        // Do nothing
+        // DTMF Tones do not need to be played here any longer - 
+        // the DTMF dialer handles that functionality now.
+    }
+
+    public void afterTextChanged(Editable input) {
+        if (SpecialCharSequenceMgr.handleChars(this, input.toString(), mDigits)) {
+            // A special sequence was entered, clear the digits
+            mDigits.getText().clear();
+        }
+
+        // Set the proper background for the dial input area
+        if (mDigits.length() != 0) {
+            mDelete.setBackgroundDrawable(mDeleteBackground);
+            mDigits.setBackgroundDrawable(mDigitsBackground);
+            mDigits.setCompoundDrawablesWithIntrinsicBounds(
+                    getResources().getDrawable(R.drawable.ic_dial_number), null, null, null);
+        } else {
+            mDelete.setBackgroundDrawable(mDeleteEmptyBackground);
+            mDigits.setBackgroundDrawable(mDigitsEmptyBackground);
+            mDigits.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        // Set the content view
+        setContentView(getContentViewResource());
+
+        // Load up the resources for the text field and delete button
+        Resources r = getResources();
+        mDigitsBackground = r.getDrawable(R.drawable.btn_dial_textfield_active);
+        //mDigitsBackground.setDither(true);
+        mDigitsEmptyBackground = r.getDrawable(R.drawable.btn_dial_textfield);
+        //mDigitsEmptyBackground.setDither(true);
+        mDeleteBackground = r.getDrawable(R.drawable.btn_dial_delete_active);
+        //mDeleteBackground.setDither(true);
+        mDeleteEmptyBackground = r.getDrawable(R.drawable.btn_dial_delete);
+        //mDeleteEmptyBackground.setDither(true);
+
+        mDigits = (EditText) findViewById(R.id.digits);
+        mDigits.setKeyListener(DialerKeyListener.getInstance());
+        mDigits.setOnClickListener(this);
+        mDigits.setOnKeyListener(this);
+        maybeAddNumberFormatting();
+
+        // Check for the presence of the keypad
+        View view = findViewById(R.id.one);
+        if (view != null) {
+            setupKeypad();
+        }
+
+        view = findViewById(R.id.backspace);
+        view.setOnClickListener(this);
+        view.setOnLongClickListener(this);
+        mDelete = view;
+
+        if (!resolveIntent() && icicle != null) {
+            super.onRestoreInstanceState(icicle);
+        }
+        
+        // if the mToneGenerator creation fails, just continue without it.  It is 
+        // a local audio signal, and is not as important as the dtmf tone itself.
+        synchronized(mToneGeneratorLock) {
+            if (mToneGenerator == null) {
+                try {
+                    mToneGenerator = new ToneGenerator(AudioManager.STREAM_RING, 
+                            TONE_RELATIVE_VOLUME);
+                } catch (RuntimeException e) {
+                    Log.w(TAG, "Exception caught while creating local tone generator: " + e);
+                    mToneGenerator = null;
+                }
+            }
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        synchronized(mToneGeneratorLock) {
+            if (mToneGenerator != null) {
+                mToneStopper.removeMessages(STOP_TONE);
+                mToneGenerator.release();
+                mToneGenerator = null;
+            }
+        }
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Bundle icicle) {
+        // Do nothing, state is restored in onCreate() if needed
+    }
+    
+    protected void maybeAddNumberFormatting() {
+        mDigits.addTextChangedListener(new PhoneNumberFormattingTextWatcher());
+    }
+    
+    /**
+     * Overridden by subclasses to control the resource used by the content view. 
+     */
+    protected int getContentViewResource() {
+        return R.layout.twelve_key_dialer;
+    }
+
+    private boolean resolveIntent() {
+        boolean ignoreState = false;
+
+        // Find the proper intent
+        final Intent intent;
+        if (isChild()) {
+            intent = getParent().getIntent();
+            ignoreState = intent.getBooleanExtra(DialtactsActivity.EXTRA_IGNORE_STATE, false);
+        } else {
+            intent = getIntent();
+        }
+
+        // by default we are not adding a call.
+        mIsAddCallMode = false;
+        
+        // Resolve the intent
+        final String action = intent.getAction();
+        if (Intent.ACTION_DIAL.equals(action) || Intent.ACTION_VIEW.equals(action)) {
+            // see if we are "adding a call" from the InCallScreen; false by default.
+            mIsAddCallMode = intent.getBooleanExtra(ADD_CALL_MODE_KEY, false);
+            Uri uri = intent.getData();
+            if (uri != null) {
+                if ("tel".equals(uri.getScheme())) {
+                    // Put the requested number into the input area
+                    String data = uri.getSchemeSpecificPart();
+                    setFormattedDigits(data);
+                } else {
+                    String type = intent.getType();
+                    if (People.CONTENT_ITEM_TYPE.equals(type)
+                            || Phones.CONTENT_ITEM_TYPE.equals(type)) {
+                        // Query the phone number
+                        Cursor c = getContentResolver().query(intent.getData(),
+                                new String[] {PhonesColumns.NUMBER}, null, null, null);
+                        if (c != null) {
+                            if (c.moveToFirst()) {
+                                // Put the number into the input area
+                                setFormattedDigits(c.getString(0));
+                            }
+                            c.close();
+                        }
+                    }
+                }
+            }
+        }
+
+        return ignoreState;
+    }
+
+    protected void setFormattedDigits(String data) {
+        // strip the non-dialable numbers out of the data string.
+        String dialString = PhoneNumberUtils.extractNetworkPortion(data);
+        dialString = PhoneNumberUtils.formatNumber(dialString);
+        if (!TextUtils.isEmpty(dialString)) {
+            Editable digits = mDigits.getText();
+            digits.replace(0, digits.length(), dialString);
+            mDigits.setCompoundDrawablesWithIntrinsicBounds(
+                    getResources().getDrawable(R.drawable.ic_dial_number), null, null, null);
+        }
+    }
+
+    @Override
+    protected void onNewIntent(Intent newIntent) {
+        setIntent(newIntent);
+        resolveIntent();
+    }
+    
+    @Override
+    protected void onPostCreate(Bundle savedInstanceState) {
+        super.onPostCreate(savedInstanceState);
+
+        // This can't be done in onCreate(), since the auto-restoring of the digits
+        // will play DTMF tones for all the old digits if it is when onRestoreSavedInstanceState()
+        // is called. This method will be called every time the activity is created, and
+        // will always happen after onRestoreSavedInstanceState().
+        mDigits.addTextChangedListener(this);
+    }
+    
+    private void setupKeypad() {
+        // Setup the listeners for the buttons
+        View view = findViewById(R.id.one);
+        view.setOnClickListener(this);
+        view.setOnLongClickListener(this);
+
+        findViewById(R.id.two).setOnClickListener(this);
+        findViewById(R.id.three).setOnClickListener(this);
+        findViewById(R.id.four).setOnClickListener(this);
+        findViewById(R.id.five).setOnClickListener(this);
+        findViewById(R.id.six).setOnClickListener(this);
+        findViewById(R.id.seven).setOnClickListener(this);
+        findViewById(R.id.eight).setOnClickListener(this);
+        findViewById(R.id.nine).setOnClickListener(this);
+        findViewById(R.id.star).setOnClickListener(this);
+
+        view = findViewById(R.id.zero);
+        view.setOnClickListener(this);
+        view.setOnLongClickListener(this);
+
+        findViewById(R.id.pound).setOnClickListener(this);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        
+        // retrieve the DTMF tone play back setting.
+        mDTMFToneEnabled = Settings.System.getInt(getContentResolver(),
+                Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;
+
+        // if the mToneGenerator creation fails, just continue without it.  It is 
+        // a local audio signal, and is not as important as the dtmf tone itself.
+        synchronized(mToneGeneratorLock) {
+            if (mToneGenerator == null) {
+                try {
+                    mToneGenerator = new ToneGenerator(AudioManager.STREAM_RING, 
+                            TONE_RELATIVE_VOLUME);
+                } catch (RuntimeException e) {
+                    Log.w(TAG, "Exception caught while creating local tone generator: " + e);
+                    mToneGenerator = null;
+                }
+            }
+        }
+        
+        Activity parent = getParent();
+        // See if we were invoked with a DIAL intent. If we were, fill in the appropriate
+        // digits in the dialer field.
+        if (parent != null && parent instanceof DialtactsActivity) {
+            Uri dialUri = ((DialtactsActivity) parent).getAndClearDialUri();
+            if (dialUri != null) {
+                resolveIntent();
+            }
+        }
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        synchronized(mToneGeneratorLock) {
+            if (mToneGenerator != null) {
+                mToneStopper.removeMessages(STOP_TONE);
+                mToneGenerator.release();
+                mToneGenerator = null;
+            }
+        }
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        mAddToContactMenuItem = menu.add(0, 0, 0, R.string.recentCalls_addToContact)
+                .setIcon(android.R.drawable.ic_menu_add);
+
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        CharSequence digits = mDigits.getText();
+        if (digits == null || !TextUtils.isGraphic(digits)) {
+            mAddToContactMenuItem.setVisible(false);
+        } else {
+            // Put the current digits string into an intent
+            Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
+            intent.putExtra(Insert.PHONE, mDigits.getText());
+            intent.setType(People.CONTENT_ITEM_TYPE);
+            mAddToContactMenuItem.setIntent(intent);
+            mAddToContactMenuItem.setVisible(true);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_CALL: {
+                long callPressDiff = SystemClock.uptimeMillis() - event.getDownTime();
+                if (callPressDiff >= ViewConfiguration.getLongPressTimeout()) {
+                    // Launch voice dialer
+                    Intent intent = new Intent(Intent.ACTION_VOICE_COMMAND);
+                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                    try {
+                        startActivity(intent);
+                    } catch (ActivityNotFoundException e) {
+                    }
+                }
+                return true;
+            }
+            case KeyEvent.KEYCODE_1: {
+                long timeDiff = SystemClock.uptimeMillis() - event.getDownTime(); 
+                if (timeDiff >= ViewConfiguration.getLongPressTimeout()) {
+                    // Long press detected, call voice mail
+                    callVoicemail();
+                }
+                return true;
+            }
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+
+    @Override
+    public boolean onKeyUp(int keyCode, KeyEvent event) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_CALL: {
+                if (mIsAddCallMode && (TextUtils.isEmpty(mDigits.getText().toString()))) {
+                    // if we are adding a call from the InCallScreen and the phone
+                    // number entered is empty, we just close the dialer to expose
+                    // the InCallScreen under it.
+                    finish();
+                } else {
+                    // otherwise, we place the call.
+                    placeCall();
+                }
+                return true;
+            }
+        }
+        return super.onKeyUp(keyCode, event);
+    }
+    
+    private void keyPressed(int keyCode) {
+        KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
+        mDigits.onKeyDown(keyCode, event);
+    }
+
+    public boolean onKey(View view, int keyCode, KeyEvent event) {
+        switch (view.getId()) {
+            case R.id.digits:
+                if (keyCode == KeyEvent.KEYCODE_ENTER) {
+                    placeCall();
+                    return true;
+                }
+                break;
+        }
+        return false;
+    }
+
+    public void onClick(View view) {
+        switch (view.getId()) {
+            case R.id.one: {
+                playTone(ToneGenerator.TONE_DTMF_1);
+                keyPressed(KeyEvent.KEYCODE_1);
+                return;
+            }
+            case R.id.two: {
+                playTone(ToneGenerator.TONE_DTMF_2);
+                keyPressed(KeyEvent.KEYCODE_2);
+                return;
+            }
+            case R.id.three: {
+                playTone(ToneGenerator.TONE_DTMF_3);
+                keyPressed(KeyEvent.KEYCODE_3);
+                return;
+            }
+            case R.id.four: {
+                playTone(ToneGenerator.TONE_DTMF_4);
+                keyPressed(KeyEvent.KEYCODE_4);
+                return;
+            }
+            case R.id.five: {
+                playTone(ToneGenerator.TONE_DTMF_5);
+                keyPressed(KeyEvent.KEYCODE_5);
+                return;
+            }
+            case R.id.six: {
+                playTone(ToneGenerator.TONE_DTMF_6);
+                keyPressed(KeyEvent.KEYCODE_6);
+                return;
+            }
+            case R.id.seven: {
+                playTone(ToneGenerator.TONE_DTMF_7);
+                keyPressed(KeyEvent.KEYCODE_7);
+                return;
+            }
+            case R.id.eight: {
+                playTone(ToneGenerator.TONE_DTMF_8);
+                keyPressed(KeyEvent.KEYCODE_8);
+                return;
+            }
+            case R.id.nine: {
+                playTone(ToneGenerator.TONE_DTMF_9);
+                keyPressed(KeyEvent.KEYCODE_9);
+                return;
+            }
+            case R.id.zero: {
+                playTone(ToneGenerator.TONE_DTMF_0);
+                keyPressed(KeyEvent.KEYCODE_0);
+                return;
+            }
+            case R.id.pound: {
+                playTone(ToneGenerator.TONE_DTMF_P);
+                keyPressed(KeyEvent.KEYCODE_POUND);
+                return;
+            }
+            case R.id.star: {
+                playTone(ToneGenerator.TONE_DTMF_S);
+                keyPressed(KeyEvent.KEYCODE_STAR);
+                return;
+            }
+            case R.id.backspace: {
+                keyPressed(KeyEvent.KEYCODE_DEL);
+                return;
+            }
+            case R.id.digits: {
+                placeCall();
+                return;
+            }
+        }
+    }
+
+    public boolean onLongClick(View view) {
+        final Editable digits = mDigits.getText();
+        int id = view.getId();
+        switch (id) {
+            case R.id.backspace: {
+                digits.clear();
+                return true;
+            }
+            case R.id.one: {
+                if (digits.length() == 0) {
+                    callVoicemail();
+                    return true;
+                }
+                return false;
+            }
+            case R.id.zero: {
+                keyPressed(KeyEvent.KEYCODE_PLUS);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    void callVoicemail() {
+        Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
+                Uri.fromParts("voicemail", "", null));
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        startActivity(intent);
+        mDigits.getText().clear();
+        finish();
+    }
+
+    void placeCall() {
+        final String number = mDigits.getText().toString();
+        if (number == null || !TextUtils.isGraphic(number)) {
+            // There is no number entered.
+            playTone(ToneGenerator.TONE_PROP_NACK);
+            return;
+        }
+        Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
+                Uri.fromParts("tel", number, null));
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        startActivity(intent);
+        mDigits.getText().clear();
+        finish();
+    }
+
+    Handler mToneStopper = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case STOP_TONE:
+                    synchronized(mToneGeneratorLock) {
+                        if (mToneGenerator == null) {
+                            Log.w(TAG, "mToneStopper: mToneGenerator == null");
+                        } else {
+                            mToneGenerator.stopTone();
+                        }
+                    }
+                    break;
+            }
+        }
+    };
+
+    /**
+     * Play a tone for TONE_LENGTH_MS milliseconds.
+     * 
+     * @param tone a tone code from {@link ToneGenerator}
+     */
+    void playTone(int tone) {
+        // if local tone playback is disabled, just return.
+        if (!mDTMFToneEnabled) {
+            return;
+        }
+ 
+        synchronized(mToneGeneratorLock) {
+            if (mToneGenerator == null) {
+                Log.w(TAG, "playTone: mToneGenerator == null, tone: "+tone);
+                return;
+            }
+            
+            // Remove pending STOP_TONE messages
+            mToneStopper.removeMessages(STOP_TONE);
+    
+            // Start the new tone (will stop any playing tone)
+            mToneGenerator.startTone(tone);
+            mToneStopper.sendEmptyMessageDelayed(STOP_TONE, TONE_LENGTH_MS);
+        }
+    }
+}
+
diff --git a/src/com/android/contacts/ViewContactActivity.java b/src/com/android/contacts/ViewContactActivity.java
new file mode 100644
index 0000000..c1e9bc5
--- /dev/null
+++ b/src/com/android/contacts/ViewContactActivity.java
@@ -0,0 +1,955 @@
+/*
+ * Copyright (C) 2007 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 static com.android.contacts.ContactEntryAdapter.CONTACT_CUSTOM_RINGTONE_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.CONTACT_NAME_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.CONTACT_NOTES_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.CONTACT_PROJECTION;
+import static com.android.contacts.ContactEntryAdapter.CONTACT_SEND_TO_VOICEMAIL_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.CONTACT_STARRED_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.METHODS_AUX_DATA_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.METHODS_DATA_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.METHODS_ID_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.METHODS_KIND_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.METHODS_LABEL_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.METHODS_STATUS_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.METHODS_TYPE_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.METHODS_WITH_PRESENCE_PROJECTION;
+import static com.android.contacts.ContactEntryAdapter.ORGANIZATIONS_COMPANY_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.ORGANIZATIONS_ID_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.ORGANIZATIONS_LABEL_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.ORGANIZATIONS_PROJECTION;
+import static com.android.contacts.ContactEntryAdapter.ORGANIZATIONS_TITLE_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.ORGANIZATIONS_TYPE_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.PHONES_ID_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.PHONES_ISPRIMARY_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.PHONES_LABEL_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.PHONES_NUMBER_COLUMN;
+import static com.android.contacts.ContactEntryAdapter.PHONES_PROJECTION;
+import static com.android.contacts.ContactEntryAdapter.PHONES_TYPE_COLUMN;
+
+import com.android.internal.telephony.ITelephony;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.ListActivity;
+import android.content.ActivityNotFoundException;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.graphics.drawable.Drawable;
+import android.media.Ringtone;
+import android.media.RingtoneManager;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.provider.Contacts;
+import android.provider.Im;
+import android.provider.Contacts.ContactMethods;
+import android.provider.Contacts.Organizations;
+import android.provider.Contacts.People;
+import android.provider.Contacts.Phones;
+import android.provider.Contacts.Presence;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.widget.AdapterView;
+import android.widget.CheckBox;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+
+/**
+ * Displays the details of a specific contact.
+ */
+public class ViewContactActivity extends ListActivity 
+        implements View.OnCreateContextMenuListener, View.OnClickListener,
+        DialogInterface.OnClickListener {
+    private static final String TAG = "ViewContact";
+
+    private static final int DIALOG_CONFIRM_DELETE = 1;
+
+    public static final int MENU_ITEM_DELETE = 1;
+    public static final int MENU_ITEM_MAKE_DEFAULT = 2;
+
+    private Uri mUri;
+    private ContentResolver mResolver;
+    private ViewAdapter mAdapter;
+    private int mNumPhoneNumbers = 0;
+
+    /* package */ ArrayList<ViewEntry> mPhoneEntries = new ArrayList<ViewEntry>();
+    /* package */ ArrayList<ViewEntry> mSmsEntries = new ArrayList<ViewEntry>();
+    /* package */ ArrayList<ViewEntry> mEmailEntries = new ArrayList<ViewEntry>();
+    /* package */ ArrayList<ViewEntry> mPostalEntries = new ArrayList<ViewEntry>();
+    /* package */ ArrayList<ViewEntry> mImEntries = new ArrayList<ViewEntry>();
+    /* package */ ArrayList<ViewEntry> mOrganizationEntries = new ArrayList<ViewEntry>();
+    /* package */ ArrayList<ViewEntry> mOtherEntries = new ArrayList<ViewEntry>();
+    /* package */ ArrayList<ArrayList<ViewEntry>> mSections = new ArrayList<ArrayList<ViewEntry>>();
+
+    private Cursor mCursor;
+    private boolean mObserverRegistered;
+    
+    private ContentObserver mObserver = new ContentObserver(new Handler()) {
+        @Override
+        public boolean deliverSelfNotifications() {
+            return true;
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            if (mCursor != null && !mCursor.isClosed()){
+                dataChanged();
+            }
+        }
+    };
+
+    public void onClick(DialogInterface dialog, int which) {
+        if (mCursor != null) {
+            if (mObserverRegistered) {
+                mCursor.unregisterContentObserver(mObserver);
+                mObserverRegistered = false;
+            }
+            mCursor.close();
+            mCursor = null;
+        }
+        getContentResolver().delete(mUri, null, null);
+        finish();
+    }
+
+    public void onClick(View view) {
+        if (!mObserverRegistered) {
+            return;
+        }
+        switch (view.getId()) {
+            case R.id.star: {
+                int oldStarredState = mCursor.getInt(CONTACT_STARRED_COLUMN);
+                ContentValues values = new ContentValues(1);
+                values.put(People.STARRED, oldStarredState == 1 ? 0 : 1);
+                getContentResolver().update(mUri, values, null, null);
+                break;
+            }
+        }
+    }
+
+    private TextView mNameView;
+    private ImageView mPhotoView;
+    private int mNoPhotoResource;
+    private CheckBox mStarView;
+    private boolean mShowSmsLinksForAllPhones;
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        setContentView(R.layout.view_contact);
+        getListView().setOnCreateContextMenuListener(this);
+
+        mNameView = (TextView) findViewById(R.id.name);
+        mPhotoView = (ImageView) findViewById(R.id.photo);
+        mStarView = (CheckBox) findViewById(R.id.star);
+        mStarView.setOnClickListener(this);
+
+        // Set the photo with a random "no contact" image
+        long now = SystemClock.elapsedRealtime();
+        int num = (int) now & 0xf;
+        if (num < 9) {
+            // Leaning in from right, common
+            mNoPhotoResource = R.drawable.ic_contact_picture;
+        } else if (num < 14) {
+            // Leaning in from left uncommon
+            mNoPhotoResource = R.drawable.ic_contact_picture_2;
+        } else {
+            // Coming in from the top, rare
+            mNoPhotoResource = R.drawable.ic_contact_picture_3;
+        }
+
+        mUri = getIntent().getData();
+        mResolver = getContentResolver();
+
+        // Build the list of sections. The order they're added to mSections dictates the
+        // order they are displayed in the list.
+        mSections.add(mPhoneEntries);
+        mSections.add(mSmsEntries);
+        mSections.add(mEmailEntries);
+        mSections.add(mImEntries);
+        mSections.add(mPostalEntries);
+        mSections.add(mOrganizationEntries);
+        mSections.add(mOtherEntries);
+
+        //TODO Read this value from a preference
+        mShowSmsLinksForAllPhones = true;
+
+        mCursor = mResolver.query(mUri, CONTACT_PROJECTION, null, null, null);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mObserverRegistered = true;
+        mCursor.registerContentObserver(mObserver);
+        dataChanged();
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        if (mCursor != null) {
+            if (mObserverRegistered) {
+                mObserverRegistered = false;
+                mCursor.unregisterContentObserver(mObserver);
+            }
+            mCursor.deactivate();
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+
+        if (mCursor != null) {
+            if (mObserverRegistered) {
+                mCursor.unregisterContentObserver(mObserver);
+                mObserverRegistered = false;
+            }
+            mCursor.close();
+        }
+    }
+
+    @Override
+    protected Dialog onCreateDialog(int id) {
+        switch (id) {
+            case DIALOG_CONFIRM_DELETE:
+                return new AlertDialog.Builder(this)
+                        .setTitle(R.string.deleteConfirmation_title)
+                        .setIcon(android.R.drawable.ic_dialog_alert)
+                        .setMessage(R.string.deleteConfirmation)
+                        .setNegativeButton(R.string.noButton, null)
+                        .setPositiveButton(R.string.yesButton, this)
+                        .setCancelable(false)
+                        .create();
+        }
+        return null;
+    }
+    
+    private void dataChanged() {
+        mCursor.requery();
+        if (mCursor.moveToFirst()) {
+            // Set the name
+            String name = mCursor.getString(CONTACT_NAME_COLUMN);
+            if (TextUtils.isEmpty(name)) {
+                mNameView.setText(getText(android.R.string.unknownName));
+            } else {
+                mNameView.setText(name);
+            }
+
+            // Load the photo
+            mPhotoView.setImageBitmap(People.loadContactPhoto(this, mUri, mNoPhotoResource,
+                    null /* use the default options */));
+
+            // Set the star
+            mStarView.setChecked(mCursor.getInt(CONTACT_STARRED_COLUMN) == 1 ? true : false);
+
+            // Build up the contact entries
+            buildEntries(mCursor);
+            if (mAdapter == null) {
+                mAdapter = new ViewAdapter(this, mSections);
+                setListAdapter(mAdapter);
+            } else {
+                mAdapter.setSections(mSections, true);
+            }
+        } else {
+            Toast.makeText(this, R.string.invalidContactMessage, Toast.LENGTH_SHORT).show();
+            Log.e(TAG, "invalid contact uri: " + mUri);
+            finish();
+        }
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        menu.add(0, 0, 0, R.string.menu_editContact)
+                .setIcon(android.R.drawable.ic_menu_edit)
+                .setIntent(new Intent(Intent.ACTION_EDIT, mUri))
+                .setAlphabeticShortcut('e');
+        menu.add(0, MENU_ITEM_DELETE, 0, R.string.menu_deleteContact)
+                .setIcon(android.R.drawable.ic_menu_delete);
+
+        return true;
+    }
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
+        AdapterView.AdapterContextMenuInfo info;
+        try {
+             info = (AdapterView.AdapterContextMenuInfo) menuInfo;
+        } catch (ClassCastException e) {
+            Log.e(TAG, "bad menuInfo", e);
+            return;
+        }
+
+        // This can be null sometimes, don't crash...
+        if (info == null) {
+            Log.e(TAG, "bad menuInfo");
+            return;
+        }
+
+        ViewEntry entry = ContactEntryAdapter.getEntry(mSections, info.position, true);
+        switch (entry.kind) {
+            case Contacts.KIND_PHONE: {
+                menu.add(0, 0, 0, R.string.menu_call).setIntent(entry.intent);
+                menu.add(0, 0, 0, R.string.menu_sendSMS).setIntent(entry.auxIntent);
+                if (entry.primaryIcon == -1) {
+                    menu.add(0, MENU_ITEM_MAKE_DEFAULT, 0, R.string.menu_makeDefaultNumber);
+                }
+                break;
+            }
+
+            case Contacts.KIND_EMAIL: {
+                menu.add(0, 0, 0, R.string.menu_sendEmail).setIntent(entry.intent);
+                break;
+            }
+
+            case Contacts.KIND_POSTAL: {
+                menu.add(0, 0, 0, R.string.menu_viewAddress).setIntent(entry.intent);
+                break;
+            }
+        }
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case MENU_ITEM_DELETE: {
+                // Get confirmation
+                showDialog(DIALOG_CONFIRM_DELETE);
+                return true;
+            }
+        }
+        return super.onOptionsItemSelected(item);
+    }
+    
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case MENU_ITEM_MAKE_DEFAULT: {
+                AdapterView.AdapterContextMenuInfo info;
+                try {
+                     info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
+                } catch (ClassCastException e) {
+                    Log.e(TAG, "bad menuInfo", e);
+                    break;
+                }
+
+                ViewEntry entry = ContactEntryAdapter.getEntry(mSections, info.position, true);
+                ContentValues values = new ContentValues(1);
+                values.put(People.PRIMARY_PHONE_ID, entry.id);
+                getContentResolver().update(mUri, values, null, null);
+                dataChanged();
+                return true;
+            }
+        }
+        return super.onContextItemSelected(item);
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_CALL: {
+                try {
+                    ITelephony phone = ITelephony.Stub.asInterface(
+                            ServiceManager.checkService("phone"));
+                    if (phone != null && !phone.isIdle()) {
+                        // Skip out and let the key be handled at a higher level
+                        break;
+                    }
+                } catch (RemoteException re) {
+                    // Fall through and try to call the contact
+                }
+
+                int index = getListView().getSelectedItemPosition();
+                if (index != -1) {
+                    ViewEntry entry = ViewAdapter.getEntry(mSections, index, true);
+                    if (entry.kind == Contacts.KIND_PHONE) {
+                        Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED, entry.uri);
+                        startActivity(intent);
+                    }
+                } else if (mNumPhoneNumbers != 0) {
+                    // There isn't anything selected, call the default number
+                    Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED, mUri);
+                    startActivity(intent);
+                }
+                return true;
+            }
+
+            case KeyEvent.KEYCODE_DEL: {
+                showDialog(DIALOG_CONFIRM_DELETE);
+                return true;
+            }
+        }
+
+        return super.onKeyDown(keyCode, event);
+    }
+
+    @Override
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+        ViewEntry entry = ViewAdapter.getEntry(mSections, position, true);
+        if (entry != null) {
+            Intent intent = entry.intent;
+            if (intent != null) {
+                try {
+                    startActivity(intent);
+                } catch (ActivityNotFoundException e) {
+                    Log.e(TAG, "No activity found for intent: " + intent);
+                    signalError();
+                }
+            } else {
+                signalError();
+            }
+        } else {
+            signalError();
+        }
+    }
+
+    /**
+     * Signal an error to the user via a beep, or some other method.
+     */
+    private void signalError() {
+        //TODO: implement this when we have the sonification APIs
+    }
+
+    /**
+     * Build separator entries for all of the sections.
+     */
+    private void buildSeparators() {
+        ViewEntry separator;
+        
+        separator = new ViewEntry();
+        separator.kind = ViewEntry.KIND_SEPARATOR;
+        separator.data = getString(R.string.listSeparatorCallNumber);
+        mPhoneEntries.add(separator);
+
+        separator = new ViewEntry();
+        separator.kind = ViewEntry.KIND_SEPARATOR;
+        separator.data = getString(R.string.listSeparatorSendSmsMms);
+        mSmsEntries.add(separator);
+
+        separator = new ViewEntry();
+        separator.kind = ViewEntry.KIND_SEPARATOR;
+        separator.data = getString(R.string.listSeparatorSendEmail);
+        mEmailEntries.add(separator);
+
+        separator = new ViewEntry();
+        separator.kind = ViewEntry.KIND_SEPARATOR;
+        separator.data = getString(R.string.listSeparatorSendIm);
+        mImEntries.add(separator);
+
+        separator = new ViewEntry();
+        separator.kind = ViewEntry.KIND_SEPARATOR;
+        separator.data = getString(R.string.listSeparatorMapAddress);
+        mPostalEntries.add(separator);
+
+        separator = new ViewEntry();
+        separator.kind = ViewEntry.KIND_SEPARATOR;
+        separator.data = getString(R.string.listSeparatorOrganizations);
+        mOrganizationEntries.add(separator);
+
+        separator = new ViewEntry();
+        separator.kind = ViewEntry.KIND_SEPARATOR;
+        separator.data = getString(R.string.listSeparatorOtherInformation);
+        mOtherEntries.add(separator);
+    }
+    
+    /**
+     * Build up the entries to display on the screen.
+     * 
+     * @param personCursor the URI for the contact being displayed
+     */
+    private final void buildEntries(Cursor personCursor) {
+        // Clear out the old entries
+        final int numSections = mSections.size();
+        for (int i = 0; i < numSections; i++) {
+            mSections.get(i).clear();
+        }
+        buildSeparators();
+
+        // Build up the phone entries
+        final Uri phonesUri = Uri.withAppendedPath(mUri, People.Phones.CONTENT_DIRECTORY);
+        final Cursor phonesCursor = mResolver.query(phonesUri, PHONES_PROJECTION, null, null,
+                Phones.ISPRIMARY + " DESC");
+
+        if (phonesCursor != null) {
+            while (phonesCursor.moveToNext()) {
+                final int type = phonesCursor.getInt(PHONES_TYPE_COLUMN);
+                final String number = phonesCursor.getString(PHONES_NUMBER_COLUMN);
+                final String label = phonesCursor.getString(PHONES_LABEL_COLUMN);
+                final boolean isPrimary = phonesCursor.getInt(PHONES_ISPRIMARY_COLUMN) == 1;
+                final long id = phonesCursor.getLong(PHONES_ID_COLUMN);
+                final Uri uri = ContentUris.withAppendedId(phonesUri, id);
+
+                // Don't crash if the number is bogus
+                if (TextUtils.isEmpty(number)) {
+                    Log.w(TAG, "empty number for phone " + id);
+                    continue;
+                }
+
+                mNumPhoneNumbers++;
+                
+                // Add a phone number entry
+                final ViewEntry entry = new ViewEntry();
+                entry.label = Phones.getDisplayLabel(this, type, label).toString();
+                entry.data = number;
+                entry.id = id;
+                entry.uri = uri;
+                entry.intent = new Intent(Intent.ACTION_CALL_PRIVILEGED, entry.uri);
+                entry.auxIntent = new Intent(Intent.ACTION_SENDTO,
+                        Uri.fromParts("sms", number, null));
+                entry.kind = Contacts.KIND_PHONE;
+                if (isPrimary) {
+                    entry.primaryIcon = R.drawable.ic_default_number;
+                }
+                entry.actionIcon = R.drawable.sym_action_call;
+                mPhoneEntries.add(entry);
+
+                if (type == Phones.TYPE_MOBILE || mShowSmsLinksForAllPhones) {
+                    // Add an SMS entry
+                    ViewEntry smsEntry = new ViewEntry();
+                    smsEntry.label = entry.label;
+                    smsEntry.data = number;
+                    smsEntry.id = id;
+                    smsEntry.uri = uri;
+                    smsEntry.intent = entry.auxIntent;
+                    smsEntry.kind = ViewEntry.KIND_SMS;
+                    smsEntry.actionIcon = R.drawable.sym_action_sms;
+                    mSmsEntries.add(smsEntry);
+                }
+            }
+
+            phonesCursor.close();
+        }
+
+        // Build the contact method entries
+        final Uri methodsUri = Uri.withAppendedPath(mUri, People.ContactMethods.CONTENT_DIRECTORY);
+        Cursor methodsCursor = mResolver.query(
+                Uri.withAppendedPath(mUri, "contact_methods_with_presence"),
+                METHODS_WITH_PRESENCE_PROJECTION, null, null, null);
+
+        if (methodsCursor != null) {
+            String[] protocolStrings = getResources().getStringArray(android.R.array.imProtocols);
+
+            while (methodsCursor.moveToNext()) {
+                final int kind = methodsCursor.getInt(METHODS_KIND_COLUMN);
+                final String label = methodsCursor.getString(METHODS_LABEL_COLUMN);
+                final String data = methodsCursor.getString(METHODS_DATA_COLUMN);
+                final int type = methodsCursor.getInt(METHODS_TYPE_COLUMN);
+                final long id = methodsCursor.getLong(METHODS_ID_COLUMN);
+                final Uri uri = ContentUris.withAppendedId(methodsUri, id);
+
+                // Don't crash if the data is bogus
+                if (TextUtils.isEmpty(data)) {
+                    Log.w(TAG, "empty data for contact method " + id);
+                    continue;
+                }
+
+                ViewEntry entry = new ViewEntry();
+                entry.id = id;
+                entry.uri = uri;
+                entry.kind = kind;
+
+                switch (kind) {
+                    case Contacts.KIND_EMAIL:
+                        entry.label = ContactMethods.getDisplayLabel(this, kind, type, label)
+                                .toString();
+                        entry.data = data;
+                        entry.intent = new Intent(Intent.ACTION_SENDTO,
+                                Uri.fromParts("mailto", data, null));
+                        if (!methodsCursor.isNull(METHODS_STATUS_COLUMN)) {
+                            entry.presenceIcon = Presence.getPresenceIconResourceId(
+                                    methodsCursor.getInt(METHODS_STATUS_COLUMN));
+                        }
+                        entry.actionIcon = R.drawable.sym_action_email;
+                        mEmailEntries.add(entry);
+                        break;
+
+                    case Contacts.KIND_POSTAL:
+                        entry.label = ContactMethods.getDisplayLabel(this, kind, type, label)
+                                .toString();
+                        entry.data = data;
+                        entry.maxLines = 4;
+                        entry.intent = new Intent(Intent.ACTION_VIEW, uri);
+                        entry.actionIcon = R.drawable.sym_action_map;
+                        mPostalEntries.add(entry);
+                        break;
+
+                    case Contacts.KIND_IM: {
+                        Object protocolObj = ContactMethods.decodeImProtocol(
+                                methodsCursor.getString(METHODS_AUX_DATA_COLUMN));
+                        String providerCategory;
+                        if (protocolObj instanceof Number) {
+                            int protocol = ((Number) protocolObj).intValue();
+                            entry.label = protocolStrings[protocol];
+                            providerCategory = ContactMethods.lookupProviderCategoryFromId(
+                                    protocol);
+                            if (protocol == ContactMethods.PROTOCOL_GOOGLE_TALK
+                                    || protocol == ContactMethods.PROTOCOL_MSN) {
+                                entry.maxLabelLines = 2;
+                            }
+                        } else {
+                            String providerName = (String) protocolObj;
+                            entry.label = providerName;
+                            providerCategory = Im.Provider.getProviderCategoryFromName(
+                                    providerName);
+                        }
+
+                        // Only add the intent if there is a valid provider name
+                        if (!TextUtils.isEmpty(providerCategory)) {
+                            entry.intent = new Intent(Intent.ACTION_SENDTO,
+                                    Uri.fromParts("im", data, null)).addCategory(providerCategory);
+                        }
+                        entry.data = data;
+                        if (!methodsCursor.isNull(METHODS_STATUS_COLUMN)) {
+                            entry.presenceIcon = Presence.getPresenceIconResourceId(
+                                    methodsCursor.getInt(METHODS_STATUS_COLUMN));
+                        }
+                        entry.actionIcon = R.drawable.sym_action_chat;
+                        mImEntries.add(entry);
+                        break;
+                    }
+                }
+            }
+
+            methodsCursor.close();
+        }
+
+        // Build IM entries for things we have presence info about but not explicit IM entries for
+        long personId = ContentUris.parseId(mUri);
+        String[] projection = new String[] {
+                Presence.IM_HANDLE, // 0
+                Presence.IM_PROTOCOL, // 1
+                Presence.PRESENCE_STATUS, // 2
+        };
+        Cursor presenceCursor = mResolver.query(Presence.CONTENT_URI, projection,
+                Presence.PERSON_ID + "=" + personId, null, null);
+        if (presenceCursor != null) {
+            try {
+                while (presenceCursor.moveToNext()) {
+                    // Find the display info for the provider
+                    String data = presenceCursor.getString(0);
+                    String label;
+                    Object protocolObj = ContactMethods.decodeImProtocol(
+                            presenceCursor.getString(1));
+                    String providerCategory;
+                    if (protocolObj instanceof Number) {
+                        int protocol = ((Number) protocolObj).intValue();
+                        label = getResources().getStringArray(
+                                android.R.array.imProtocols)[protocol];
+                        providerCategory = ContactMethods.lookupProviderCategoryFromId(
+                                protocol);
+                    } else {
+                        String providerName = (String) protocolObj;
+                        label = providerName;
+                        providerCategory = Im.Provider.getProviderCategoryFromName(providerName);
+                    }
+
+                    if (TextUtils.isEmpty(providerCategory)) {
+                        // A valid provider name is required
+                        continue;
+                    }
+
+                    Intent intent = new Intent(Intent.ACTION_SENDTO,
+                            Uri.fromParts("im", data, null)).addCategory(providerCategory);
+
+                    // Check to see if there is already an entry for this IM account
+                    boolean addEntry = true;
+                    int numImEntries = mImEntries.size();
+                    for (int i = 0; i < numImEntries; i++) {
+                        // Check to see if the intent point to the same thing, if so we won't
+                        // add this entry to the list since there is already an explict entry
+                        // for the IM account
+                        Intent existingIntent = mImEntries.get(i).intent;
+                        if (intent.filterEquals(existingIntent)) {
+                            addEntry = false;
+                            break;
+                        }
+                    }
+
+                    // Add the entry if an existing one wasn't found
+                    if (addEntry) {
+                        ViewEntry entry = new ViewEntry();
+                        entry.kind = Contacts.KIND_IM;
+                        entry.data = data;
+                        entry.label = label;
+                        entry.intent = intent;
+                        entry.actionIcon = R.drawable.sym_action_chat;
+                        entry.presenceIcon = Presence.getPresenceIconResourceId(
+                                presenceCursor.getInt(2));
+                        entry.maxLabelLines = 2;
+                        mImEntries.add(entry);
+                    }
+                }
+            } finally {
+                presenceCursor.close();
+            }
+        }
+
+        // Build the organization entries
+        final Uri organizationsUri = Uri.withAppendedPath(mUri, Organizations.CONTENT_DIRECTORY);
+        Cursor organizationsCursor = mResolver.query(organizationsUri, ORGANIZATIONS_PROJECTION,
+                null, null, null);
+
+        if (organizationsCursor != null) {
+            while (organizationsCursor.moveToNext()) {
+                ViewEntry entry = new ViewEntry();
+                entry.id = organizationsCursor.getLong(ORGANIZATIONS_ID_COLUMN);
+                entry.uri = ContentUris.withAppendedId(organizationsUri, entry.id);
+                entry.kind = Contacts.KIND_ORGANIZATION;
+                entry.data = organizationsCursor.getString(ORGANIZATIONS_COMPANY_COLUMN);
+                entry.data2 = organizationsCursor.getString(ORGANIZATIONS_TITLE_COLUMN);
+                entry.label = Organizations.getDisplayLabel(this,
+                        organizationsCursor.getInt(ORGANIZATIONS_TYPE_COLUMN),
+                        organizationsCursor.getString(ORGANIZATIONS_LABEL_COLUMN)).toString();
+                mOrganizationEntries.add(entry);
+            }
+
+            organizationsCursor.close();
+        }
+
+
+        // Build the other entries
+        String note = personCursor.getString(CONTACT_NOTES_COLUMN);
+        if (!TextUtils.isEmpty(note)) {
+            ViewEntry entry = new ViewEntry();
+            entry.label = getString(R.string.label_notes);
+            entry.data = note;
+            entry.id = 0;
+            entry.kind = ViewEntry.KIND_CONTACT;
+            entry.uri = null;
+            entry.intent = null;
+            entry.maxLines = 10;
+            mOtherEntries.add(entry);
+        }
+        
+        // Build the ringtone entry
+        String ringtoneStr = personCursor.getString(CONTACT_CUSTOM_RINGTONE_COLUMN);
+        if (!TextUtils.isEmpty(ringtoneStr)) {
+            // Get the URI
+            Uri ringtoneUri = Uri.parse(ringtoneStr);
+            if (ringtoneUri != null) {
+                Ringtone ringtone = RingtoneManager.getRingtone(this, ringtoneUri);
+                if (ringtone != null) {
+                    ViewEntry entry = new ViewEntry();
+                    entry.label = getString(R.string.label_ringtone);
+                    entry.data = ringtone.getTitle(this);
+                    entry.kind = ViewEntry.KIND_CONTACT;
+                    entry.uri = ringtoneUri;
+                    mOtherEntries.add(entry);
+                }
+            }
+        }
+
+        boolean sendToVoicemail = personCursor.getInt(CONTACT_SEND_TO_VOICEMAIL_COLUMN) == 1;
+        if (sendToVoicemail) {
+            ViewEntry entry = new ViewEntry();
+            entry.label = getString(R.string.send_to_voicemail_view);
+            entry.isLabelOnly = true;
+            entry.kind = ViewEntry.KIND_CONTACT;
+            mOtherEntries.add(entry);
+        }
+    }
+
+    /**
+     * A basic structure with the data for a contact entry in the list.
+     */
+    private final static class ViewEntry extends ContactEntryAdapter.Entry {
+        public int primaryIcon = -1;
+        public Intent intent;
+        public Intent auxIntent = null;
+        public int presenceIcon = -1;
+        public int actionIcon = -1;
+        public String data2 = null;
+        public boolean isLabelOnly = false;
+        public int maxLabelLines = 1;
+    }
+
+    private static final class ViewAdapter extends ContactEntryAdapter<ViewEntry> {
+        /** Cache of the children views of a row */
+        static class ViewCache {
+            public TextView label;
+            public TextView data;
+            public TextView data2;
+            
+            // Need to keep track of this too
+            ViewEntry entry;
+        }
+        
+        ViewAdapter(Context context, ArrayList<ArrayList<ViewEntry>> sections) {
+            super(context, sections, true);
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            ViewEntry entry = getEntry(mSections, position, true); 
+            View v;
+
+            // Handle separators specially
+            if (entry.kind == ViewEntry.KIND_SEPARATOR) {
+                TextView separator = (TextView) mInflater.inflate(
+                        R.layout.list_separator, parent, false);
+                separator.setText(entry.data);
+                return separator;
+            }
+
+            ViewCache views;
+
+            // Check to see if we can reuse convertView
+            if (convertView != null) {
+                views = (ViewCache) convertView.getTag();
+                if (views != null) {
+                    ViewEntry origEntry = views.entry;
+                    if (origEntry != null) {
+                        // Check to see if the view and the entry are compatible
+                        if (entry.kind == Contacts.KIND_ORGANIZATION
+                                && origEntry.kind != Contacts.KIND_ORGANIZATION) {
+                            v = null;
+                        } else if (entry.kind != Contacts.KIND_ORGANIZATION
+                                && origEntry.kind == Contacts.KIND_ORGANIZATION) {
+                            v = null;
+                        } else if (entry.isLabelOnly != origEntry.isLabelOnly) {
+                            v = null;
+                        } else {
+                            v = convertView;
+                        }
+                    } else {
+                        v = null;
+                    }
+                } else {
+                    v = null;
+                }
+            } else {
+                v = null;
+            }
+
+            // Create a new view if needed
+            if (v == null) {
+                if (entry.kind == Contacts.KIND_ORGANIZATION) {
+                    v = mInflater.inflate(R.layout.view_contact_entry_organization, parent, false);
+                } else if (entry.isLabelOnly) {
+                    v = mInflater.inflate(R.layout.view_contact_entry_only_label, parent, false);
+                } else {
+                    v = mInflater.inflate(R.layout.view_contact_entry, parent, false);
+                }
+
+                // Cache the children
+                views = new ViewCache();
+                views.label = (TextView) v.findViewById(R.id.label);
+                views.data = (TextView) v.findViewById(R.id.data);
+                // label-only contact entries don't have a data view
+                if (views.data != null) {
+                    views.data.setCompoundDrawablePadding(3);
+                }
+                views.data2 = (TextView) v.findViewById(R.id.data2);
+            } else {
+                views = (ViewCache) v.getTag();
+            }
+
+            // Set the tag on the view so it knows what it's displaying
+            views.entry = entry;
+            v.setTag(views);
+
+            // Bind the data to the view
+            bindView(v, entry);
+            return v;
+        }
+
+        @Override
+        protected View newView(int position, ViewGroup parent) {
+            // getView() handles this
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        protected void bindView(View view, ViewEntry entry) {
+            final Resources resources = mContext.getResources();
+            ViewCache views = (ViewCache) view.getTag();
+
+            // Set the label
+            TextView label = views.label;
+            setMaxLines(label, entry.maxLabelLines);
+            label.setText(entry.label);
+
+            // Set the data
+            TextView data = views.data;
+            if (data != null) {
+                data.setText(entry.data);
+                setMaxLines(data, entry.maxLines);
+            }
+
+            // Set the left icon
+            Drawable left = null;
+            if (entry.primaryIcon != -1) {
+                left = resources.getDrawable(entry.primaryIcon);
+            } else if (entry.presenceIcon != -1) {
+                left = resources.getDrawable(entry.presenceIcon);
+            }
+
+            // Set the right icon
+            Drawable right = null;
+            if (entry.actionIcon != -1) {
+                right = resources.getDrawable(entry.actionIcon);
+            }
+            
+            if (data != null) {
+                data.setCompoundDrawablesWithIntrinsicBounds(left, null, right, null);
+            }
+
+            // Set data2 if we have it
+            if (entry.kind == Contacts.KIND_ORGANIZATION) {
+                views.data2.setText(entry.data2);
+            }
+        }
+
+        private void setMaxLines(TextView textView, int maxLines) {
+            if (maxLines == 1) {
+                textView.setSingleLine(true);
+                textView.setEllipsize(TextUtils.TruncateAt.END);
+            } else {
+                textView.setSingleLine(false);
+                textView.setMaxLines(maxLines);
+                textView.setEllipsize(null);
+            }
+        }
+    }
+}
+
+
