diff --git a/src/com/android/contacts/ContactsListActivity.java b/src/com/android/contacts/ContactsListActivity.java
index 5cc0254..f5ed2d7 100644
--- a/src/com/android/contacts/ContactsListActivity.java
+++ b/src/com/android/contacts/ContactsListActivity.java
@@ -1227,6 +1227,7 @@
                 return new AlertDialog.Builder(this)
                         .setTitle(R.string.confirm_share_visible_contacts_title)
                         .setMessage(getString(R.string.confirm_share_visible_contacts_message))
+                        .setNegativeButton(android.R.string.cancel, null)
                         .setPositiveButton(android.R.string.ok,
                                 new DialogInterface.OnClickListener() {
                             public void onClick(DialogInterface dialog, int which) {
diff --git a/src/com/android/contacts/ImportVCardActivity.java b/src/com/android/contacts/ImportVCardActivity.java
index 4f2749d..30b6cbf 100644
--- a/src/com/android/contacts/ImportVCardActivity.java
+++ b/src/com/android/contacts/ImportVCardActivity.java
@@ -22,6 +22,7 @@
 import android.app.Dialog;
 import android.app.ProgressDialog;
 import android.content.ContentResolver;
+import android.content.ContentUris;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -45,6 +46,7 @@
 import android.pim.vcard.exception.VCardNestedException;
 import android.pim.vcard.exception.VCardNotSupportedException;
 import android.pim.vcard.exception.VCardVersionException;
+import android.provider.ContactsContract.RawContacts;
 import android.text.SpannableStringBuilder;
 import android.text.Spanned;
 import android.text.TextUtils;
@@ -189,6 +191,7 @@
         public void run() {
             boolean shouldCallFinish = true;
             mWakeLock.acquire();
+            Uri createdUri = null;
             // Some malicious vCard data may make this thread broken
             // (e.g. OutOfMemoryError).
             // Even in such cases, some should be done.
@@ -238,7 +241,7 @@
                     mProgressDialogForReadVCard.setIndeterminate(false);
                     mProgressDialogForReadVCard.setMax(counter.getCount());
                     String charset = detector.getEstimatedCharset();
-                    doActuallyReadOneVCard(mUri, null, charset, true, detector,
+                    createdUri = doActuallyReadOneVCard(mUri, null, charset, true, detector,
                             mErrorFileNameList);
                 } else {  // Read multiple files.
                     mProgressDialogForReadVCard.setProgressNumberFormat(
@@ -262,7 +265,7 @@
                             // Assume that VCardSourceDetector was able to detect the source.
                         }
                         String charset = detector.getEstimatedCharset();
-                        doActuallyReadOneVCard(uri, mAccount,
+                        createdUri = doActuallyReadOneVCard(uri, mAccount,
                                 charset, false, detector, mErrorFileNameList);
                         mProgressDialogForReadVCard.incrementProgressBy(1);
                     }
@@ -274,18 +277,18 @@
                 if (shouldCallFinish && !isFinishing()) {
                     if (mErrorFileNameList == null || mErrorFileNameList.isEmpty()) {
                         finish();
-                        // TODO: Send out ACTION_EDIT intent here to review the
-                        // incoming contact
                         if (mNeedReview) {
                             mNeedReview = false;
                             Log.v("importVCardActivity", "Prepare to review the imported contact");
-                            Uri uri = null; // TODO: need get the uri of the
-                                            // incoming contact
-                            Intent editIntent = new Intent(Intent.ACTION_EDIT, uri);
-                            if (editIntent != null) {
-                                //startActivity(editIntent);
-                            }
 
+                            // get contact_id of this raw_contact
+                            final long rawContactId = ContentUris.parseId(createdUri);
+                            Uri contactUri = RawContacts.getContactLookupUri(getContentResolver(),
+                                    ContentUris.withAppendedId(RawContacts.CONTENT_URI,
+                                            rawContactId));
+
+                            Intent viewIntent = new Intent(Intent.ACTION_VIEW, contactUri);
+                            startActivity(viewIntent);
                         }
                     } else {
                         StringBuilder builder = new StringBuilder();
@@ -298,7 +301,7 @@
                             }
                             builder.append(fileName);
                         }
-                        
+
                         mHandler.post(new DialogDisplayer(
                                 getString(R.string.fail_reason_failed_to_read_files,
                                         builder.toString())));
@@ -307,7 +310,7 @@
             }
         }
 
-        private boolean doActuallyReadOneVCard(Uri uri, Account account,
+        private Uri doActuallyReadOneVCard(Uri uri, Account account,
                 String charset, boolean showEntryParseProgress,
                 VCardSourceDetector detector, List<String> errorFileNameList) {
             final Context context = ImportVCardActivity.this;
@@ -321,7 +324,8 @@
                 charset = VCardConfig.DEFAULT_CHARSET;
                 builder = new VCardEntryConstructor(null, null, false, vcardType, mAccount);
             }
-            builder.addEntryHandler(new VCardEntryCommitter(mResolver));
+            VCardEntryCommitter committer = new VCardEntryCommitter(mResolver);
+            builder.addEntryHandler(committer);
             if (showEntryParseProgress) {
                 builder.addEntryHandler(new ProgressShower(mProgressDialogForReadVCard,
                         context.getString(R.string.reading_vcard_message),
@@ -331,12 +335,12 @@
 
             try {
                 if (!readOneVCardFile(uri, charset, builder, detector, false, null)) {
-                    return false;
+                    return null;
                 }
             } catch (VCardNestedException e) {
                 Log.e(LOG_TAG, "Never reach here.");
             }
-            return true;
+            return committer.getLastCreatedUri();
         }
 
         private boolean readOneVCardFile(Uri uri, String charset,
@@ -431,7 +435,7 @@
         public static final int IMPORT_MULTIPLE = 1;
         public static final int IMPORT_ALL = 2;
         public static final int IMPORT_TYPE_SIZE = 3;
-        
+
         private int mCurrentIndex;
 
         public void onClick(DialogInterface dialog, int which) {
@@ -454,7 +458,7 @@
             }
         }
     }
-    
+
     private class VCardSelectedListener implements
             DialogInterface.OnClickListener, DialogInterface.OnMultiChoiceClickListener {
         private int mCurrentIndex;
@@ -472,7 +476,7 @@
                 if (mSelectedIndexSet != null) {
                     List<VCardFile> selectedVCardFileList = new ArrayList<VCardFile>();
                     int size = mAllVCardFileList.size();
-                    // We'd like to sort the files by its index, so we do not use Set iterator. 
+                    // We'd like to sort the files by its index, so we do not use Set iterator.
                     for (int i = 0; i < size; i++) {
                         if (mSelectedIndexSet.contains(i)) {
                             selectedVCardFileList.add(mAllVCardFileList.get(i));
@@ -633,7 +637,7 @@
             mHandler.post(new DialogDisplayer(R.id.dialog_select_one_vcard));
         }
     }
-    
+
     private void importMultipleVCardFromSDCard(final List<VCardFile> selectedVCardFileList) {
         mHandler.post(new Runnable() {
             public void run() {
diff --git a/src/com/android/contacts/JapaneseContactListIndexer.java b/src/com/android/contacts/JapaneseContactListIndexer.java
deleted file mode 100644
index ca7ca33..0000000
--- a/src/com/android/contacts/JapaneseContactListIndexer.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts;
-
-import java.util.Map;
-
-import android.database.Cursor;
-import android.database.DataSetObserver;
-import android.util.Log;
-import android.util.SparseIntArray;
-import android.widget.SectionIndexer;
-
-/**
- * SectionIndexer which is for "phonetically sortable" String. This class heavily depends on the
- * algorithm of the SQL function "GET_PHONETICALLY_SORTABLE_STRING", whose implementation
- * is written in C++.
- */
-public final class JapaneseContactListIndexer extends DataSetObserver implements SectionIndexer {
-    private static String TAG = "JapaneseContactListIndexer";
-
-    private static final String[] sSections = {
-            " ", // Sections of SectionIndexer should start with " " (some components assume it).
-            "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
-            "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
-            "\u3042", "\u304B", "\u3055", "\u305F", "\u306A", // a, ka, sa, ta, na 
-            "\u306F", "\u307E", "\u3084", "\u3089", "\u308F", // ha, ma, ya, ra, wa
-            "\uFF21", "\uFF22", "\uFF23", "\uFF24", "\uFF25", // full-width ABCDE
-            "\uFF26", "\uFF27", "\uFF28", "\uFF29", "\uFF2A", // full-width FGHIJ
-            "\uFF2B", "\uFF2C", "\uFF2D", "\uFF2E", "\uFF2F", // full-width KLMNO
-            "\uFF30", "\uFF31", "\uFF32", "\uFF33", "\uFF34", // full-width PQRST
-            "\uFF35", "\uFF36", "\uFF37", "\uFF38", "\uFF39", // full-width UVWXY
-            "\uFF40", // full-width Z
-            "\u6570", "\u8A18" // alphabets, numbers, symbols
-            };
-    private static final int sSectionsLength = sSections.length;
-
-    /**
-     * Converts given character into half-width ascii. If it is small ascii, it is translated
-     * into large ascii.
-     * This method is temporal huck until fixing the issue in which Ascii comes before Kana-s.
-     * Note that names starting from symbols corrupt the indexer.
-     *
-     * The current ICU mapping used in the locale ja merges full-width/half-width Asciis into
-     * one without caring its order. This mapping translates the unified characters into
-     * full-width capitalized ascii.
-     * TODO: Similar method should exist in public API. vCard code also has similar mapping.
-     */
-    private static int toHalfWidthCapitalizedAscii(int codePoint) {
-       if (0x61 <= codePoint && codePoint <= 0x7A) {
-           return codePoint - 0x20;  // half-width small ascii -> half-width capitalized ascii.
-       } else if ((0xFF01 <= codePoint && codePoint <= 0xFF40) ||
-               (0xFF5B <= codePoint && codePoint <= 0xFF5E)) {
-           return codePoint - (0xFF01 - 0x0020);
-       } else if (0xFF41 <= codePoint && codePoint <= 0xFF5A) {
-           return codePoint - (0xFF41 - 0x0041);
-       } else {
-           return codePoint;
-       }
-    }
-
-    private int mColumnIndex;
-    private Cursor mDataCursor;
-    private SparseIntArray mStringMap;
-    
-    public JapaneseContactListIndexer(Cursor cursor, int columnIndex) {
-        int len = sSections.length;
-        mColumnIndex = columnIndex;
-        mDataCursor = cursor;
-        mStringMap = new SparseIntArray(sSectionsLength);
-        if (cursor != null) {
-            cursor.registerDataSetObserver(this);
-        }
-    }
-    
-    public void setCursor(Cursor cursor) {
-        if (mDataCursor != null) {
-            mDataCursor.unregisterDataSetObserver(this);
-        }
-        mDataCursor = cursor;
-        if (cursor != null) {
-            mDataCursor.registerDataSetObserver(this);
-        }
-    }
-    
-    private int getSectionCodePoint(int index) {
-        if (index < sSections.length - 2) {
-            return sSections[index].codePointAt(0);
-        } else if (index == sSections.length - 2) {
-            return 0xFF66;  // Numbers are mapped from 0xFF66.
-        } else {  // index == mSections.length - 1
-            return 0xFF70;  // Symbols are mapped from 0xFF70.
-        }
-    }
-    
-    public int getPositionForSection(int sectionIndex) {
-        final SparseIntArray stringMap = mStringMap;
-        final Cursor cursor = mDataCursor;
-
-        if (cursor == null || sectionIndex <= 0) {
-            return 0;
-        }
-        
-        if (sectionIndex >= sSectionsLength) {
-            sectionIndex = sSectionsLength - 1;
-        }
-
-        int savedCursorPos = cursor.getPosition();
-
-        String targetLetter = sSections[sectionIndex];
-        int key = targetLetter.codePointAt(0);
-
-        // Check cache map
-        {
-            int tmp = stringMap.get(key, Integer.MIN_VALUE);
-            if (Integer.MIN_VALUE != tmp) {
-                return tmp;
-            }
-        }
-
-        int end = cursor.getCount();
-        int pos = 0;
-
-        {
-            // Note that sectionIndex > 0.
-            int prevLetter = sSections[sectionIndex - 1].codePointAt(0);
-            int prevLetterPos = stringMap.get(prevLetter, Integer.MIN_VALUE);
-            if (prevLetterPos != Integer.MIN_VALUE) {
-                pos = prevLetterPos;
-            }
-        }
-        
-        // Do rough binary search if there are a lot of entries.
-        while (end - pos > 100) {
-            int tmp = (end + pos) / 2;
-            cursor.moveToPosition(tmp);
-            String sort_name;
-            do {
-                sort_name = cursor.getString(mColumnIndex);
-                if (sort_name == null || sort_name.length() == 0) {
-                    // This should not happen, since sort_name field is created
-                    // automatically when syncing to a server, or creating/editing
-                    // the entry...
-                    Log.e(TAG, "sort_name is null or its length is 0. index: " + tmp);
-                    cursor.moveToNext();
-                    tmp++;
-                    continue;
-                }
-                break;
-            } while (tmp < end);
-            if (tmp == end) {
-                break;
-            }
-            int codePoint = sort_name.codePointAt(0);
-            if (codePoint < getSectionCodePoint(sectionIndex)) {
-                pos = tmp;
-            } else {
-                end = tmp;
-            }
-        }
-        
-        for (cursor.moveToPosition(pos); !cursor.isAfterLast(); ++pos, cursor.moveToNext()) {
-            String sort_name = cursor.getString(mColumnIndex);
-            if (sort_name == null || sort_name.length() == 0) {
-                // This should not happen, since sort_name field is created
-                // automatically when syncing to a server, or creating/editing
-                // the entry...
-                Log.e(TAG, "sort_name is null or its length is 0. index: " + pos);
-                continue;
-            }
-            int codePoint = toHalfWidthCapitalizedAscii(sort_name.codePointAt(0));
-            if (codePoint >= getSectionCodePoint(sectionIndex)) {
-                break;
-            }
-        }
-        
-        stringMap.put(key, pos);
-        cursor.moveToPosition(savedCursorPos);
-        return pos;
-    }
-    
-    public int getSectionForPosition(int position) {
-        // Not used in Contacts. Ignore for now.
-        return 0;
-    }
-
-    public Object[] getSections() {
-        return sSections;
-    }
-
-    @Override
-    public void onChanged() {
-        super.onChanged();
-        mStringMap.clear();
-    }
-
-    @Override
-    public void onInvalidated() {
-        super.onInvalidated();
-        mStringMap.clear();
-    }
-}
