Merge "Check bigrams for lowercased previous word if original is not found"
diff --git a/java/res/layout/setup_step.xml b/java/res/layout/setup_step.xml
index c6462e9..fa84902 100644
--- a/java/res/layout/setup_step.xml
+++ b/java/res/layout/setup_step.xml
@@ -25,14 +25,14 @@
     <TextView
         android:id="@+id/setup_step_title"
         style="@style/setupStepTitleStyle"
-        android:paddingTop="16dp"
-        android:paddingBottom="16dp" />
+        android:paddingTop="@dimen/setup_step_vertical_padding"
+        android:paddingBottom="@dimen/setup_step_vertical_padding" />
     <TextView
         android:id="@+id/setup_step_instruction"
         style="@style/setupStepInstructionStyle"
-        android:paddingBottom="16dp" />
+        android:paddingBottom="@dimen/setup_step_vertical_padding" />
     <TextView
         android:id="@+id/setup_step_action_label"
         style="@style/setupStepActionLabelStyle"
-        android:layout_marginTop="2dp" />
+        android:layout_marginTop="@dimen/setup_step_horizontal_line_height" />
 </LinearLayout>
diff --git a/java/res/layout/setup_steps_cards.xml b/java/res/layout/setup_steps_cards.xml
index 17207d3..6c46461 100644
--- a/java/res/layout/setup_steps_cards.xml
+++ b/java/res/layout/setup_steps_cards.xml
@@ -23,7 +23,7 @@
         android:id="@+id/setup_step_bullets"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginTop="16dp"
+        android:layout_marginTop="@dimen/setup_step_vertical_padding"
         android:orientation="horizontal">
         <TextView
             android:id="@+id/setup_step1_bullet"
@@ -40,8 +40,7 @@
     </LinearLayout>
     <com.android.inputmethod.latin.setup.SetupStepIndicatorView
         android:id="@+id/setup_step_indicator"
-        android:layout_width="match_parent"
-        android:layout_height="24dp" />
+        style="@style/setupStepIndicatorStyle" />
     <FrameLayout
         android:id="@+id/setup_steps_pane"
         android:layout_width="match_parent"
@@ -60,5 +59,5 @@
         android:id="@+id/setup_finish"
         android:text="@string/setup_finish_action"
         style="@style/setupStepActionLabelStyle"
-        android:layout_marginTop="2dp" />
+        android:layout_marginTop="@dimen/setup_step_horizontal_line_height" />
 </merge>
diff --git a/java/res/layout/setup_welcome_video.xml b/java/res/layout/setup_welcome_video.xml
index 3aa4f3c..da59ec8 100644
--- a/java/res/layout/setup_welcome_video.xml
+++ b/java/res/layout/setup_welcome_video.xml
@@ -30,8 +30,8 @@
         <VideoView
             android:id="@+id/setup_welcome_video"
             android:layout_weight="@integer/setup_welcome_video_weight_in_screen"
-            android:layout_marginTop="24dp"
-            android:layout_marginBottom="24dp"
+            android:layout_marginTop="@dimen/setup_welcome_video_vertical_margin"
+            android:layout_marginBottom="@dimen/setup_welcome_video_vertical_margin"
             android:layout_width="0dp"
             android:layout_height="wrap_content" />
         <View
diff --git a/java/res/layout/setup_wizard.xml b/java/res/layout/setup_wizard.xml
index e766e4c..176f836 100644
--- a/java/res/layout/setup_wizard.xml
+++ b/java/res/layout/setup_wizard.xml
@@ -24,8 +24,8 @@
     android:background="@color/setup_background"
     android:paddingLeft="@dimen/setup_horizontal_padding"
     android:paddingRight="@dimen/setup_horizontal_padding"
-    android:paddingTop="16dp"
-    android:paddingBottom="16dp">
+    android:paddingTop="@dimen/setup_vertical_padding"
+    android:paddingBottom="@dimen/setup_vertical_padding">
     <include
         android:id="@+id/setup_welcome_screen"
         layout="@layout/setup_welcome_screen" />
diff --git a/java/res/values/config.xml b/java/res/values/config.xml
index d4fff62..4e2936c 100644
--- a/java/res/values/config.xml
+++ b/java/res/values/config.xml
@@ -58,9 +58,11 @@
     <bool name="config_sliding_key_input_enabled">true</bool>
     <!-- Sliding key input preview parameters -->
     <dimen name="config_sliding_key_input_preview_width">8.0dp</dimen>
-    <!-- Percentages of sliding key input preview body and shadow, in proportion to the width. -->
-    <integer name="config_sliding_key_input_preview_body_ratio">80</integer>
-    <integer name="config_sliding_key_input_preview_shadow_ratio">50</integer>
+    <!-- Percentages of sliding key input preview body and shadow, in proportion to the width.
+         A negative value of the shadow ratio disables drawing shadow. -->
+    <!-- TODO: May use the shadow to alleviate rugged trail drawing. -->
+    <integer name="config_sliding_key_input_preview_body_ratio">100</integer>
+    <integer name="config_sliding_key_input_preview_shadow_ratio">-1</integer>
     <integer name="config_key_repeat_start_timeout">400</integer>
     <integer name="config_key_repeat_interval">50</integer>
     <integer name="config_default_longpress_key_timeout">300</integer>  <!-- milliseconds -->
diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml
index db33ad8..e9b34aa 100644
--- a/java/res/values/dimens.xml
+++ b/java/res/values/dimens.xml
@@ -103,9 +103,11 @@
     <!-- Gesture preview trail parameters -->
     <dimen name="gesture_preview_trail_start_width">10.0dp</dimen>
     <dimen name="gesture_preview_trail_end_width">2.5dp</dimen>
-    <!-- Percentages of gesture preview taril body and shadow, in proportion to the trail width. -->
-    <integer name="gesture_preview_trail_body_ratio">80</integer>
-    <integer name="gesture_preview_trail_shadow_ratio">50</integer>
+    <!-- Percentages of gesture preview taril body and shadow, in proportion to the trail width.
+         A negative value of the shadow ratio disables drawing shadow. -->
+    <!-- TODO: May use the shadow to alleviate rugged trail drawing. -->
+    <integer name="gesture_preview_trail_body_ratio">100</integer>
+    <integer name="gesture_preview_trail_shadow_ratio">-1</integer>
     <!-- Gesture floating preview text parameters -->
     <dimen name="gesture_floating_preview_text_size">24dp</dimen>
     <dimen name="gesture_floating_preview_text_offset">73dp</dimen>
diff --git a/java/res/values/setup-dimens.xml b/java/res/values/setup-dimens.xml
index 1634777..5abc289 100644
--- a/java/res/values/setup-dimens.xml
+++ b/java/res/values/setup-dimens.xml
@@ -17,9 +17,21 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
     <dimen name="setup_title_text_size">46sp</dimen>
     <dimen name="setup_welcome_description_text_size">26sp</dimen>
+    <dimen name="setup_step_bullet_text_size">22sp</dimen>
+    <dimen name="setup_step_triangle_indicator_height">24dp</dimen>
+    <dimen name="setup_step_title_text_size">22sp</dimen>
+    <dimen name="setup_step_instruction_text_size">14sp</dimen>
+    <dimen name="setup_step_action_text_size">18sp</dimen>
+    <dimen name="setup_vertical_padding">16dp</dimen>
     <dimen name="setup_horizontal_padding">16dp</dimen>
+    <dimen name="setup_step_action_height">48dp</dimen>
+    <dimen name="setup_step_horizontal_padding">24dp</dimen>
+    <dimen name="setup_step_horizontal_padding_half">12dp</dimen>
+    <dimen name="setup_step_vertical_padding">16dp</dimen>
+    <dimen name="setup_step_horizontal_line_height">2dp</dimen>
     <integer name="setup_title_weight_in_screen">40</integer>
     <integer name="setup_body_weight_in_screen">60</integer>
+    <dimen name="setup_welcome_video_vertical_margin">24dp</dimen>
     <integer name="setup_welcome_video_weight_in_screen">80</integer>
     <integer name="setup_welcome_video_left_padding_weight_in_screen">10</integer>
     <integer name="setup_welcome_video_right_padding_weight_in_screen">10</integer>
diff --git a/java/res/values/setup-styles-common.xml b/java/res/values/setup-styles-common.xml
index e9c72eb..686decf 100644
--- a/java/res/values/setup-styles-common.xml
+++ b/java/res/values/setup-styles-common.xml
@@ -24,9 +24,13 @@
     <style name="setupWelcomeDescritpionStyle" parent="setupTitleStyle">
         <item name="android:textSize">@dimen/setup_welcome_description_text_size</item>
     </style>
+    <style name="setupStepIndicatorStyle">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">@dimen/setup_step_triangle_indicator_height</item>
+    </style>
     <style name="setupStepBulletStyle">
         <item name="android:textColor">@color/setup_text_dark</item>
-        <item name="android:textSize">22sp</item>
+        <item name="android:textSize">@dimen/setup_step_bullet_text_size</item>
         <item name="android:layout_width">0dp</item>
         <item name="android:layout_weight">1.0</item>
         <item name="android:layout_height">wrap_content</item>
@@ -37,32 +41,33 @@
         <item name="android:background">@color/setup_step_background</item>
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">wrap_content</item>
-        <item name="android:paddingLeft">24dp</item>
-        <item name="android:paddingRight">24dp</item>
+        <item name="android:paddingLeft">@dimen/setup_step_horizontal_padding</item>
+        <item name="android:paddingRight">@dimen/setup_step_horizontal_padding</item>
     </style>
     <style name="setupStepTitleStyle" parent="setupStepBaseStyle">
-        <item name="android:textSize">22sp</item>
+        <item name="android:textSize">@dimen/setup_step_title_text_size</item>
     </style>
     <style name="setupStepInstructionStyle" parent="setupStepBaseStyle">
-        <item name="android:textSize">14sp</item>
+        <item name="android:textSize">@dimen/setup_step_instruction_text_size</item>
     </style>
     <style name="setupStepStartIndicatorStyle">
-        <item name="android:layout_width">24dp</item>
-        <item name="android:layout_height">48dp</item>
+        <!-- The triangle indicator here is placed sideways. -->
+        <item name="android:layout_width">@dimen/setup_step_triangle_indicator_height</item>
+        <item name="android:layout_height">@dimen/setup_step_action_height</item>
     </style>
     <style name="setupStepActionLabelStyleCommon" parent="setupStepBaseStyle">
         <item name="android:textColor">@color/setup_step_action_color</item>
         <item name="android:background">@drawable/setup_step_action_background</item>
-        <item name="android:layout_height">48dp</item>
-        <item name="android:paddingLeft">12dp</item>
-        <item name="android:textSize">18sp</item>
-        <item name="android:drawablePadding">12dp</item>
+        <item name="android:layout_height">@dimen/setup_step_action_height</item>
+        <item name="android:paddingLeft">@dimen/setup_step_horizontal_padding_half</item>
+        <item name="android:textSize">@dimen/setup_step_action_text_size</item>
+        <item name="android:drawablePadding">@dimen/setup_step_horizontal_padding_half</item>
         <item name="android:gravity">center_vertical</item>
         <item name="android:clickable">true</item>
         <item name="android:focusable">true</item>
     </style>
     <style name="setupStepStartActionLabelStyleCommon" parent="setupStepActionLabelStyleCommon">
-        <item name="android:paddingLeft">24dp</item>
-        <item name="android:paddingRight">24dp</item>
+        <item name="android:paddingLeft">@dimen/setup_step_horizontal_padding</item>
+        <item name="android:paddingRight">@dimen/setup_step_horizontal_padding</item>
     </style>
 </resources>
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 1152063..d8a88a8 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -107,6 +107,9 @@
     <!-- Description for option to enable auto capitalization of sentences -->
     <string name="auto_cap_summary">Capitalize the first word of each sentence</string>
 
+    <!-- Option to edit personal dictionary. [CHAR_LIMIT=30]-->
+    <string name="edit_personal_dictionary">Personal dictionary</string>
+
     <!-- Option to configure dictionaries -->
     <string name="configure_dictionaries_title">Add-on dictionaries</string>
     <!-- Name of the main dictionary, as opposed to auxiliary dictionaries (medical/entertainment/sports...) -->
@@ -456,7 +459,7 @@
     <string name="setup_step1_bullet" translatable="false">1</string>
     <!-- Title of the 1st step in the setup wizard. [CHAR LIMIT=64] -->
     <string name="setup_step1_title">"Enable <xliff:g id="application_name">%s</xliff:g>"</string>
-    <!-- Detailed instruction of the 1st step in the setup wizard. [CHAR LIMIT=80] -->
+    <!-- Detailed instruction of the 1st step in the setup wizard. [CHAR LIMIT=120] -->
     <string name="setup_step1_instruction">"Please check \"<xliff:g id="application_name">%s</xliff:g>\" in your Language &amp; input settings. This will authorize it to run on your device."</string>
     <!-- The label of the button that triggers the Language & input settings in order to enable the keyboard. [CHAR_LIMIT=64] -->
     <string name="setup_step1_action">Enable in Settings</string>
@@ -464,7 +467,7 @@
     <string name="setup_step2_bullet" translatable="false">2</string>
     <!-- Title of the 2nd step in the setup wizard. [CHAR LIMIT=64] -->
     <string name="setup_step2_title">"Switch to <xliff:g id="application_name">%s</xliff:g>"</string>
-    <!-- Detailed instruction of the 2nd step in the setup wizard. [CHAR LIMIT=80] -->
+    <!-- Detailed instruction of the 2nd step in the setup wizard. [CHAR LIMIT=120] -->
     <string name="setup_step2_instruction">"Next, select \"<xliff:g id="application_name">%s</xliff:g>\" as your active text-input method."</string>
     <!-- The label of the button that triggers the choose input method dialog in order to select the keyboard. [CHAR_LIMIT=64] -->
     <string name="setup_step2_action">Switch input methods</string>
@@ -472,14 +475,16 @@
     <string name="setup_step3_bullet" translatable="false">3</string>
     <!-- Title of the 3rd step in the setup wizard. [CHAR LIMIT=64] -->
     <string name="setup_step3_title">"Congratulations, you're all set!"</string>
-    <!-- Detailed instruction of the 3rd step in the setup wizard. [CHAR LIMIT=80] -->
+    <!-- Detailed instruction of the 3rd step in the setup wizard. [CHAR LIMIT=120] -->
     <string name="setup_step3_instruction">Now you can type in all your favorite apps with <xliff:g id="application_name">%s</xliff:g>.</string>
     <!-- The label of the button that triggers the screen for configuaring additional languages of the keyboard. [CHAR_LIMIT=64] -->
     <string name="setup_step3_action">Configure additional languages</string>
     <!-- The label of the button that finishes the setup wizard. [CHAR_LIMIT=64] -->
     <string name="setup_finish_action">Finished</string>
     <!-- Option to show setup wizard icon. [CHAR LIMIT=30]-->
-    <string name="show_setup_wizard_icon">Show setup wizard icon</string>
+    <string name="show_setup_wizard_icon">Show app icon</string>
+    <!-- Description for the option to show setup wizard application icon of this IME in the laucher. [CHAR_LIMIT=65] -->
+    <string name="show_setup_wizard_icon_summary">Display application icon in the launcher</string>
 
     <!-- The dictionary provider application name. Visible in Settings/Applications/Manage applications. -->
     <string name="app_name">Dictionary Provider</string>
diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index 22ae51d..eea90f9 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -54,6 +54,11 @@
         android:title="@string/correction_category"
         android:key="correction_settings">
         <PreferenceScreen
+            android:key="edit_personal_dictionary"
+            android:title="@string/edit_personal_dictionary">
+            <intent android:action="android.settings.USER_DICTIONARY_SETTINGS" />
+        </PreferenceScreen>
+        <PreferenceScreen
             android:key="configure_dictionaries_key"
             android:title="@string/configure_dictionaries_title">
            <intent
@@ -172,11 +177,12 @@
                 android:key="pref_keypress_sound_volume"
                 android:title="@string/prefs_keypress_sound_volume_settings"
                 latin:maxValue="100" /> <!-- percent -->
-            <!-- The show setup wizard icon settings shouldn't be persistent and the default value
-                 is added programmatically. -->
+            <!-- The settigs for showing setup wizard application icon shouldn't be persistent and
+                 the default value is added programmatically. -->
             <CheckBoxPreference
                 android:key="pref_show_setup_wizard_icon"
-                android:title="@string/show_setup_wizard_icon" />
+                android:title="@string/show_setup_wizard_icon"
+                android:summary="@string/show_setup_wizard_icon_summary" />
         </PreferenceScreen>
         <PreferenceScreen
             android:key="send_feedback"
diff --git a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
index cb8e25e..03ed267 100644
--- a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
+++ b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
@@ -45,16 +45,16 @@
     private static final int METADATA_DATABASE_INITIAL_VERSION = 3;
     // This is the first released version of the database that implements CLIENTID. It is
     // used to identify the versions for upgrades. This should never change going forward.
-    private static final int METADATA_DATABASE_VERSION_WITH_CLIENTID = 5;
+    private static final int METADATA_DATABASE_VERSION_WITH_CLIENTID = 6;
     // This is the current database version. It should be updated when the database schema
     // gets updated. It is passed to the framework constructor of SQLiteOpenHelper, so
     // that's what the framework uses to track our database version.
-    private static final int METADATA_DATABASE_VERSION = 5;
+    private static final int METADATA_DATABASE_VERSION = 6;
 
     private final static long NOT_A_DOWNLOAD_ID = -1;
 
     public static final String METADATA_TABLE_NAME = "pendingUpdates";
-    private static final String CLIENT_TABLE_NAME = "clients";
+    static final String CLIENT_TABLE_NAME = "clients";
     public static final String PENDINGID_COLUMN = "pendingid"; // Download Manager ID
     public static final String TYPE_COLUMN = "type";
     public static final String STATUS_COLUMN = "status";
@@ -73,6 +73,7 @@
 
     private static final String CLIENT_CLIENT_ID_COLUMN = "clientid";
     private static final String CLIENT_METADATA_URI_COLUMN = "uri";
+    private static final String CLIENT_METADATA_ADDITIONAL_ID_COLUMN = "additionalid";
     private static final String CLIENT_LAST_UPDATE_DATE_COLUMN = "lastupdate";
     private static final String CLIENT_PENDINGID_COLUMN = "pendingid"; // Download Manager ID
 
@@ -128,6 +129,7 @@
             "CREATE TABLE IF NOT EXISTS " + CLIENT_TABLE_NAME + " ("
             + CLIENT_CLIENT_ID_COLUMN + " TEXT, "
             + CLIENT_METADATA_URI_COLUMN + " TEXT, "
+            + CLIENT_METADATA_ADDITIONAL_ID_COLUMN + " TEXT, "
             + CLIENT_LAST_UPDATE_DATE_COLUMN + " INTEGER NOT NULL DEFAULT 0, "
             + CLIENT_PENDINGID_COLUMN + " INTEGER, "
             + FLAGS_COLUMN + " INTEGER, "
@@ -282,14 +284,15 @@
      * @return the string representation of the URI
      */
     public static String getMetadataUriAsString(final Context context, final String clientId) {
-        SQLiteDatabase defaultDb = getDb(context, null);
-        final Cursor cursor = defaultDb.query(CLIENT_TABLE_NAME,
-                new String[] { CLIENT_METADATA_URI_COLUMN },
-                CLIENT_CLIENT_ID_COLUMN + " = ?", new String[] { clientId },
+        SQLiteDatabase defaultDb = MetadataDbHelper.getDb(context, null);
+        final Cursor cursor = defaultDb.query(MetadataDbHelper.CLIENT_TABLE_NAME,
+                new String[] { MetadataDbHelper.CLIENT_METADATA_URI_COLUMN,
+                        MetadataDbHelper.CLIENT_METADATA_ADDITIONAL_ID_COLUMN },
+                MetadataDbHelper.CLIENT_CLIENT_ID_COLUMN + " = ?", new String[] { clientId },
                 null, null, null, null);
         try {
             if (!cursor.moveToFirst()) return null;
-            return cursor.getString(0); // Only one column, return it
+            return MetadataUriGetter.getUri(context, cursor.getString(0), cursor.getString(1));
         } finally {
             cursor.close();
         }
@@ -298,7 +301,8 @@
     /**
      * Update the last metadata update time for all clients using a particular URI.
      *
-     * All clients using this metadata URI will be indicated as having been updated now.
+     * This method searches for all clients using a particular URI and updates the last
+     * update time for this client.
      * The current time is used as the latest update time. This saved date will be what
      * is returned henceforth by {@link #getLastUpdateDateForClient(Context, String)},
      * until this method is called again.
@@ -311,8 +315,22 @@
         final ContentValues values = new ContentValues();
         values.put(CLIENT_LAST_UPDATE_DATE_COLUMN, System.currentTimeMillis());
         final SQLiteDatabase defaultDb = getDb(context, null);
-        defaultDb.update(CLIENT_TABLE_NAME, values,
-                CLIENT_METADATA_URI_COLUMN + " = ?", new String[] { uri });
+        final Cursor cursor = MetadataDbHelper.queryClientIds(context);
+        if (null == cursor) return;
+        try {
+            if (!cursor.moveToFirst()) return;
+            do {
+                final String clientId = cursor.getString(0);
+                final String metadataUri =
+                        MetadataDbHelper.getMetadataUriAsString(context, clientId);
+                if (metadataUri.equals(uri)) {
+                    defaultDb.update(CLIENT_TABLE_NAME, values,
+                            CLIENT_CLIENT_ID_COLUMN + " = ?", new String[] { clientId });
+                }
+            } while (cursor.moveToNext());
+        } finally {
+            cursor.close();
+        }
     }
 
     /**
@@ -727,11 +745,13 @@
     /**
      * Updates information relative to a specific client.
      *
-     * Updatable information includes only the metadata URI, but may be expanded in the future.
+     * Updatable information includes the metadata URI and the additional ID column. It may be
+     * expanded in the future.
      * The passed values must include a client ID in the key CLIENT_CLIENT_ID_COLUMN, and it must
-     * be equal to the string passed as an argument for clientId.
-     * The passed values must also include a non-empty metadata URI in the
-     * CLIENT_METADATA_URI_COLUMN column.
+     * be equal to the string passed as an argument for clientId. It may not be empty.
+     * The passed values must also include a non-null metadata URI in the
+     * CLIENT_METADATA_URI_COLUMN column, as well as a non-null additional ID in the
+     * CLIENT_METADATA_ADDITIONAL_ID_COLUMN. Both these strings may be empty.
      * If any of the above is not complied with, this function returns without updating data.
      *
      * @param context the context, to open the database
@@ -743,10 +763,16 @@
         // Sanity check the content values
         final String valuesClientId = values.getAsString(CLIENT_CLIENT_ID_COLUMN);
         final String valuesMetadataUri = values.getAsString(CLIENT_METADATA_URI_COLUMN);
-        // Empty string is a valid client ID, but external apps may not configure it.
-        // Empty string is a valid metadata URI if the client does not want updates.
-        if (TextUtils.isEmpty(valuesClientId) || null == valuesMetadataUri) {
-            // We need both these columns to be filled in
+        final String valuesMetadataAdditionalId =
+                values.getAsString(CLIENT_METADATA_ADDITIONAL_ID_COLUMN);
+        // Empty string is a valid client ID, but external apps may not configure it, so disallow
+        // both null and empty string.
+        // Empty string is a valid metadata URI if the client does not want updates, so allow
+        // empty string but disallow null.
+        // Empty string is a valid additional ID so allow empty string but disallow null.
+        if (TextUtils.isEmpty(valuesClientId) || null == valuesMetadataUri
+                || null == valuesMetadataAdditionalId) {
+            // We need all these columns to be filled in
             Utils.l("Missing parameter for updateClientInfo");
             return;
         }
@@ -777,8 +803,9 @@
      * Register a download ID for a specific metadata URI.
      *
      * This method should be called when a download for a metadata URI is starting. It will
-     * register the download ID for all clients using this metadata URI into the database
-     * for later retrieval by {@link #getDownloadRecordsForDownloadId(Context, long)}.
+     * search for all clients using this metadata URI and will register for each of them
+     * the download ID into the database for later retrieval by
+     * {@link #getDownloadRecordsForDownloadId(Context, long)}.
      *
      * @param context a context for opening databases
      * @param uri the metadata URI
@@ -789,8 +816,22 @@
         final ContentValues values = new ContentValues();
         values.put(CLIENT_PENDINGID_COLUMN, downloadId);
         final SQLiteDatabase defaultDb = getDb(context, "");
-        defaultDb.update(CLIENT_TABLE_NAME, values,
-                CLIENT_METADATA_URI_COLUMN + " = ?", new String[] { uri });
+        final Cursor cursor = MetadataDbHelper.queryClientIds(context);
+        if (null == cursor) return;
+        try {
+            if (!cursor.moveToFirst()) return;
+            do {
+                final String clientId = cursor.getString(0);
+                final String metadataUri =
+                        MetadataDbHelper.getMetadataUriAsString(context, clientId);
+                if (metadataUri.equals(uri)) {
+                    defaultDb.update(CLIENT_TABLE_NAME, values,
+                            CLIENT_CLIENT_ID_COLUMN + " = ?", new String[] { clientId });
+                }
+            } while (cursor.moveToNext());
+        } finally {
+            cursor.close();
+        }
     }
 
     /**
diff --git a/java/src/com/android/inputmethod/dictionarypack/MetadataUriGetter.java b/java/src/com/android/inputmethod/dictionarypack/MetadataUriGetter.java
new file mode 100644
index 0000000..ed81765
--- /dev/null
+++ b/java/src/com/android/inputmethod/dictionarypack/MetadataUriGetter.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2013 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.inputmethod.dictionarypack;
+
+import android.content.Context;
+
+/**
+ * Helper to get the metadata URI from its base URI and the additional ID, if any.
+ */
+public class MetadataUriGetter {
+    private MetadataUriGetter() {
+        // This helper class is not instantiable.
+    }
+
+    public static String getUri(final Context context, final String baseUri,
+            final String additionalId) {
+        return baseUri;
+    }
+}
diff --git a/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java b/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java
index 93f12d5..f042795 100644
--- a/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java
+++ b/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java
@@ -16,10 +16,9 @@
 
 package com.android.inputmethod.dictionarypack;
 
-import android.app.Dialog;
 import android.content.Context;
 import android.content.SharedPreferences;
-import android.preference.DialogPreference;
+import android.preference.Preference;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
@@ -38,7 +37,7 @@
  * pack. Upon being pressed, it displays a menu to allow the user to install, disable,
  * enable or delete it as appropriate for the current state of the word list.
  */
-public final class WordListPreference extends DialogPreference {
+public final class WordListPreference extends Preference {
     static final private String TAG = WordListPreference.class.getSimpleName();
 
     // What to display in the "status" field when we receive unknown data as a status from
@@ -93,12 +92,6 @@
         if (status == mStatus) return;
         mStatus = status;
         setSummary(getSummary(status));
-        // If we are currently displaying the dialog, we should update it, or at least
-        // dismiss it.
-        final Dialog dialog = getDialog();
-        if (null != dialog) {
-            dialog.dismiss();
-        }
     }
 
     private String getSummary(final int status) {
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
index 42f7136..4a2c3bb 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
@@ -81,6 +81,7 @@
     private static final String QUERY_PATH_METADATA = "metadata";
     private static final String INSERT_METADATA_CLIENT_ID_COLUMN = "clientid";
     private static final String INSERT_METADATA_METADATA_URI_COLUMN = "uri";
+    private static final String INSERT_METADATA_METADATA_ADDITIONAL_ID_COLUMN = "additionalid";
 
     // Prevents this class to be accidentally instantiated.
     private BinaryDictionaryFileDumper() {
@@ -423,6 +424,7 @@
     private static void reinitializeClientRecordInDictionaryContentProvider(final Context context,
             final ContentProviderClient client, final String clientId) throws RemoteException {
         final String metadataFileUri = MetadataFileUriGetter.getMetadataUri(context);
+        final String metadataAdditionalId = MetadataFileUriGetter.getMetadataAdditionalId(context);
         if (TextUtils.isEmpty(metadataFileUri)) return;
         // Tell the content provider to reset all information about this client id
         final Uri metadataContentUri = getProviderUriBuilder(clientId)
@@ -434,6 +436,7 @@
         final ContentValues metadataValues = new ContentValues();
         metadataValues.put(INSERT_METADATA_CLIENT_ID_COLUMN, clientId);
         metadataValues.put(INSERT_METADATA_METADATA_URI_COLUMN, metadataFileUri);
+        metadataValues.put(INSERT_METADATA_METADATA_ADDITIONAL_ID_COLUMN, metadataAdditionalId);
         client.insert(metadataContentUri, metadataValues);
 
         // Update the dictionary list.
diff --git a/java/src/com/android/inputmethod/latin/MetadataFileUriGetter.java b/java/src/com/android/inputmethod/latin/MetadataFileUriGetter.java
index e6dc6db..a98ecc7 100644
--- a/java/src/com/android/inputmethod/latin/MetadataFileUriGetter.java
+++ b/java/src/com/android/inputmethod/latin/MetadataFileUriGetter.java
@@ -19,10 +19,18 @@
 import android.content.Context;
 
 /**
- * Helper class to get the metadata URI.
+ * Helper class to get the metadata URI and the additional ID.
  */
 public class MetadataFileUriGetter {
-    public static String getMetadataUri(Context context) {
+    private MetadataFileUriGetter() {
+        // This helper class is not instantiable.
+    }
+
+    public static String getMetadataUri(final Context context) {
         return context.getString(R.string.dictionary_pack_metadata_uri);
     }
+
+    public static String getMetadataAdditionalId(final Context context) {
+        return "";
+    }
 }
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index 04be1c9..22ec015 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -36,6 +36,7 @@
     public static final String PREF_POPUP_ON = "popup_on";
     public static final String PREF_VOICE_MODE = "voice_mode";
     public static final String PREF_CORRECTION_SETTINGS = "correction_settings";
+    public static final String PREF_EDIT_PERSONAL_DICTIONARY = "edit_personal_dictionary";
     public static final String PREF_CONFIGURE_DICTIONARIES_KEY = "configure_dictionaries_key";
     public static final String PREF_AUTO_CORRECTION_THRESHOLD = "auto_correction_threshold";
     public static final String PREF_SHOW_SUGGESTIONS_SETTING = "show_suggestions_setting";
diff --git a/java/src/com/android/inputmethod/latin/SettingsFragment.java b/java/src/com/android/inputmethod/latin/SettingsFragment.java
index 2e41368..88a2714 100644
--- a/java/src/com/android/inputmethod/latin/SettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/SettingsFragment.java
@@ -20,6 +20,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
 import android.media.AudioManager;
 import android.os.Bundle;
@@ -29,6 +31,7 @@
 import android.preference.Preference.OnPreferenceClickListener;
 import android.preference.PreferenceGroup;
 import android.preference.PreferenceScreen;
+import android.util.Log;
 import android.view.inputmethod.InputMethodSubtype;
 
 import com.android.inputmethod.dictionarypack.DictionarySettingsActivity;
@@ -38,6 +41,8 @@
 
 public final class SettingsFragment extends InputMethodSettingsFragment
         implements SharedPreferences.OnSharedPreferenceChangeListener {
+    private static final String TAG = SettingsFragment.class.getSimpleName();
+
     private ListPreference mVoicePreference;
     private ListPreference mShowCorrectionSuggestionsPreference;
     private ListPreference mAutoCorrectionThresholdPreference;
@@ -187,6 +192,16 @@
             textCorrectionGroup.removePreference(dictionaryLink);
         }
 
+        final Preference editPersonalDictionary =
+                findPreference(Settings.PREF_EDIT_PERSONAL_DICTIONARY);
+        final Intent editPersonalDictionaryIntent = editPersonalDictionary.getIntent();
+        final ResolveInfo ri = context.getPackageManager().resolveActivity(
+                editPersonalDictionaryIntent, PackageManager.MATCH_DEFAULT_ONLY);
+        if (ri == null) {
+            // TODO: Set a intent that invokes our own edit personal dictionary activity.
+            Log.w(TAG, "No activity that responds to " + editPersonalDictionaryIntent.getAction());
+        }
+
         if (!Settings.readFromBuildConfigIfGestureInputEnabled(res)) {
             removePreference(Settings.PREF_GESTURE_SETTINGS, getPreferenceScreen());
         }
diff --git a/native/jni/src/suggest/core/policy/weighting.cpp b/native/jni/src/suggest/core/policy/weighting.cpp
index b9c0b81..a6d30e4 100644
--- a/native/jni/src/suggest/core/policy/weighting.cpp
+++ b/native/jni/src/suggest/core/policy/weighting.cpp
@@ -229,7 +229,7 @@
         case CT_MATCH:
             return 1;
         case CT_COMPLETION:
-            return 0;
+            return 1;
         case CT_TERMINAL:
             return 0;
         case CT_NEW_WORD_SPACE_SUBSTITUTION:
diff --git a/native/jni/src/suggest/policyimpl/typing/scoring_params.cpp b/native/jni/src/suggest/policyimpl/typing/scoring_params.cpp
index 11ccf17..9933586 100644
--- a/native/jni/src/suggest/policyimpl/typing/scoring_params.cpp
+++ b/native/jni/src/suggest/policyimpl/typing/scoring_params.cpp
@@ -41,8 +41,8 @@
 const float ScoringParams::COST_NEW_WORD = 0.024f;
 const float ScoringParams::COST_NEW_WORD_CAPITALIZED = 0.174f;
 const float ScoringParams::DISTANCE_WEIGHT_LANGUAGE = 1.123f;
-const float ScoringParams::COST_FIRST_LOOKAHEAD = 0.462f;
-const float ScoringParams::COST_LOOKAHEAD = 0.092f;
+const float ScoringParams::COST_FIRST_LOOKAHEAD = 0.545f;
+const float ScoringParams::COST_LOOKAHEAD = 0.073f;
 const float ScoringParams::HAS_PROXIMITY_TERMINAL_COST = 0.126f;
 const float ScoringParams::HAS_EDIT_CORRECTION_TERMINAL_COST = 0.056f;
 const float ScoringParams::HAS_MULTI_WORD_TERMINAL_COST = 0.536f;