Merge "Fix a bug where changing auto-shift would cancel autorepeat."
diff --git a/java/res/values-af/strings.xml b/java/res/values-af/strings.xml
index 8600b72..92f2466 100644
--- a/java/res/values-af/strings.xml
+++ b/java/res/values-af/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"tyd"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"Steminvoerinstellings"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Geen steminvoermetodes geaktiveer nie. Gaan taal- en invoerinstellings na."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Stel invoermetodes op"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Invoertale"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Stuur terugvoer"</string>
diff --git a/java/res/values-ar/strings.xml b/java/res/values-ar/strings.xml
index b42cd29..fa9309f 100644
--- a/java/res/values-ar/strings.xml
+++ b/java/res/values-ar/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"الوقت"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"‏عنوان URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"مفتاح الإدخال الصوتي"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"لم يتم تمكين أي أساليب إدخال صوتي. تحقق من إعدادات اللغة والإدخال."</string>
     <string name="configure_input_method" msgid="373356270290742459">"تهيئة طرق الإدخال"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"لغات الإدخال"</string>
     <string name="send_feedback" msgid="1780431884109392046">"إرسال تعليقات"</string>
diff --git a/java/res/values-ca/strings.xml b/java/res/values-ca/strings.xml
index 21dd7d5..9aff403 100644
--- a/java/res/values-ca/strings.xml
+++ b/java/res/values-ca/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"hora"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"Tecla d\'entrada de veu"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"No hi ha cap mètode d\'introducció activat. Comprova la configuració d\'Idioma i introducció de text."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Configura mètodes d\'entrada"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Idiomes"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Envia comentaris"</string>
diff --git a/java/res/values-cs/strings.xml b/java/res/values-cs/strings.xml
index 8140615..77bae55 100644
--- a/java/res/values-cs/strings.xml
+++ b/java/res/values-cs/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"čas"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"adresy URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"Klávesa hlasového vstupu"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Nejsou povoleny žádné metody hlasového vstupu. Zkontrolujte nastavení Jazyk a vstup."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Konfigurace metod zadávání"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Vstupní jazyky"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Odeslat zpětnou vazbu"</string>
diff --git a/java/res/values-da/strings.xml b/java/res/values-da/strings.xml
index b7f75b3..cd3a667 100644
--- a/java/res/values-da/strings.xml
+++ b/java/res/values-da/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"klokkeslæt"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"Webadresse"</string>
     <string name="voice_input" msgid="3583258583521397548">"Nøgle til stemmeinput"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Der er ingen aktiverede stemmeinputmetoder. Kontrollér Indstillinger for sprog og input."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Konfigurer inputmetoder"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Inputsprog"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Send feedback"</string>
diff --git a/java/res/values-de/strings.xml b/java/res/values-de/strings.xml
index 178db3c..1d0a549 100644
--- a/java/res/values-de/strings.xml
+++ b/java/res/values-de/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"Zeit"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"Taste für Spracheingabe"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Keine Spracheingabemethoden aktiviert. Rufen Sie die Einstellungen für \"Sprache &amp; Eingabe\" auf."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Eingabemethoden konfigurieren"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Eingabesprachen"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Feedback geben"</string>
diff --git a/java/res/values-el/strings.xml b/java/res/values-el/strings.xml
index 6875f68..c9086fd 100644
--- a/java/res/values-el/strings.xml
+++ b/java/res/values-el/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"ώρα"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"διεύθυνση URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"Κλειδί φωνητικής εξόδου"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Δεν έχουν ενεργοποιηθεί μέθοδοι φωνητικής εισαγωγής. Ελέγξτε τις Ρυθμίσεις Γλώσσας και εισαγωγής."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Διαμόρφωση μεθόδων εισαγωγής"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Γλώσσες εισόδου"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Αποστολή σχολίων"</string>
diff --git a/java/res/values-en-rGB/strings.xml b/java/res/values-en-rGB/strings.xml
index 7e5e0e1..f344e73 100644
--- a/java/res/values-en-rGB/strings.xml
+++ b/java/res/values-en-rGB/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"time"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"Voice input key"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"No voice input methods enabled. Check Language &amp; input settings."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Configure input methods"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Input languages"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Send feedback"</string>
diff --git a/java/res/values-en-rIN/strings.xml b/java/res/values-en-rIN/strings.xml
index 7e5e0e1..f344e73 100644
--- a/java/res/values-en-rIN/strings.xml
+++ b/java/res/values-en-rIN/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"time"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"Voice input key"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"No voice input methods enabled. Check Language &amp; input settings."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Configure input methods"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Input languages"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Send feedback"</string>
diff --git a/java/res/values-es/strings.xml b/java/res/values-es/strings.xml
index cfcb988..5427349 100644
--- a/java/res/values-es/strings.xml
+++ b/java/res/values-es/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"hora"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"Tecla de entrada de voz"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Sin métodos de introducción de voz habilitados. Comprueba ajustes de Idioma e introducción de texto."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Configurar métodos de entrada"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Idiomas"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Danos tu opinión"</string>
diff --git a/java/res/values-et-rEE/strings.xml b/java/res/values-et-rEE/strings.xml
index 68be2f2..2c94c77 100644
--- a/java/res/values-et-rEE/strings.xml
+++ b/java/res/values-et-rEE/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"aeg"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"Häälesisendi klahv"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Ühtegi häälsisendmeetodit pole lubatud. Kontrollige keele- ja sisendiseadeid."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Sisestusmeetodite seadistamine"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Sisestuskeeled"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Saatke tagasisidet"</string>
diff --git a/java/res/values-fi/strings.xml b/java/res/values-fi/strings.xml
index 2e4a2c7..b729c2b 100644
--- a/java/res/values-fi/strings.xml
+++ b/java/res/values-fi/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"aika"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"URL-osoite"</string>
     <string name="voice_input" msgid="3583258583521397548">"Äänisyöteavain"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Äänen syöttötapoja ei ole otettu käyttöön. Tarkista Kieli ja syöttötapa -asetukset."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Määritä syöttötavat"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Syöttökielet"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Lähetä palautetta"</string>
diff --git a/java/res/values-fr-rCA/strings.xml b/java/res/values-fr-rCA/strings.xml
index 1427202..d767165 100644
--- a/java/res/values-fr-rCA/strings.xml
+++ b/java/res/values-fr-rCA/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"Heure"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"Touche de saisie vocale"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Aucun mode d\'entrée vocale n\'a été activé. Vérifiez les paramètres de langues et d\'entrée de texte."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Configurer les modes de saisie"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Langues de saisie"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Envoyer des commentaires"</string>
diff --git a/java/res/values-hi/strings.xml b/java/res/values-hi/strings.xml
index 7336156..7b9cbfa 100644
--- a/java/res/values-hi/strings.xml
+++ b/java/res/values-hi/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"समय"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"ध्‍वनि‍ इनपुट कुंजी"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"कोई ध्वनि इनपुट पद्धति सक्षम नहीं है. भाषा और इनपुट सेटिंग जांचें."</string>
     <string name="configure_input_method" msgid="373356270290742459">"इनपुट पद्धति कॉन्‍फ़िगर करें"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"इनपुट भाषा"</string>
     <string name="send_feedback" msgid="1780431884109392046">"सुझाव भेजें"</string>
diff --git a/java/res/values-hr/strings.xml b/java/res/values-hr/strings.xml
index 1afe99e..cb8dda1 100644
--- a/java/res/values-hr/strings.xml
+++ b/java/res/values-hr/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"vrijeme"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"Tipka za glasovni unos"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Nije omogućen nijedan način glasovnog unosa. Provjerite postavke jezika i unosa."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Konfiguriraj načine ulaza"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Jezici unosa"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Slanje povratnih informacija"</string>
diff --git a/java/res/values-hu/strings.xml b/java/res/values-hu/strings.xml
index 8ed477a..2948826 100644
--- a/java/res/values-hu/strings.xml
+++ b/java/res/values-hu/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"idő"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"Hangbeviteli gomb"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Nincs engedélyezett hangbeviteli módszer. Nézze meg a Nyelvi és beviteli beállításokat."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Beviteli módok beállítása"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Beviteli nyelvek"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Visszajelzés küldése"</string>
diff --git a/java/res/values-in/strings.xml b/java/res/values-in/strings.xml
index 6957700..96fa1f8 100644
--- a/java/res/values-in/strings.xml
+++ b/java/res/values-in/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"waktu"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"Tombol masukan suara"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Tidak ada metode masukan suara yang diaktifkan. Periksa setelan Bahasan &amp; masukan."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Konfigurasikan metode masukan"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Bahasa masukan"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Kirim masukan"</string>
diff --git a/java/res/values-it/strings.xml b/java/res/values-it/strings.xml
index 12f5004..ea8bf02 100644
--- a/java/res/values-it/strings.xml
+++ b/java/res/values-it/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"ora"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"Tasto input vocale"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Nessun metodo di immissione vocale abilitato. Controlla le impostazioni Lingua e input."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Configura metodi di immissione"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Lingue comandi"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Invia feedback"</string>
diff --git a/java/res/values-iw/strings.xml b/java/res/values-iw/strings.xml
index 0604eb7..8899cec 100644
--- a/java/res/values-iw/strings.xml
+++ b/java/res/values-iw/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"זמן"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"כתובות אתרים"</string>
     <string name="voice_input" msgid="3583258583521397548">"מקש קלט קולי"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"לא הופעלו שיטות של קלט קולי. בדוק את הגדרות השפה והקלט."</string>
     <string name="configure_input_method" msgid="373356270290742459">"הגדרת שיטות קלט"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"שפות קלט"</string>
     <string name="send_feedback" msgid="1780431884109392046">"שלח משוב"</string>
diff --git a/java/res/values-km-rKH/strings.xml b/java/res/values-km-rKH/strings.xml
index e98afd2..4fdb7d2 100644
--- a/java/res/values-km-rKH/strings.xml
+++ b/java/res/values-km-rKH/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"ពេលវេលា"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"គ្រាប់​ចុច​បញ្ចូល​​សំឡេង"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"គ្មាន​វិធីសាស្ត្រ​បញ្ចូល​សំឡេង​បាន​បើក។ ពិនិត្យ​មើល​ការ​កំណត់​ភាសា &amp; ការ​បញ្ចូល។"</string>
     <string name="configure_input_method" msgid="373356270290742459">"កំណត់​រចនាសម្ព័ន្ធ​វិធីសាស្ត្រ​បញ្ចូល"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"បញ្ចូល​ភាសា"</string>
     <string name="send_feedback" msgid="1780431884109392046">"ផ្ញើ​មតិ​អ្នក​ប្រើ"</string>
diff --git a/java/res/values-lt/strings.xml b/java/res/values-lt/strings.xml
index 714205e0..62460b2 100644
--- a/java/res/values-lt/strings.xml
+++ b/java/res/values-lt/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"laiko"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"Įvesties balsu klavišas"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Nėra jokių įgalintų įvesties balsu metodų. Patikrinkite kalbos ir įvesties nustatymus."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Konfigūruoti įvesties metodus"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Įvesties kalbos"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Siųsti atsiliepimą"</string>
diff --git a/java/res/values-mn-rMN/strings.xml b/java/res/values-mn-rMN/strings.xml
index 2f74dfa..e015752 100644
--- a/java/res/values-mn-rMN/strings.xml
+++ b/java/res/values-mn-rMN/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"цаг"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"Дуун оруулгын товч"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Ямар ч дуу оруулах хэрэглүүр идэвхжээгүй байна. Хэл болон оруулалтын тохиргоог шалгана уу."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Оруулах аргуудын тохиргоо"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Оруулах хэл"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Санал хүсэлт илгээх"</string>
diff --git a/java/res/values-nb/strings.xml b/java/res/values-nb/strings.xml
index 16ccadc..ed85364 100644
--- a/java/res/values-nb/strings.xml
+++ b/java/res/values-nb/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"tid"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"Nettadresse"</string>
     <string name="voice_input" msgid="3583258583521397548">"Tast for taleinndata"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Ingen taleinndatametoder er aktivert. Sjekk Språk og inndata-innstillingene."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Konfigurer inndatametoder"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Inndataspråk"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Send tilbakemelding"</string>
diff --git a/java/res/values-nl/strings.xml b/java/res/values-nl/strings.xml
index 81791fa..57511f9 100644
--- a/java/res/values-nl/strings.xml
+++ b/java/res/values-nl/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"tijd"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"Toets voor spraakinvoer"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Geen spraakinvoermethoden ingeschakeld. Ga naar \'Instellingen voor taal en invoer\'."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Invoermethoden configureren"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Invoertalen"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Feedback verzenden"</string>
diff --git a/java/res/values-pl/strings.xml b/java/res/values-pl/strings.xml
index cfc6c7c..257fc2a 100644
--- a/java/res/values-pl/strings.xml
+++ b/java/res/values-pl/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"godzina"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"Klawisz rozpoznawania mowy"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Nie włączono żadnych metod wprowadzania głosowego. Sprawdź ustawienia języka i wprowadzania."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Konfiguruj metody wprowadzania"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Języki wprowadzania"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Prześlij opinię"</string>
diff --git a/java/res/values-pt-rPT/strings.xml b/java/res/values-pt-rPT/strings.xml
index c247d3b..de4bada 100644
--- a/java/res/values-pt-rPT/strings.xml
+++ b/java/res/values-pt-rPT/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"hora"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"URLs"</string>
     <string name="voice_input" msgid="3583258583521397548">"Chave de entrada de voz"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Nenhum método de entrada de texto por voz ativado. Verifique as definições de Idioma e introdução."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Configurar métodos de introdução"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Idiomas de entrada"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Enviar comentários"</string>
diff --git a/java/res/values-sl/strings.xml b/java/res/values-sl/strings.xml
index f330127..cbbf758 100644
--- a/java/res/values-sl/strings.xml
+++ b/java/res/values-sl/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"ura"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"Tipka za glasovni vnos"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Ni omogočenih glasovnih načinov vnosa. Preverite nastavitve v razdelku »Jezik in vnos«."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Nastavitev načinov vnosa"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Jeziki vnosa"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Pošljite povratne informacije"</string>
diff --git a/java/res/values-sr/strings.xml b/java/res/values-sr/strings.xml
index 42f7b3b..00f0031 100644
--- a/java/res/values-sr/strings.xml
+++ b/java/res/values-sr/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"време"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"Тастер за гласовни унос"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Ниједан метод гласовног уноса није омогућен. Проверите Подешавања језика и уноса."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Конфигурисање метода уноса"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Језици за унос"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Пошаљи повратне информације"</string>
diff --git a/java/res/values-sv/strings.xml b/java/res/values-sv/strings.xml
index bc10054..6a16d33 100644
--- a/java/res/values-sv/strings.xml
+++ b/java/res/values-sv/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"klockslag"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"webbadresser"</string>
     <string name="voice_input" msgid="3583258583521397548">"Röstinmatningsknapp"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Ingen röstinmatningsmetod har aktiverats. Kontrollera språk- och inmatningsinställningarna."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Konfigurera inmatningsmetoder"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Inmatningsspråk"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Skicka feedback"</string>
diff --git a/java/res/values-uk/strings.xml b/java/res/values-uk/strings.xml
index eb249fb..3463004 100644
--- a/java/res/values-uk/strings.xml
+++ b/java/res/values-uk/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"час"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"URL-адреси"</string>
     <string name="voice_input" msgid="3583258583521397548">"Ключ голосового вводу"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Способи голосового вводу не ввімкнено. Перейдіть у налаштування \"Мова та введення\"."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Налаштування методів введення"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Мови вводу"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Надіслати відгук"</string>
diff --git a/java/res/values-zu/strings.xml b/java/res/values-zu/strings.xml
index 9cf6cb9..0afb3b9 100644
--- a/java/res/values-zu/strings.xml
+++ b/java/res/values-zu/strings.xml
@@ -119,8 +119,7 @@
     <string name="keyboard_mode_time" msgid="4381856885582143277">"isikhathi"</string>
     <string name="keyboard_mode_url" msgid="1519819835514911218">"I-URL"</string>
     <string name="voice_input" msgid="3583258583521397548">"Inkinobho yokufaka izwi"</string>
-    <!-- no translation found for voice_input_disabled_summary (8141750303464726129) -->
-    <skip />
+    <string name="voice_input_disabled_summary" msgid="8141750303464726129">"Azikho izindlela zokufaka zezwi ezinikwe amandla. Hlola izilungiselelo zolimi kanye nezokufaka."</string>
     <string name="configure_input_method" msgid="373356270290742459">"Misa izindlela zokufakwayo"</string>
     <string name="language_selection_title" msgid="1651299598555326750">"Izilimi zokufakwayo"</string>
     <string name="send_feedback" msgid="1780431884109392046">"Thumela impendulo"</string>
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
index c9bcfe3..aa8bb2c 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
@@ -36,6 +36,7 @@
 import java.util.Locale;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
 // TODO: Consolidate dictionaries in native code.
@@ -55,8 +56,7 @@
     private UserHistoryDictionary mUserHistoryDictionary;
     private PersonalizationDictionary mPersonalizationDictionary;
 
-    @UsedForTesting
-    private boolean mIsCurrentlyWaitingForMainDictionary = false;
+    private final CountDownLatch mLatchForWaitingLoadingMainDictionary;
 
     public interface DictionaryInitializationListener {
         public void onUpdateMainDictionaryAvailability(boolean isMainDictionaryAvailable);
@@ -77,13 +77,41 @@
             final DictionaryFacilitatorForSuggest oldDictionaryFacilitator) {
         mContext = context;
         mLocale = locale;
+        mLatchForWaitingLoadingMainDictionary = new CountDownLatch(1);
         initForDebug(settingsValues);
-        reloadMainDict(context, locale, listener);
+        loadMainDict(context, locale, listener);
         setUserDictionary(new UserBinaryDictionary(context, locale));
         resetAdditionalDictionaries(oldDictionaryFacilitator, settingsValues);
     }
 
     /**
+     * Creates instance for reloading the main dict.
+     *
+     * @param listener the listener
+     * @param oldDictionaryFacilitator the instance having old dictionaries. This must not be null.
+     */
+    public DictionaryFacilitatorForSuggest(final DictionaryInitializationListener listener,
+            final DictionaryFacilitatorForSuggest oldDictionaryFacilitator) {
+        mContext = oldDictionaryFacilitator.mContext;
+        mLocale = oldDictionaryFacilitator.mLocale;
+        mDictionarySubsetForDebug = oldDictionaryFacilitator.mDictionarySubsetForDebug;
+        mLatchForWaitingLoadingMainDictionary = new CountDownLatch(1);
+        loadMainDict(mContext, mLocale, listener);
+        // Transfer user dictionary.
+        setUserDictionary(oldDictionaryFacilitator.mUserDictionary);
+        oldDictionaryFacilitator.removeDictionary(Dictionary.TYPE_USER);
+        // Transfer contacts dictionary.
+        setContactsDictionary(oldDictionaryFacilitator.mContactsDictionary);
+        oldDictionaryFacilitator.removeDictionary(Dictionary.TYPE_CONTACTS);
+        // Transfer user history dictionary.
+        setUserHistoryDictionary(oldDictionaryFacilitator.mUserHistoryDictionary);
+        oldDictionaryFacilitator.removeDictionary(Dictionary.TYPE_USER_HISTORY);
+        // Transfer personalization dictionary.
+        setPersonalizationDictionary(oldDictionaryFacilitator.mPersonalizationDictionary);
+        oldDictionaryFacilitator.removeDictionary(Dictionary.TYPE_PERSONALIZATION);
+    }
+
+    /**
      * Creates instance for when the settings values have been changed.
      *
      * @param settingsValues the new settings values
@@ -94,6 +122,7 @@
             final DictionaryFacilitatorForSuggest oldDictionaryFacilitator) {
         mContext = oldDictionaryFacilitator.mContext;
         mLocale = oldDictionaryFacilitator.mLocale;
+        mLatchForWaitingLoadingMainDictionary = new CountDownLatch(0);
         initForDebug(settingsValues);
         // Transfer main dictionary.
         setMainDictionary(oldDictionaryFacilitator.mMainDictionary);
@@ -110,6 +139,7 @@
             final ArrayList<String> dictionaryTypes, final HashMap<String, File> dictionaryFiles) {
         mContext = context;
         mLocale = locale;
+        mLatchForWaitingLoadingMainDictionary = new CountDownLatch(0);
         for (final String dictType : dictionaryTypes) {
             if (dictType.equals(Dictionary.TYPE_MAIN)) {
                 final DictionaryCollection mainDictionary =
@@ -167,9 +197,8 @@
         }
     }
 
-    public void reloadMainDict(final Context context, final Locale locale,
+    private void loadMainDict(final Context context, final Locale locale,
             final DictionaryInitializationListener listener) {
-        mIsCurrentlyWaitingForMainDictionary = true;
         mMainDictionary = null;
         if (listener != null) {
             listener.onUpdateMainDictionaryAvailability(hasMainDictionary());
@@ -183,7 +212,7 @@
                 if (listener != null) {
                     listener.onUpdateMainDictionaryAvailability(hasMainDictionary());
                 }
-                mIsCurrentlyWaitingForMainDictionary = false;
+                mLatchForWaitingLoadingMainDictionary.countDown();
             }
         }.start();
     }
@@ -194,9 +223,9 @@
         return null != mMainDictionary && mMainDictionary.isInitialized();
     }
 
-    @UsedForTesting
-    public boolean isCurrentlyWaitingForMainDictionary() {
-        return mIsCurrentlyWaitingForMainDictionary;
+    public void waitForLoadingMainDictionary(final long timeout, final TimeUnit unit)
+            throws InterruptedException {
+        mLatchForWaitingLoadingMainDictionary.await(timeout, unit);
     }
 
     private void setMainDictionary(final Dictionary mainDictionary) {
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index b1552ab..aadb651 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -89,6 +89,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Locale;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Input method implementation for Qwerty'ish keyboard.
@@ -519,10 +520,14 @@
                     new DictionaryFacilitatorForSuggest(currentSettingsValues,
                             oldDictionaryFacilitator);
             // Create Suggest instance with the new dictionary facilitator.
-            mInputLogic.mSuggest = new Suggest(suggest /* oldSuggest */, dictionaryFacilitator);
-            suggest.close();
+            resetSuggest(new Suggest(suggest /* oldSuggest */, dictionaryFacilitator));
+        } else if (suggest == null) {
+            initSuggestForLocale(locale);
         }
-        if (currentSettingsValues.mUsePersonalizedDicts) {
+    }
+
+    private void refreshPersonalizationDictionarySession() {
+        if (mSettings.getCurrent().mUsePersonalizedDicts) {
             if (mSubtypeSwitcher.isSystemLocaleSameAsLocaleOfAllEnabledSubtypes()) {
                 final DictionaryFacilitatorForSuggest dictionaryFacilitator =
                         (mInputLogic.mSuggest == null) ?
@@ -562,33 +567,41 @@
         } else {
             subtypeLocale = switcherSubtypeLocale;
         }
+        initSuggestForLocale(subtypeLocale);
+    }
 
+    private void initSuggestForLocale(final Locale locale) {
         final SettingsValues settingsValues = mSettings.getCurrent();
         final DictionaryFacilitatorForSuggest oldDictionaryFacilitator =
                 (mInputLogic.mSuggest == null) ? null : mInputLogic.mSuggest.mDictionaryFacilitator;
         // Creates new dictionary facilitator for the new locale.
         final DictionaryFacilitatorForSuggest dictionaryFacilitator =
-                new DictionaryFacilitatorForSuggest(this /* context */, subtypeLocale,
+                new DictionaryFacilitatorForSuggest(this /* context */, locale,
                         settingsValues, this /* DictionaryInitializationListener */,
                         oldDictionaryFacilitator);
-        PersonalizationDictionarySessionRegistrar.onConfigurationChanged(
-                this, getResources().getConfiguration(), dictionaryFacilitator);
-        final Suggest newSuggest = new Suggest(subtypeLocale, dictionaryFacilitator);
+        final Suggest newSuggest = new Suggest(locale, dictionaryFacilitator);
         if (settingsValues.mCorrectionEnabled) {
             newSuggest.setAutoCorrectionThreshold(settingsValues.mAutoCorrectionThreshold);
         }
+        resetSuggest(newSuggest);
+    }
+
+    /* package private */ void resetSuggestMainDict() {
+        final DictionaryFacilitatorForSuggest oldDictionaryFacilitator =
+                mInputLogic.mSuggest.mDictionaryFacilitator;
+        final DictionaryFacilitatorForSuggest dictionaryFacilitator =
+                new DictionaryFacilitatorForSuggest(this /* listener */, oldDictionaryFacilitator);
+        resetSuggest(new Suggest(mInputLogic.mSuggest /* oldSuggest */, dictionaryFacilitator));
+    }
+
+    private void resetSuggest(final Suggest newSuggest) {
         if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
             ResearchLogger.getInstance().initDictionary(newSuggest.mDictionaryFacilitator);
         }
         final Suggest oldSuggest = mInputLogic.mSuggest;
         mInputLogic.mSuggest = newSuggest;
         if (oldSuggest != null) oldSuggest.close();
-    }
-
-    /* package private */ void resetSuggestMainDict() {
-        final Locale subtypeLocale = mSubtypeSwitcher.getCurrentSubtypeLocale();
-        mInputLogic.mSuggest.mDictionaryFacilitator.reloadMainDict(this, subtypeLocale,
-                this /* SuggestInitializationListener */);
+        refreshPersonalizationDictionarySession();
     }
 
     @Override
@@ -1301,7 +1314,8 @@
     @UsedForTesting
     public boolean isShowingPunctuationList() {
         if (mInputLogic.mSuggestedWords == null) return false;
-        return mSettings.getCurrent().mSuggestPuncList == mInputLogic.mSuggestedWords;
+        return mSettings.getCurrent().mSpacingAndPunctuations.mSuggestPuncList
+                == mInputLogic.mSuggestedWords;
     }
 
     // TODO[IL]: Define a clear interface for this
@@ -1417,7 +1431,8 @@
 
     private SuggestedWords getOlderSuggestions(final String typedWord) {
         SuggestedWords previousSuggestedWords = mInputLogic.mSuggestedWords;
-        if (previousSuggestedWords == mSettings.getCurrent().mSuggestPuncList) {
+        if (previousSuggestedWords
+                == mSettings.getCurrent().mSpacingAndPunctuations.mSuggestPuncList) {
             previousSuggestedWords = SuggestedWords.EMPTY;
         }
         if (typedWord == null) {
@@ -1570,7 +1585,7 @@
         if (currentSettings.mBigramPredictionEnabled) {
             clearSuggestionStrip();
         } else {
-            setSuggestedWords(currentSettings.mSuggestPuncList);
+            setSuggestedWords(currentSettings.mSpacingAndPunctuations.mSuggestPuncList);
         }
         setAutoCorrectionIndicator(false);
         setSuggestionStripShown(isSuggestionsStripVisible());
@@ -1787,14 +1802,20 @@
 
     // DO NOT USE THIS for any other purpose than testing. This is information private to LatinIME.
     @UsedForTesting
-    /* package for test */ boolean isCurrentlyWaitingForMainDictionary() {
-        return mInputLogic.mSuggest.mDictionaryFacilitator.isCurrentlyWaitingForMainDictionary();
+    /* package for test */ void waitForMainDictionary(final long timeout, final TimeUnit unit)
+            throws InterruptedException {
+        mInputLogic.mSuggest.mDictionaryFacilitator.waitForLoadingMainDictionary(timeout, unit);
     }
 
     // DO NOT USE THIS for any other purpose than testing. This can break the keyboard badly.
     @UsedForTesting
-    /* package for test */ void replaceMainDictionaryForTest(final Locale locale) {
-        mInputLogic.mSuggest.mDictionaryFacilitator.reloadMainDict(this, locale, null);
+    /* package for test */ void replaceDictionariesForTest(final Locale locale) {
+        final DictionaryFacilitatorForSuggest oldDictionaryFacilitator =
+                mInputLogic.mSuggest.mDictionaryFacilitator;
+        final DictionaryFacilitatorForSuggest dictionaryFacilitator =
+                new DictionaryFacilitatorForSuggest(this, locale, mSettings.getCurrent(),
+                        this /* listener */, oldDictionaryFacilitator);
+        resetSuggest(new Suggest(locale, dictionaryFacilitator));
     }
 
     public void debugDumpStateAndCrashWithException(final String context) {
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 20ba48d..968129a 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -529,7 +529,7 @@
         // In languages with spaces, we only start composing a word when we are not already
         // touching a word. In languages without spaces, the above conditions are sufficient.
                 (!mConnection.isCursorTouchingWord(settingsValues)
-                        || !settingsValues.mCurrentLanguageHasSpaces)) {
+                        || !settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces)) {
             // Reset entirely the composing state anyway, then start composing a new word unless
             // the character is a single quote or a dash. The idea here is, single quote and dash
             // are not separators and they should be treated as normal characters, except in the
@@ -594,7 +594,7 @@
         boolean didAutoCorrect = false;
         // We avoid sending spaces in languages without spaces if we were composing.
         final boolean shouldAvoidSendingCode = Constants.CODE_SPACE == codePoint
-                && !settingsValues.mCurrentLanguageHasSpaces
+                && !settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces
                 && mWordComposer.isComposingWord();
         if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) {
             // If we are in the middle of a recorrection, we need to commit the recorrection
@@ -813,7 +813,7 @@
                 }
             }
             if (settingsValues.isSuggestionStripVisible()
-                    && settingsValues.mCurrentLanguageHasSpaces
+                    && settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces
                     && !mConnection.isCursorFollowedByWordCharacter(settingsValues)) {
                 restartSuggestionsOnWordTouchedByCursor(settingsValues,
                         deleteCountAtStart - mDeleteCount /* offset */,
@@ -912,8 +912,8 @@
         if (canBeFollowedByDoubleSpacePeriod(firstCodePoint)) {
             handler.cancelDoubleSpacePeriodTimer();
             mConnection.deleteSurroundingText(2, 0);
-            final String textToInsert = new String(
-                    new int[] { settingsValues.mSentenceSeparator, Constants.CODE_SPACE }, 0, 2);
+            final String textToInsert =
+                    settingsValues.mSpacingAndPunctuations.mSentenceSeparatorAndSpace;
             mConnection.commitText(textToInsert, 1);
             if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
                 ResearchLogger.latinIME_maybeDoubleSpacePeriod(textToInsert,
@@ -967,7 +967,7 @@
             if (TextUtils.isEmpty(selectedText)) return; // Race condition with the input connection
             mRecapitalizeStatus.initialize(mLastSelectionStart, mLastSelectionEnd,
                     selectedText.toString(),
-                    settingsValues.mLocale, settingsValues.mWordSeparators);
+                    settingsValues.mLocale, settingsValues.mSpacingAndPunctuations.mWordSeparators);
             // We trim leading and trailing whitespace.
             mRecapitalizeStatus.trim();
             // Trimming the object may have changed the length of the string, and we need to
@@ -1066,7 +1066,7 @@
         if (!mLatinIME.isSuggestionsStripVisible()) return;
         // Recorrection is not supported in languages without spaces because we don't know
         // how to segment them yet.
-        if (!settingsValues.mCurrentLanguageHasSpaces) return;
+        if (!settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces) return;
         // If the cursor is not touching a word, or if there is a selection, return right away.
         if (mLastSelectionStart != mLastSelectionEnd) return;
         // If we don't know the cursor location, return.
@@ -1074,7 +1074,8 @@
         final int expectedCursorPosition = mLastSelectionStart + offset; // We know Start == End
         if (!mConnection.isCursorTouchingWord(settingsValues)) return;
         final TextRange range = mConnection.getWordRangeAtCursor(
-                settingsValues.mWordSeparators, 0 /* additionalPrecedingWordsCount */);
+                settingsValues.mSpacingAndPunctuations.mWordSeparators,
+                0 /* additionalPrecedingWordsCount */);
         if (null == range) return; // Happens if we don't have an input connection at all
         if (range.length() <= 0) return; // Race condition. No text to resume on, so bail out.
         // If for some strange reason (editor bug or so) we measure the text before the cursor as
@@ -1207,7 +1208,7 @@
             }
         }
         final String stringToCommit = originallyTypedWord + mLastComposedWord.mSeparatorString;
-        if (settingsValues.mCurrentLanguageHasSpaces) {
+        if (settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces) {
             // For languages with spaces, we revert to the typed string, but the cursor is still
             // after the separator so we don't resume suggestions. If the user wants to correct
             // the word, they have to press backspace again.
@@ -1307,7 +1308,7 @@
     // TODO: Make this private
     public String getNthPreviousWordForSuggestion(final SettingsValues currentSettings,
             final int nthPreviousWord) {
-        if (currentSettings.mCurrentLanguageHasSpaces) {
+        if (currentSettings.mSpacingAndPunctuations.mCurrentLanguageHasSpaces) {
             // If we are typing in a language with spaces we can just look up the previous
             // word from textview.
             return mConnection.getNthPreviousWord(currentSettings, nthPreviousWord);
@@ -1398,7 +1399,7 @@
         if (settingsValues.mBigramPredictionEnabled) {
             mLatinIME.clearSuggestionStrip();
         } else {
-            mLatinIME.setSuggestedWords(settingsValues.mSuggestPuncList);
+            mLatinIME.setSuggestedWords(settingsValues.mSpacingAndPunctuations.mSuggestPuncList);
         }
         mConnection.resetCachesUponCursorMoveAndReturnSuccess(newSelStart, newSelEnd,
                 shouldFinishComposition);
@@ -1507,7 +1508,7 @@
     // TODO: Make this private.
     public void promotePhantomSpace(final SettingsValues settingsValues) {
         if (settingsValues.shouldInsertSpacesAutomatically()
-                && settingsValues.mCurrentLanguageHasSpaces
+                && settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces
                 && !mConnection.textBeforeCursorLooksLikeURL()) {
             if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
                 ResearchLogger.latinIME_promotePhantomSpace();
diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java
index 75c7258..84ba722 100644
--- a/java/src/com/android/inputmethod/latin/settings/Settings.java
+++ b/java/src/com/android/inputmethod/latin/settings/Settings.java
@@ -176,7 +176,7 @@
     }
 
     public String getWordSeparators() {
-        return mSettingsValues.mWordSeparators;
+        return mSettingsValues.mSpacingAndPunctuations.mWordSeparators;
     }
 
     public boolean isWordSeparator(final int code) {
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
index a07a0ce..3fa686b 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
@@ -26,20 +26,12 @@
 
 import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.compat.AppWorkaroundsUtils;
-import com.android.inputmethod.keyboard.internal.KeySpecParser;
-import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.Dictionary;
 import com.android.inputmethod.latin.InputAttributes;
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.RichInputMethodManager;
-import com.android.inputmethod.latin.SuggestedWords;
-import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
 import com.android.inputmethod.latin.utils.AsyncResultHolder;
-import com.android.inputmethod.latin.utils.CollectionUtils;
-import com.android.inputmethod.latin.utils.StringUtils;
 import com.android.inputmethod.latin.utils.TargetPackageInfoGetterTask;
 
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Locale;
 
@@ -56,15 +48,9 @@
     private static final int TIMEOUT_TO_GET_TARGET_PACKAGE = 5; // seconds
 
     // From resources:
+    public final SpacingAndPunctuations mSpacingAndPunctuations;
     public final int mDelayUpdateOldSuggestions;
-    public final int[] mSymbolsPrecededBySpace;
-    public final int[] mSymbolsFollowedBySpace;
-    public final int[] mWordConnectors;
-    public final SuggestedWords mSuggestPuncList;
-    public final String mWordSeparators;
-    public final int mSentenceSeparator;
     public final CharSequence mHintToSaveText;
-    public final boolean mCurrentLanguageHasSpaces;
 
     // From preferences, in the same order as xml/prefs.xml:
     public final boolean mAutoCap;
@@ -115,22 +101,8 @@
         mLocale = locale;
         // Get the resources
         mDelayUpdateOldSuggestions = res.getInteger(R.integer.config_delay_update_old_suggestions);
-        mSymbolsPrecededBySpace =
-                StringUtils.toCodePointArray(res.getString(R.string.symbols_preceded_by_space));
-        Arrays.sort(mSymbolsPrecededBySpace);
-        mSymbolsFollowedBySpace =
-                StringUtils.toCodePointArray(res.getString(R.string.symbols_followed_by_space));
-        Arrays.sort(mSymbolsFollowedBySpace);
-        mWordConnectors =
-                StringUtils.toCodePointArray(res.getString(R.string.symbols_word_connectors));
-        Arrays.sort(mWordConnectors);
-        final String[] suggestPuncsSpec = KeySpecParser.splitKeySpecs(res.getString(
-                R.string.suggested_punctuations));
-        mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec);
-        mWordSeparators = res.getString(R.string.symbols_word_separators);
-        mSentenceSeparator = res.getInteger(R.integer.sentence_separator);
+        mSpacingAndPunctuations = new SpacingAndPunctuations(res);
         mHintToSaveText = res.getText(R.string.hint_add_to_dictionary);
-        mCurrentLanguageHasSpaces = res.getBoolean(R.bool.current_language_has_spaces);
 
         // Store the input attributes
         if (null == inputAttributes) {
@@ -199,18 +171,8 @@
         // TODO: locale is saved, but not used yet. May have to change this if tests require.
         mLocale = locale;
         mDelayUpdateOldSuggestions = 0;
-        mSymbolsPrecededBySpace = new int[] { '(', '[', '{', '&' };
-        Arrays.sort(mSymbolsPrecededBySpace);
-        mSymbolsFollowedBySpace = new int[] { '.', ',', ';', ':', '!', '?', ')', ']', '}', '&' };
-        Arrays.sort(mSymbolsFollowedBySpace);
-        mWordConnectors = new int[] { '\'', '-' };
-        Arrays.sort(mWordConnectors);
-        mSentenceSeparator = Constants.CODE_PERIOD;
-        final String[] suggestPuncsSpec = new String[] { "!", "?", ",", ":", ";" };
-        mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec);
-        mWordSeparators = "&\t \n()[]{}*&<>+=|.,;:!?/_\"";
+        mSpacingAndPunctuations = SpacingAndPunctuations.DEFAULT;
         mHintToSaveText = "Touch again to save";
-        mCurrentLanguageHasSpaces = true;
         mInputAttributes = new InputAttributes(null, false /* isFullscreenMode */);
         mAutoCap = true;
         mVibrateOn = true;
@@ -265,11 +227,11 @@
     }
 
     public boolean isWordSeparator(final int code) {
-        return mWordSeparators.contains(String.valueOf((char)code));
+        return mSpacingAndPunctuations.isWordSeparator(code);
     }
 
     public boolean isWordConnector(final int code) {
-        return Arrays.binarySearch(mWordConnectors, code) >= 0;
+        return mSpacingAndPunctuations.isWordConnector(code);
     }
 
     public boolean isWordCodePoint(final int code) {
@@ -277,11 +239,11 @@
     }
 
     public boolean isUsuallyPrecededBySpace(final int code) {
-        return Arrays.binarySearch(mSymbolsPrecededBySpace, code) >= 0;
+        return mSpacingAndPunctuations.isUsuallyPrecededBySpace(code);
     }
 
     public boolean isUsuallyFollowedBySpace(final int code) {
-        return Arrays.binarySearch(mSymbolsFollowedBySpace, code) >= 0;
+        return mSpacingAndPunctuations.isUsuallyFollowedBySpace(code);
     }
 
     public boolean shouldInsertSpacesAutomatically() {
@@ -320,27 +282,6 @@
         return null == appWorkaroundUtils ? false : appWorkaroundUtils.isBrokenByRecorrection();
     }
 
-    // Helper functions to create member values.
-    private static SuggestedWords createSuggestPuncList(final String[] puncs) {
-        final ArrayList<SuggestedWordInfo> puncList = CollectionUtils.newArrayList();
-        if (puncs != null) {
-            for (final String puncSpec : puncs) {
-                // TODO: Stop using KeySpceParser.getLabel().
-                puncList.add(new SuggestedWordInfo(KeySpecParser.getLabel(puncSpec),
-                        SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_HARDCODED,
-                        Dictionary.DICTIONARY_HARDCODED,
-                        SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
-                        SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */));
-            }
-        }
-        return new SuggestedWords(puncList,
-                false /* typedWordValid */,
-                false /* hasAutoCorrectionCandidate */,
-                true /* isPunctuationSuggestions */,
-                false /* isObsoleteSuggestions */,
-                false /* isPrediction */);
-    }
-
     private static final int SUGGESTION_VISIBILITY_SHOW_VALUE =
             R.string.prefs_suggestion_visibility_show_value;
     private static final int SUGGESTION_VISIBILITY_SHOW_ONLY_PORTRAIT_VALUE =
diff --git a/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java b/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java
new file mode 100644
index 0000000..0500f4a
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.settings;
+
+import android.content.res.Resources;
+
+import com.android.inputmethod.keyboard.internal.KeySpecParser;
+import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.Dictionary;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.SuggestedWords;
+import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.StringUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public final class SpacingAndPunctuations {
+    private final int[] mSymbolsPrecededBySpace;
+    private final int[] mSymbolsFollowedBySpace;
+    private final int[] mWordConnectors;
+    public final SuggestedWords mSuggestPuncList;
+    public final String mWordSeparators;
+    private final int mSentenceSeparator;
+    public final String mSentenceSeparatorAndSpace;
+    public final boolean mCurrentLanguageHasSpaces;
+
+    public static final SpacingAndPunctuations DEFAULT = new SpacingAndPunctuations();
+
+    private SpacingAndPunctuations() {
+        mSymbolsPrecededBySpace = new int[] { '(', '[', '{', '&' };
+        Arrays.sort(mSymbolsPrecededBySpace);
+        mSymbolsFollowedBySpace = new int[] { '.', ',', ';', ':', '!', '?', ')', ']', '}', '&' };
+        Arrays.sort(mSymbolsFollowedBySpace);
+        mWordConnectors = new int[] { '\'', '-' };
+        Arrays.sort(mWordConnectors);
+        mSentenceSeparator = Constants.CODE_PERIOD;
+        mSentenceSeparatorAndSpace = ". ";
+        final String[] suggestPuncsSpec = new String[] { "!", "?", ",", ":", ";" };
+        mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec);
+        mWordSeparators = "&\t \n()[]{}*&<>+=|.,;:!?/_\"";
+        mCurrentLanguageHasSpaces = true;
+    }
+
+    public SpacingAndPunctuations(final Resources res) {
+        mSymbolsPrecededBySpace =
+                StringUtils.toCodePointArray(res.getString(R.string.symbols_preceded_by_space));
+        Arrays.sort(mSymbolsPrecededBySpace);
+        mSymbolsFollowedBySpace =
+                StringUtils.toCodePointArray(res.getString(R.string.symbols_followed_by_space));
+        Arrays.sort(mSymbolsFollowedBySpace);
+        mWordConnectors =
+                StringUtils.toCodePointArray(res.getString(R.string.symbols_word_connectors));
+        Arrays.sort(mWordConnectors);
+        final String[] suggestPuncsSpec = KeySpecParser.splitKeySpecs(res.getString(
+                R.string.suggested_punctuations));
+        mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec);
+        mWordSeparators = res.getString(R.string.symbols_word_separators);
+        mSentenceSeparator = res.getInteger(R.integer.sentence_separator);
+        mSentenceSeparatorAndSpace = new String(new int[] {
+                mSentenceSeparator, Constants.CODE_SPACE }, 0, 2);
+        mCurrentLanguageHasSpaces = res.getBoolean(R.bool.current_language_has_spaces);
+    }
+
+    // Helper functions to create member values.
+    private static SuggestedWords createSuggestPuncList(final String[] puncs) {
+        final ArrayList<SuggestedWordInfo> puncList = CollectionUtils.newArrayList();
+        if (puncs != null) {
+            for (final String puncSpec : puncs) {
+                // TODO: Stop using KeySpceParser.getLabel().
+                puncList.add(new SuggestedWordInfo(KeySpecParser.getLabel(puncSpec),
+                        SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_HARDCODED,
+                        Dictionary.DICTIONARY_HARDCODED,
+                        SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
+                        SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */));
+            }
+        }
+        return new SuggestedWords(puncList,
+                false /* typedWordValid */,
+                false /* hasAutoCorrectionCandidate */,
+                true /* isPunctuationSuggestions */,
+                false /* isObsoleteSuggestions */,
+                false /* isPrediction */);
+    }
+
+    public boolean isWordSeparator(final int code) {
+        return mWordSeparators.contains(String.valueOf((char)code));
+    }
+
+    public boolean isWordConnector(final int code) {
+        return Arrays.binarySearch(mWordConnectors, code) >= 0;
+    }
+
+    public boolean isWordCodePoint(final int code) {
+        return Character.isLetter(code) || isWordConnector(code);
+    }
+
+    public boolean isUsuallyPrecededBySpace(final int code) {
+        return Arrays.binarySearch(mSymbolsPrecededBySpace, code) >= 0;
+    }
+
+    public boolean isUsuallyFollowedBySpace(final int code) {
+        return Arrays.binarySearch(mSymbolsFollowedBySpace, code) >= 0;
+    }
+
+    public boolean isSentenceSeparator(final int code) {
+        return code == mSentenceSeparator;
+    }
+}
diff --git a/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java b/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java
index 3d4404a..6ad5c77 100644
--- a/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java
@@ -191,7 +191,7 @@
         if (c == Constants.CODE_QUESTION_MARK || c == Constants.CODE_EXCLAMATION_MARK) {
             return (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_SENTENCES) & reqModes;
         }
-        if (settingsValues.mSentenceSeparator != c || j <= 0) {
+        if (!settingsValues.mSpacingAndPunctuations.isSentenceSeparator(c) || j <= 0) {
             return (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_WORDS) & reqModes;
         }
 
@@ -241,7 +241,7 @@
             case WORD:
                 if (Character.isLetter(c)) {
                     state = WORD;
-                } else if (settingsValues.mSentenceSeparator == c) {
+                } else if (settingsValues.mSpacingAndPunctuations.isSentenceSeparator(c)) {
                     state = PERIOD;
                 } else {
                     return caps;
@@ -257,7 +257,7 @@
             case LETTER:
                 if (Character.isLetter(c)) {
                     state = LETTER;
-                } else if (settingsValues.mSentenceSeparator == c) {
+                } else if (settingsValues.mSpacingAndPunctuations.isSentenceSeparator(c)) {
                     state = PERIOD;
                 } else {
                     return noCaps;
diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
index cee73c9..84e8a86 100644
--- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java
+++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
@@ -25,6 +25,7 @@
 import android.text.SpannableStringBuilder;
 import android.text.style.CharacterStyle;
 import android.text.style.SuggestionSpan;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -41,8 +42,10 @@
 import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
 
 import java.util.Locale;
+import java.util.concurrent.TimeUnit;
 
 public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
+    private static final String TAG = InputTestsBase.class.getSimpleName();
 
     private static final String PREF_DEBUG_MODE = "debug_mode";
     private static final String PREF_AUTO_CORRECTION_THRESHOLD = "auto_correction_threshold";
@@ -54,6 +57,7 @@
     protected static final int DELAY_TO_WAIT_FOR_UNDERLINE = 500;
     // The message that sets predictions is posted with a 200 ms delay
     protected static final int DELAY_TO_WAIT_FOR_PREDICTIONS = 200;
+    private final int TIMEOUT_TO_WAIT_FOR_LOADING_MAIN_DICTIONARY_IN_SECONDS = 60;
 
     protected LatinIME mLatinIME;
     protected Keyboard mKeyboard;
@@ -260,15 +264,11 @@
     }
 
     protected void waitForDictionaryToBeLoaded() {
-        int remainingAttempts = 300;
-        while (remainingAttempts > 0 && mLatinIME.isCurrentlyWaitingForMainDictionary()) {
-            try {
-                Thread.sleep(200);
-            } catch (InterruptedException e) {
-                // Don't do much
-            } finally {
-                --remainingAttempts;
-            }
+        try {
+            mLatinIME.waitForMainDictionary(
+                    TIMEOUT_TO_WAIT_FOR_LOADING_MAIN_DICTIONARY_IN_SECONDS, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            Log.e(TAG, "Interrupted during waiting for loading main dictionary.", e);
         }
     }
 
@@ -300,8 +300,7 @@
             final String dictLocale) {
         changeLanguage(keyboardLocale);
         if (!keyboardLocale.equals(dictLocale)) {
-            mLatinIME.replaceMainDictionaryForTest(
-                    LocaleUtils.constructLocaleFromString(dictLocale));
+            mLatinIME.replaceDictionariesForTest(LocaleUtils.constructLocaleFromString(dictLocale));
         }
         waitForDictionaryToBeLoaded();
     }