diff --git a/src/com/android/contacts/AttachImage.java b/src/com/android/contacts/AttachImage.java
new file mode 100644
index 0000000..8c91722
--- /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.
+ */
+public 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/CallDetailActivity.java b/src/com/android/contacts/CallDetailActivity.java
new file mode 100644
index 0000000..012a33e
--- /dev/null
+++ b/src/com/android/contacts/CallDetailActivity.java
@@ -0,0 +1,355 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.contacts;
+
+import android.app.ListActivity;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.CallLog;
+import android.provider.Contacts;
+import android.provider.CallLog.Calls;
+import android.provider.Contacts.People;
+import android.provider.Contacts.Phones;
+import android.provider.Contacts.Intents.Insert;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.text.format.DateUtils;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Displays the details of a specific call log entry.
+ */
+public class CallDetailActivity extends ListActivity implements
+        AdapterView.OnItemClickListener {
+    private static final String TAG = "CallDetail";
+
+    private TextView mCallType;
+    private ImageView mCallTypeIcon;
+    private TextView mCallTime;
+    private TextView mCallDuration;
+
+    private String mNumber = null;
+    
+    /* package */ LayoutInflater mInflater;
+    /* package */ Resources mResources;
+    
+    static final String[] CALL_LOG_PROJECTION = new String[] {
+        CallLog.Calls.DATE,
+        CallLog.Calls.DURATION,
+        CallLog.Calls.NUMBER,
+        CallLog.Calls.TYPE,
+    };
+    
+    static final int DATE_COLUMN_INDEX = 0;
+    static final int DURATION_COLUMN_INDEX = 1;
+    static final int NUMBER_COLUMN_INDEX = 2;
+    static final int CALL_TYPE_COLUMN_INDEX = 3;
+    
+    static final String[] PHONES_PROJECTION = new String[] {
+        Phones.PERSON_ID,
+        Phones.DISPLAY_NAME,
+        Phones.TYPE,
+        Phones.LABEL,
+        Phones.NUMBER,
+    };
+    static final int COLUMN_INDEX_ID = 0;
+    static final int COLUMN_INDEX_NAME = 1;
+    static final int COLUMN_INDEX_TYPE = 2;
+    static final int COLUMN_INDEX_LABEL = 3;
+    static final int COLUMN_INDEX_NUMBER = 4;
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        setContentView(R.layout.call_detail);
+
+        mInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
+        mResources = getResources();
+        
+        mCallType = (TextView) findViewById(R.id.type);
+        mCallTypeIcon = (ImageView) findViewById(R.id.icon);
+        mCallTime = (TextView) findViewById(R.id.time);
+        mCallDuration = (TextView) findViewById(R.id.duration);
+        
+        getListView().setOnItemClickListener(this);
+    }
+    
+    @Override
+    public void onResume() {
+        super.onResume();
+        updateData(getIntent().getData());
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_CALL: {
+                // Make sure phone isn't already busy before starting direct call
+                TelephonyManager tm = (TelephonyManager)
+                        getSystemService(Context.TELEPHONY_SERVICE);
+                if (tm.getCallState() == TelephonyManager.CALL_STATE_IDLE) {
+                    Intent callIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
+                            Uri.fromParts("tel", mNumber, null));
+                    startActivity(callIntent);
+                    return true;
+                }
+            }
+        }
+        
+        return super.onKeyDown(keyCode, event);
+    }
+    
+    /**
+     * Update user interface with details of given call.
+     * 
+     * @param callUri Uri into {@link CallLog.Calls}
+     */
+    private void updateData(Uri callUri) {
+        ContentResolver resolver = getContentResolver();
+        Cursor callCursor = resolver.query(callUri, CALL_LOG_PROJECTION, null, null, null);
+        try {
+            if (callCursor != null && callCursor.moveToFirst()) {
+                // Read call log specifics
+                mNumber = callCursor.getString(NUMBER_COLUMN_INDEX);
+                long date = callCursor.getLong(DATE_COLUMN_INDEX);
+                long duration = callCursor.getLong(DURATION_COLUMN_INDEX);
+                int callType = callCursor.getInt(CALL_TYPE_COLUMN_INDEX);
+                
+                // Pull out string in format [relative], [date]
+                CharSequence dateClause = DateUtils.formatDateRange(this, date, date,
+                        DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE |
+                        DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_YEAR);
+                mCallTime.setText(dateClause);
+                
+                // Set the duration
+                if (callType == Calls.MISSED_TYPE) {
+                    mCallDuration.setVisibility(View.GONE);
+                } else {
+                    mCallDuration.setVisibility(View.VISIBLE);
+                    mCallDuration.setText(formatDuration(duration));
+                }
+    
+                // Set the call type icon and caption
+                String callText = null;
+                switch (callType) {
+                    case Calls.INCOMING_TYPE:
+                        mCallTypeIcon.setImageResource(android.R.drawable.sym_call_incoming);
+                        mCallType.setText(R.string.type_incoming);
+                        callText = getString(R.string.callBack);
+                        break;
+    
+                    case Calls.OUTGOING_TYPE:
+                        mCallTypeIcon.setImageResource(android.R.drawable.sym_call_outgoing);
+                        mCallType.setText(R.string.type_outgoing);
+                        callText = getString(R.string.callAgain);
+                        break;
+    
+                    case Calls.MISSED_TYPE:
+                        mCallTypeIcon.setImageResource(android.R.drawable.sym_call_missed);
+                        mCallType.setText(R.string.type_missed);
+                        callText = getString(R.string.returnCall);
+                        break;
+                }
+    
+                // Perform a reverse-phonebook lookup to find the PERSON_ID
+                String callLabel = null;
+                Uri personUri = null;
+                Uri phoneUri = Uri.withAppendedPath(Phones.CONTENT_FILTER_URL, Uri.encode(mNumber));
+                Cursor phonesCursor = resolver.query(phoneUri, PHONES_PROJECTION, null, null, null);
+                try {
+                    if (phonesCursor != null && phonesCursor.moveToFirst()) {
+                        long personId = phonesCursor.getLong(COLUMN_INDEX_ID);
+                        personUri = ContentUris.withAppendedId(
+                                Contacts.People.CONTENT_URI, personId);
+                        callText = getString(R.string.recentCalls_callNumber,
+                                phonesCursor.getString(COLUMN_INDEX_NAME));
+                        mNumber = phonesCursor.getString(COLUMN_INDEX_NUMBER);
+                        callLabel = Phones.getDisplayLabel(this,
+                                phonesCursor.getInt(COLUMN_INDEX_TYPE),
+                                phonesCursor.getString(COLUMN_INDEX_LABEL)).toString();
+                    } else {
+                        mNumber = PhoneNumberUtils.formatNumber(mNumber);
+                    }
+                } finally {
+                    if (phonesCursor != null) phonesCursor.close();
+                }
+
+                // Build list of various available actions
+                List<ViewEntry> actions = new ArrayList<ViewEntry>();
+                
+                Intent callIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
+                        Uri.fromParts("tel", mNumber, null));
+                ViewEntry entry = new ViewEntry(android.R.drawable.sym_action_call, callText,
+                        callIntent);
+                entry.number = mNumber;
+                entry.label = callLabel;
+                actions.add(entry);
+                
+                Intent smsIntent = new Intent(Intent.ACTION_SENDTO,
+                        Uri.fromParts("sms", mNumber, null));
+                actions.add(new ViewEntry(R.drawable.sym_action_sms,
+                        getString(R.string.menu_sendTextMessage), smsIntent));
+                
+                // Let user view contact details if they exist, otherwise add option
+                // to create new contact from this number.
+                if (personUri != null) {
+                    Intent viewIntent = new Intent(Intent.ACTION_VIEW, personUri);
+                    actions.add(new ViewEntry(R.drawable.sym_action_view_contact,
+                            getString(R.string.menu_viewContact), viewIntent));
+                } else {
+                    Intent createIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
+                    createIntent.setType(People.CONTENT_ITEM_TYPE);
+                    createIntent.putExtra(Insert.PHONE, mNumber);
+                    actions.add(new ViewEntry(R.drawable.sym_action_add,
+                            getString(R.string.recentCalls_addToContact), createIntent));
+                }
+                
+                ViewAdapter adapter = new ViewAdapter(this, actions);
+                setListAdapter(adapter);
+            } else {
+                // Something went wrong reading in our primary data, so we're going to
+                // bail out and show error to users.
+                Toast.makeText(this, R.string.toast_call_detail_error,
+                        Toast.LENGTH_SHORT).show();
+                finish();
+            }
+        } finally {
+            if (callCursor != null) {
+                callCursor.close();
+            }
+        }
+    }
+
+    private String formatDuration(long elapsedSeconds) {
+        long minutes = 0;
+        long seconds = 0;
+
+        if (elapsedSeconds >= 60) {
+            minutes = elapsedSeconds / 60;
+            elapsedSeconds -= minutes * 60;
+        }
+        seconds = elapsedSeconds;
+
+        return getString(R.string.callDetailsDurationFormat, minutes, seconds);
+    }
+
+    static final class ViewEntry {
+        public int icon = -1;
+        public String text = null;
+        public Intent intent = null;
+        public String label = null;
+        public String number = null;
+        
+        public ViewEntry(int icon, String text, Intent intent) {
+            this.icon = icon;
+            this.text = text;
+            this.intent = intent;
+        }
+    }
+
+    static final class ViewAdapter extends BaseAdapter {
+        
+        private final List<ViewEntry> mActions;
+        
+        private final LayoutInflater mInflater;
+        
+        public ViewAdapter(Context context, List<ViewEntry> actions) {
+            mActions = actions;
+            mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        }
+        
+        public int getCount() {
+            return mActions.size();
+        }
+
+        public Object getItem(int position) {
+            return mActions.get(position);
+        }
+
+        public long getItemId(int position) {
+            return position;
+        }
+        
+        public View getView(int position, View convertView, ViewGroup parent) {
+            // Make sure we have a valid convertView to start with
+            if (convertView == null) {
+                convertView = mInflater.inflate(R.layout.call_detail_list_item, parent, false);
+            }
+
+            // Fill action with icon and text.
+            ViewEntry entry = mActions.get(position);
+            convertView.setTag(entry);
+            
+            ImageView icon = (ImageView) convertView.findViewById(R.id.icon);
+            TextView text = (TextView) convertView.findViewById(android.R.id.text1);
+
+            icon.setImageResource(entry.icon);
+            text.setText(entry.text);
+
+            View line2 = convertView.findViewById(R.id.line2);
+            boolean numberEmpty = TextUtils.isEmpty(entry.number);
+            boolean labelEmpty = TextUtils.isEmpty(entry.label) || numberEmpty;
+            if (labelEmpty && numberEmpty) {
+                line2.setVisibility(View.GONE);
+            } else {
+                line2.setVisibility(View.VISIBLE);
+                
+                TextView label = (TextView) convertView.findViewById(R.id.label);
+                if (labelEmpty) {
+                    label.setVisibility(View.GONE);
+                } else {
+                    label.setText(entry.label);
+                    label.setVisibility(View.VISIBLE);
+                }
+
+                TextView number = (TextView) convertView.findViewById(R.id.number);
+                number.setText(entry.number);
+            }
+            
+            return convertView;
+        }
+    }
+    
+    public void onItemClick(AdapterView parent, View view, int position, long id) {
+        // Handle passing action off to correct handler.
+        if (view.getTag() instanceof ViewEntry) {
+            ViewEntry entry = (ViewEntry) view.getTag();
+            if (entry.intent != null) {
+                startActivity(entry.intent);
+            }
+        }
+    }    
+}
diff --git a/src/com/android/contacts/ContactEntryAdapter.java b/src/com/android/contacts/ContactEntryAdapter.java
new file mode 100644
index 0000000..c5b7ccf
--- /dev/null
+++ b/src/com/android/contacts/ContactEntryAdapter.java
@@ -0,0 +1,341 @@
+/*
+ * 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
+        People.PHONETIC_NAME, // 8
+    };
+    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 int CONTACT_PHONETIC_NAME_COLUMN = 8;
+
+    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..80b5166
--- /dev/null
+++ b/src/com/android/contacts/ContactsGroupSyncSelector.java
@@ -0,0 +1,256 @@
+/*
+ * 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 com.google.android.googlelogin.GoogleLoginServiceConstants;
+import com.google.android.googlelogin.GoogleLoginServiceHelper;
+
+import android.app.ListActivity;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.provider.Contacts;
+import android.provider.Gmail;
+import android.provider.Contacts.Groups;
+import android.provider.Contacts.Settings;
+import android.text.TextUtils;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+public final class ContactsGroupSyncSelector extends ListActivity implements View.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 static final int SUBACTIVITY_GET_ACCOUNT = 1;
+
+    boolean[] mChecked;
+    boolean mSyncAllGroups;
+    long[] mGroupIds;
+    
+    private final class GroupsAdapter extends ArrayAdapter<CharSequence> {
+        public GroupsAdapter(CharSequence[] items) {
+            super(ContactsGroupSyncSelector.this,
+                    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
+     */
+    @Override
+    protected void onListItemClick(ListView list, View view, int position, long id) {
+        boolean isChecked = list.isItemChecked(position);
+        mChecked[position] = isChecked;
+        if (position == 0) {
+            mSyncAllGroups = isChecked;
+            adjustChecks();
+        }
+    }
+
+    /**
+     * Handles clicks on the OK and cancel buttons
+     */
+    public void onClick(View view) {
+        switch (view.getId()) {
+            case R.id.cancel: {
+                finish();
+                break;
+            }
+            
+            case R.id.ok: {
+                // The list isn't setup yet, so just return without doing anything.
+                if (mChecked == null) {
+                    finish();
+                    return;
+                }
+
+                final ContentResolver resolver = getContentResolver();
+                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(resolver, null, Settings.SYNC_EVERYTHING, "1");
+                } else {
+                    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");
+                }
+                finish();
+                break;
+            }
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedState) {
+        super.onCreate(savedState);
+
+        // Only look for an account on first run.
+        if (savedState == null) {
+            // This will request a Gmail account and if none are present, it will
+            // invoke SetupWizard to login or create one. The result is returned
+            // through onActivityResult().
+            Bundle bundle = new Bundle();
+            bundle.putCharSequence("optional_message", getText(R.string.contactsSyncPlug));
+            GoogleLoginServiceHelper.getCredentials(this, SUBACTIVITY_GET_ACCOUNT,
+                    bundle, GoogleLoginServiceConstants.PREFER_HOSTED, Gmail.GMAIL_AUTH_SERVICE,
+                    true);
+        }
+
+        setContentView(R.layout.sync_settings);
+
+        findViewById(R.id.ok).setOnClickListener(this);
+        findViewById(R.id.cancel).setOnClickListener(this);
+        
+        getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
+        super.onActivityResult(requestCode, resultCode, intent);
+        if (requestCode == SUBACTIVITY_GET_ACCOUNT) {
+            if (resultCode == RESULT_OK) {
+                // There is an account setup, build the group list
+                buildItems();
+                adjustChecks();
+            } else {
+                finish();
+            }
+        }
+    }
+
+    private void buildItems() {
+        final ContentResolver resolver = getContentResolver();
+        Cursor cursor = resolver.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(resolver);
+                checked[0] = mSyncAllGroups;
+                mGroupIds = groupIds;
+    
+                // Setup the adapter
+                setListAdapter(new GroupsAdapter(items));
+            } finally {
+                cursor.close();
+            }
+        }
+    }
+
+    private void adjustChecks() {
+        final ListView list = getListView();
+        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..6e72fbd
--- /dev/null
+++ b/src/com/android/contacts/ContactsListActivity.java
@@ -0,0 +1,1518 @@
+/*
+ * 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.IContentProvider;
+import android.content.ISyncAdapter;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.database.CharArrayBuffer;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.os.RemoteException;
+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.text.TextUtils;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.Gravity;
+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.view.inputmethod.InputMethodManager;
+import android.widget.AdapterView;
+import android.widget.AlphabetIndexer;
+import android.widget.Filter;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.ResourceCursorAdapter;
+import android.widget.SectionIndexer;
+import android.widget.TextView;
+
+import java.lang.ref.WeakReference;
+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_SEARCH = 1;
+    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;
+
+    /**
+     * The type of data to display in the main contacts list. 
+     */
+    static final String PREF_DISPLAY_TYPE = "display_system_group";
+
+    /** Unknown display type. */
+    static final int DISPLAY_TYPE_UNKNOWN = -1;
+    /** Display all contacts */
+    static final int DISPLAY_TYPE_ALL = 0;
+    /** Display all contacts that have phone numbers */
+    static final int DISPLAY_TYPE_ALL_WITH_PHONES = 1;
+    /** Display a system group */
+    static final int DISPLAY_TYPE_SYSTEM_GROUP = 2;
+    /** Display a user group */
+    static final int DISPLAY_TYPE_USER_GROUP = 3;
+
+    /**
+     * Info about what to display. If {@link #PREF_DISPLAY_TYPE}
+     * is {@link #DISPLAY_TYPE_SYSTEM_GROUP} then this will be the system id.
+     * If {@link #PREF_DISPLAY_TYPE} is {@link #DISPLAY_TYPE_USER_GROUP} then this will
+     * be the group name.
+     */ 
+    static final String PREF_DISPLAY_INFO = "display_group";
+
+    
+    static final String NAME_COLUMN = 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;
+
+    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;
+    private boolean mSyncEnabled;
+
+    /**
+     * 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);
+
+        // 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;
+        }
+
+        // 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);
+        setListAdapter(mAdapter);
+
+        // We manually save/restore the listview state
+        list.setSaveEnabled(false);
+
+        mQueryHandler = new QueryHandler(this);
+        mJustCreated = true;
+
+        // Check to see if sync is enabled
+        final ContentResolver resolver = getContentResolver();
+        IContentProvider provider = resolver.acquireProvider(Contacts.CONTENT_URI);
+        if (provider == null) {
+            // No contacts provider, bail.
+            finish();
+            return;
+        }
+
+        try {
+            ISyncAdapter sa = provider.getSyncAdapter();
+            mSyncEnabled = sa != null;
+        } catch (RemoteException e) {
+            mSyncEnabled = false;
+        } finally {
+            resolver.releaseProvider(provider);
+        }
+    }
+
+    private void setEmptyText() {
+        TextView empty = (TextView) findViewById(R.id.emptyText);
+        // Center the text by default
+        int gravity = Gravity.CENTER;
+        switch (mMode) {
+            case MODE_GROUP:
+                if (Groups.GROUP_MY_CONTACTS.equals(mDisplayInfo)) {
+                    if (mSyncEnabled) {
+                        empty.setText(getText(R.string.noContactsHelpTextWithSync));
+                    } else {
+                        empty.setText(getText(R.string.noContactsHelpText));
+                    }
+                    gravity = Gravity.NO_GRAVITY;
+                } else {
+                    empty.setText(getString(R.string.groupEmpty, mDisplayInfo));
+                }
+                break;
+
+            case MODE_STARRED:
+            case MODE_STREQUENT:
+            case MODE_FREQUENT:
+                empty.setText(getText(R.string.noFavorites));
+                break;
+
+            case MODE_WITH_PHONES:
+                empty.setText(getText(R.string.noContactsWithPhoneNumbers));
+                break;
+
+            default:
+                empty.setText(getText(R.string.noContacts));
+                break;
+        }
+        empty.setGravity(gravity);
+    }
+
+    /**
+     * Builds the URIs to query when displaying a user group
+     * 
+     * @param groupName the group being displayed
+     */
+    private void buildUserGroupUris(String groupName) {
+        mGroupFilterUri = Uri.parse("content://contacts/groups/name/" + groupName
+                + "/members/filter/");
+        mGroupUri = Uri.parse("content://contacts/groups/name/" + groupName + "/members");
+    }
+
+    /**
+     * Builds the URIs to query when displaying a system group
+     * 
+     * @param systemId the system group's ID 
+     */
+    private void buildSystemGroupUris(String systemId) {
+        mGroupFilterUri = Uri.parse("content://contacts/groups/system_id/" + systemId
+                + "/members/filter/");
+        mGroupUri = Uri.parse("content://contacts/groups/system_id/" + systemId + "/members");
+    }
+
+    /**
+     * Sets the mode when the request is for "default"
+     */
+    private void setDefaultMode() {
+        // Load the preferences
+        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+        
+        // Lookup the group to display
+        mDisplayType = prefs.getInt(PREF_DISPLAY_TYPE, DISPLAY_TYPE_UNKNOWN);
+        switch (mDisplayType) {
+            case DISPLAY_TYPE_ALL_WITH_PHONES: {
+                mMode = MODE_WITH_PHONES;
+                mDisplayInfo = null;
+                break;
+            }
+
+            case DISPLAY_TYPE_SYSTEM_GROUP: {
+                String systemId = prefs.getString(
+                        PREF_DISPLAY_INFO, null);
+                if (!TextUtils.isEmpty(systemId)) {
+                    // Display the selected system group
+                    mMode = MODE_GROUP;
+                    buildSystemGroupUris(systemId);
+                    mDisplayInfo = systemId;
+                } else {
+                    // No valid group is present, display everything
+                    mMode = MODE_WITH_PHONES;
+                    mDisplayInfo = null;
+                    mDisplayType = DISPLAY_TYPE_ALL;
+                }
+                break;
+            }
+
+            case DISPLAY_TYPE_USER_GROUP: {
+                String displayGroup = prefs.getString(
+                        PREF_DISPLAY_INFO, null);
+                if (!TextUtils.isEmpty(displayGroup)) {
+                    // Display the selected user group
+                    mMode = MODE_GROUP;
+                    buildUserGroupUris(displayGroup);
+                    mDisplayInfo = displayGroup;
+                } else {
+                    // No valid group is present, display everything
+                    mMode = MODE_WITH_PHONES;
+                    mDisplayInfo = null;
+                    mDisplayType = DISPLAY_TYPE_ALL;
+                }
+                break;
+            }
+
+            case DISPLAY_TYPE_ALL: {
+                mMode = MODE_ALL_CONTACTS;
+                mDisplayInfo = null;
+                break;
+            }
+
+            default: {
+                // We don't know what to display, default to My Contacts
+                mMode = MODE_GROUP;
+                mDisplayType = DISPLAY_TYPE_SYSTEM_GROUP;
+                buildSystemGroupUris(Groups.GROUP_MY_CONTACTS);
+                mDisplayInfo = Groups.GROUP_MY_CONTACTS;
+                break;
+            }
+        }
+
+        // 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 (mJustCreated && runQuery) {
+            // We need to start a query here the first time the activity is launched, as long
+            // as we aren't doing a filter.
+            startQuery();
+        }
+        mJustCreated = false;
+    }
+    
+    @Override
+    protected void onRestart() {
+        super.onRestart();
+
+        // The cursor was killed off in onStop(), so we need to get a new one here
+        startQuery();
+    }
+    
+    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 onRestart() 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;
+        }
+
+        // Search
+        menu.add(0, MENU_SEARCH, 0, R.string.menu_search)
+                .setIcon(android.R.drawable.ic_menu_search);
+
+        // New contact
+        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');
+
+        // Display group
+        if (mDefaultMode) {
+            menu.add(0, MENU_DISPLAY_GROUP, 0, R.string.menu_displayGroup)
+                    .setIcon(com.android.internal.R.drawable.ic_menu_allfriends);
+        }
+
+        // Sync settings
+        if (mSyncEnabled) {
+            Intent syncIntent = new Intent(Intent.ACTION_VIEW);
+            syncIntent.setClass(this, ContactsGroupSyncSelector.class);
+            menu.add(0, 0, 0, R.string.syncGroupPreference)
+                    .setIcon(com.android.internal.R.drawable.ic_menu_refresh)
+                    .setIntent(syncIntent);
+        }
+        
+        // SIM import
+        Intent importIntent = new Intent(Intent.ACTION_VIEW);
+        importIntent.setType("vnd.android.cursor.item/sim-contact");
+        importIntent.setClassName("com.android.phone", "com.android.phone.SimContacts");
+        menu.add(0, 0, 0, R.string.importFromSim)
+                .setIcon(R.drawable.ic_menu_import_contact)
+                .setIntent(importIntent);
+
+        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 = DISPLAY_TYPE_ALL;
+                    mDisplayInfo = null;
+                } else if (mDisplayGroupCurrentSelection
+                        == DISPLAY_GROUP_INDEX_ALL_CONTACTS_WITH_PHONES) {
+                    // Display all with phone numbers
+                    mDisplayType = DISPLAY_TYPE_ALL_WITH_PHONES;
+                    mDisplayInfo = null;
+                } else if (mDisplayGroupsIncludesMyContacts &&
+                        mDisplayGroupCurrentSelection == DISPLAY_GROUP_INDEX_MY_CONTACTS) {
+                    mDisplayType = DISPLAY_TYPE_SYSTEM_GROUP;
+                    mDisplayInfo = Groups.GROUP_MY_CONTACTS;
+                } else {
+                    mDisplayType = DISPLAY_TYPE_USER_GROUP;
+                    mDisplayInfo = mDisplayGroups[mDisplayGroupCurrentSelection].toString();
+                }
+
+                // Save the changes to the preferences
+                SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+                prefs.edit()
+                        .putInt(PREF_DISPLAY_TYPE, mDisplayType)
+                        .putString(PREF_DISPLAY_INFO, mDisplayInfo)
+                        .commit();
+
+                // Update the display state
+                updateGroup();
+            }
+        } else {
+            // A list item was selected, cache the position
+            mDisplayGroupCurrentSelection = which;
+        }
+    }
+    
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case MENU_DISPLAY_GROUP:
+                AlertDialog.Builder builder = new AlertDialog.Builder(this)
+                    .setTitle(R.string.select_group_title)
+                    .setPositiveButton(android.R.string.ok, this)
+                    .setNegativeButton(android.R.string.cancel, null);
+                
+                setGroupEntries(builder);
+                
+                builder.show();
+                return true;
+
+            case MENU_SEARCH:
+                startSearch(null, false, null, false);
+                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(android.R.string.cancel, null)
+                    .setPositiveButton(android.R.string.ok, new DeleteClickListener(uri))
+                    .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(android.R.string.cancel, null)
+                        .setPositiveButton(android.R.string.ok, 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) {
+        // Hide soft keyboard, if visible
+        InputMethodManager inputMethodManager = (InputMethodManager)
+                getSystemService(Context.INPUT_METHOD_SERVICE);
+        inputMethodManager.hideSoftInputFromWindow(mList.getWindowToken(), 0);
+
+        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, 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, 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 == DISPLAY_TYPE_SYSTEM_GROUP
+                            && Groups.GROUP_MY_CONTACTS.equals(mDisplayInfo)) {
+                        currentIndex = DISPLAY_GROUP_INDEX_MY_CONTACTS;
+                    }
+                    mDisplayGroupsIncludesMyContacts = true;
+                }
+            }
+            if (mMode == MODE_ALL_CONTACTS) {
+                currentIndex = DISPLAY_GROUP_INDEX_ALL_CONTACTS;
+            } else if (mMode == MODE_WITH_PHONES) {
+                currentIndex = DISPLAY_GROUP_INDEX_ALL_CONTACTS_WITH_PHONES;
+            }
+            mDisplayGroups = groups.toArray(new CharSequence[groups.size()]);
+            builder.setSingleChoiceItems(mDisplayGroups,
+                    currentIndex, this);
+            mDisplayGroupOriginalSelection = currentIndex;
+        } finally {
+            cursor.close();
+        }
+    }
+
+    private static final class QueryHandler extends AsyncQueryHandler {
+        private final WeakReference<ContactsListActivity> mActivity;
+
+        public QueryHandler(Context context) {
+            super(context.getContentResolver());
+            mActivity = new WeakReference<ContactsListActivity>((ContactsListActivity) context);
+        }
+
+        @Override
+        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
+            final ContactsListActivity activity = mActivity.get();
+            if (activity != null && !activity.isFinishing()) {
+                activity.mAdapter.setLoading(false);
+                activity.getListView().clearTextFilter();                
+                activity.mAdapter.changeCursor(cursor);
+    
+                // Now that the cursor is populated again, it's possible to restore the list state
+                if (activity.mListState != null) {
+                    activity.mList.onRestoreInstanceState(activity.mListState);
+                    if (activity.mListHasFocus) {
+                        activity.mList.requestFocus();
+                    }
+                    activity.mListHasFocus = false;
+                    activity.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);
+        public ImageView presenceView;
+    }
+
+    private final class ContactItemListAdapter extends ResourceCursorAdapter 
+            implements SectionIndexer {
+        
+        private AlphabetIndexer mIndexer;
+        private String mAlphabet;
+        private boolean mLoading = true;
+        private CharSequence mUnknownNameText;
+        private CharSequence[] mLocalizedLabels;
+
+        public ContactItemListAdapter(Context context) {
+            super(context, R.layout.contacts_list_item, null, false);
+            
+            mAlphabet = context.getString(com.android.internal.R.string.fast_scroll_alphabet);
+            
+            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;
+            }
+        }
+
+        /**
+         * Callback on the UI thread when the content observer on the backing cursor fires.
+         * Instead of calling requery we need to do an async query so that the requery doesn't
+         * block the UI thread for a long time. 
+         */
+        @Override
+        protected void onContentChanged() {
+            CharSequence constraint = getListView().getTextFilter();
+            if (!TextUtils.isEmpty(constraint)) {
+                // Reset the filter state then start an async filter operation
+                Filter filter = getFilter();
+                filter.filter(constraint);
+            } else {
+                // Start an async query
+                startQuery();
+            }
+        }
+        
+        public void setLoading(boolean loading) {
+            mLoading = loading;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            if ((mMode & MODE_MASK_CREATE_NEW) == MODE_MASK_CREATE_NEW) {
+                // This mode mask adds a header and we always want it to show up, even
+                // if the list is empty, so always claim the list is not empty.
+                return false;
+            } else {
+                if (mLoading) {
+                    // We don't want the empty state to show when loading.
+                    return false;
+                } else {
+                    return super.isEmpty();
+                }
+            }
+        }
+        
+        @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.numberView = (TextView) view.findViewById(R.id.number);
+            cache.presenceView = (ImageView) view.findViewById(R.id.presence);
+            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;
+            TextView labelView = cache.labelView;
+            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);
+                labelView.setVisibility(View.VISIBLE);
+            } else {
+                numberView.setVisibility(View.GONE);
+                labelView.setVisibility(View.GONE);
+            }
+
+            // Set the label
+            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 {
+                // There is no label, hide the the view
+                labelView.setVisibility(View.GONE);
+            }
+
+            // Set the proper icon (star or presence or nothing)
+            ImageView presenceView = cache.presenceView;
+            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);
+                        presenceView.setImageResource(
+                                Presence.getPresenceIconResourceId(serverStatus));
+                        presenceView.setVisibility(View.VISIBLE);
+                    } else {
+                        presenceView.setVisibility(View.GONE);
+                    }
+                } else {
+                    presenceView.setVisibility(View.GONE);
+                }
+            } else {
+                if (cursor.getInt(STARRED_COLUMN_INDEX) != 0) {
+                    presenceView.setImageResource(R.drawable.star_on);
+                    presenceView.setVisibility(View.VISIBLE);
+                } else {
+                    presenceView.setVisibility(View.GONE);
+                }
+            }
+        }
+
+        @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 mIndexer.getSections();
+           }
+        }
+        
+        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.getPositionForSection(sectionIndex);
+        }
+        
+        public int getSectionForPosition(int position) {
+            return 0;
+        }        
+    }
+}
+
+
diff --git a/src/com/android/contacts/ContactsLiveFolders.java b/src/com/android/contacts/ContactsLiveFolders.java
new file mode 100644
index 0000000..8ca199a
--- /dev/null
+++ b/src/com/android/contacts/ContactsLiveFolders.java
@@ -0,0 +1,112 @@
+/*
+ * 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.Intent;
+import android.content.Context;
+import android.net.Uri;
+import android.app.Activity;
+import android.os.Bundle;
+import android.provider.LiveFolders;
+import android.provider.Contacts;
+
+public class ContactsLiveFolders {
+    public static class StarredContacts extends Activity {
+        public static final Uri CONTENT_URI =
+                Uri.parse("content://contacts/live_folders/favorites");
+
+        @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+
+            final Intent intent = getIntent();
+            final String action = intent.getAction();
+
+            if (LiveFolders.ACTION_CREATE_LIVE_FOLDER.equals(action)) {
+                setResult(RESULT_OK, createLiveFolder(this, CONTENT_URI,
+                        getString(R.string.liveFolder_favorites_label),
+                        R.drawable.ic_launcher_contacts_starred));
+            } else {
+                setResult(RESULT_CANCELED);
+            }
+
+            finish();
+        }
+    }
+
+    public static class PhoneContacts extends Activity {
+        public static final Uri CONTENT_URI =
+                Uri.parse("content://contacts/live_folders/people_with_phones");
+
+        @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+
+            final Intent intent = getIntent();
+            final String action = intent.getAction();
+
+            if (LiveFolders.ACTION_CREATE_LIVE_FOLDER.equals(action)) {
+                setResult(RESULT_OK, createLiveFolder(this, CONTENT_URI,
+                        getString(R.string.liveFolder_phones_label),
+                        R.drawable.ic_launcher_contacts_phones));
+            } else {
+                setResult(RESULT_CANCELED);
+            }
+
+            finish();
+        }
+    }
+
+    public static class AllContacts extends Activity {
+        public static final Uri CONTENT_URI =
+                Uri.parse("content://contacts/live_folders/people");
+
+        @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+
+            final Intent intent = getIntent();
+            final String action = intent.getAction();
+
+            if (LiveFolders.ACTION_CREATE_LIVE_FOLDER.equals(action)) {
+                setResult(RESULT_OK, createLiveFolder(this, CONTENT_URI,
+                        getString(R.string.liveFolder_all_label),
+                        R.drawable.ic_launcher_contacts));
+            } else {
+                setResult(RESULT_CANCELED);
+            }
+
+            finish();
+        }
+    }
+
+    private static Intent createLiveFolder(Context context, Uri uri, String name,
+            int icon) {
+
+        final Intent intent = new Intent();
+
+        intent.setData(uri);
+        intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_BASE_INTENT, new Intent(Intent.ACTION_VIEW,
+                Contacts.People.CONTENT_URI));
+        intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_NAME, name);
+        intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_ICON,
+                Intent.ShortcutIconResource.fromContext(context, icon));
+        intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_DISPLAY_MODE, LiveFolders.DISPLAY_MODE_LIST);
+
+        return intent;
+    }
+}
diff --git a/src/com/android/contacts/DialtactsActivity.java b/src/com/android/contacts/DialtactsActivity.java
new file mode 100644
index 0000000..d3f8981
--- /dev/null
+++ b/src/com/android/contacts/DialtactsActivity.java
@@ -0,0 +1,311 @@
+/*
+ * 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.Activity;
+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 implements TabHost.OnTabChangeListener {
+    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();
+        mTabHost.setOnTabChangedListener(this);
+
+        // 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;
+        }
+        
+        // Dismiss menu provided by any children activites
+        Activity activity = getLocalActivityManager().
+                getActivity(mTabHost.getCurrentTabTag());
+        if (activity != null) {
+            activity.closeOptionsMenu();
+        }
+
+        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);
+    }
+
+    /** {@inheritDoc} */
+    public void onTabChanged(String tabId) {
+        // Because we're using Activities as our tab children, we trigger
+        // onWindowFocusChanged() to let them know when they're active.  This may
+        // seem to duplicate the purpose of onResume(), but it's needed because
+        // onResume() can't reliably check if a keyguard is active.
+        Activity activity = getLocalActivityManager().getActivity(tabId);
+        if (activity != null) {
+            activity.onWindowFocusChanged(true);
+        }
+    }
+}
diff --git a/src/com/android/contacts/EditContactActivity.java b/src/com/android/contacts/EditContactActivity.java
new file mode 100644
index 0000000..49569e3
--- /dev/null
+++ b/src/com/android/contacts/EditContactActivity.java
@@ -0,0 +1,2108 @@
+/*
+ * 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_PHONETIC_NAME_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.ColorStateList;
+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.Groups;
+import android.provider.Contacts.Organizations;
+import android.provider.Contacts.People;
+import android.provider.Contacts.Phones;
+import android.telephony.PhoneNumberFormattingTextWatcher;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.text.method.TextKeyListener;
+import android.text.method.TextKeyListener.Capitalize;
+import android.util.Log;
+import android.util.SparseBooleanArray;
+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.view.inputmethod.EditorInfo;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+
+/**
+ * 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,
+        TextWatcher, View.OnFocusChangeListener {
+    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;
+    
+    // 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 DELETE_CONFIRMATION_DIALOG = 2;
+    
+    // Section IDs
+    final static int SECTION_PHONES = 3;
+    final static int SECTION_EMAIL = 4;
+    final static int SECTION_IM = 5;
+    final static int SECTION_POSTAL = 6;
+    final static int SECTION_ORG = 7;
+    final static int SECTION_NOTE = 8;
+
+    // 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_PHOTO = 6;
+    
+    /** 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 LinearLayout mLayout;
+    private LayoutInflater mInflater;
+    private MenuItem mPhotoMenuItem;
+    private boolean mPhotoPresent = false;
+    private EditText mPhoneticNameView;  // invisible in some locales, but always present
+
+    /** Flag marking this contact as changed, meaning we should write changes back. */
+    private boolean mContactChanged = 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> mOrgEntries = new ArrayList<EditEntry>();
+    /* package */ ArrayList<EditEntry> mNoteEntries = 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;
+
+    private static final int[] TYPE_PRECEDENCE_PHONES = new int[] {
+            Phones.TYPE_MOBILE, Phones.TYPE_HOME, Phones.TYPE_WORK, Phones.TYPE_OTHER
+    };
+    private static final int[] TYPE_PRECEDENCE_METHODS = new int[] {
+            ContactMethods.TYPE_HOME, ContactMethods.TYPE_WORK, ContactMethods.TYPE_OTHER
+    };
+    private static final int[] TYPE_PRECEDENCE_IM = new int[] {
+            ContactMethods.PROTOCOL_GOOGLE_TALK, ContactMethods.PROTOCOL_AIM,
+            ContactMethods.PROTOCOL_MSN, ContactMethods.PROTOCOL_YAHOO,
+            ContactMethods.PROTOCOL_JABBER
+    };
+    private static final int[] TYPE_PRECEDENCE_ORG = new int[] {
+            Organizations.TYPE_WORK, Organizations.TYPE_OTHER
+    };
+
+    public void onClick(View v) {
+        switch (v.getId()) {
+            case R.id.photoImage: {
+                doPickPhotoAction();
+                break;
+            }
+            
+            case R.id.checkable: {
+                CheckBox checkBox = (CheckBox) v.findViewById(R.id.checkbox);
+                checkBox.toggle();
+                
+                EditEntry entry = findEntryForView(v);
+                entry.data = checkBox.isChecked() ? "1" : "0";
+                
+                mContactChanged = true;
+                break;
+            }
+            
+            case R.id.entry_ringtone: {
+                EditEntry entry = findEntryForView(v);
+                doPickRingtone(entry);
+                break;
+            }
+            
+            case R.id.separator: {
+                // Someone clicked on a section header, so handle add action
+                int sectionType = (Integer) v.getTag();
+                doAddAction(sectionType);
+                break;
+            }
+
+            case R.id.saveButton:
+                doSaveAction();
+                break;
+
+            case R.id.discardButton:
+                doRevertAction();
+                break;
+
+            case R.id.delete: {
+                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;
+                }
+                
+                // Force rebuild of views because section headers might need to change
+                buildViews();
+                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;
+            }
+        }
+    }
+
+    private void setPhotoPresent(boolean present) {
+        mPhotoPresent = present;
+        
+        // Correctly scale the contact photo if present, otherwise just center
+        // the photo placeholder icon.
+        if (mPhotoPresent) {
+            mPhotoImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
+        } else {
+            mPhotoImageView.setImageResource(R.drawable.ic_menu_add_picture);
+            mPhotoImageView.setScaleType(ImageView.ScaleType.CENTER);
+        }
+        
+        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(R.drawable.ic_menu_add_picture);
+            }
+        }
+    }
+    
+    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);
+        mPhoneticNameView = (EditText) findViewById(R.id.phonetic_name);
+        
+        // Setup the bottom buttons
+        View 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();
+                }
+                setTitle(R.string.editContact_title_edit);
+                mState = STATE_EDIT;
+            } else if (action.equals(Intent.ACTION_INSERT)) {
+                if (icicle == null) {
+                    // Build the entries & views
+                    buildEntriesForInsert(getIntent().getExtras());
+                    buildViews();
+                }
+                setTitle(R.string.editContact_title_insert);
+                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(mOrgEntries);
+        mSections.add(mNoteEntries);
+        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("orgEntries", mOrgEntries);
+        outState.putParcelableArrayList("noteEntries", mNoteEntries);
+        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.putString("phoneticName", mPhoneticNameView.getText().toString());
+        outState.putBoolean("contactChanged", mContactChanged);
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Bundle inState) {
+        mPhoneEntries = inState.getParcelableArrayList("phoneEntries");
+        mEmailEntries = inState.getParcelableArrayList("emailEntries");
+        mImEntries = inState.getParcelableArrayList("imEntries");
+        mPostalEntries = inState.getParcelableArrayList("postalEntries");
+        mOrgEntries = inState.getParcelableArrayList("orgEntries");
+        mNoteEntries = inState.getParcelableArrayList("noteEntries");
+        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");
+        mPhoneticNameView.setText(inState.getString("phoneticName"));
+        mContactChanged = inState.getBoolean("contactChanged");
+
+        // 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);
+                mContactChanged = true;
+                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);
+        }
+
+        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_PHOTO:
+                if (!mPhotoPresent) {
+                    doPickPhotoAction();
+                } else {
+                    doRemovePhotoAction();
+                }
+                return true;
+        }
+
+        return false;
+    }
+    
+    /**
+     * Try guessing the next-best type of {@link EditEntry} to insert into the
+     * given list. We walk down the precedence list until we find a type that
+     * doesn't exist yet, or default to the lowest ranking type.
+     */
+    private int guessNextType(ArrayList<EditEntry> entries, int[] precedenceList) {
+        // Keep track of the types we've seen already
+        SparseBooleanArray existAlready = new SparseBooleanArray(entries.size());
+        for (int i = entries.size() - 1; i >= 0; i--) {
+            EditEntry entry = entries.get(i);
+            if (!entry.isDeleted) {
+                existAlready.put(entry.type, true);
+            }
+        }
+        
+        // Pick the first item we haven't seen
+        for (int type : precedenceList) {
+            if (!existAlready.get(type, false)) {
+                return type;
+            }
+        }
+        
+        // Otherwise default to last item
+        return precedenceList[precedenceList.length - 1];
+    }
+
+    private void doAddAction(int sectionType) {
+        EditEntry entry = null;
+        switch (sectionType) {
+            case SECTION_PHONES: {
+                // Try figuring out which type to insert next
+                int nextType = guessNextType(mPhoneEntries, TYPE_PRECEDENCE_PHONES);
+                entry = EditEntry.newPhoneEntry(EditContactActivity.this,
+                        Uri.withAppendedPath(mUri, People.Phones.CONTENT_DIRECTORY),
+                        nextType);
+                mPhoneEntries.add(entry);
+                break;
+            }
+            case SECTION_EMAIL: {
+                // Try figuring out which type to insert next
+                int nextType = guessNextType(mEmailEntries, TYPE_PRECEDENCE_METHODS);
+                entry = EditEntry.newEmailEntry(EditContactActivity.this,
+                        Uri.withAppendedPath(mUri, People.ContactMethods.CONTENT_DIRECTORY),
+                        nextType);
+                mEmailEntries.add(entry);
+                break;
+            }
+            case SECTION_IM: {
+                // Try figuring out which type to insert next
+                int nextType = guessNextType(mImEntries, TYPE_PRECEDENCE_IM);
+                entry = EditEntry.newImEntry(EditContactActivity.this,
+                        Uri.withAppendedPath(mUri, People.ContactMethods.CONTENT_DIRECTORY),
+                        nextType);
+                mImEntries.add(entry);
+                break;
+            }
+            case SECTION_POSTAL: {
+                int nextType = guessNextType(mPostalEntries, TYPE_PRECEDENCE_METHODS);
+                entry = EditEntry.newPostalEntry(EditContactActivity.this,
+                        Uri.withAppendedPath(mUri, People.ContactMethods.CONTENT_DIRECTORY),
+                        nextType);
+                mPostalEntries.add(entry);
+                break;
+            }
+            case SECTION_ORG: {
+                int nextType = guessNextType(mOrgEntries, TYPE_PRECEDENCE_ORG);
+                entry = EditEntry.newOrganizationEntry(EditContactActivity.this,
+                        Uri.withAppendedPath(mUri, Organizations.CONTENT_DIRECTORY),
+                        nextType);
+                mOrgEntries.add(entry);
+                break;
+            }
+            case SECTION_NOTE: {
+                entry = EditEntry.newNotesEntry(EditContactActivity.this, null, mUri);
+                mNoteEntries.add(entry);
+                break;
+            }
+        }
+        
+        // Rebuild the views if needed
+        if (entry != null) {
+            buildViews();
+            mContactChanged = true;
+
+            View dataView = entry.view.findViewById(R.id.data);
+            if (dataView == null) {
+                entry.view.requestFocus();
+            } else {
+                dataView.requestFocus();
+            }
+        }
+    }
+
+    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(android.R.string.ok, null)
+                .show();
+        }
+    }
+
+    private void doRemovePhotoAction() {
+        mPhoto = null;
+        mPhotoChanged = true;
+        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);
+        
+        Uri ringtoneUri;
+        if (entry.data != null) {
+            ringtoneUri = Uri.parse(entry.data);
+        } else {
+            // Otherwise pick default ringtone Uri so that something is selected.
+            ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
+        }
+        
+        // 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 = getOtherEntry(People.CUSTOM_RINGTONE);
+        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) {
+        String ringtoneName;
+        if (entry.data == null) {
+            ringtoneName = 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;
+            }
+            ringtoneName = ringtone.getTitle(this);
+        }
+        
+        updateDataView(entry, ringtoneName);
+    }
+    
+    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 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(android.R.string.cancel, null)
+                        .setPositiveButton(android.R.string.ok, 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;
+        }
+    }
+    
+    private EditEntry getOtherEntry(String column) {
+        for (int i = mOtherEntries.size() - 1; i >= 0; i--) {
+            EditEntry entry = mOtherEntries.get(i);
+            if (isOtherEntry(entry, column)) {
+                return entry;
+            }
+        }
+        return null;
+    }
+    
+    private static boolean isOtherEntry(EditEntry entry, String column) {
+        return entry != null && entry.column != null && entry.column.equals(column);
+    }
+    
+    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(android.R.string.ok, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int which) {
+                        entry.setLabel(EditContactActivity.this, ContactMethods.TYPE_CUSTOM,
+                                label.getText().toString());
+                        mContactChanged = true;
+
+                        if (addTo != null) {
+                            addTo.add(entry);
+                            buildViews();
+                            entry.view.requestFocus(View.FOCUS_DOWN);
+                        }
+                    }
+                })
+                .setNegativeButton(android.R.string.cancel, 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.PHONETIC_NAME, mPhoneticNameView.getText().toString());
+        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));
+
+            // Only notify user if we actually changed contact
+            if (mContactChanged || mPhotoChanged) {
+                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.PHONETIC_NAME, mPhoneticNameView.getText().toString());
+
+        // 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(ContactsListActivity.PREF_DISPLAY_TYPE,
+                ContactsListActivity.DISPLAY_TYPE_UNKNOWN);
+        if (displayType == ContactsListActivity.DISPLAY_TYPE_USER_GROUP) {
+            String displayGroup = prefs.getString(ContactsListActivity.PREF_DISPLAY_INFO,
+                    null);
+            if (!TextUtils.isEmpty(displayGroup)) {
+                People.addToGroup(mResolver, ContentUris.parseId(contactUri), displayGroup);
+            }
+        } else {
+            // Check to see if we're not syncing everything and if so if My Contacts is synced.
+            // If it isn't then the created contact can end up not in any groups that are
+            // currently synced and end up getting removed from the phone, which is really bad.
+            boolean syncingEverything = !"0".equals(Contacts.Settings.getSetting(mResolver, null,
+                    Contacts.Settings.SYNC_EVERYTHING));
+            if (!syncingEverything) {
+                boolean syncingMyContacts = false;
+                Cursor c = mResolver.query(Groups.CONTENT_URI, new String[] { Groups.SHOULD_SYNC },
+                        Groups.SYSTEM_ID + "=?", new String[] { Groups.GROUP_MY_CONTACTS }, null);
+                if (c != null) {
+                    try {
+                        if (c.moveToFirst()) {
+                            syncingMyContacts = !"0".equals(c.getString(0));
+                        }
+                    } finally {
+                        c.close();
+                    }
+                }
+
+                if (!syncingMyContacts) {
+                    // Not syncing My Contacts, so find a group that is being synced and stick
+                    // the contact in there. We sort the list so at least all contacts
+                    // will appear in the same group.
+                    c = mResolver.query(Groups.CONTENT_URI, new String[] { Groups._ID },
+                            Groups.SHOULD_SYNC + "!=0", null, Groups.DEFAULT_SORT_ORDER);
+                    if (c != null) {
+                        try {
+                            if (c.moveToFirst()) {
+                                People.addToGroup(mResolver, ContentUris.parseId(contactUri),
+                                        c.getLong(0));
+                            }
+                        } finally {
+                            c.close();
+                        }
+                    }
+                }
+            }
+        }
+
+        // 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));
+        mNameView.addTextChangedListener(this);
+
+        // Photo
+        mPhoto = People.loadContactPhoto(this, mUri, 0, null);
+        if (mPhoto == null) {
+            setPhotoPresent(false);
+        } else {
+            setPhotoPresent(true);
+            mPhotoImageView.setImageBitmap(mPhoto);
+        }
+        
+        // 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;
+                mOrgEntries.add(entry);
+            }
+            organizationsCursor.close();
+        }
+
+        // Notes
+        if (!personCursor.isNull(CONTACT_NOTES_COLUMN)) {
+            entry = EditEntry.newNotesEntry(this, personCursor.getString(CONTACT_NOTES_COLUMN),
+                    mUri);
+            mNoteEntries.add(entry);
+        }
+
+        // Ringtone
+        entry = EditEntry.newRingtoneEntry(this,
+                personCursor.getString(CONTACT_CUSTOM_RINGTONE_COLUMN), mUri);
+        mOtherEntries.add(entry);
+        
+        // Send to voicemail
+        entry = EditEntry.newSendToVoicemailEntry(this,
+                personCursor.getString(CONTACT_SEND_TO_VOICEMAIL_COLUMN), mUri);
+        mOtherEntries.add(entry);
+
+        // Phonetic name
+        mPhoneticNameView.setText(personCursor.getString(CONTACT_PHONETIC_NAME_COLUMN));
+        mPhoneticNameView.addTextChangedListener(this);
+
+        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);
+        }
+
+        mContactChanged = false;
+    }
+
+    /**
+     * 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);
+        
+        // Send to voicemail
+        entry = EditEntry.newSendToVoicemailEntry(this, "0", 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);
+        }
+
+        // Read the phonetic name from the bundle
+        CharSequence phoneticName = extras.getCharSequence(Insert.PHONETIC_NAME);
+        if (!TextUtils.isEmpty(phoneticName)) {
+            mPhoneticNameView.setText(phoneticName);
+        }
+
+        // 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
+        addEmailFromExtras(extras, methodsUri, Insert.EMAIL, Insert.EMAIL_TYPE,
+                Insert.EMAIL_ISPRIMARY);
+        addEmailFromExtras(extras, methodsUri, Insert.SECONDARY_EMAIL, Insert.SECONDARY_EMAIL_TYPE,
+                null);
+        addEmailFromExtras(extras, methodsUri, Insert.TERTIARY_EMAIL, Insert.TERTIARY_EMAIL_TYPE,
+                null);
+   
+        // Phone entries from extras
+        addPhoneFromExtras(extras, phonesUri, Insert.PHONE, Insert.PHONE_TYPE,
+                Insert.PHONE_ISPRIMARY);
+        addPhoneFromExtras(extras, phonesUri, Insert.SECONDARY_PHONE, Insert.SECONDARY_PHONE_TYPE,
+                null);
+        addPhoneFromExtras(extras, phonesUri, Insert.TERTIARY_PHONE, Insert.TERTIARY_PHONE_TYPE,
+                null);
+
+        // 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);
+        }
+    }
+
+    private void addEmailFromExtras(Bundle extras, Uri methodsUri, String emailField,
+            String typeField, String primaryField) {
+        CharSequence email = extras.getCharSequence(emailField);
+        
+        // Correctly handle String in typeField as TYPE_CUSTOM 
+        int emailType = INVALID_TYPE;
+        String customLabel = null;
+        if(extras.get(typeField) instanceof String) {
+            emailType = ContactMethods.TYPE_CUSTOM;
+            customLabel = extras.getString(typeField);
+        } else {
+            emailType = extras.getInt(typeField, INVALID_TYPE);
+        }
+
+        if (!TextUtils.isEmpty(email) && emailType == INVALID_TYPE) {
+            emailType = DEFAULT_EMAIL_TYPE;
+            mPrimaryEmailAdded = true;
+        }
+
+        if (emailType != INVALID_TYPE) {
+            EditEntry entry = EditEntry.newEmailEntry(this, customLabel, emailType, email.toString(),
+                    methodsUri, 0);
+            entry.isPrimary = (primaryField == null) ? false : extras.getBoolean(primaryField);
+            mEmailEntries.add(entry);
+
+            // Keep track of which primary types have been added
+            if (entry.isPrimary) {
+                mPrimaryEmailAdded = true;
+            }
+        }
+    }
+
+    private void addPhoneFromExtras(Bundle extras, Uri phonesUri, String phoneField,
+            String typeField, String primaryField) {
+        CharSequence phoneNumber = extras.getCharSequence(phoneField);
+        
+        // Correctly handle String in typeField as TYPE_CUSTOM 
+        int phoneType = INVALID_TYPE;
+        String customLabel = null;
+        if(extras.get(typeField) instanceof String) {
+            phoneType = Phones.TYPE_CUSTOM;
+            customLabel = extras.getString(typeField);
+        } else {
+            phoneType = extras.getInt(typeField, INVALID_TYPE);
+        }
+        
+        if (!TextUtils.isEmpty(phoneNumber) && phoneType == INVALID_TYPE) {
+            phoneType = DEFAULT_PHONE_TYPE;
+        }
+
+        if (phoneType != INVALID_TYPE) {
+            EditEntry entry = EditEntry.newPhoneEntry(this, customLabel, phoneType,
+                    phoneNumber.toString(), phonesUri, 0);
+            entry.isPrimary = (primaryField == null) ? false : extras.getBoolean(primaryField);
+            mPhoneEntries.add(entry);
+
+            // Keep track of which primary types have been added
+            if (phoneType == Phones.TYPE_MOBILE) {
+                mMobilePhoneAdded = true;
+            }
+        }
+    }
+
+    /**
+     * 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_edit, SECTION_PHONES);
+        buildViewsForSection(layout, mEmailEntries,
+                R.string.listSeparatorSendEmail_edit, SECTION_EMAIL);
+        buildViewsForSection(layout, mImEntries,
+                R.string.listSeparatorSendIm_edit, SECTION_IM);
+        buildViewsForSection(layout, mPostalEntries,
+                R.string.listSeparatorMapAddress_edit, SECTION_POSTAL);
+        buildViewsForSection(layout, mOrgEntries,
+                R.string.listSeparatorOrganizations, SECTION_ORG);
+        buildViewsForSection(layout, mNoteEntries,
+                R.string.label_notes, SECTION_NOTE);
+        
+        buildOtherViews(layout, mOtherEntries);
+    }
+
+
+    /**
+     * 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, int sectionType) {
+        
+        View divider = mInflater.inflate(R.layout.edit_divider, layout, false);
+        layout.addView(divider);
+        
+        // Count up undeleted children
+        int activeChildren = 0;
+        for (int i = section.size() - 1; i >= 0; i--) {
+            EditEntry entry = section.get(i);
+            if (!entry.isDeleted) {
+                activeChildren++;
+            }
+        }
+        
+        // Build the correct group header based on undeleted children
+        ViewGroup header;
+        if (activeChildren == 0) {
+            header = (ViewGroup) mInflater.inflate(R.layout.edit_separator_alone, layout, false);
+        } else {
+            header = (ViewGroup) mInflater.inflate(R.layout.edit_separator, layout, false);
+        }
+
+        // Because we're emulating a ListView, we need to handle focus changes
+        // with some additional logic.
+        header.setOnFocusChangeListener(this);
+        
+        TextView text = (TextView) header.findViewById(R.id.text);
+        text.setText(getText(separatorResource));
+        
+        // Force TextView to always default color if we have children.  This makes sure
+        // we don't change color when parent is pressed.
+        if (activeChildren > 0) {
+            ColorStateList stateList = text.getTextColors();
+            text.setTextColor(stateList.getDefaultColor());
+        }
+
+        View addView = header.findViewById(R.id.separator);
+        addView.setTag(Integer.valueOf(sectionType));
+        addView.setOnClickListener(this);
+        
+        // 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);
+                header.addView(view);
+            }
+        }
+        
+        layout.addView(header);
+    }
+    
+    private void buildOtherViews(final LinearLayout layout, ArrayList<EditEntry> section) {
+        // Build views for the current section, putting a divider between each one
+        for (EditEntry entry : section) {
+            View divider = mInflater.inflate(R.layout.edit_divider, layout, false);
+            layout.addView(divider);
+
+            entry.activity = this; // this could be null from when the state is restored
+            View view = buildViewForEntry(entry);
+            view.setOnClickListener(this);
+            layout.addView(view);
+        }
+        
+        View divider = mInflater.inflate(R.layout.edit_divider, layout, false);
+        layout.addView(divider);
+    }
+    
+    /**
+     * 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;
+
+        // Because we're emulating a ListView, we might need to handle focus changes
+        // with some additional logic.
+        if (entry.kind == Contacts.KIND_ORGANIZATION) {
+            view = mInflater.inflate(R.layout.edit_contact_entry_org, parent, false);
+        } else if (isOtherEntry(entry, People.CUSTOM_RINGTONE)) {
+            view = mInflater.inflate(R.layout.edit_contact_entry_ringtone, parent, false);
+            view.setOnFocusChangeListener(this);
+        } else if (isOtherEntry(entry, People.SEND_TO_VOICEMAIL)) {
+            view = mInflater.inflate(R.layout.edit_contact_entry_voicemail, parent, false);
+            view.setOnFocusChangeListener(this);
+        } 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);
+            }
+        }
+        int contentType = entry.contentType;
+        if (contentType != EditorInfo.TYPE_NULL) {
+            data.setInputType(contentType);
+            if (data2 != null) {
+                data2.setInputType(contentType);
+            }
+            if ((contentType&EditorInfo.TYPE_MASK_CLASS)
+                    == EditorInfo.TYPE_CLASS_PHONE) {
+                data.addTextChangedListener(new PhoneNumberFormattingTextWatcher());
+                if (data2 != null) {
+                    data2.addTextChangedListener(new PhoneNumberFormattingTextWatcher());
+                }
+            }
+        }
+
+        // Connect listeners up to watch for changed values.
+        if (data instanceof EditText) {
+            data.addTextChangedListener(this);
+        }
+        if (data2 instanceof EditText) {
+            data2.addTextChangedListener(this);
+        }
+
+        // Hook up the delete button
+        View delete = view.findViewById(R.id.delete);
+        if (delete != null) delete.setOnClickListener(this);
+        
+        return view;
+    }
+
+    private void fillViewData(final EditEntry entry) {
+        if (isOtherEntry(entry, People.CUSTOM_RINGTONE)) {
+            updateRingtoneView(entry);
+        } else if (isOtherEntry(entry, People.SEND_TO_VOICEMAIL)) {
+            CheckBox checkBox = (CheckBox) entry.view.findViewById(R.id.checkbox);
+            boolean sendToVoicemail = false;
+            if (entry.data != null) {
+                sendToVoicemail = (Integer.valueOf(entry.data) == 1);
+            }
+            checkBox.setChecked(sendToVoicemail);
+        }
+    }
+    
+    /**
+     * 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]);
+                    mContactChanged = true;
+                }
+            } else {
+                mEntry.setLabel(EditContactActivity.this, which, mLabels[which]);
+                mContactChanged = true;
+            }
+        }
+    }
+
+    /**
+     * 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 contentType;
+        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(contentType);
+            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.contentType = 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;
+            }
+
+            // Only set the ISPRIMARY flag if part of the incoming data.  This is because the
+            // ContentProvider will try finding a new primary when setting to false, meaning
+            // it's possible to lose primary altogether as we walk down the list.  If this editor
+            // implements editing of primaries in the future, this will need to be revisited.
+            if (isPrimary) {
+                values.put(ContactMethods.ISPRIMARY, 1);
+            }
+
+            // 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.contentType = EditorInfo.TYPE_CLASS_TEXT
+                    | EditorInfo.TYPE_TEXT_FLAG_CAP_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.contentType = EditorInfo.TYPE_CLASS_TEXT
+                    | EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES
+                    | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
+            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 send-to-voicemail entry with the given data.
+         */
+        public static final EditEntry newSendToVoicemailEntry(EditContactActivity activity,
+                String data, Uri uri) {
+            EditEntry entry = new EditEntry(activity);
+            entry.label = activity.getString(R.string.actionIncomingCall);
+            entry.data = data;
+            entry.uri = uri;
+            entry.column = People.SEND_TO_VOICEMAIL;
+            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.contentType = EditorInfo.TYPE_CLASS_PHONE;
+            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.contentType = EditorInfo.TYPE_CLASS_TEXT
+                    | EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+            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.contentType = EditorInfo.TYPE_CLASS_TEXT
+                    | EditorInfo.TYPE_TEXT_VARIATION_POSTAL_ADDRESS
+                    | EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS
+                    | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
+            entry.maxLines = 4;
+            entry.lines = 2;
+            return entry;
+        }
+
+        /**
+         * Create a new IM address entry
+         */
+        public static final EditEntry newImEntry(EditContactActivity activity,
+                Uri uri, int type) {
+            return newImEntry(activity, null, type, null, uri, 0);
+        }
+
+        /**
+         * Create a new IM 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.contentType = EditorInfo.TYPE_CLASS_TEXT;
+            return entry;
+        }
+    }
+
+    public void afterTextChanged(Editable s) {
+        // Someone edited a text field, so assume this contact is changed
+        mContactChanged = true;
+    }
+
+    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+        // Do nothing; editing handled by afterTextChanged()
+    }
+
+    public void onTextChanged(CharSequence s, int start, int before, int count) {
+        // Do nothing; editing handled by afterTextChanged()
+    }
+    
+    public void onFocusChange(View v, boolean hasFocus) {
+        // Because we're emulating a ListView, we need to setSelected() for
+        // views as they are focused.
+        v.setSelected(hasFocus);
+    }
+}
diff --git a/src/com/android/contacts/RecentCallsListActivity.java b/src/com/android/contacts/RecentCallsListActivity.java
new file mode 100644
index 0000000..dbf2879
--- /dev/null
+++ b/src/com/android/contacts/RecentCallsListActivity.java
@@ -0,0 +1,828 @@
+/*
+ * 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.provider.CallLog;
+import android.provider.CallLog.Calls;
+import android.provider.Contacts.People;
+import android.provider.Contacts.Phones;
+import android.provider.Contacts.Intents.Insert;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.text.format.DateUtils;
+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;
+import java.lang.ref.WeakReference;
+
+/**
+ * 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.DISPLAY_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 final LinkedList<CallerInfoQuery> mRequests;
+        private volatile 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;
+        private Thread mCallerIdThread;
+
+        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;
+            mCallerIdThread = new Thread(this);
+            mCallerIdThread.setPriority(Thread.MIN_PRIORITY);
+            mCallerIdThread.start();
+        }
+
+        public void stopRequestProcessing() {
+            mDone = true;
+            if (mCallerIdThread != null) mCallerIdThread.interrupt();
+        }
+
+        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,
+                                    Uri.encode(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);
+                } else {
+                    // Just a raw number, format it to look pretty
+                    number = PhoneNumberUtils.formatNumber(number);
+                }
+
+                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 date/time field by mixing relative and absolute times.
+            int flags = DateUtils.FORMAT_ABBREV_RELATIVE | DateUtils.FORMAT_SHOW_DATE
+                    | DateUtils.FORMAT_ABBREV_MONTH;
+            
+            views.dateView.setText(DateUtils.getRelativeDateTimeString(context, date,
+                    DateUtils.MINUTE_IN_MILLIS, DateUtils.DAY_IN_MILLIS * 2, flags));
+
+            // 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 static final class QueryHandler extends AsyncQueryHandler {
+        private final WeakReference<RecentCallsListActivity> mActivity;
+
+        public QueryHandler(Context context) {
+            super(context.getContentResolver());
+            mActivity = new WeakReference<RecentCallsListActivity>(
+                    (RecentCallsListActivity) context);
+        }
+
+        @Override
+        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
+            final RecentCallsListActivity activity = mActivity.get();
+            if (activity != null && !activity.isFinishing()) {
+                final RecentCallsListActivity.RecentCallsAdapter callsAdapter = activity.mAdapter;
+                callsAdapter.setLoading(false);
+                callsAdapter.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();
+
+        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();
+        mAdapter.stopRequestProcessing();
+        Cursor cursor = mAdapter.getCursor();
+        if (cursor != null && !cursor.isClosed()) {
+            cursor.close();
+        }
+    }
+
+    @Override
+    public void onWindowFocusChanged(boolean hasFocus) {
+        super.onWindowFocusChanged(hasFocus);
+        
+        // Clear notifications only when window gains focus.  This activity won't
+        // immediately receive focus if the keyguard screen is above it.
+        if (hasFocus) {
+            try {
+                ITelephony iTelephony =
+                        ITelephony.Stub.asInterface(ServiceManager.getService("phone"));
+                if (iTelephony != null) {
+                    iTelephony.cancelMissedCallsNotification();
+                } else {
+                    Log.w(TAG, "Telephony service is null, can't call " +
+                            "cancelMissedCallsNotification");
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to clear missed calls notification due to remote exception");
+            }
+        }
+    }
+
+    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) {
+        Intent intent = new Intent(this, CallDetailActivity.class);
+        intent.setData(ContentUris.withAppendedId(CallLog.Calls.CONTENT_URI, id));
+        startActivity(intent);
+    }
+}
diff --git a/src/com/android/contacts/SpecialCharSequenceMgr.java b/src/com/android/contacts/SpecialCharSequenceMgr.java
new file mode 100644
index 0000000..38bc93d
--- /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(android.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..c80e67b
--- /dev/null
+++ b/src/com/android/contacts/TwelveKeyDialer.java
@@ -0,0 +1,913 @@
+/*
+ * 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.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+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.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.provider.Contacts.Intents.Insert;
+import android.provider.Contacts.People;
+import android.provider.Contacts.Phones;
+import android.provider.Contacts.PhonesColumns;
+import android.provider.Settings;
+import android.telephony.PhoneNumberFormattingTextWatcher;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.PhoneStateListener;
+import android.telephony.TelephonyManager;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.text.method.DialerKeyListener;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.android.internal.telephony.ITelephony;
+
+/**
+ * Dialer activity that displays the typical twelve key interface.
+ */
+public class TwelveKeyDialer extends Activity implements View.OnClickListener,
+        View.OnLongClickListener, View.OnKeyListener,
+        AdapterView.OnItemClickListener, 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;
+    private View mDigitsAndBackspace;
+    private View mDialpad;
+    private ListView mDialpadChooser;
+    private DialpadChooserAdapter mDialpadChooserAdapter;
+
+    // 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;
+
+    PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+            /**
+             * Listen for phone state changes so that we can take down the
+             * "dialpad chooser" if the phone becomes idle while the
+             * chooser UI is visible.
+             */
+            @Override
+            public void onCallStateChanged(int state, String incomingNumber) {
+                // Log.i(TAG, "PhoneStateListener.onCallStateChanged: "
+                //       + state + ", '" + incomingNumber + "'");
+                if ((state == TelephonyManager.CALL_STATE_IDLE) && dialpadChooserVisible()) {
+                    // Log.i(TAG, "Call ended with dialpad chooser visible!  Taking it down...");
+                    // Note there's a race condition in the UI here: the
+                    // dialpad chooser could conceivably disappear (on its
+                    // own) at the exact moment the user was trying to select
+                    // one of the choices, which would be confusing.  (But at
+                    // least that's better than leaving the dialpad chooser
+                    // onscreen, but useless...)
+                    showDialpadChooser(false);
+                }
+            }
+        };
+
+    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;
+
+        mDigitsAndBackspace = (View) findViewById(R.id.digitsAndBackspace);
+        mDialpad = (View) findViewById(R.id.dialpad);  // This is null in landscape mode
+
+        // Set up the "dialpad chooser" UI; see showDialpadChooser().
+        mDialpadChooser = (ListView) findViewById(R.id.dialpadChooser);
+        mDialpadChooser.setOnItemClickListener(this);
+
+        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_VOICE_CALL, 
+                            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();
+        }
+        // Log.i(TAG, "==> resolveIntent(): intent: " + intent);
+
+        // by default we are not adding a call.
+        mIsAddCallMode = false;
+
+        // By default we don't show the "dialpad chooser" UI.
+        boolean needToShowDialpadChooser = 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();
+                        }
+                    }
+                }
+            }
+        } else if (Intent.ACTION_MAIN.equals(action)) {
+            // The MAIN action means we're bringing up a blank dialer
+            // (e.g. by selecting the Home shortcut, or tabbing over from
+            // Contacts or Call log.)
+            //
+            // At this point, IF there's already an active call, there's a
+            // good chance that the user got here accidentally (but really
+            // wanted the in-call dialpad instead).  So we bring up an
+            // intermediate UI to make the user confirm what they really
+            // want to do.
+            if (phoneIsInUse()) {
+                // Log.i(TAG, "resolveIntent(): phone is in use; showing dialpad chooser!");
+                needToShowDialpadChooser = true;
+            }
+        }
+
+        // Bring up the "dialpad chooser" IFF we need to make the user
+        // confirm which dialpad they really want.
+        showDialpadChooser(needToShowDialpadChooser);
+
+        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_VOICE_CALL, 
+                            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();
+            }
+        }
+
+        // While we're in the foreground, listen for phone state changes,
+        // purely so that we can take down the "dialpad chooser" if the
+        // phone becomes idle while the chooser UI is visible.
+        TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
+        telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
+
+        // Potentially show hint text in the mDigits field when the user
+        // hasn't typed any digits yet.  (If there's already an active call,
+        // this hint text will remind the user that he's about to add a new
+        // call.)
+        //
+        // TODO: consider adding better UI for the case where *both* lines
+        // are currently in use.  (Right now we let the user try to add
+        // another call, but that call is guaranteed to fail.  Perhaps the
+        // entire dialer UI should be disabled instead.)
+        if (phoneIsInUse()) {
+            mDigits.setHint(R.string.dialerDialpadHintText);
+        } else {
+            // Common case; no hint necessary.
+            mDigits.setHint(null);
+
+            // Also, a sanity-check: the "dialpad chooser" UI should NEVER
+            // be visible if the phone is idle!
+            showDialpadChooser(false);
+        }
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        // Stop listening for phone state changes.
+        TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
+        telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
+
+        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) {
+        // We never show a menu if the "choose dialpad" UI is up.
+        if (dialpadChooserVisible()) {
+            return false;
+        }
+
+        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);
+        }
+    }
+
+    /**
+     * Brings up the "dialpad chooser" UI in place of the usual Dialer
+     * elements (the textfield/button and the dialpad underneath).
+     *
+     * We show this UI if the user brings up the Dialer while a call is
+     * already in progress, since there's a good chance we got here
+     * accidentally (and the user really wanted the in-call dialpad instead).
+     * So in this situation we display an intermediate UI that lets the user
+     * explicitly choose between the in-call dialpad ("Use touch tone
+     * keypad") and the regular Dialer ("Add call").  (Or, the option "Return
+     * to call in progress" just goes back to the in-call UI with no dialpad
+     * at all.)
+     *
+     * @param enabled If true, show the "dialpad chooser" instead
+     *                of the regular Dialer UI
+     */
+    private void showDialpadChooser(boolean enabled) {
+        if (enabled) {
+            // Log.i(TAG, "Showing dialpad chooser!");
+            mDigitsAndBackspace.setVisibility(View.GONE);
+            if (mDialpad != null) mDialpad.setVisibility(View.GONE);
+            mDialpadChooser.setVisibility(View.VISIBLE);
+
+            // Instantiate the DialpadChooserAdapter and hook it up to the
+            // ListView.  We do this only once.
+            if (mDialpadChooserAdapter == null) {
+                mDialpadChooserAdapter = new DialpadChooserAdapter(this);
+                mDialpadChooser.setAdapter(mDialpadChooserAdapter);
+            }
+        } else {
+            // Log.i(TAG, "Displaying normal Dialer UI.");
+            mDigitsAndBackspace.setVisibility(View.VISIBLE);
+            if (mDialpad != null) mDialpad.setVisibility(View.VISIBLE);
+            mDialpadChooser.setVisibility(View.GONE);
+        }
+    }
+
+    /**
+     * @return true if we're currently showing the "dialpad chooser" UI.
+     */
+    private boolean dialpadChooserVisible() {
+        return mDialpadChooser.getVisibility() == View.VISIBLE;
+    }
+
+    /**
+     * Simple list adapter, binding to an icon + text label
+     * for each item in the "dialpad chooser" list.
+     */
+    private static class DialpadChooserAdapter extends BaseAdapter {
+        private LayoutInflater mInflater;
+
+        // Simple struct for a single "choice" item.
+        static class ChoiceItem {
+            String text;
+            Bitmap icon;
+            int id;
+
+            public ChoiceItem(String s, Bitmap b, int i) {
+                text = s;
+                icon = b;
+                id = i;
+            }
+        }
+
+        // IDs for the possible "choices":
+        static final int DIALPAD_CHOICE_USE_DTMF_DIALPAD = 101;
+        static final int DIALPAD_CHOICE_RETURN_TO_CALL = 102;
+        static final int DIALPAD_CHOICE_ADD_NEW_CALL = 103;
+
+        private static final int NUM_ITEMS = 3;
+        private ChoiceItem mChoiceItems[] = new ChoiceItem[NUM_ITEMS];
+
+        public DialpadChooserAdapter(Context context) {
+            // Cache the LayoutInflate to avoid asking for a new one each time.
+            mInflater = LayoutInflater.from(context);
+
+            // Initialize the possible choices.
+            // TODO: could this be specified entirely in XML?
+
+            // - "Use touch tone keypad"
+            mChoiceItems[0] = new ChoiceItem(
+                    context.getString(R.string.dialer_useDtmfDialpad),
+                    BitmapFactory.decodeResource(context.getResources(),
+                                                 R.drawable.ic_dialer_fork_tt_keypad),
+                    DIALPAD_CHOICE_USE_DTMF_DIALPAD);
+
+            // - "Return to call in progress"
+            mChoiceItems[1] = new ChoiceItem(
+                    context.getString(R.string.dialer_returnToInCallScreen),
+                    BitmapFactory.decodeResource(context.getResources(),
+                                                 R.drawable.ic_dialer_fork_current_call),
+                    DIALPAD_CHOICE_RETURN_TO_CALL);
+
+            // - "Add call"
+            mChoiceItems[2] = new ChoiceItem(
+                    context.getString(R.string.dialer_addAnotherCall),
+                    BitmapFactory.decodeResource(context.getResources(),
+                                                 R.drawable.ic_dialer_fork_add_call),
+                    DIALPAD_CHOICE_ADD_NEW_CALL);
+        }
+
+        public int getCount() {
+            return NUM_ITEMS;
+        }
+
+        /**
+         * Return the ChoiceItem for a given position.
+         */
+        public Object getItem(int position) {
+            return mChoiceItems[position];
+        }
+
+        /**
+         * Return a unique ID for each possible choice.
+         */
+        public long getItemId(int position) {
+            return position;
+        }
+
+        /**
+         * Make a view for each row.
+         */
+        public View getView(int position, View convertView, ViewGroup parent) {
+            // When convertView is non-null, we can reuse it (there's no need
+            // to reinflate it.)
+            if (convertView == null) {
+                convertView = mInflater.inflate(R.layout.dialpad_chooser_list_item, null);
+            }
+
+            TextView text = (TextView) convertView.findViewById(R.id.text);
+            text.setText(mChoiceItems[position].text);
+
+            ImageView icon = (ImageView) convertView.findViewById(R.id.icon);
+            icon.setImageBitmap(mChoiceItems[position].icon);
+
+            return convertView;
+        }
+    }
+
+    /**
+     * Handle clicks from the dialpad chooser.
+     */
+    public void onItemClick(AdapterView parent, View v, int position, long id) {
+        DialpadChooserAdapter.ChoiceItem item =
+                (DialpadChooserAdapter.ChoiceItem) parent.getItemAtPosition(position);
+        int itemId = item.id;
+        switch (itemId) {
+            case DialpadChooserAdapter.DIALPAD_CHOICE_USE_DTMF_DIALPAD:
+                // Log.i(TAG, "DIALPAD_CHOICE_USE_DTMF_DIALPAD");
+                // Fire off an intent to go back to the in-call UI
+                // with the dialpad visible.
+                returnToInCallScreen(true);
+                break;
+
+            case DialpadChooserAdapter.DIALPAD_CHOICE_RETURN_TO_CALL:
+                // Log.i(TAG, "DIALPAD_CHOICE_RETURN_TO_CALL");
+                // Fire off an intent to go back to the in-call UI
+                // (with the dialpad hidden).
+                returnToInCallScreen(false);
+                break;
+
+            case DialpadChooserAdapter.DIALPAD_CHOICE_ADD_NEW_CALL:
+                // Log.i(TAG, "DIALPAD_CHOICE_ADD_NEW_CALL");
+                // Ok, guess the user really did want to be here (in the
+                // regular Dialer) after all.  Bring back the normal Dialer UI.
+                showDialpadChooser(false);
+                break;
+
+            default:
+                Log.w(TAG, "onItemClick: unexpected itemId: " + itemId);
+                break;
+        }
+    }
+
+    /**
+     * Returns to the in-call UI (where there's presumably a call in
+     * progress) in response to the user selecting "use touch tone keypad"
+     * or "return to call" from the dialpad chooser.
+     */
+    private void returnToInCallScreen(boolean showDialpad) {
+        try {
+            ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
+            if (phone != null) phone.showCallScreenWithDialpad(showDialpad);
+        } catch (RemoteException e) {
+            Log.w(TAG, "phone.showCallScreenWithDialpad() failed", e);
+        }
+
+        // Finally, finish() ourselves so that we don't stay on the
+        // activity stack.
+        // Note that we do this whether or not the showCallScreenWithDialpad()
+        // call above had any effect or not!  (That call is a no-op if the
+        // phone is idle, which can happen if the current call ends while
+        // the dialpad chooser is up.  In this case we can't show the
+        // InCallScreen, and there's no point staying here in the Dialer,
+        // so we just take the user back where he came from...)
+        finish();
+    }
+
+    /**
+     * @return true if the phone is "in use", meaning that at least one line
+     *              is active (ie. off hook or ringing or dialing).
+     */
+    private boolean phoneIsInUse() {
+        boolean phoneInUse = false;
+        try {
+            ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
+            if (phone != null) phoneInUse = !phone.isIdle();
+        } catch (RemoteException e) {
+            Log.w(TAG, "phone.isIdle() failed", e);
+        }
+        return phoneInUse;
+    }
+}
diff --git a/src/com/android/contacts/ViewContactActivity.java b/src/com/android/contacts/ViewContactActivity.java
new file mode 100644
index 0000000..99e72b0
--- /dev/null
+++ b/src/com/android/contacts/ViewContactActivity.java
@@ -0,0 +1,1032 @@
+/*
+ * 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_PHONETIC_NAME_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.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+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;
+import java.util.List;
+
+/**
+ * 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 String SHOW_BARCODE_INTENT = "com.google.zxing.client.android.ENCODE";
+
+    private static final boolean SHOW_SEPARATORS = false;
+    
+    private static final String[] PHONE_KEYS = {
+        Contacts.Intents.Insert.PHONE,
+        Contacts.Intents.Insert.SECONDARY_PHONE,
+        Contacts.Intents.Insert.TERTIARY_PHONE
+    };
+
+    private static final String[] EMAIL_KEYS = {
+        Contacts.Intents.Insert.EMAIL,
+        Contacts.Intents.Insert.SECONDARY_EMAIL,
+        Contacts.Intents.Insert.TERTIARY_EMAIL
+    };
+
+    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;
+    public static final int MENU_ITEM_SHOW_BARCODE = 3;
+
+    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 TextView mPhoneticNameView;  // may be null in some locales
+    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);
+        mPhoneticNameView = (TextView) findViewById(R.id.phonetic_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(android.R.string.cancel, null)
+                        .setPositiveButton(android.R.string.ok, 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);
+            }
+
+            if (mPhoneticNameView != null) {
+                String phoneticName = mCursor.getString(CONTACT_PHONETIC_NAME_COLUMN);
+                mPhoneticNameView.setText(phoneticName);
+            }
+
+            // 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, SHOW_SEPARATORS);
+            }
+        } 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 boolean onPrepareOptionsMenu(Menu menu) {
+        super.onPrepareOptionsMenu(menu);
+        // Perform this check each time the menu is about to be shown, because the Barcode Scanner
+        // could be installed or uninstalled at any time.
+        if (isBarcodeScannerInstalled()) {
+            if (menu.findItem(MENU_ITEM_SHOW_BARCODE) == null) {
+                menu.add(0, MENU_ITEM_SHOW_BARCODE, 0, R.string.menu_showBarcode)
+                        .setIcon(R.drawable.ic_menu_show_barcode);
+            }
+        } else {
+            menu.removeItem(MENU_ITEM_SHOW_BARCODE);
+        }
+        return true;
+    }
+
+    private boolean isBarcodeScannerInstalled() {
+        final Intent intent = new Intent(SHOW_BARCODE_INTENT);
+        ResolveInfo ri = getPackageManager().resolveActivity(intent,
+                PackageManager.MATCH_DEFAULT_ONLY);
+        return ri != null;
+    }
+
+    @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, SHOW_SEPARATORS);
+        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;
+            }
+            case MENU_ITEM_SHOW_BARCODE:
+                if (mCursor.moveToFirst()) {
+                    Intent intent = new Intent(SHOW_BARCODE_INTENT);
+                    intent.putExtra("ENCODE_TYPE", "CONTACT_TYPE");
+                    Bundle bundle = new Bundle();
+                    String name = mCursor.getString(CONTACT_NAME_COLUMN);
+                    if (!TextUtils.isEmpty(name)) {
+                        bundle.putString(Contacts.Intents.Insert.NAME, name);
+                        // The 0th ViewEntry in each ArrayList below is a separator item
+                        int entriesToAdd = Math.min(mPhoneEntries.size() - 1, PHONE_KEYS.length);
+                        for (int x = 0; x < entriesToAdd; x++) {
+                            ViewEntry entry = mPhoneEntries.get(x + 1);
+                            bundle.putString(PHONE_KEYS[x], entry.data);
+                        }
+                        entriesToAdd = Math.min(mEmailEntries.size() - 1, EMAIL_KEYS.length);
+                        for (int x = 0; x < entriesToAdd; x++) {
+                            ViewEntry entry = mEmailEntries.get(x + 1);
+                            bundle.putString(EMAIL_KEYS[x], entry.data);
+                        }
+                        if (mPostalEntries.size() >= 2) {
+                            ViewEntry entry = mPostalEntries.get(1);
+                            bundle.putString(Contacts.Intents.Insert.POSTAL, entry.data);
+                        }
+                        intent.putExtra("ENCODE_DATA", bundle);
+                        try {
+                            startActivity(intent);
+                        } catch (ActivityNotFoundException e) {
+                            // The check in onPrepareOptionsMenu() should make this impossible, but
+                            // for safety I'm catching the exception rather than crashing. Ideally
+                            // I'd call Menu.removeItem() here too, but I don't see a way to get
+                            // the options menu.
+                            Log.e(TAG, "Show barcode menu item was clicked but Barcode Scanner " +
+                                    "was not installed.");
+                        }
+                        return true;
+                    }
+                }
+                break;
+        }
+        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,
+                        SHOW_SEPARATORS);
+                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, SHOW_SEPARATORS);
+                    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, SHOW_SEPARATORS);
+        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);
+    }
+
+    private Uri constructImToUrl(String host, String data) {
+	    // don't encode the url, because the Activity Manager can't find using the encoded url
+        StringBuilder buf = new StringBuilder("imto://");
+        buf.append(host);
+        buf.append('/');
+        buf.append(data);
+        return Uri.parse(buf.toString());
+    }
+
+    /**
+     * 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();
+        }
+
+        if (SHOW_SEPARATORS) {
+            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();
+                final CharSequence displayLabel = Phones.getDisplayLabel(this, type, label);
+                entry.label = buildActionString(R.string.actionCall, displayLabel, true);
+                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 = android.R.drawable.sym_action_call;
+                mPhoneEntries.add(entry);
+
+                if (type == Phones.TYPE_MOBILE || mShowSmsLinksForAllPhones) {
+                    // Add an SMS entry
+                    ViewEntry smsEntry = new ViewEntry();
+                    smsEntry.label = buildActionString(R.string.actionText, displayLabel, true);
+                    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 = buildActionString(R.string.actionEmail,
+                                ContactMethods.getDisplayLabel(this, kind, type, label), true);
+                        entry.data = data;
+                        entry.intent = new Intent(Intent.ACTION_SENDTO,
+                                Uri.fromParts("mailto", data, null));
+                        entry.actionIcon = android.R.drawable.sym_action_email;
+                        mEmailEntries.add(entry);
+                        break;
+
+                    case Contacts.KIND_POSTAL:
+                        entry.label = buildActionString(R.string.actionMap,
+                                ContactMethods.getDisplayLabel(this, kind, type, label), true);
+                        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 host;
+                        if (protocolObj instanceof Number) {
+                            int protocol = ((Number) protocolObj).intValue();
+                            entry.label = buildActionString(R.string.actionChat,
+                                    protocolStrings[protocol], false);
+                            host = ContactMethods.lookupProviderNameFromId(protocol).toLowerCase();
+                            if (protocol == ContactMethods.PROTOCOL_GOOGLE_TALK
+                                    || protocol == ContactMethods.PROTOCOL_MSN) {
+                                entry.maxLabelLines = 2;
+                            }
+                        } else {
+                            String providerName = (String) protocolObj;
+                            entry.label = buildActionString(R.string.actionChat,
+                                    providerName, false);
+                            host = providerName.toLowerCase();
+                        }
+
+                        // Only add the intent if there is a valid host
+                        if (!TextUtils.isEmpty(host)) {
+                            entry.intent = new Intent(Intent.ACTION_SENDTO,
+                                    constructImToUrl(host, data));
+                        }
+                        entry.data = data;
+                        if (!methodsCursor.isNull(METHODS_STATUS_COLUMN)) {
+                            entry.presenceIcon = Presence.getPresenceIconResourceId(
+                                    methodsCursor.getInt(METHODS_STATUS_COLUMN));
+                        }
+                        entry.actionIcon = android.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 host;
+                    if (protocolObj instanceof Number) {
+                        int protocol = ((Number) protocolObj).intValue();
+                        label = getResources().getStringArray(
+                                android.R.array.imProtocols)[protocol];
+                        host = ContactMethods.lookupProviderNameFromId(protocol).toLowerCase();
+                    } else {
+                        String providerName = (String) protocolObj;
+                        label = providerName;
+                        host = providerName.toLowerCase();
+                    }
+
+                    if (TextUtils.isEmpty(host)) {
+                        // A valid provider name is required
+                        continue;
+                    }
+
+
+                    Intent intent = new Intent(Intent.ACTION_SENDTO, constructImToUrl(host, data));
+
+                    // 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 = android.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.label = organizationsCursor.getString(ORGANIZATIONS_COMPANY_COLUMN);
+                entry.data = organizationsCursor.getString(ORGANIZATIONS_TITLE_COLUMN);
+                entry.actionIcon = R.drawable.sym_action_organization;
+/*
+                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;
+            entry.actionIcon = R.drawable.sym_note;
+            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;
+                    entry.actionIcon = R.drawable.sym_ringtone;
+                    mOtherEntries.add(entry);
+                }
+            }
+        }
+
+        // Build the send directly to voice mail entry
+        boolean sendToVoicemail = personCursor.getInt(CONTACT_SEND_TO_VOICEMAIL_COLUMN) == 1;
+        if (sendToVoicemail) {
+            ViewEntry entry = new ViewEntry();
+            entry.label = getString(R.string.actionIncomingCall);
+            entry.data = getString(R.string.detailIncomingCallsGoToVoicemail);
+            entry.kind = ViewEntry.KIND_CONTACT;
+            entry.actionIcon = R.drawable.sym_send_to_voicemail;
+            mOtherEntries.add(entry);
+        }
+    }
+
+    String buildActionString(int actionResId, CharSequence type, boolean lowerCase) {
+        if (lowerCase) {
+            return getString(actionResId, type.toString().toLowerCase());
+        } else {
+            return getString(actionResId, type.toString());
+        }
+    }
+    
+    /**
+     * A basic structure with the data for a contact entry in the list.
+     */
+    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 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 ImageView actionIcon;
+            public ImageView presenceIcon;
+            
+            // Need to keep track of this too
+            ViewEntry entry;
+        }
+        
+        ViewAdapter(Context context, ArrayList<ArrayList<ViewEntry>> sections) {
+            super(context, sections, SHOW_SEPARATORS);
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            ViewEntry entry = getEntry(mSections, position, false); 
+            View v;
+
+            // Handle separators specially
+            if (entry.kind == ViewEntry.KIND_SEPARATOR) {
+                TextView separator = (TextView) mInflater.inflate(
+                        R.layout.list_separator, parent, SHOW_SEPARATORS);
+                separator.setText(entry.data);
+                return separator;
+            }
+
+            ViewCache views;
+
+            // Check to see if we can reuse convertView
+            if (convertView != null) {
+                v = convertView;
+                views = (ViewCache) v.getTag();
+            } else {
+                // Create a new view if needed
+                v = mInflater.inflate(R.layout.list_item_text_icons, parent, false);
+
+                // Cache the children
+                views = new ViewCache();
+                views.label = (TextView) v.findViewById(android.R.id.text1);
+                views.data = (TextView) v.findViewById(android.R.id.text2);
+                views.actionIcon = (ImageView) v.findViewById(R.id.icon1);
+                views.presenceIcon = (ImageView) v.findViewById(R.id.icon2);
+                v.setTag(views);
+            }
+
+            // Update the entry in the view cache
+            views.entry = entry;
+
+            // 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 action icon
+            ImageView action = views.actionIcon;
+            if (entry.actionIcon != -1) {
+                action.setImageDrawable(resources.getDrawable(entry.actionIcon));
+                action.setVisibility(View.VISIBLE);
+            } else {
+                // Things should still line up as if there was an icon, so make it invisible
+                action.setVisibility(View.INVISIBLE);
+            }
+
+            // Set the presence icon
+            Drawable presenceIcon = null;
+            if (entry.primaryIcon != -1) {
+                presenceIcon = resources.getDrawable(entry.primaryIcon);
+            } else if (entry.presenceIcon != -1) {
+                presenceIcon = resources.getDrawable(entry.presenceIcon);
+            }
+
+            ImageView presence = views.presenceIcon;
+            if (presenceIcon != null) {
+                presence.setImageDrawable(presenceIcon);
+                presence.setVisibility(View.VISIBLE);
+            } else {
+                presence.setVisibility(View.GONE);
+            }
+        }
+
+        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);
+            }
+        }
+    }
+}
