diff --git a/src/com/android/contacts/ContactsListActivity.java b/src/com/android/contacts/ContactsListActivity.java
index 39e127a..b9dc4f2 100644
--- a/src/com/android/contacts/ContactsListActivity.java
+++ b/src/com/android/contacts/ContactsListActivity.java
@@ -73,6 +73,7 @@
 import java.lang.ref.SoftReference;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
+import java.util.Locale;
 
 /**
  * Displays a list of contacts. Usually is embedded into the ContactsActivity.
@@ -83,7 +84,7 @@
 
     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;
@@ -169,6 +170,7 @@
 
     
     static final String NAME_COLUMN = People.DISPLAY_NAME;
+    static final String SORT_STRING = People.SORT_STRING;
     
     static final String[] CONTACTS_PROJECTION = new String[] {
         People._ID, // 0
@@ -180,6 +182,7 @@
         People.PRIMARY_PHONE_ID, // 6
         People.PRIMARY_EMAIL_ID, // 7
         People.PRESENCE_STATUS, // 8
+        SORT_STRING, // 9
     };
 
     static final String[] STREQUENT_PROJECTION = new String[] {
@@ -227,6 +230,7 @@
     static final int PRIMARY_EMAIL_ID_COLUMN_INDEX = 7;
     static final int SERVER_STATUS_COLUMN_INDEX = 8;
     static final int PHOTO_COLUMN_INDEX = 9;
+    static final int SORT_STRING_INDEX = 9;
 
     static final int PHONES_PERSON_ID_INDEX = 6;
     static final int CONTACT_METHODS_PERSON_ID_INDEX = 6;
@@ -234,9 +238,7 @@
     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[] {
@@ -1137,6 +1139,15 @@
         }
     }
 
+    private static String getSortOrder(String[] projectionType) {
+        if (Locale.getDefault().equals(Locale.JAPAN) &&
+                projectionType == CONTACTS_PROJECTION) {
+            return SORT_STRING + " ASC";
+        } else {
+            return NAME_COLUMN + " COLLATE LOCALIZED ASC";
+        }
+    }
+    
     void startQuery() {
         mAdapter.setLoading(true);
         
@@ -1147,7 +1158,8 @@
         switch (mMode) {
             case MODE_GROUP:
                 mQueryHandler.startQuery(QUERY_TOKEN, null,
-                        mGroupUri, CONTACTS_PROJECTION, null, null, SORT_ORDER);
+                        mGroupUri, CONTACTS_PROJECTION, null, null,
+                        getSortOrder(CONTACTS_PROJECTION));
                 break;
 
             case MODE_ALL_CONTACTS:
@@ -1155,18 +1167,20 @@
             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);
+                        null, null, getSortOrder(CONTACTS_PROJECTION));
                 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);
+                        People.PRIMARY_PHONE_ID + " IS NOT NULL", null,
+                        getSortOrder(CONTACTS_PROJECTION));
                 break;
 
             case MODE_QUERY: {
                 mQuery = getIntent().getStringExtra(SearchManager.QUERY);
                 mQueryHandler.startQuery(QUERY_TOKEN, null, getPeopleFilterUri(mQuery),
-                        CONTACTS_PROJECTION, null, null, SORT_ORDER);
+                        CONTACTS_PROJECTION, null, null,
+                        getSortOrder(CONTACTS_PROJECTION));
                 break;
             }
             
@@ -1182,27 +1196,31 @@
                     ssp = data.getSchemeSpecificPart();
                     mCreateData = ssp;
                 }
+                
+                mCreateExtras = new Bundle();
+                Bundle originalExtras = getIntent().getExtras();
+                if (originalExtras != null) {
+                    mCreateExtras.putAll(originalExtras);
+                }
 
                 if ("mailto".equals(scheme)) {
-                    mCreateExtras = new Bundle();
-                    mCreateExtras.putAll(getIntent().getExtras());
                     mCreateExtras.putString(Intents.Insert.EMAIL, ssp);
                     mCreatePersonIndex = CONTACT_METHODS_PERSON_ID_INDEX;
                     
                     mQueryHandler.startQuery(QUERY_TOKEN, null,
                             ContactMethods.CONTENT_URI, CONTACT_METHODS_PROJECTION,
                             ContactMethodsColumns.KIND + "=" + Contacts.KIND_EMAIL + " AND " +
-                            ContactMethods.DATA + "=?", new String[] { ssp }, SORT_ORDER);
+                            ContactMethods.DATA + "=?", new String[] { ssp },
+                            getSortOrder(CONTACT_METHODS_PROJECTION));
                     
                 } else if ("tel".equals(scheme)) {
-                    mCreateExtras = new Bundle();
-                    mCreateExtras.putAll(getIntent().getExtras());
                     mCreateExtras.putString(Intents.Insert.PHONE, ssp);
                     mCreatePersonIndex = PHONES_PERSON_ID_INDEX;
                     
                     mQueryHandler.startQuery(QUERY_TOKEN, null,
                             Uri.withAppendedPath(Phones.CONTENT_FILTER_URL, ssp),
-                            PHONES_PROJECTION, null, null, SORT_ORDER);
+                            PHONES_PROJECTION, null, null,
+                            getSortOrder(PHONES_PROJECTION));
                     
                 } else {
                     Log.w(TAG, "Invalid intent:" + getIntent());
@@ -1213,14 +1231,16 @@
             }
 
             case MODE_STARRED:
-                mQueryHandler.startQuery(QUERY_TOKEN, null, People.CONTENT_URI, CONTACTS_PROJECTION,
-                        People.STARRED + "=1", null, SORT_ORDER);
+                mQueryHandler.startQuery(QUERY_TOKEN, null, People.CONTENT_URI,
+                        CONTACTS_PROJECTION,
+                        People.STARRED + "=1", null, getSortOrder(CONTACTS_PROJECTION));
                 break;
 
             case MODE_FREQUENT:
-                mQueryHandler.startQuery(QUERY_TOKEN, null, People.CONTENT_URI, CONTACTS_PROJECTION,
+                mQueryHandler.startQuery(QUERY_TOKEN, null,
+                        People.CONTENT_URI, CONTACTS_PROJECTION,
                         People.TIMES_CONTACTED + " > 0", null,
-                        People.TIMES_CONTACTED + " DESC, " + NAME_COLUMN + " ASC");
+                        People.TIMES_CONTACTED + " DESC, " + getSortOrder(CONTACTS_PROJECTION));
                 break;
 
             case MODE_STREQUENT:
@@ -1231,13 +1251,14 @@
 
             case MODE_PICK_PHONE:
                 mQueryHandler.startQuery(QUERY_TOKEN, null, Phones.CONTENT_URI, PHONES_PROJECTION,
-                        null, null, SORT_ORDER);
+                        null, null, getSortOrder(PHONES_PROJECTION));
                 break;
 
             case MODE_PICK_POSTAL:
                 mQueryHandler.startQuery(QUERY_TOKEN, null, ContactMethods.CONTENT_URI,
                         CONTACT_METHODS_PROJECTION,
-                        ContactMethods.KIND + "=" + Contacts.KIND_POSTAL, null, SORT_ORDER);
+                        ContactMethods.KIND + "=" + Contacts.KIND_POSTAL, null,
+                        getSortOrder(CONTACT_METHODS_PROJECTION));
                 break;
         }
     }
@@ -1259,7 +1280,8 @@
                 } else {
                     uri = Uri.withAppendedPath(mGroupFilterUri, Uri.encode(filter));
                 }
-                return resolver.query(uri, CONTACTS_PROJECTION, null, null, SORT_ORDER);
+                return resolver.query(uri, CONTACTS_PROJECTION, null, null,
+                        getSortOrder(CONTACTS_PROJECTION));
             }
 
             case MODE_ALL_CONTACTS:
@@ -1267,23 +1289,25 @@
             case MODE_PICK_OR_CREATE_CONTACT:
             case MODE_INSERT_OR_EDIT_CONTACT: {
                 return resolver.query(getPeopleFilterUri(filter), CONTACTS_PROJECTION, null, null,
-                        SORT_ORDER);
+                        getSortOrder(CONTACTS_PROJECTION));
             }
 
             case MODE_WITH_PHONES: {
                 return resolver.query(getPeopleFilterUri(filter), CONTACTS_PROJECTION,
-                        People.PRIMARY_PHONE_ID + " IS NOT NULL", null, SORT_ORDER);
+                        People.PRIMARY_PHONE_ID + " IS NOT NULL", null,
+                        getSortOrder(CONTACTS_PROJECTION));
             }
 
             case MODE_STARRED: {
                 return resolver.query(getPeopleFilterUri(filter), CONTACTS_PROJECTION,
-                        People.STARRED + "=1", null, SORT_ORDER);
+                        People.STARRED + "=1", null, getSortOrder(CONTACTS_PROJECTION));
             }
 
             case MODE_FREQUENT: {
                 return resolver.query(getPeopleFilterUri(filter), CONTACTS_PROJECTION,
                         People.TIMES_CONTACTED + " > 0", null,
-                        People.TIMES_CONTACTED + " DESC, " + NAME_COLUMN + " ASC");
+                        People.TIMES_CONTACTED + " DESC, " + getSortOrder(CONTACTS_PROJECTION));
+                
             }
 
             case MODE_STREQUENT: {
@@ -1305,7 +1329,8 @@
                 } else {
                     uri = Phones.CONTENT_URI;
                 }
-                return resolver.query(uri, PHONES_PROJECTION, null, null, SORT_ORDER);
+                return resolver.query(uri, PHONES_PROJECTION, null, null,
+                        getSortOrder(PHONES_PROJECTION));
             }
         }
         throw new UnsupportedOperationException("filtering not allowed in mode " + mMode);
@@ -1475,7 +1500,7 @@
 
     private final class ContactItemListAdapter extends ResourceCursorAdapter 
             implements SectionIndexer {
-        private AlphabetIndexer mIndexer;
+        private SectionIndexer mIndexer;
         private String mAlphabet;
         private boolean mLoading = true;
         private CharSequence mUnknownNameText;
@@ -1507,6 +1532,14 @@
             }
         }
 
+        private SectionIndexer getNewIndexer(Cursor cursor) {
+            if (Locale.getDefault().equals(Locale.JAPAN)) {
+                return new JapaneseContactListIndexer(cursor, SORT_STRING_INDEX);
+            } else {
+                return new AlphabetIndexer(cursor, NAME_COLUMN_INDEX, mAlphabet);
+            }
+        }
+        
         /**
          * 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
@@ -1682,9 +1715,21 @@
         
         private void updateIndexer(Cursor cursor) {
             if (mIndexer == null) {
-                mIndexer = new AlphabetIndexer(cursor, NAME_COLUMN_INDEX, mAlphabet);
+                mIndexer = getNewIndexer(cursor);
             } else {
-                mIndexer.setCursor(cursor);
+                if (Locale.getDefault().equals(Locale.JAPAN)) {
+                    if (mIndexer instanceof JapaneseContactListIndexer) {
+                        ((JapaneseContactListIndexer)mIndexer).setCursor(cursor);
+                    } else {
+                        mIndexer = getNewIndexer(cursor);
+                    }
+                } else {
+                    if (mIndexer instanceof AlphabetIndexer) {
+                        ((AlphabetIndexer)mIndexer).setCursor(cursor);
+                    } else {
+                        mIndexer = getNewIndexer(cursor);
+                    }
+                }
             }
         }
         
@@ -1716,13 +1761,16 @@
                     // No cursor, the section doesn't exist so just return 0
                     return 0;
                 }
-                mIndexer = new AlphabetIndexer(cursor, NAME_COLUMN_INDEX, mAlphabet);
+                mIndexer = getNewIndexer(cursor);
             }
 
             return mIndexer.getPositionForSection(sectionIndex);
         }
         
         public int getSectionForPosition(int position) {
+            // Note: JapaneseContactListIndexer depends on the fact
+            // this method always returns 0. If you change this,
+            // please care it too.
             return 0;
         }        
     }
diff --git a/src/com/android/contacts/JapaneseContactListIndexer.java b/src/com/android/contacts/JapaneseContactListIndexer.java
new file mode 100644
index 0000000..d5d6dcd
--- /dev/null
+++ b/src/com/android/contacts/JapaneseContactListIndexer.java
@@ -0,0 +1,187 @@
+/*
+ * 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.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";
+
+    static private final String[] sSections = {
+            " ", // Sections of SectionIndexer should start with " " (some components assume it).
+            "\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
+            };
+    static private final int sSectionsLength = sSections.length;
+    
+    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 = 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();
+    }
+}
