Merge "Initialize ResearchLogger later to avoid NPE"
diff --git a/java/res/values-af/strings.xml b/java/res/values-af/strings.xml
index 92de687..edc4e44 100644
--- a/java/res/values-af/strings.xml
+++ b/java/res/values-af/strings.xml
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"Nie nou nie"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Dieselfde invoerstyl bestaan ​​reeds: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Bruikbaarheidstudie-modus"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Sleuteldruk se vibrasie-tydsduurinstellings"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Sleuteldruk se klankvolume-instellings"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Lees eksterne woordeboeklêer"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Geen woordeboeklêers in die aflaaiselsvouer nie"</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Kies \'n woordeboeklêer om te installeer"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Moet hierdie lêer regtig vir <xliff:g id="LOCALE_NAME">%s</xliff:g> geïnstalleer word?"</string>
+    <string name="error" msgid="8940763624668513648">"Daar was \'n fout"</string>
     <string name="button_default" msgid="3988017840431881491">"Verstek"</string>
 </resources>
diff --git a/java/res/values-am/strings.xml b/java/res/values-am/strings.xml
index c5c02da..ede51c9 100644
--- a/java/res/values-am/strings.xml
+++ b/java/res/values-am/strings.xml
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"አሁን አልፈልግም"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"ተመሳሳዩ የግብዓት ቅጥ አስቀድሞ አለ፦ <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"የተገልጋይነት ጥናት ሁነታ"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"ቁልፍ ተጫን በቅንጅቶች ወቅት ንዝረት"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"ቁልፍ ተጫን የድምጽ መጠን ቅንብሮች"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"ውጫዊ የመዝገበቃላት ፋይል አንብብ"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"በውርዶች አቃፊው ውስጥ ምንም የመዝገበ-ፋይሎች የሉም"</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"የሚጭኑት የመዝገበ-ቃላት ፋይል ይምረጡ"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"እውን ይሄ ፋይል ለ<xliff:g id="LOCALE_NAME">%s</xliff:g> ይጫን?"</string>
+    <string name="error" msgid="8940763624668513648">"ስህተት ተከስቶ ነበር"</string>
     <string name="button_default" msgid="3988017840431881491">"ነባሪ"</string>
 </resources>
diff --git a/java/res/values-ar/strings.xml b/java/res/values-ar/strings.xml
index 3282727..5d7dfce 100644
--- a/java/res/values-ar/strings.xml
+++ b/java/res/values-ar/strings.xml
@@ -144,6 +144,8 @@
     <string name="not_now" msgid="6172462888202790482">"ليس الآن"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"نمط الإدخال ذاته موجود من قبل: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"وضع سهولة الاستخدام"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"إعدادات مدة اهتزاز الضغط على المفاتيح"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"إعدادات مستوى صوت الضغط على المفاتيح"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"قراءة ملف قاموس خارجي"</string>
diff --git a/java/res/values-be/strings.xml b/java/res/values-be/strings.xml
index ad9fb77..3a3a601 100644
--- a/java/res/values-be/strings.xml
+++ b/java/res/values-be/strings.xml
@@ -144,6 +144,8 @@
     <string name="not_now" msgid="6172462888202790482">"Не цяпер"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Такі метад уводу ўжо існуе: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Рэжым даследвання выкарыстальнасці"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Налады працягласцi вiбрацыi пры нацiску"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Налады гучнасцi пры нацiску"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Чытанне знешняга файла слоўніка"</string>
diff --git a/java/res/values-bg/strings.xml b/java/res/values-bg/strings.xml
index 588e076..d192623 100644
--- a/java/res/values-bg/strings.xml
+++ b/java/res/values-bg/strings.xml
@@ -144,6 +144,8 @@
     <string name="not_now" msgid="6172462888202790482">"Не сега"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Същият стил на въвеждане вече съществува: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Режим за изучаване на използваемостта"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Настройки за продължителност на вибрирането при натискане на клавиш"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Настройки за силата на звука при натискане на клавиш"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Четене на файл за външен речник"</string>
diff --git a/java/res/values-ca/strings.xml b/java/res/values-ca/strings.xml
index 796374c..b59d225 100644
--- a/java/res/values-ca/strings.xml
+++ b/java/res/values-ca/strings.xml
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"Ara no"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Ja existeix aquest estil d\'entrada: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Mode d\'estudi d\'usabilitat"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Configuració de durada de vibracions en prémer tecles"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Configuració del volum de so en prémer tecles"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Lectura d\'un fitxer de diccionari extern"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"No hi ha cap fitxer de diccionari a la carpeta Baixades"</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Selecció d\'un fitxer de diccionari per instal·lar"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Realment vols instal·lar aquest fitxer per a <xliff:g id="LOCALE_NAME">%s</xliff:g>?"</string>
+    <string name="error" msgid="8940763624668513648">"S\'ha produït un error"</string>
     <string name="button_default" msgid="3988017840431881491">"Predeterminat"</string>
 </resources>
diff --git a/java/res/values-cs/strings.xml b/java/res/values-cs/strings.xml
index 3316819..41b4959 100644
--- a/java/res/values-cs/strings.xml
+++ b/java/res/values-cs/strings.xml
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"Teď ne"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Tento styl zadávání již existuje: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Režim studie použitelnosti"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Délka vibrace při stisku klávesy"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Hlasitost při stisknutí klávesy"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Číst soubor externího slovníku"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Ve složce Stažené nejsou žádné soubory slovníků."</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Vyberte soubor slovníku k instalaci"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Chcete nainstalovat tento soubor pro jazyk <xliff:g id="LOCALE_NAME">%s</xliff:g>?"</string>
+    <string name="error" msgid="8940763624668513648">"Došlo k chybě"</string>
     <string name="button_default" msgid="3988017840431881491">"Výchozí"</string>
 </resources>
diff --git a/java/res/values-da/strings.xml b/java/res/values-da/strings.xml
index 8a93ba9..e5a7900 100644
--- a/java/res/values-da/strings.xml
+++ b/java/res/values-da/strings.xml
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"Ikke nu"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Denne inputstil findes allerede: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Tilstand for brugsstudie"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Indstillinger for varighed af vibration ved tastetryk"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Indstillinger for lydstyrke ved tastetryk"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Læs ekstern ordbogsfil"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Der er ingen ordbogsfiler i mappen Downloads"</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Vælg den ordbog, som du vil installere"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Er du klar til at installere denne fil til <xliff:g id="LOCALE_NAME">%s</xliff:g>?"</string>
+    <string name="error" msgid="8940763624668513648">"Der opstod en fejl"</string>
     <string name="button_default" msgid="3988017840431881491">"Standard"</string>
 </resources>
diff --git a/java/res/values-de/strings.xml b/java/res/values-de/strings.xml
index 1a0a017..cb8763d 100644
--- a/java/res/values-de/strings.xml
+++ b/java/res/values-de/strings.xml
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"Später"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Der gleiche Eingabestil ist bereits vorhanden: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Studie zur Benutzerfreundlichkeit"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Vibrationsdauer bei Tastendruck"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Tonlautstärke bei Tastendruck"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Externe Wörterbuchdatei lesen"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Keine Wörterbuchdateien im Ordner \"Downloads\""</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Wörterbuchdatei zum Installieren auswählen"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Möchten Sie diese Datei für <xliff:g id="LOCALE_NAME">%s</xliff:g> installieren?"</string>
+    <string name="error" msgid="8940763624668513648">"Es ist ein Fehler aufgetreten"</string>
     <string name="button_default" msgid="3988017840431881491">"Standard"</string>
 </resources>
diff --git a/java/res/values-el/strings.xml b/java/res/values-el/strings.xml
index 3ac4e47..0311629 100644
--- a/java/res/values-el/strings.xml
+++ b/java/res/values-el/strings.xml
@@ -42,7 +42,7 @@
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Χρόνος εξαφ. αναδ. παραθ."</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Χωρίς καθυστέρ."</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Προεπιλογή"</string>
-    <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g>ms"</string>
+    <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g>χλστ. δ."</string>
     <string name="use_contacts_dict" msgid="4435317977804180815">"Πρόταση ονομάτων επαφών"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Χρησιμοποιήστε ονόματα από τις Επαφές για προτάσεις και διορθ."</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Τελεία με διπλό πάτημα πλήκτρ.διαστ."</string>
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"Όχι τώρα"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Το ίδιο στυλ εισόδου υπάρχει ήδη: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Λειτουργία μελέτης χρηστικότητας"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Ρυθμίσεις διάρκειας δόνησης κατά το πάτημα πλήκτρων"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Ρυθμίσεις έντασης ήχου κατά το πάτημα πλήκτρων"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Ανάγνωση εξωτερικού αρχείου λεξικού"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Δεν υπάρχουν αρχεία λεξικού στο φάκελο \"Λήψεις\""</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Επιλογή αρχείου λεξικού για εγκατάσταση"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Να εγκατασταθεί όντως αυτό το αρχείο για <xliff:g id="LOCALE_NAME">%s</xliff:g>;"</string>
+    <string name="error" msgid="8940763624668513648">"Παρουσιάστηκε σφάλμα."</string>
     <string name="button_default" msgid="3988017840431881491">"Προεπιλογή"</string>
 </resources>
diff --git a/java/res/values-en-rGB/strings.xml b/java/res/values-en-rGB/strings.xml
index df3b238..60bc9b4 100644
--- a/java/res/values-en-rGB/strings.xml
+++ b/java/res/values-en-rGB/strings.xml
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"Not now"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"The same input style already exists: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Usability study mode"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Key-press vibration duration settings"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Key-press sound volume settings"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Read external dictionary file"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"No dictionary files in the Downloads folder"</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Select a dictionary file to install"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Really install this file for <xliff:g id="LOCALE_NAME">%s</xliff:g>?"</string>
+    <string name="error" msgid="8940763624668513648">"There was an error"</string>
     <string name="button_default" msgid="3988017840431881491">"Default"</string>
 </resources>
diff --git a/java/res/values-es-rUS/strings.xml b/java/res/values-es-rUS/strings.xml
index 7e67f29..73ae5f0 100644
--- a/java/res/values-es-rUS/strings.xml
+++ b/java/res/values-es-rUS/strings.xml
@@ -144,6 +144,8 @@
     <string name="not_now" msgid="6172462888202790482">"Ahora no"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Ya existe el estilo de entrada <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>."</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modo de estudio de usabilidad"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Duración de vibración al presionar teclas"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Volumen de sonido al presionar teclas"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Leer archivo de diccionario externo"</string>
diff --git a/java/res/values-es/strings.xml b/java/res/values-es/strings.xml
index 6c39ceb..674fbe8 100644
--- a/java/res/values-es/strings.xml
+++ b/java/res/values-es/strings.xml
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"Ahora no"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Ya existe el estilo de entrada <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>."</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modo estudio de usabilidad"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Duración de la vibración al pulsar tecla"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Volumen sonido al pulsar tecla"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Leer archivo de diccionario externo"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"No hay archivos de diccionario en la carpeta de descargas."</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Selecciona un archivo de diccionario para instalar"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"¿Seguro que quieres instalar este archivo para <xliff:g id="LOCALE_NAME">%s</xliff:g>?"</string>
+    <string name="error" msgid="8940763624668513648">"Se ha producido un error"</string>
     <string name="button_default" msgid="3988017840431881491">"Predeterminado"</string>
 </resources>
diff --git a/java/res/values-et/strings.xml b/java/res/values-et/strings.xml
index 1d2b029..a31566c 100644
--- a/java/res/values-et/strings.xml
+++ b/java/res/values-et/strings.xml
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"Mitte kohe"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Sama sisendstiil on juba olemas: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Kasutatavuse uurimisrežiim"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Klahvivajutuse vibratsiooni kestuse seaded"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Klahvivajutuse helitugevuse seaded"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Välise sõnastikufaili lugemine"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Kaustas Allalaadimised pole ühtegi sõnastikufaili"</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Installitava sõnastikufaili valimine"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Kas soovite tõesti installida faili lokaadile <xliff:g id="LOCALE_NAME">%s</xliff:g>?"</string>
+    <string name="error" msgid="8940763624668513648">"Ilmnes viga"</string>
     <string name="button_default" msgid="3988017840431881491">"Vaikeväärtus"</string>
 </resources>
diff --git a/java/res/values-fa/strings.xml b/java/res/values-fa/strings.xml
index f9a3e2e..5c4858e 100644
--- a/java/res/values-fa/strings.xml
+++ b/java/res/values-fa/strings.xml
@@ -148,6 +148,8 @@
     <string name="not_now" msgid="6172462888202790482">"اکنون خیر"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"سبک ورودی مشابهی در حال حاضر وجود دارد: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"حالت بررسی قابلیت استفاده"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"تنظیمات مدت زمان لرزش فشار کلید"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"تنظیمات میزان صدای فشار کلید"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"خواندن فایل فرهنگ لغت خارجی"</string>
diff --git a/java/res/values-fi/strings.xml b/java/res/values-fi/strings.xml
index 24f06e2..7525a60 100644
--- a/java/res/values-fi/strings.xml
+++ b/java/res/values-fi/strings.xml
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"Ei nyt"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Sama tulotyyli on jo olemassa: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Käytettävyystutkimustila"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Näppäimenpainalluksen värinän kestoasetukset"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Näppäimenpainalluksen äänenvoimakkuusasetukset"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Lue ulkoista sanakirjatiedostoa"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Lataukset-kansiossa ei ole sanakirjatiedostoja"</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Valitse asennettava sanakirjatiedosto"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Haluatko asentaa tämä tiedoston kielelle <xliff:g id="LOCALE_NAME">%s</xliff:g>?"</string>
+    <string name="error" msgid="8940763624668513648">"Tapahtui virhe."</string>
     <string name="button_default" msgid="3988017840431881491">"Oletusarvot"</string>
 </resources>
diff --git a/java/res/values-fr/strings.xml b/java/res/values-fr/strings.xml
index 8e86888..f04856b 100644
--- a/java/res/values-fr/strings.xml
+++ b/java/res/values-fr/strings.xml
@@ -144,6 +144,8 @@
     <string name="not_now" msgid="6172462888202790482">"Pas maintenant"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Le style de saisie suivant existe déjà : <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>."</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Mode d\'étude de l\'utilisabilité"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Durée de vibration à chaque pression"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Volume sonore à chaque pression"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Lire un fichier de dictionnaire externe"</string>
diff --git a/java/res/values-hi/strings.xml b/java/res/values-hi/strings.xml
index 44ea37f..2db3f57 100644
--- a/java/res/values-hi/strings.xml
+++ b/java/res/values-hi/strings.xml
@@ -144,6 +144,8 @@
     <string name="not_now" msgid="6172462888202790482">"अभी नहीं"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"ऐसी ही इनपुट शैली पहले से मौजूद है: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"उपयोगिता अध्ययन मोड"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"कुंजी-स्‍पर्श कंपन अवधि सेटिंग"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"कुंजी-स्‍पर्श ध्‍वनि वॉल्‍यूम सेटिंग"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"बाहरी डिक्शनरी फ़ाइल पढ़ें"</string>
diff --git a/java/res/values-hr/strings.xml b/java/res/values-hr/strings.xml
index f8db8c9..c080812 100644
--- a/java/res/values-hr/strings.xml
+++ b/java/res/values-hr/strings.xml
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"Ne sada"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Već postoji isti stil unosa: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Način studije upotrebljivosti"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Postavke trajanja vibracije kod pritiska tipke"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Postavke glasnoće zvuka kod pritiska tipke"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Čitanje datoteke vanjskog rječnika"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"U mapi Preuzimanja nema datoteka rječnika"</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Odabir datoteke rječnika za instaliranje"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Želite li doista instalirati ovu datoteku za <xliff:g id="LOCALE_NAME">%s</xliff:g>?"</string>
+    <string name="error" msgid="8940763624668513648">"Došlo je do pogreške"</string>
     <string name="button_default" msgid="3988017840431881491">"Zadano"</string>
 </resources>
diff --git a/java/res/values-hu/strings.xml b/java/res/values-hu/strings.xml
index 2d93847..00c6cef 100644
--- a/java/res/values-hu/strings.xml
+++ b/java/res/values-hu/strings.xml
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"Most nem"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Ugyanez a bemenetstílus már létezik: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Használhatósági teszt"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Gombnyomás rezgési időtartamának beállításai"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Gombnyomás hangerejének beállításai"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Külső szótárfájl olvasása"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Nincs szótárfájl a Letöltések mappában."</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Válasszon ki egy szótárfájlt a telepítéshez."</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Valóban telepíti ezt a fájlt <xliff:g id="LOCALE_NAME">%s</xliff:g> nyelvhez?"</string>
+    <string name="error" msgid="8940763624668513648">"Hiba történt."</string>
     <string name="button_default" msgid="3988017840431881491">"Alapértelmezett"</string>
 </resources>
diff --git a/java/res/values-in/strings.xml b/java/res/values-in/strings.xml
index b2d4665..e6f6130 100644
--- a/java/res/values-in/strings.xml
+++ b/java/res/values-in/strings.xml
@@ -144,6 +144,8 @@
     <string name="not_now" msgid="6172462888202790482">"Nanti saja"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Sudah ada gaya masukan yang sama: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Mode studi daya guna"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Setelan durasi getaran saat tombol ditekan"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Setelan volume suara saat tombol ditekan"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Membaca file kamus eksternal"</string>
diff --git a/java/res/values-is/strings.xml b/java/res/values-is/strings.xml
index c5d45b9..8fda3ce 100644
--- a/java/res/values-is/strings.xml
+++ b/java/res/values-is/strings.xml
@@ -263,6 +263,8 @@
     <skip />
     <!-- no translation found for prefs_usability_study_mode (1261130555134595254) -->
     <skip />
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <!-- no translation found for prefs_keypress_vibration_duration_settings (1829950405285211668) -->
     <skip />
     <!-- no translation found for prefs_keypress_sound_volume_settings (5875933757082305040) -->
diff --git a/java/res/values-it/strings.xml b/java/res/values-it/strings.xml
index 704cc14..340e85a 100644
--- a/java/res/values-it/strings.xml
+++ b/java/res/values-it/strings.xml
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"Non ora"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Esiste già uno stile di inuput uguale: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modalità Studio sull\'usabilità"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Durata vibrazione alla pressione tasto"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Volume audio alla pressione di un tasto"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Leggi file dizionario esterno"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Nessun file di dizionario nella cartella Download"</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Seleziona un file di dizionario da installare"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Installare questo file per <xliff:g id="LOCALE_NAME">%s</xliff:g>?"</string>
+    <string name="error" msgid="8940763624668513648">"Si è verificato un errore"</string>
     <string name="button_default" msgid="3988017840431881491">"Predefinito"</string>
 </resources>
diff --git a/java/res/values-iw/strings.xml b/java/res/values-iw/strings.xml
index 6775986..0006d24 100644
--- a/java/res/values-iw/strings.xml
+++ b/java/res/values-iw/strings.xml
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"לא עכשיו"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"סגנון קלט זהה כבר קיים: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"מצב מחקר שימושיות"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"הגדרות משך רטט בלחיצה על מקש"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"הגדרות עוצמת קול בלחיצה על מקש"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"קריאה של קובץ מילון חיצוני"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"אין קובצי מילונים בתיקיית ההורדות"</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"בחירת קובץ מילון להתקנה"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"האם באמת להתקין את הקובץ הזה עבור <xliff:g id="LOCALE_NAME">%s</xliff:g>?"</string>
+    <string name="error" msgid="8940763624668513648">"אירעה שגיאה"</string>
     <string name="button_default" msgid="3988017840431881491">"ברירת מחדל"</string>
 </resources>
diff --git a/java/res/values-ja/strings.xml b/java/res/values-ja/strings.xml
index 17e32e4..813da0a 100644
--- a/java/res/values-ja/strings.xml
+++ b/java/res/values-ja/strings.xml
@@ -144,6 +144,8 @@
     <string name="not_now" msgid="6172462888202790482">"後で行う"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"同じ入力スタイルが既に存在します: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"使いやすさの研究モード"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"キー操作バイブの振動時間の設定"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"キー操作音の音量設定"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"外部辞書ファイルの読み取り"</string>
diff --git a/java/res/values-ka/strings.xml b/java/res/values-ka/strings.xml
index 10d587a..2740613 100644
--- a/java/res/values-ka/strings.xml
+++ b/java/res/values-ka/strings.xml
@@ -263,6 +263,8 @@
     <skip />
     <!-- no translation found for prefs_usability_study_mode (1261130555134595254) -->
     <skip />
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <!-- no translation found for prefs_keypress_vibration_duration_settings (1829950405285211668) -->
     <skip />
     <!-- no translation found for prefs_keypress_sound_volume_settings (5875933757082305040) -->
diff --git a/java/res/values-ko/strings.xml b/java/res/values-ko/strings.xml
index c58d73c..b7275fc 100644
--- a/java/res/values-ko/strings.xml
+++ b/java/res/values-ko/strings.xml
@@ -144,6 +144,8 @@
     <string name="not_now" msgid="6172462888202790482">"나중에"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"같은 입력 스타일이 다음과 같이 이미 존재합니다. <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"가용성 연구 모드"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"키를 누를 때 진동 시간 설정"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"키를 누를 때 효과음 설정"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"외부 사전 파일 읽기"</string>
diff --git a/java/res/values-lt/strings.xml b/java/res/values-lt/strings.xml
index 3e58791..68919d0 100644
--- a/java/res/values-lt/strings.xml
+++ b/java/res/values-lt/strings.xml
@@ -144,6 +144,8 @@
     <string name="not_now" msgid="6172462888202790482">"Ne dabar"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Toks pat įvesties stilius jau yra: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Tinkamumo tyrimo režimas"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Vibracijos paspaudus mygtuką trukmės nustatymai"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Garso paspaudus mygtuką garsumo nustatymai"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Skaityti išorinį žodyno failą"</string>
diff --git a/java/res/values-lv/strings.xml b/java/res/values-lv/strings.xml
index 95bed36..92636a7 100644
--- a/java/res/values-lv/strings.xml
+++ b/java/res/values-lv/strings.xml
@@ -144,6 +144,8 @@
     <string name="not_now" msgid="6172462888202790482">"Vēlāk"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Šāds ievades stils jau pastāv: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Lietojamības izpētes režīms"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Taustiņu nospiešanas vibrācijas ilguma iestatījumi"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Taustiņu nospiešanas skaņas skaļuma iestatījumi"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Ārējās vārdnīcas faila nolasīšana"</string>
diff --git a/java/res/values-mk/strings.xml b/java/res/values-mk/strings.xml
index 3b21023..0d34d92 100644
--- a/java/res/values-mk/strings.xml
+++ b/java/res/values-mk/strings.xml
@@ -263,6 +263,8 @@
     <skip />
     <!-- no translation found for prefs_usability_study_mode (1261130555134595254) -->
     <skip />
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <!-- no translation found for prefs_keypress_vibration_duration_settings (1829950405285211668) -->
     <skip />
     <!-- no translation found for prefs_keypress_sound_volume_settings (5875933757082305040) -->
diff --git a/java/res/values-mn/strings.xml b/java/res/values-mn/strings.xml
index 3b8f21b..cd4f800 100644
--- a/java/res/values-mn/strings.xml
+++ b/java/res/values-mn/strings.xml
@@ -263,6 +263,8 @@
     <skip />
     <!-- no translation found for prefs_usability_study_mode (1261130555134595254) -->
     <skip />
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <!-- no translation found for prefs_keypress_vibration_duration_settings (1829950405285211668) -->
     <skip />
     <!-- no translation found for prefs_keypress_sound_volume_settings (5875933757082305040) -->
diff --git a/java/res/values-ms/strings.xml b/java/res/values-ms/strings.xml
index fa2297e..fd94786 100644
--- a/java/res/values-ms/strings.xml
+++ b/java/res/values-ms/strings.xml
@@ -42,8 +42,7 @@
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Pop tmbl knci ketpkn lengah"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Tiada lengah"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Lalai"</string>
-    <!-- no translation found for abbreviation_unit_milliseconds (8700286094028323363) -->
-    <skip />
+    <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g>ms"</string>
     <string name="use_contacts_dict" msgid="4435317977804180815">"Cadangkan nama Kenalan"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Menggunakan nama daripada Kenalan untuk cadangan dan pembetulan"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Titik ruang berganda"</string>
@@ -145,17 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"Bukan sekarang"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Gaya input yang sama sudah wujud: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Mod kajian kebolehgunaan"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Tetapan tempoh getaran tekan kekunci"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Tetapan kelantangan bunyi tekanan kekunci"</string>
-    <!-- no translation found for prefs_read_external_dictionary (2588931418575013067) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Baca fail kamus luaran"</string>
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Tiada fail kamus dalam folder Muat Turun"</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Pilih fail kamus untuk dipasang"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Betul-betul pasang fail ini untuk <xliff:g id="LOCALE_NAME">%s</xliff:g>?"</string>
+    <string name="error" msgid="8940763624668513648">"Berlaku ralat"</string>
     <string name="button_default" msgid="3988017840431881491">"Lalai"</string>
 </resources>
diff --git a/java/res/values-nb/strings.xml b/java/res/values-nb/strings.xml
index 646f1af..23f5c1a 100644
--- a/java/res/values-nb/strings.xml
+++ b/java/res/values-nb/strings.xml
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"Ikke nå"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Inndatastilen finnes allerede: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Bruksstudiemodus"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Innstillinger for vibrasjonsvarighet ved tastetrykk"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Innstillinger for lydstyrke ved tastetrykk"</string>
-    <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Les en ekstern ordlistefil"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Bruk en ekstern ordlistefil"</string>
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Det ligger ingen ordboksfiler i Nedlastinger-mappen"</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Velg ordboksfilen du vil installere"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Vil du virkelig installere denne filen for <xliff:g id="LOCALE_NAME">%s</xliff:g>?"</string>
+    <string name="error" msgid="8940763624668513648">"Det oppsto en feil"</string>
     <string name="button_default" msgid="3988017840431881491">"Standard"</string>
 </resources>
diff --git a/java/res/values-nl/strings.xml b/java/res/values-nl/strings.xml
index 5b236dc..5c19dce 100644
--- a/java/res/values-nl/strings.xml
+++ b/java/res/values-nl/strings.xml
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"Niet nu"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Dezelfde invoerstijl bestaat al: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modus voor gebruiksvriendelijkheidsonderzoek"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Instellingen voor trillingsduur bij druk op een toets"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Instellingen voor geluidsvolume bij druk op een toets"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Extern woordenboekbestand lezen"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Geen woordenboekbestanden in de map \'Downloads\'"</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Selecteer een woordenboekbestand om te installeren"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Wilt u dit bestand voor <xliff:g id="LOCALE_NAME">%s</xliff:g> echt installeren?"</string>
+    <string name="error" msgid="8940763624668513648">"Er is een fout opgetreden"</string>
     <string name="button_default" msgid="3988017840431881491">"Standaard"</string>
 </resources>
diff --git a/java/res/values-pl/strings.xml b/java/res/values-pl/strings.xml
index 893de38..6f709ef 100644
--- a/java/res/values-pl/strings.xml
+++ b/java/res/values-pl/strings.xml
@@ -144,6 +144,8 @@
     <string name="not_now" msgid="6172462888202790482">"Nie teraz"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Taki styl wprowadzania już istnieje: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Tryb badania przydatności"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Czas trwania wibracji przy naciśnięciu"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Głośność dźwięku przy naciśnięciu"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Odczyt zewnętrznego pliku słownika"</string>
diff --git a/java/res/values-pt-rPT/strings.xml b/java/res/values-pt-rPT/strings.xml
index 84c0ce5..16e59d1 100644
--- a/java/res/values-pt-rPT/strings.xml
+++ b/java/res/values-pt-rPT/strings.xml
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"Agora não"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Já existe o mesmo estilo de introdução: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modo de estudo da capacidade de utilização"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Definições de duração da vibração ao premir as teclas"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Definições de volume de som ao premir as teclas"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Ler ficheiro de dicionário externo"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Não há ficheiros de dicionário na pasta Transferências"</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Selecione um ficheiro de dicionário para instalar"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Instalar mesmo este ficheiro para <xliff:g id="LOCALE_NAME">%s</xliff:g>?"</string>
+    <string name="error" msgid="8940763624668513648">"Ocorreu um erro"</string>
     <string name="button_default" msgid="3988017840431881491">"Predefinido"</string>
 </resources>
diff --git a/java/res/values-pt/strings.xml b/java/res/values-pt/strings.xml
index 80d9171..d5f0c61 100644
--- a/java/res/values-pt/strings.xml
+++ b/java/res/values-pt/strings.xml
@@ -42,8 +42,7 @@
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Dispens. atraso chave princ."</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Sem atraso"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Padrão"</string>
-    <!-- no translation found for abbreviation_unit_milliseconds (8700286094028323363) -->
-    <skip />
+    <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g> ms"</string>
     <string name="use_contacts_dict" msgid="4435317977804180815">"Sugerir nomes de contato"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Usar nomes dos Contatos para sugestões e correções"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Duplo espaço p/ ponto"</string>
@@ -145,10 +144,11 @@
     <string name="not_now" msgid="6172462888202790482">"Agora não"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"O estilo de entrada já existe: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modo de estudo de utilização"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Configurações de duração da vibração ao tocar a tecla"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Config. volume ao tocar a tecla"</string>
-    <!-- no translation found for prefs_read_external_dictionary (2588931418575013067) -->
-    <skip />
+    <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Ler arquivo de dicionário externo"</string>
     <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
     <skip />
     <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
diff --git a/java/res/values-rm/strings.xml b/java/res/values-rm/strings.xml
index 879174b..515bca4 100644
--- a/java/res/values-rm/strings.xml
+++ b/java/res/values-rm/strings.xml
@@ -255,6 +255,8 @@
     <skip />
     <!-- no translation found for prefs_usability_study_mode (1261130555134595254) -->
     <skip />
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <!-- no translation found for prefs_keypress_vibration_duration_settings (1829950405285211668) -->
     <skip />
     <!-- no translation found for prefs_keypress_sound_volume_settings (5875933757082305040) -->
diff --git a/java/res/values-ro/strings.xml b/java/res/values-ro/strings.xml
index 1484d4a..a51ac70 100644
--- a/java/res/values-ro/strings.xml
+++ b/java/res/values-ro/strings.xml
@@ -144,6 +144,8 @@
     <string name="not_now" msgid="6172462888202790482">"Nu acum"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Acelaşi stil de introducere există deja: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modul Studiu privind utilizarea"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Setări pentru durata vibrării la apăsarea tastei"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Setări pentru volumul sunetului la apăsarea tastei"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Citiți fișierul de dicționar extern"</string>
diff --git a/java/res/values-ru/strings.xml b/java/res/values-ru/strings.xml
index c15695b..d77e15f 100644
--- a/java/res/values-ru/strings.xml
+++ b/java/res/values-ru/strings.xml
@@ -144,6 +144,8 @@
     <string name="not_now" msgid="6172462888202790482">"Не сейчас"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Такой стиль ввода уже существует: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Режим проверки удобства использования"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Настройки вибросигнала при нажатии клавиш"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Настройки громкости звука при нажатии клавиш"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Считывать данные из внешнего словаря"</string>
diff --git a/java/res/values-sk/strings.xml b/java/res/values-sk/strings.xml
index 101f47b..c57b8b1 100644
--- a/java/res/values-sk/strings.xml
+++ b/java/res/values-sk/strings.xml
@@ -144,6 +144,8 @@
     <string name="not_now" msgid="6172462888202790482">"Teraz nie"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Rovnaký štýl vstupu už existuje: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Režim štúdie použiteľnosti"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Nastavenia trvania vibrovania pri stlačení klávesu"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Nastavenia hlasitosti zvuku pri stlačení klávesu"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Čítať súbor externého slovníka"</string>
diff --git a/java/res/values-sl/strings.xml b/java/res/values-sl/strings.xml
index 698443c..d48657f 100644
--- a/java/res/values-sl/strings.xml
+++ b/java/res/values-sl/strings.xml
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"Ne zdaj"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Isti slog vnosa že obstaja: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Način za preučevanje uporabnosti"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Nastavitve za trajanje vibriranja ob pritisku tipke"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Nastavitve za glasnost zvoka ob pritisku tipke"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Branje zunanje datoteke slovarja"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"V mapi »Prenosi« ni nobene datoteke slovarja"</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Izberite datoteko slovarja, ki jo želite namestiti"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Zares želite namestiti to datoteko za jezik <xliff:g id="LOCALE_NAME">%s</xliff:g>?"</string>
+    <string name="error" msgid="8940763624668513648">"Prišlo je do napake"</string>
     <string name="button_default" msgid="3988017840431881491">"Privzeto"</string>
 </resources>
diff --git a/java/res/values-sr/strings.xml b/java/res/values-sr/strings.xml
index 58708b0..30a7a57 100644
--- a/java/res/values-sr/strings.xml
+++ b/java/res/values-sr/strings.xml
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"Не сада"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Исти стил уноса већ постоји: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Режим за студију могућности коришћења"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Подешавања трајања вибрације при притиску на тастере"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Подешавања јачине звука при притиску на тастере"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Читање датотеке спољног речника"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"У директоријуму Преузимања нема датотека речника"</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Избор датотеке речника за инсталирање"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Желите ли стварно да инсталирате ову датотеку за <xliff:g id="LOCALE_NAME">%s</xliff:g>?"</string>
+    <string name="error" msgid="8940763624668513648">"Дошло је до грешке"</string>
     <string name="button_default" msgid="3988017840431881491">"Подразумевано"</string>
 </resources>
diff --git a/java/res/values-sv/strings.xml b/java/res/values-sv/strings.xml
index ef544a6..08aa9d9 100644
--- a/java/res/values-sv/strings.xml
+++ b/java/res/values-sv/strings.xml
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"Inte nu"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Samma indatastil finns redan: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Läge för studie av användbarhet"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Inställningar för vibrationslängd vid knapptryck"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Volyminställningar för knappljud"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Läs extern ordboksfil"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Inga ordboksfiler i mappen Hämtningar"</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Välj en ordboksfil att installera"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Vill du verkligen installera filen för <xliff:g id="LOCALE_NAME">%s</xliff:g>?"</string>
+    <string name="error" msgid="8940763624668513648">"Ett fel uppstod"</string>
     <string name="button_default" msgid="3988017840431881491">"Standard"</string>
 </resources>
diff --git a/java/res/values-sw/strings.xml b/java/res/values-sw/strings.xml
index 4bbe9c0..6aa0fe0 100644
--- a/java/res/values-sw/strings.xml
+++ b/java/res/values-sw/strings.xml
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"Sio sasa"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Mfumo sawa wa maingizo tayari upo: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modi ya uchunguzi wa utumizi"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Bonyeza mipangilio ya kipindi cha mtetemo"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Bonyeza mipangilio ya nguvu za sauti"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Soma faili ya nje ya kamusi"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Hakuna faili za kamusi katika folda ya Vipakuzi"</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Chagua faili ya kamusi ya kusakinisha"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Sakinisha faili hii kwa <xliff:g id="LOCALE_NAME">%s</xliff:g>?"</string>
+    <string name="error" msgid="8940763624668513648">"Kulikuwa na hitilafu"</string>
     <string name="button_default" msgid="3988017840431881491">"Chaguo-msingi"</string>
 </resources>
diff --git a/java/res/values-sw600dp/config.xml b/java/res/values-sw600dp/config.xml
index b47eacb..9527fd6 100644
--- a/java/res/values-sw600dp/config.xml
+++ b/java/res/values-sw600dp/config.xml
@@ -22,10 +22,10 @@
     <!-- Device form factor. This value must be aligned with {@link KeyboardId.FORM_FACTOR_TABLET7} -->
     <integer name="config_device_form_factor">1</integer>
     <bool name="config_enable_show_voice_key_option">false</bool>
-    <bool name="config_enable_show_popup_on_keypress_option">false</bool>
+    <bool name="config_enable_show_option_of_key_preview_popup">false</bool>
     <bool name="config_enable_bigram_suggestions_option">false</bool>
     <!-- Whether or not Popup on key press is enabled by default -->
-    <bool name="config_default_popup_preview">false</bool>
+    <bool name="config_default_key_preview_popup">false</bool>
     <bool name="config_default_sound_enabled">true</bool>
     <bool name="config_auto_correction_spacebar_led_enabled">false</bool>
     <!-- The language is never displayed if == 0, always displayed if < 0 -->
diff --git a/java/res/values-sw768dp/config.xml b/java/res/values-sw768dp/config.xml
index 5e79541..3c2c198 100644
--- a/java/res/values-sw768dp/config.xml
+++ b/java/res/values-sw768dp/config.xml
@@ -22,10 +22,10 @@
     <!-- Device form factor. This value must be aligned with {@link KeyboardId.FORM_FACTOR_TABLET10} -->
     <integer name="config_device_form_factor">2</integer>
     <bool name="config_enable_show_voice_key_option">false</bool>
-    <bool name="config_enable_show_popup_on_keypress_option">false</bool>
+    <bool name="config_enable_show_option_of_key_preview_popup">false</bool>
     <bool name="config_enable_bigram_suggestions_option">false</bool>
     <!-- Whether or not Popup on key press is enabled by default -->
-    <bool name="config_default_popup_preview">false</bool>
+    <bool name="config_default_key_preview_popup">false</bool>
     <bool name="config_default_sound_enabled">true</bool>
     <bool name="config_auto_correction_spacebar_led_enabled">false</bool>
     <!-- This configuration is the index of the array {@link KeyboardSwitcher.KEYBOARD_THEMES}. -->
diff --git a/java/res/values-th/strings.xml b/java/res/values-th/strings.xml
index a70500e..56b0223 100644
--- a/java/res/values-th/strings.xml
+++ b/java/res/values-th/strings.xml
@@ -144,6 +144,8 @@
     <string name="not_now" msgid="6172462888202790482">"ข้ามไปก่อน"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"รูปแบบการป้อนข้อมูลเดียวกันนี้มีอยู่แล้ว: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"โหมดศึกษาประโยชน์ในการใช้งาน"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"การตั้งค่าระยะเวลาการสั่นเมื่อกดแป้นพิมพ์"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"การตั้งค่าระดับเสียงเมื่อกดแป้นพิมพ์"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"อ่านไฟล์พจนานุกรมภายนอก"</string>
diff --git a/java/res/values-tl/strings.xml b/java/res/values-tl/strings.xml
index 3c93dd5..577fee3 100644
--- a/java/res/values-tl/strings.xml
+++ b/java/res/values-tl/strings.xml
@@ -144,6 +144,8 @@
     <string name="not_now" msgid="6172462888202790482">"Hindi ngayon"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Umiiral na ang parehong estilo ng input: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Study mode ng pagiging kapaki-pakinabang"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Mga setting ng tagal ng vibration ng keypress"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Mga setting ng volume ng tunog ng keypress"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Magbasa ng panlabas na file ng diksyunaryo"</string>
diff --git a/java/res/values-tr/strings.xml b/java/res/values-tr/strings.xml
index f2c5f24..fe35aae 100644
--- a/java/res/values-tr/strings.xml
+++ b/java/res/values-tr/strings.xml
@@ -144,6 +144,8 @@
     <string name="not_now" msgid="6172462888202790482">"Şimdi değil"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Aynı giriş stili zaten var: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Kullanılabilirlik çalışması modu"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Tuşa basma titreşim süresi ayarları"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Tuşa basma ses düzeyi ayarları"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Harici sözlük dosyasını oku"</string>
diff --git a/java/res/values-uk/strings.xml b/java/res/values-uk/strings.xml
index f2de1be..12981f9 100644
--- a/java/res/values-uk/strings.xml
+++ b/java/res/values-uk/strings.xml
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"Не зараз"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Такий стиль введення вже існує: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Режим вивчення зручності у використанні"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Налаштування тривалості вібрації під час натискання клавіші"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Налаштування гучності звуку під час натискання клавіші"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Читати файл зовнішнього словника"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"У папці \"Завантаження\" немає файлів словника"</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Вибрати файл словника, який потрібно встановити"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Справді встановити цей файл для такої мови: <xliff:g id="LOCALE_NAME">%s</xliff:g>?"</string>
+    <string name="error" msgid="8940763624668513648">"Сталася помилка"</string>
     <string name="button_default" msgid="3988017840431881491">"За умовчанням"</string>
 </resources>
diff --git a/java/res/values-vi/strings.xml b/java/res/values-vi/strings.xml
index 7ba032f..abf2669 100644
--- a/java/res/values-vi/strings.xml
+++ b/java/res/values-vi/strings.xml
@@ -144,6 +144,8 @@
     <string name="not_now" msgid="6172462888202790482">"Để sau"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Đã tồn tại kiểu nhập tương tự: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Chế độ nghiên cứu tính khả dụng"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Cài đặt thời gian rung khi nhấn phím"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Cài đặt âm lượng khi nhấn phím"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Đọc tệp từ điển bên ngoài"</string>
diff --git a/java/res/values-zh-rCN/strings.xml b/java/res/values-zh-rCN/strings.xml
index b4ead85..51b4040 100644
--- a/java/res/values-zh-rCN/strings.xml
+++ b/java/res/values-zh-rCN/strings.xml
@@ -144,9 +144,11 @@
     <string name="not_now" msgid="6172462888202790482">"以后再说"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"已经存在相同的输入风格:<xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"可用性研究模式"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"按键振动持续时间设置"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"按键音量设置"</string>
-    <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"读取外部字典文件"</string>
+    <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"读取外部词典文件"</string>
     <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
     <skip />
     <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
diff --git a/java/res/values-zh-rTW/strings.xml b/java/res/values-zh-rTW/strings.xml
index 8d34ba2..de9fd2f 100644
--- a/java/res/values-zh-rTW/strings.xml
+++ b/java/res/values-zh-rTW/strings.xml
@@ -144,6 +144,8 @@
     <string name="not_now" msgid="6172462888202790482">"暫時不要"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"已存在相同的輸入樣式:<xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"使用習慣學習模式"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"按鍵震動持續時間設定"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"按鍵音量設定"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"讀取外部字典檔案"</string>
diff --git a/java/res/values-zu/strings.xml b/java/res/values-zu/strings.xml
index 660dab1..740eda1 100644
--- a/java/res/values-zu/strings.xml
+++ b/java/res/values-zu/strings.xml
@@ -144,16 +144,14 @@
     <string name="not_now" msgid="6172462888202790482">"Hhayi manje"</string>
     <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Isitayela sokufaka esifanayo sesivele sikhona: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
     <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Imodi yesitadi yokusebenziseka"</string>
+    <!-- no translation found for prefs_key_longpress_timeout_settings (1881822418815012326) -->
+    <skip />
     <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Izilungiselelo ze-keypress vibration duraton"</string>
     <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Izilungiselelo zevolumu yomsindo wekeypress"</string>
     <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Funda ifayela elangaphandle lesichazamazwi"</string>
-    <!-- no translation found for read_external_dictionary_no_files_message (4947420942224623792) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_multiple_files_title (7637749044265808628) -->
-    <skip />
-    <!-- no translation found for read_external_dictionary_confirm_install_message (6898610163768980870) -->
-    <skip />
-    <!-- no translation found for error (8940763624668513648) -->
-    <skip />
+    <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Awekho amafayela wesichazamazwi kufolda yokulandiwe"</string>
+    <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Khetha ifayela lesichazamazwi ukuze ulifake"</string>
+    <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Ufuna ukufakela i-<xliff:g id="LOCALE_NAME">%s</xliff:g> leli fayela ngokweqiniso?"</string>
+    <string name="error" msgid="8940763624668513648">"Kube nephutha"</string>
     <string name="button_default" msgid="3988017840431881491">"Okuzenzakalelayo"</string>
 </resources>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index 850b1b8..51a0758 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -83,6 +83,8 @@
         <attr name="touchNoiseThresholdDistance" format="dimension" />
         <!-- Sliding key input enable -->
         <attr name="slidingKeyInputEnable" format="boolean" />
+        <attr name="slidingKeyInputPreviewColor" format="color" />
+        <attr name="slidingKeyInputPreviewWidth" format="dimension" />
         <!-- Key repeat start timeout -->
         <attr name="keyRepeatStartTimeout" format="integer" />
         <!-- Key repeat interval in millisecond. -->
diff --git a/java/res/values/colors.xml b/java/res/values/colors.xml
index da4d87c..c0ea321 100644
--- a/java/res/values/colors.xml
+++ b/java/res/values/colors.xml
@@ -17,6 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
     <!-- Color resources for default, and Gingerbread theme. -->
     <color name="highlight_color_default">#FFFCAE00</color>
+    <color name="highlight_translucent_color_default">#99FCAE00</color>
     <color name="key_text_color_default">@android:color/white</color>
     <color name="key_text_shadow_color_default">#BB000000</color>
     <color name="key_text_inactivated_color_default">@android:color/white</color>
@@ -39,7 +40,9 @@
     <color name="spacebar_text_color_stone">@android:color/black</color>
     <color name="spacebar_text_shadow_color_stone">#D0FFFFFF</color>
     <!-- Color resources for IceCreamSandwich theme. -->
+    <!-- android:color/holo_blue_light value is #FF33B5E5 -->
     <color name="highlight_color_ics">@android:color/holo_blue_light</color>
+    <color name="highlight_translucent_color_ics">#9933B5E5</color>
     <color name="key_text_color_ics">@android:color/white</color>
     <color name="key_text_shadow_color_ics">@android:color/transparent</color>
     <color name="key_text_inactivated_color_ics">#66E0E4E5</color>
diff --git a/java/res/values/config.xml b/java/res/values/config.xml
index 6b3c891..d248a68 100644
--- a/java/res/values/config.xml
+++ b/java/res/values/config.xml
@@ -23,11 +23,11 @@
     <integer name="config_device_form_factor">0</integer>
     <bool name="config_use_fullscreen_mode">false</bool>
     <bool name="config_enable_show_voice_key_option">true</bool>
-    <bool name="config_enable_show_popup_on_keypress_option">true</bool>
+    <bool name="config_enable_show_option_of_key_preview_popup">true</bool>
     <!-- TODO: Disable the following configuration for production. -->
     <bool name="config_enable_usability_study_mode_option">true</bool>
     <!-- Whether or not Popup on key press is enabled by default -->
-    <bool name="config_default_popup_preview">true</bool>
+    <bool name="config_default_key_preview_popup">true</bool>
     <!-- Default value for next word prediction: after entering a word and a space only, should we look
          at input history to suggest a hopefully helpful suggestions for the next word? -->
     <bool name="config_default_next_word_prediction">true</bool>
@@ -46,14 +46,7 @@
     <!-- This configuration is the index of the array {@link KeyboardSwitcher.KEYBOARD_THEMES}. -->
     <string name="config_default_keyboard_theme_index" translatable="false">5</string>
     <integer name="config_max_more_keys_column">5</integer>
-    <!--
-         Configuration for KeyboardView
-    -->
-    <integer name="config_key_preview_linger_timeout">70</integer>
-    <integer name="config_gesture_floating_preview_text_linger_timeout">200</integer>
-    <integer name="config_gesture_preview_trail_fadeout_start_delay">100</integer>
-    <integer name="config_gesture_preview_trail_fadeout_duration">800</integer>
-    <integer name="config_gesture_preview_trail_update_interval">20</integer>
+
     <!--
          Configuration for MainKeyboardView
     -->
@@ -61,7 +54,10 @@
     <dimen name="config_key_hysteresis_distance_for_sliding_modifier">8.0dp</dimen>
     <integer name="config_touch_noise_threshold_time">40</integer>
     <dimen name="config_touch_noise_threshold_distance">12.6dp</dimen>
+    <integer name="config_key_preview_linger_timeout">70</integer>
     <bool name="config_sliding_key_input_enabled">true</bool>
+    <!-- Sliding key input preview parameters -->
+    <dimen name="config_sliding_key_input_preview_width">8.0dp</dimen>
     <integer name="config_key_repeat_start_timeout">400</integer>
     <integer name="config_key_repeat_interval">50</integer>
     <integer name="config_default_longpress_key_timeout">300</integer>  <!-- milliseconds -->
@@ -74,6 +70,10 @@
     <!-- Showing more keys keyboard, just above the touched point if true, aligned to the key if
          false -->
     <bool name="config_show_more_keys_keyboard_at_touched_point">false</bool>
+    <integer name="config_gesture_floating_preview_text_linger_timeout">200</integer>
+    <integer name="config_gesture_preview_trail_fadeout_start_delay">100</integer>
+    <integer name="config_gesture_preview_trail_fadeout_duration">800</integer>
+    <integer name="config_gesture_preview_trail_update_interval">20</integer>
     <!-- Static threshold for gesture after fast typing (msec) -->
     <integer name="config_gesture_static_time_threshold_after_fast_typing">500</integer>
     <!-- Static threshold for starting gesture detection (keyWidth%/sec) -->
diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml
index 36412b4..edf615a 100644
--- a/java/res/values/donottranslate.xml
+++ b/java/res/values/donottranslate.xml
@@ -120,18 +120,14 @@
     </string-array>
 
     <!-- Subtype locale display name exceptions.
-         For each exception, there should be related string resource for display name that has
-         explicit keyboard layout. The string resource name must be "subtype_with_layout_<locale>. -->
+         For each exception, there should be related string resources for display name that may have
+         explicit keyboard layout. The string resource name must be "subtype_<locale>" or
+         "subtype_with_layout_<locale>. Please refer to strings.xml for these resources. -->
     <string-array name="subtype_locale_exception_keys">
         <item>en_US</item>
         <item>en_GB</item>
         <item>es_US</item>
     </string-array>
-    <string-array name="subtype_locale_exception_values">
-        <item>English (US)</item>
-        <item>English (UK)</item>
-        <item>Español (EE.UU.)</item>
-    </string-array>
 
     <!-- Generic subtype label -->
     <string name="subtype_generic">%s</string>
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index e39cafc..1b518a1 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -69,6 +69,9 @@
     <!-- Option summary for showing language switch key [CHAR LIMIT=65] -->
     <string name="show_language_switch_key_summary">Show when multiple input languages are enabled</string>
 
+    <!-- Option to enable sliding key input preview. The user can see a rubber band during sliding key input. [CHAR LIMIT=30]-->
+    <string name="sliding_key_input_preview">Sliding key input preview</string>
+
     <!-- Option for the dismiss delay of the key popup [CHAR LIMIT=25] -->
     <string name="key_preview_popup_dismiss_delay">Key popup dismiss delay</string>
     <!-- Description for delay for dismissing a popup on keypress: no delay [CHAR LIMIT=15] -->
@@ -319,12 +322,17 @@
     <string name="subtype_en_GB">English (UK)</string>
     <!-- Description for English (United States) keyboard subtype [CHAR LIMIT=25] -->
     <string name="subtype_en_US">English (US)</string>
+    <!-- Description for Spanish (United States) keyboard subtype [CHAR LIMIT=25] -->
+    <string name="subtype_es_US">Spanish (US)</string>
     <!-- Description for English (United Kingdom) keyboard subtype with explicit keyboard layout [CHAR LIMIT=25]
          This should be identical to subtype_en_GB aside from the trailing (%s). -->
     <string name="subtype_with_layout_en_GB">English (UK) (<xliff:g id="layout">%s</xliff:g>)</string>
     <!-- Description for English (United States) keyboard subtype with explicit keyboard layout [CHAR LIMIT=25]
          This should be identical to subtype_en_US aside from the trailing (%s). -->
     <string name="subtype_with_layout_en_US">English (US) (<xliff:g id="layout">%s</xliff:g>)</string>
+    <!-- Description for Spanish (United States) keyboard subtype with explicit keyboard layout [CHAR LIMIT=25]
+         This should be identical to subtype_es_US aside from the trailing (%s). -->
+    <string name="subtype_with_layout_es_US">Spanish (US) (<xliff:g id="layout">%s</xliff:g>)</string>
     <!-- TODO: Uncomment once we can handle IETF language tag with script name specified.
          Description for Serbian Cyrillic keyboard subtype [CHAR LIMIT=25]
     <string name="subtype_serbian_cyrillic">Serbian (Cyrillic)</string>
diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml
index f71963a..f07f2d3 100644
--- a/java/res/values/styles.xml
+++ b/java/res/values/styles.xml
@@ -78,6 +78,8 @@
         <item name="touchNoiseThresholdTime">@integer/config_touch_noise_threshold_time</item>
         <item name="touchNoiseThresholdDistance">@dimen/config_touch_noise_threshold_distance</item>
         <item name="slidingKeyInputEnable">@bool/config_sliding_key_input_enabled</item>
+        <item name="slidingKeyInputPreviewColor">@color/highlight_translucent_color_default</item>
+        <item name="slidingKeyInputPreviewWidth">@dimen/config_sliding_key_input_preview_width</item>
         <item name="keyRepeatStartTimeout">@integer/config_key_repeat_start_timeout</item>
         <item name="keyRepeatInterval">@integer/config_key_repeat_interval</item>
         <item name="longPressShiftLockTimeout">@integer/config_longpress_shift_lock_timeout</item>
@@ -336,6 +338,7 @@
         <item name="keyPreviewOffset">@dimen/key_preview_offset_ics</item>
         <item name="keyTextShadowColor">@color/key_text_shadow_color_ics</item>
         <item name="keyTextShadowRadius">0.0</item>
+        <item name="slidingKeyInputPreviewColor">@color/highlight_translucent_color_ics</item>
         <item name="gestureFloatingPreviewTextColor">@color/highlight_color_ics</item>
         <item name="gesturePreviewTrailColor">@color/highlight_color_ics</item>
     </style>
diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml
index aa59c57..f30ef23 100644
--- a/java/res/xml/method.xml
+++ b/java/res/xml/method.xml
@@ -186,7 +186,7 @@
             android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
     />
     <subtype android:icon="@drawable/ic_subtype_keyboard"
-            android:label="@string/subtype_generic"
+            android:label="@string/subtype_es_US"
             android:subtypeId="0x84d2efc6"
             android:imeSubtypeLocale="es_US"
             android:imeSubtypeMode="keyboard"
diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index 84e7f54..da6e601 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -42,7 +42,7 @@
             android:key="popup_on"
             android:title="@string/popup_on_keypress"
             android:persistent="true"
-            android:defaultValue="@bool/config_default_popup_preview" />
+            android:defaultValue="@bool/config_default_key_preview_popup" />
         <ListPreference
             android:key="voice_mode"
             android:title="@string/voice_input"
@@ -142,6 +142,11 @@
                 android:key="custom_input_styles"
                 android:title="@string/custom_input_styles_title" />
             <!-- Values for popup dismiss delay are added programatically -->
+            <CheckBoxPreference
+                android:key="pref_sliding_key_input_preview"
+                android:title="@string/sliding_key_input_preview"
+                android:persistent="true"
+                android:defaultValue="true" />
             <ListPreference
                 android:key="pref_key_preview_popup_dismiss_delay"
                 android:title="@string/key_preview_popup_dismiss_delay" />
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index cf89ef2..1dd7b06 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -879,6 +879,10 @@
         mDrawingHandler.dismissKeyPreview(mKeyPreviewLingerTimeout, tracker);
     }
 
+    public void setSlidingKeyInputPreviewEnabled(final boolean enabled) {
+        mSlidingKeyInputPreview.setPreviewEnabled(enabled);
+    }
+
     @Override
     public void showSlidingKeyInputPreview(final PointerTracker tracker) {
         locatePreviewPlacerView();
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 1988bb8..d54b98c 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -951,12 +951,6 @@
             return;
         }
 
-        if (isShowingMoreKeysPanel()) {
-            final int translatedX = mMoreKeysPanel.translateX(x);
-            final int translatedY = mMoreKeysPanel.translateY(y);
-            mMoreKeysPanel.onMoveEvent(translatedX, translatedY, mPointerId, eventTime);
-        }
-
         if (sShouldHandleGesture && me != null) {
             // Add historical points to gesture path.
             final int pointerIndex = me.findPointerIndex(mPointerId);
@@ -971,7 +965,11 @@
         }
 
         if (isShowingMoreKeysPanel()) {
-            // Do not handle sliding keys (or show key pop-ups) when the MoreKeysPanel is visible.
+            final int translatedX = mMoreKeysPanel.translateX(x);
+            final int translatedY = mMoreKeysPanel.translateY(y);
+            mMoreKeysPanel.onMoveEvent(translatedX, translatedY, mPointerId, eventTime);
+            onMoveKey(x, y);
+            mDrawingProxy.showSlidingKeyInputPreview(this);
             return;
         }
         onMoveEventInternal(x, y, eventTime);
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingPreviewText.java b/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingPreviewText.java
index 0954a7a..28655a9 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingPreviewText.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingPreviewText.java
@@ -157,6 +157,7 @@
      */
     protected void updatePreviewPosition() {
         if (mSuggestedWords.isEmpty() || TextUtils.isEmpty(mSuggestedWords.getWord(0))) {
+            getDrawingView().invalidate();
             return;
         }
         final String text = mSuggestedWords.getWord(0);
diff --git a/java/src/com/android/inputmethod/keyboard/internal/SlidingKeyInputPreview.java b/java/src/com/android/inputmethod/keyboard/internal/SlidingKeyInputPreview.java
index 322f981..37f4e35 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/SlidingKeyInputPreview.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/SlidingKeyInputPreview.java
@@ -18,25 +18,40 @@
 
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
 import android.view.View;
 
 import com.android.inputmethod.keyboard.PointerTracker;
 import com.android.inputmethod.latin.CoordinateUtils;
+import com.android.inputmethod.latin.R;
 
 /**
  * Draw rubber band preview graphics during sliding key input.
  */
 public final class SlidingKeyInputPreview extends AbstractDrawingPreview {
+    private final int mPreviewWidth;
+
     private boolean mShowSlidingKeyInputPreview;
-    private final int[] mRubberBandFrom = CoordinateUtils.newInstance();
-    private final int[] mRubberBandTo = CoordinateUtils.newInstance();
+    private final int[] mPreviewFrom = CoordinateUtils.newInstance();
+    private final int[] mPreviewTo = CoordinateUtils.newInstance();
+
+    // TODO: Finalize the rubber band preview implementation.
+    private final RoundedLine mRoundedLine = new RoundedLine();
+    private final Paint mPaint = new Paint();
 
     public SlidingKeyInputPreview(final View drawingView, final TypedArray mainKeyboardViewAttr) {
         super(drawingView);
+        final int previewColor = mainKeyboardViewAttr.getColor(
+                R.styleable.MainKeyboardView_slidingKeyInputPreviewColor, 0);
+        mPreviewWidth = mainKeyboardViewAttr.getDimensionPixelSize(
+                R.styleable.MainKeyboardView_slidingKeyInputPreviewWidth, 0);
+        mPaint.setColor(previewColor);
     }
 
     public void dismissSlidingKeyInputPreview() {
         mShowSlidingKeyInputPreview = false;
+        getDrawingView().invalidate();
     }
 
     /**
@@ -45,10 +60,16 @@
      */
     @Override
     public void drawPreview(final Canvas canvas) {
-        if (!isPreviewEnabled() || mShowSlidingKeyInputPreview == false) {
+        if (!isPreviewEnabled() || !mShowSlidingKeyInputPreview) {
             return;
         }
-        // TODO: Implement rubber band preview
+
+        // TODO: Finalize the rubber band preview implementation.
+        final int radius = mPreviewWidth / 2;
+        final Path path = mRoundedLine.makePath(
+                CoordinateUtils.x(mPreviewFrom), CoordinateUtils.y(mPreviewFrom), radius,
+                CoordinateUtils.x(mPreviewTo), CoordinateUtils.y(mPreviewTo), radius);
+        canvas.drawPath(path, mPaint);
     }
 
     /**
@@ -61,8 +82,8 @@
             mShowSlidingKeyInputPreview = false;
             return;
         }
-        tracker.getDownCoordinates(mRubberBandFrom);
-        tracker.getLastCoordinates(mRubberBandTo);
+        tracker.getDownCoordinates(mPreviewFrom);
+        tracker.getLastCoordinates(mPreviewTo);
         mShowSlidingKeyInputPreview = true;
         getDrawingView().invalidate();
     }
diff --git a/java/src/com/android/inputmethod/latin/AdditionalSubtypeSettings.java b/java/src/com/android/inputmethod/latin/AdditionalSubtypeSettings.java
index a56c78b..f787722 100644
--- a/java/src/com/android/inputmethod/latin/AdditionalSubtypeSettings.java
+++ b/java/src/com/android/inputmethod/latin/AdditionalSubtypeSettings.java
@@ -72,7 +72,8 @@
         }
 
         public SubtypeLocaleItem(final String localeString) {
-            this(localeString, SubtypeLocale.getSubtypeLocaleDisplayName(localeString));
+            this(localeString,
+                    SubtypeLocale.getSubtypeLocaleDisplayNameInSystemLocale(localeString));
         }
 
         @Override
@@ -103,7 +104,7 @@
                 if (DEBUG_SUBTYPE_ID) {
                     android.util.Log.d(TAG, String.format("%-6s 0x%08x %11d %s",
                             subtype.getLocale(), subtype.hashCode(), subtype.hashCode(),
-                            SubtypeLocale.getSubtypeDisplayName(subtype)));
+                            SubtypeLocale.getSubtypeDisplayNameInSystemLocale(subtype)));
                 }
                 if (subtype.containsExtraValueKey(ASCII_CAPABLE)) {
                     items.add(createItem(context, subtype.getLocale()));
@@ -205,7 +206,8 @@
                 setDialogTitle(R.string.add_style);
                 setKey(KEY_NEW_SUBTYPE);
             } else {
-                final String displayName = SubtypeLocale.getSubtypeDisplayName(subtype);
+                final String displayName =
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(subtype);
                 setTitle(displayName);
                 setDialogTitle(displayName);
                 setKey(KEY_PREFIX + subtype.getLocale() + "_"
@@ -497,7 +499,7 @@
         final Context context = getActivity();
         final Resources res = context.getResources();
         final String message = res.getString(R.string.custom_input_style_already_exists,
-                SubtypeLocale.getSubtypeDisplayName(subtype));
+                SubtypeLocale.getSubtypeDisplayNameInSystemLocale(subtype));
         Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
     }
 
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 6b0d741..d6487cb 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -71,7 +71,6 @@
 import com.android.inputmethod.keyboard.KeyboardActionListener;
 import com.android.inputmethod.keyboard.KeyboardId;
 import com.android.inputmethod.keyboard.KeyboardSwitcher;
-import com.android.inputmethod.keyboard.KeyboardView;
 import com.android.inputmethod.keyboard.MainKeyboardView;
 import com.android.inputmethod.latin.Utils.Stats;
 import com.android.inputmethod.latin.define.ProductionFlag;
@@ -653,6 +652,7 @@
         super.onStartInputView(editorInfo, restarting);
         final KeyboardSwitcher switcher = mKeyboardSwitcher;
         final MainKeyboardView mainKeyboardView = switcher.getMainKeyboardView();
+        final SettingsValues currentSettings = mSettings.getCurrent();
 
         if (editorInfo == null) {
             Log.e(TAG, "Null EditorInfo in onStartInputView()");
@@ -706,7 +706,7 @@
             accessUtils.onStartInputViewInternal(mainKeyboardView, editorInfo, restarting);
         }
 
-        final boolean inputTypeChanged = !mSettings.getCurrent().isSameInputType(editorInfo);
+        final boolean inputTypeChanged = !currentSettings.isSameInputType(editorInfo);
         final boolean isDifferentTextField = !restarting || inputTypeChanged;
         if (isDifferentTextField) {
             mSubtypeSwitcher.updateParametersOnStartInputView();
@@ -737,12 +737,11 @@
             mainKeyboardView.closing();
             loadSettings();
 
-            if (mSuggest != null && mSettings.getCurrent().mCorrectionEnabled) {
-                mSuggest.setAutoCorrectionThreshold(
-                        mSettings.getCurrent().mAutoCorrectionThreshold);
+            if (mSuggest != null && currentSettings.mCorrectionEnabled) {
+                mSuggest.setAutoCorrectionThreshold(currentSettings.mAutoCorrectionThreshold);
             }
 
-            switcher.loadKeyboard(editorInfo, mSettings.getCurrent());
+            switcher.loadKeyboard(editorInfo, currentSettings);
         } else if (restarting) {
             // TODO: Come up with a more comprehensive way to reset the keyboard layout when
             // a keyboard layout set doesn't get reloaded in this method.
@@ -764,12 +763,14 @@
         mHandler.cancelDoubleSpacePeriodTimer();
 
         mainKeyboardView.setMainDictionaryAvailability(mIsMainDictionaryAvailable);
-        mainKeyboardView.setKeyPreviewPopupEnabled(mSettings.getCurrent().mKeyPreviewPopupOn,
-                mSettings.getCurrent().mKeyPreviewPopupDismissDelay);
+        mainKeyboardView.setKeyPreviewPopupEnabled(currentSettings.mKeyPreviewPopupOn,
+                currentSettings.mKeyPreviewPopupDismissDelay);
+        mainKeyboardView.setSlidingKeyInputPreviewEnabled(
+                currentSettings.mSlidingKeyInputPreviewEnabled);
         mainKeyboardView.setGestureHandlingEnabledByUser(
-                mSettings.getCurrent().mGestureInputEnabled);
-        mainKeyboardView.setGesturePreviewMode(mSettings.getCurrent().mGesturePreviewTrailEnabled,
-                mSettings.getCurrent().mGestureFloatingPreviewTextEnabled);
+                currentSettings.mGestureInputEnabled);
+        mainKeyboardView.setGesturePreviewMode(currentSettings.mGesturePreviewTrailEnabled,
+                currentSettings.mGestureFloatingPreviewTextEnabled);
 
         // If we have a user dictionary addition in progress, we should check now if we should
         // replace the previously committed string with the word that has actually been added
@@ -1480,6 +1481,7 @@
     @Override
     public void onStartBatchInput() {
         BatchInputUpdater.getInstance().onStartBatchInput(this);
+        mHandler.cancelUpdateSuggestionStrip();
         mConnection.beginBatchEdit();
         if (mWordComposer.isComposingWord()) {
             if (ProductionFlag.IS_INTERNAL) {
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index 408ea4a..02b44c7 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -55,6 +55,7 @@
     public static final String PREF_BIGRAM_PREDICTIONS = "next_word_prediction";
     public static final String PREF_GESTURE_SETTINGS = "gesture_typing_settings";
     public static final String PREF_GESTURE_INPUT = "gesture_input";
+    public static final String PREF_SLIDING_KEY_INPUT_PREVIEW = "pref_sliding_key_input_preview";
     public static final String PREF_KEY_LONGPRESS_TIMEOUT = "pref_key_longpress_timeout";
     public static final String PREF_VIBRATION_DURATION_SETTINGS =
             "pref_vibration_duration_settings";
@@ -125,13 +126,49 @@
     }
 
     // Accessed from the settings interface, hence public
+    public static boolean readKeypressSoundEnabled(final SharedPreferences prefs,
+            final Resources res) {
+        return prefs.getBoolean(Settings.PREF_SOUND_ON,
+                res.getBoolean(R.bool.config_default_sound_enabled));
+    }
+
+    public static boolean readVibrationEnabled(final SharedPreferences prefs,
+            final Resources res) {
+        final boolean hasVibrator = AudioAndHapticFeedbackManager.getInstance().hasVibrator();
+        return hasVibrator && prefs.getBoolean(PREF_VIBRATE_ON,
+                res.getBoolean(R.bool.config_default_vibration_enabled));
+    }
+
+    public static boolean readAutoCorrectEnabled(final String currentAutoCorrectionSetting,
+            final Resources res) {
+        final String autoCorrectionOff = res.getString(
+                R.string.auto_correction_threshold_mode_index_off);
+        return !currentAutoCorrectionSetting.equals(autoCorrectionOff);
+    }
+
+    public static boolean readFromBuildConfigIfGestureInputEnabled(final Resources res) {
+        return res.getBoolean(R.bool.config_gesture_input_enabled_by_build_config);
+    }
+
+    public static boolean readGestureInputEnabled(final SharedPreferences prefs,
+            final Resources res) {
+        return readFromBuildConfigIfGestureInputEnabled(res)
+                && prefs.getBoolean(Settings.PREF_GESTURE_INPUT, true);
+    }
+
+    public static boolean readFromBuildConfigIfToShowKeyPreviewPopupSettingsOption(
+            final Resources res) {
+        return res.getBoolean(R.bool.config_enable_show_option_of_key_preview_popup);
+    }
+
     public static boolean readKeyPreviewPopupEnabled(final SharedPreferences prefs,
             final Resources res) {
-        final boolean showPopupOption = res.getBoolean(
-                R.bool.config_enable_show_popup_on_keypress_option);
-        if (!showPopupOption) return res.getBoolean(R.bool.config_default_popup_preview);
-        return prefs.getBoolean(PREF_POPUP_ON,
-                res.getBoolean(R.bool.config_default_popup_preview));
+        final boolean defaultKeyPreviewPopup = res.getBoolean(
+                R.bool.config_default_key_preview_popup);
+        if (!readFromBuildConfigIfToShowKeyPreviewPopupSettingsOption(res)) {
+            return defaultKeyPreviewPopup;
+        }
+        return prefs.getBoolean(PREF_POPUP_ON, defaultKeyPreviewPopup);
     }
 
     public static int readKeyPreviewPopupDismissDelay(final SharedPreferences prefs,
diff --git a/java/src/com/android/inputmethod/latin/SettingsFragment.java b/java/src/com/android/inputmethod/latin/SettingsFragment.java
index 3ba24fb..edd064c 100644
--- a/java/src/com/android/inputmethod/latin/SettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/SettingsFragment.java
@@ -41,7 +41,6 @@
     private ListPreference mKeyPreviewPopupDismissDelay;
     // Use bigrams to predict the next word when there is no input for it yet
     private CheckBoxPreference mBigramPrediction;
-    private Preference mDebugSettingsPreference;
 
     private void setPreferenceEnabled(final String preferenceKey, final boolean enabled) {
         final Preference preference = findPreference(preferenceKey);
@@ -50,11 +49,14 @@
         }
     }
 
-    private void ensureConsistencyOfAutoCorrectionSettings() {
-        final String autoCorrectionOff = getResources().getString(
-                R.string.auto_correction_threshold_mode_index_off);
-        final String currentSetting = mAutoCorrectionThresholdPreference.getValue();
-        mBigramPrediction.setEnabled(!currentSetting.equals(autoCorrectionOff));
+    private static void removePreference(final String preferenceKey, final PreferenceGroup parent) {
+        if (parent == null) {
+            return;
+        }
+        final Preference preference = parent.findPreference(preferenceKey);
+        if (preference != null) {
+            parent.removePreference(preference);
+        }
     }
 
     @Override
@@ -84,22 +86,18 @@
 
         final PreferenceGroup generalSettings =
                 (PreferenceGroup) findPreference(Settings.PREF_GENERAL_SETTINGS);
-        final PreferenceGroup textCorrectionGroup =
-                (PreferenceGroup) findPreference(Settings.PREF_CORRECTION_SETTINGS);
-        final PreferenceGroup gestureTypingSettings =
-                (PreferenceGroup) findPreference(Settings.PREF_GESTURE_SETTINGS);
         final PreferenceGroup miscSettings =
                 (PreferenceGroup) findPreference(Settings.PREF_MISC_SETTINGS);
 
-        mDebugSettingsPreference = findPreference(Settings.PREF_DEBUG_SETTINGS);
-        if (mDebugSettingsPreference != null) {
+        final Preference debugSettings = findPreference(Settings.PREF_DEBUG_SETTINGS);
+        if (debugSettings != null) {
             if (ProductionFlag.IS_INTERNAL) {
                 final Intent debugSettingsIntent = new Intent(Intent.ACTION_MAIN);
                 debugSettingsIntent.setClassName(
                         context.getPackageName(), DebugSettingsActivity.class.getName());
-                mDebugSettingsPreference.setIntent(debugSettingsIntent);
+                debugSettings.setIntent(debugSettingsIntent);
             } else {
-                miscSettings.removePreference(mDebugSettingsPreference);
+                miscSettings.removePreference(debugSettings);
             }
         }
 
@@ -112,32 +110,26 @@
         final PreferenceGroup advancedSettings =
                 (PreferenceGroup) findPreference(Settings.PREF_ADVANCED_SETTINGS);
         if (!AudioAndHapticFeedbackManager.getInstance().hasVibrator()) {
-            generalSettings.removePreference(findPreference(Settings.PREF_VIBRATE_ON));
-            if (null != advancedSettings) { // Theoretically advancedSettings cannot be null
-                advancedSettings.removePreference(
-                        findPreference(Settings.PREF_VIBRATION_DURATION_SETTINGS));
-            }
+            removePreference(Settings.PREF_VIBRATE_ON, generalSettings);
+            removePreference(Settings.PREF_VIBRATION_DURATION_SETTINGS, advancedSettings);
         }
 
-        final boolean showKeyPreviewPopupOption = res.getBoolean(
-                R.bool.config_enable_show_popup_on_keypress_option);
         mKeyPreviewPopupDismissDelay =
                 (ListPreference) findPreference(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY);
-        if (!showKeyPreviewPopupOption) {
-            generalSettings.removePreference(findPreference(Settings.PREF_POPUP_ON));
-            if (null != advancedSettings) { // Theoretically advancedSettings cannot be null
-                advancedSettings.removePreference(mKeyPreviewPopupDismissDelay);
-            }
+        if (!Settings.readFromBuildConfigIfToShowKeyPreviewPopupSettingsOption(res)) {
+            removePreference(Settings.PREF_POPUP_ON, generalSettings);
+            removePreference(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY, advancedSettings);
         } else {
-            final String[] entries = new String[] {
-                    res.getString(R.string.key_preview_popup_dismiss_no_delay),
-                    res.getString(R.string.key_preview_popup_dismiss_default_delay),
-            };
             final String popupDismissDelayDefaultValue = Integer.toString(res.getInteger(
                     R.integer.config_key_preview_linger_timeout));
-            mKeyPreviewPopupDismissDelay.setEntries(entries);
-            mKeyPreviewPopupDismissDelay.setEntryValues(
-                    new String[] { "0", popupDismissDelayDefaultValue });
+            mKeyPreviewPopupDismissDelay.setEntries(new String[] {
+                    res.getString(R.string.key_preview_popup_dismiss_no_delay),
+                    res.getString(R.string.key_preview_popup_dismiss_default_delay),
+            });
+            mKeyPreviewPopupDismissDelay.setEntryValues(new String[] {
+                    "0",
+                    popupDismissDelayDefaultValue
+            });
             if (null == mKeyPreviewPopupDismissDelay.getValue()) {
                 mKeyPreviewPopupDismissDelay.setValue(popupDismissDelayDefaultValue);
             }
@@ -148,20 +140,19 @@
         setPreferenceEnabled(Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST,
                 Settings.readShowsLanguageSwitchKey(prefs));
 
+        final PreferenceGroup textCorrectionGroup =
+                (PreferenceGroup) findPreference(Settings.PREF_CORRECTION_SETTINGS);
         final PreferenceScreen dictionaryLink =
                 (PreferenceScreen) findPreference(Settings.PREF_CONFIGURE_DICTIONARIES_KEY);
         final Intent intent = dictionaryLink.getIntent();
-
         final int number = context.getPackageManager().queryIntentActivities(intent, 0).size();
         // TODO: The experimental version is not supported by the Dictionary Pack Service yet
         if (ProductionFlag.IS_EXPERIMENTAL || 0 >= number) {
             textCorrectionGroup.removePreference(dictionaryLink);
         }
 
-        final boolean gestureInputEnabledByBuildConfig = res.getBoolean(
-                R.bool.config_gesture_input_enabled_by_build_config);
-        if (!gestureInputEnabledByBuildConfig) {
-            getPreferenceScreen().removePreference(gestureTypingSettings);
+        if (!Settings.readFromBuildConfigIfGestureInputEnabled(res)) {
+            removePreference(Settings.PREF_GESTURE_SETTINGS, getPreferenceScreen());
         }
 
         setupKeyLongpressTimeoutSettings(prefs, res);
@@ -194,23 +185,17 @@
     @Override
     public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
         (new BackupManager(getActivity())).dataChanged();
+        final Resources res = getResources();
         if (key.equals(Settings.PREF_POPUP_ON)) {
             setPreferenceEnabled(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY,
-                    prefs.getBoolean(Settings.PREF_POPUP_ON, true));
+                    Settings.readKeyPreviewPopupEnabled(prefs, res));
         } else if (key.equals(Settings.PREF_SHOW_LANGUAGE_SWITCH_KEY)) {
             setPreferenceEnabled(Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST,
                     Settings.readShowsLanguageSwitchKey(prefs));
         } else if (key.equals(Settings.PREF_GESTURE_INPUT)) {
-            final boolean gestureInputEnabledByConfig = getResources().getBoolean(
-                    R.bool.config_gesture_input_enabled_by_build_config);
-            if (gestureInputEnabledByConfig) {
-                final boolean gestureInputEnabledByUser = prefs.getBoolean(
-                        Settings.PREF_GESTURE_INPUT, true);
-                setPreferenceEnabled(Settings.PREF_GESTURE_PREVIEW_TRAIL,
-                        gestureInputEnabledByUser);
-                setPreferenceEnabled(Settings.PREF_GESTURE_FLOATING_PREVIEW_TEXT,
-                        gestureInputEnabledByUser);
-            }
+            final boolean gestureInputEnabled = Settings.readGestureInputEnabled(prefs, res);
+            setPreferenceEnabled(Settings.PREF_GESTURE_PREVIEW_TRAIL, gestureInputEnabled);
+            setPreferenceEnabled(Settings.PREF_GESTURE_FLOATING_PREVIEW_TEXT, gestureInputEnabled);
         }
         ensureConsistencyOfAutoCorrectionSettings();
         updateVoiceModeSummary();
@@ -219,6 +204,13 @@
         refreshEnablingsOfKeypressSoundAndVibrationSettings(prefs, getResources());
     }
 
+    private void ensureConsistencyOfAutoCorrectionSettings() {
+        final String autoCorrectionOff = getResources().getString(
+                R.string.auto_correction_threshold_mode_index_off);
+        final String currentSetting = mAutoCorrectionThresholdPreference.getValue();
+        mBigramPrediction.setEnabled(!currentSetting.equals(autoCorrectionOff));
+    }
+
     private void updateShowCorrectionSuggestionsSummary() {
         mShowCorrectionSuggestionsPreference.setSummary(
                 getResources().getStringArray(R.array.prefs_suggestion_visibilities)
@@ -237,7 +229,7 @@
         final StringBuilder styles = new StringBuilder();
         for (final InputMethodSubtype subtype : subtypes) {
             if (styles.length() > 0) styles.append(", ");
-            styles.append(SubtypeLocale.getSubtypeDisplayName(subtype));
+            styles.append(SubtypeLocale.getSubtypeDisplayNameInSystemLocale(subtype));
         }
         customInputStyles.setSummary(styles);
     }
@@ -257,16 +249,10 @@
 
     private void refreshEnablingsOfKeypressSoundAndVibrationSettings(
             final SharedPreferences sp, final Resources res) {
-        final boolean hasVibratorHardware =
-                AudioAndHapticFeedbackManager.getInstance().hasVibrator();
-        final boolean vibrateOnByUser = sp.getBoolean(Settings.PREF_VIBRATE_ON,
-                res.getBoolean(R.bool.config_default_vibration_enabled));
         setPreferenceEnabled(Settings.PREF_VIBRATION_DURATION_SETTINGS,
-                hasVibratorHardware && vibrateOnByUser);
-
-        final boolean soundOn = sp.getBoolean(Settings.PREF_SOUND_ON,
-                res.getBoolean(R.bool.config_default_sound_enabled));
-        setPreferenceEnabled(Settings.PREF_KEYPRESS_SOUND_VOLUME, soundOn);
+                Settings.readVibrationEnabled(sp, res));
+        setPreferenceEnabled(Settings.PREF_KEYPRESS_SOUND_VOLUME,
+                Settings.readKeypressSoundEnabled(sp, res));
     }
 
     private void setupKeypressVibrationDurationSettings(final SharedPreferences sp,
diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java
index 29e79e4..728f6b2 100644
--- a/java/src/com/android/inputmethod/latin/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/SettingsValues.java
@@ -59,6 +59,7 @@
     public final boolean mGestureInputEnabled;
     public final boolean mGesturePreviewTrailEnabled;
     public final boolean mGestureFloatingPreviewTextEnabled;
+    public final boolean mSlidingKeyInputPreviewEnabled;
     public final int mKeyLongpressTimeout;
 
     // From the input box
@@ -103,10 +104,11 @@
 
         // Get the settings preferences
         mAutoCap = prefs.getBoolean(Settings.PREF_AUTO_CAP, true);
-        mVibrateOn = readVibrationEnabled(prefs, res);
-        mSoundOn = prefs.getBoolean(Settings.PREF_SOUND_ON,
-                res.getBoolean(R.bool.config_default_sound_enabled));
+        mVibrateOn = Settings.readVibrationEnabled(prefs, res);
+        mSoundOn = Settings.readKeypressSoundEnabled(prefs, res);
         mKeyPreviewPopupOn = Settings.readKeyPreviewPopupEnabled(prefs, res);
+        mSlidingKeyInputPreviewEnabled = prefs.getBoolean(
+                Settings.PREF_SLIDING_KEY_INPUT_PREVIEW, true);
         final String voiceModeMain = res.getString(R.string.voice_mode_main);
         final String voiceModeOff = res.getString(R.string.voice_mode_off);
         mVoiceMode = prefs.getString(Settings.PREF_VOICE_MODE, voiceModeMain);
@@ -118,7 +120,7 @@
         mShowsLanguageSwitchKey = Settings.readShowsLanguageSwitchKey(prefs);
         mUseContactsDict = prefs.getBoolean(Settings.PREF_KEY_USE_CONTACTS_DICT, true);
         mUseDoubleSpacePeriod = prefs.getBoolean(Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, true);
-        mAutoCorrectEnabled = readAutoCorrectEnabled(res, autoCorrectionThresholdRawValue);
+        mAutoCorrectEnabled = Settings.readAutoCorrectEnabled(autoCorrectionThresholdRawValue, res);
         mBigramPredictionEnabled = readBigramPredictionEnabled(prefs, res);
 
         // Compute other readable settings
@@ -130,10 +132,7 @@
                 autoCorrectionThresholdRawValue);
         mVoiceKeyEnabled = mVoiceMode != null && !mVoiceMode.equals(voiceModeOff);
         mVoiceKeyOnMain = mVoiceMode != null && mVoiceMode.equals(voiceModeMain);
-        final boolean gestureInputEnabledByBuildConfig = res.getBoolean(
-                R.bool.config_gesture_input_enabled_by_build_config);
-        mGestureInputEnabled = gestureInputEnabledByBuildConfig
-                && prefs.getBoolean(Settings.PREF_GESTURE_INPUT, true);
+        mGestureInputEnabled = Settings.readGestureInputEnabled(prefs, res);
         mGesturePreviewTrailEnabled = prefs.getBoolean(Settings.PREF_GESTURE_PREVIEW_TRAIL, true);
         mGestureFloatingPreviewTextEnabled = prefs.getBoolean(
                 Settings.PREF_GESTURE_FLOATING_PREVIEW_TEXT, true);
@@ -247,20 +246,6 @@
         throw new RuntimeException("Bug: visibility string is not configured correctly");
     }
 
-    private static boolean readVibrationEnabled(final SharedPreferences prefs,
-            final Resources res) {
-        final boolean hasVibrator = AudioAndHapticFeedbackManager.getInstance().hasVibrator();
-        return hasVibrator && prefs.getBoolean(Settings.PREF_VIBRATE_ON,
-                res.getBoolean(R.bool.config_default_vibration_enabled));
-    }
-
-    private static boolean readAutoCorrectEnabled(final Resources res,
-            final String currentAutoCorrectionSetting) {
-        final String autoCorrectionOff = res.getString(
-                R.string.auto_correction_threshold_mode_index_off);
-        return !currentAutoCorrectionSetting.equals(autoCorrectionOff);
-    }
-
     private static boolean readBigramPredictionEnabled(final SharedPreferences prefs,
             final Resources res) {
         return prefs.getBoolean(Settings.PREF_BIGRAM_PREDICTIONS, res.getBoolean(
diff --git a/java/src/com/android/inputmethod/latin/SubtypeLocale.java b/java/src/com/android/inputmethod/latin/SubtypeLocale.java
index 068c34e..2f26f92 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeLocale.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeLocale.java
@@ -51,20 +51,22 @@
     private static final HashMap<String, Integer> sKeyboardLayoutToNameIdsMap =
             CollectionUtils.newHashMap();
     // Exceptional locale to subtype name resource id map.
+    private static final HashMap<String, Integer> sExceptionalLocaleToNameIdsMap =
+            CollectionUtils.newHashMap();
+    // Exceptional locale to subtype name with layout resource id map.
     private static final HashMap<String, Integer> sExceptionalLocaleToWithLayoutNameIdsMap =
             CollectionUtils.newHashMap();
+    private static final String SUBTYPE_NAME_RESOURCE_PREFIX =
+            "string/subtype_";
     private static final String SUBTYPE_NAME_RESOURCE_GENERIC_PREFIX =
             "string/subtype_generic_";
     private static final String SUBTYPE_NAME_RESOURCE_WITH_LAYOUT_PREFIX =
             "string/subtype_with_layout_";
     private static final String SUBTYPE_NAME_RESOURCE_NO_LANGUAGE_PREFIX =
             "string/subtype_no_language_";
-    // Exceptional locales to display name map.
-    private static final HashMap<String, String> sExceptionalDisplayNamesMap =
-            CollectionUtils.newHashMap();
     // Keyboard layout set name for the subtypes that don't have a keyboardLayoutSet extra value.
     // This is for compatibility to keep the same subtype ids as pre-JellyBean.
-    private static final HashMap<String,String> sLocaleAndExtraValueToKeyboardLayoutSetMap =
+    private static final HashMap<String, String> sLocaleAndExtraValueToKeyboardLayoutSetMap =
             CollectionUtils.newHashMap();
 
     private SubtypeLocale() {
@@ -98,14 +100,16 @@
 
         final String[] exceptionalLocales = res.getStringArray(
                 R.array.subtype_locale_exception_keys);
-        final String[] exceptionalDisplayNames = res.getStringArray(
-                R.array.subtype_locale_exception_values);
         for (int i = 0; i < exceptionalLocales.length; i++) {
             final String localeString = exceptionalLocales[i];
-            sExceptionalDisplayNamesMap.put(localeString, exceptionalDisplayNames[i]);
-            final String resourceName = SUBTYPE_NAME_RESOURCE_WITH_LAYOUT_PREFIX + localeString;
+            final String resourceName = SUBTYPE_NAME_RESOURCE_PREFIX + localeString;
             final int resId = res.getIdentifier(resourceName, null, RESOURCE_PACKAGE_NAME);
-            sExceptionalLocaleToWithLayoutNameIdsMap.put(localeString, resId);
+            sExceptionalLocaleToNameIdsMap.put(localeString, resId);
+            final String resourceNameWithLayout =
+                    SUBTYPE_NAME_RESOURCE_WITH_LAYOUT_PREFIX + localeString;
+            final int resIdWithLayout = res.getIdentifier(
+                    resourceNameWithLayout, null, RESOURCE_PACKAGE_NAME);
+            sExceptionalLocaleToWithLayoutNameIdsMap.put(localeString, resIdWithLayout);
         }
 
         final String[] keyboardLayoutSetMap = res.getStringArray(
@@ -124,7 +128,7 @@
     }
 
     public static boolean isExceptionalLocale(final String localeString) {
-        return sExceptionalLocaleToWithLayoutNameIdsMap.containsKey(localeString);
+        return sExceptionalLocaleToNameIdsMap.containsKey(localeString);
     }
 
     private static final String getNoLanguageLayoutKey(final String keyboardLayoutName) {
@@ -143,13 +147,33 @@
         return nameId == null ? UNKNOWN_KEYBOARD_LAYOUT : nameId;
     }
 
+    public static String getSubtypeLocaleDisplayNameInSystemLocale(final String localeString) {
+        final Locale displayLocale = sResources.getConfiguration().locale;
+        return getSubtypeLocaleDisplayNameInternal(localeString, displayLocale);
+    }
+
     public static String getSubtypeLocaleDisplayName(final String localeString) {
-        final String exceptionalValue = sExceptionalDisplayNamesMap.get(localeString);
-        if (exceptionalValue != null) {
-            return exceptionalValue;
-        }
+        final Locale displayLocale = LocaleUtils.constructLocaleFromString(localeString);
+        return getSubtypeLocaleDisplayNameInternal(localeString, displayLocale);
+    }
+
+    private static String getSubtypeLocaleDisplayNameInternal(final String localeString,
+            final Locale displayLocale) {
         final Locale locale = LocaleUtils.constructLocaleFromString(localeString);
-        return StringUtils.toTitleCase(locale.getDisplayName(locale), locale);
+        final Integer exceptionalNameResId = sExceptionalLocaleToNameIdsMap.get(localeString);
+        final String displayName;
+        if (exceptionalNameResId != null) {
+            final RunInLocale<String> getExceptionalName = new RunInLocale<String>() {
+                @Override
+                protected String job(final Resources res) {
+                    return res.getString(exceptionalNameResId);
+                }
+            };
+            displayName = getExceptionalName.runInLocale(sResources, displayLocale);
+        } else {
+            displayName = locale.getDisplayName(displayLocale);
+        }
+        return StringUtils.toTitleCase(displayName, displayLocale);
     }
 
     // InputMethodSubtype's display name in its locale.
@@ -165,24 +189,36 @@
     //  zz    qwerty  F  No language (QWERTY)    in system locale
     //  fr    qwertz  T  Français (QWERTZ)
     //  de    qwerty  T  Deutsch (QWERTY)
-    //  en_US azerty  T  English (US) (AZERTY)
+    //  en_US azerty  T  English (US) (AZERTY)   exception
     //  zz    azerty  T  No language (AZERTY)    in system locale
 
-    private static String getReplacementString(final InputMethodSubtype subtype) {
+    private static String getReplacementString(final InputMethodSubtype subtype,
+            final Locale displayLocale) {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
                 && subtype.containsExtraValueKey(UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME)) {
             return subtype.getExtraValueOf(UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME);
         } else {
-            return getSubtypeLocaleDisplayName(subtype.getLocale());
+            return getSubtypeLocaleDisplayNameInternal(subtype.getLocale(), displayLocale);
         }
     }
 
+    public static String getSubtypeDisplayNameInSystemLocale(final InputMethodSubtype subtype) {
+        final Locale subtypeLocale = sResources.getConfiguration().locale;
+        return getSubtypeDisplayNameInternal(subtype, subtypeLocale);
+    }
+
     public static String getSubtypeDisplayName(final InputMethodSubtype subtype) {
-        final String replacementString = getReplacementString(subtype);
+        final Locale subtypeLocale = LocaleUtils.constructLocaleFromString(subtype.getLocale());
+        return getSubtypeDisplayNameInternal(subtype, subtypeLocale);
+    }
+
+    private static String getSubtypeDisplayNameInternal(final InputMethodSubtype subtype,
+            final Locale displayLocale) {
+        final String replacementString = getReplacementString(subtype, displayLocale);
         final int nameResId = subtype.getNameResId();
         final RunInLocale<String> getSubtypeName = new RunInLocale<String>() {
             @Override
-            protected String job(Resources res) {
+            protected String job(final Resources res) {
                 try {
                     return res.getString(nameResId, replacementString);
                 } catch (Resources.NotFoundException e) {
@@ -197,8 +233,9 @@
             }
         };
         final Locale locale = isNoLanguage(subtype)
-                ? sResources.getConfiguration().locale : getSubtypeLocale(subtype);
-        return getSubtypeName.runInLocale(sResources, locale);
+                ? sResources.getConfiguration().locale : displayLocale;
+        return StringUtils.toTitleCase(
+                getSubtypeName.runInLocale(sResources, locale), locale);
     }
 
     public static boolean isNoLanguage(final InputMethodSubtype subtype) {
diff --git a/java/src/com/android/inputmethod/research/FixedLogBuffer.java b/java/src/com/android/inputmethod/research/FixedLogBuffer.java
index 73f284a..78dc595 100644
--- a/java/src/com/android/inputmethod/research/FixedLogBuffer.java
+++ b/java/src/com/android/inputmethod/research/FixedLogBuffer.java
@@ -61,7 +61,7 @@
      */
     @Override
     public void shiftIn(final LogUnit newLogUnit) {
-        if (newLogUnit.getWord() == null) {
+        if (!newLogUnit.hasWord()) {
             // This LogUnit isn't a word, so it doesn't count toward the word-limit.
             super.shiftIn(newLogUnit);
             return;
@@ -153,8 +153,7 @@
         for (int i = 0; i < length && n > 0; i++) {
             final LogUnit logUnit = logUnits.get(i);
             list.add(logUnit);
-            final String word = logUnit.getWord();
-            if (word != null) {
+            if (logUnit.hasWord()) {
                 n--;
             }
         }
diff --git a/java/src/com/android/inputmethod/research/LogUnit.java b/java/src/com/android/inputmethod/research/LogUnit.java
index 0234bbc..638b7d9 100644
--- a/java/src/com/android/inputmethod/research/LogUnit.java
+++ b/java/src/com/android/inputmethod/research/LogUnit.java
@@ -286,7 +286,7 @@
      * string.
      */
     public void setWord(final String word) {
-        if (mWord != null) {
+        if (hasWord()) {
             // The word was already set once, and it is now being changed.  See if the new word
             // is close to the old word.  If so, then the change is probably a typo correction.
             // If not, the user may have decided to enter a different word, so flag it.
@@ -310,7 +310,7 @@
     }
 
     public boolean hasWord() {
-        return mWord != null;
+        return mWord != null && !TextUtils.isEmpty(mWord.trim());
     }
 
     public void setMayContainDigit() {
diff --git a/java/src/com/android/inputmethod/research/MainLogBuffer.java b/java/src/com/android/inputmethod/research/MainLogBuffer.java
index 57d5c41..3a87bf1 100644
--- a/java/src/com/android/inputmethod/research/MainLogBuffer.java
+++ b/java/src/com/android/inputmethod/research/MainLogBuffer.java
@@ -117,20 +117,19 @@
         if (IS_LOGGING_EVERYTHING) {
             if (mIsStopping) {
                 return true;
-            } else {
-                // Only check that it is the right length.  If not, wait for later words to make
-                // complete n-grams.
-                int numWordsInLogUnitList = 0;
-                final int length = logUnits.size();
-                for (int i = 0; i < length; i++) {
-                    final LogUnit logUnit = logUnits.get(i);
-                    final String word = logUnit.getWord();
-                    if (word != null) {
-                        numWordsInLogUnitList++;
-                    }
-                }
-                return numWordsInLogUnitList >= minNGramSize;
             }
+            // Only check that it is the right length.  If not, wait for later words to make
+            // complete n-grams.
+            int numWordsInLogUnitList = 0;
+            final int length = logUnits.size();
+            for (int i = 0; i < length; i++) {
+                final LogUnit logUnit = logUnits.get(i);
+                final String word = logUnit.getWord();
+                if (word != null) {
+                    numWordsInLogUnitList++;
+                }
+            }
+            return numWordsInLogUnitList >= minNGramSize;
         }
 
         // Check that we are not sampling too frequently.  Having sampled recently might disclose
@@ -157,14 +156,14 @@
         final int length = logUnits.size();
         for (int i = 0; i < length; i++) {
             final LogUnit logUnit = logUnits.get(i);
-            final String word = logUnit.getWord();
-            if (word == null) {
+            if (!logUnit.hasWord()) {
                 // Digits outside words are a privacy threat.
                 if (logUnit.mayContainDigit()) {
                     return false;
                 }
             } else {
                 numWordsInLogUnitList++;
+                final String word = logUnit.getWord();
                 // Words not in the dictionary are a privacy threat.
                 if (ResearchLogger.hasLetters(word) && !(dictionary.isValidWord(word))) {
                     if (DEBUG) {
diff --git a/native/jni/src/char_utils.h b/native/jni/src/char_utils.h
index 60da203..7a4384d 100644
--- a/native/jni/src/char_utils.h
+++ b/native/jni/src/char_utils.h
@@ -72,5 +72,16 @@
     // TODO: Do not hardcode here
     return codePoint == KEYCODE_SINGLE_QUOTE || codePoint == KEYCODE_HYPHEN_MINUS;
 }
+
+inline static int getCodePointCount(const int arraySize, const int *const codePoints) {
+    int size = 0;
+    for (; size < arraySize; ++size) {
+        if (codePoints[size] == '\0') {
+            break;
+        }
+    }
+    return size;
+}
+
 } // namespace latinime
 #endif // LATINIME_CHAR_UTILS_H
diff --git a/native/jni/src/proximity_info_state.cpp b/native/jni/src/proximity_info_state.cpp
index 8c6a525..387b03a 100644
--- a/native/jni/src/proximity_info_state.cpp
+++ b/native/jni/src/proximity_info_state.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include <cstring> // for memset()
+#include <cstring> // for memset() and memcpy()
 #include <sstream> // for debug prints
 
 #define LOG_TAG "LatinIME: proximity_info_state.cpp"
@@ -33,8 +33,10 @@
         const ProximityInfo *proximityInfo, const int *const inputCodes, const int inputSize,
         const int *const xCoordinates, const int *const yCoordinates, const int *const times,
         const int *const pointerIds, const bool isGeometric) {
-    mIsContinuationPossible = checkAndReturnIsContinuationPossible(
-            inputSize, xCoordinates, yCoordinates, times, isGeometric);
+    ASSERT(isGeometric || (inputSize < MAX_WORD_LENGTH));
+    mIsContinuationPossible = ProximityInfoStateUtils::checkAndReturnIsContinuationPossible(
+            inputSize, xCoordinates, yCoordinates, times, mSampledInputSize, &mSampledInputXs,
+            &mSampledInputYs, &mSampledTimes, &mSampledInputIndice);
 
     mProximityInfo = proximityInfo;
     mHasTouchPositionCorrectionData = proximityInfo->hasTouchPositionCorrectionData();
@@ -57,12 +59,15 @@
     int pushTouchPointStartIndex = 0;
     int lastSavedInputSize = 0;
     mMaxPointToKeyLength = maxPointToKeyLength;
+    mSampledInputSize = 0;
+    mMostProbableStringProbability = 0.0f;
+
     if (mIsContinuationPossible && mSampledInputIndice.size() > 1) {
         // Just update difference.
-        // Two points prior is never skipped. Thus, we pop 2 input point data here.
-        pushTouchPointStartIndex = mSampledInputIndice[mSampledInputIndice.size() - 2];
-        popInputData();
-        popInputData();
+        // Previous two points are never skipped. Thus, we pop 2 input point data here.
+        pushTouchPointStartIndex = ProximityInfoStateUtils::trimLastTwoTouchPoints(
+                &mSampledInputXs, &mSampledInputYs, &mSampledTimes, &mSampledLengthCache,
+                &mSampledInputIndice);
         lastSavedInputSize = mSampledInputXs.size();
     } else {
         // Clear all data.
@@ -79,11 +84,11 @@
         mCharProbabilities.clear();
         mDirections.clear();
     }
+
     if (DEBUG_GEO_FULL) {
         AKLOGI("Init ProximityInfoState: reused points =  %d, last input size = %d",
                 pushTouchPointStartIndex, lastSavedInputSize);
     }
-    mSampledInputSize = 0;
 
     if (xCoordinates && yCoordinates) {
         mSampledInputSize = ProximityInfoStateUtils::updateTouchPoints(
@@ -119,6 +124,9 @@
             ProximityInfoStateUtils::updateSampledSearchKeysVector(mProximityInfo,
                     mSampledInputSize, lastSavedInputSize, &mSampledLengthCache,
                     &mSampledNearKeysVector, &mSampledSearchKeysVector);
+            mMostProbableStringProbability = ProximityInfoStateUtils::getMostProbableString(
+                    mProximityInfo, mSampledInputSize, &mCharProbabilities, mMostProbableString);
+
         }
     }
 
@@ -130,8 +138,6 @@
     // end
     ///////////////////////
 
-    memset(mNormalizedSquaredDistances, NOT_A_DISTANCE, sizeof(mNormalizedSquaredDistances));
-    memset(mPrimaryInputWord, 0, sizeof(mPrimaryInputWord));
     mTouchPositionCorrectionEnabled = mSampledInputSize > 0 && mHasTouchPositionCorrectionData
             && xCoordinates && yCoordinates;
     if (!isGeometric && pointerId == 0) {
@@ -140,8 +146,7 @@
         if (mTouchPositionCorrectionEnabled) {
             ProximityInfoStateUtils::initNormalizedSquaredDistances(
                     mProximityInfo, inputSize, xCoordinates, yCoordinates, mInputProximities,
-                    hasInputCoordinates(), &mSampledInputXs, &mSampledInputYs,
-                    mNormalizedSquaredDistances);
+                    &mSampledInputXs, &mSampledInputYs, mNormalizedSquaredDistances);
         }
     }
     if (DEBUG_GEO_FULL) {
@@ -149,39 +154,6 @@
     }
 }
 
-bool ProximityInfoState::checkAndReturnIsContinuationPossible(const int inputSize,
-        const int *const xCoordinates, const int *const yCoordinates, const int *const times,
-        const bool isGeometric) const {
-    if (isGeometric) {
-        for (int i = 0; i < mSampledInputSize; ++i) {
-            const int index = mSampledInputIndice[i];
-            if (index > inputSize || xCoordinates[index] != mSampledInputXs[i] ||
-                    yCoordinates[index] != mSampledInputYs[i] || times[index] != mSampledTimes[i]) {
-                return false;
-            }
-        }
-    } else {
-        if (inputSize < mSampledInputSize) {
-            // Assuming the cache is invalid if the previous input size is larger than the new one.
-            return false;
-        }
-        for (int i = 0; i < mSampledInputSize && i < MAX_WORD_LENGTH; ++i) {
-            if (xCoordinates[i] != mSampledInputXs[i]
-                    || yCoordinates[i] != mSampledInputYs[i]) {
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
-int ProximityInfoState::getDuration(const int index) const {
-    if (index >= 0 && index < mSampledInputSize - 1) {
-        return mSampledTimes[index + 1] - mSampledTimes[index];
-    }
-    return 0;
-}
-
 // TODO: Remove the "scale" parameter
 // This function basically converts from a length to an edit distance. Accordingly, it's obviously
 // wrong to compare with mMaxPointToKeyLength.
@@ -309,16 +281,10 @@
 }
 
 bool ProximityInfoState::isKeyInSerchKeysAfterIndex(const int index, const int keyId) const {
-    ASSERT(keyId >= 0);
-    ASSERT(index >= 0 && index < mSampledInputSize);
+    ASSERT(keyId >= 0 && index >= 0 && index < mSampledInputSize);
     return mSampledSearchKeysVector[index].test(keyId);
 }
 
-void ProximityInfoState::popInputData() {
-    ProximityInfoStateUtils::popInputData(&mSampledInputXs, &mSampledInputYs, &mSampledTimes,
-            &mSampledLengthCache, &mSampledInputIndice);
-}
-
 float ProximityInfoState::getDirection(const int index0, const int index1) const {
     return ProximityInfoStateUtils::getDirection(
             &mSampledInputXs, &mSampledInputYs, index0, index1);
@@ -344,33 +310,9 @@
             keyX, keyY, x0, y0, x1, y1, extend);
 }
 
-// Get a word that is detected by tracing the most probable string into codePointBuf and
-// returns probability of generating the word.
 float ProximityInfoState::getMostProbableString(int *const codePointBuf) const {
-    static const float DEMOTION_LOG_PROBABILITY = 0.3f;
-    int index = 0;
-    float sumLogProbability = 0.0f;
-    // TODO: Current implementation is greedy algorithm. DP would be efficient for many cases.
-    for (int i = 0; i < mSampledInputSize && index < MAX_WORD_LENGTH - 1; ++i) {
-        float minLogProbability = static_cast<float>(MAX_POINT_TO_KEY_LENGTH);
-        int character = NOT_AN_INDEX;
-        for (hash_map_compat<int, float>::const_iterator it = mCharProbabilities[i].begin();
-                it != mCharProbabilities[i].end(); ++it) {
-            const float logProbability = (it->first != NOT_AN_INDEX)
-                    ? it->second + DEMOTION_LOG_PROBABILITY : it->second;
-            if (logProbability < minLogProbability) {
-                minLogProbability = logProbability;
-                character = it->first;
-            }
-        }
-        if (character != NOT_AN_INDEX) {
-            codePointBuf[index] = mProximityInfo->getCodePointOf(character);
-            index++;
-        }
-        sumLogProbability += minLogProbability;
-    }
-    codePointBuf[index] = '\0';
-    return sumLogProbability;
+    memcpy(codePointBuf, mMostProbableString, sizeof(mMostProbableString));
+    return mMostProbableStringProbability;
 }
 
 bool ProximityInfoState::hasSpaceProximity(const int index) const {
diff --git a/native/jni/src/proximity_info_state.h b/native/jni/src/proximity_info_state.h
index 642925c..7422cb0 100644
--- a/native/jni/src/proximity_info_state.h
+++ b/native/jni/src/proximity_info_state.h
@@ -54,10 +54,12 @@
               mSampledInputIndice(), mSampledLengthCache(), mBeelineSpeedPercentiles(),
               mSampledDistanceCache_G(), mSpeedRates(), mDirections(), mCharProbabilities(),
               mSampledNearKeysVector(), mSampledSearchKeysVector(),
-              mTouchPositionCorrectionEnabled(false), mSampledInputSize(0) {
+              mTouchPositionCorrectionEnabled(false), mSampledInputSize(0),
+              mMostProbableStringProbability(0.0f) {
         memset(mInputProximities, 0, sizeof(mInputProximities));
         memset(mNormalizedSquaredDistances, 0, sizeof(mNormalizedSquaredDistances));
         memset(mPrimaryInputWord, 0, sizeof(mPrimaryInputWord));
+        memset(mMostProbableString, 0, sizeof(mMostProbableString));
     }
 
     // Non virtual inline destructor -- never inherit this class
@@ -67,6 +69,21 @@
         return getProximityCodePointsAt(index)[0];
     }
 
+    inline bool sameAsTyped(const int *word, int length) const {
+        if (length != mSampledInputSize) {
+            return false;
+        }
+        const int *inputProximities = mInputProximities;
+        while (length--) {
+            if (*inputProximities != *word) {
+                return false;
+            }
+            inputProximities += MAX_PROXIMITY_CHARS_SIZE;
+            word++;
+        }
+        return true;
+    }
+
     AK_FORCE_INLINE bool existsCodePointInProximityAt(const int index, const int c) const {
         const int *codePoints = getProximityCodePointsAt(index);
         int i = 0;
@@ -107,23 +124,6 @@
         return mTouchPositionCorrectionEnabled;
     }
 
-    inline bool sameAsTyped(const int *word, int length) const {
-        if (length != mSampledInputSize) {
-            return false;
-        }
-        const int *inputProximities = mInputProximities;
-        while (length--) {
-            if (*inputProximities != *word) {
-                return false;
-            }
-            inputProximities += MAX_PROXIMITY_CHARS_SIZE;
-            word++;
-        }
-        return true;
-    }
-
-    int getDuration(const int index) const;
-
     bool isUsed() const {
         return mSampledInputSize > 0;
     }
@@ -210,16 +210,9 @@
     // Defined here                        //
     /////////////////////////////////////////
 
-    bool hasInputCoordinates() const {
-        return mSampledInputXs.size() > 0 && mSampledInputYs.size() > 0;
-    }
-
     inline const int *getProximityCodePointsAt(const int index) const {
         return ProximityInfoStateUtils::getProximityCodePointsAt(mInputProximities, index);
     }
-    bool checkAndReturnIsContinuationPossible(const int inputSize, const int *const xCoordinates,
-            const int *const yCoordinates, const int *const times, const bool isGeometric) const;
-    void popInputData();
 
     // const
     const ProximityInfo *mProximityInfo;
@@ -259,6 +252,8 @@
     int mNormalizedSquaredDistances[MAX_PROXIMITY_CHARS_SIZE * MAX_WORD_LENGTH];
     int mSampledInputSize;
     int mPrimaryInputWord[MAX_WORD_LENGTH];
+    float mMostProbableStringProbability;
+    int mMostProbableString[MAX_WORD_LENGTH];
 };
 } // namespace latinime
 #endif // LATINIME_PROXIMITY_INFO_STATE_H
diff --git a/native/jni/src/proximity_info_state_utils.cpp b/native/jni/src/proximity_info_state_utils.cpp
index cbc191e..9f85743 100644
--- a/native/jni/src/proximity_info_state_utils.cpp
+++ b/native/jni/src/proximity_info_state_utils.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <cmath>
+#include <cstring> // for memset()
 #include <sstream> // for debug prints
 #include <vector>
 
@@ -26,6 +27,17 @@
 
 namespace latinime {
 
+/* static */ int ProximityInfoStateUtils::trimLastTwoTouchPoints(std::vector<int> *sampledInputXs,
+        std::vector<int> *sampledInputYs, std::vector<int> *sampledInputTimes,
+        std::vector<int> *sampledLengthCache, std::vector<int> *sampledInputIndice) {
+    const int nextStartIndex = (*sampledInputIndice)[sampledInputIndice->size() - 2];
+    popInputData(sampledInputXs, sampledInputYs, sampledInputTimes, sampledLengthCache,
+            sampledInputIndice);
+    popInputData(sampledInputXs, sampledInputYs, sampledInputTimes, sampledLengthCache,
+            sampledInputIndice);
+    return nextStartIndex;
+}
+
 /* static */ int ProximityInfoStateUtils::updateTouchPoints(const int mostCommonKeyWidth,
         const ProximityInfo *const proximityInfo, const int maxPointToKeyLength,
         const int *const inputProximities, const int *const inputXCoordinates,
@@ -133,6 +145,7 @@
 
 /* static */ void ProximityInfoStateUtils::initPrimaryInputWord(
         const int inputSize, const int *const inputProximities, int *primaryInputWord) {
+    memset(primaryInputWord, 0, sizeof(primaryInputWord[0]) * MAX_WORD_LENGTH);
     for (int i = 0; i < inputSize; ++i) {
         primaryInputWord[i] = getPrimaryCodePointAt(inputProximities, i);
     }
@@ -171,10 +184,13 @@
 /* static */ void ProximityInfoStateUtils::initNormalizedSquaredDistances(
         const ProximityInfo *const proximityInfo, const int inputSize,
         const int *inputXCoordinates, const int *inputYCoordinates,
-        const int *const inputProximities, const bool hasInputCoordinates,
+        const int *const inputProximities,
         const std::vector<int> *const sampledInputXs,
         const std::vector<int> *const sampledInputYs,
         int *normalizedSquaredDistances) {
+    memset(normalizedSquaredDistances, NOT_A_DISTANCE,
+            sizeof(normalizedSquaredDistances[0]) * MAX_PROXIMITY_CHARS_SIZE * MAX_WORD_LENGTH);
+    const bool hasInputCoordinates = sampledInputXs->size() > 0 && sampledInputYs->size() > 0;
     for (int i = 0; i < inputSize; ++i) {
         const int *proximityCodePoints = getProximityCodePointsAt(inputProximities, i);
         const int primaryKey = proximityCodePoints[0];
@@ -983,6 +999,68 @@
     return true;
 }
 
+/* static */ bool ProximityInfoStateUtils::checkAndReturnIsContinuationPossible(const int inputSize,
+        const int *const xCoordinates, const int *const yCoordinates, const int *const times,
+        const int sampledInputSize, const std::vector<int> *const sampledInputXs,
+        const std::vector<int> *const sampledInputYs,
+        const std::vector<int> *const sampledTimes,
+        const std::vector<int> *const sampledInputIndices) {
+    if (inputSize < sampledInputSize) {
+        return false;
+    }
+    for (int i = 0; i < sampledInputSize; ++i) {
+        const int index = (*sampledInputIndices)[i];
+        if (index >= inputSize) {
+            return false;
+        }
+        if (xCoordinates[index] != (*sampledInputXs)[i]
+                || yCoordinates[index] != (*sampledInputYs)[i]) {
+            return false;
+        }
+        if (!times) {
+            continue;
+        }
+        if (times[index] != (*sampledTimes)[i]) {
+            return false;
+        }
+    }
+    return true;
+}
+
+// Get a word that is detected by tracing the most probable string into codePointBuf and
+// returns probability of generating the word.
+/* static */ float ProximityInfoStateUtils::getMostProbableString(
+        const ProximityInfo *const proximityInfo, const int sampledInputSize,
+        const std::vector<hash_map_compat<int, float> > *const charProbabilities,
+        int *const codePointBuf) {
+    ASSERT(charProbabilities->size() >= 0 && sampledInputSize >= 0);
+    memset(codePointBuf, 0, sizeof(codePointBuf[0]) * MAX_WORD_LENGTH);
+    static const float DEMOTION_LOG_PROBABILITY = 0.3f;
+    int index = 0;
+    float sumLogProbability = 0.0f;
+    // TODO: Current implementation is greedy algorithm. DP would be efficient for many cases.
+    for (int i = 0; i < sampledInputSize && index < MAX_WORD_LENGTH - 1; ++i) {
+        float minLogProbability = static_cast<float>(MAX_POINT_TO_KEY_LENGTH);
+        int character = NOT_AN_INDEX;
+        for (hash_map_compat<int, float>::const_iterator it = (*charProbabilities)[i].begin();
+                it != (*charProbabilities)[i].end(); ++it) {
+            const float logProbability = (it->first != NOT_AN_INDEX)
+                    ? it->second + DEMOTION_LOG_PROBABILITY : it->second;
+            if (logProbability < minLogProbability) {
+                minLogProbability = logProbability;
+                character = it->first;
+            }
+        }
+        if (character != NOT_AN_INDEX) {
+            codePointBuf[index] = proximityInfo->getCodePointOf(character);
+            index++;
+        }
+        sumLogProbability += minLogProbability;
+    }
+    codePointBuf[index] = '\0';
+    return sumLogProbability;
+}
+
 /* static */ void ProximityInfoStateUtils::dump(const bool isGeometric, const int inputSize,
         const int *const inputXCoordinates, const int *const inputYCoordinates,
         const int sampledInputSize, const std::vector<int> *const sampledInputXs,
diff --git a/native/jni/src/proximity_info_state_utils.h b/native/jni/src/proximity_info_state_utils.h
index 17ef1c3..c8f0aeb 100644
--- a/native/jni/src/proximity_info_state_utils.h
+++ b/native/jni/src/proximity_info_state_utils.h
@@ -32,6 +32,9 @@
     typedef hash_map_compat<int, float> NearKeysDistanceMap;
     typedef std::bitset<MAX_KEY_COUNT_IN_A_KEYBOARD> NearKeycodesSet;
 
+    static int trimLastTwoTouchPoints(std::vector<int> *sampledInputXs,
+            std::vector<int> *sampledInputYs, std::vector<int> *sampledInputTimes,
+            std::vector<int> *sampledLengthCache, std::vector<int> *sampledInputIndice);
     static int updateTouchPoints(const int mostCommonKeyWidth,
             const ProximityInfo *const proximityInfo, const int maxPointToKeyLength,
             const int *const inputProximities,
@@ -96,7 +99,7 @@
     static void initNormalizedSquaredDistances(
             const ProximityInfo *const proximityInfo, const int inputSize,
             const int *inputXCoordinates, const int *inputYCoordinates,
-            const int *const inputProximities, const bool hasInputCoordinates,
+            const int *const inputProximities,
             const std::vector<int> *const sampledInputXs,
             const std::vector<int> *const sampledInputYs,
             int *normalizedSquaredDistances);
@@ -107,6 +110,18 @@
             const std::vector<int> *const sampledTimes,
             const std::vector<float> *const sampledSpeedRates,
             const std::vector<int> *const sampledBeelineSpeedPercentiles);
+    static bool checkAndReturnIsContinuationPossible(const int inputSize,
+            const int *const xCoordinates, const int *const yCoordinates, const int *const times,
+            const int sampledInputSize, const std::vector<int> *const sampledInputXs,
+            const std::vector<int> *const sampledInputYs,
+            const std::vector<int> *const sampledTimes,
+            const std::vector<int> *const sampledInputIndices);
+    // TODO: Move to most_probable_string_utils.h
+    static float getMostProbableString(
+            const ProximityInfo *const proximityInfo, const int sampledInputSize,
+            const std::vector<hash_map_compat<int, float> > *const charProbabilities,
+            int *const codePointBuf);
+
  private:
     DISALLOW_IMPLICIT_CONSTRUCTORS(ProximityInfoStateUtils);
 
diff --git a/tests/src/com/android/inputmethod/latin/SubtypeLocaleTests.java b/tests/src/com/android/inputmethod/latin/SubtypeLocaleTests.java
index 9af6dbc..e37fef7 100644
--- a/tests/src/com/android/inputmethod/latin/SubtypeLocaleTests.java
+++ b/tests/src/com/android/inputmethod/latin/SubtypeLocaleTests.java
@@ -42,8 +42,10 @@
     InputMethodSubtype ZZ;
     InputMethodSubtype DE_QWERTY;
     InputMethodSubtype FR_QWERTZ;
-    InputMethodSubtype US_AZERTY;
-    InputMethodSubtype ZZ_AZERTY;
+    InputMethodSubtype EN_US_AZERTY;
+    InputMethodSubtype EN_UK_DVORAK;
+    InputMethodSubtype ES_US_COLEMAK;
+    InputMethodSubtype ZZ_PC;
 
     @Override
     protected void setUp() throws Exception {
@@ -72,10 +74,14 @@
                 Locale.GERMAN.toString(), "qwerty", null);
         FR_QWERTZ = AdditionalSubtype.createAdditionalSubtype(
                 Locale.FRENCH.toString(), "qwertz", null);
-        US_AZERTY = AdditionalSubtype.createAdditionalSubtype(
+        EN_US_AZERTY = AdditionalSubtype.createAdditionalSubtype(
                 Locale.US.toString(), "azerty", null);
-        ZZ_AZERTY = AdditionalSubtype.createAdditionalSubtype(
-                SubtypeLocale.NO_LANGUAGE, "azerty", null);
+        EN_UK_DVORAK = AdditionalSubtype.createAdditionalSubtype(
+                Locale.UK.toString(), "dvorak", null);
+        ES_US_COLEMAK = AdditionalSubtype.createAdditionalSubtype(
+                "es_US", "colemak", null);
+        ZZ_PC = AdditionalSubtype.createAdditionalSubtype(
+                SubtypeLocale.NO_LANGUAGE, "pcqwerty", null);
 
     }
 
@@ -106,8 +112,10 @@
     //  zz    qwerty  F  No language (QWERTY)    in system locale
     //  fr    qwertz  T  Français (QWERTZ)
     //  de    qwerty  T  Deutsch (QWERTY)
-    //  en_US azerty  T  English (US) (AZERTY)
-    //  zz    azerty  T  No language (AZERTY)    in system locale
+    //  en_US azerty  T  English (US) (AZERTY)   exception
+    //  en_UK dvorak  T  English (UK) (Dvorak)   exception
+    //  es_US colemak T  Español (EE.UU.) (Colemak)  exception
+    //  zz    pc      T  No language (PC)        in system locale
 
     public void testPredefinedSubtypesInEnglish() {
         assertEquals("en_US", "qwerty", SubtypeLocale.getKeyboardLayoutSetName(EN_US));
@@ -150,9 +158,13 @@
                 assertEquals("de qwerty",    "Deutsch (QWERTY)",
                         SubtypeLocale.getSubtypeDisplayName(DE_QWERTY));
                 assertEquals("en_US azerty", "English (US) (AZERTY)",
-                        SubtypeLocale.getSubtypeDisplayName(US_AZERTY));
-                assertEquals("zz azerty",    "No language (AZERTY)",
-                        SubtypeLocale.getSubtypeDisplayName(ZZ_AZERTY));
+                        SubtypeLocale.getSubtypeDisplayName(EN_US_AZERTY));
+                assertEquals("en_UK dvorak", "English (UK) (Dvorak)",
+                        SubtypeLocale.getSubtypeDisplayName(EN_UK_DVORAK));
+                assertEquals("es_US colemak","Español (EE.UU.) (Colemak)",
+                        SubtypeLocale.getSubtypeDisplayName(ES_US_COLEMAK));
+                assertEquals("zz pc",        "No language (PC)",
+                        SubtypeLocale.getSubtypeDisplayName(ZZ_PC));
                 return null;
             }
         };
@@ -192,9 +204,149 @@
                 assertEquals("de qwerty",    "Deutsch (QWERTY)",
                         SubtypeLocale.getSubtypeDisplayName(DE_QWERTY));
                 assertEquals("en_US azerty", "English (US) (AZERTY)",
-                        SubtypeLocale.getSubtypeDisplayName(US_AZERTY));
-                assertEquals("zz azerty",    "Aucune langue (AZERTY)",
-                        SubtypeLocale.getSubtypeDisplayName(ZZ_AZERTY));
+                        SubtypeLocale.getSubtypeDisplayName(EN_US_AZERTY));
+                assertEquals("en_UK dvorak", "English (UK) (Dvorak)",
+                        SubtypeLocale.getSubtypeDisplayName(EN_UK_DVORAK));
+                assertEquals("es_US colemak","Español (EE.UU.) (Colemak)",
+                        SubtypeLocale.getSubtypeDisplayName(ES_US_COLEMAK));
+                assertEquals("zz azerty",    "Aucune langue (PC)",
+                        SubtypeLocale.getSubtypeDisplayName(ZZ_PC));
+                return null;
+            }
+        };
+        tests.runInLocale(mRes, Locale.FRENCH);
+    }
+
+    // InputMethodSubtype's display name in system locale (en_US).
+    //        isAdditionalSubtype (T=true, F=false)
+    // locale layout  |  display name
+    // ------ ------- - ----------------------
+    //  en_US qwerty  F  English (US)            exception
+    //  en_GB qwerty  F  English (UK)            exception
+    //  es_US spanish F  Spanish (US)            exception
+    //  fr    azerty  F  French
+    //  fr_CA qwerty  F  French (Canada)
+    //  de    qwertz  F  German
+    //  zz    qwerty  F  No language (QWERTY)
+    //  fr    qwertz  T  French (QWERTZ)
+    //  de    qwerty  T  German (QWERTY)
+    //  en_US azerty  T  English (US) (AZERTY)   exception
+    //  en_UK dvorak  T  English (UK) (Dvorak)   exception
+    //  es_US colemak T  Spanish (US) (Colemak)  exception
+    //  zz    pc      T  No language (PC)
+
+    public void testPredefinedSubtypesInEnglishSystemLocale() {
+        assertEquals("en_US", "qwerty", SubtypeLocale.getKeyboardLayoutSetName(EN_US));
+        assertEquals("en_GB", "qwerty", SubtypeLocale.getKeyboardLayoutSetName(EN_GB));
+        assertEquals("es_US", "spanish", SubtypeLocale.getKeyboardLayoutSetName(ES_US));
+        assertEquals("fr   ", "azerty", SubtypeLocale.getKeyboardLayoutSetName(FR));
+        assertEquals("fr_CA", "qwerty", SubtypeLocale.getKeyboardLayoutSetName(FR_CA));
+        assertEquals("de   ", "qwertz", SubtypeLocale.getKeyboardLayoutSetName(DE));
+        assertEquals("zz   ", "qwerty", SubtypeLocale.getKeyboardLayoutSetName(ZZ));
+
+        final RunInLocale<Void> tests = new RunInLocale<Void>() {
+            @Override
+            protected Void job(Resources res) {
+                assertEquals("en_US", "English (US)",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(EN_US));
+                assertEquals("en_GB", "English (UK)",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(EN_GB));
+                assertEquals("es_US", "Spanish (US)",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(ES_US));
+                assertEquals("fr   ", "French",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(FR));
+                assertEquals("fr_CA", "French (Canada)",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(FR_CA));
+                assertEquals("de   ", "German",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(DE));
+                assertEquals("zz   ", "No language (QWERTY)",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(ZZ));
+                return null;
+            }
+        };
+        tests.runInLocale(mRes, Locale.ENGLISH);
+    }
+
+    public void testAdditionalSubtypesInEnglishSystemLocale() {
+        final RunInLocale<Void> tests = new RunInLocale<Void>() {
+            @Override
+            protected Void job(Resources res) {
+                assertEquals("fr qwertz",    "French (QWERTZ)",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(FR_QWERTZ));
+                assertEquals("de qwerty",    "German (QWERTY)",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(DE_QWERTY));
+                assertEquals("en_US azerty", "English (US) (AZERTY)",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(EN_US_AZERTY));
+                assertEquals("en_UK dvorak", "English (UK) (Dvorak)",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(EN_UK_DVORAK));
+                assertEquals("es_US colemak","Spanish (US) (Colemak)",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(ES_US_COLEMAK));
+                assertEquals("zz azerty",    "No language (PC)",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(ZZ_PC));
+                return null;
+            }
+        };
+        tests.runInLocale(mRes, Locale.ENGLISH);
+    }
+
+    // InputMethodSubtype's display name in system locale (fr).
+    //        isAdditionalSubtype (T=true, F=false)
+    // locale layout  |  display name
+    // ------ ------- - ----------------------
+    //  en_US qwerty  F  Anglais (États-Unis)            exception
+    //  en_GB qwerty  F  Anglais (Royaume-Uni)            exception
+    //  es_US spanish F  Espagnol (États-Unis)            exception
+    //  fr    azerty  F  Français
+    //  fr_CA qwerty  F  Français (Canada)
+    //  de    qwertz  F  Allemand
+    //  zz    qwerty  F  Pas de langue (QWERTY)
+    //  fr    qwertz  T  Français (QWERTZ)
+    //  de    qwerty  T  Allemand (QWERTY)
+    //  en_US azerty  T  Anglais (États-Unis) (AZERTY)   exception
+    //  en_UK dvorak  T  Anglais (Royaume-Uni) (Dvorak)   exception
+    //  es_US colemak T  Espagnol (États-Unis) (Colemak)  exception
+    //  zz    pc      T  Aucune langue (PC)
+
+    public void testPredefinedSubtypesInFrenchSystemLocale() {
+        final RunInLocale<Void> tests = new RunInLocale<Void>() {
+            @Override
+            protected Void job(Resources res) {
+                assertEquals("en_US", "Anglais (États-Unis)",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(EN_US));
+                assertEquals("en_GB", "Anglais (Royaume-Uni)",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(EN_GB));
+                assertEquals("es_US", "Espagnol (États-Unis)",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(ES_US));
+                assertEquals("fr   ", "Français",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(FR));
+                assertEquals("fr_CA", "Français (Canada)",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(FR_CA));
+                assertEquals("de   ", "Allemand",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(DE));
+                assertEquals("zz   ", "Pas de langue (QWERTY)",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(ZZ));
+                return null;
+            }
+        };
+        tests.runInLocale(mRes, Locale.FRENCH);
+    }
+
+    public void testAdditionalSubtypesInFrenchSystemLocale() {
+        final RunInLocale<Void> tests = new RunInLocale<Void>() {
+            @Override
+            protected Void job(Resources res) {
+                assertEquals("fr qwertz",    "Français (QWERTZ)",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(FR_QWERTZ));
+                assertEquals("de qwerty",    "Allemand (QWERTY)",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(DE_QWERTY));
+                assertEquals("en_US azerty", "Anglais (États-Unis) (AZERTY)",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(EN_US_AZERTY));
+                assertEquals("en_UK dvorak", "Anglais (Royaume-Uni) (Dvorak)",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(EN_UK_DVORAK));
+                assertEquals("es_US colemak","Espagnol (États-Unis) (Colemak)",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(ES_US_COLEMAK));
+                assertEquals("zz azerty",    "Aucune langue (PC)",
+                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(ZZ_PC));
                 return null;
             }
         };