Merge "Add StatsUtils for checking state"
diff --git a/java/AndroidManifest.xml b/java/AndroidManifest.xml
index a7e64bf..6f4e602 100644
--- a/java/AndroidManifest.xml
+++ b/java/AndroidManifest.xml
@@ -57,6 +57,7 @@
         </service>
 
         <activity android:name=".setup.SetupActivity"
+                android:theme="@style/platformActivityTheme"
                 android:label="@string/english_ime_name"
                 android:icon="@drawable/ic_launcher_keyboard"
                 android:launchMode="singleTask"
@@ -68,6 +69,7 @@
         </activity>
 
         <activity android:name=".setup.SetupWizardActivity"
+                android:theme="@style/platformActivityTheme"
                 android:label="@string/english_ime_name"
                 android:clearTaskOnLaunch="true">
             <intent-filter>
@@ -84,6 +86,7 @@
         </receiver>
 
         <activity android:name=".settings.SettingsActivity"
+                android:theme="@style/platformActivityTheme"
                 android:label="@string/english_ime_settings"
                 android:uiOptions="splitActionBarWhenNarrow">
             <intent-filter>
@@ -92,6 +95,7 @@
         </activity>
 
         <activity android:name=".spellcheck.SpellCheckerSettingsActivity"
+                  android:theme="@style/platformActivityTheme"
                   android:label="@string/android_spell_checker_settings">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -99,6 +103,7 @@
         </activity>
 
         <activity android:name=".settings.DebugSettingsActivity"
+                android:theme="@style/platformActivityTheme"
                 android:label="@string/english_ime_debug_settings">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -145,8 +150,8 @@
         </receiver>
 
         <activity android:name="com.android.inputmethod.dictionarypack.DictionarySettingsActivity"
+                android:theme="@style/platformActivityTheme"
                 android:label="@string/dictionary_settings_title"
-                android:theme="@android:style/Theme.Holo"
                 android:uiOptions="splitActionBarWhenNarrow">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
@@ -154,8 +159,8 @@
         </activity>
 
         <activity android:name="com.android.inputmethod.dictionarypack.DownloadOverMeteredDialog"
-                android:label="@string/dictionary_install_over_metered_network_prompt"
-                android:theme="@android:style/Theme.Holo">
+                android:theme="@style/platformActivityTheme"
+                android:label="@string/dictionary_install_over_metered_network_prompt">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
             </intent-filter>
diff --git a/java/proguard.flags b/java/proguard.flags
index c08a968..f7b7f28 100644
--- a/java/proguard.flags
+++ b/java/proguard.flags
@@ -14,3 +14,10 @@
 -keepclassmembers class * {
     native <methods>;
 }
+
+# Keep classes that are used as a parameter type of methods that are also marked as keep
+# to preserve changing those methods' signature.
+-keep class com.android.inputmethod.latin.utils.LanguageModelParam
+-keep class com.android.inputmethod.latin.AssetFileAddress
+-keep class com.android.inputmethod.latin.makedict.ProbabilityInfo
+-keep class com.android.inputmethod.latin.Dictionary
diff --git a/java/res/layout/emoji_palettes_view.xml b/java/res/layout/emoji_palettes_view.xml
index 4fb744e..ef565a4 100644
--- a/java/res/layout/emoji_palettes_view.xml
+++ b/java/res/layout/emoji_palettes_view.xml
@@ -73,7 +73,7 @@
             android:background="@color/emoji_key_background_color"
             android:src="@drawable/sym_keyboard_delete_holo_dark" />
     </LinearLayout>
-    <com.android.inputmethod.keyboard.internal.CustomViewPager
+    <android.support.v4.view.ViewPager
         android:id="@+id/emoji_keyboard_pager"
         android:layout_width="match_parent"
         android:layout_height="wrap_content" />
diff --git a/java/res/values-af/strings.xml b/java/res/values-af/strings.xml
index 9c9f022..ce64ae80 100644
--- a/java/res/values-af/strings.xml
+++ b/java/res/values-af/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Oortjie"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"Spasie"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"Steminvoering"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"Emosiekone"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"Soek"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"Punt"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Engels (VK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Engels (VS) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spaans (VS) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Tradisioneel)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Tradisioneel)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Geen taal nie (alfabet)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabet (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabet (QWERTZ)"</string>
diff --git a/java/res/values-am/strings.xml b/java/res/values-am/strings.xml
index 3f9b03f..6155c1a 100644
--- a/java/res/values-am/strings.xml
+++ b/java/res/values-am/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"ትር"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"ባዶ ቦታ"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"የድምፅ ግቤ ት"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"ኢሞጂ"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"ተመለስ"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"ፍለጋ"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"ነጥብ"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"እንግሊዝኛ (ዩኬ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"እንግሊዝኛ (አሜሪካ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"ስፓኒሽ (አሜሪካ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ተለምዷዊ)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ተለምዷዊ)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"ምንም ቋንቋ (ፊደላት)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"ፊደላት (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"ፊደላት (QWERTZ)"</string>
diff --git a/java/res/values-ar/strings.xml b/java/res/values-ar/strings.xml
index 9d8cc63..9a28af6 100644
--- a/java/res/values-ar/strings.xml
+++ b/java/res/values-ar/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"الإنجليزية (المملكة المتحدة) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"الإنجليزية (الولايات المتحدة) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"الإسبانية (الولايات المتحدة) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (التقليدية)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (التقليدية)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"بدون لغة (أبجدية)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"‏الأبجدية (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"‏الأبجدية (QWERTZ)"</string>
diff --git a/java/res/values-az-rAZ/strings.xml b/java/res/values-az-rAZ/strings.xml
index 99765a9..4afb49a 100644
--- a/java/res/values-az-rAZ/strings.xml
+++ b/java/res/values-az-rAZ/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"Boşluq"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"Səs daxiletməsi"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"Emoji"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Qayıt"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"Axtar"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"Nöqtə"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"İngilis (Britaniya) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"İngilis (Amerika) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"İspan (Amerika) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Ənənəvi)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Ənənəvi)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Dil yoxdur (Əlifba)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Əlifba (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Əlifba (QWERTZ)"</string>
diff --git a/java/res/values-bg/strings.xml b/java/res/values-bg/strings.xml
index 03e8b8c..5460ba9 100644
--- a/java/res/values-bg/strings.xml
+++ b/java/res/values-bg/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"Интервал"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"Гласово въвеждане"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"Емотикони"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"Търсене"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"Точка"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"английски (Великобр.) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"английски (САЩ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"испански (САЩ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (традиционен)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (традиционна клавиатура)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Без език (латиница)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Латиница (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Латиница (QWERTZ)"</string>
diff --git a/java/res/values-ca/strings.xml b/java/res/values-ca/strings.xml
index 0845486..197df50 100644
--- a/java/res/values-ca/strings.xml
+++ b/java/res/values-ca/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Anglès (Regne Unit) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Anglès (EUA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Espanyol (EUA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicional)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicional)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Cap idioma (alfabet)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabet (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabet (QWERTZ)"</string>
diff --git a/java/res/values-cs/strings.xml b/java/res/values-cs/strings.xml
index b190857..7d19f76 100644
--- a/java/res/values-cs/strings.xml
+++ b/java/res/values-cs/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Tabulátor"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"Mezerník"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"Hlasový vstup"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"Emodži"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"vyhledávací tlačítko"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"Tečka"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"angličtina (VB) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"angličtina (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"španělština (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradiční)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradiční)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Žádný jazyk (latinka)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Latinka (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Latinka (QWERTZ)"</string>
diff --git a/java/res/values-da/strings.xml b/java/res/values-da/strings.xml
index e87fffd..a82ef06 100644
--- a/java/res/values-da/strings.xml
+++ b/java/res/values-da/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Tabulatortast"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"Mellemrum"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"Taleinput"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"Emoji"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Tilbage"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"Søg"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"Punktum"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Engelsk (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Engelsk (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spansk (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditionelt)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditionelt)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Intet sprog (Alfabet)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabet (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabet (QWERTZ)"</string>
diff --git a/java/res/values-de/strings.xml b/java/res/values-de/strings.xml
index 54dca98..f23dbe4 100644
--- a/java/res/values-de/strings.xml
+++ b/java/res/values-de/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Englisch (GB) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Englisch (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spanisch (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditionell)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditionell)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Keine Sprache (lat. Alphabet)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Lat. Alphabet (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Lat. Alphabet (QWERTZ)"</string>
diff --git a/java/res/values-el/strings.xml b/java/res/values-el/strings.xml
index 3aee4ad..b7cc285 100644
--- a/java/res/values-el/strings.xml
+++ b/java/res/values-el/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Αγγλικά (Ηνωμένο Βασίλειο) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Αγγλικά (ΗΠΑ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Ισπανικά (ΗΠΑ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Παραδοσιακά)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Παραδοσιακά)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Καμία γλώσσα (Αλφάβητο)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Αλφάβητο (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Αλφάβητο (QWERTZ)"</string>
diff --git a/java/res/values-en-rGB/strings.xml b/java/res/values-en-rGB/strings.xml
index 5d1ec87..3361f1b 100644
--- a/java/res/values-en-rGB/strings.xml
+++ b/java/res/values-en-rGB/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"English (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"English (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spanish (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Traditional)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Traditional)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"No language (Alphabet)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alphabet (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alphabet (QWERTZ)"</string>
diff --git a/java/res/values-en-rIN/strings.xml b/java/res/values-en-rIN/strings.xml
index 5d1ec87..3361f1b 100644
--- a/java/res/values-en-rIN/strings.xml
+++ b/java/res/values-en-rIN/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"English (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"English (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spanish (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Traditional)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Traditional)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"No language (Alphabet)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alphabet (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alphabet (QWERTZ)"</string>
diff --git a/java/res/values-es-rUS/strings.xml b/java/res/values-es-rUS/strings.xml
index 2e8dc16..37925c7 100644
--- a/java/res/values-es-rUS/strings.xml
+++ b/java/res/values-es-rUS/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Pestaña"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"Espacio"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"Entrada de voz"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"Emoji"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Volver"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"Buscar"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"Punto"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Inglés, Reino Unido (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Inglés, EE. UU. (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Español, EE. UU. (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicional)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicional)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Ningún idioma (alfabeto)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabeto (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabeto (QWERTZ)"</string>
diff --git a/java/res/values-es/strings.xml b/java/res/values-es/strings.xml
index 81a62cd..4522234 100644
--- a/java/res/values-es/strings.xml
+++ b/java/res/values-es/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Inglés (Reino Unido) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Inglés (EE.UU.) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Español (EE.UU.) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicional)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicional)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Ningún idioma (alfabeto)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabeto (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabeto (QWERTZ)"</string>
diff --git a/java/res/values-et-rEE/strings.xml b/java/res/values-et-rEE/strings.xml
index bd7c6e6..88ef006 100644
--- a/java/res/values-et-rEE/strings.xml
+++ b/java/res/values-et-rEE/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Inglise (Ühendk.) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Inglise (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Hispaania (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditsiooniline)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditsiooniline)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Keel puudub (tähestik)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Tähestik (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Tähestik (QWERTZ)"</string>
diff --git a/java/res/values-fa/strings.xml b/java/res/values-fa/strings.xml
index 14957eb..954d6fb 100644
--- a/java/res/values-fa/strings.xml
+++ b/java/res/values-fa/strings.xml
@@ -97,8 +97,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"فاصله"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"ورودی صدا"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"Emoji"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"جستجو"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"نقطه"</string>
@@ -140,7 +139,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"انگلیسی (بریتانیا) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"انگلیسی (آمریکا) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"اسپانیایی (آمریکا) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (سنتی)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (سنتی)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"بدون زبان (حروف الفبا)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"‏حروف الفبا (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"‏حروف الفبا (QWERTZ)"</string>
diff --git a/java/res/values-fi/strings.xml b/java/res/values-fi/strings.xml
index 514e07c..3148ed0 100644
--- a/java/res/values-fi/strings.xml
+++ b/java/res/values-fi/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Sarkain"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"Välilyönti"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"Äänisyöte"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"Emoji"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Takaisin"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"Haku"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"Piste"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"englanti (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"englanti (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"espanja (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (perinteinen)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (perinteinen)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Ei kieltä (aakkoset)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Aakkoset (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Aakkoset (QWERTZ)"</string>
diff --git a/java/res/values-fr-rCA/strings.xml b/java/res/values-fr-rCA/strings.xml
index b0b4c01..ae079d5 100644
--- a/java/res/values-fr-rCA/strings.xml
+++ b/java/res/values-fr-rCA/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Onglet"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"Espace"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"Saisie vocale"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"Emoji"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Renvoyer"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"Rechercher"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"Point"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"anglais (Royaume-Uni) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"anglais (États-Unis) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"espagnol (États-Unis) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditionnel)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditionnel)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Aucune langue (alphabet)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alphabet latin (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alphabet latin (QWERTZ)"</string>
diff --git a/java/res/values-fr/strings.xml b/java/res/values-fr/strings.xml
index 1afd4af..b2c418c 100644
--- a/java/res/values-fr/strings.xml
+++ b/java/res/values-fr/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Tabulation"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"Espace"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"Saisie vocale"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"Emoji"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Entrée"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"Rechercher"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"Point"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"anglais (Royaume-Uni) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"anglais (États-Unis) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"espagnol (États-Unis) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditionnel)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditionnel)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Aucune langue (latin)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alphabet latin (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alphabet latin (QWERTZ)"</string>
diff --git a/java/res/values-hi/strings.xml b/java/res/values-hi/strings.xml
index 28e7b9c..2a1e880 100644
--- a/java/res/values-hi/strings.xml
+++ b/java/res/values-hi/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"अंग्रेज़ी (यूके) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"अंग्रेज़ी (यूएस) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"स्‍पेनिश (यूएस) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (पारंपरिक)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (पारंपरिक)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"भाषा उपलब्ध नहीं है (लैटिन वर्णाक्षर)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"वर्णाक्षर (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"वर्णाक्षर (QWERTZ)"</string>
diff --git a/java/res/values-hr/strings.xml b/java/res/values-hr/strings.xml
index 93435b7..9c50ecb 100644
--- a/java/res/values-hr/strings.xml
+++ b/java/res/values-hr/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"engleska (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"engleska (SAD) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"španjolska (SAD) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicionalna)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicionalni)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Nema jezika (abeceda)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Abeceda (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Abeceda (QWERTZ)"</string>
diff --git a/java/res/values-hu/strings.xml b/java/res/values-hu/strings.xml
index b0ccba6..e434518 100644
--- a/java/res/values-hu/strings.xml
+++ b/java/res/values-hu/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"angol (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"angol (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"spanyol (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (hagyományos)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (hagyományos)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Nincs nyelv (ábécé)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Ábécé (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Ábécé (QWERTZ)"</string>
diff --git a/java/res/values-hy-rAM/strings.xml b/java/res/values-hy-rAM/strings.xml
index 975b7b3..de8f077 100644
--- a/java/res/values-hy-rAM/strings.xml
+++ b/java/res/values-hy-rAM/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"Բացակ"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"Ձայնային մուտքագրում"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"Զմայլիկներ"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Վերադարձ"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"Որոնել"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"Կետ"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Անգլերեն (ՄԹ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Անգլերեն (ԱՄՆ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Իսպաներեն (ԱՄՆ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ավանդական)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ավանդական)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Ոչ մի լեզվով (Այբուբեն)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Այբուբեն (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Այբուբեն (QWERTZ)"</string>
diff --git a/java/res/values-in/strings.xml b/java/res/values-in/strings.xml
index 48b4f9d..3b5cf91 100644
--- a/java/res/values-in/strings.xml
+++ b/java/res/values-in/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>) Inggris (Inggris)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>) Inggris (AS)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>) Spanyol (AS)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Tradisional)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Tradisional)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Tidak ada bahasa (Abjad)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Abjad (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Abjad (QWERTZ)"</string>
diff --git a/java/res/values-it/strings.xml b/java/res/values-it/strings.xml
index 6cdbef7..35c4537 100644
--- a/java/res/values-it/strings.xml
+++ b/java/res/values-it/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Inglese (Regno Unito) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Inglese (Stati Uniti) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spagnolo (Stati Uniti) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradizionale)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradizionale)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Nessuna lingua (alfabeto)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabeto (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabeto (QWERTZ)"</string>
diff --git a/java/res/values-iw/strings.xml b/java/res/values-iw/strings.xml
index d9178b2..08e7d3c 100644
--- a/java/res/values-iw/strings.xml
+++ b/java/res/values-iw/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"אנגלית (בריטניה)‏ (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"אנגלית (ארה\"ב) ‏(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"ספרדית (ארה\"ב) ‏(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (מסורתית)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (מסורתית)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"ללא שפה (אלף-בית)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"‏אלף-בית (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"‏אלף-בית (QWERTZ)"</string>
diff --git a/java/res/values-ja/strings.xml b/java/res/values-ja/strings.xml
index 76ba650..4567ec9 100644
--- a/java/res/values-ja/strings.xml
+++ b/java/res/values-ja/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"Space"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"音声入力"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"絵文字"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"検索"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"中点"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"英語(英国)(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"英語(米国)(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"スペイン語(米国)(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>(繁体)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>(繁体)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"言語なし(アルファベット)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"アルファベット(QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"アルファベット(QWERTZ)"</string>
diff --git a/java/res/values-ka-rGE/strings.xml b/java/res/values-ka-rGE/strings.xml
index dcb8061..72441c1 100644
--- a/java/res/values-ka-rGE/strings.xml
+++ b/java/res/values-ka-rGE/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"შორისი"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"ხმოვანი შეყვანა"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"Emoji"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"დაბრუნება"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"ძიება"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"წერტილი"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"ინგლისური (გაერთ.სამ.) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"ინგლისური (აშშ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"ესპანური (აშშ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ტრადიციული)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ტრადიციული)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"ენის გარეშე (ანბანი)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"ანბანი (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"ანბანი (QWERTZ)"</string>
diff --git a/java/res/values-km-rKH/strings.xml b/java/res/values-km-rKH/strings.xml
index 5e519f5..e3b325f 100644
--- a/java/res/values-km-rKH/strings.xml
+++ b/java/res/values-km-rKH/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"អង់គ្លេស (ចក្រភព​អង់គ្លេស) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"អង់គ្លេស (អាមេរិក) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"អេស្ប៉ាញ (អាមេរិក) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (អក្សរ​ពេញ)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (អក្សរ​ពេញ)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"គ្មាន​ភាសា (អក្សរ​ក្រម)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"តាម​លំដាប់​អក្សរក្រម (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"តាម​លំដាប់​អក្សរក្រម (QWERTZ)"</string>
@@ -167,7 +167,7 @@
     <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"ជ្រើស​ឯកសារ​វចនានុក្រម​ ដើម្បី​ដំឡើង"</string>
     <string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"ពិត​ជា​ដំឡើង​ឯកសារ​នេះ​សម្រាប់ <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
     <string name="error" msgid="8940763624668513648">"មាន​កំហុស"</string>
-    <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"បោះបង់​វចនានុក្រម​ទំនាក់ទំនង"</string>
+    <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"រាយ​វចនានុក្រម​ទំនាក់ទំនង"</string>
     <string name="prefs_dump_user_dict" msgid="294870685041741951">"បោះបង់​វចនានុក្រម​ផ្ទាល់ខ្លួន"</string>
     <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"បោះបង់​វចនានុក្រម​​ប្រវត្តិ​អ្នកប្រើ"</string>
     <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"បោះបង់​វចនានុក្រម​ផ្ទាល់ខ្លួន"</string>
diff --git a/java/res/values-ko/strings.xml b/java/res/values-ko/strings.xml
index 30907b6..e80f2ce 100644
--- a/java/res/values-ko/strings.xml
+++ b/java/res/values-ko/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"탭"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"스페이스"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"음성 입력"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"그림 이모티콘"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"리턴 키"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"검색"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"점"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"영어(영국)(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"영어(미국)(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"스페인어(미국)(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>(일반)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>(번체)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"언어 없음(알파벳)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"알파벳(QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"알파벳(QWERTZ)"</string>
diff --git a/java/res/values-lo-rLA/strings.xml b/java/res/values-lo-rLA/strings.xml
index 445d695..ac7f8ad 100644
--- a/java/res/values-lo-rLA/strings.xml
+++ b/java/res/values-lo-rLA/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"ອັງ​ກິດ (ສະ​ຫະ​ລາດ​ຊະ​ອາ​ນາ​ຈັກ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"ອັງ​ກິດ (ສະ​ຫະ​ລັດຯ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"ສະ​ແປນ​ນິດ (ສະ​ຫະ​ລັດຯ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ດັ້ງ​ເດີມ)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ດັ້ງ​ເດີມ)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"ບໍ່ມີພາສາ (ໂຕອັກສອນ)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"ໂຕອັກສອນ (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"ໂຕອັກສອນ (QWERTZ)"</string>
diff --git a/java/res/values-lt/strings.xml b/java/res/values-lt/strings.xml
index 49258fb..93404c9 100644
--- a/java/res/values-lt/strings.xml
+++ b/java/res/values-lt/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Anglų (JK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Anglų (JAV) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Ispanų (JAV) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicinė)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicinė)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Kalbos nėra (abėcėlė)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Abėcėlė (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Abėcėlė (QWERTZ)"</string>
diff --git a/java/res/values-lv/strings.xml b/java/res/values-lv/strings.xml
index e92d8e3..d9a9e71 100644
--- a/java/res/values-lv/strings.xml
+++ b/java/res/values-lv/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Angļu (Lielbritānija) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Angļu (ASV) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spāņu (ASV) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicionālā)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicionālā)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Nav valodas (alfabēts)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabēts (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabēts (QWERTZ)"</string>
diff --git a/java/res/values-mn-rMN/strings.xml b/java/res/values-mn-rMN/strings.xml
index 684c03f..362e644 100644
--- a/java/res/values-mn-rMN/strings.xml
+++ b/java/res/values-mn-rMN/strings.xml
@@ -93,7 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Таб"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"Хоосон зай"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"Дуугаар оруулах"</string>
-    <string name="spoken_description_emoji" msgid="6934027701390427635">"Emoji"</string>
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"Эможи"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Буцах"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"Хайх"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"Цэг"</string>
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Англи (ИБ) ( <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g> )"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Англи (АНУ) ( <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g> )"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Испани (АНУ-ын) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (уламжлалт)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (уламжлалт)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Хэл байхгүй (Цагаан толгой)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Цагаан толгой (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Цагаан толгой (QWERTZ)"</string>
diff --git a/java/res/values-ms-rMY/strings.xml b/java/res/values-ms-rMY/strings.xml
index 2cbba21..96735c0 100644
--- a/java/res/values-ms-rMY/strings.xml
+++ b/java/res/values-ms-rMY/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"Ruang"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"Input suara"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"Emoji"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Kembali"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"Cari"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"Titik"</string>
@@ -136,7 +135,8 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Bahasa Inggeris (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Bahasa Inggeris (AS) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Bahasa Sepanyol (AS) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Tradisional)"</string>
+    <!-- no translation found for subtype_generic_traditional (8584594350973800586) -->
+    <skip />
     <string name="subtype_no_language" msgid="7137390094240139495">"Tiada bahasa (Abjad)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Abjad (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Abjad (QWERTZ)"</string>
diff --git a/java/res/values-nb/strings.xml b/java/res/values-nb/strings.xml
index 57a274b..fe38a86 100644
--- a/java/res/values-nb/strings.xml
+++ b/java/res/values-nb/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Engelsk (Storbritannia) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Engelsk (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spansk (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradisjonell)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradisjonell)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Ingen språk (alfabet)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabet (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabet (QWERTZ)"</string>
diff --git a/java/res/values-ne-rNP/strings.xml b/java/res/values-ne-rNP/strings.xml
index 04a2d09..2bf1fb7 100644
--- a/java/res/values-ne-rNP/strings.xml
+++ b/java/res/values-ne-rNP/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"ट्याब"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"स्पेस"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"आवाज इनपुट"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"इमोजी"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"फर्कनुहोस्"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"खोज्नुहोस्"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"डट"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"अंग्रेजी (बेलायत) ( <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g> )"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"अंग्रेजी (अमेरिका) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"स्पेनेली (अमेरिका) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (परम्परागत)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (परम्परागत)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"कुनै भाषा होइन (वर्णमाला)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"वर्णमाला (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"वर्णमाला (QWERTZ)"</string>
diff --git a/java/res/values-nl/strings.xml b/java/res/values-nl/strings.xml
index a86c638..7d139b6 100644
--- a/java/res/values-nl/strings.xml
+++ b/java/res/values-nl/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Engels (VK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Engels (VS) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spaans (VS) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditioneel)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditioneel)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Geen taal (alfabet)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabet (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabet (QWERTZ)"</string>
diff --git a/java/res/values-pl/strings.xml b/java/res/values-pl/strings.xml
index 607dc26..8de3903 100644
--- a/java/res/values-pl/strings.xml
+++ b/java/res/values-pl/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Angielski (Wielka Brytania) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Angielski (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Hiszpański (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradycyjny)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradycyjny)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Bez języka (alfabet)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabet (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabet (QWERTZ)"</string>
diff --git a/java/res/values-pt-rPT/strings.xml b/java/res/values-pt-rPT/strings.xml
index 8b4131c..0406c8f 100644
--- a/java/res/values-pt-rPT/strings.xml
+++ b/java/res/values-pt-rPT/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"Espaço"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"Entrada de voz"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"Emoji"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"Pesquisar"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"Ponto"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Inglês (RU) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Inglês (EUA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Espanhol (EUA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicional)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicional)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Sem idioma (alfabeto)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabeto (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabeto (QWERTZ)"</string>
diff --git a/java/res/values-pt/strings.xml b/java/res/values-pt/strings.xml
index a74d24a..6ac3464 100644
--- a/java/res/values-pt/strings.xml
+++ b/java/res/values-pt/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"Espaço"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"Entrada de voz"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"Emojis"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Voltar"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"Pesquisar"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"Ponto"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Inglês (Reino Unido) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Inglês (EUA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Espanhol (EUA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicional)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicional)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Nenhum idioma (alfabeto)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabeto (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabeto (QWERTZ)"</string>
diff --git a/java/res/values-ro/strings.xml b/java/res/values-ro/strings.xml
index d40f442..2d5fd1f 100644
--- a/java/res/values-ro/strings.xml
+++ b/java/res/values-ro/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"Spaţiu"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"Intrare vocală"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"Emoji"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"Căutaţi"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"Punct"</string>
@@ -136,7 +135,8 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Engleză (Regatul Unit) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Engleză (S.U.A.) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spaniolă (S.U.A.) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradițională)"</string>
+    <!-- no translation found for subtype_generic_traditional (8584594350973800586) -->
+    <skip />
     <string name="subtype_no_language" msgid="7137390094240139495">"Nicio limbă (alfabet)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabet (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabet (QWERTZ)"</string>
diff --git a/java/res/values-ru/strings.xml b/java/res/values-ru/strings.xml
index 44cb0fa..f4541d1 100644
--- a/java/res/values-ru/strings.xml
+++ b/java/res/values-ru/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Клавиша табуляции"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"Пробел"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"Голосовой ввод"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"Смайлики."</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Клавиша \"Ввод\""</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"Поиск"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"Точка"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Английский (Великобритания, <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Английский (США, <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Испанский (США, <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (классическая)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (классическая)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Язык не определен (латиница)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Латиница (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Латиница (QWERTZ)"</string>
diff --git a/java/res/values-sk/strings.xml b/java/res/values-sk/strings.xml
index 68df7ae..4a355f7 100644
--- a/java/res/values-sk/strings.xml
+++ b/java/res/values-sk/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Karta"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"Medzerník"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"Hlasový vstup"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"Emoji"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"Hľadať"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"Bodka"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"angličtina (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"angličtina (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"španielčina (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradičná)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradičná)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Žiadny jazyk (latinka)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Latinka (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Latinka (QWERTZ)"</string>
diff --git a/java/res/values-sl/strings.xml b/java/res/values-sl/strings.xml
index 16a3531..8d9ee47 100644
--- a/java/res/values-sl/strings.xml
+++ b/java/res/values-sl/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"angleščina (VB) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"angleščina (ZDA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"španščina (ZDA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicionalna)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicionalna)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Brez jezika (latinice)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Latinica (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Latinica (QWERTZ)"</string>
diff --git a/java/res/values-sr/strings.xml b/java/res/values-sr/strings.xml
index e1ead18..c51dd93 100644
--- a/java/res/values-sr/strings.xml
+++ b/java/res/values-sr/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"Размак"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"Гласовни унос"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"Емоџи"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"Претражи"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"Тачка"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"енглески (УК) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"енглески (САД) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"шпански (САД) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (традиционални)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (традиционални)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Нема језика (абецеда)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Абецеда (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Абецеда (QWERTZ)"</string>
diff --git a/java/res/values-sv/strings.xml b/java/res/values-sv/strings.xml
index 225e795..7d7b7a4 100644
--- a/java/res/values-sv/strings.xml
+++ b/java/res/values-sv/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Engelska (Storbritannien) <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Engelska (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spanska (USA (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditionell)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditionell)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Inget språk (alfabet)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabet (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabet (QWERTZ)"</string>
diff --git a/java/res/values-sw/strings.xml b/java/res/values-sw/strings.xml
index f931e13..050e8aa 100644
--- a/java/res/values-sw/strings.xml
+++ b/java/res/values-sw/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Kiingereza (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Kiingereza (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Kihispania (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (cha Jadi)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (cha Jadi)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Hakuna lugha (Alfabeti)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabeti (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabeti (QWERTZ)"</string>
diff --git a/java/res/values-th/strings.xml b/java/res/values-th/strings.xml
index fe118bd..985dcd0 100644
--- a/java/res/values-th/strings.xml
+++ b/java/res/values-th/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"แท็บ"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"Space"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"การป้อนข้อมูลด้วยเสียง"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"อีโมจิ"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"ค้นหา"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"เครื่องหมายจุด"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"อังกฤษ (สหราชอาณาจักร) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"อังกฤษ (สหรัฐอเมริกา) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"สเปน (สหรัฐอเมริกา) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ดั้งเดิม)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ดั้งเดิม)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"ไม่มีภาษา (ตัวอักษรละติน)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"ตัวอักษร (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"ตัวอักษร (QWERTZ)"</string>
diff --git a/java/res/values-tl/strings.xml b/java/res/values-tl/strings.xml
index 02bc8ba..da7bcd2 100644
--- a/java/res/values-tl/strings.xml
+++ b/java/res/values-tl/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"Puwang"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"Input ng boses"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"Emoji"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Bumalik"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"Paghahanap"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"Tuldok"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Ingles (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Ingles (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spanish (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Tradisyonal)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Traditional)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Walang wika (Alpabeto)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alpabeto (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alpabeto (QWERTZ)"</string>
diff --git a/java/res/values-tr/strings.xml b/java/res/values-tr/strings.xml
index ca6d664..616c077 100644
--- a/java/res/values-tr/strings.xml
+++ b/java/res/values-tr/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Sekme"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"Boşluk"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"Ses girişi"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"Emoji"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"Ara"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"Nokta"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"İngilizce (İngiltere) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"İngilizce (ABD) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"İspanyolca (ABD) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Geleneksel)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Geleneksel)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Dil yok (Alfabe)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabe (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabe (QWERTZ)"</string>
diff --git a/java/res/values-uk/strings.xml b/java/res/values-uk/strings.xml
index d4c9ff3..c5276b4 100644
--- a/java/res/values-uk/strings.xml
+++ b/java/res/values-uk/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Англійська (Британія) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Англійська (США) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Іспанська (США) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (традиційне письмо)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (традиційна)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Стандартна (латиниця)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Латиниця (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Латиниця (QWERTZ)"</string>
diff --git a/java/res/values-v20/platform-theme.xml b/java/res/values-v20/platform-theme.xml
new file mode 100644
index 0000000..0606204
--- /dev/null
+++ b/java/res/values-v20/platform-theme.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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.
+*/
+-->
+
+<!-- TODO: This file is temporarily placed under values-v20. -->
+<!-- TODO: It might be moved under values-v21. -->
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+    <style name="platformActivityTheme" parent="@android:style/Theme.Quantum.Light" />
+    <style name="platformDialogTheme" parent="@android:style/Theme.Quantum.Light.Dialog" />
+</resources>
diff --git a/java/res/values-vi/strings.xml b/java/res/values-vi/strings.xml
index 9524442..36c9499 100644
--- a/java/res/values-vi/strings.xml
+++ b/java/res/values-vi/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"Dấu cách"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"Nhập dữ liệu bằng giọng nói"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"Biểu tượng cảm xúc"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Quay lại"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"Tìm kiếm"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"Dấu chấm"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Tiếng Anh (Anh) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Tiếng Anh (Mỹ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Tiếng Tây Ban Nha (Mỹ) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Truyền thống)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Truyền thống)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Không ngôn ngữ nào (Bảng chữ cái)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Bảng chữ cái (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Bảng chữ cái (QWERTZ)"</string>
@@ -190,7 +189,7 @@
     <string name="setup_step3_action" msgid="600879797256942259">"Định cấu hình các ngôn ngữ khác"</string>
     <string name="setup_finish_action" msgid="276559243409465389">"Đã xong"</string>
     <string name="show_setup_wizard_icon" msgid="5008028590593710830">"Hiển thị biểu tượng ứng dụng"</string>
-    <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"Hiển thị biểu tượng ứng dụng trong trình khởi chạy"</string>
+    <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"Hiển thị biểu tượng ứng dụng trong trình chạy"</string>
     <string name="app_name" msgid="6320102637491234792">"Nhà cung cấp từ điển"</string>
     <string name="dictionary_provider_name" msgid="3027315045397363079">"Nhà cung cấp từ điển"</string>
     <string name="dictionary_service_name" msgid="6237472350693511448">"Dịch vụ từ điển"</string>
diff --git a/java/res/values-zh-rCN/strings.xml b/java/res/values-zh-rCN/strings.xml
index 603e84b..09064e0 100644
--- a/java/res/values-zh-rCN/strings.xml
+++ b/java/res/values-zh-rCN/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"空格"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"语音输入"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"表情符"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"返回"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"搜索"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"点"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"英式英语(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"美式英语(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"美式西班牙语(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>(传统)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>(传统)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"无语言(字母)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"字母 (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"字母 (QWERTZ)"</string>
diff --git a/java/res/values-zh-rHK/strings.xml b/java/res/values-zh-rHK/strings.xml
index 0b64703..f1ec42c 100644
--- a/java/res/values-zh-rHK/strings.xml
+++ b/java/res/values-zh-rHK/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"英文 (英國) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"英文 (美國) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"西班牙文 (美國) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (傳統)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (傳統)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"無語言 (字母)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"字母 (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"字母 (QWERTZ)"</string>
diff --git a/java/res/values-zh-rTW/strings.xml b/java/res/values-zh-rTW/strings.xml
index 2309c5c..722476e 100644
--- a/java/res/values-zh-rTW/strings.xml
+++ b/java/res/values-zh-rTW/strings.xml
@@ -93,8 +93,7 @@
     <string name="spoken_description_tab" msgid="2667716002663482248">"Tab 鍵"</string>
     <string name="spoken_description_space" msgid="2582521050049860859">"空白鍵"</string>
     <string name="spoken_description_mic" msgid="615536748882611950">"語音輸入"</string>
-    <!-- no translation found for spoken_description_emoji (6934027701390427635) -->
-    <skip />
+    <string name="spoken_description_emoji" msgid="6934027701390427635">"表情符號"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"返回"</string>
     <string name="spoken_description_search" msgid="1247236163755920808">"搜尋"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"點"</string>
@@ -136,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"英文 (英國) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"英文 (美國) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"西班牙文 (美國) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (傳統)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (傳統)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"無語言 (字母)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"字母 (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"字母 (QWERTZ)"</string>
diff --git a/java/res/values-zu/strings.xml b/java/res/values-zu/strings.xml
index 4917e6c..e499bd9 100644
--- a/java/res/values-zu/strings.xml
+++ b/java/res/values-zu/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"I-English (UK) ( <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g> )"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"I-English (US) ( <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g> )"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Isi-Spanish (US) ( <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g> )"</string>
-    <string name="subtype_nepali_traditional" msgid="1994571919751163596">"Isi-<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Eyosiko)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"Isi-<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Eyosiko)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Alikho ulimi (Alfabhethi)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabhethi (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabhethi (QWERTZ)"</string>
diff --git a/java/res/values/platform-theme.xml b/java/res/values/platform-theme.xml
new file mode 100644
index 0000000..8e131a2
--- /dev/null
+++ b/java/res/values/platform-theme.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, 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 xmlns:android="http://schemas.android.com/apk/res/android">
+    <style name="platformActivityTheme" parent="@android:style/Theme.Holo" />
+    <style name="platformDialogTheme" parent="@android:style/Theme.Holo.Dialog" />
+</resources>
diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml
index ee1b54b..6db80b8 100644
--- a/java/res/xml/method.xml
+++ b/java/res/xml/method.xml
@@ -49,7 +49,7 @@
     fr_CH: French (Switzerland)/swiss
     gl_ES: Galician (Spain)/spanish
     hi: Hindi/hindi
-    hi: Hindi/hindi_compact
+    (hi: Hindi/hindi_compact) # This is a preliminary keyboard layout.
     hr: Croatian/qwertz
     hu: Hungarian/qwertz
     hy_AM: Armenian (Armenia) Phonetic/armenian_phonetic
diff --git a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
index 8badaf4..4a8fa51 100644
--- a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
+++ b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
@@ -45,10 +45,8 @@
     // 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 = 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 = 6;
+    // The current database version.
+    private static final int CURRENT_METADATA_DATABASE_VERSION = 7;
 
     private final static long NOT_A_DOWNLOAD_ID = -1;
 
@@ -169,7 +167,7 @@
     private MetadataDbHelper(final Context context, final String clientId) {
         super(context,
                 METADATA_DATABASE_NAME_STEM + (TextUtils.isEmpty(clientId) ? "" : "." + clientId),
-                null, METADATA_DATABASE_VERSION);
+                null, CURRENT_METADATA_DATABASE_VERSION);
         mContext = context;
         mClientId = clientId;
     }
@@ -219,22 +217,45 @@
 
     /**
      * Upgrade the database. Upgrade from version 3 is supported.
+     * Version 3 has a DB named METADATA_DATABASE_NAME_STEM containing a table METADATA_TABLE_NAME.
+     * Version 6 and above has a DB named METADATA_DATABASE_NAME_STEM containing a
+     * table CLIENT_TABLE_NAME, and for each client a table called METADATA_TABLE_STEM + "." + the
+     * name of the client and contains a table METADATA_TABLE_NAME.
+     * For schemas, see the above create statements. The schemas have never changed so far.
+     *
+     * This method is called by the framework. See {@link SQLiteOpenHelper#onUpgrade}
+     * @param db The database we are upgrading
+     * @param oldVersion The old database version (the one on the disk)
+     * @param newVersion The new database version as supplied to the constructor of SQLiteOpenHelper
      */
     @Override
     public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
         if (METADATA_DATABASE_INITIAL_VERSION == oldVersion
-                && METADATA_DATABASE_VERSION_WITH_CLIENTID == newVersion) {
+                && METADATA_DATABASE_VERSION_WITH_CLIENTID <= newVersion
+                && CURRENT_METADATA_DATABASE_VERSION >= newVersion) {
             // Upgrade from version METADATA_DATABASE_INITIAL_VERSION to version
             // METADATA_DATABASE_VERSION_WITH_CLIENT_ID
+            // Only the default database should contain the client table, so we test for mClientId.
             if (TextUtils.isEmpty(mClientId)) {
-                // Only the default database should contain the client table.
-                // Anyway in version 3 only the default table existed so the emptyness
+                // Anyway in version 3 only the default table existed so the emptiness
                 // test should always be true, but better check to be sure.
                 createClientTable(db);
             }
+        } else if (METADATA_DATABASE_VERSION_WITH_CLIENTID < newVersion
+                && CURRENT_METADATA_DATABASE_VERSION >= newVersion) {
+            // Here we drop the client table, so that all clients send us their information again.
+            // The client table contains the URL to hit to update the available dictionaries list,
+            // but the info about the dictionaries themselves is stored in the table called
+            // METADATA_TABLE_NAME and we want to keep it, so we only drop the client table.
+            db.execSQL("DROP TABLE IF EXISTS " + CLIENT_TABLE_NAME);
+            // Only the default database should contain the client table, so we test for mClientId.
+            if (TextUtils.isEmpty(mClientId)) {
+                createClientTable(db);
+            }
         } else {
-            // Version 3 was the earliest version, so we should never come here. If we do, we
-            // have no idea what this database is, so we'd better wipe it off.
+            // If we're not in the above case, either we are upgrading from an earlier versionCode
+            // and we should wipe the database, or we are handling a version we never heard about
+            // (can only be a bug) so it's safer to wipe the database.
             db.execSQL("DROP TABLE IF EXISTS " + METADATA_TABLE_NAME);
             db.execSQL("DROP TABLE IF EXISTS " + CLIENT_TABLE_NAME);
             onCreate(db);
diff --git a/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java b/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java
index 7e21667..4edc616 100644
--- a/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java
+++ b/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java
@@ -518,6 +518,14 @@
     }
 
     @Override
+    public boolean dispatchTouchEvent(final MotionEvent ev) {
+        // Add here to the stack trace to nail down the {@link IllegalArgumentException} exception
+        // in MotionEvent that sporadically happens.
+        // TODO: Remove this override method once the issue has been addressed.
+        return super.dispatchTouchEvent(ev);
+    }
+
+    @Override
     public void onTabChanged(final String tabId) {
         final int categoryId = mEmojiCategory.getCategoryId(tabId);
         setCurrentCategoryId(categoryId, false /* force */);
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index fd0be6f..2e4a090 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -219,22 +219,15 @@
         return null;
     }
 
-    /**
-     * Update keyboard shift state triggered by connected EditText status change.
-     */
-    public void updateShiftState() {
-        mState.onUpdateShiftState(mLatinIME.getCurrentAutoCapsState(),
-                mLatinIME.getCurrentRecapitalizeState());
-    }
-
     // TODO: Remove this method. Come up with a more comprehensive way to reset the keyboard layout
     // when a keyboard layout set doesn't get reloaded in LatinIME.onStartInputViewInternal().
     public void resetKeyboardStateToAlphabet() {
         mState.onResetKeyboardStateToAlphabet();
     }
 
-    public void onPressKey(final int code, final boolean isSinglePointer) {
-        mState.onPressKey(code, isSinglePointer, mLatinIME.getCurrentAutoCapsState());
+    public void onPressKey(final int code, final boolean isSinglePointer,
+            final int currentAutoCapsState) {
+        mState.onPressKey(code, isSinglePointer, currentAutoCapsState);
     }
 
     public void onReleaseKey(final int code, final boolean withSliding) {
@@ -338,8 +331,8 @@
     /**
      * Updates state machine to figure out when to automatically switch back to the previous mode.
      */
-    public void onCodeInput(final int code) {
-        mState.onCodeInput(code, mLatinIME.getCurrentAutoCapsState());
+    public void onCodeInput(final int code, final int currentAutoCapsState) {
+        mState.onCodeInput(code, currentAutoCapsState);
     }
 
     public boolean isShowingEmojiPalettes() {
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 0f9c39a..d8dd93a 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -30,7 +30,6 @@
 import android.graphics.drawable.Drawable;
 import android.preference.PreferenceManager;
 import android.util.AttributeSet;
-import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -428,21 +427,11 @@
     }
 
     private void locatePreviewPlacerView() {
-        if (mDrawingPreviewPlacerView.getParent() != null) {
-            return;
-        }
-        final int width = getWidth();
-        final int height = getHeight();
-        if (width == 0 || height == 0) {
-            // In transient state.
-            return;
-        }
         getLocationInWindow(mOriginCoords);
-        final DisplayMetrics dm = getResources().getDisplayMetrics();
-        if (CoordinateUtils.y(mOriginCoords) < dm.heightPixels / 4) {
-            // In transient state.
-            return;
-        }
+        mDrawingPreviewPlacerView.setKeyboardViewGeometry(mOriginCoords, getWidth(), getHeight());
+    }
+
+    private void installPreviewPlacerView() {
         final View rootView = getRootView();
         if (rootView == null) {
             Log.w(TAG, "Cannot find root view");
@@ -452,10 +441,9 @@
         // Note: It'd be very weird if we get null by android.R.id.content.
         if (windowContentView == null) {
             Log.w(TAG, "Cannot find android.R.id.content view to add DrawingPreviewPlacerView");
-        } else {
-            windowContentView.addView(mDrawingPreviewPlacerView);
-            mDrawingPreviewPlacerView.setKeyboardViewGeometry(mOriginCoords, width, height);
+            return;
         }
+        windowContentView.addView(mDrawingPreviewPlacerView);
     }
 
     /**
@@ -576,6 +564,7 @@
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
+        installPreviewPlacerView();
         // Notify the ResearchLogger (development only diagnostics) that the keyboard view has
         // been attached.  This is needed to properly show the splash screen, which requires that
         // the window token of the KeyboardView be non-null.
diff --git a/java/src/com/android/inputmethod/keyboard/internal/AbstractDrawingPreview.java b/java/src/com/android/inputmethod/keyboard/internal/AbstractDrawingPreview.java
index cd7dd6f..3a72aed 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/AbstractDrawingPreview.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/AbstractDrawingPreview.java
@@ -29,25 +29,37 @@
 public abstract class AbstractDrawingPreview {
     private final View mDrawingView;
     private boolean mPreviewEnabled;
+    private boolean mHasValidGeometry;
 
     protected AbstractDrawingPreview(final View drawingView) {
         mDrawingView = drawingView;
     }
 
-    public final View getDrawingView() {
+    protected final View getDrawingView() {
         return mDrawingView;
     }
 
+    protected final boolean isPreviewEnabled() {
+        return mPreviewEnabled && mHasValidGeometry;
+    }
+
     public final void setPreviewEnabled(final boolean enabled) {
         mPreviewEnabled = enabled;
     }
 
-    public boolean isPreviewEnabled() {
-        return mPreviewEnabled;
-    }
-
-    public void setKeyboardGeometry(final int[] originCoords, final int width, final int height) {
-        // Default implementation is empty.
+    /**
+     * Set {@link MainKeyboardView} geometry and position in the {@link SoftInputWindow}.
+     * The class that is overriding this method must call this super implementation.
+     *
+     * @param originCoords the top-left coordinates of the {@link MainKeyboardView} in
+     *        {@link SoftInputWindow} coordinate-system. This is unused but has a point in an
+     *        extended class, such as {@link GestureTrailsDrawingPreview}.
+     * @param width the width of {@link MainKeyboardView}.
+     * @param height the height of {@link MainKeyboardView}.
+     */
+    public void setKeyboardViewGeometry(final int[] originCoords, final int width,
+            final int height) {
+        mHasValidGeometry = (width > 0 && height > 0);
     }
 
     public abstract void onDeallocateMemory();
diff --git a/java/src/com/android/inputmethod/keyboard/internal/CustomViewPager.java b/java/src/com/android/inputmethod/keyboard/internal/CustomViewPager.java
deleted file mode 100644
index f5cc45c..0000000
--- a/java/src/com/android/inputmethod/keyboard/internal/CustomViewPager.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.keyboard.internal;
-
-import android.content.Context;
-import android.support.v4.view.ViewPager;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.MotionEvent;
-
-/**
- * Custom view pager to prevent {@link ViewPager} from crashing while handling multi-touch
- * event.
- */
-public class CustomViewPager extends ViewPager {
-    private static final String TAG = CustomViewPager.class.getSimpleName();
-
-    public CustomViewPager(final Context context, final AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(final MotionEvent event) {
-        // This only happens when you multi-touch, take the first finger off and move.
-        // Unfortunately this causes {@link ViewPager} to crash, so we will ignore such events.
-        if (event.getAction() == MotionEvent.ACTION_MOVE && event.getPointerId(0) != 0) {
-            Log.w(TAG, "Ignored multi-touch move event to prevent ViewPager from crashing");
-            return false;
-        }
-
-        return super.onInterceptTouchEvent(event);
-    }
-}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/DrawingPreviewPlacerView.java b/java/src/com/android/inputmethod/keyboard/internal/DrawingPreviewPlacerView.java
index 606addc..fdc2458 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/DrawingPreviewPlacerView.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/DrawingPreviewPlacerView.java
@@ -55,7 +55,7 @@
         CoordinateUtils.copy(mKeyboardViewOrigin, originCoords);
         final int count = mPreviews.size();
         for (int i = 0; i < count; i++) {
-            mPreviews.get(i).setKeyboardGeometry(originCoords, width, height);
+            mPreviews.get(i).setKeyboardViewGeometry(originCoords, width, height);
         }
     }
 
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsDrawingPreview.java b/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsDrawingPreview.java
index eef4b36..d8b00c7 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsDrawingPreview.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsDrawingPreview.java
@@ -95,7 +95,9 @@
     }
 
     @Override
-    public void setKeyboardGeometry(final int[] originCoords, final int width, final int height) {
+    public void setKeyboardViewGeometry(final int[] originCoords, final int width,
+            final int height) {
+        super.setKeyboardViewGeometry(originCoords, width, height);
         mOffscreenOffsetY = (int)(height
                 * GestureStrokeRecognitionPoints.EXTRA_GESTURE_TRAIL_AREA_ABOVE_KEYBOARD_RATIO);
         mOffscreenWidth = width;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
index 56acdde..0047aa4 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
@@ -41,8 +41,7 @@
     private HashMap<String, String> mResourceNameToTextsMap = CollectionUtils.newHashMap();
 
     public void setLocale(final Locale locale, final Context context) {
-        final String language = locale.getLanguage();
-        mTextsTable = KeyboardTextsTable.getTextsTable(language);
+        mTextsTable = KeyboardTextsTable.getTextsTable(locale);
         final Resources res = context.getResources();
         final int referenceId = context.getApplicationInfo().labelRes;
         final String resourcePackageName = res.getResourcePackageName(referenceId);
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
index fc67f08..1bd9833 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
@@ -19,6 +19,7 @@
 import com.android.inputmethod.latin.utils.CollectionUtils;
 
 import java.util.HashMap;
+import java.util.Locale;
 
 /**
  * !!!!! DO NOT EDIT THIS FILE !!!!!
@@ -44,19 +45,19 @@
 public final class KeyboardTextsTable {
     // Name to index map.
     private static final HashMap<String, Integer> sNameToIndexesMap = CollectionUtils.newHashMap();
-    // Language to texts table map.
-    private static final HashMap<String, String[]> sLanguageToTextsTableMap =
+    // Locale to texts table map.
+    private static final HashMap<String, String[]> sLocaleToTextsTableMap =
             CollectionUtils.newHashMap();
     // TODO: Remove this variable after debugging.
-    // Texts table to language maps.
-    private static final HashMap<String[], String> sTextsTableToLanguageMap =
+    // Texts table to locale maps.
+    private static final HashMap<String[], String> sTextsTableToLocaleMap =
             CollectionUtils.newHashMap();
 
     public static String getText(final String name, final String[] textsTable) {
         final Integer indexObj = sNameToIndexesMap.get(name);
         if (indexObj == null) {
-            throw new RuntimeException("Unknown text name=" + name + " language="
-                    + sTextsTableToLanguageMap.get(textsTable));
+            throw new RuntimeException("Unknown text name=" + name + " locale="
+                    + sTextsTableToLocaleMap.get(textsTable));
         }
         final int index = indexObj;
         final String text = (index < textsTable.length) ? textsTable[index] : null;
@@ -64,17 +65,24 @@
             return text;
         }
         // Sanity check.
-        if (index >= 0 && index < LANGUAGE_DEFAULT.length) {
-            return LANGUAGE_DEFAULT[index];
+        if (index >= 0 && index < TEXTS_DEFAULT.length) {
+            return TEXTS_DEFAULT[index];
         }
         // Throw exception for debugging purpose.
         throw new RuntimeException("Illegal index=" + index + " for name=" + name
-                + " language=" + sTextsTableToLanguageMap.get(textsTable));
+                + " locale=" + sTextsTableToLocaleMap.get(textsTable));
     }
 
-    public static String[] getTextsTable(final String language) {
-        final String[] textsTable = sLanguageToTextsTableMap.get(language);
-        return textsTable != null ? textsTable : LANGUAGE_DEFAULT;
+    public static String[] getTextsTable(final Locale locale) {
+        final String localeKey = locale.toString();
+        if (sLocaleToTextsTableMap.containsKey(localeKey)) {
+            return sLocaleToTextsTableMap.get(localeKey);
+        }
+        final String languageKey = locale.getLanguage();
+        if (sLocaleToTextsTableMap.containsKey(languageKey)) {
+            return sLocaleToTextsTableMap.get(languageKey);
+        }
+        return TEXTS_DEFAULT;
     }
 
     private static final String[] NAMES = {
@@ -188,23 +196,23 @@
         /* 106: 2 */ "morekeys_symbols_percent",
         /* 107: 1 */ "morekeys_v",
         /* 108: 1 */ "morekeys_j",
-        /* 109: 1 */ "morekeys_east_slavic_row2_11",
-        /* 110: 1 */ "morekeys_cyrillic_ka",
-        /* 111: 1 */ "morekeys_cyrillic_a",
-        /* 112: 1 */ "morekeys_currency_dollar",
-        /* 113: 1 */ "morekeys_tablet_punctuation",
-        /* 114: 1 */ "morekeys_plus",
-        /* 115: 1 */ "morekeys_less_than",
-        /* 116: 1 */ "morekeys_greater_than",
-        /* 117: 1 */ "keyspec_period",
-        /* 118: 1 */ "keyspec_tablet_period",
-        /* 119: 1 */ "morekeys_exclamation",
-        /* 120: 1 */ "morekeys_q",
-        /* 121: 1 */ "morekeys_x",
-        /* 122: 1 */ "keyspec_q",
-        /* 123: 1 */ "keyspec_w",
-        /* 124: 1 */ "keyspec_y",
-        /* 125: 1 */ "keyspec_x",
+        /* 109: 1 */ "morekeys_q",
+        /* 110: 1 */ "morekeys_x",
+        /* 111: 1 */ "keyspec_q",
+        /* 112: 1 */ "keyspec_w",
+        /* 113: 1 */ "keyspec_y",
+        /* 114: 1 */ "keyspec_x",
+        /* 115: 1 */ "morekeys_east_slavic_row2_11",
+        /* 116: 1 */ "morekeys_cyrillic_ka",
+        /* 117: 1 */ "morekeys_cyrillic_a",
+        /* 118: 1 */ "morekeys_currency_dollar",
+        /* 119: 1 */ "morekeys_tablet_punctuation",
+        /* 120: 1 */ "morekeys_plus",
+        /* 121: 1 */ "morekeys_less_than",
+        /* 122: 1 */ "morekeys_greater_than",
+        /* 123: 1 */ "keyspec_period",
+        /* 124: 1 */ "keyspec_tablet_period",
+        /* 125: 1 */ "morekeys_exclamation",
         /* 126: 0 */ "morekeys_currency",
         /* 127: 0 */ "morekeys_symbols_1",
         /* 128: 0 */ "morekeys_symbols_2",
@@ -252,7 +260,7 @@
     private static final String EMPTY = "";
 
     /* Default texts */
-    private static final String[] LANGUAGE_DEFAULT = {
+    private static final String[] TEXTS_DEFAULT = {
         /* morekeys_a ~ */
         EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
         /* ~ morekeys_c */
@@ -345,7 +353,14 @@
         // U+2030: "‰" PER MILLE SIGN
         /* morekeys_symbols_percent */ "\u2030",
         /* morekeys_v ~ */
-        EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
+        EMPTY, EMPTY, EMPTY, EMPTY,
+        /* ~ morekeys_x */
+        /* keyspec_q */ "q",
+        /* keyspec_w */ "w",
+        /* keyspec_y */ "y",
+        /* keyspec_x */ "x",
+        /* morekeys_east_slavic_row2_11 ~ */
+        EMPTY, EMPTY, EMPTY,
         /* ~ morekeys_cyrillic_a */
         // U+00A2: "¢" CENT SIGN
         // U+00A3: "£" POUND SIGN
@@ -363,12 +378,6 @@
         /* keyspec_tablet_period */ ".",
         // U+00A1: "¡" INVERTED EXCLAMATION MARK
         /* morekeys_exclamation */ "\u00A1",
-        /* morekeys_q */ EMPTY,
-        /* morekeys_x */ EMPTY,
-        /* keyspec_q */ "q",
-        /* keyspec_w */ "w",
-        /* keyspec_y */ "y",
-        /* keyspec_x */ "x",
         /* morekeys_currency */ "$,\u00A2,\u20AC,\u00A3,\u00A5,\u20B1",
         // U+00B9: "¹" SUPERSCRIPT ONE
         // U+00BD: "½" VULGAR FRACTION ONE HALF
@@ -456,8 +465,8 @@
         /* keyspec_emoji_key */ "!icon/emoji_key|!code/key_emoji",
     };
 
-    /* Language af: Afrikaans */
-    private static final String[] LANGUAGE_af = {
+    /* Locale af: Afrikaans */
+    private static final String[] TEXTS_af = {
         // This is the same as Dutch except more keys of y and demoting vowels with diaeresis.
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
         // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
@@ -512,8 +521,8 @@
         /* morekeys_y */ "\u00FD,\u0133",
     };
 
-    /* Language ar: Arabic */
-    private static final String[] LANGUAGE_ar = {
+    /* Locale ar: Arabic */
+    private static final String[] TEXTS_ar = {
         /* morekeys_a ~ */
         null, null, null, null, null, null, null, null, null,
         /* ~ single_quotes */
@@ -639,8 +648,8 @@
         /* morekeys_symbols_percent */ "\\%,\u2030",
     };
 
-    /* Language az_AZ: Azerbaijani (Azerbaijan) */
-    private static final String[] LANGUAGE_az_AZ = {
+    /* Locale az_AZ: Azerbaijani (Azerbaijan) */
+    private static final String[] TEXTS_az_AZ = {
         // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
         /* morekeys_a */ "\u00E2",
         // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
@@ -687,8 +696,8 @@
         /* morekeys_g */ "\u011F",
     };
 
-    /* Language be_BY: Belarusian (Belarus) */
-    private static final String[] LANGUAGE_be_BY = {
+    /* Locale be_BY: Belarusian (Belarus) */
+    private static final String[] TEXTS_be_BY = {
         /* morekeys_a ~ */
         null, null, null, null, null, null,
         /* ~ morekeys_c */
@@ -720,8 +729,8 @@
         /* morekeys_cyrillic_soft_sign */ "\u044A",
     };
 
-    /* Language bg: Bulgarian */
-    private static final String[] LANGUAGE_bg = {
+    /* Locale bg: Bulgarian */
+    private static final String[] TEXTS_bg = {
         /* morekeys_a ~ */
         null, null, null, null, null, null,
         /* ~ morekeys_c */
@@ -736,8 +745,8 @@
         /* keylabel_to_alpha */ "\u0410\u0411\u0412",
     };
 
-    /* Language ca: Catalan */
-    private static final String[] LANGUAGE_ca = {
+    /* Locale ca: Catalan */
+    private static final String[] TEXTS_ca = {
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
         // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
@@ -810,13 +819,13 @@
         /* keyspec_spanish_row2_10 */ "\u00E7",
         /* morekeys_bullet ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null,
         /* ~ morekeys_currency_dollar */
         /* morekeys_tablet_punctuation */ "!autoColumnOrder!8,\\,,',\u00B7,#,),(,/,;,@,:,-,\",+,\\%,&",
     };
 
-    /* Language cs: Czech */
-    private static final String[] LANGUAGE_cs = {
+    /* Locale cs: Czech */
+    private static final String[] TEXTS_cs = {
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
         // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
@@ -893,8 +902,8 @@
         /* morekeys_r */ "\u0159",
     };
 
-    /* Language da: Danish */
-    private static final String[] LANGUAGE_da = {
+    /* Locale da: Danish */
+    private static final String[] TEXTS_da = {
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
         // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
@@ -962,8 +971,8 @@
         /* morekeys_nordic_row2_11 */ "\u00F6",
     };
 
-    /* Language de: German */
-    private static final String[] LANGUAGE_de = {
+    /* Locale de: German */
+    private static final String[] TEXTS_de = {
         // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
         // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
@@ -1032,8 +1041,8 @@
         /* morekeys_swiss_row2_11 */ "\u00E0",
     };
 
-    /* Language el: Greek */
-    private static final String[] LANGUAGE_el = {
+    /* Locale el: Greek */
+    private static final String[] TEXTS_el = {
         /* morekeys_a ~ */
         null, null, null, null, null, null, null, null, null,
         /* ~ single_quotes */
@@ -1044,8 +1053,8 @@
         /* keylabel_to_alpha */ "\u0391\u0392\u0393",
     };
 
-    /* Language en: English */
-    private static final String[] LANGUAGE_en = {
+    /* Locale en: English */
+    private static final String[] TEXTS_en = {
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
         // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
@@ -1093,8 +1102,8 @@
         /* morekeys_s */ "\u00DF",
     };
 
-    /* Language eo: Esperanto */
-    private static final String[] LANGUAGE_eo = {
+    /* Locale eo: Esperanto */
+    private static final String[] TEXTS_eo = {
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
         // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
@@ -1229,9 +1238,7 @@
         /* ~ morekeys_symbols_percent */
         // U+0175: "ŵ" LATIN SMALL LETTER W WITH CIRCUMFLEX
         /* morekeys_v */ "w,\u0175",
-        /* morekeys_j ~ */
-        null, null, null, null, null, null, null, null, null, null, null, null,
-        /* ~ morekeys_exclamation */
+        /* morekeys_j */ null,
         /* morekeys_q */ "q",
         /* morekeys_x */ "x",
         // U+015D: "ŝ" LATIN SMALL LETTER S WITH CIRCUMFLEX
@@ -1244,8 +1251,8 @@
         /* keyspec_x */ "\u0109",
     };
 
-    /* Language es: Spanish */
-    private static final String[] LANGUAGE_es = {
+    /* Locale es: Spanish */
+    private static final String[] TEXTS_es = {
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
         // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
@@ -1307,8 +1314,8 @@
         /* morekeys_punctuation */ "!autoColumnOrder!9,\\,,?,!,#,),(,/,;,\u00A1,',@,:,-,\",+,\\%,&,\u00BF",
     };
 
-    /* Language et_EE: Estonian (Estonia) */
-    private static final String[] LANGUAGE_et_EE = {
+    /* Locale et_EE: Estonian (Estonia) */
+    private static final String[] TEXTS_et_EE = {
         // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
         // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
@@ -1410,8 +1417,8 @@
         /* morekeys_nordic_row2_10 */ "\u00F5",
     };
 
-    /* Language eu_ES: Basque (Spain) */
-    private static final String[] LANGUAGE_eu_ES = {
+    /* Locale eu_ES: Basque (Spain) */
+    private static final String[] TEXTS_eu_ES = {
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
         // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
@@ -1464,8 +1471,8 @@
         /* morekeys_n */ "\u00F1,\u0144",
     };
 
-    /* Language fa: Persian */
-    private static final String[] LANGUAGE_fa = {
+    /* Locale fa: Persian */
+    private static final String[] TEXTS_fa = {
         /* morekeys_a ~ */
         null, null, null, null, null, null, null, null, null,
         /* ~ single_quotes */
@@ -1590,7 +1597,7 @@
         // U+2030: "‰" PER MILLE SIGN
         /* morekeys_symbols_percent */ "\\%,\u2030",
         /* morekeys_v ~ */
-        null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         /* ~ morekeys_plus */
         // U+2264: "≤" LESS-THAN OR EQUAL TO
         // U+2265: "≥" GREATER-THAN EQUAL TO
@@ -1602,8 +1609,8 @@
         /* morekeys_greater_than */ "!fixedColumnOrder!3,!text/keyspec_right_single_angle_quote,!text/keyspec_greater_than_equal,!text/keyspec_greater_than",
     };
 
-    /* Language fi: Finnish */
-    private static final String[] LANGUAGE_fi = {
+    /* Locale fi: Finnish */
+    private static final String[] TEXTS_fi = {
         // U+00E6: "æ" LATIN SMALL LETTER AE
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
@@ -1652,8 +1659,8 @@
         /* morekeys_nordic_row2_11 */ "\u00E6",
     };
 
-    /* Language fr: French */
-    private static final String[] LANGUAGE_fr = {
+    /* Locale fr: French */
+    private static final String[] TEXTS_fr = {
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
         // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
         // U+00E6: "æ" LATIN SMALL LETTER AE
@@ -1725,8 +1732,8 @@
         /* morekeys_swiss_row2_11 */ "\u00E4",
     };
 
-    /* Language gl_ES: Gallegan (Spain) */
-    private static final String[] LANGUAGE_gl_ES = {
+    /* Locale gl_ES: Gallegan (Spain) */
+    private static final String[] TEXTS_gl_ES = {
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
         // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
@@ -1779,8 +1786,8 @@
         /* morekeys_n */ "\u00F1,\u0144",
     };
 
-    /* Language hi: Hindi */
-    private static final String[] LANGUAGE_hi = {
+    /* Locale hi: Hindi */
+    private static final String[] TEXTS_hi = {
         /* morekeys_a ~ */
         null, null, null, null, null, null, null, null, null,
         /* ~ single_quotes */
@@ -1831,8 +1838,8 @@
         /* additional_morekeys_symbols_0 */ "0",
     };
 
-    /* Language hr: Croatian */
-    private static final String[] LANGUAGE_hr = {
+    /* Locale hr: Croatian */
+    private static final String[] TEXTS_hr = {
         /* morekeys_a ~ */
         null, null, null, null, null,
         /* ~ morekeys_i */
@@ -1864,8 +1871,8 @@
         /* double_angle_quotes */ "!text/double_raqm_laqm",
     };
 
-    /* Language hu: Hungarian */
-    private static final String[] LANGUAGE_hu = {
+    /* Locale hu: Hungarian */
+    private static final String[] TEXTS_hu = {
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
         // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
@@ -1918,8 +1925,8 @@
         /* double_angle_quotes */ "!text/double_raqm_laqm",
     };
 
-    /* Language hy_AM: Armenian (Armenia) */
-    private static final String[] LANGUAGE_hy_AM = {
+    /* Locale hy_AM: Armenian (Armenia) */
+    private static final String[] TEXTS_hy_AM = {
         /* morekeys_a ~ */
         null, null, null, null, null, null, null, null, null,
         /* ~ single_quotes */
@@ -1960,7 +1967,8 @@
         /* morekeys_h ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null,
         /* ~ morekeys_greater_than */
         // U+0589: "։" ARMENIAN FULL STOP
         /* keyspec_period */ "\u0589",
@@ -1970,8 +1978,8 @@
         /* morekeys_exclamation */ "\u055C,\u00A1",
     };
 
-    /* Language is: Icelandic */
-    private static final String[] LANGUAGE_is = {
+    /* Locale is: Icelandic */
+    private static final String[] TEXTS_is = {
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
         // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
         // U+00E6: "æ" LATIN SMALL LETTER AE
@@ -2027,8 +2035,8 @@
         /* morekeys_t */ "\u00FE",
     };
 
-    /* Language it: Italian */
-    private static final String[] LANGUAGE_it = {
+    /* Locale it: Italian */
+    private static final String[] TEXTS_it = {
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
         // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
@@ -2072,8 +2080,8 @@
         /* morekeys_i */ "\u00EC,\u00ED,\u00EE,\u00EF,\u012F,\u012B",
     };
 
-    /* Language iw: Hebrew */
-    private static final String[] LANGUAGE_iw = {
+    /* Locale iw: Hebrew */
+    private static final String[] TEXTS_iw = {
         /* morekeys_a ~ */
         null, null, null, null, null, null,
         /* ~ morekeys_c */
@@ -2122,15 +2130,16 @@
         /* keyspec_tablet_comma ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null,
         /* ~ morekeys_tablet_punctuation */
         // U+00B1: "±" PLUS-MINUS SIGN
         // U+FB29: "﬩" HEBREW LETTER ALTERNATIVE PLUS SIGN
         /* morekeys_plus */ "\u00B1,\uFB29",
     };
 
-    /* Language ka_GE: Georgian (Georgia) */
-    private static final String[] LANGUAGE_ka_GE = {
+    /* Locale ka_GE: Georgian (Georgia) */
+    private static final String[] TEXTS_ka_GE = {
         /* morekeys_a ~ */
         null, null, null, null, null, null,
         /* ~ morekeys_c */
@@ -2144,8 +2153,8 @@
         /* keylabel_to_alpha */ "\u10D0\u10D1\u10D2",
     };
 
-    /* Language kk: Kazakh */
-    private static final String[] LANGUAGE_kk = {
+    /* Locale kk: Kazakh */
+    private static final String[] TEXTS_kk = {
         /* morekeys_a ~ */
         null, null, null, null, null, null, null, null, null,
         /* ~ single_quotes */
@@ -2190,8 +2199,9 @@
         /* morekeys_cyrillic_o */ "\u04E9",
         /* morekeys_cyrillic_i ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        /* ~ morekeys_j */
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null,
+        /* ~ keyspec_x */
         // U+04BB: "һ" CYRILLIC SMALL LETTER SHHA
         /* morekeys_east_slavic_row2_11 */ "\u04BB",
         // U+049B: "қ" CYRILLIC SMALL LETTER KA WITH DESCENDER
@@ -2200,8 +2210,8 @@
         /* morekeys_cyrillic_a */ "\u04D9",
     };
 
-    /* Language km_KH: Khmer (Cambodia) */
-    private static final String[] LANGUAGE_km_KH = {
+    /* Locale km_KH: Khmer (Cambodia) */
+    private static final String[] TEXTS_km_KH = {
         /* morekeys_a ~ */
         null, null, null, null, null, null, null, null, null,
         /* ~ single_quotes */
@@ -2217,14 +2227,15 @@
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null,
         /* ~ morekeys_cyrillic_a */
         // U+17DB: "៛" KHMER CURRENCY SYMBOL RIEL
         /* morekeys_currency_dollar */ "\u17DB,\u00A2,\u00A3,\u20AC,\u00A5,\u20B1",
     };
 
-    /* Language ky: Kirghiz */
-    private static final String[] LANGUAGE_ky = {
+    /* Locale ky: Kirghiz */
+    private static final String[] TEXTS_ky = {
         /* morekeys_a ~ */
         null, null, null, null, null, null, null, null, null,
         /* ~ single_quotes */
@@ -2265,8 +2276,8 @@
         /* morekeys_cyrillic_o */ "\u04E9",
     };
 
-    /* Language lo_LA: Lao (Laos) */
-    private static final String[] LANGUAGE_lo_LA = {
+    /* Locale lo_LA: Lao (Laos) */
+    private static final String[] TEXTS_lo_LA = {
         /* morekeys_a ~ */
         null, null, null, null, null, null, null, null, null,
         /* ~ single_quotes */
@@ -2282,8 +2293,8 @@
         /* keyspec_currency */ "\u20AD",
     };
 
-    /* Language lt: Lithuanian */
-    private static final String[] LANGUAGE_lt = {
+    /* Locale lt: Lithuanian */
+    private static final String[] TEXTS_lt = {
         // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK
         // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
         // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON
@@ -2377,8 +2388,8 @@
         /* morekeys_k */ "\u0137",
     };
 
-    /* Language lv: Latvian */
-    private static final String[] LANGUAGE_lv = {
+    /* Locale lv: Latvian */
+    private static final String[] TEXTS_lv = {
         // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
@@ -2471,8 +2482,8 @@
         /* morekeys_k */ "\u0137",
     };
 
-    /* Language mk: Macedonian */
-    private static final String[] LANGUAGE_mk = {
+    /* Locale mk: Macedonian */
+    private static final String[] TEXTS_mk = {
         /* morekeys_a ~ */
         null, null, null, null, null, null,
         /* ~ morekeys_c */
@@ -2507,8 +2518,8 @@
         /* keyspec_south_slavic_row3_8 */ "\u0453",
     };
 
-    /* Language mn_MN: Mongolian (Mongolia) */
-    private static final String[] LANGUAGE_mn_MN = {
+    /* Locale mn_MN: Mongolian (Mongolia) */
+    private static final String[] TEXTS_mn_MN = {
         /* morekeys_a ~ */
         null, null, null, null, null, null, null, null, null,
         /* ~ single_quotes */
@@ -2524,8 +2535,8 @@
         /* keyspec_currency */ "\u20AE",
     };
 
-    /* Language my_MM: Burmese (Myanmar) */
-    private static final String[] LANGUAGE_my_MM = {
+    /* Locale my_MM: Burmese (Myanmar) */
+    private static final String[] TEXTS_my_MM = {
         /* morekeys_a ~ */
         null, null, null, null, null, null, null, null, null,
         /* ~ single_quotes */
@@ -2536,8 +2547,8 @@
         /* keylabel_to_alpha */ "\u1000\u1001\u1002",
     };
 
-    /* Language nb: Norwegian Bokmål */
-    private static final String[] LANGUAGE_nb = {
+    /* Locale nb: Norwegian Bokmål */
+    private static final String[] TEXTS_nb = {
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
         // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
@@ -2590,8 +2601,8 @@
         /* morekeys_nordic_row2_11 */ "\u00E4",
     };
 
-    /* Language ne_NP: Nepali (Nepal) */
-    private static final String[] LANGUAGE_ne_NP = {
+    /* Locale ne_NP: Nepali (Nepal) */
+    private static final String[] TEXTS_ne_NP = {
         /* morekeys_a ~ */
         null, null, null, null, null, null, null, null, null,
         /* ~ single_quotes */
@@ -2642,8 +2653,8 @@
         /* additional_morekeys_symbols_0 */ "0",
     };
 
-    /* Language nl: Dutch */
-    private static final String[] LANGUAGE_nl = {
+    /* Locale nl: Dutch */
+    private static final String[] TEXTS_nl = {
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
         // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
         // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
@@ -2696,8 +2707,8 @@
         /* morekeys_y */ "\u0133",
     };
 
-    /* Language pl: Polish */
-    private static final String[] LANGUAGE_pl = {
+    /* Locale pl: Polish */
+    private static final String[] TEXTS_pl = {
         // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
@@ -2752,8 +2763,8 @@
         /* morekeys_l */ "\u0142",
     };
 
-    /* Language pt: Portuguese */
-    private static final String[] LANGUAGE_pt = {
+    /* Locale pt: Portuguese */
+    private static final String[] TEXTS_pt = {
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
         // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
@@ -2800,8 +2811,8 @@
         /* morekeys_c */ "\u00E7,\u010D,\u0107",
     };
 
-    /* Language rm: Raeto-Romance */
-    private static final String[] LANGUAGE_rm = {
+    /* Locale rm: Raeto-Romance */
+    private static final String[] TEXTS_rm = {
         /* morekeys_a */ null,
         // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
         // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
@@ -2813,8 +2824,8 @@
         /* morekeys_o */ "\u00F2,\u00F3,\u00F6,\u00F4,\u00F5,\u0153,\u00F8",
     };
 
-    /* Language ro: Romanian */
-    private static final String[] LANGUAGE_ro = {
+    /* Locale ro: Romanian */
+    private static final String[] TEXTS_ro = {
         // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
         // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE
         // U+0103: "ă" LATIN SMALL LETTER A WITH BREVE
@@ -2852,8 +2863,8 @@
         /* morekeys_t */ "\u021B",
     };
 
-    /* Language ru: Russian */
-    private static final String[] LANGUAGE_ru = {
+    /* Locale ru: Russian */
+    private static final String[] TEXTS_ru = {
         /* morekeys_a ~ */
         null, null, null, null, null, null,
         /* ~ morekeys_c */
@@ -2885,8 +2896,8 @@
         /* morekeys_cyrillic_soft_sign */ "\u044A",
     };
 
-    /* Language sk: Slovak */
-    private static final String[] LANGUAGE_sk = {
+    /* Locale sk: Slovak */
+    private static final String[] TEXTS_sk = {
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
         // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
         // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON
@@ -2980,8 +2991,8 @@
         /* morekeys_k */ "\u0137",
     };
 
-    /* Language sl: Slovenian */
-    private static final String[] LANGUAGE_sl = {
+    /* Locale sl: Slovenian */
+    private static final String[] TEXTS_sl = {
         /* morekeys_a ~ */
         null, null, null, null, null,
         /* ~ morekeys_i */
@@ -3006,8 +3017,8 @@
         /* double_angle_quotes */ "!text/double_raqm_laqm",
     };
 
-    /* Language sr: Serbian */
-    private static final String[] LANGUAGE_sr = {
+    /* Locale sr: Serbian */
+    private static final String[] TEXTS_sr = {
         /* morekeys_a ~ */
         null, null, null, null, null, null,
         /* ~ morekeys_c */
@@ -3066,8 +3077,8 @@
         /* keyspec_south_slavic_row3_8 */ "\u0452",
     };
 
-    /* Language sv: Swedish */
-    private static final String[] LANGUAGE_sv = {
+    /* Locale sv: Swedish */
+    private static final String[] TEXTS_sv = {
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
         // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
@@ -3152,8 +3163,8 @@
         /* morekeys_nordic_row2_11 */ "\u00E6",
     };
 
-    /* Language sw: Swahili */
-    private static final String[] LANGUAGE_sw = {
+    /* Locale sw: Swahili */
+    private static final String[] TEXTS_sw = {
         // This is the same as English except morekeys_g.
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
@@ -3206,8 +3217,8 @@
         /* morekeys_g */ "g\'",
     };
 
-    /* Language th: Thai */
-    private static final String[] LANGUAGE_th = {
+    /* Locale th: Thai */
+    private static final String[] TEXTS_th = {
         /* morekeys_a ~ */
         null, null, null, null, null, null, null, null, null,
         /* ~ single_quotes */
@@ -3223,8 +3234,8 @@
         /* keyspec_currency */ "\u0E3F",
     };
 
-    /* Language tl: Tagalog */
-    private static final String[] LANGUAGE_tl = {
+    /* Locale tl: Tagalog */
+    private static final String[] TEXTS_tl = {
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
         // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
@@ -3277,8 +3288,8 @@
         /* morekeys_n */ "\u00F1,\u0144",
     };
 
-    /* Language tr: Turkish */
-    private static final String[] LANGUAGE_tr = {
+    /* Locale tr: Turkish */
+    private static final String[] TEXTS_tr = {
         // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
         /* morekeys_a */ "\u00E2",
         // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
@@ -3324,8 +3335,8 @@
         /* morekeys_g */ "\u011F",
     };
 
-    /* Language uk: Ukrainian */
-    private static final String[] LANGUAGE_uk = {
+    /* Locale uk: Ukrainian */
+    private static final String[] TEXTS_uk = {
         /* morekeys_a ~ */
         null, null, null, null, null, null,
         /* ~ morekeys_c */
@@ -3368,8 +3379,8 @@
         /* morekeys_cyrillic_ghe */ "\u0491",
     };
 
-    /* Language vi: Vietnamese */
-    private static final String[] LANGUAGE_vi = {
+    /* Locale vi: Vietnamese */
+    private static final String[] TEXTS_vi = {
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
         // U+1EA3: "ả" LATIN SMALL LETTER A WITH HOOK ABOVE
@@ -3454,8 +3465,8 @@
         /* keyspec_currency */ "\u20AB",
     };
 
-    /* Language zu: Zulu */
-    private static final String[] LANGUAGE_zu = {
+    /* Locale zu: Zulu */
+    private static final String[] TEXTS_zu = {
         // This is the same as English
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
@@ -3504,8 +3515,8 @@
         /* morekeys_s */ "\u00DF",
     };
 
-    /* Language zz: Alphabet */
-    private static final String[] LANGUAGE_zz = {
+    /* Locale zz: Alphabet */
+    private static final String[] TEXTS_zz = {
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
         // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
         // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
@@ -3643,67 +3654,65 @@
         /* morekeys_j */ "\u0135",
     };
 
-    // TODO: Use the language + "_" + region representation for the locale string key.
-    // Currently we are dropping the region from the key.
-    private static final Object[] LANGUAGES_AND_TEXTS = {
+    private static final Object[] LOCALES_AND_TEXTS = {
     // "locale", TEXT_ARRAY,  /* numberOfNonNullText/lengthOf_TEXT_ARRAY localeName */
-        "DEFAULT", LANGUAGE_DEFAULT, /* 168/168 default */
-        "af", LANGUAGE_af,    /*   7/ 12 Afrikaans */
-        "ar", LANGUAGE_ar,    /*  55/107 Arabic */
-        "az", LANGUAGE_az_AZ, /*   8/ 17 Azerbaijani (Azerbaijan) */
-        "be", LANGUAGE_be_BY, /*   9/ 32 Belarusian (Belarus) */
-        "bg", LANGUAGE_bg,    /*   2/ 10 Bulgarian */
-        "ca", LANGUAGE_ca,    /*  11/114 Catalan */
-        "cs", LANGUAGE_cs,    /*  17/ 21 Czech */
-        "da", LANGUAGE_da,    /*  19/ 33 Danish */
-        "de", LANGUAGE_de,    /*  16/ 91 German */
-        "el", LANGUAGE_el,    /*   1/ 10 Greek */
-        "en", LANGUAGE_en,    /*   8/ 11 English */
-        "eo", LANGUAGE_eo,    /*  26/126 Esperanto */
-        "es", LANGUAGE_es,    /*   8/ 55 Spanish */
-        "et", LANGUAGE_et_EE, /*  22/ 27 Estonian (Estonia) */
-        "eu", LANGUAGE_eu_ES, /*   7/  8 Basque (Spain) */
-        "fa", LANGUAGE_fa,    /*  58/117 Persian */
-        "fi", LANGUAGE_fi,    /*  10/ 33 Finnish */
-        "fr", LANGUAGE_fr,    /*  13/ 91 French */
-        "gl", LANGUAGE_gl_ES, /*   7/  8 Gallegan (Spain) */
-        "hi", LANGUAGE_hi,    /*  23/ 54 Hindi */
-        "hr", LANGUAGE_hr,    /*   9/ 19 Croatian */
-        "hu", LANGUAGE_hu,    /*   9/ 19 Hungarian */
-        "hy", LANGUAGE_hy_AM, /*   8/120 Armenian (Armenia) */
-        "is", LANGUAGE_is,    /*  10/ 15 Icelandic */
-        "it", LANGUAGE_it,    /*   5/  5 Italian */
-        "iw", LANGUAGE_iw,    /*  20/115 Hebrew */
-        "ka", LANGUAGE_ka_GE, /*   3/ 10 Georgian (Georgia) */
-        "kk", LANGUAGE_kk,    /*  15/112 Kazakh */
-        "km", LANGUAGE_km_KH, /*   2/113 Khmer (Cambodia) */
-        "ky", LANGUAGE_ky,    /*  10/ 80 Kirghiz */
-        "lo", LANGUAGE_lo_LA, /*   2/ 20 Lao (Laos) */
-        "lt", LANGUAGE_lt,    /*  18/ 22 Lithuanian */
-        "lv", LANGUAGE_lv,    /*  18/ 22 Latvian */
-        "mk", LANGUAGE_mk,    /*   9/ 85 Macedonian */
-        "mn", LANGUAGE_mn_MN, /*   2/ 20 Mongolian (Mongolia) */
-        "my", LANGUAGE_my_MM, /*   1/ 10 Burmese (Myanmar) */
-        "nb", LANGUAGE_nb,    /*  11/ 33 Norwegian Bokmål */
-        "ne", LANGUAGE_ne_NP, /*  23/ 54 Nepali (Nepal) */
-        "nl", LANGUAGE_nl,    /*   9/ 12 Dutch */
-        "pl", LANGUAGE_pl,    /*  10/ 16 Polish */
-        "pt", LANGUAGE_pt,    /*   6/  6 Portuguese */
-        "rm", LANGUAGE_rm,    /*   1/  2 Raeto-Romance */
-        "ro", LANGUAGE_ro,    /*   6/ 15 Romanian */
-        "ru", LANGUAGE_ru,    /*   9/ 32 Russian */
-        "sk", LANGUAGE_sk,    /*  20/ 22 Slovak */
-        "sl", LANGUAGE_sl,    /*   8/ 19 Slovenian */
-        "sr", LANGUAGE_sr,    /*  11/ 85 Serbian */
-        "sv", LANGUAGE_sv,    /*  21/ 33 Swedish */
-        "sw", LANGUAGE_sw,    /*   9/ 17 Swahili */
-        "th", LANGUAGE_th,    /*   2/ 20 Thai */
-        "tl", LANGUAGE_tl,    /*   7/  8 Tagalog */
-        "tr", LANGUAGE_tr,    /*   7/ 17 Turkish */
-        "uk", LANGUAGE_uk,    /*  11/ 79 Ukrainian */
-        "vi", LANGUAGE_vi,    /*   8/ 20 Vietnamese */
-        "zu", LANGUAGE_zu,    /*   8/ 11 Zulu */
-        "zz", LANGUAGE_zz,    /*  19/109 Alphabet */
+        "DEFAULT", TEXTS_DEFAULT, /* 168/168 default */
+        "af"     , TEXTS_af,    /*   7/ 12 Afrikaans */
+        "ar"     , TEXTS_ar,    /*  55/107 Arabic */
+        "az_AZ"  , TEXTS_az_AZ, /*   8/ 17 Azerbaijani (Azerbaijan) */
+        "be_BY"  , TEXTS_be_BY, /*   9/ 32 Belarusian (Belarus) */
+        "bg"     , TEXTS_bg,    /*   2/ 10 Bulgarian */
+        "ca"     , TEXTS_ca,    /*  11/120 Catalan */
+        "cs"     , TEXTS_cs,    /*  17/ 21 Czech */
+        "da"     , TEXTS_da,    /*  19/ 33 Danish */
+        "de"     , TEXTS_de,    /*  16/ 91 German */
+        "el"     , TEXTS_el,    /*   1/ 10 Greek */
+        "en"     , TEXTS_en,    /*   8/ 11 English */
+        "eo"     , TEXTS_eo,    /*  26/115 Esperanto */
+        "es"     , TEXTS_es,    /*   8/ 55 Spanish */
+        "et_EE"  , TEXTS_et_EE, /*  22/ 27 Estonian (Estonia) */
+        "eu_ES"  , TEXTS_eu_ES, /*   7/  8 Basque (Spain) */
+        "fa"     , TEXTS_fa,    /*  58/123 Persian */
+        "fi"     , TEXTS_fi,    /*  10/ 33 Finnish */
+        "fr"     , TEXTS_fr,    /*  13/ 91 French */
+        "gl_ES"  , TEXTS_gl_ES, /*   7/  8 Gallegan (Spain) */
+        "hi"     , TEXTS_hi,    /*  23/ 54 Hindi */
+        "hr"     , TEXTS_hr,    /*   9/ 19 Croatian */
+        "hu"     , TEXTS_hu,    /*   9/ 19 Hungarian */
+        "hy_AM"  , TEXTS_hy_AM, /*   8/126 Armenian (Armenia) */
+        "is"     , TEXTS_is,    /*  10/ 15 Icelandic */
+        "it"     , TEXTS_it,    /*   5/  5 Italian */
+        "iw"     , TEXTS_iw,    /*  20/121 Hebrew */
+        "ka_GE"  , TEXTS_ka_GE, /*   3/ 10 Georgian (Georgia) */
+        "kk"     , TEXTS_kk,    /*  15/118 Kazakh */
+        "km_KH"  , TEXTS_km_KH, /*   2/119 Khmer (Cambodia) */
+        "ky"     , TEXTS_ky,    /*  10/ 80 Kirghiz */
+        "lo_LA"  , TEXTS_lo_LA, /*   2/ 20 Lao (Laos) */
+        "lt"     , TEXTS_lt,    /*  18/ 22 Lithuanian */
+        "lv"     , TEXTS_lv,    /*  18/ 22 Latvian */
+        "mk"     , TEXTS_mk,    /*   9/ 85 Macedonian */
+        "mn_MN"  , TEXTS_mn_MN, /*   2/ 20 Mongolian (Mongolia) */
+        "my_MM"  , TEXTS_my_MM, /*   1/ 10 Burmese (Myanmar) */
+        "nb"     , TEXTS_nb,    /*  11/ 33 Norwegian Bokmål */
+        "ne_NP"  , TEXTS_ne_NP, /*  23/ 54 Nepali (Nepal) */
+        "nl"     , TEXTS_nl,    /*   9/ 12 Dutch */
+        "pl"     , TEXTS_pl,    /*  10/ 16 Polish */
+        "pt"     , TEXTS_pt,    /*   6/  6 Portuguese */
+        "rm"     , TEXTS_rm,    /*   1/  2 Raeto-Romance */
+        "ro"     , TEXTS_ro,    /*   6/ 15 Romanian */
+        "ru"     , TEXTS_ru,    /*   9/ 32 Russian */
+        "sk"     , TEXTS_sk,    /*  20/ 22 Slovak */
+        "sl"     , TEXTS_sl,    /*   8/ 19 Slovenian */
+        "sr"     , TEXTS_sr,    /*  11/ 85 Serbian */
+        "sv"     , TEXTS_sv,    /*  21/ 33 Swedish */
+        "sw"     , TEXTS_sw,    /*   9/ 17 Swahili */
+        "th"     , TEXTS_th,    /*   2/ 20 Thai */
+        "tl"     , TEXTS_tl,    /*   7/  8 Tagalog */
+        "tr"     , TEXTS_tr,    /*   7/ 17 Turkish */
+        "uk"     , TEXTS_uk,    /*  11/ 79 Ukrainian */
+        "vi"     , TEXTS_vi,    /*   8/ 20 Vietnamese */
+        "zu"     , TEXTS_zu,    /*   8/ 11 Zulu */
+        "zz"     , TEXTS_zz,    /*  19/109 Alphabet */
     };
 
     static {
@@ -3711,11 +3720,11 @@
             sNameToIndexesMap.put(NAMES[index], index);
         }
 
-        for (int i = 0; i < LANGUAGES_AND_TEXTS.length; i += 2) {
-            final String language = (String)LANGUAGES_AND_TEXTS[i];
-            final String[] textsTable = (String[])LANGUAGES_AND_TEXTS[i + 1];
-            sLanguageToTextsTableMap.put(language, textsTable);
-            sTextsTableToLanguageMap.put(textsTable, language);
+        for (int i = 0; i < LOCALES_AND_TEXTS.length; i += 2) {
+            final String locale = (String)LOCALES_AND_TEXTS[i];
+            final String[] textsTable = (String[])LOCALES_AND_TEXTS[i + 1];
+            sLocaleToTextsTableMap.put(locale, textsTable);
+            sTextsTableToLocaleMap.put(textsTable, locale);
         }
     }
 }
diff --git a/java/src/com/android/inputmethod/latin/ImportantNoticeDialog.java b/java/src/com/android/inputmethod/latin/ImportantNoticeDialog.java
index 9870faa..be54b66 100644
--- a/java/src/com/android/inputmethod/latin/ImportantNoticeDialog.java
+++ b/java/src/com/android/inputmethod/latin/ImportantNoticeDialog.java
@@ -23,6 +23,7 @@
 import android.content.DialogInterface.OnDismissListener;
 import android.content.DialogInterface.OnShowListener;
 
+import com.android.inputmethod.latin.utils.DialogUtils;
 import com.android.inputmethod.latin.utils.ImportantNoticeUtils;
 
 /**
@@ -40,7 +41,7 @@
 
     public ImportantNoticeDialog(
             final Context context, final ImportantNoticeDialogListener listener) {
-        super(context, THEME_HOLO_DARK);
+        super(DialogUtils.getPlatformDialogThemeContext(context));
         mListener = listener;
         mNextImportantNoticeVersion = ImportantNoticeUtils.getNextImportantNoticeVersion(context);
         setMessage(ImportantNoticeUtils.getNextImportantNoticeContents(context));
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 325ef64..6d36af7 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -83,6 +83,7 @@
 import com.android.inputmethod.latin.utils.ApplicationUtils;
 import com.android.inputmethod.latin.utils.CapsModeUtils;
 import com.android.inputmethod.latin.utils.CoordinateUtils;
+import com.android.inputmethod.latin.utils.DialogUtils;
 import com.android.inputmethod.latin.utils.ImportantNoticeUtils;
 import com.android.inputmethod.latin.utils.IntentUtils;
 import com.android.inputmethod.latin.utils.JniUtils;
@@ -198,7 +199,7 @@
                         latinIme.mSettings.getCurrent());
                 break;
             case MSG_UPDATE_SHIFT_STATE:
-                switcher.updateShiftState();
+                switcher.requestUpdatingShiftState();
                 break;
             case MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP:
                 if (msg.arg1 == ARG1_NOT_GESTURE_INPUT) {
@@ -837,7 +838,7 @@
             // we need to re-evaluate the shift state, but not the whole layout which would be
             // disruptive.
             // Space state must be updated before calling updateShiftState
-            switcher.updateShiftState();
+            switcher.requestUpdatingShiftState();
         }
         // This will set the punctuation suggestions if next word suggestion is off;
         // otherwise it will clear the suggestion strip.
@@ -916,7 +917,7 @@
         // TODO: find a better way to simulate actual execution.
         if (isInputViewShown() &&
                 mInputLogic.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd)) {
-            mKeyboardSwitcher.updateShiftState();
+            mKeyboardSwitcher.requestUpdatingShiftState();
         }
 
         mSubtypeState.currentSubtypeUsed();
@@ -1235,7 +1236,7 @@
                 mInputLogic.onCodeInput(mSettings.getCurrent(), event,
                         mKeyboardSwitcher.getKeyboardShiftMode(), mHandler);
         updateStateAfterInputTransaction(completeInputTransaction);
-        mKeyboardSwitcher.onCodeInput(codePoint);
+        mKeyboardSwitcher.onCodeInput(codePoint, getCurrentAutoCapsState());
     }
 
     // A helper method to split the code point and the key code. Ultimately, they should not be
@@ -1260,8 +1261,8 @@
         // TODO: have the keyboard pass the correct key code when we need it.
         final Event event = Event.createSoftwareTextEvent(rawText, Event.NOT_A_KEY_CODE);
         mInputLogic.onTextInput(mSettings.getCurrent(), event, mHandler);
-        mKeyboardSwitcher.updateShiftState();
-        mKeyboardSwitcher.onCodeInput(Constants.CODE_OUTPUT_TEXT);
+        mKeyboardSwitcher.requestUpdatingShiftState();
+        mKeyboardSwitcher.onCodeInput(Constants.CODE_OUTPUT_TEXT, getCurrentAutoCapsState());
     }
 
     @Override
@@ -1504,7 +1505,7 @@
             mHandler.postUpdateShiftState();
             break;
         case InputTransaction.SHIFT_UPDATE_NOW:
-            mKeyboardSwitcher.updateShiftState();
+            mKeyboardSwitcher.requestUpdatingShiftState();
             break;
         default: // SHIFT_NO_UPDATE
         }
@@ -1544,7 +1545,7 @@
     @Override
     public void onPressKey(final int primaryCode, final int repeatCount,
             final boolean isSinglePointer) {
-        mKeyboardSwitcher.onPressKey(primaryCode, isSinglePointer);
+        mKeyboardSwitcher.onPressKey(primaryCode, isSinglePointer, getCurrentAutoCapsState());
         hapticAndAudioFeedback(primaryCode, repeatCount);
     }
 
@@ -1666,8 +1667,9 @@
                 }
             }
         };
-        final AlertDialog.Builder builder =
-                new AlertDialog.Builder(this).setItems(items, listener).setTitle(title);
+        final AlertDialog.Builder builder = new AlertDialog.Builder(
+                DialogUtils.getPlatformDialogThemeContext(this));
+        builder.setItems(items, listener).setTitle(title);
         showOptionDialog(builder.create());
     }
 
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index f31fb13..81d642f 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -165,67 +165,61 @@
     }
 
     /**
-     * Add a new event for a key stroke, with the pressed key's code point with the touch point
-     * coordinates.
+     * Process an input event.
+     *
+     * All input events should be supported, including software/hardware events, characters as well
+     * as deletions, multiple inputs and gestures.
+     *
+     * @param event the event to process.
      */
-    public void add(final Event event) {
+    public void processEvent(final Event event) {
         final int primaryCode = event.mCodePoint;
         final int keyX = event.mX;
         final int keyY = event.mY;
         final int newIndex = size();
-        processEvent(event);
-        mCursorPositionWithinWord = mCodePointSize;
-        if (newIndex < MAX_WORD_LENGTH) {
-            mPrimaryKeyCodes[newIndex] = primaryCode >= Constants.CODE_SPACE
-                    ? Character.toLowerCase(primaryCode) : primaryCode;
-            // In the batch input mode, the {@code mInputPointers} holds batch input points and
-            // shouldn't be overridden by the "typed key" coordinates
-            // (See {@link #setBatchInputWord}).
-            if (!mIsBatchMode) {
-                // TODO: Set correct pointer id and time
-                mInputPointers.addPointerAt(newIndex, keyX, keyY, 0, 0);
-            }
-        }
-        mIsFirstCharCapitalized = isFirstCharCapitalized(
-                newIndex, primaryCode, mIsFirstCharCapitalized);
-        if (Character.isUpperCase(primaryCode)) mCapsCount++;
-        if (Character.isDigit(primaryCode)) mDigitsCount++;
-        if (Constants.CODE_SINGLE_QUOTE == primaryCode) {
-            ++mTrailingSingleQuotesCount;
-        } else {
-            mTrailingSingleQuotesCount = 0;
-        }
-        mAutoCorrection = null;
-    }
-
-    private void processEvent(final Event event) {
         mCombinerChain.processEvent(mEvents, event);
         mEvents.add(event);
         refreshTypedWordCache();
-    }
-
-    /**
-     * Delete the last composing unit as a result of hitting backspace.
-     */
-    public void deleteLast(final Event event) {
-        processEvent(event);
+        mCursorPositionWithinWord = mCodePointSize;
         // We may have deleted the last one.
-        if (0 == size()) {
+        if (0 == mCodePointSize) {
             mIsFirstCharCapitalized = false;
         }
-        if (mTrailingSingleQuotesCount > 0) {
-            --mTrailingSingleQuotesCount;
-        } else {
-            int i = mTypedWordCache.length();
-            while (i > 0) {
-                i = Character.offsetByCodePoints(mTypedWordCache, i, -1);
-                if (Constants.CODE_SINGLE_QUOTE != Character.codePointAt(mTypedWordCache, i)) {
-                    break;
+        if (Constants.CODE_DELETE == event.mKeyCode) {
+            if (mTrailingSingleQuotesCount > 0) {
+                --mTrailingSingleQuotesCount;
+            } else {
+                // Delete, but we didn't end in a quote: must recompute mTrailingSingleQuotesCount
+                // We're only searching for single quotes, so no need to account for code points
+                for (int i = mTypedWordCache.length() - 1; i > 0; --i) {
+                    if (Constants.CODE_SINGLE_QUOTE != mTypedWordCache.charAt(i)) {
+                        break;
+                    }
+                    ++mTrailingSingleQuotesCount;
                 }
-                ++mTrailingSingleQuotesCount;
             }
+        } else {
+            if (Constants.CODE_SINGLE_QUOTE == primaryCode) {
+                ++mTrailingSingleQuotesCount;
+            } else {
+                mTrailingSingleQuotesCount = 0;
+            }
+            if (newIndex < MAX_WORD_LENGTH) {
+                mPrimaryKeyCodes[newIndex] = primaryCode >= Constants.CODE_SPACE
+                        ? Character.toLowerCase(primaryCode) : primaryCode;
+                // In the batch input mode, the {@code mInputPointers} holds batch input points and
+                // shouldn't be overridden by the "typed key" coordinates
+                // (See {@link #setBatchInputWord}).
+                if (!mIsBatchMode) {
+                    // TODO: Set correct pointer id and time
+                    mInputPointers.addPointerAt(newIndex, keyX, keyY, 0, 0);
+                }
+            }
+            mIsFirstCharCapitalized = isFirstCharCapitalized(
+                    newIndex, primaryCode, mIsFirstCharCapitalized);
+            if (Character.isUpperCase(primaryCode)) mCapsCount++;
+            if (Character.isDigit(primaryCode)) mDigitsCount++;
         }
-        mCursorPositionWithinWord = mCodePointSize;
         mAutoCorrection = null;
     }
 
@@ -300,7 +294,7 @@
             final int codePoint = Character.codePointAt(word, i);
             // We don't want to override the batch input points that are held in mInputPointers
             // (See {@link #add(int,int,int)}).
-            add(Event.createEventForCodePointFromUnknownSource(codePoint));
+            processEvent(Event.createEventForCodePointFromUnknownSource(codePoint));
         }
     }
 
@@ -317,7 +311,7 @@
         reset();
         final int length = codePoints.length;
         for (int i = 0; i < length; ++i) {
-            add(Event.createEventForCodePointFromAlreadyTypedText(codePoints[i],
+            processEvent(Event.createEventForCodePointFromAlreadyTypedText(codePoints[i],
                     CoordinateUtils.xFromArray(coordinates, i),
                     CoordinateUtils.yFromArray(coordinates, i)));
         }
diff --git a/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java b/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java
index 800f565..139e73a 100644
--- a/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java
+++ b/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java
@@ -28,6 +28,7 @@
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.makedict.DictionaryHeader;
 import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.DialogUtils;
 import com.android.inputmethod.latin.utils.DictionaryInfoUtils;
 import com.android.inputmethod.latin.utils.LocaleUtils;
 
@@ -70,7 +71,7 @@
     }
 
     private static void showNoFileDialog(final Context context) {
-        new AlertDialog.Builder(context)
+        new AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(context))
                 .setMessage(R.string.read_external_dictionary_no_files_message)
                 .setPositiveButton(android.R.string.ok, new OnClickListener() {
                     @Override
@@ -81,8 +82,8 @@
     }
 
     private static void showChooseFileDialog(final Context context, final String[] fileNames) {
-        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
-        builder.setTitle(R.string.read_external_dictionary_multiple_files_title)
+        new AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(context))
+                .setTitle(R.string.read_external_dictionary_multiple_files_title)
                 .setItems(fileNames, new OnClickListener() {
                     @Override
                     public void onClick(final DialogInterface dialog, final int which) {
@@ -111,7 +112,7 @@
         final String title = String.format(
                 context.getString(R.string.read_external_dictionary_confirm_install_message),
                 languageName);
-        new AlertDialog.Builder(context)
+        new AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(context))
                 .setTitle(title)
                 .setMessage(message)
                 .setNegativeButton(android.R.string.cancel, new OnClickListener() {
@@ -167,7 +168,7 @@
             }
         } catch (IOException e) {
             // There was an error: show a dialog
-            new AlertDialog.Builder(context)
+            new AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(context))
                     .setTitle(R.string.error)
                     .setMessage(e.toString())
                     .setPositiveButton(android.R.string.ok, new OnClickListener() {
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index c89be35..7cf8c5e 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -537,7 +537,7 @@
                 // after typing some letters and a period, then gesturing; the keyboard is not in
                 // caps mode yet, but since a gesture is starting, it should go in caps mode,
                 // unless the user explictly said it should not.
-                keyboardSwitcher.updateShiftState();
+                keyboardSwitcher.requestUpdatingShiftState();
             }
         }
         mConnection.endBatchEdit();
@@ -579,7 +579,7 @@
                     promotePhantomSpace(settingsValues);
                     mConnection.commitText(commitParts[0], 0);
                     mSpaceState = SpaceState.PHANTOM;
-                    keyboardSwitcher.updateShiftState();
+                    keyboardSwitcher.requestUpdatingShiftState();
                     mWordComposer.setCapitalizedModeAndPreviousWordAtStartComposingTime(
                             getActualCapsMode(settingsValues,
                                     keyboardSwitcher.getKeyboardShiftMode()), commitParts[0]);
@@ -727,7 +727,7 @@
             resetComposingState(false /* alsoResetLastComposedWord */);
         }
         if (isComposingWord) {
-            mWordComposer.add(inputTransaction.mEvent);
+            mWordComposer.processEvent(inputTransaction.mEvent);
             // If it's the first letter, make note of auto-caps state
             if (mWordComposer.isSingleLetter()) {
                 // We pass 1 to getPreviousWordForSuggestion because we were not composing a word
@@ -823,13 +823,11 @@
         }
 
         if (Constants.CODE_SPACE == codePoint) {
-            if (inputTransaction.mSettingsValues.isSuggestionsRequested()) {
-                if (maybeDoubleSpacePeriod(inputTransaction)) {
-                    inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
-                    mSpaceState = SpaceState.DOUBLE;
-                } else if (!mSuggestedWords.isPunctuationSuggestions()) {
-                    mSpaceState = SpaceState.WEAK;
-                }
+            if (maybeDoubleSpacePeriod(inputTransaction)) {
+                inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
+                mSpaceState = SpaceState.DOUBLE;
+            } else if (!mSuggestedWords.isPunctuationSuggestions()) {
+                mSpaceState = SpaceState.WEAK;
             }
 
             startDoubleSpacePeriodCountdown(inputTransaction);
@@ -895,7 +893,7 @@
                 mWordComposer.reset();
                 mWordComposer.setRejectedBatchModeSuggestion(rejectedSuggestion);
             } else {
-                mWordComposer.deleteLast(inputTransaction.mEvent);
+                mWordComposer.processEvent(inputTransaction.mEvent);
             }
             mConnection.setComposingText(getTextWithUnderline(mWordComposer.getTypedWord()), 1);
             inputTransaction.setRequiresUpdateSuggestions();
@@ -1821,7 +1819,7 @@
         }
         // Space state must be updated before calling updateShiftState
         mSpaceState = SpaceState.PHANTOM;
-        keyboardSwitcher.updateShiftState();
+        keyboardSwitcher.requestUpdatingShiftState();
     }
 
     /**
diff --git a/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java b/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java
index 6dae620..39977e7 100644
--- a/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java
+++ b/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java
@@ -48,6 +48,7 @@
 import com.android.inputmethod.latin.RichInputMethodManager;
 import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
 import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.DialogUtils;
 import com.android.inputmethod.latin.utils.IntentUtils;
 import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
 
@@ -517,7 +518,8 @@
 
     private AlertDialog createDialog(
             @SuppressWarnings("unused") final SubtypePreference subtypePref) {
-        final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+        final AlertDialog.Builder builder = new AlertDialog.Builder(
+                DialogUtils.getPlatformDialogThemeContext(getActivity()));
         builder.setTitle(R.string.custom_input_styles_title)
                 .setMessage(R.string.custom_input_style_note_message)
                 .setNegativeButton(R.string.not_now, null)
diff --git a/java/src/com/android/inputmethod/latin/utils/DialogUtils.java b/java/src/com/android/inputmethod/latin/utils/DialogUtils.java
new file mode 100644
index 0000000..a05c932
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/utils/DialogUtils.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 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.latin.utils;
+
+import android.content.Context;
+import android.view.ContextThemeWrapper;
+
+import com.android.inputmethod.latin.R;
+
+public final class DialogUtils {
+    private DialogUtils() {
+        // This utility class is not publicly instantiable.
+    }
+
+    public static Context getPlatformDialogThemeContext(final Context context) {
+        // Because {@link AlertDialog.Builder.create()} doesn't honor the specified theme with
+        // createThemeContextWrapper=false, the result dialog box has unneeded paddings around it.
+        return new ContextThemeWrapper(context, R.style.platformDialogTheme);
+    }
+}
diff --git a/native/jni/HostUnitTests.mk b/native/jni/HostUnitTests.mk
index 967099a..572d365 100644
--- a/native/jni/HostUnitTests.mk
+++ b/native/jni/HostUnitTests.mk
@@ -29,10 +29,8 @@
 LOCAL_CFLAGS += -std=c++11 -Wno-unused-parameter -Wno-unused-function
 LOCAL_CLANG := true
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(LATIN_IME_SRC_DIR)
-LOCAL_IS_HOST_MODULE := true
 LOCAL_MODULE := liblatinime_host_static_for_unittests
 LOCAL_MODULE_TAGS := optional
-LOCAL_NDK_STL_VARIANT := c++_static
 LOCAL_SRC_FILES := $(addprefix $(LATIN_IME_SRC_DIR)/, $(LATIN_IME_CORE_SRC_FILES))
 include $(BUILD_HOST_STATIC_LIBRARY)
 
@@ -43,10 +41,8 @@
 LOCAL_CFLAGS += -std=c++11 -Wno-unused-parameter -Wno-unused-function
 LOCAL_CLANG := true
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(LATIN_IME_SRC_DIR)
-LOCAL_IS_HOST_MODULE := true
 LOCAL_MODULE := liblatinime_host_unittests
 LOCAL_MODULE_TAGS := tests
-LOCAL_NDK_STL_VARIANT := c++_static
 LOCAL_SRC_FILES := $(addprefix $(LATIN_IME_TEST_SRC_DIR)/, $(LATIN_IME_CORE_TEST_FILES))
 LOCAL_STATIC_LIBRARIES += liblatinime_host_static_for_unittests libgtest_host libgtest_main_host
 include $(BUILD_HOST_NATIVE_TEST)
diff --git a/native/jni/NativeFileList.mk b/native/jni/NativeFileList.mk
index 3da9d56..1031903 100644
--- a/native/jni/NativeFileList.mk
+++ b/native/jni/NativeFileList.mk
@@ -32,7 +32,7 @@
         digraph_utils.cpp \
         error_type_utils.cpp \
         multi_bigram_map.cpp \
-        word_property.cpp) \
+        property/word_property.cpp) \
     $(addprefix suggest/core/layout/, \
         additional_proximity_chars.cpp \
         proximity_info.cpp \
diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
index bf03fdf..a102344 100644
--- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
+++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
@@ -24,7 +24,7 @@
 #include "jni.h"
 #include "jni_common.h"
 #include "suggest/core/dictionary/dictionary.h"
-#include "suggest/core/dictionary/word_property.h"
+#include "suggest/core/dictionary/property/word_property.h"
 #include "suggest/core/result/suggestion_results.h"
 #include "suggest/core/suggest_options.h"
 #include "suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.h"
diff --git a/native/jni/src/suggest/core/dicnode/dic_nodes_cache.h b/native/jni/src/suggest/core/dicnode/dic_nodes_cache.h
index 089d446..fb76c73 100644
--- a/native/jni/src/suggest/core/dicnode/dic_nodes_cache.h
+++ b/native/jni/src/suggest/core/dicnode/dic_nodes_cache.h
@@ -18,7 +18,6 @@
 #define LATINIME_DIC_NODES_CACHE_H
 
 #include <algorithm>
-#include <stdint.h>
 
 #include "defines.h"
 #include "suggest/core/dicnode/dic_node_priority_queue.h"
diff --git a/native/jni/src/suggest/core/dicnode/internal/dic_node_properties.h b/native/jni/src/suggest/core/dicnode/internal/dic_node_properties.h
index 6ddb7f1..11f8c29 100644
--- a/native/jni/src/suggest/core/dicnode/internal/dic_node_properties.h
+++ b/native/jni/src/suggest/core/dicnode/internal/dic_node_properties.h
@@ -17,7 +17,7 @@
 #ifndef LATINIME_DIC_NODE_PROPERTIES_H
 #define LATINIME_DIC_NODE_PROPERTIES_H
 
-#include <stdint.h>
+#include <cstdint>
 
 #include "defines.h"
 
diff --git a/native/jni/src/suggest/core/dicnode/internal/dic_node_state_output.h b/native/jni/src/suggest/core/dicnode/internal/dic_node_state_output.h
index ea48de1..69a886f 100644
--- a/native/jni/src/suggest/core/dicnode/internal/dic_node_state_output.h
+++ b/native/jni/src/suggest/core/dicnode/internal/dic_node_state_output.h
@@ -18,8 +18,8 @@
 #define LATINIME_DIC_NODE_STATE_OUTPUT_H
 
 #include <algorithm>
+#include <cstdint>
 #include <cstring> // for memmove()
-#include <stdint.h>
 
 #include "defines.h"
 
diff --git a/native/jni/src/suggest/core/dicnode/internal/dic_node_state_scoring.h b/native/jni/src/suggest/core/dicnode/internal/dic_node_state_scoring.h
index f164edb..c19d48e 100644
--- a/native/jni/src/suggest/core/dicnode/internal/dic_node_state_scoring.h
+++ b/native/jni/src/suggest/core/dicnode/internal/dic_node_state_scoring.h
@@ -18,7 +18,7 @@
 #define LATINIME_DIC_NODE_STATE_SCORING_H
 
 #include <algorithm>
-#include <stdint.h>
+#include <cstdint>
 
 #include "defines.h"
 #include "suggest/core/dictionary/digraph_utils.h"
diff --git a/native/jni/src/suggest/core/dictionary/bloom_filter.h b/native/jni/src/suggest/core/dictionary/bloom_filter.h
index e22c3ae..85b8fc3 100644
--- a/native/jni/src/suggest/core/dictionary/bloom_filter.h
+++ b/native/jni/src/suggest/core/dictionary/bloom_filter.h
@@ -17,8 +17,8 @@
 #ifndef LATINIME_BLOOM_FILTER_H
 #define LATINIME_BLOOM_FILTER_H
 
+#include <cstdint>
 #include <cstring>
-#include <stdint.h>
 
 #include "defines.h"
 
diff --git a/native/jni/src/suggest/core/dictionary/dictionary.cpp b/native/jni/src/suggest/core/dictionary/dictionary.cpp
index ef7a0a8..8445da3 100644
--- a/native/jni/src/suggest/core/dictionary/dictionary.cpp
+++ b/native/jni/src/suggest/core/dictionary/dictionary.cpp
@@ -18,8 +18,6 @@
 
 #include "suggest/core/dictionary/dictionary.h"
 
-#include <stdint.h>
-
 #include "defines.h"
 #include "suggest/core/policy/dictionary_header_structure_policy.h"
 #include "suggest/core/result/suggestion_results.h"
diff --git a/native/jni/src/suggest/core/dictionary/dictionary.h b/native/jni/src/suggest/core/dictionary/dictionary.h
index cd983b0..6b77565 100644
--- a/native/jni/src/suggest/core/dictionary/dictionary.h
+++ b/native/jni/src/suggest/core/dictionary/dictionary.h
@@ -17,13 +17,12 @@
 #ifndef LATINIME_DICTIONARY_H
 #define LATINIME_DICTIONARY_H
 
-#include <stdint.h>
 #include <memory>
 
 #include "defines.h"
 #include "jni.h"
 #include "suggest/core/dictionary/bigram_dictionary.h"
-#include "suggest/core/dictionary/word_property.h"
+#include "suggest/core/dictionary/property/word_property.h"
 #include "suggest/core/policy/dictionary_header_structure_policy.h"
 #include "suggest/core/policy/dictionary_structure_with_buffer_policy.h"
 #include "suggest/core/suggest_interface.h"
diff --git a/native/jni/src/suggest/core/dictionary/error_type_utils.h b/native/jni/src/suggest/core/dictionary/error_type_utils.h
index cc77867..0e8e5b6 100644
--- a/native/jni/src/suggest/core/dictionary/error_type_utils.h
+++ b/native/jni/src/suggest/core/dictionary/error_type_utils.h
@@ -17,7 +17,7 @@
 #ifndef LATINIME_ERROR_TYPE_UTILS_H
 #define LATINIME_ERROR_TYPE_UTILS_H
 
-#include <stdint.h>
+#include <cstdint>
 
 #include "defines.h"
 
diff --git a/native/jni/src/suggest/core/dictionary/property/bigram_property.h b/native/jni/src/suggest/core/dictionary/property/bigram_property.h
new file mode 100644
index 0000000..8d3429b
--- /dev/null
+++ b/native/jni/src/suggest/core/dictionary/property/bigram_property.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef LATINIME_BIGRAM_PROPERTY_H
+#define LATINIME_BIGRAM_PROPERTY_H
+
+#include <vector>
+
+#include "defines.h"
+
+namespace latinime {
+
+class BigramProperty {
+ public:
+    BigramProperty(const std::vector<int> *const targetCodePoints,
+            const int probability, const int timestamp, const int level, const int count)
+            : mTargetCodePoints(*targetCodePoints), mProbability(probability),
+              mTimestamp(timestamp), mLevel(level), mCount(count) {}
+
+    const std::vector<int> *getTargetCodePoints() const {
+        return &mTargetCodePoints;
+    }
+
+    int getProbability() const {
+        return mProbability;
+    }
+
+    int getTimestamp() const {
+        return mTimestamp;
+    }
+
+    int getLevel() const {
+        return mLevel;
+    }
+
+    int getCount() const {
+        return mCount;
+    }
+
+ private:
+    // Default copy constructor and assign operator are used for using in std::vector.
+    DISALLOW_DEFAULT_CONSTRUCTOR(BigramProperty);
+
+    // TODO: Make members const.
+    std::vector<int> mTargetCodePoints;
+    int mProbability;
+    int mTimestamp;
+    int mLevel;
+    int mCount;
+};
+} // namespace latinime
+#endif // LATINIME_WORD_PROPERTY_H
diff --git a/native/jni/src/suggest/core/dictionary/property/unigram_property.h b/native/jni/src/suggest/core/dictionary/property/unigram_property.h
new file mode 100644
index 0000000..d255105
--- /dev/null
+++ b/native/jni/src/suggest/core/dictionary/property/unigram_property.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef LATINIME_UNIGRAM_PROPERTY_H
+#define LATINIME_UNIGRAM_PROPERTY_H
+
+#include <vector>
+
+#include "defines.h"
+
+namespace latinime {
+
+class UnigramProperty {
+ public:
+    class ShortcutProperty {
+     public:
+        ShortcutProperty(const std::vector<int> *const targetCodePoints, const int probability)
+                : mTargetCodePoints(*targetCodePoints), mProbability(probability) {}
+
+        const std::vector<int> *getTargetCodePoints() const {
+            return &mTargetCodePoints;
+        }
+
+        int getProbability() const {
+            return mProbability;
+        }
+
+     private:
+        // Default copy constructor and assign operator are used for using in std::vector.
+        DISALLOW_DEFAULT_CONSTRUCTOR(ShortcutProperty);
+
+        // TODO: Make members const.
+        std::vector<int> mTargetCodePoints;
+        int mProbability;
+    };
+
+    UnigramProperty()
+            : mIsNotAWord(false), mIsBlacklisted(false), mProbability(NOT_A_PROBABILITY),
+              mTimestamp(NOT_A_TIMESTAMP), mLevel(0), mCount(0), mShortcuts() {}
+
+    UnigramProperty(const bool isNotAWord, const bool isBlacklisted, const int probability,
+            const int timestamp, const int level, const int count,
+            const std::vector<ShortcutProperty> *const shortcuts)
+            : mIsNotAWord(isNotAWord), mIsBlacklisted(isBlacklisted), mProbability(probability),
+              mTimestamp(timestamp), mLevel(level), mCount(count), mShortcuts(*shortcuts) {}
+
+    bool isNotAWord() const {
+        return mIsNotAWord;
+    }
+
+    bool isBlacklisted() const {
+        return mIsBlacklisted;
+    }
+
+    bool hasShortcuts() const {
+        return !mShortcuts.empty();
+    }
+
+    int getProbability() const {
+        return mProbability;
+    }
+
+    int getTimestamp() const {
+        return mTimestamp;
+    }
+
+    int getLevel() const {
+        return mLevel;
+    }
+
+    int getCount() const {
+        return mCount;
+    }
+
+    const std::vector<ShortcutProperty> &getShortcuts() const {
+        return mShortcuts;
+    }
+
+ private:
+    // Default copy constructor is used for using as a return value.
+    DISALLOW_ASSIGNMENT_OPERATOR(UnigramProperty);
+
+    // TODO: Make members const.
+    bool mIsNotAWord;
+    bool mIsBlacklisted;
+    int mProbability;
+    // Historical information
+    int mTimestamp;
+    int mLevel;
+    int mCount;
+    std::vector<ShortcutProperty> mShortcuts;
+};
+} // namespace latinime
+#endif // LATINIME_UNIGRAM_PROPERTY_H
diff --git a/native/jni/src/suggest/core/dictionary/word_property.cpp b/native/jni/src/suggest/core/dictionary/property/word_property.cpp
similarity index 75%
rename from native/jni/src/suggest/core/dictionary/word_property.cpp
rename to native/jni/src/suggest/core/dictionary/property/word_property.cpp
index 4733118..95608dc 100644
--- a/native/jni/src/suggest/core/dictionary/word_property.cpp
+++ b/native/jni/src/suggest/core/dictionary/property/word_property.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "suggest/core/dictionary/word_property.h"
+#include "suggest/core/dictionary/property/word_property.h"
 
 namespace latinime {
 
@@ -23,9 +23,12 @@
         jobject outBigramProbabilities, jobject outShortcutTargets,
         jobject outShortcutProbabilities) const {
     env->SetIntArrayRegion(outCodePoints, 0 /* start */, mCodePoints.size(), &mCodePoints[0]);
-    jboolean flags[] = {mIsNotAWord, mIsBlacklisted, mHasBigrams, mHasShortcuts};
+
+    jboolean flags[] = {mUnigramProperty.isNotAWord(), mUnigramProperty.isBlacklisted(),
+            !mBigrams.empty(), mUnigramProperty.hasShortcuts()};
     env->SetBooleanArrayRegion(outFlags, 0 /* start */, NELEMS(flags), flags);
-    int probabilityInfo[] = {mProbability, mTimestamp, mLevel, mCount};
+    int probabilityInfo[] = {mUnigramProperty.getProbability(), mUnigramProperty.getTimestamp(),
+            mUnigramProperty.getLevel(), mUnigramProperty.getCount()};
     env->SetIntArrayRegion(outProbabilityInfo, 0 /* start */, NELEMS(probabilityInfo),
             probabilityInfo);
 
@@ -35,19 +38,17 @@
     jmethodID addMethodId = env->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z");
 
     // Output bigrams.
-    const int bigramCount = mBigrams.size();
-    for (int i = 0; i < bigramCount; ++i) {
-        const BigramProperty *const bigramProperty = &mBigrams[i];
-        const std::vector<int> *const word1CodePoints = bigramProperty->getTargetCodePoints();
+    for (const auto &bigramProperty : mBigrams) {
+        const std::vector<int> *const word1CodePoints = bigramProperty.getTargetCodePoints();
         jintArray bigramWord1CodePointArray = env->NewIntArray(word1CodePoints->size());
         env->SetIntArrayRegion(bigramWord1CodePointArray, 0 /* start */,
-                word1CodePoints->size(), &word1CodePoints->at(0));
+                word1CodePoints->size(), word1CodePoints->data());
         env->CallBooleanMethod(outBigramTargets, addMethodId, bigramWord1CodePointArray);
         env->DeleteLocalRef(bigramWord1CodePointArray);
 
-        int bigramProbabilityInfo[] = {bigramProperty->getProbability(),
-                bigramProperty->getTimestamp(), bigramProperty->getLevel(),
-                bigramProperty->getCount()};
+        int bigramProbabilityInfo[] = {bigramProperty.getProbability(),
+                bigramProperty.getTimestamp(), bigramProperty.getLevel(),
+                bigramProperty.getCount()};
         jintArray bigramProbabilityInfoArray = env->NewIntArray(NELEMS(bigramProbabilityInfo));
         env->SetIntArrayRegion(bigramProbabilityInfoArray, 0 /* start */,
                 NELEMS(bigramProbabilityInfo), bigramProbabilityInfo);
@@ -56,16 +57,15 @@
     }
 
     // Output shortcuts.
-    const int shortcutTargetCount = mShortcuts.size();
-    for (int i = 0; i < shortcutTargetCount; ++i) {
-        const std::vector<int> *const targetCodePoints = mShortcuts[i].getTargetCodePoints();
+    for (const auto &shortcut : mUnigramProperty.getShortcuts()) {
+        const std::vector<int> *const targetCodePoints = shortcut.getTargetCodePoints();
         jintArray shortcutTargetCodePointArray = env->NewIntArray(targetCodePoints->size());
         env->SetIntArrayRegion(shortcutTargetCodePointArray, 0 /* start */,
-                targetCodePoints->size(), &targetCodePoints->at(0));
+                targetCodePoints->size(), targetCodePoints->data());
         env->CallBooleanMethod(outShortcutTargets, addMethodId, shortcutTargetCodePointArray);
         env->DeleteLocalRef(shortcutTargetCodePointArray);
         jobject integerProbability = env->NewObject(integerClass, intToIntegerConstructorId,
-                mShortcuts[i].getProbability());
+                shortcut.getProbability());
         env->CallBooleanMethod(outShortcutProbabilities, addMethodId, integerProbability);
         env->DeleteLocalRef(integerProbability);
     }
diff --git a/native/jni/src/suggest/core/dictionary/property/word_property.h b/native/jni/src/suggest/core/dictionary/property/word_property.h
new file mode 100644
index 0000000..5519a91
--- /dev/null
+++ b/native/jni/src/suggest/core/dictionary/property/word_property.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef LATINIME_WORD_PROPERTY_H
+#define LATINIME_WORD_PROPERTY_H
+
+#include <vector>
+
+#include "defines.h"
+#include "jni.h"
+#include "suggest/core/dictionary/property/bigram_property.h"
+#include "suggest/core/dictionary/property/unigram_property.h"
+
+namespace latinime {
+
+// This class is used for returning information belonging to a word to java side.
+class WordProperty {
+ public:
+    // Default constructor is used to create an instance that indicates an invalid word.
+    WordProperty()
+            : mCodePoints(), mUnigramProperty(), mBigrams() {}
+
+    WordProperty(const std::vector<int> *const codePoints,
+            const UnigramProperty *const unigramProperty,
+            const std::vector<BigramProperty> *const bigrams)
+            : mCodePoints(*codePoints), mUnigramProperty(*unigramProperty), mBigrams(*bigrams) {}
+
+    void outputProperties(JNIEnv *const env, jintArray outCodePoints, jbooleanArray outFlags,
+            jintArray outProbabilityInfo, jobject outBigramTargets, jobject outBigramProbabilities,
+            jobject outShortcutTargets, jobject outShortcutProbabilities) const;
+
+ private:
+    // Default copy constructor is used for using as a return value.
+    DISALLOW_ASSIGNMENT_OPERATOR(WordProperty);
+
+    const std::vector<int> mCodePoints;
+    const UnigramProperty mUnigramProperty;
+    const std::vector<BigramProperty> mBigrams;
+};
+} // namespace latinime
+#endif // LATINIME_WORD_PROPERTY_H
diff --git a/native/jni/src/suggest/core/dictionary/word_property.h b/native/jni/src/suggest/core/dictionary/word_property.h
deleted file mode 100644
index 40b1a91..0000000
--- a/native/jni/src/suggest/core/dictionary/word_property.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef LATINIME_WORD_PROPERTY_H
-#define LATINIME_WORD_PROPERTY_H
-
-#include <cstring>
-#include <vector>
-
-#include "defines.h"
-#include "jni.h"
-
-namespace latinime {
-
-// This class is used for returning information belonging to a word to java side.
-class WordProperty {
- public:
-    class BigramProperty {
-     public:
-        BigramProperty(const std::vector<int> *const targetCodePoints,
-                const int probability, const int timestamp, const int level, const int count)
-                : mTargetCodePoints(*targetCodePoints), mProbability(probability),
-                  mTimestamp(timestamp), mLevel(level), mCount(count) {}
-
-        const std::vector<int> *getTargetCodePoints() const {
-            return &mTargetCodePoints;
-        }
-
-        int getProbability() const {
-            return mProbability;
-        }
-
-        int getTimestamp() const {
-            return mTimestamp;
-        }
-
-        int getLevel() const {
-            return mLevel;
-        }
-
-        int getCount() const {
-            return mCount;
-        }
-
-     private:
-        std::vector<int> mTargetCodePoints;
-        int mProbability;
-        int mTimestamp;
-        int mLevel;
-        int mCount;
-    };
-
-    class ShortcutProperty {
-     public:
-        ShortcutProperty(const std::vector<int> *const targetCodePoints, const int probability)
-                : mTargetCodePoints(*targetCodePoints), mProbability(probability) {}
-
-        const std::vector<int> *getTargetCodePoints() const {
-            return &mTargetCodePoints;
-        }
-
-        int getProbability() const {
-            return mProbability;
-        }
-
-     private:
-        std::vector<int> mTargetCodePoints;
-        int mProbability;
-    };
-
-    // Invalid word.
-    WordProperty()
-            : mCodePoints(), mIsNotAWord(false), mIsBlacklisted(false),
-              mHasBigrams(false), mHasShortcuts(false), mProbability(NOT_A_PROBABILITY),
-              mTimestamp(0), mLevel(0), mCount(0), mBigrams(), mShortcuts() {}
-
-    WordProperty(const std::vector<int> *const codePoints,
-            const bool isNotAWord, const bool isBlacklisted, const bool hasBigrams,
-            const bool hasShortcuts, const int probability, const int timestamp,
-            const int level, const int count, const std::vector<BigramProperty> *const bigrams,
-            const std::vector<ShortcutProperty> *const shortcuts)
-            : mCodePoints(*codePoints), mIsNotAWord(isNotAWord), mIsBlacklisted(isBlacklisted),
-              mHasBigrams(hasBigrams), mHasShortcuts(hasShortcuts), mProbability(probability),
-              mTimestamp(timestamp), mLevel(level), mCount(count), mBigrams(*bigrams),
-              mShortcuts(*shortcuts) {}
-
-    void outputProperties(JNIEnv *const env, jintArray outCodePoints, jbooleanArray outFlags,
-            jintArray outProbabilityInfo, jobject outBigramTargets, jobject outBigramProbabilities,
-            jobject outShortcutTargets, jobject outShortcutProbabilities) const;
-
- private:
-    DISALLOW_ASSIGNMENT_OPERATOR(WordProperty);
-
-    std::vector<int> mCodePoints;
-    bool mIsNotAWord;
-    bool mIsBlacklisted;
-    bool mHasBigrams;
-    bool mHasShortcuts;
-    int mProbability;
-    // Historical information
-    int mTimestamp;
-    int mLevel;
-    int mCount;
-    std::vector<BigramProperty> mBigrams;
-    std::vector<ShortcutProperty> mShortcuts;
-};
-} // namespace latinime
-#endif // LATINIME_WORD_PROPERTY_H
diff --git a/native/jni/src/suggest/core/layout/normal_distribution.h b/native/jni/src/suggest/core/layout/normal_distribution.h
new file mode 100644
index 0000000..5f21a59
--- /dev/null
+++ b/native/jni/src/suggest/core/layout/normal_distribution.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef LATINIME_NORMAL_DISTRIBUTION_H
+#define LATINIME_NORMAL_DISTRIBUTION_H
+
+#include <cmath>
+
+#include "defines.h"
+
+namespace latinime {
+
+// Normal distribution N(u, sigma^2).
+class NormalDistribution {
+ public:
+    NormalDistribution(const float u, const float sigma)
+            : mU(u),
+              mPreComputedNonExpPart(1.0f / sqrtf(2.0f * M_PI_F
+                      * GeometryUtils::SQUARE_FLOAT(sigma))),
+              mPreComputedExponentPart(-1.0f / (2.0f * GeometryUtils::SQUARE_FLOAT(sigma))) {}
+
+    float getProbabilityDensity(const float x) const {
+        const float shiftedX = x - mU;
+        return mPreComputedNonExpPart
+                * expf(mPreComputedExponentPart * GeometryUtils::SQUARE_FLOAT(shiftedX));
+    }
+
+ private:
+    DISALLOW_IMPLICIT_CONSTRUCTORS(NormalDistribution);
+
+    const float mU; // mean value
+    const float mPreComputedNonExpPart; // = 1 / sqrt(2 * PI * sigma^2)
+    const float mPreComputedExponentPart; // = -1 / (2 * sigma^2)
+};
+} // namespace latinime
+#endif // LATINIME_NORMAL_DISTRIBUTION_H
diff --git a/native/jni/src/suggest/core/layout/proximity_info_state_utils.cpp b/native/jni/src/suggest/core/layout/proximity_info_state_utils.cpp
index 867f598..5a3ff73 100644
--- a/native/jni/src/suggest/core/layout/proximity_info_state_utils.cpp
+++ b/native/jni/src/suggest/core/layout/proximity_info_state_utils.cpp
@@ -24,6 +24,7 @@
 
 #include "defines.h"
 #include "suggest/core/layout/geometry_utils.h"
+#include "suggest/core/layout/normal_distribution.h"
 #include "suggest/core/layout/proximity_info.h"
 #include "suggest/core/layout/proximity_info_params.h"
 
@@ -717,8 +718,8 @@
         const float sigma = speedxAngleRate + speedxNearestKeyDistanceRate
                 + ProximityInfoParams::MIN_STANDARD_DEVIATION;
 
-        ProximityInfoUtils::NormalDistribution
-                distribution(ProximityInfoParams::CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION, sigma);
+        NormalDistribution distribution(
+                ProximityInfoParams::CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION, sigma);
         // Summing up probability densities of all near keys.
         float sumOfProbabilityDensities = 0.0f;
         for (int j = 0; j < keyCount; ++j) {
diff --git a/native/jni/src/suggest/core/layout/proximity_info_utils.h b/native/jni/src/suggest/core/layout/proximity_info_utils.h
index 310bbdb..c273ef4 100644
--- a/native/jni/src/suggest/core/layout/proximity_info_utils.h
+++ b/native/jni/src/suggest/core/layout/proximity_info_utils.h
@@ -125,28 +125,6 @@
          return type == MATCH_CHAR || type == PROXIMITY_CHAR || type == ADDITIONAL_PROXIMITY_CHAR;
      }
 
-    // Normal distribution N(u, sigma^2).
-    struct NormalDistribution {
-     public:
-        NormalDistribution(const float u, const float sigma)
-                : mU(u),
-                  mPreComputedNonExpPart(1.0f / sqrtf(2.0f * M_PI_F
-                          * GeometryUtils::SQUARE_FLOAT(sigma))),
-                  mPreComputedExponentPart(-1.0f / (2.0f * GeometryUtils::SQUARE_FLOAT(sigma))) {}
-
-        float getProbabilityDensity(const float x) const {
-            const float shiftedX = x - mU;
-            return mPreComputedNonExpPart
-                    * expf(mPreComputedExponentPart * GeometryUtils::SQUARE_FLOAT(shiftedX));
-        }
-
-     private:
-        DISALLOW_IMPLICIT_CONSTRUCTORS(NormalDistribution);
-        const float mU; // mean value
-        const float mPreComputedNonExpPart; // = 1 / sqrt(2 * PI * sigma^2)
-        const float mPreComputedExponentPart; // = -1 / (2 * sigma^2)
-    }; // struct NormalDistribution
-
  private:
     DISALLOW_IMPLICIT_CONSTRUCTORS(ProximityInfoUtils);
 
diff --git a/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h b/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h
index b6dc7d0..ae2e7a8 100644
--- a/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h
+++ b/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h
@@ -20,7 +20,7 @@
 #include <memory>
 
 #include "defines.h"
-#include "suggest/core/dictionary/word_property.h"
+#include "suggest/core/dictionary/property/word_property.h"
 
 namespace latinime {
 
diff --git a/native/jni/src/suggest/core/session/dic_traverse_session.h b/native/jni/src/suggest/core/session/dic_traverse_session.h
index 9e5d902..843ca85 100644
--- a/native/jni/src/suggest/core/session/dic_traverse_session.h
+++ b/native/jni/src/suggest/core/session/dic_traverse_session.h
@@ -17,7 +17,6 @@
 #ifndef LATINIME_DIC_TRAVERSE_SESSION_H
 #define LATINIME_DIC_TRAVERSE_SESSION_H
 
-#include <stdint.h>
 #include <vector>
 
 #include "defines.h"
diff --git a/native/jni/src/suggest/policyimpl/dictionary/bigram/bigram_list_policy.h b/native/jni/src/suggest/policyimpl/dictionary/bigram/bigram_list_policy.h
index 6ff95ca..a898e2a 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/bigram/bigram_list_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/bigram/bigram_list_policy.h
@@ -17,7 +17,7 @@
 #ifndef LATINIME_BIGRAM_LIST_POLICY_H
 #define LATINIME_BIGRAM_LIST_POLICY_H
 
-#include <stdint.h>
+#include <cstdint>
 
 #include "defines.h"
 #include "suggest/core/policy/dictionary_bigrams_structure_policy.h"
diff --git a/native/jni/src/suggest/policyimpl/dictionary/bigram/bigram_list_read_write_utils.h b/native/jni/src/suggest/policyimpl/dictionary/bigram/bigram_list_read_write_utils.h
index 7e10383..15f924a 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/bigram/bigram_list_read_write_utils.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/bigram/bigram_list_read_write_utils.h
@@ -17,8 +17,8 @@
 #ifndef LATINIME_BIGRAM_LIST_READ_WRITE_UTILS_H
 #define LATINIME_BIGRAM_LIST_READ_WRITE_UTILS_H
 
+#include <cstdint>
 #include <cstdlib>
-#include <stdint.h>
 
 #include "defines.h"
 
diff --git a/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.h b/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.h
index 6682424..f950cad 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.h
@@ -17,7 +17,7 @@
 #ifndef LATINIME_HEADER_POLICY_H
 #define LATINIME_HEADER_POLICY_H
 
-#include <stdint.h>
+#include <cstdint>
 
 #include "defines.h"
 #include "suggest/core/policy/dictionary_header_structure_policy.h"
diff --git a/native/jni/src/suggest/policyimpl/dictionary/header/header_read_write_utils.h b/native/jni/src/suggest/policyimpl/dictionary/header/header_read_write_utils.h
index 4185a2e..a6b4c4e 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/header/header_read_write_utils.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/header/header_read_write_utils.h
@@ -17,7 +17,7 @@
 #ifndef LATINIME_HEADER_READ_WRITE_UTILS_H
 #define LATINIME_HEADER_READ_WRITE_UTILS_H
 
-#include <stdint.h>
+#include <cstdint>
 
 #include "defines.h"
 #include "suggest/core/policy/dictionary_header_structure_policy.h"
diff --git a/native/jni/src/suggest/policyimpl/dictionary/shortcut/shortcut_list_policy.h b/native/jni/src/suggest/policyimpl/dictionary/shortcut/shortcut_list_policy.h
index d73f739..6d2b477 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/shortcut/shortcut_list_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/shortcut/shortcut_list_policy.h
@@ -17,7 +17,7 @@
 #ifndef LATINIME_SHORTCUT_LIST_POLICY_H
 #define LATINIME_SHORTCUT_LIST_POLICY_H
 
-#include <stdint.h>
+#include <cstdint>
 
 #include "defines.h"
 #include "suggest/core/policy/dictionary_shortcuts_structure_policy.h"
diff --git a/native/jni/src/suggest/policyimpl/dictionary/shortcut/shortcut_list_reading_utils.h b/native/jni/src/suggest/policyimpl/dictionary/shortcut/shortcut_list_reading_utils.h
index a83ed5a..d065bf7 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/shortcut/shortcut_list_reading_utils.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/shortcut/shortcut_list_reading_utils.h
@@ -17,7 +17,7 @@
 #ifndef LATINIME_SHORTCUT_LIST_READING_UTILS_H
 #define LATINIME_SHORTCUT_LIST_READING_UTILS_H
 
-#include <stdint.h>
+#include <cstdint>
 
 #include "defines.h"
 
diff --git a/native/jni/src/suggest/policyimpl/dictionary/shortcut/ver4_shortcut_list_policy.h b/native/jni/src/suggest/policyimpl/dictionary/shortcut/ver4_shortcut_list_policy.h
index f2fa5b7..fe98461 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/shortcut/ver4_shortcut_list_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/shortcut/ver4_shortcut_list_policy.h
@@ -17,8 +17,6 @@
 #ifndef LATINIME_VER4_SHORTCUT_LIST_POLICY_H
 #define LATINIME_VER4_SHORTCUT_LIST_POLICY_H
 
-#include <stdint.h>
-
 #include "defines.h"
 #include "suggest/core/policy/dictionary_shortcuts_structure_policy.h"
 #include "suggest/policyimpl/dictionary/shortcut/shortcut_list_reading_utils.h"
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.cpp
index 79bcf6f..5f19534 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.cpp
@@ -17,7 +17,6 @@
 #include "suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.h"
 
 #include <climits>
-#include <stdint.h>
 
 #include "defines.h"
 #include "suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h"
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.h b/native/jni/src/suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.h
index 9454ddf..6053b7e 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.h
@@ -17,8 +17,6 @@
 #ifndef LATINIME_DICTIONARY_STRUCTURE_WITH_BUFFER_POLICY_FACTORY_H
 #define LATINIME_DICTIONARY_STRUCTURE_WITH_BUFFER_POLICY_FACTORY_H
 
-#include <stdint.h>
-
 #include "defines.h"
 #include "suggest/core/policy/dictionary_structure_with_buffer_policy.h"
 
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_reading_utils.h b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_reading_utils.h
index 89ae12c..b13a075 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_reading_utils.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_reading_utils.h
@@ -17,7 +17,7 @@
 #ifndef LATINIME_DYNAMIC_PT_READING_UTILS_H
 #define LATINIME_DYNAMIC_PT_READING_UTILS_H
 
-#include <stdint.h>
+#include <cstdint>
 
 #include "defines.h"
 
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.h b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.h
index 71f4730..f703baf 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.h
@@ -17,8 +17,6 @@
 #ifndef LATINIME_DYNAMIC_PT_UPDATING_HELPER_H
 #define LATINIME_DYNAMIC_PT_UPDATING_HELPER_H
 
-#include <stdint.h>
-
 #include "defines.h"
 #include "suggest/policyimpl/dictionary/structure/pt_common/pt_node_params.h"
 #include "utils/hash_map_compat.h"
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_writing_utils.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_writing_utils.cpp
index ebbdc2e..664aeeb 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_writing_utils.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_writing_utils.cpp
@@ -17,8 +17,8 @@
 #include "suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_writing_utils.h"
 
 #include <cstddef>
+#include <cstdint>
 #include <cstdlib>
-#include <stdint.h>
 
 #include "suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h"
 
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp
index 4e795f8..b426dbf 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp
@@ -339,7 +339,7 @@
     std::vector<int> codePointVector(ptNodeParams.getCodePoints(),
             ptNodeParams.getCodePoints() + ptNodeParams.getCodePointCount());
     // Fetch bigram information.
-    std::vector<WordProperty::BigramProperty> bigrams;
+    std::vector<BigramProperty> bigrams;
     const int bigramListPos = getBigramsPositionOfPtNode(ptNodePos);
     int bigramWord1CodePoints[MAX_WORD_LENGTH];
     BinaryDictionaryBigramsIterator bigramsIt(getBigramsStructurePolicy(), bigramListPos);
@@ -360,7 +360,7 @@
         }
     }
     // Fetch shortcut information.
-    std::vector<WordProperty::ShortcutProperty> shortcuts;
+    std::vector<UnigramProperty::ShortcutProperty> shortcuts;
     int shortcutPos = getShortcutPositionOfPtNode(ptNodePos);
     if (shortcutPos != NOT_A_DICT_POS) {
         int shortcutTargetCodePoints[MAX_WORD_LENGTH];
@@ -379,11 +379,10 @@
             shortcuts.emplace_back(&shortcutTarget, shortcutProbability);
         }
     }
-    return WordProperty(&codePointVector, ptNodeParams.isNotAWord(),
-            ptNodeParams.isBlacklisted(), ptNodeParams.hasBigrams(),
-            ptNodeParams.hasShortcutTargets(), ptNodeParams.getProbability(),
-            NOT_A_TIMESTAMP /* timestamp */, 0 /* level */, 0 /* count */,
-            &bigrams, &shortcuts);
+    const UnigramProperty unigramProperty(ptNodeParams.isNotAWord(),
+            ptNodeParams.isBlacklisted(), ptNodeParams.getProbability(),
+            NOT_A_TIMESTAMP /* timestamp */, 0 /* level */, 0 /* count */, &shortcuts);
+    return WordProperty(&codePointVector, &unigramProperty, &bigrams);
 }
 
 int PatriciaTriePolicy::getNextWordAndNextToken(const int token, int *const outCodePoints) {
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h
index 11a40de..79500b9 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h
@@ -17,7 +17,7 @@
 #ifndef LATINIME_PATRICIA_TRIE_POLICY_H
 #define LATINIME_PATRICIA_TRIE_POLICY_H
 
-#include <stdint.h>
+#include <cstdint>
 #include <vector>
 
 #include "defines.h"
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_reading_utils.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_reading_utils.h
index fa1430c..a6090a5 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_reading_utils.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_reading_utils.h
@@ -17,7 +17,7 @@
 #ifndef LATINIME_PATRICIA_TRIE_READING_UTILS_H
 #define LATINIME_PATRICIA_TRIE_READING_UTILS_H
 
-#include <stdint.h>
+#include <cstdint>
 
 #include "defines.h"
 
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/ver2_patricia_trie_node_reader.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/ver2_patricia_trie_node_reader.h
index dd1a0da..86fc89c 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/ver2_patricia_trie_node_reader.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/ver2_patricia_trie_node_reader.h
@@ -17,7 +17,7 @@
 #ifndef LATINIME_VER2_PATRICIA_TRIE_NODE_READER_H
 #define LATINIME_VER2_PATRICIA_TRIE_NODE_READER_H
 
-#include <stdint.h>
+#include <cstdint>
 
 #include "defines.h"
 #include "suggest/policyimpl/dictionary/structure/pt_common/pt_node_params.h"
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/ver2_pt_node_array_reader.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/ver2_pt_node_array_reader.h
index 77404ad..5482721 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/ver2_pt_node_array_reader.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/ver2_pt_node_array_reader.h
@@ -17,7 +17,7 @@
 #ifndef LATINIME_VER2_PT_NODE_ARRAY_READER_H
 #define LATINIME_VER2_PT_NODE_ARRAY_READER_H
 
-#include <stdint.h>
+#include <cstdint>
 
 #include "defines.h"
 #include "suggest/policyimpl/dictionary/structure/pt_common/pt_node_array_reader.h"
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.h
index 1db9ea0..f24307e 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.h
@@ -17,8 +17,6 @@
 #ifndef LATINIME_VER4_PATRICIA_TRIE_NODE_READER_H
 #define LATINIME_VER4_PATRICIA_TRIE_NODE_READER_H
 
-#include <stdint.h>
-
 #include "defines.h"
 #include "suggest/policyimpl/dictionary/structure/pt_common/pt_node_params.h"
 #include "suggest/policyimpl/dictionary/structure/pt_common/pt_node_reader.h"
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h
index f01b3af..b2b0504 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h
@@ -17,8 +17,6 @@
 #ifndef LATINIME_VER4_PATRICIA_TRIE_NODE_WRITER_H
 #define LATINIME_VER4_PATRICIA_TRIE_NODE_WRITER_H
 
-#include <stdint.h>
-
 #include "defines.h"
 #include "suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_reading_helper.h"
 #include "suggest/policyimpl/dictionary/structure/pt_common/pt_node_params.h"
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp
index 107ddab..6cf8409 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp
@@ -20,7 +20,9 @@
 
 #include "suggest/core/dicnode/dic_node.h"
 #include "suggest/core/dicnode/dic_node_vector.h"
-#include "suggest/core/dictionary/word_property.h"
+#include "suggest/core/dictionary/property/bigram_property.h"
+#include "suggest/core/dictionary/property/unigram_property.h"
+#include "suggest/core/dictionary/property/word_property.h"
 #include "suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_reading_helper.h"
 #include "suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.h"
 #include "suggest/policyimpl/dictionary/utils/forgetting_curve_utils.h"
@@ -358,7 +360,7 @@
                     ptNodeParams.getTerminalId());
     const HistoricalInfo *const historicalInfo = probabilityEntry.getHistoricalInfo();
     // Fetch bigram information.
-    std::vector<WordProperty::BigramProperty> bigrams;
+    std::vector<BigramProperty> bigrams;
     const int bigramListPos = getBigramsPositionOfPtNode(ptNodePos);
     if (bigramListPos != NOT_A_DICT_POS) {
         int bigramWord1CodePoints[MAX_WORD_LENGTH];
@@ -395,7 +397,7 @@
         }
     }
     // Fetch shortcut information.
-    std::vector<WordProperty::ShortcutProperty> shortcuts;
+    std::vector<UnigramProperty::ShortcutProperty> shortcuts;
     int shortcutPos = getShortcutPositionOfPtNode(ptNodePos);
     if (shortcutPos != NOT_A_DICT_POS) {
         int shortcutTarget[MAX_WORD_LENGTH];
@@ -411,11 +413,11 @@
             shortcuts.emplace_back(&target, shortcutProbability);
         }
     }
-    return WordProperty(&codePointVector, ptNodeParams.isNotAWord(),
-            ptNodeParams.isBlacklisted(), ptNodeParams.hasBigrams(),
-            ptNodeParams.hasShortcutTargets(), ptNodeParams.getProbability(),
+    const UnigramProperty unigramProperty(ptNodeParams.isNotAWord(),
+            ptNodeParams.isBlacklisted(), ptNodeParams.getProbability(),
             historicalInfo->getTimeStamp(), historicalInfo->getLevel(),
-            historicalInfo->getCount(), &bigrams, &shortcuts);
+            historicalInfo->getCount(), &shortcuts);
+    return WordProperty(&codePointVector, &unigramProperty, &bigrams);
 }
 
 int Ver4PatriciaTriePolicy::getNextWordAndNextToken(const int token, int *const outCodePoints) {
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_reading_utils.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_reading_utils.h
index e418c49..466ff55 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_reading_utils.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_reading_utils.h
@@ -17,7 +17,7 @@
 #ifndef LATINIME_VER4_PATRICIA_TRIE_READING_UTILS_H
 #define LATINIME_VER4_PATRICIA_TRIE_READING_UTILS_H
 
-#include <stdint.h>
+#include <cstdint>
 
 #include "defines.h"
 
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h b/native/jni/src/suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h
index 76be165..23cbe3a 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h
@@ -18,7 +18,7 @@
 #define LATINIME_BUFFER_WITH_EXTENDABLE_BUFFER_H
 
 #include <cstddef>
-#include <stdint.h>
+#include <cstdint>
 #include <vector>
 
 #include "defines.h"
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/byte_array_utils.h b/native/jni/src/suggest/policyimpl/dictionary/utils/byte_array_utils.h
index ebdd523..c0a9fcb 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/byte_array_utils.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/byte_array_utils.h
@@ -17,7 +17,7 @@
 #ifndef LATINIME_BYTE_ARRAY_UTILS_H
 #define LATINIME_BYTE_ARRAY_UTILS_H
 
-#include <stdint.h>
+#include <cstdint>
 
 #include "defines.h"
 
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/format_utils.h b/native/jni/src/suggest/policyimpl/dictionary/utils/format_utils.h
index 7c6a21d..759b1c9 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/format_utils.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/format_utils.h
@@ -17,7 +17,7 @@
 #ifndef LATINIME_FORMAT_UTILS_H
 #define LATINIME_FORMAT_UTILS_H
 
-#include <stdint.h>
+#include <cstdint>
 
 #include "defines.h"
 
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/mmapped_buffer.h b/native/jni/src/suggest/policyimpl/dictionary/utils/mmapped_buffer.h
index f73716c..8460087 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/mmapped_buffer.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/mmapped_buffer.h
@@ -17,8 +17,8 @@
 #ifndef LATINIME_MMAPPED_BUFFER_H
 #define LATINIME_MMAPPED_BUFFER_H
 
+#include <cstdint>
 #include <memory>
-#include <stdint.h>
 
 #include "defines.h"
 
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/probability_utils.h b/native/jni/src/suggest/policyimpl/dictionary/utils/probability_utils.h
index 14fdf53..3b339e6 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/probability_utils.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/probability_utils.h
@@ -17,8 +17,6 @@
 #ifndef LATINIME_PROBABILITY_UTILS_H
 #define LATINIME_PROBABILITY_UTILS_H
 
-#include <stdint.h>
-
 #include "defines.h"
 
 namespace latinime {
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/sparse_table.h b/native/jni/src/suggest/policyimpl/dictionary/utils/sparse_table.h
index 21c1675..fca8120 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/sparse_table.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/sparse_table.h
@@ -17,7 +17,7 @@
 #ifndef LATINIME_SPARSE_TABLE_H
 #define LATINIME_SPARSE_TABLE_H
 
-#include <stdint.h>
+#include <cstdint>
 
 #include "defines.h"
 #include "suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h"
diff --git a/native/jni/src/suggest/policyimpl/typing/typing_traversal.h b/native/jni/src/suggest/policyimpl/typing/typing_traversal.h
index 7c86b7d..5ba8bfa 100644
--- a/native/jni/src/suggest/policyimpl/typing/typing_traversal.h
+++ b/native/jni/src/suggest/policyimpl/typing/typing_traversal.h
@@ -17,7 +17,7 @@
 #ifndef LATINIME_TYPING_TRAVERSAL_H
 #define LATINIME_TYPING_TRAVERSAL_H
 
-#include <stdint.h>
+#include <cstdint>
 
 #include "defines.h"
 #include "suggest/core/dicnode/dic_node.h"
diff --git a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetSubtypesCountTests.java b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetSubtypesCountTests.java
index bbffc8d..d6d12ea 100644
--- a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetSubtypesCountTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetSubtypesCountTests.java
@@ -25,7 +25,7 @@
 
 @SmallTest
 public class KeyboardLayoutSetSubtypesCountTests extends KeyboardLayoutSetTestsBase {
-    private static final int NUMBER_OF_SUBTYPES = 66;
+    private static final int NUMBER_OF_SUBTYPES = 67;
     private static final int NUMBER_OF_ASCII_CAPABLE_SUBTYPES = 42;
     private static final int NUMBER_OF_PREDEFINED_ADDITIONAL_SUBTYPES = 2;
 
diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTests.java b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
index b366452..d2dd292 100644
--- a/tests/src/com/android/inputmethod/latin/InputLogicTests.java
+++ b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
@@ -16,7 +16,10 @@
 
 package com.android.inputmethod.latin;
 
+import com.android.inputmethod.latin.settings.Settings;
+
 import android.test.suitebuilder.annotation.LargeTest;
+import android.text.TextUtils;
 import android.view.inputmethod.BaseInputConnection;
 
 @LargeTest
@@ -179,6 +182,8 @@
     }
 
     public void testDoubleSpace() {
+        // Set default pref just in case
+        setBooleanPreference(Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, true, true);
         // U+1F607 is an emoji
         final String[] STRINGS_TO_TYPE =
                 new String[] { "this   ", "a+  ", "\u1F607  ", "..  ", ")  ", "(  ", "%  " };
@@ -200,6 +205,76 @@
         assertEquals("double space make a period", EXPECTED_RESULT, mEditText.getText().toString());
     }
 
+    private void testDoubleSpacePeriodWithSettings(final boolean expectsPeriod,
+            final Object... settingsKeysValues) {
+        final Object[] oldSettings = new Object[settingsKeysValues.length / 2];
+        final String STRING_WITHOUT_PERIOD = "this  ";
+        final String STRING_WITH_PERIOD = "this. ";
+        final String EXPECTED_RESULT = expectsPeriod ? STRING_WITH_PERIOD : STRING_WITHOUT_PERIOD;
+        try {
+            for (int i = 0; i < settingsKeysValues.length; i += 2) {
+                if (settingsKeysValues[i + 1] instanceof String) {
+                    oldSettings[i / 2] = setStringPreference((String)settingsKeysValues[i],
+                            (String)settingsKeysValues[i + 1], "0");
+                } else {
+                    oldSettings[i / 2] = setBooleanPreference((String)settingsKeysValues[i],
+                            (Boolean)settingsKeysValues[i + 1], false);
+                }
+            }
+            mLatinIME.loadSettings();
+            mEditText.setText("");
+            type(STRING_WITHOUT_PERIOD);
+            assertEquals("double-space-to-period with specific settings "
+                    + TextUtils.join(" ", settingsKeysValues),
+                    EXPECTED_RESULT, mEditText.getText().toString());
+        } finally {
+            // Restore old settings
+            for (int i = 0; i < settingsKeysValues.length; i += 2) {
+                if (null == oldSettings[i / 2]) {
+                    break;
+                } if (oldSettings[i / 2] instanceof String) {
+                    setStringPreference((String)settingsKeysValues[i], (String)oldSettings[i / 2],
+                            "");
+                } else {
+                    setBooleanPreference((String)settingsKeysValues[i], (Boolean)oldSettings[i / 2],
+                            false);
+                }
+            }
+        }
+    }
+
+    public void testDoubleSpacePeriod() {
+        // Reset settings to default, else these tests will go flaky.
+        setStringPreference(Settings.PREF_SHOW_SUGGESTIONS_SETTING, "0", "0");
+        setStringPreference(Settings.PREF_AUTO_CORRECTION_THRESHOLD, "1", "1");
+        setBooleanPreference(Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, true, true);
+        testDoubleSpacePeriodWithSettings(true /* expectsPeriod */);
+        // "Suggestion visibility" to "always hide"
+        testDoubleSpacePeriodWithSettings(true, Settings.PREF_SHOW_SUGGESTIONS_SETTING, "2");
+        // "Suggestion visibility" to "portrait only"
+        testDoubleSpacePeriodWithSettings(true, Settings.PREF_SHOW_SUGGESTIONS_SETTING, "1");
+        // "Suggestion visibility" to "always show"
+        testDoubleSpacePeriodWithSettings(true, Settings.PREF_SHOW_SUGGESTIONS_SETTING, "0");
+
+        // "Double-space period" to "off"
+        testDoubleSpacePeriodWithSettings(false, Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, false);
+
+        // "Auto-correction" to "off"
+        testDoubleSpacePeriodWithSettings(true, Settings.PREF_AUTO_CORRECTION_THRESHOLD, "0");
+        // "Auto-correction" to "modest"
+        testDoubleSpacePeriodWithSettings(true, Settings.PREF_AUTO_CORRECTION_THRESHOLD, "1");
+        // "Auto-correction" to "very aggressive"
+        testDoubleSpacePeriodWithSettings(true, Settings.PREF_AUTO_CORRECTION_THRESHOLD, "3");
+
+        // "Suggestion visibility" to "always hide" and "Auto-correction" to "off"
+        testDoubleSpacePeriodWithSettings(true, Settings.PREF_SHOW_SUGGESTIONS_SETTING, "0",
+                Settings.PREF_AUTO_CORRECTION_THRESHOLD, "0");
+        // "Suggestion visibility" to "always hide" and "Auto-correction" to "off"
+        testDoubleSpacePeriodWithSettings(false, Settings.PREF_SHOW_SUGGESTIONS_SETTING, "0",
+                Settings.PREF_AUTO_CORRECTION_THRESHOLD, "0",
+                Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, false);
+    }
+
     public void testBackspaceAtStartAfterAutocorrect() {
         final String STRING_TO_TYPE = "tgis ";
         final int typedLength = STRING_TO_TYPE.length();
diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
index 690c559..1383ff9 100644
--- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java
+++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
@@ -65,7 +65,6 @@
     protected MyEditText mEditText;
     protected View mInputView;
     protected InputConnection mInputConnection;
-    private boolean mPreviousDebugSetting;
     private boolean mPreviousBigramPredictionSettings;
     private String mPreviousAutoCorrectSetting;
 
@@ -185,7 +184,7 @@
         mEditText.setEnabled(true);
         setupService();
         mLatinIME = getService();
-        mPreviousDebugSetting = setDebugMode(true);
+        setDebugMode(true);
         mPreviousBigramPredictionSettings = setBooleanPreference(Settings.PREF_BIGRAM_PREDICTIONS,
                 true, true /* defaultValue */);
         mPreviousAutoCorrectSetting = setStringPreference(Settings.PREF_AUTO_CORRECTION_THRESHOLD,
@@ -219,7 +218,7 @@
                 true /* defaultValue */);
         setStringPreference(Settings.PREF_AUTO_CORRECTION_THRESHOLD, mPreviousAutoCorrectSetting,
                 DEFAULT_AUTO_CORRECTION_THRESHOLD);
-        setDebugMode(mPreviousDebugSetting);
+        setDebugMode(false);
         super.tearDown();
     }
 
diff --git a/tools/dicttool/Android.mk b/tools/dicttool/Android.mk
index f49dee7..e12d7e0 100644
--- a/tools/dicttool/Android.mk
+++ b/tools/dicttool/Android.mk
@@ -85,7 +85,6 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LATINIME_HOST_NATIVE_LIBNAME)
 LOCAL_JAR_MANIFEST := etc/manifest.txt
 LOCAL_MODULE := dicttool_aosp
-LOCAL_IS_HOST_MODULE := true
 
 include $(BUILD_HOST_JAVA_LIBRARY)
 include $(LOCAL_PATH)/etc/Android.mk
diff --git a/tools/dicttool/NativeLib.mk b/tools/dicttool/NativeLib.mk
index 0d3507b..7403448 100644
--- a/tools/dicttool/NativeLib.mk
+++ b/tools/dicttool/NativeLib.mk
@@ -29,13 +29,7 @@
     LOCAL_CFLAGS += -DFLAG_DBG -funwind-tables -fno-inline
 endif #FLAG_DBG
 
-ifneq ($(strip $(HOST_JDK_IS_64BIT_VERSION)),)
-LOCAL_CFLAGS += -m64
-LOCAL_LDFLAGS += -m64
-endif #HOST_JDK_IS_64BIT_VERSION
-
-LOCAL_CFLAGS += -DHOST_TOOL -fPIC -Wno-deprecated
-LOCAL_NO_DEFAULT_COMPILER_FLAGS := true
+LOCAL_CFLAGS += -DHOST_TOOL -fPIC -Wno-deprecated -Wno-unused-parameter -Wno-unused-function
 
 LOCAL_CLANG := true
 # For C++11
@@ -44,7 +38,6 @@
 LATINIME_NATIVE_JNI_DIR := $(LATINIME_DIR_RELATIVE_TO_DICTTOOL)/native/jni
 LATINIME_NATIVE_SRC_DIR := $(LATINIME_DIR_RELATIVE_TO_DICTTOOL)/native/jni/src
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(LATINIME_NATIVE_SRC_DIR)
-# Used in jni_common.cpp to avoid registering useless methods.
 
 include $(LOCAL_PATH)/$(LATINIME_NATIVE_JNI_DIR)/NativeFileList.mk
 
@@ -53,7 +46,6 @@
     $(addprefix $(LATINIME_NATIVE_SRC_DIR)/, $(LATIN_IME_CORE_SRC_FILES))
 
 LOCAL_MODULE := $(LATINIME_HOST_NATIVE_LIBNAME)
-LOCAL_IS_HOST_MODULE := true
 
 include $(BUILD_HOST_SHARED_LIBRARY)
 
diff --git a/tools/dicttool/etc/dicttool_aosp b/tools/dicttool/etc/dicttool_aosp
index 65a1c3a..09d65c6 100755
--- a/tools/dicttool/etc/dicttool_aosp
+++ b/tools/dicttool/etc/dicttool_aosp
@@ -68,5 +68,14 @@
     libpath="$frameworkdir/$lib"
 fi
 
+# Check if the host Java executable supports a 32-bit JVM. It needs to do because the JNI
+# library is 32-bit.
+${DICTTOOL_JAVA-java} -d32 -version > /dev/null 2>&1
+if [[ $? != 0 ]] ; then
+    echo Please specify a Java executable that supports a 32-bit JVM as DICTTOOL_JAVA.
+    exit 1
+fi
+
 # might need more memory, e.g. -Xmx128M
-exec java -ea -classpath "$libpath":"$jarpath" -Djava.library.path="$libdir" "$classname" "$@"
+exec ${DICTTOOL_JAVA-java} -d32 -ea -classpath "$libpath":"$jarpath" \
+    -Djava.library.path="$libdir" "$classname" "$@"
diff --git a/tools/make-keyboard-text/res/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.tmpl b/tools/make-keyboard-text/res/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.tmpl
index b25bfb2..2b5494f 100644
--- a/tools/make-keyboard-text/res/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.tmpl
+++ b/tools/make-keyboard-text/res/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.tmpl
@@ -19,6 +19,7 @@
 import com.android.inputmethod.latin.utils.CollectionUtils;
 
 import java.util.HashMap;
+import java.util.Locale;
 
 /**
  * !!!!! DO NOT EDIT THIS FILE !!!!!
@@ -44,19 +45,19 @@
 public final class KeyboardTextsTable {
     // Name to index map.
     private static final HashMap<String, Integer> sNameToIndexesMap = CollectionUtils.newHashMap();
-    // Language to texts table map.
-    private static final HashMap<String, String[]> sLanguageToTextsTableMap =
+    // Locale to texts table map.
+    private static final HashMap<String, String[]> sLocaleToTextsTableMap =
             CollectionUtils.newHashMap();
     // TODO: Remove this variable after debugging.
-    // Texts table to language maps.
-    private static final HashMap<String[], String> sTextsTableToLanguageMap =
+    // Texts table to locale maps.
+    private static final HashMap<String[], String> sTextsTableToLocaleMap =
             CollectionUtils.newHashMap();
 
     public static String getText(final String name, final String[] textsTable) {
         final Integer indexObj = sNameToIndexesMap.get(name);
         if (indexObj == null) {
-            throw new RuntimeException("Unknown text name=" + name + " language="
-                    + sTextsTableToLanguageMap.get(textsTable));
+            throw new RuntimeException("Unknown text name=" + name + " locale="
+                    + sTextsTableToLocaleMap.get(textsTable));
         }
         final int index = indexObj;
         final String text = (index < textsTable.length) ? textsTable[index] : null;
@@ -64,17 +65,24 @@
             return text;
         }
         // Sanity check.
-        if (index >= 0 && index < LANGUAGE_DEFAULT.length) {
-            return LANGUAGE_DEFAULT[index];
+        if (index >= 0 && index < TEXTS_DEFAULT.length) {
+            return TEXTS_DEFAULT[index];
         }
         // Throw exception for debugging purpose.
         throw new RuntimeException("Illegal index=" + index + " for name=" + name
-                + " language=" + sTextsTableToLanguageMap.get(textsTable));
+                + " locale=" + sTextsTableToLocaleMap.get(textsTable));
     }
 
-    public static String[] getTextsTable(final String language) {
-        final String[] textsTable = sLanguageToTextsTableMap.get(language);
-        return textsTable != null ? textsTable : LANGUAGE_DEFAULT;
+    public static String[] getTextsTable(final Locale locale) {
+        final String localeKey = locale.toString();
+        if (sLocaleToTextsTableMap.containsKey(localeKey)) {
+            return sLocaleToTextsTableMap.get(localeKey);
+        }
+        final String languageKey = locale.getLanguage();
+        if (sLocaleToTextsTableMap.containsKey(languageKey)) {
+            return sLocaleToTextsTableMap.get(languageKey);
+        }
+        return TEXTS_DEFAULT;
     }
 
     private static final String[] NAMES = {
@@ -85,16 +93,14 @@
     private static final String EMPTY = "";
 
     /* Default texts */
-    private static final String[] LANGUAGE_DEFAULT = {
+    private static final String[] TEXTS_DEFAULT = {
         /* @DEFAULT_TEXTS@ */
     };
 
     /* @TEXTS@ */
-    // TODO: Use the language + "_" + region representation for the locale string key.
-    // Currently we are dropping the region from the key.
-    private static final Object[] LANGUAGES_AND_TEXTS = {
+    private static final Object[] LOCALES_AND_TEXTS = {
     // "locale", TEXT_ARRAY,  /* numberOfNonNullText/lengthOf_TEXT_ARRAY localeName */
-        /* @LANGUAGES_AND_TEXTS@ */
+        /* @LOCALES_AND_TEXTS@ */
     };
 
     static {
@@ -102,11 +108,11 @@
             sNameToIndexesMap.put(NAMES[index], index);
         }
 
-        for (int i = 0; i < LANGUAGES_AND_TEXTS.length; i += 2) {
-            final String language = (String)LANGUAGES_AND_TEXTS[i];
-            final String[] textsTable = (String[])LANGUAGES_AND_TEXTS[i + 1];
-            sLanguageToTextsTableMap.put(language, textsTable);
-            sTextsTableToLanguageMap.put(textsTable, language);
+        for (int i = 0; i < LOCALES_AND_TEXTS.length; i += 2) {
+            final String locale = (String)LOCALES_AND_TEXTS[i];
+            final String[] textsTable = (String[])LOCALES_AND_TEXTS[i + 1];
+            sLocaleToTextsTableMap.put(locale, textsTable);
+            sTextsTableToLocaleMap.put(textsTable, locale);
         }
     }
 }
diff --git a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/JarUtils.java b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/JarUtils.java
index a74096e..b892df2 100644
--- a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/JarUtils.java
+++ b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/JarUtils.java
@@ -16,6 +16,7 @@
 
 package com.android.inputmethod.keyboard.tools;
 
+import java.io.Closeable;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
@@ -58,7 +59,7 @@
         public boolean accept(String dirName, String name);
     }
 
-    public static ArrayList<String> getNameListing(final JarFile jar, final JarFilter filter) {
+    public static ArrayList<String> getEntryNameListing(final JarFile jar, final JarFilter filter) {
         final ArrayList<String> result = new ArrayList<String>();
         final Enumeration<JarEntry> entries = jar.entries();
         while (entries.hasMoreElements()) {
@@ -74,12 +75,42 @@
         return result;
     }
 
-    public static ArrayList<String> getNameListing(final JarFile jar, final String filterName) {
-        return getNameListing(jar, new JarFilter() {
+    public static ArrayList<String> getEntryNameListing(final JarFile jar,
+            final String filterName) {
+        return getEntryNameListing(jar, new JarFilter() {
             @Override
             public boolean accept(final String dirName, final String name) {
                 return name.equals(filterName);
             }
         });
     }
+
+    // The locale is taken from string resource jar entry name (values-<locale>/)
+    // or {@link LocaleUtils#DEFAULT_LOCALE_KEY} for the default string resource
+    // directory (values/).
+    public static String getLocaleFromEntryName(final String jarEntryName) {
+        final String dirName = jarEntryName.substring(0, jarEntryName.lastIndexOf('/'));
+        final int pos = dirName.lastIndexOf('/');
+        final String parentName = (pos >= 0) ? dirName.substring(pos + 1) : dirName;
+        final int localePos = parentName.indexOf('-');
+        if (localePos < 0) {
+            // Default resource name.
+            return LocaleUtils.DEFAULT_LOCALE_KEY;
+        }
+        final String locale = parentName.substring(localePos + 1);
+        final int regionPos = locale.indexOf("-r");
+        if (regionPos < 0) {
+            return locale;
+        }
+        return locale.replace("-r", "_");
+    }
+
+    public static void close(final Closeable stream) {
+        try {
+            if (stream != null) {
+                stream.close();
+            }
+        } catch (IOException e) {
+        }
+    }
 }
diff --git a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/LocaleUtils.java b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/LocaleUtils.java
index 9fdc1f6..d0f8b42 100644
--- a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/LocaleUtils.java
+++ b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/LocaleUtils.java
@@ -26,6 +26,10 @@
  * for the make-keyboard-text tool.
  */
 public final class LocaleUtils {
+    public static final String DEFAULT_LOCALE_KEY = "DEFAULT";
+    public static final String NO_LANGUAGE_LOCALE_CODE = "zz";
+    public static final String NO_LANGUAGE_LOCALE_DISPLAY_NAME = "Alphabet";
+
     private LocaleUtils() {
         // Intentional empty constructor for utility class.
     }
@@ -44,7 +48,8 @@
             if (retval != null) {
                 return retval;
             }
-            String[] localeParams = localeStr.split("_", 3);
+            final String[] localeParams = localeStr.split("_", 3);
+            // TODO: Use JDK 7 Locale.Builder to handle a script name.
             if (localeParams.length == 1) {
                 retval = new Locale(localeParams[0]);
             } else if (localeParams.length == 2) {
@@ -58,4 +63,12 @@
             return retval;
         }
     }
+
+    public static String getLocaleDisplayName(final String localeString) {
+        if (localeString.equals(NO_LANGUAGE_LOCALE_CODE)) {
+            return NO_LANGUAGE_LOCALE_DISPLAY_NAME;
+        }
+        final Locale locale = constructLocaleFromString(localeString);
+        return locale.getDisplayName(Locale.ENGLISH);
+    }
 }
diff --git a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MoreKeysResources.java b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MoreKeysResources.java
index 9bb2b38..c1a9753 100644
--- a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MoreKeysResources.java
+++ b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MoreKeysResources.java
@@ -16,10 +16,8 @@
 
 package com.android.inputmethod.keyboard.tools;
 
-import java.io.Closeable;
 import java.io.File;
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.LineNumberReader;
 import java.io.PrintStream;
@@ -27,7 +25,7 @@
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
-import java.util.Locale;
+import java.util.TreeMap;
 import java.util.jar.JarFile;
 
 public class MoreKeysResources {
@@ -37,21 +35,15 @@
     private static final String MARK_NAMES = "@NAMES@";
     private static final String MARK_DEFAULT_TEXTS = "@DEFAULT_TEXTS@";
     private static final String MARK_TEXTS = "@TEXTS@";
-    private static final String MARK_LANGUAGES_AND_TEXTS = "@LANGUAGES_AND_TEXTS@";
-    private static final String DEFAULT_LANGUAGE_NAME = "DEFAULT";
+    private static final String TEXTS_ARRAY_NAME_PREFIX = "TEXTS_";
+    private static final String MARK_LOCALES_AND_TEXTS = "@LOCALES_AND_TEXTS@";
     private static final String EMPTY_STRING_VAR = "EMPTY";
 
-    private static final String NO_LANGUAGE_CODE = "zz";
-    private static final String NO_LANGUAGE_DISPLAY_NAME = "Alphabet";
-
     private final JarFile mJar;
-    // Language to string resources map.
-    private final HashMap<String, StringResourceMap> mResourcesMap =
-            new HashMap<String, StringResourceMap>();
-    // Sorted languages list. The language is taken from string resource directories
-    // (values-<language>/) or {@link #DEFAULT_LANGUAGE_NAME} for the default string resource
-    // directory (values/).
-    private final ArrayList<String> mSortedLanguagesList = new ArrayList<String>();
+    // String resources maps sorted by its language. The language is determined from the jar entry
+    // name by calling {@link JarUtils#getLocaleFromEntryName(String)}.
+    private final TreeMap<String, StringResourceMap> mResourcesMap =
+            new TreeMap<String, StringResourceMap>();
     // Default string resources map.
     private final StringResourceMap mDefaultResourceMap;
     // Histogram of string resource names. This is used to sort {@link #mSortedResourceNames}.
@@ -64,22 +56,13 @@
 
     public MoreKeysResources(final JarFile jar) {
         mJar = jar;
-        final ArrayList<String> resources = JarUtils.getNameListing(jar, TEXT_RESOURCE_NAME);
-        for (final String name : resources) {
-            final String dirName = name.substring(0, name.lastIndexOf('/'));
-            final int pos = dirName.lastIndexOf('/');
-            final String parentName = (pos >= 0) ? dirName.substring(pos + 1) : dirName;
-            final String language = getLanguageFromResDir(parentName);
-            final InputStream stream = JarUtils.openResource(name);
-            try {
-                mResourcesMap.put(language, new StringResourceMap(stream));
-            } finally {
-                close(stream);
-            }
+        final ArrayList<String> resourceEntryNames = JarUtils.getEntryNameListing(
+                jar, TEXT_RESOURCE_NAME);
+        for (final String entryName : resourceEntryNames) {
+            final StringResourceMap resMap = new StringResourceMap(entryName);
+            mResourcesMap.put(resMap.mLocale, resMap);
         }
-        mDefaultResourceMap = mResourcesMap.get(DEFAULT_LANGUAGE_NAME);
-        mSortedLanguagesList.addAll(mResourcesMap.keySet());
-        Collections.sort(mSortedLanguagesList);
+        mDefaultResourceMap = mResourcesMap.get(LocaleUtils.DEFAULT_LOCALE_KEY);
 
         // Initialize name histogram and names list.
         final HashMap<String, Integer> nameHistogram = mNameHistogram;
@@ -89,12 +72,12 @@
             resourceNamesList.add(res.mName);
         }
         // Make name histogram.
-        for (final String language : mResourcesMap.keySet()) {
-            final StringResourceMap resMap = mResourcesMap.get(language);
+        for (final String locale : mResourcesMap.keySet()) {
+            final StringResourceMap resMap = mResourcesMap.get(locale);
             if (resMap == mDefaultResourceMap) continue;
             for (final StringResource res : resMap.getResources()) {
                 if (!mDefaultResourceMap.contains(res.mName)) {
-                    throw new RuntimeException(res.mName + " in " + language
+                    throw new RuntimeException(res.mName + " in " + locale
                             + " doesn't have default resource");
                 }
                 final int histogramValue = nameHistogram.get(res.mName);
@@ -118,22 +101,8 @@
         mSortedResourceNames = resourceNamesList.toArray(new String[resourceNamesList.size()]);
     }
 
-    private static String getLanguageFromResDir(final String dirName) {
-        final int languagePos = dirName.indexOf('-');
-        if (languagePos < 0) {
-            // Default resource.
-            return DEFAULT_LANGUAGE_NAME;
-        }
-        final String language = dirName.substring(languagePos + 1);
-        final int countryPos = language.indexOf("-r");
-        if (countryPos < 0) {
-            return language;
-        }
-        return language.replace("-r", "_");
-    }
-
     public void writeToJava(final String outDir) {
-        final ArrayList<String> list = JarUtils.getNameListing(mJar, JAVA_TEMPLATE);
+        final ArrayList<String> list = JarUtils.getEntryNameListing(mJar, JAVA_TEMPLATE);
         if (list.isEmpty()) {
             throw new RuntimeException("Can't find java template " + JAVA_TEMPLATE);
         }
@@ -159,8 +128,8 @@
         } catch (IOException e) {
             throw new RuntimeException(e);
         } finally {
-            close(lnr);
-            close(ps);
+            JarUtils.close(lnr);
+            JarUtils.close(ps);
         }
     }
 
@@ -174,8 +143,8 @@
                 dumpDefaultTexts(out);
             } else if (line.contains(MARK_TEXTS)) {
                 dumpTexts(out);
-            } else if (line.contains(MARK_LANGUAGES_AND_TEXTS)) {
-                dumpLanguageMap(out);
+            } else if (line.contains(MARK_LOCALES_AND_TEXTS)) {
+                dumpLocalesMap(out);
             } else {
                 out.println(line);
             }
@@ -196,16 +165,17 @@
         mDefaultResourceMap.setOutputArraySize(outputArraySize);
     }
 
-    private static String getArrayNameForLanguage(final String language) {
-        return "LANGUAGE_" + language;
+    private static String getArrayNameForLocale(final String locale) {
+        return TEXTS_ARRAY_NAME_PREFIX + locale;
     }
 
     private void dumpTexts(final PrintStream out) {
-        for (final String language : mSortedLanguagesList) {
-            final StringResourceMap resMap = mResourcesMap.get(language);
+        for (final StringResourceMap resMap : mResourcesMap.values()) {
+            final String locale = resMap.mLocale;
             if (resMap == mDefaultResourceMap) continue;
-            out.format("    /* Language %s: %s */\n", language, getLanguageDisplayName(language));
-            out.format("    private static final String[] " + getArrayNameForLanguage(language)
+            out.format("    /* Locale %s: %s */\n",
+                    locale, LocaleUtils.getLocaleDisplayName(locale));
+            out.format("    private static final String[] " + getArrayNameForLocale(locale)
                     + " = {\n");
             final int outputArraySize = dumpTextsInternal(out, resMap);
             resMap.setOutputArraySize(outputArraySize);
@@ -213,28 +183,19 @@
         }
     }
 
-    private void dumpLanguageMap(final PrintStream out) {
-        for (final String language : mSortedLanguagesList) {
-            final StringResourceMap resMap = mResourcesMap.get(language);
-            final Locale locale = LocaleUtils.constructLocaleFromString(language);
-            final String languageKeyToDump = locale.getCountry().isEmpty()
-                    ? String.format("\"%s\"", language)
-                    : String.format("\"%s\"", locale.getLanguage());
-            out.format("        %s, %-15s /* %3d/%3d %s */\n",
-                    languageKeyToDump, getArrayNameForLanguage(language) + ",",
+    private void dumpLocalesMap(final PrintStream out) {
+        for (final StringResourceMap resMap : mResourcesMap.values()) {
+            final String locale = resMap.mLocale;
+            final String localeToDump = locale.equals(LocaleUtils.DEFAULT_LOCALE_KEY)
+                    ? String.format("\"%s\"", locale)
+                    : String.format("\"%s\"%s", locale, "       ".substring(locale.length()));
+            out.format("        %s, %-12s /* %3d/%3d %s */\n",
+                    localeToDump, getArrayNameForLocale(locale) + ",",
                     resMap.getResources().size(), resMap.getOutputArraySize(),
-                    getLanguageDisplayName(language));
+                    LocaleUtils.getLocaleDisplayName(locale));
         }
     }
 
-    private static String getLanguageDisplayName(final String language) {
-        final Locale locale = LocaleUtils.constructLocaleFromString(language);
-        if (locale.getLanguage().equals(NO_LANGUAGE_CODE)) {
-            return NO_LANGUAGE_DISPLAY_NAME;
-        }
-        return locale.getDisplayName(Locale.ENGLISH);
-    }
-
     private int dumpTextsInternal(final PrintStream out, final StringResourceMap resMap) {
         final ArrayInitializerFormatter formatter =
                 new ArrayInitializerFormatter(out, 100, "        ", mSortedResourceNames);
@@ -289,13 +250,4 @@
         }
         return sb.toString();
     }
-
-    private static void close(final Closeable stream) {
-        try {
-            if (stream != null) {
-                stream.close();
-            }
-        } catch (IOException e) {
-        }
-    }
 }
diff --git a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/StringResourceMap.java b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/StringResourceMap.java
index 4eff8a2..d7e76ad 100644
--- a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/StringResourceMap.java
+++ b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/StringResourceMap.java
@@ -34,6 +34,8 @@
 import javax.xml.parsers.SAXParserFactory;
 
 public class StringResourceMap {
+    // Locale name.
+    public final String mLocale;
     // String resource list.
     private final List<StringResource> mResources;
     // Name to string resource map.
@@ -42,25 +44,31 @@
     // The length of String[] that is created from this {@link StringResourceMap}. The length is
     // calculated in {@link MoreKeysResources#dumpTexts(OutputStream)} and recorded by
     // {@link #setOutputArraySize(int)}. The recorded length is used as a part of comment by
-    // {@link MoreKeysResources#dumpLanguageMap(OutputStream)} via {@link #getOutputArraySize()}.
+    // {@link MoreKeysResources#dumpLocaleMap(OutputStream)} via {@link #getOutputArraySize()}.
     private int mOutputArraySize;
 
-    public StringResourceMap(final InputStream is) {
+    public StringResourceMap(final String jarEntryName) {
+        mLocale = JarUtils.getLocaleFromEntryName(jarEntryName);
         final StringResourceHandler handler = new StringResourceHandler();
         final SAXParserFactory factory = SAXParserFactory.newInstance();
         factory.setNamespaceAware(true);
+        final InputStream stream = JarUtils.openResource(jarEntryName);
         try {
             final SAXParser parser = factory.newSAXParser();
             // In order to get comment tag.
             parser.setProperty("http://xml.org/sax/properties/lexical-handler", handler);
-            parser.parse(is, handler);
+            parser.parse(stream, handler);
         } catch (ParserConfigurationException e) {
+            throw new RuntimeException(e.getMessage(), e);
         } catch (SAXParseException e) {
             throw new RuntimeException(e.getMessage() + " at line " + e.getLineNumber()
-                    + ", column " + e.getColumnNumber());
+                    + ", column " + e.getColumnNumber(), e);
         } catch (SAXException e) {
-            throw new RuntimeException(e.getMessage());
+            throw new RuntimeException(e.getMessage(), e);
         } catch (IOException e) {
+            throw new RuntimeException(e.getMessage(), e);
+        } finally {
+            JarUtils.close(stream);
         }
 
         mResources = Collections.unmodifiableList(handler.mResources);