Merge "Purge ver3 dictionary reading in native code."
diff --git a/java/AndroidManifest.xml b/java/AndroidManifest.xml
index a8dabd2..0d80c03 100644
--- a/java/AndroidManifest.xml
+++ b/java/AndroidManifest.xml
@@ -32,7 +32,7 @@
     <uses-permission android:name="android.permission.WRITE_USER_DICTIONARY" />
 
     <application android:label="@string/english_ime_name"
-            android:icon="@mipmap/ic_launcher_keyboard"
+            android:icon="@drawable/ic_launcher_keyboard"
             android:killAfterRestore="false"
             android:supportsRtl="true">
 
@@ -57,7 +57,7 @@
 
         <activity android:name=".setup.SetupActivity"
                 android:label="@string/english_ime_name"
-                android:icon="@mipmap/ic_launcher_keyboard"
+                android:icon="@drawable/ic_launcher_keyboard"
                 android:launchMode="singleTask"
                 android:noHistory="true">
             <intent-filter>
diff --git a/java/res/mipmap-hdpi/ic_launcher_keyboard.png b/java/res/drawable-hdpi/ic_launcher_keyboard.png
similarity index 100%
rename from java/res/mipmap-hdpi/ic_launcher_keyboard.png
rename to java/res/drawable-hdpi/ic_launcher_keyboard.png
Binary files differ
diff --git a/java/res/mipmap-mdpi/ic_launcher_keyboard.png b/java/res/drawable-mdpi/ic_launcher_keyboard.png
similarity index 100%
rename from java/res/mipmap-mdpi/ic_launcher_keyboard.png
rename to java/res/drawable-mdpi/ic_launcher_keyboard.png
Binary files differ
diff --git a/java/res/mipmap-xhdpi/ic_launcher_keyboard.png b/java/res/drawable-xhdpi/ic_launcher_keyboard.png
similarity index 100%
rename from java/res/mipmap-xhdpi/ic_launcher_keyboard.png
rename to java/res/drawable-xhdpi/ic_launcher_keyboard.png
Binary files differ
diff --git a/java/res/mipmap-xxhdpi/ic_launcher_keyboard.png b/java/res/drawable-xxhdpi/ic_launcher_keyboard.png
similarity index 100%
rename from java/res/mipmap-xxhdpi/ic_launcher_keyboard.png
rename to java/res/drawable-xxhdpi/ic_launcher_keyboard.png
Binary files differ
diff --git a/java/res/values-sw540dp/config.xml b/java/res/values-sw540dp/config.xml
index 8d0b7f4..ffba0a2 100644
--- a/java/res/values-sw540dp/config.xml
+++ b/java/res/values-sw540dp/config.xml
@@ -20,14 +20,11 @@
 
 <!-- Configuration values for Large Phone and Small Tablet Portrait. -->
 <resources>
-    <bool name="config_enable_show_option_of_key_preview_popup">false</bool>
+    <bool name="config_enable_show_key_preview_popup_option">false</bool>
     <!-- Whether or not Popup on key press is enabled by default -->
     <bool name="config_default_key_preview_popup">false</bool>
     <bool name="config_default_sound_enabled">true</bool>
-    <integer name="config_max_more_keys_column">5</integer>
-    <!--
-        Configuration for MainKeyboardView
-    -->
+
     <dimen name="config_key_hysteresis_distance">40.0dp</dimen>
     <bool name="config_key_selection_by_dragging_finger">false</bool>
     <!-- Showing more keys keyboard, just above the touched point if true, aligned to the key if
diff --git a/java/res/values-sw768dp/config.xml b/java/res/values-sw768dp/config.xml
index bc6feba..b63b509 100644
--- a/java/res/values-sw768dp/config.xml
+++ b/java/res/values-sw768dp/config.xml
@@ -21,14 +21,11 @@
 <!-- Configuration values for Large Tablet Portrait. -->
 <resources>
     <bool name="config_enable_show_voice_key_option">false</bool>
-    <bool name="config_enable_show_option_of_key_preview_popup">false</bool>
+    <bool name="config_enable_show_key_preview_popup_option">false</bool>
     <!-- Whether or not Popup on key press is enabled by default -->
     <bool name="config_default_key_preview_popup">false</bool>
     <bool name="config_default_sound_enabled">true</bool>
-    <integer name="config_max_more_keys_column">5</integer>
-    <!--
-        Configuration for MainKeyboardView
-    -->
+
     <bool name="config_key_selection_by_dragging_finger">false</bool>
     <!-- Showing more keys keyboard, just above the touched point if true, aligned to the key if
          false -->
diff --git a/java/res/values/config-common.xml b/java/res/values/config-common.xml
new file mode 100644
index 0000000..ab16a90
--- /dev/null
+++ b/java/res/values/config-common.xml
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<resources>
+    <bool name="config_block_potentially_offensive">true</bool>
+    <!-- Default value for next word prediction: after entering a word and a space only, should we look
+         at input history to suggest a hopefully helpful suggestions for the next word? -->
+    <bool name="config_default_next_word_prediction">true</bool>
+
+    <!-- This configuration is an index of  {@link KeyboardSwitcher#KEYBOARD_THEMES[]}. -->
+    <string name="config_default_keyboard_theme_index" translatable="false">2</string>
+
+    <integer name="config_delay_update_shift_state">100</integer>
+    <integer name="config_double_space_period_timeout">1100</integer>
+
+    <integer name="config_key_repeat_start_timeout">400</integer>
+    <integer name="config_key_repeat_interval">50</integer>
+
+    <integer name="config_ignore_alt_code_key_timeout">350</integer>
+
+    <integer name="config_key_preview_zoom_in_duration">35</integer>
+    <integer name="config_key_preview_zoom_out_duration">40</integer>
+    <integer name="config_key_preview_linger_timeout">70</integer>
+    <!-- Suppress showing key preview duration after batch input in millisecond -->
+    <integer name="config_suppress_key_preview_after_batch_input_duration">1000</integer>
+
+    <bool name="config_default_vibration_enabled">true</bool>
+    <integer name="config_max_vibration_duration">100</integer>
+
+    <integer name="config_default_longpress_key_timeout">300</integer>
+    <integer name="config_max_longpress_timeout">700</integer>
+    <integer name="config_min_longpress_timeout">100</integer>
+    <integer name="config_longpress_timeout_step">10</integer>
+    <integer name="config_max_more_keys_column">5</integer>
+    <integer name="config_more_keys_keyboard_fadein_anim_time">0</integer>
+    <integer name="config_more_keys_keyboard_fadeout_anim_time">100</integer>
+
+    <!-- Long pressing shift will invoke caps-lock if > 0, never invoke caps-lock if == 0 -->
+    <integer name="config_longpress_shift_lock_timeout">1200</integer>
+
+    <!-- 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.
+         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>
+    <dimen name="config_key_hysteresis_distance_for_sliding_modifier">8.0dp</dimen>
+
+    <integer name="config_language_on_spacebar_final_alpha">128</integer>
+    <dimen name="config_language_on_spacebar_horizontal_margin">1dp</dimen>
+
+    <integer name="config_gesture_floating_preview_text_linger_timeout">200</integer>
+    <integer name="config_gesture_trail_fadeout_start_delay">100</integer>
+    <integer name="config_gesture_trail_fadeout_duration">800</integer>
+    <integer name="config_gesture_trail_update_interval">20</integer>
+    <!-- Static threshold for gesture after fast typing (msec) -->
+    <integer name="config_gesture_static_time_threshold_after_fast_typing">500</integer>
+    <!-- Static threshold for starting gesture detection (keyWidth%/sec) -->
+    <fraction name="config_gesture_detect_fast_move_speed_threshold">150%</fraction>
+    <!-- Dynamic threshold for gesture after fast typing (msec) -->
+    <integer name="config_gesture_dynamic_threshold_decay_duration">450</integer>
+    <!-- Time based threshold values for gesture detection (msec) -->
+    <integer name="config_gesture_dynamic_time_threshold_from">300</integer>
+    <integer name="config_gesture_dynamic_time_threshold_to">20</integer>
+    <!-- Distance based threshold values for gesture detection (keyWidth%/sec) -->
+    <fraction name="config_gesture_dynamic_distance_threshold_from">600%</fraction>
+    <fraction name="config_gesture_dynamic_distance_threshold_to">50%</fraction>
+    <!-- Parameter for gesture sampling (keyWidth%/sec) -->
+    <fraction name="config_gesture_sampling_minimum_distance">16.6666%</fraction>
+    <!-- Parameters for gesture recognition (msec) and (keyWidth%/sec) -->
+    <integer name="config_gesture_recognition_minimum_time">100</integer>
+    <integer name="config_gesture_recognition_update_time">100</integer>
+    <fraction name="config_gesture_recognition_speed_threshold">550%</fraction>
+
+    <integer name="config_keyboard_grid_width">32</integer>
+    <integer name="config_keyboard_grid_height">16</integer>
+    <dimen name="config_touch_noise_threshold_distance">12.6dp</dimen>
+    <integer name="config_touch_noise_threshold_time">40</integer>
+
+    <!-- Common keyboard configuration. -->
+    <fraction name="config_keyboard_left_padding">0%p</fraction>
+    <fraction name="config_keyboard_right_padding">0%p</fraction>
+    <dimen name="config_keyboard_vertical_correction">0.0dp</dimen>
+
+    <!-- Common key top visual configuration. -->
+    <dimen name="config_key_popup_hint_letter_padding">2dp</dimen>
+
+    <!-- Common suggestion strip configuration. -->
+    <integer name="config_suggestions_count_in_strip">3</integer>
+    <fraction name="config_center_suggestion_percentile">36%</fraction>
+    <integer name="config_delay_update_suggestions">100</integer>
+    <integer name="config_delay_update_old_suggestions">300</integer>
+
+    <!-- Common more suggestions configuraion. -->
+    <dimen name="config_more_suggestions_key_horizontal_padding">12dp</dimen>
+    <dimen name="config_more_suggestions_bottom_gap">6dp</dimen>
+    <dimen name="config_more_suggestions_modal_tolerance">32.0dp</dimen>
+    <fraction name="config_more_suggestions_info_ratio">18%</fraction>
+
+    <!-- Common gesture trail parameters -->
+    <!-- Minimum distance between gesture trail sampling points. -->
+    <dimen name="config_gesture_trail_min_sampling_distance">9.6dp</dimen>
+    <!-- Maximum angular threshold between gesture trails interpolation segments in degree. -->
+    <integer name="config_gesture_trail_max_interpolation_angular_threshold">15</integer>
+    <!-- Maximum distance threshold between gesture trails interpolation segments. -->
+    <dimen name="config_gesture_trail_max_interpolation_distance_threshold">16.0dp</dimen>
+    <!-- Maximum number of gesture trail interpolation segments. -->
+    <integer name="config_gesture_trail_max_interpolation_segments">6</integer>
+    <dimen name="config_gesture_trail_start_width">10.0dp</dimen>
+    <dimen name="config_gesture_trail_end_width">2.5dp</dimen>
+    <!-- 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="config_gesture_trail_body_ratio">100</integer>
+    <integer name="config_gesture_trail_shadow_ratio">-1</integer>
+
+    <!-- Common configuration of Emoji keyboard -->
+    <dimen name="config_emoji_category_page_id_height">3dp</dimen>
+
+    <!-- Inset used in Accessibility mode to avoid accidental key presses when a finger slides off the screen. -->
+    <dimen name="config_accessibility_edge_slop">8dp</dimen>
+
+    <integer name="config_user_dictionary_max_word_length">48</integer>
+</resources>
diff --git a/java/res/values/config.xml b/java/res/values/config.xml
index 2c56651..698efa9 100644
--- a/java/res/values/config.xml
+++ b/java/res/values/config.xml
@@ -22,83 +22,16 @@
 <resources>
     <bool name="config_use_fullscreen_mode">false</bool>
     <bool name="config_enable_show_voice_key_option">true</bool>
-    <bool name="config_enable_show_option_of_key_preview_popup">true</bool>
+    <bool name="config_enable_show_key_preview_popup_option">true</bool>
     <!-- Whether or not Popup on key press is enabled by default -->
     <bool name="config_default_key_preview_popup">true</bool>
-    <!-- Default value for next word prediction: after entering a word and a space only, should we look
-         at input history to suggest a hopefully helpful suggestions for the next word? -->
-    <bool name="config_default_next_word_prediction">true</bool>
     <bool name="config_default_sound_enabled">false</bool>
-    <bool name="config_default_vibration_enabled">true</bool>
-    <integer name="config_max_vibration_duration">100</integer> <!-- milliseconds -->
-    <integer name="config_delay_update_suggestions">100</integer>
-    <integer name="config_delay_update_old_suggestions">300</integer>
-    <integer name="config_delay_update_shift_state">100</integer>
-    <integer name="config_language_on_spacebar_final_alpha">128</integer>
-    <integer name="config_more_keys_keyboard_fadein_anim_time">0</integer>
-    <integer name="config_more_keys_keyboard_fadeout_anim_time">100</integer>
-    <integer name="config_keyboard_grid_width">32</integer>
-    <integer name="config_keyboard_grid_height">16</integer>
-    <integer name="config_double_space_period_timeout">1100</integer>
-    <!-- This configuration is an index of  {@link KeyboardSwitcher#KEYBOARD_THEMES[]}. -->
-    <string name="config_default_keyboard_theme_index" translatable="false">2</string>
-    <integer name="config_max_more_keys_column">5</integer>
 
-    <!--
-         Configuration for MainKeyboardView
-    -->
     <dimen name="config_key_hysteresis_distance">8.0dp</dimen>
-    <dimen name="config_key_hysteresis_distance_for_sliding_modifier">8.0dp</dimen>
-    <integer name="config_touch_noise_threshold_time">40</integer>
-    <dimen name="config_touch_noise_threshold_distance">12.6dp</dimen>
-    <integer name="config_key_preview_zoom_in_duration">35</integer>
-    <integer name="config_key_preview_zoom_out_duration">40</integer>
-    <integer name="config_key_preview_linger_timeout">70</integer>
     <bool name="config_key_selection_by_dragging_finger">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.
-         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 -->
-    <integer name="config_longpress_timeout_step">10</integer> <!-- milliseconds -->
-    <integer name="config_min_longpress_timeout">100</integer> <!-- milliseconds -->
-    <integer name="config_max_longpress_timeout">700</integer> <!-- milliseconds -->
-    <!-- Long pressing shift will invoke caps-lock if > 0, never invoke caps-lock if == 0 -->
-    <integer name="config_longpress_shift_lock_timeout">1200</integer> <!-- milliseconds -->
-    <integer name="config_ignore_alt_code_key_timeout">350</integer> <!-- milliseconds -->
     <!-- Showing more keys keyboard, just above the touched point if true, aligned to the key if
          false -->
     <bool name="config_show_more_keys_keyboard_at_touched_point">false</bool>
-    <bool name="config_block_potentially_offensive">true</bool>
-    <integer name="config_gesture_floating_preview_text_linger_timeout">200</integer>
-    <integer name="config_gesture_trail_fadeout_start_delay">100</integer>
-    <integer name="config_gesture_trail_fadeout_duration">800</integer>
-    <integer name="config_gesture_trail_update_interval">20</integer>
-    <!-- Static threshold for gesture after fast typing (msec) -->
-    <integer name="config_gesture_static_time_threshold_after_fast_typing">500</integer>
-    <!-- Static threshold for starting gesture detection (keyWidth%/sec) -->
-    <fraction name="config_gesture_detect_fast_move_speed_threshold">150%</fraction>
-    <!-- Dynamic threshold for gesture after fast typing (msec) -->
-    <integer name="config_gesture_dynamic_threshold_decay_duration">450</integer>
-    <!-- Time based threshold values for gesture detection (msec) -->
-    <integer name="config_gesture_dynamic_time_threshold_from">300</integer>
-    <integer name="config_gesture_dynamic_time_threshold_to">20</integer>
-    <!-- Distance based threshold values for gesture detection (keyWidth%/sec) -->
-    <fraction name="config_gesture_dynamic_distance_threshold_from">600%</fraction>
-    <fraction name="config_gesture_dynamic_distance_threshold_to">50%</fraction>
-    <!-- Parameter for gesture sampling (keyWidth%/sec) -->
-    <fraction name="config_gesture_sampling_minimum_distance">16.6666%</fraction>
-    <!-- Parameters for gesture recognition (msec) and (keyWidth%/sec) -->
-    <integer name="config_gesture_recognition_minimum_time">100</integer>
-    <integer name="config_gesture_recognition_update_time">100</integer>
-    <fraction name="config_gesture_recognition_speed_threshold">550%</fraction>
-    <!-- Suppress showing key preview duration after batch input in millisecond -->
-    <integer name="config_suppress_key_preview_after_batch_input_duration">1000</integer>
 
     <!-- Preferable keyboard height in absolute scale: 1.285in -->
     <!-- This config_default_keyboard_height value should match with keyboard-heights.xml -->
@@ -110,9 +43,6 @@
 
     <dimen name="config_more_keys_keyboard_key_horizontal_padding">8dp</dimen>
 
-    <fraction name="config_keyboard_left_padding">0%p</fraction>
-    <fraction name="config_keyboard_right_padding">0%p</fraction>
-
     <fraction name="config_keyboard_top_padding_gb">1.556%p</fraction>
     <fraction name="config_keyboard_bottom_padding_gb">4.669%p</fraction>
     <fraction name="config_key_vertical_gap_gb">6.495%p</fraction>
@@ -128,7 +58,6 @@
     <dimen name="config_more_keys_keyboard_slide_allowance">63.36dp</dimen>
     <!-- config_more_keys_keyboard_key_height x -1.0 -->
     <dimen name="config_more_keys_keyboard_vertical_correction_gb">-52.8dp</dimen>
-    <dimen name="config_keyboard_vertical_correction">0.0dp</dimen>
 
     <fraction name="config_key_letter_ratio">55%</fraction>
     <fraction name="config_key_large_letter_ratio">65%</fraction>
@@ -144,7 +73,6 @@
 
     <dimen name="config_key_label_horizontal_padding">4dp</dimen>
     <dimen name="config_key_hint_letter_padding">1dp</dimen>
-    <dimen name="config_key_popup_hint_letter_padding">2dp</dimen>
     <dimen name="config_key_shifted_letter_hint_padding">2dp</dimen>
 
     <!-- For 5-row keyboard -->
@@ -157,37 +85,15 @@
     <dimen name="config_more_keys_keyboard_vertical_correction_holo">-26.4dp</dimen>
 
     <dimen name="config_suggestions_strip_height">40dp</dimen>
-    <dimen name="config_more_suggestions_key_horizontal_padding">12dp</dimen>
     <dimen name="config_more_suggestions_row_height">40dp</dimen>
-    <dimen name="config_more_suggestions_bottom_gap">6dp</dimen>
-    <dimen name="config_more_suggestions_modal_tolerance">32.0dp</dimen>
     <integer name="config_max_more_suggestions_row">6</integer>
     <fraction name="config_min_more_suggestions_width">90%</fraction>
-    <fraction name="config_more_suggestions_info_ratio">18%</fraction>
     <dimen name="config_suggestions_strip_horizontal_padding">0dp</dimen>
     <dimen name="config_suggestion_min_width">44dp</dimen>
     <dimen name="config_suggestion_text_horizontal_padding">6dp</dimen>
     <dimen name="config_suggestion_text_size">18dp</dimen>
     <dimen name="config_more_suggestions_hint_text_size">27dp</dimen>
-    <integer name="config_suggestions_count_in_strip">3</integer>
-    <fraction name="config_center_suggestion_percentile">36%</fraction>
 
-    <!-- Gesture trail parameters -->
-    <!-- Minimum distance between gesture trail sampling points. -->
-    <dimen name="config_gesture_trail_min_sampling_distance">9.6dp</dimen>
-    <!-- Maximum angular threshold between gesture trails interpolation segments in degree. -->
-    <integer name="config_gesture_trail_max_interpolation_angular_threshold">15</integer>
-    <!-- Maximum distance threshold between gesture trails interpolation segments. -->
-    <dimen name="config_gesture_trail_max_interpolation_distance_threshold">16.0dp</dimen>
-    <!-- Maximum number of gesture trail interpolation segments. -->
-    <integer name="config_gesture_trail_max_interpolation_segments">6</integer>
-    <dimen name="config_gesture_trail_start_width">10.0dp</dimen>
-    <dimen name="config_gesture_trail_end_width">2.5dp</dimen>
-    <!-- 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="config_gesture_trail_body_ratio">100</integer>
-    <integer name="config_gesture_trail_shadow_ratio">-1</integer>
     <!-- Gesture floating preview text parameters -->
     <dimen name="config_gesture_floating_preview_text_size">24dp</dimen>
     <dimen name="config_gesture_floating_preview_text_offset">73dp</dimen>
@@ -200,12 +106,4 @@
     <fraction name="config_emoji_keyboard_row_height">33%p</fraction>
     <fraction name="config_emoji_keyboard_key_letter_size">68%p</fraction>
     <integer name="config_emoji_keyboard_max_page_key_count">21</integer>
-    <dimen name="config_emoji_category_page_id_height">3dp</dimen>
-
-    <!-- Inset used in Accessibility mode to avoid accidental key presses when a finger slides off the screen. -->
-    <dimen name="config_accessibility_edge_slop">8dp</dimen>
-
-    <integer name="config_user_dictionary_max_word_length" translatable="false">48</integer>
-
-    <dimen name="config_language_on_spacebar_horizontal_margin">1dp</dimen>
 </resources>
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 4fa682d..174bbfb 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -376,7 +376,10 @@
     private void reopen() {
         close();
         final File dictFile = new File(mDictFilePath);
-        mNativeDict = openNative(dictFile.getAbsolutePath(), 0 /* startOffset */,
+        // WARNING: Because we pass 0 as the offstet and file.length() as the length, this can
+        // only be called for actual files. Right now it's only called by the flush() family of
+        // functions, which require an updatable dictionary, so it's okay. But beware.
+        loadDictionary(dictFile.getAbsolutePath(), 0 /* startOffset */,
                 dictFile.length(), true /* isUpdatable */);
     }
 
diff --git a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
index 366f3d4..b70362f 100644
--- a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
@@ -72,8 +72,8 @@
     private final boolean mUseFirstLastBigrams;
 
     public ContactsBinaryDictionary(final Context context, final Locale locale) {
-        super(context, getFilenameWithLocale(NAME, locale.toString()), Dictionary.TYPE_CONTACTS,
-                false /* isUpdatable */);
+        super(context, getFilenameWithLocale(NAME, locale), locale,
+                Dictionary.TYPE_CONTACTS, false /* isUpdatable */);
         mLocale = locale;
         mUseFirstLastBigrams = useFirstLastBigramsForLocale(locale);
         registerObserver(context);
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index 17cb715..154e9b5 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -33,8 +33,10 @@
 import java.io.File;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Locale;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -99,6 +101,9 @@
      */
     private final String mFilename;
 
+    /** Dictionary locale */
+    private final Locale mLocale;
+
     /** Whether to support dynamically updating the dictionary */
     private final boolean mIsUpdatable;
 
@@ -183,15 +188,17 @@
      * @param context The application context of the parent.
      * @param filename The filename for this binary dictionary. Multiple dictionaries with the same
      *        filename is supported.
+     * @param locale the dictionary locale.
      * @param dictType the dictionary type, as a human-readable string
      * @param isUpdatable whether to support dynamically updating the dictionary. Please note that
      *        dynamic dictionary has negative effects on memory space and computation time.
      */
     public ExpandableBinaryDictionary(final Context context, final String filename,
-            final String dictType, final boolean isUpdatable) {
+            final Locale locale, final String dictType, final boolean isUpdatable) {
         super(dictType);
         mFilename = filename;
         mContext = context;
+        mLocale = locale;
         mIsUpdatable = isUpdatable;
         mBinaryDictionary = null;
         mFilenameDictionaryUpdateController = getDictionaryUpdateController(filename);
@@ -199,8 +206,8 @@
         mDictionaryWriter = getDictionaryWriter(context, dictType, isUpdatable);
     }
 
-    protected static String getFilenameWithLocale(final String name, final String localeStr) {
-        return name + "." + localeStr + DICT_FILE_EXTENSION;
+    protected static String getFilenameWithLocale(final String name, final Locale locale) {
+        return name + "." + locale.toString() + DICT_FILE_EXTENSION;
     }
 
     /**
@@ -237,9 +244,10 @@
 
     protected Map<String, String> getHeaderAttributeMap() {
         HashMap<String, String> attributeMap = new HashMap<String, String>();
-        attributeMap.put(FormatSpec.FileHeader.SUPPORTS_DYNAMIC_UPDATE_ATTRIBUTE,
-                SUPPORTS_DYNAMIC_UPDATE);
         attributeMap.put(FormatSpec.FileHeader.DICTIONARY_ID_ATTRIBUTE, mFilename);
+        attributeMap.put(FormatSpec.FileHeader.DICTIONARY_LOCALE_ATTRIBUTE, mLocale.toString());
+        attributeMap.put(FormatSpec.FileHeader.DICTIONARY_VERSION_ATTRIBUTE,
+                String.valueOf(TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())));
         return attributeMap;
     }
 
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 6f9dd67..8ce1e38 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -614,7 +614,6 @@
         final Locale switcherSubtypeLocale = mSubtypeSwitcher.getCurrentSubtypeLocale();
         final String switcherLocaleStr = switcherSubtypeLocale.toString();
         final Locale subtypeLocale;
-        final String localeStr;
         if (TextUtils.isEmpty(switcherLocaleStr)) {
             // This happens in very rare corner cases - for example, immediately after a switch
             // to LatinIME has been requested, about a frame later another switch happens. In this
@@ -624,10 +623,8 @@
             // of knowing anyway.
             Log.e(TAG, "System is reporting no current subtype.");
             subtypeLocale = getResources().getConfiguration().locale;
-            localeStr = subtypeLocale.toString();
         } else {
             subtypeLocale = switcherSubtypeLocale;
-            localeStr = switcherLocaleStr;
         }
 
         final Suggest newSuggest = new Suggest(this /* Context */, subtypeLocale,
@@ -642,19 +639,20 @@
             ResearchLogger.getInstance().initSuggest(newSuggest);
         }
 
-        mUserDictionary = new UserBinaryDictionary(this, localeStr);
+        mUserDictionary = new UserBinaryDictionary(this, subtypeLocale);
         mIsUserDictionaryAvailable = mUserDictionary.isEnabled();
         newSuggest.setUserDictionary(mUserDictionary);
 
         final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
 
-        mUserHistoryDictionary = PersonalizationHelper.getUserHistoryDictionary(this, localeStr);
+        mUserHistoryDictionary = PersonalizationHelper.getUserHistoryDictionary(
+                this, subtypeLocale);
         newSuggest.setUserHistoryDictionary(mUserHistoryDictionary);
         mPersonalizationDictionary =
-                PersonalizationHelper.getPersonalizationDictionary(this, localeStr);
+                PersonalizationHelper.getPersonalizationDictionary(this, subtypeLocale);
         newSuggest.setPersonalizationDictionary(mPersonalizationDictionary);
         mPersonalizationPredictionDictionary =
-                PersonalizationHelper.getPersonalizationPredictionDictionary(this, localeStr);
+                PersonalizationHelper.getPersonalizationPredictionDictionary(this, subtypeLocale);
         newSuggest.setPersonalizationPredictionDictionary(mPersonalizationPredictionDictionary);
 
         final Suggest oldSuggest = mSuggest;
diff --git a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java
index 6405b5e..9cb2f5b 100644
--- a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java
@@ -22,14 +22,15 @@
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
 
 import java.util.ArrayList;
+import java.util.Locale;
 
 public final class SynchronouslyLoadedUserBinaryDictionary extends UserBinaryDictionary {
 
-    public SynchronouslyLoadedUserBinaryDictionary(final Context context, final String locale) {
+    public SynchronouslyLoadedUserBinaryDictionary(final Context context, final Locale locale) {
         this(context, locale, false);
     }
 
-    public SynchronouslyLoadedUserBinaryDictionary(final Context context, final String locale,
+    public SynchronouslyLoadedUserBinaryDictionary(final Context context, final Locale locale,
             final boolean alsoUseMoreRestrictiveLocales) {
         super(context, locale, alsoUseMoreRestrictiveLocales);
     }
diff --git a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
index 15b3d8d..cc7687b 100644
--- a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
@@ -75,20 +75,21 @@
     final private String mLocale;
     final private boolean mAlsoUseMoreRestrictiveLocales;
 
-    public UserBinaryDictionary(final Context context, final String locale) {
+    public UserBinaryDictionary(final Context context, final Locale locale) {
         this(context, locale, false);
     }
 
-    public UserBinaryDictionary(final Context context, final String locale,
+    public UserBinaryDictionary(final Context context, final Locale locale,
             final boolean alsoUseMoreRestrictiveLocales) {
-        super(context, getFilenameWithLocale(NAME, locale), Dictionary.TYPE_USER,
+        super(context, getFilenameWithLocale(NAME, locale), locale, Dictionary.TYPE_USER,
                 false /* isUpdatable */);
         if (null == locale) throw new NullPointerException(); // Catch the error earlier
-        if (SubtypeLocaleUtils.NO_LANGUAGE.equals(locale)) {
+        final String localeStr = locale.toString();
+        if (SubtypeLocaleUtils.NO_LANGUAGE.equals(localeStr)) {
             // If we don't have a locale, insert into the "all locales" user dictionary.
             mLocale = USER_DICTIONARY_ALL_LANGUAGES;
         } else {
-            mLocale = locale;
+            mLocale = localeStr;
         }
         mAlsoUseMoreRestrictiveLocales = alsoUseMoreRestrictiveLocales;
         // Perform a managed query. The Activity will handle closing and re-querying the cursor
diff --git a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java
index dbf6d00..8f26f84 100644
--- a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java
+++ b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java
@@ -35,7 +35,9 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Locale;
 import java.util.Map;
+import java.util.concurrent.TimeUnit;
 
 /**
  * This class is a base class of a dictionary that supports decaying for the personalized language
@@ -55,7 +57,7 @@
     public static final int REQUIRED_BINARY_DICTIONARY_VERSION = 4;
 
     /** Locale for which this user history dictionary is storing words */
-    private final String mLocale;
+    private final Locale mLocale;
 
     private final String mFileName;
 
@@ -66,11 +68,11 @@
     @UsedForTesting boolean mIsTest = false;
 
     /* package */ DecayingExpandableBinaryDictionaryBase(final Context context,
-            final String locale, final String dictionaryType, final String fileName) {
-        super(context, fileName, dictionaryType, true);
+            final Locale locale, final String dictionaryType, final String fileName) {
+        super(context, fileName, locale, dictionaryType, true);
         mLocale = locale;
         mFileName = fileName;
-        if (mLocale != null && mLocale.length() > 1) {
+        if (mLocale != null && mLocale.toString().length() > 1) {
             reloadDictionaryIfRequired();
         }
     }
@@ -93,7 +95,9 @@
         attributeMap.put(FormatSpec.FileHeader.USES_FORGETTING_CURVE_ATTRIBUTE,
                 FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE);
         attributeMap.put(FormatSpec.FileHeader.DICTIONARY_ID_ATTRIBUTE, mFileName);
-        attributeMap.put(FormatSpec.FileHeader.DICTIONARY_LOCALE_ATTRIBUTE, mLocale);
+        attributeMap.put(FormatSpec.FileHeader.DICTIONARY_LOCALE_ATTRIBUTE, mLocale.toString());
+        attributeMap.put(FormatSpec.FileHeader.DICTIONARY_VERSION_ATTRIBUTE,
+                String.valueOf(TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())));
         return attributeMap;
     }
 
@@ -164,10 +168,6 @@
         // Never loaded to memory in Java side.
     }
 
-    protected String getLocale() {
-        return mLocale;
-    }
-
     public void registerUpdateSession(PersonalizationDictionaryUpdateSession session) {
         session.setPredictionDictionary(this);
         mSessions.add(session);
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java
index 67015f4..8d3dcc3 100644
--- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java
+++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java
@@ -21,9 +21,9 @@
 import com.android.inputmethod.latin.utils.CollectionUtils;
 
 import android.content.Context;
-import android.content.SharedPreferences;
 
 import java.util.ArrayList;
+import java.util.Locale;
 
 /**
  * This class is a dictionary for the personalized language model that uses binary dictionary.
@@ -33,14 +33,10 @@
     private final ArrayList<PersonalizationDictionaryUpdateSession> mSessions =
             CollectionUtils.newArrayList();
 
-    /** Locale for which this user history dictionary is storing words */
-    private final String mLocale;
-
-    public PersonalizationDictionary(final Context context, final String locale) {
+    public PersonalizationDictionary(final Context context, final Locale locale) {
         // TODO: Make isUpdatable true.
-        super(context, getFilenameWithLocale(NAME, locale), Dictionary.TYPE_PERSONALIZATION,
-                false /* isUpdatable */);
-        mLocale = locale;
+        super(context, getFilenameWithLocale(NAME, locale), locale,
+                Dictionary.TYPE_PERSONALIZATION, false /* isUpdatable */);
         // TODO: Restore last updated time
         loadDictionary();
     }
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java
index a47cc4d..f73bb28 100644
--- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java
+++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java
@@ -24,6 +24,7 @@
 import android.util.Log;
 
 import java.lang.ref.SoftReference;
+import java.util.Locale;
 import java.util.concurrent.ConcurrentHashMap;
 
 public class PersonalizationHelper {
@@ -41,11 +42,12 @@
                             CollectionUtils.newConcurrentHashMap();
 
     public static UserHistoryDictionary getUserHistoryDictionary(
-            final Context context, final String locale) {
+            final Context context, final Locale locale) {
+        final String localeStr = locale.toString();
         synchronized (sLangUserHistoryDictCache) {
-            if (sLangUserHistoryDictCache.containsKey(locale)) {
+            if (sLangUserHistoryDictCache.containsKey(localeStr)) {
                 final SoftReference<UserHistoryDictionary> ref =
-                        sLangUserHistoryDictCache.get(locale);
+                        sLangUserHistoryDictCache.get(localeStr);
                 final UserHistoryDictionary dict = ref == null ? null : ref.get();
                 if (dict != null) {
                     if (DEBUG) {
@@ -56,7 +58,8 @@
                 }
             }
             final UserHistoryDictionary dict = new UserHistoryDictionary(context, locale);
-            sLangUserHistoryDictCache.put(locale, new SoftReference<UserHistoryDictionary>(dict));
+            sLangUserHistoryDictCache.put(localeStr,
+                    new SoftReference<UserHistoryDictionary>(dict));
             return dict;
         }
     }
@@ -74,7 +77,7 @@
     }
 
     public static void registerPersonalizationDictionaryUpdateSession(final Context context,
-            final PersonalizationDictionaryUpdateSession session, String locale) {
+            final PersonalizationDictionaryUpdateSession session, Locale locale) {
         final PersonalizationPredictionDictionary predictionDictionary =
                 getPersonalizationPredictionDictionary(context, locale);
         predictionDictionary.registerUpdateSession(session);
@@ -83,11 +86,12 @@
     }
 
     public static PersonalizationDictionary getPersonalizationDictionary(
-            final Context context, final String locale) {
+            final Context context, final Locale locale) {
+        final String localeStr = locale.toString();
         synchronized (sLangPersonalizationDictCache) {
-            if (sLangPersonalizationDictCache.containsKey(locale)) {
+            if (sLangPersonalizationDictCache.containsKey(localeStr)) {
                 final SoftReference<PersonalizationDictionary> ref =
-                        sLangPersonalizationDictCache.get(locale);
+                        sLangPersonalizationDictCache.get(localeStr);
                 final PersonalizationDictionary dict = ref == null ? null : ref.get();
                 if (dict != null) {
                     if (DEBUG) {
@@ -98,17 +102,18 @@
             }
             final PersonalizationDictionary dict = new PersonalizationDictionary(context, locale);
             sLangPersonalizationDictCache.put(
-                    locale, new SoftReference<PersonalizationDictionary>(dict));
+                    localeStr, new SoftReference<PersonalizationDictionary>(dict));
             return dict;
         }
     }
 
     public static PersonalizationPredictionDictionary getPersonalizationPredictionDictionary(
-            final Context context, final String locale) {
+            final Context context, final Locale locale) {
+        final String localeStr = locale.toString();
         synchronized (sLangPersonalizationPredictionDictCache) {
-            if (sLangPersonalizationPredictionDictCache.containsKey(locale)) {
+            if (sLangPersonalizationPredictionDictCache.containsKey(localeStr)) {
                 final SoftReference<PersonalizationPredictionDictionary> ref =
-                        sLangPersonalizationPredictionDictCache.get(locale);
+                        sLangPersonalizationPredictionDictCache.get(localeStr);
                 final PersonalizationPredictionDictionary dict = ref == null ? null : ref.get();
                 if (dict != null) {
                     if (DEBUG) {
@@ -120,7 +125,7 @@
             final PersonalizationPredictionDictionary dict =
                     new PersonalizationPredictionDictionary(context, locale);
             sLangPersonalizationPredictionDictCache.put(
-                    locale, new SoftReference<PersonalizationPredictionDictionary>(dict));
+                    localeStr, new SoftReference<PersonalizationPredictionDictionary>(dict));
             return dict;
         }
     }
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java
index 16107e2..6d94716 100644
--- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java
+++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java
@@ -19,14 +19,16 @@
 import com.android.inputmethod.latin.Dictionary;
 import com.android.inputmethod.latin.ExpandableBinaryDictionary;
 
+import java.util.Locale;
+
 import android.content.Context;
 
 public class PersonalizationPredictionDictionary extends DecayingExpandableBinaryDictionaryBase {
     private static final String NAME = PersonalizationPredictionDictionary.class.getSimpleName();
 
-    /* package */ PersonalizationPredictionDictionary(final Context context, final String locale) {
+    /* package */ PersonalizationPredictionDictionary(final Context context, final Locale locale) {
         super(context, locale, Dictionary.TYPE_PERSONALIZATION_PREDICTION_IN_JAVA,
-                getDictionaryFileName(locale));
+                getDictionaryFileName(locale.toString()));
     }
 
     private static String getDictionaryFileName(final String locale) {
diff --git a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java
index 95a6fe1..60370d8 100644
--- a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java
@@ -19,6 +19,8 @@
 import com.android.inputmethod.latin.Dictionary;
 import com.android.inputmethod.latin.ExpandableBinaryDictionary;
 
+import java.util.Locale;
+
 import android.content.Context;
 
 /**
@@ -28,8 +30,9 @@
 public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBase {
     /* package for tests */ static final String NAME =
             UserHistoryDictionary.class.getSimpleName();
-    /* package */ UserHistoryDictionary(final Context context, final String locale) {
-        super(context, locale, Dictionary.TYPE_USER_HISTORY, getDictionaryFileName(locale));
+    /* package */ UserHistoryDictionary(final Context context, final Locale locale) {
+        super(context, locale, Dictionary.TYPE_USER_HISTORY,
+                getDictionaryFileName(locale.toString()));
     }
 
     private static String getDictionaryFileName(final String locale) {
diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java
index f5c1d10..714c3a9 100644
--- a/java/src/com/android/inputmethod/latin/settings/Settings.java
+++ b/java/src/com/android/inputmethod/latin/settings/Settings.java
@@ -27,12 +27,10 @@
 import com.android.inputmethod.latin.InputAttributes;
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
-import com.android.inputmethod.latin.utils.LocaleUtils;
 import com.android.inputmethod.latin.utils.ResourceUtils;
 import com.android.inputmethod.latin.utils.RunInLocale;
 import com.android.inputmethod.latin.utils.StringUtils;
 
-import java.util.HashMap;
 import java.util.Locale;
 import java.util.concurrent.locks.ReentrantLock;
 
@@ -227,16 +225,15 @@
                 res.getBoolean(R.bool.config_default_phrase_gesture_enabled));
     }
 
-    public static boolean readFromBuildConfigIfToShowKeyPreviewPopupSettingsOption(
-            final Resources res) {
-        return res.getBoolean(R.bool.config_enable_show_option_of_key_preview_popup);
+    public static boolean readFromBuildConfigIfToShowKeyPreviewPopupOption(final Resources res) {
+        return res.getBoolean(R.bool.config_enable_show_key_preview_popup_option);
     }
 
     public static boolean readKeyPreviewPopupEnabled(final SharedPreferences prefs,
             final Resources res) {
         final boolean defaultKeyPreviewPopup = res.getBoolean(
                 R.bool.config_default_key_preview_popup);
-        if (!readFromBuildConfigIfToShowKeyPreviewPopupSettingsOption(res)) {
+        if (!readFromBuildConfigIfToShowKeyPreviewPopupOption(res)) {
             return defaultKeyPreviewPopup;
         }
         return prefs.getBoolean(PREF_POPUP_ON, defaultKeyPreviewPopup);
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
index 2cee130..d7a3e95 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
@@ -169,7 +169,7 @@
             removePreference(Settings.PREF_VIBRATION_DURATION_SETTINGS, advancedSettings);
         }
 
-        if (!Settings.readFromBuildConfigIfToShowKeyPreviewPopupSettingsOption(res)) {
+        if (!Settings.readFromBuildConfigIfToShowKeyPreviewPopupOption(res)) {
             removePreference(Settings.PREF_POPUP_ON, generalSettings);
             removePreference(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY, advancedSettings);
         } else {
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 503b18b..c108b20 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -428,7 +428,7 @@
         final String localeStr = locale.toString();
         UserBinaryDictionary userDictionary = mUserDictionaries.get(localeStr);
         if (null == userDictionary) {
-            userDictionary = new SynchronouslyLoadedUserBinaryDictionary(this, localeStr, true);
+            userDictionary = new SynchronouslyLoadedUserBinaryDictionary(this, locale, true);
             mUserDictionaries.put(localeStr, userDictionary);
         }
         dictionaryCollection.addDictionary(userDictionary);
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.cpp
index a871e2b..04c80a7 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.cpp
@@ -25,7 +25,7 @@
     const BufferWithExtendableBuffer *const bigramListBuffer = getContentBuffer();
     const int bigramFlags = bigramListBuffer->readUintAndAdvancePosition(
             Ver4DictConstants::BIGRAM_FLAGS_FIELD_SIZE, bigramEntryPos);
-    const int hasNext = (bigramFlags & Ver4DictConstants::BIGRAM_HAS_NEXT_MASK) != 0;
+    const bool hasNext = (bigramFlags & Ver4DictConstants::BIGRAM_HAS_NEXT_MASK) != 0;
     int probability = NOT_A_PROBABILITY;
     int timestamp = Ver4DictConstants::NOT_A_TIME_STAMP;
     int level = 0;
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/terminal_position_lookup_table.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/terminal_position_lookup_table.cpp
index c38aeb4..d0853a5 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/terminal_position_lookup_table.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/terminal_position_lookup_table.cpp
@@ -53,13 +53,12 @@
 bool TerminalPositionLookupTable::flushToFile(const char *const dictDirPath,
         const int newHeaderRegionSize) const {
     const int headerRegionSizeDiff = newHeaderRegionSize - mHeaderRegionSize;
-    // If header region size has been changed, terminal PtNode positions have to be adjusted
-    // depending on the new header region size.
-    if (headerRegionSizeDiff != 0) {
-        TerminalPositionLookupTable lookupTableToWrite;
+    // If header region size has been changed or used buffer size is smaller than actual buffer
+    // size, regenerate lookup table and write the new table to file.
+    if (headerRegionSizeDiff != 0 || getEntryPos(mSize) < getBuffer()->getTailPosition()) {
+        TerminalPositionLookupTable lookupTableToWrite(newHeaderRegionSize);
         for (int i = 0; i < mSize; ++i) {
-            const int terminalPtNodePosition = getTerminalPtNodePosition(i)
-                    + headerRegionSizeDiff;
+            const int terminalPtNodePosition = getTerminalPtNodePosition(i);
             if (!lookupTableToWrite.setTerminalPtNodePosition(i, terminalPtNodePosition)) {
                 AKLOGE("Cannot set terminal position to lookupTableToWrite."
                         " terminalId: %d, position: %d", i, terminalPtNodePosition);
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/terminal_position_lookup_table.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/terminal_position_lookup_table.h
index ca33d71..80b358c 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/terminal_position_lookup_table.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/terminal_position_lookup_table.h
@@ -37,6 +37,9 @@
                       / Ver4DictConstants::TERMINAL_ADDRESS_TABLE_ADDRESS_SIZE),
               mHeaderRegionSize(headerRegionSize) {}
 
+    explicit TerminalPositionLookupTable(const int headerRegionSize)
+            : mSize(0), mHeaderRegionSize(headerRegionSize) {}
+
     TerminalPositionLookupTable() : mSize(0), mHeaderRegionSize(0) {}
 
     int getTerminalPtNodePosition(const int terminalId) const;
diff --git a/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java b/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java
index 9c93b8b..beac57b 100644
--- a/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java
+++ b/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java
@@ -26,6 +26,7 @@
 import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Locale;
 import java.util.Random;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
@@ -84,7 +85,7 @@
         final List<String> words = generateWords(numberOfWords, random);
         final UserHistoryDictionary dict =
                 PersonalizationHelper.getUserHistoryDictionary(getContext(),
-                        testFilenameSuffix /* locale */);
+                        new Locale(testFilenameSuffix));
         // Add random words to the user history dictionary.
         addToDict(dict, words);
         if (checkContents) {
@@ -108,7 +109,7 @@
     private void clearHistory(final String testFilenameSuffix) {
         final UserHistoryDictionary dict =
                 PersonalizationHelper.getUserHistoryDictionary(getContext(),
-                        testFilenameSuffix /* locale */);
+                        new Locale(testFilenameSuffix));
         dict.clearAndFlushDictionary();
         dict.close();
     }
@@ -121,7 +122,7 @@
         try {
             final UserHistoryDictionary dict =
                     PersonalizationHelper.getUserHistoryDictionary(getContext(),
-                            testFilenameSuffix);
+                            new Locale(testFilenameSuffix));
             dict.shutdownExecutorForTests();
             while (!dict.isTerminatedForTests()) {
                 Thread.sleep(WAIT_TERMINATING_IN_MILLISECONDS);
@@ -134,7 +135,7 @@
     public void testRandomWords() {
         Log.d(TAG, "This test can be used for profiling.");
         Log.d(TAG, "Usage: please set UserHistoryDictionary.PROFILE_SAVE_RESTORE to true.");
-        final String testFilenameSuffix = "testRandomWords" + System.currentTimeMillis();
+        final String testFilenameSuffix = "test_random_words" + System.currentTimeMillis();
         final String fileName = UserHistoryDictionary.NAME + "." + testFilenameSuffix
                 + ExpandableBinaryDictionary.DICT_FILE_EXTENSION;
 
@@ -169,7 +170,7 @@
 
             // Create filename suffixes for this test.
             for (int i = 0; i < numberOfLanguages; i++) {
-                testFilenameSuffixes[i] = "testSwitchingLanguages" + i;
+                testFilenameSuffixes[i] = "test_switching_languages" + i;
                 final String fileName = UserHistoryDictionary.NAME + "." +
                         testFilenameSuffixes[i] + ExpandableBinaryDictionary.DICT_FILE_EXTENSION;
                 dictFiles[i] = new File(getContext().getFilesDir(), fileName);
@@ -205,7 +206,7 @@
     }
 
     public void testAddManyWords() {
-        final String testFilenameSuffix = "testRandomWords" + System.currentTimeMillis();
+        final String testFilenameSuffix = "test_random_words" + System.currentTimeMillis();
         final int numberOfWords = 10000;
         final Random random = new Random(123456);
         clearHistory(testFilenameSuffix);