Merge "Catch exceptions we can't do anything about."
diff --git a/java/res/drawable-hdpi/sym_keyboard_info_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_info_holo_dark.png
deleted file mode 100644
index f52f5af..0000000
--- a/java/res/drawable-hdpi/sym_keyboard_info_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_more_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_more_holo_dark.png
deleted file mode 100644
index 72e2b29..0000000
--- a/java/res/drawable-hdpi/sym_keyboard_more_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_info_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_info_holo_dark.png
deleted file mode 100644
index fa4e239..0000000
--- a/java/res/drawable-mdpi/sym_keyboard_info_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_more_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_more_holo_dark.png
deleted file mode 100644
index 58e27a2..0000000
--- a/java/res/drawable-mdpi/sym_keyboard_more_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_info_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_info_holo_dark.png
deleted file mode 100644
index 513892f..0000000
--- a/java/res/drawable-xhdpi/sym_keyboard_info_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_more_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_more_holo_dark.png
deleted file mode 100644
index 07e9bee..0000000
--- a/java/res/drawable-xhdpi/sym_keyboard_more_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_info_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_info_holo_dark.png
deleted file mode 100644
index b214d0e..0000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_info_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_more_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_more_holo_dark.png
deleted file mode 100644
index 702da27..0000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_more_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/java/res/layout/emoji_palettes_view.xml b/java/res/layout/emoji_palettes_view.xml
index b252859..4fb744e 100644
--- a/java/res/layout/emoji_palettes_view.xml
+++ b/java/res/layout/emoji_palettes_view.xml
@@ -89,22 +89,22 @@
         android:layout_height="0dip"
         android:layout_weight="1"
     >
-        <ImageButton
-            android:id="@+id/emoji_keyboard_alphabet"
+        <TextView
+            android:id="@+id/emoji_keyboard_alphabet_left"
             android:layout_width="0dip"
             android:layout_weight="0.15"
-            android:layout_height="match_parent"
-            android:src="@drawable/ic_ime_switcher_dark" />
+            android:gravity="center"
+            android:layout_height="match_parent" />
         <ImageButton
             android:id="@+id/emoji_keyboard_space"
             android:layout_width="0dip"
             android:layout_weight="0.70"
             android:layout_height="match_parent" />
-        <ImageButton
-            android:id="@+id/emoji_keyboard_alphabet2"
+        <TextView
+            android:id="@+id/emoji_keyboard_alphabet_right"
             android:layout_width="0dip"
             android:layout_weight="0.15"
-            android:layout_height="match_parent"
-            android:src="@drawable/ic_ime_switcher_dark" />
+            android:gravity="center"
+            android:layout_height="match_parent" />
     </LinearLayout>
 </com.android.inputmethod.keyboard.EmojiPalettesView>
diff --git a/java/res/layout/suggestions_strip.xml b/java/res/layout/suggestions_strip.xml
index 5e1019b..b962abe 100644
--- a/java/res/layout/suggestions_strip.xml
+++ b/java/res/layout/suggestions_strip.xml
@@ -55,7 +55,8 @@
             android:text="@string/important_notice_title"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:textSize="14sp"
+            android:padding="6sp"
+            android:textSize="16sp"
             style="?attr/suggestionWordStyle" />
     </LinearLayout>
 </merge>
diff --git a/java/res/values-af/strings-config-important-notice.xml b/java/res/values-af/strings-config-important-notice.xml
index 3fe5cf8..eca184a 100644
--- a/java/res/values-af/strings-config-important-notice.xml
+++ b/java/res/values-af/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Leer uit jou kommunikasie en getikte data om voorstelle te verbeter"</string>
 </resources>
diff --git a/java/res/values-af/strings.xml b/java/res/values-af/strings.xml
index 522180f..d9e7d2d 100644
--- a/java/res/values-af/strings.xml
+++ b/java/res/values-af/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Stel kontakname voor"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Gebruik name van kontakte vir voorstelle en korreksies"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Gepersonaliseerde voorstelle"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Leer uit jou kommunikasie en getikte data om voorstelle te verbeter"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Dubbelspasie-punt"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Dubbeltik op spasiebalk voeg \'n punt in, gevolg deur \'n spasie"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Outohoofletters"</string>
diff --git a/java/res/values-am/strings-config-important-notice.xml b/java/res/values-am/strings-config-important-notice.xml
index 3fe5cf8..2fba008 100644
--- a/java/res/values-am/strings-config-important-notice.xml
+++ b/java/res/values-am/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"የጥቆማ አስተያየቶችን ለማሻሻል ከእርስዎ ግንኙነቶች እና የተተየበ ውሂብ ይማሩ"</string>
 </resources>
diff --git a/java/res/values-am/strings.xml b/java/res/values-am/strings.xml
index 0133c30..f4feac6 100644
--- a/java/res/values-am/strings.xml
+++ b/java/res/values-am/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"የዕውቂያ ስም ጠቁም"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"ከዕውቂያዎች ለጥቆማዎች እና ማስተካከያዎች ስሞች ተጠቀም"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"ግላዊ የጥቆማ አስተያየቶች"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"የጥቆማ አስተያየቶችን ለማሻሻል ከእርስዎ ግንኙነቶች እና የተተየበ ውሂብ ይማሩ"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"የድርብ-ክፍተት ነጥብ"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"የክፍተት አሞሌው ላይ ሁለቴ መታ ማድረግ አንድ ነጥብ እና ክፍተት አስከትሎ ያስገባል"</string>
     <string name="auto_cap" msgid="1719746674854628252">"ራስ-ሰር አቢይ ማድረግ"</string>
diff --git a/java/res/values-iw/config-spacing-and-punctuations.xml b/java/res/values-ar-sw600dp/config-spacing-and-punctuations.xml
similarity index 83%
rename from java/res/values-iw/config-spacing-and-punctuations.xml
rename to java/res/values-ar-sw600dp/config-spacing-and-punctuations.xml
index 9e637e4..5629636 100644
--- a/java/res/values-iw/config-spacing-and-punctuations.xml
+++ b/java/res/values-ar-sw600dp/config-spacing-and-punctuations.xml
@@ -2,7 +2,7 @@
 <!--
 /*
 **
-** Copyright 2012, The Android Open Source Project
+** Copyright 2014, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
@@ -21,5 +21,7 @@
     <!-- The all letters need to be mirrored are found at
          http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt -->
     <!-- Symbols that are suggested between words -->
-    <string name="suggested_punctuations" translatable="false">!,?,\\,,:,;,\",(|),)|(,\',-,/,@,_</string>
+    <!-- U+061F: "؟" ARABIC QUESTION MARK
+         U+061B: "؛" ARABIC SEMICOLON -->
+    <string name="suggested_punctuations" translatable="false">!,&#x061F;,:,&#x061B;,\",\',(|),)|(,-,/,@,_</string>
 </resources>
diff --git a/java/res/values-ar/config-spacing-and-punctuations.xml b/java/res/values-ar/config-spacing-and-punctuations.xml
index 9e637e4..d33a104 100644
--- a/java/res/values-ar/config-spacing-and-punctuations.xml
+++ b/java/res/values-ar/config-spacing-and-punctuations.xml
@@ -21,5 +21,8 @@
     <!-- The all letters need to be mirrored are found at
          http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt -->
     <!-- Symbols that are suggested between words -->
-    <string name="suggested_punctuations" translatable="false">!,?,\\,,:,;,\",(|),)|(,\',-,/,@,_</string>
+    <!-- U+061F: "؟" ARABIC QUESTION MARK
+         U+060C: "،" ARABIC COMMA
+         U+061B: "؛" ARABIC SEMICOLON -->
+    <string name="suggested_punctuations" translatable="false">!,&#x061F;,&#x060C;,:,&#x061B;,\",(|),)|(,\',-,/,@,_</string>
 </resources>
diff --git a/java/res/values-ar/strings-config-important-notice.xml b/java/res/values-ar/strings-config-important-notice.xml
index 3fe5cf8..b2c4d30 100644
--- a/java/res/values-ar/strings-config-important-notice.xml
+++ b/java/res/values-ar/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"التعلم من اتصالاتك والبيانات التي تكتبها لتحسين الاقتراحات"</string>
 </resources>
diff --git a/java/res/values-ar/strings.xml b/java/res/values-ar/strings.xml
index 63fde8c..55689ee 100644
--- a/java/res/values-ar/strings.xml
+++ b/java/res/values-ar/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"اقتراح أسماء جهات الاتصال"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"استخدام الأسماء من جهات الاتصال للاقتراحات والتصحيحات"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"اقتراحات مخصصة"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"التعلم من اتصالاتك والبيانات التي تكتبها لتحسين الاقتراحات"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"نقطة المسافة المزدوجة"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"يؤدي النقر نقرًا مزدوجًا على مفتاح المسافة إلى إدخال نقطة متبوعة بمسافة"</string>
     <string name="auto_cap" msgid="1719746674854628252">"أحرف كبيرة تلقائيًا"</string>
diff --git a/java/res/values-az-rAZ/strings-config-important-notice.xml b/java/res/values-az-rAZ/strings-config-important-notice.xml
index 3fe5cf8..477a270 100644
--- a/java/res/values-az-rAZ/strings-config-important-notice.xml
+++ b/java/res/values-az-rAZ/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Təklifləri inkişaf etdirmək üçün rabitənizdən və yazılmış datadan məlumat əldə edin"</string>
 </resources>
diff --git a/java/res/values-az-rAZ/strings.xml b/java/res/values-az-rAZ/strings.xml
index d6aae5b..673f159 100644
--- a/java/res/values-az-rAZ/strings.xml
+++ b/java/res/values-az-rAZ/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Kontakt adları təklif edin"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Təklif və korreksiya üçün Kontaktlardakı adlardan istifadə edin"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Fərdiləşmiş təkliflər"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Təklifləri inkişaf etdirmək üçün rabitənizdən və yazılmış datadan məlumat əldə edin"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"İkili boşluq periodu"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Boşluqdakı iki klik boşluqdan sonra pauza daxil edir"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Avtomatik böyük hərfləşmə"</string>
diff --git a/java/res/values-bg/strings-config-important-notice.xml b/java/res/values-bg/strings-config-important-notice.xml
index 3fe5cf8..2ab2f33 100644
--- a/java/res/values-bg/strings-config-important-notice.xml
+++ b/java/res/values-bg/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Ползване на съобщ. ви и въведени от вас данни за подобряване на предложенията"</string>
 </resources>
diff --git a/java/res/values-bg/strings.xml b/java/res/values-bg/strings.xml
index a164d8e..641be3c 100644
--- a/java/res/values-bg/strings.xml
+++ b/java/res/values-bg/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Предложения за контакти"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Използване на имена от „Контакти“ за предложения и поправки"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Персонализ. предложения"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Ползване на съобщ. ви и въведени от вас данни за подобряване на предложенията"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Точка чрез двоен интервал"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Двукр. докосване на клав. за интервал вмъква точка, следвана от интервал"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Автоматично поставяне на главни букви"</string>
diff --git a/java/res/values-ca/strings-config-important-notice.xml b/java/res/values-ca/strings-config-important-notice.xml
index 3fe5cf8..a3761a7 100644
--- a/java/res/values-ca/strings-config-important-notice.xml
+++ b/java/res/values-ca/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Considera comunicacions i dades introduïdes per millorar sugger."</string>
 </resources>
diff --git a/java/res/values-ca/strings.xml b/java/res/values-ca/strings.xml
index 305d255..0c61857 100644
--- a/java/res/values-ca/strings.xml
+++ b/java/res/values-ca/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Suggereix noms de contactes"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilitza els noms de contactes per fer suggeriments i correccions"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Suggeriments personalitz."</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Considera comunicacions i dades introduïdes per millorar sugger."</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Punt amb doble espai"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Picar dues vegades la barra d\'espai insereix punt i espai blanc"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Majúscules automàtiques"</string>
diff --git a/java/res/values-cs/strings-config-important-notice.xml b/java/res/values-cs/strings-config-important-notice.xml
index 3fe5cf8..a70140d 100644
--- a/java/res/values-cs/strings-config-important-notice.xml
+++ b/java/res/values-cs/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Zlepšovat návrhy na základě vaší komunikace a zadaných dat"</string>
 </resources>
diff --git a/java/res/values-cs/strings.xml b/java/res/values-cs/strings.xml
index 1b2fb0c..1208e19 100644
--- a/java/res/values-cs/strings.xml
+++ b/java/res/values-cs/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Navrhovat jména kontaktů"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Použít jména ze seznamu kontaktů k návrhům a opravám"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Personalizované návrhy"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Zlepšovat návrhy na základě vaší komunikace a zadaných dat"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Tečka dvojitým mezerníkem"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Dvojím klepnutím na mezerník vložíte tečku následovanou mezerou."</string>
     <string name="auto_cap" msgid="1719746674854628252">"Velká písmena automaticky"</string>
diff --git a/java/res/values-da/strings-config-important-notice.xml b/java/res/values-da/strings-config-important-notice.xml
index 3fe5cf8..14d870e 100644
--- a/java/res/values-da/strings-config-important-notice.xml
+++ b/java/res/values-da/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Giv bedre forslag ud fra tidligere kommunikation og data"</string>
 </resources>
diff --git a/java/res/values-da/strings.xml b/java/res/values-da/strings.xml
index b64684d..ab7a637 100644
--- a/java/res/values-da/strings.xml
+++ b/java/res/values-da/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Foreslå navne på kontakter"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Brug navne fra Kontaktpersoner til forslag og rettelser"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Tilpassede forslag"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Giv bedre forslag ud fra tidligere kommunikation og data"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"To mellemrum for punktum"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"To tryk på mellemrumstasten indsætter et punktum og et mellemrum"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Skriv aut. med stort"</string>
diff --git a/java/res/values-de/strings-config-important-notice.xml b/java/res/values-de/strings-config-important-notice.xml
index 3fe5cf8..11430c3 100644
--- a/java/res/values-de/strings-config-important-notice.xml
+++ b/java/res/values-de/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Vorschläge anhand bisheriger Nachrichten und Eingaben verbessern"</string>
 </resources>
diff --git a/java/res/values-de/strings.xml b/java/res/values-de/strings.xml
index 137a2df..f6e53c5 100644
--- a/java/res/values-de/strings.xml
+++ b/java/res/values-de/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Kontakte vorschlagen"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Namen aus \"Kontakte\" als Vorschläge und Korrekturmöglichkeiten anzeigen"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Personalisierte Vorschläge"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Vorschläge anhand bisheriger Nachrichten und Eingaben verbessern"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Punkt plus Leerzeichen"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Für Punkt plus Leerzeichen zweimal auf die Leertaste tippen"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Autom. Groß-/Kleinschreibung"</string>
diff --git a/java/res/values-el/strings-config-important-notice.xml b/java/res/values-el/strings-config-important-notice.xml
index 3fe5cf8..f47f0dd 100644
--- a/java/res/values-el/strings-config-important-notice.xml
+++ b/java/res/values-el/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Χρήση επικοινωνιών/δεδομένων πληκτρολόγησης για βελτίωση προτάσεων"</string>
 </resources>
diff --git a/java/res/values-el/strings.xml b/java/res/values-el/strings.xml
index b73a729..976f091 100644
--- a/java/res/values-el/strings.xml
+++ b/java/res/values-el/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Πρόταση ονομάτων επαφών"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Χρησιμοποιήστε ονόματα από τις Επαφές για προτάσεις και διορθ."</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Εξατομικευμένες προτάσεις"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Χρήση επικοινωνιών/δεδομένων πληκτρολόγησης για βελτίωση προτάσεων"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Τελεία με διπλό πάτημα πλήκτρ.διαστ."</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Το διπλό πάτημα του πλήκτρ.διαστ. εισάγει μια τελεία και ένα κενό"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Αυτόματη χρήση κεφαλαίων"</string>
diff --git a/java/res/values-en-rGB/strings-config-important-notice.xml b/java/res/values-en-rGB/strings-config-important-notice.xml
index 3fe5cf8..3b41bfa 100644
--- a/java/res/values-en-rGB/strings-config-important-notice.xml
+++ b/java/res/values-en-rGB/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Learn from your communications and typed data to improve suggestions"</string>
 </resources>
diff --git a/java/res/values-en-rGB/strings.xml b/java/res/values-en-rGB/strings.xml
index 967a673..28e53a1 100644
--- a/java/res/values-en-rGB/strings.xml
+++ b/java/res/values-en-rGB/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Suggest Contact names"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Use names from Contacts for suggestions and corrections"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Personalised suggestions"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Learn from your communications and typed data to improve suggestions"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Double-space full stop"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Double tap on spacebar inserts a full stop followed by a space"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Auto-capitalisation"</string>
diff --git a/java/res/values-en-rIN/strings-config-important-notice.xml b/java/res/values-en-rIN/strings-config-important-notice.xml
index 3fe5cf8..3b41bfa 100644
--- a/java/res/values-en-rIN/strings-config-important-notice.xml
+++ b/java/res/values-en-rIN/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Learn from your communications and typed data to improve suggestions"</string>
 </resources>
diff --git a/java/res/values-en-rIN/strings.xml b/java/res/values-en-rIN/strings.xml
index 967a673..28e53a1 100644
--- a/java/res/values-en-rIN/strings.xml
+++ b/java/res/values-en-rIN/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Suggest Contact names"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Use names from Contacts for suggestions and corrections"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Personalised suggestions"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Learn from your communications and typed data to improve suggestions"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Double-space full stop"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Double tap on spacebar inserts a full stop followed by a space"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Auto-capitalisation"</string>
diff --git a/java/res/values-es-rUS/strings-config-important-notice.xml b/java/res/values-es-rUS/strings-config-important-notice.xml
index 3fe5cf8..f019ee4 100644
--- a/java/res/values-es-rUS/strings-config-important-notice.xml
+++ b/java/res/values-es-rUS/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Aprende de mensajes y datos ingresados para mejorar sugerencias."</string>
 </resources>
diff --git a/java/res/values-es-rUS/strings.xml b/java/res/values-es-rUS/strings.xml
index 3e5b910..98efbd5 100644
--- a/java/res/values-es-rUS/strings.xml
+++ b/java/res/values-es-rUS/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Sugerir nombres de contacto"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Usar nombres de los contactos para sugerencias y correcciones"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Sugerenc. personalizadas"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Aprende de mensajes y datos ingresados para mejorar sugerencias."</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Punto y doble espacio"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Tocar dos veces la barra espaciadora inserta un punto y espacio."</string>
     <string name="auto_cap" msgid="1719746674854628252">"Mayúsculas automáticas"</string>
diff --git a/java/res/values-es/strings-config-important-notice.xml b/java/res/values-es/strings-config-important-notice.xml
index 3fe5cf8..79ea6b9 100644
--- a/java/res/values-es/strings-config-important-notice.xml
+++ b/java/res/values-es/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Aprende de mensajes y datos escritos para mejorar sugerencias"</string>
 </resources>
diff --git a/java/res/values-es/strings.xml b/java/res/values-es/strings.xml
index 37692f1..0116c63 100644
--- a/java/res/values-es/strings.xml
+++ b/java/res/values-es/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Sugerir contactos"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilizar nombres de contactos para sugerencias y correcciones"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Sugerencias personalizadas"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Aprende de mensajes y datos escritos para mejorar sugerencias"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Punto y espacio"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Si tocas dos veces el espacio, se inserta un punto seguido de un espacio"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Mayúsculas automáticas"</string>
diff --git a/java/res/values-et-rEE/strings-config-important-notice.xml b/java/res/values-et-rEE/strings-config-important-notice.xml
index 3fe5cf8..d6c5b73 100644
--- a/java/res/values-et-rEE/strings-config-important-notice.xml
+++ b/java/res/values-et-rEE/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Suhtlusest ja sisest. andmetest õppimine soovituste täiustamiseks"</string>
 </resources>
diff --git a/java/res/values-et-rEE/strings.xml b/java/res/values-et-rEE/strings.xml
index 93615c7..ee9bf17 100644
--- a/java/res/values-et-rEE/strings.xml
+++ b/java/res/values-et-rEE/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Soovita kontaktkirjeid"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Kasuta soovitusteks ja parandusteks nimesid kontaktiloendist"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Isikupärast. soovitused"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Suhtlusest ja sisest. andmetest õppimine soovituste täiustamiseks"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Punkt tühikuklahviga"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Tühikuklahvi kaks korda puudutades sisestatakse punkt ja tühik"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Automaatne suurtähtede kasutamine"</string>
diff --git a/java/res/values-iw/config-spacing-and-punctuations.xml b/java/res/values-fa-sw600dp/config-spacing-and-punctuations.xml
similarity index 83%
copy from java/res/values-iw/config-spacing-and-punctuations.xml
copy to java/res/values-fa-sw600dp/config-spacing-and-punctuations.xml
index 9e637e4..5629636 100644
--- a/java/res/values-iw/config-spacing-and-punctuations.xml
+++ b/java/res/values-fa-sw600dp/config-spacing-and-punctuations.xml
@@ -2,7 +2,7 @@
 <!--
 /*
 **
-** Copyright 2012, The Android Open Source Project
+** Copyright 2014, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
@@ -21,5 +21,7 @@
     <!-- The all letters need to be mirrored are found at
          http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt -->
     <!-- Symbols that are suggested between words -->
-    <string name="suggested_punctuations" translatable="false">!,?,\\,,:,;,\",(|),)|(,\',-,/,@,_</string>
+    <!-- U+061F: "؟" ARABIC QUESTION MARK
+         U+061B: "؛" ARABIC SEMICOLON -->
+    <string name="suggested_punctuations" translatable="false">!,&#x061F;,:,&#x061B;,\",\',(|),)|(,-,/,@,_</string>
 </resources>
diff --git a/java/res/values-fa/config-spacing-and-punctuations.xml b/java/res/values-fa/config-spacing-and-punctuations.xml
index 9e637e4..d33a104 100644
--- a/java/res/values-fa/config-spacing-and-punctuations.xml
+++ b/java/res/values-fa/config-spacing-and-punctuations.xml
@@ -21,5 +21,8 @@
     <!-- The all letters need to be mirrored are found at
          http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt -->
     <!-- Symbols that are suggested between words -->
-    <string name="suggested_punctuations" translatable="false">!,?,\\,,:,;,\",(|),)|(,\',-,/,@,_</string>
+    <!-- U+061F: "؟" ARABIC QUESTION MARK
+         U+060C: "،" ARABIC COMMA
+         U+061B: "؛" ARABIC SEMICOLON -->
+    <string name="suggested_punctuations" translatable="false">!,&#x061F;,&#x060C;,:,&#x061B;,\",(|),)|(,\',-,/,@,_</string>
 </resources>
diff --git a/java/res/values-fa/strings-config-important-notice.xml b/java/res/values-fa/strings-config-important-notice.xml
index 3fe5cf8..8f4d091 100644
--- a/java/res/values-fa/strings-config-important-notice.xml
+++ b/java/res/values-fa/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"یادگیری از ارتباطات و اطلاعات تایپ شده شما برای بهبود پیشنهادات"</string>
 </resources>
diff --git a/java/res/values-fa/strings.xml b/java/res/values-fa/strings.xml
index f77c474..61ce785 100644
--- a/java/res/values-fa/strings.xml
+++ b/java/res/values-fa/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"پیشنهاد نام‌های مخاطب"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"برای پیشنهاد و تصحیح از نام مخاطبین استفاده شود"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"پیشنهادات شخصی شده"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"یادگیری از ارتباطات و اطلاعات تایپ شده شما برای بهبود پیشنهادات"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"نقطه با دو فاصله"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"با دوبار ضربه روی دکمه فاصله نقطه با یک فاصله بعد آن درج می‌شود"</string>
     <string name="auto_cap" msgid="1719746674854628252">"بزرگ‌کردن خودکار حروف"</string>
diff --git a/java/res/values-fi/strings-config-important-notice.xml b/java/res/values-fi/strings-config-important-notice.xml
index 3fe5cf8..d4b1a11 100644
--- a/java/res/values-fi/strings-config-important-notice.xml
+++ b/java/res/values-fi/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Ehdotusten parannus viestinnän ja kirjoitettujen tietojen avulla"</string>
 </resources>
diff --git a/java/res/values-fi/strings.xml b/java/res/values-fi/strings.xml
index 897d5a6..b2701fc 100644
--- a/java/res/values-fi/strings.xml
+++ b/java/res/values-fi/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Ehdota yht.tietojen nimiä"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Käytä yhteystietojen nimiä ehdotuksissa ja korjauksissa"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Räätälöidyt ehdotukset"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Ehdotusten parannus viestinnän ja kirjoitettujen tietojen avulla"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Kaksoisvälilyönti = piste"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Välilyönnin kaksoisnapautus lisää tekstiin pisteen ja välilyönnin"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Automaattiset isot kirjaimet"</string>
diff --git a/java/res/values-fr-rCA/config-spacing-and-punctuations.xml b/java/res/values-fr-rCA/config-spacing-and-punctuations.xml
index c3a1a0a..ff91449 100644
--- a/java/res/values-fr-rCA/config-spacing-and-punctuations.xml
+++ b/java/res/values-fr-rCA/config-spacing-and-punctuations.xml
@@ -25,7 +25,7 @@
     <string name="symbols_followed_by_space" translatable="false">.,;:!?)]}&amp;</string>
     <!-- Symbols that separate words -->
     <!-- Don't remove the enclosing double quotes, they protect whitespace (not just U+0020) -->
-    <string name="symbols_word_separators" translatable="false">"&#x0009;&#x0020;&#x000A;"()[]{}*&amp;&lt;&gt;+=|.,;:!?/_\"</string>
+    <string name="symbols_word_separators" translatable="false">"&#x0009;&#x0020;&#x000A;&#x00A0;"()[]{}*&amp;&lt;&gt;+=|.,;:!?/_\"</string>
     <!-- Word connectors -->
     <string name="symbols_word_connectors" translatable="false">\'-</string>
 </resources>
diff --git a/java/res/values-fr-rCA/strings-config-important-notice.xml b/java/res/values-fr-rCA/strings-config-important-notice.xml
index 3fe5cf8..9f0dcc1 100644
--- a/java/res/values-fr-rCA/strings-config-important-notice.xml
+++ b/java/res/values-fr-rCA/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Apprendre de vos comm. et données entrées pour amél. suggestions"</string>
 </resources>
diff --git a/java/res/values-fr-rCA/strings.xml b/java/res/values-fr-rCA/strings.xml
index 937e605..6173497 100644
--- a/java/res/values-fr-rCA/strings.xml
+++ b/java/res/values-fr-rCA/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Proposer noms de contacts"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utiliser des noms de contacts pour les suggestions et corrections"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Suggestions personnalisées"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Apprendre de vos comm. et données entrées pour amél. suggestions"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Point et espace"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Appuyez deux fois sur la barre d\'espace pour insérer un point et une espace"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Majuscules automatiques"</string>
diff --git a/java/res/values-fr/config-spacing-and-punctuations.xml b/java/res/values-fr/config-spacing-and-punctuations.xml
index 8b53fb3..d09b0c0 100644
--- a/java/res/values-fr/config-spacing-and-punctuations.xml
+++ b/java/res/values-fr/config-spacing-and-punctuations.xml
@@ -24,7 +24,7 @@
     <string name="symbols_followed_by_space" translatable="false">.,;:!?)]}&amp;</string>
     <!-- Symbols that separate words -->
     <!-- Don't remove the enclosing double quotes, they protect whitespace (not just U+0020) -->
-    <string name="symbols_word_separators" translatable="false">"&#x0009;&#x0020;&#x000A;"()[]{}*&amp;&lt;&gt;+=|.,;:!?/_\"</string>
+    <string name="symbols_word_separators" translatable="false">"&#x0009;&#x0020;&#x000A;&#x00A0;"()[]{}*&amp;&lt;&gt;+=|.,;:!?/_\"</string>
     <!-- Word connectors -->
     <string name="symbols_word_connectors" translatable="false">\'-</string>
 </resources>
diff --git a/java/res/values-fr/strings-config-important-notice.xml b/java/res/values-fr/strings-config-important-notice.xml
index 3fe5cf8..9013a39 100644
--- a/java/res/values-fr/strings-config-important-notice.xml
+++ b/java/res/values-fr/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Améliorer suggestions en fonction des messages et données saisies"</string>
 </resources>
diff --git a/java/res/values-fr/strings.xml b/java/res/values-fr/strings.xml
index e22983c..29be6ca 100644
--- a/java/res/values-fr/strings.xml
+++ b/java/res/values-fr/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Proposer noms de contacts"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utiliser des noms de contacts pour les suggestions et corrections"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Suggestions personnalisées"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Améliorer suggestions en fonction des messages et données saisies"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Point et espace"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Appuyez deux fois sur la barre d\'espace pour insérer un point et un espace."</string>
     <string name="auto_cap" msgid="1719746674854628252">"Majuscules auto"</string>
diff --git a/java/res/values-hi/strings-config-important-notice.xml b/java/res/values-hi/strings-config-important-notice.xml
index 3fe5cf8..45240b0 100644
--- a/java/res/values-hi/strings-config-important-notice.xml
+++ b/java/res/values-hi/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"सुझावों में सुधार हेतु अपने संचार और लिखे गए डेटा से जानकारी पाएं"</string>
 </resources>
diff --git a/java/res/values-hi/strings.xml b/java/res/values-hi/strings.xml
index 5797ec1..58a31c1 100644
--- a/java/res/values-hi/strings.xml
+++ b/java/res/values-hi/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"संपर्क नाम सुझाएं"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"सुझाव और सुधार के लिए संपर्क से नामों का उपयोग करें"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"वैयक्तिकृत सुझाव"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"सुझावों में सुधार हेतु अपने संचार और लिखे गए डेटा से जानकारी पाएं"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"दोहरे स्पेस वाला पीरियड"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"स्पेसबार पर डबल टैप करने से पीरियड शामिल हो जाता है जिसके बाद एक रिक्ति होती है"</string>
     <string name="auto_cap" msgid="1719746674854628252">"स्‍वत: अक्षर बड़े करना"</string>
diff --git a/java/res/values-hr/strings-config-important-notice.xml b/java/res/values-hr/strings-config-important-notice.xml
index 3fe5cf8..553fbf3 100644
--- a/java/res/values-hr/strings-config-important-notice.xml
+++ b/java/res/values-hr/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Upotrijebi poruke i upisane podatke za poboljšanje prijedloga"</string>
 </resources>
diff --git a/java/res/values-hr/strings.xml b/java/res/values-hr/strings.xml
index f4a006e..4e828cf 100644
--- a/java/res/values-hr/strings.xml
+++ b/java/res/values-hr/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Predlaži imena kontakata"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Upotreba imena iz Kontakata za prijedloge i ispravke"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Prilagođeni prijedlozi"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Upotrijebi poruke i upisane podatke za poboljšanje prijedloga"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Točka s dva razmaka"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Dvostrukim dodirivanjem razmaknice umeću se točka i razmak"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Automatsko pisanje velikih slova"</string>
diff --git a/java/res/values-hu/strings-config-important-notice.xml b/java/res/values-hu/strings-config-important-notice.xml
index 3fe5cf8..af78095 100644
--- a/java/res/values-hu/strings-config-important-notice.xml
+++ b/java/res/values-hu/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Javaslatok javítása a kommunikáció és begépelt adatok alapján"</string>
 </resources>
diff --git a/java/res/values-hu/strings.xml b/java/res/values-hu/strings.xml
index faaadbb..e94bd98 100644
--- a/java/res/values-hu/strings.xml
+++ b/java/res/values-hu/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Javasolt névjegyek"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"A névjegyek használata a javaslatokhoz és javításokhoz"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Testreszabott javaslatok"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Javaslatok javítása a kommunikáció és begépelt adatok alapján"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Dupla szóköz: pont"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"A szóköz kétszeri megérintése beszúr egy pontot, majd egy szóközt"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Automatikusan nagy kezdőbetű"</string>
diff --git a/java/res/values-hy-rAM/config-spacing-and-punctuations.xml b/java/res/values-hy-rAM/config-spacing-and-punctuations.xml
index 8bc1b85..792762d 100644
--- a/java/res/values-hy-rAM/config-spacing-and-punctuations.xml
+++ b/java/res/values-hy-rAM/config-spacing-and-punctuations.xml
@@ -25,7 +25,7 @@
     <string name="symbols_followed_by_space" translatable="false">.,;:!?)]}&amp;&#x0589;&#x055D;</string>
     <!-- Symbols that separate words. Adding armenian period and comma. -->
     <!-- Don't remove the enclosing double quotes, they protect whitespace (not just U+0020) -->
-    <string name="symbols_word_separators" translatable="false">"&#x0009;&#x0020;&#x000A;"()[]{}*&amp;&lt;&gt;+=|.,;:!?/_\"&#x0589;&#x055D;</string>
+    <string name="symbols_word_separators" translatable="false">"&#x0009;&#x0020;&#x000A;&#x00A0;"()[]{}*&amp;&lt;&gt;+=|.,;:!?/_\"&#x0589;&#x055D;</string>
     <!-- The sentence separator code point, for capitalization -->
     <!-- U+0589: "։" ARMENIAN FULL STOP   ; 589h = 1417d -->
     <integer name="sentence_separator" translatable="false">1417</integer>
diff --git a/java/res/values-hy-rAM/strings-config-important-notice.xml b/java/res/values-hy-rAM/strings-config-important-notice.xml
index 3fe5cf8..e6ace36 100644
--- a/java/res/values-hy-rAM/strings-config-important-notice.xml
+++ b/java/res/values-hy-rAM/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Բարելավեք առաջարկները` ձեր զրույցներից և մուտքագրած տվյալներից"</string>
 </resources>
diff --git a/java/res/values-hy-rAM/strings.xml b/java/res/values-hy-rAM/strings.xml
index f281f67..5ba8c4e 100644
--- a/java/res/values-hy-rAM/strings.xml
+++ b/java/res/values-hy-rAM/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Առաջարկել կոնտակտների անունները"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Օգտագործել կոնտակտների անունները՝ առաջարկների և ուղղումների համար"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Անհատականացված առաջարկներ"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Բարելավեք առաջարկները` ձեր զրույցներից և մուտքագրած տվյալներից"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Կրկնաբացակի վերջակետ"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Բացակի ստեղնի կրկնակի հպումը բացակից հետո վերջակետ է դնում"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Ավտոմատ գլխատառացում"</string>
diff --git a/java/res/values-in/strings-config-important-notice.xml b/java/res/values-in/strings-config-important-notice.xml
index 3fe5cf8..603b408 100644
--- a/java/res/values-in/strings-config-important-notice.xml
+++ b/java/res/values-in/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Belajar dari komunikasi &amp; data terketik untuk meningkatkan saran"</string>
 </resources>
diff --git a/java/res/values-in/strings.xml b/java/res/values-in/strings.xml
index 888219a..afed130 100644
--- a/java/res/values-in/strings.xml
+++ b/java/res/values-in/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Sarankan nama Kontak"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Menggunakan nama dari Kontak untuk saran dan koreksi"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Saran hasil personalisasi"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Belajar dari komunikasi &amp; data terketik untuk meningkatkan saran"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Titik spasi ganda"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Mengetuk tombol spasi dua kali akan memasukkan titik diikuti satu spasi"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Kapitalisasi otomatis"</string>
diff --git a/java/res/values-it/strings-config-important-notice.xml b/java/res/values-it/strings-config-important-notice.xml
index 3fe5cf8..4a4bb07 100644
--- a/java/res/values-it/strings-config-important-notice.xml
+++ b/java/res/values-it/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Usa comunicazioni e dati digitati per migliorare i suggerimenti"</string>
 </resources>
diff --git a/java/res/values-it/strings.xml b/java/res/values-it/strings.xml
index b688a9d..47ae61a 100644
--- a/java/res/values-it/strings.xml
+++ b/java/res/values-it/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Suggerisci nomi di contatti"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilizza nomi di Contatti per suggerimenti e correzioni"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Suggerimenti personalizz."</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Usa comunicazioni e dati digitati per migliorare i suggerimenti"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Doppio spazio per punto"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Tocca due volte barra spaziatr. per inserire punto seguito da spazio"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Maiuscole automatiche"</string>
diff --git a/java/res/values-iw/strings-config-important-notice.xml b/java/res/values-iw/strings-config-important-notice.xml
index 3fe5cf8..c04e240 100644
--- a/java/res/values-iw/strings-config-important-notice.xml
+++ b/java/res/values-iw/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"למד מהתכתבויות ומנתונים שהקלדת כדי לשפר את ההצעות"</string>
 </resources>
diff --git a/java/res/values-iw/strings.xml b/java/res/values-iw/strings.xml
index 19f2466..27ed135 100644
--- a/java/res/values-iw/strings.xml
+++ b/java/res/values-iw/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"הצע שמות של אנשי קשר"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"השתמש בשמות מרשימת אנשי הקשר עבור הצעות ותיקונים"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"הצעות מותאמות אישית"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"למד מהתכתבויות ומנתונים שהקלדת כדי לשפר את ההצעות"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"רווח כפול לנקודה"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"הקשה פעמיים על מקש הרווח מזינה נקודה ואחריה רווח"</string>
     <string name="auto_cap" msgid="1719746674854628252">"הפיכת אותיות לרישיות באופן אוטומטי"</string>
diff --git a/java/res/values-ja/strings-config-important-notice.xml b/java/res/values-ja/strings-config-important-notice.xml
index 3fe5cf8..0d4da7e 100644
--- a/java/res/values-ja/strings-config-important-notice.xml
+++ b/java/res/values-ja/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"メッセージなどのやり取りや入力したデータから入力候補を予測します"</string>
 </resources>
diff --git a/java/res/values-ja/strings.xml b/java/res/values-ja/strings.xml
index 4e3910f..a27e3a4 100644
--- a/java/res/values-ja/strings.xml
+++ b/java/res/values-ja/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"連絡先の名前を候補に表示"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"連絡先の名前を使用して候補表示や自動修正を行います"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"入力候補のカスタマイズ"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"メッセージなどのやり取りや入力したデータから入力候補を予測します"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"ダブルスペースピリオド"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"スペースバーをダブルタップするとピリオドとスペースを挿入できます"</string>
     <string name="auto_cap" msgid="1719746674854628252">"自動大文字変換"</string>
diff --git a/java/res/values-ka-rGE/strings-config-important-notice.xml b/java/res/values-ka-rGE/strings-config-important-notice.xml
index 3fe5cf8..fe2d136 100644
--- a/java/res/values-ka-rGE/strings-config-important-notice.xml
+++ b/java/res/values-ka-rGE/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"უკეთესი შეთავაზებისთვის თქვენი კომუნიკაციიდან და ტექსტიდან სწავლა"</string>
 </resources>
diff --git a/java/res/values-ka-rGE/strings.xml b/java/res/values-ka-rGE/strings.xml
index a040e95..2bdb1b8 100644
--- a/java/res/values-ka-rGE/strings.xml
+++ b/java/res/values-ka-rGE/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"კონტაქტის სახელების შეთავაზება"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"კონტაქტებიდან სახელების გამოყენება შეთავაზებებისთვის და კორექციისთვის"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"პერსონალიზებული შეთავაზებები"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"უკეთესი შეთავაზებისთვის თქვენი კომუნიკაციიდან და ტექსტიდან სწავლა"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"წერტილი ორმაგი შორისით"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"შორისზე ორჯერ შეხება დაწერს წერტილს და შორისის სიმბოლოს"</string>
     <string name="auto_cap" msgid="1719746674854628252">"ავტო-კაპიტალიზაცია"</string>
diff --git a/java/res/values-km-rKH/strings-config-important-notice.xml b/java/res/values-km-rKH/strings-config-important-notice.xml
index 3fe5cf8..301e544 100644
--- a/java/res/values-km-rKH/strings-config-important-notice.xml
+++ b/java/res/values-km-rKH/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"រៀន​ពី​ការ​ភ្ជាប់​របស់​អ្នក និង​ទិន្នន័យ​​ដែល​បាន​បញ្ចូល ដើម្បី​​លើក​កម្ពស់​ការ​ស្នើ"</string>
 </resources>
diff --git a/java/res/values-km-rKH/strings.xml b/java/res/values-km-rKH/strings.xml
index 2112ed7..142607c 100644
--- a/java/res/values-km-rKH/strings.xml
+++ b/java/res/values-km-rKH/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"ស្នើ​ឈ្មោះ​ទំនាក់ទំនង"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"ប្រើ​ឈ្មោះ​ពី​ទំនាក់ទំនង​សម្រាប់​ការ​​ស្នើ និង​​​កែ"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"ការ​ស្នើ​ផ្ទាល់​ខ្លួន"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"រៀន​ពី​ការ​ភ្ជាប់​របស់​អ្នក និង​ទិន្នន័យ​​ដែល​បាន​បញ្ចូល ដើម្បី​​លើក​កម្ពស់​ការ​ស្នើ"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"រយៈ​ពេល​ចុច​ដកឃ្លា​ពីរដង"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"ប៉ះ​ដកឃ្លា​ពីរ​​ដង​បញ្ចូល​​​រយៈ​ពេល​ដែល​អនុវត្ត​តាម​ដកឃ្លា"</string>
     <string name="auto_cap" msgid="1719746674854628252">"ការ​សរសេរ​ជា​អក្សរ​ធំ​​ស្វ័យប្រវត្តិ"</string>
diff --git a/java/res/values-ko/strings-config-important-notice.xml b/java/res/values-ko/strings-config-important-notice.xml
index 3fe5cf8..1ede0e5 100644
--- a/java/res/values-ko/strings-config-important-notice.xml
+++ b/java/res/values-ko/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"사용자의 대화 내용과 입력한 데이터를 통해 추천 검색어의 정확도를 개선합니다."</string>
 </resources>
diff --git a/java/res/values-ko/strings.xml b/java/res/values-ko/strings.xml
index a803e6f..0cf0b10 100644
--- a/java/res/values-ko/strings.xml
+++ b/java/res/values-ko/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"주소록 이름 활용"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"추천 및 수정에 주소록의 이름 사용"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"맞춤 추천 검색어"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"사용자의 대화 내용과 입력한 데이터를 통해 추천 검색어의 정확도를 개선합니다."</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"더블스페이스 마침표"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"스페이스바를 두 번 탭하면 마침표와 공백 한 개가 삽입됩니다."</string>
     <string name="auto_cap" msgid="1719746674854628252">"자동 대문자화"</string>
diff --git a/java/res/values-lo-rLA/strings-config-important-notice.xml b/java/res/values-lo-rLA/strings-config-important-notice.xml
index 3fe5cf8..6b2bc5b 100644
--- a/java/res/values-lo-rLA/strings-config-important-notice.xml
+++ b/java/res/values-lo-rLA/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"ຮຽນຮູ້ຈາກການສື່ສານ ແລະຂໍ້ມູນທີ່ເຄີຍພິມຂອງທ່ານເພື່ອປັບປຸງຄຳແນະນຳ"</string>
 </resources>
diff --git a/java/res/values-lo-rLA/strings.xml b/java/res/values-lo-rLA/strings.xml
index a206cdb..881358f 100644
--- a/java/res/values-lo-rLA/strings.xml
+++ b/java/res/values-lo-rLA/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"ແນະນຳລາຍຊື່ຜູ່ຕິດຕໍ່"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"ໃຊ້ຊື່ຈາກລາຍຊື່ຜູ່ຕິດຕໍ່ສຳລັບການແນະນຳ ແລະ ການຊ່ວຍແກ້ຄຳ"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"ຄຳແນະນຳຕາມການນຳໃຊ້ຂອງທ່ານ"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"ຮຽນຮູ້ຈາກການສື່ສານ ແລະຂໍ້ມູນທີ່ເຄີຍພິມຂອງທ່ານເພື່ອປັບປຸງຄຳແນະນຳ"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"ຍະຫວ່າງສອງເທື່ອເພື່ອໃສ່ຈ້ຳເມັດ"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"ກົດທີ່ປຸ່ມຍະຫວ່າງສອງເທື່ອເພື່ອໃສ່ຈ້ຳເມັດແລ້ວຕາມດ້ວຍການຍະຫວ່າງ"</string>
     <string name="auto_cap" msgid="1719746674854628252">"ເຮັດໂຕພິມໃຫຍ່ອັດຕະໂນມັດ"</string>
diff --git a/java/res/values-lt/strings-config-important-notice.xml b/java/res/values-lt/strings-config-important-notice.xml
index 3fe5cf8..7468e4a 100644
--- a/java/res/values-lt/strings-config-important-notice.xml
+++ b/java/res/values-lt/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Mokytis iš ryšių ir įvestų duomenų, siekiant pagerinti pasiūlymus"</string>
 </resources>
diff --git a/java/res/values-lt/strings.xml b/java/res/values-lt/strings.xml
index 0fe7dd6..3f504e4 100644
--- a/java/res/values-lt/strings.xml
+++ b/java/res/values-lt/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Siūlyti kontaktų vardus"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Siūlant ir taisant naudoti vardus iš „Kontaktų“"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Suasmeninti pasiūlymai"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Mokytis iš ryšių ir įvestų duomenų, siekiant pagerinti pasiūlymus"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Tšk. ir tarp. pal. dukart"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Dukart palietus tarpo klavišą įterpiamas taškas ir tarpas."</string>
     <string name="auto_cap" msgid="1719746674854628252">"Automatinis didžiųjų raidžių rašymas"</string>
diff --git a/java/res/values-lv/strings-config-important-notice.xml b/java/res/values-lv/strings-config-important-notice.xml
index 3fe5cf8..8a80a0b 100644
--- a/java/res/values-lv/strings-config-important-notice.xml
+++ b/java/res/values-lv/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Izmantojiet saziņu un ievadītos datus, lai uzlabotu ieteikumus."</string>
 </resources>
diff --git a/java/res/values-lv/strings.xml b/java/res/values-lv/strings.xml
index 9b09dd6..55f002d 100644
--- a/java/res/values-lv/strings.xml
+++ b/java/res/values-lv/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Ieteikt kontaktp. vārdus"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Izmantot kontaktpersonu vārdus kā ieteikumus un labojumus"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Personalizēti ieteikumi"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Izmantojiet saziņu un ievadītos datus, lai uzlabotu ieteikumus."</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Dubultpiesk. = punkts"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Divreiz pieskaroties atst. taustiņam, ievada punktu un atstarpi."</string>
     <string name="auto_cap" msgid="1719746674854628252">"Automātiska lielo burtu lietošana"</string>
diff --git a/java/res/values-mn-rMN/strings-config-important-notice.xml b/java/res/values-mn-rMN/strings-config-important-notice.xml
index 3fe5cf8..a101765 100644
--- a/java/res/values-mn-rMN/strings-config-important-notice.xml
+++ b/java/res/values-mn-rMN/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Зөвлөмжүүдийг сайжруулахын тулд таны харилцсан, бичсэн зүйлсээс суралцана"</string>
 </resources>
diff --git a/java/res/values-mn-rMN/strings.xml b/java/res/values-mn-rMN/strings.xml
index a89b974..a3ce365 100644
--- a/java/res/values-mn-rMN/strings.xml
+++ b/java/res/values-mn-rMN/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Харилцагчдын нэрс санал болгох"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Санал болгох, залруулахда Харилцагчдын нэрсээс ашиглах"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Хувийн тохиргоотой зөвлөмжүүд"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Зөвлөмжүүдийг сайжруулахын тулд таны харилцсан, бичсэн зүйлсээс суралцана"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Давхар зайтай цэг"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Ардаа зайтай цэг оруулахын тулд Зай авах дээр давхар товшино уу"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Автоматаар томруулах"</string>
diff --git a/java/res/values-ms-rMY/strings-config-important-notice.xml b/java/res/values-ms-rMY/strings-config-important-notice.xml
index 3fe5cf8..47ef54e 100644
--- a/java/res/values-ms-rMY/strings-config-important-notice.xml
+++ b/java/res/values-ms-rMY/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Belajar daripada komunikasi &amp; data ditaip utk memperbaik cadangan"</string>
 </resources>
diff --git a/java/res/values-ms-rMY/strings.xml b/java/res/values-ms-rMY/strings.xml
index c042a79..5f42b7c 100644
--- a/java/res/values-ms-rMY/strings.xml
+++ b/java/res/values-ms-rMY/strings.xml
@@ -47,7 +47,6 @@
     <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_personalized_dicts" msgid="5167396352105467626">"Cadangan diperibadikan"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Belajar daripada komunikasi &amp; data ditaip utk memperbaik cadangan"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Titik ruang berganda"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Mengetik 2X pada bar ruang memasukkan titik diikuti dengan ruang"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Autopenghurufbesaran"</string>
diff --git a/java/res/values-nb/strings-config-important-notice.xml b/java/res/values-nb/strings-config-important-notice.xml
index 3fe5cf8..ab2563b 100644
--- a/java/res/values-nb/strings-config-important-notice.xml
+++ b/java/res/values-nb/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Lær av kommunikasjonen og inndataene dine for å få bedre forslag"</string>
 </resources>
diff --git a/java/res/values-nb/strings.xml b/java/res/values-nb/strings.xml
index 510bef4..0af4e62 100644
--- a/java/res/values-nb/strings.xml
+++ b/java/res/values-nb/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Foreslå kontaktnavn"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Bruk navn fra Kontakter til forslag og korrigeringer"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Spesialtilpassede forslag"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Lær av kommunikasjonen og inndataene dine for å få bedre forslag"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Punktum ved doble mellomrom"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Dobbeltrykk på mellomromstasten for punktum etterfulgt av mellomrom"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Stor forbokstav"</string>
diff --git a/java/res/values-ne-rNP/strings-config-important-notice.xml b/java/res/values-ne-rNP/strings-config-important-notice.xml
index 3fe5cf8..cb74c95 100644
--- a/java/res/values-ne-rNP/strings-config-important-notice.xml
+++ b/java/res/values-ne-rNP/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"सुझावहरू सुधार गर्न तपाईँको सञ्‍चारहरू र टाइप गरिएको डेटाबाट जान्नुहोस्"</string>
 </resources>
diff --git a/java/res/values-ne-rNP/strings.xml b/java/res/values-ne-rNP/strings.xml
index fa7ebd2..800a934 100644
--- a/java/res/values-ne-rNP/strings.xml
+++ b/java/res/values-ne-rNP/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"सम्पर्क नामहरू सुझाव गर्नुहोस्"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"सुझाव र सुधारका लागि सम्पर्कबाट नामहरू प्रयोग गर्नुहोस्"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"निजीकृत सुझावहरू"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"सुझावहरू सुधार गर्न तपाईँको सञ्‍चारहरू र टाइप गरिएको डेटाबाट जान्नुहोस्"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"डबल-स्पेस पूर्णविराम"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"स्पेसबारमा डबल ट्याप गर्नाले पूर्णविरामपछि स्पेस राख्दछ"</string>
     <string name="auto_cap" msgid="1719746674854628252">"स्वतः पूँजिकरण"</string>
diff --git a/java/res/values-nl/strings-config-important-notice.xml b/java/res/values-nl/strings-config-important-notice.xml
index 3fe5cf8..bb12d41 100644
--- a/java/res/values-nl/strings-config-important-notice.xml
+++ b/java/res/values-nl/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Suggesties verbeteren met uw communicatie en getypte gegevens"</string>
 </resources>
diff --git a/java/res/values-nl/strings.xml b/java/res/values-nl/strings.xml
index 565811b..4835f7e 100644
--- a/java/res/values-nl/strings.xml
+++ b/java/res/values-nl/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Contactnamen suggereren"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Namen uit Contacten gebruiken voor suggesties en correcties"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Gepersonaliseerde suggesties"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Suggesties verbeteren met uw communicatie en getypte gegevens"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Dubbeltik is punt, spatie"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Dubbeltik op spatiebalk voor een punt gevolgd door een spatie"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Auto-hoofdlettergebruik"</string>
diff --git a/java/res/values-pl/strings-config-important-notice.xml b/java/res/values-pl/strings-config-important-notice.xml
index 3fe5cf8..f87cd2b 100644
--- a/java/res/values-pl/strings-config-important-notice.xml
+++ b/java/res/values-pl/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Analizuj wiadomości i wpisywane dane, by ulepszać podpowiedzi"</string>
 </resources>
diff --git a/java/res/values-pl/strings.xml b/java/res/values-pl/strings.xml
index 15ce516..5d30113 100644
--- a/java/res/values-pl/strings.xml
+++ b/java/res/values-pl/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Proponuj osoby z kontaktów"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"W propozycjach i poprawkach użyj nazwisk z kontaktów"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Spersonalizowane sugestie"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Analizuj wiadomości i wpisywane dane, by ulepszać podpowiedzi"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Szybka kropka ze spacją"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Dwukrotne kliknięcie spacji wstawia kropkę ze spacją"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Wstawiaj wielkie litery"</string>
diff --git a/java/res/values-pt-rPT/strings-config-important-notice.xml b/java/res/values-pt-rPT/strings-config-important-notice.xml
index 3fe5cf8..f330c4b 100644
--- a/java/res/values-pt-rPT/strings-config-important-notice.xml
+++ b/java/res/values-pt-rPT/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Aprender com comunicações e dados introd. para melhorar sugestões"</string>
 </resources>
diff --git a/java/res/values-pt-rPT/strings.xml b/java/res/values-pt-rPT/strings.xml
index eb519d2..69d995b 100644
--- a/java/res/values-pt-rPT/strings.xml
+++ b/java/res/values-pt-rPT/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Sugerir nomes de Contactos"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilizar nomes dos Contactos para sugestões e correções"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Sugestões personalizadas"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Aprender com comunicações e dados introd. para melhorar sugestões"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Ponto de espaço duplo"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Tocar duas vezes na barra espaço insere ponto seguido de espaço"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Letras maiúsculas automáticas"</string>
diff --git a/java/res/values-pt/strings-config-important-notice.xml b/java/res/values-pt/strings-config-important-notice.xml
index 3fe5cf8..de5ce0c 100644
--- a/java/res/values-pt/strings-config-important-notice.xml
+++ b/java/res/values-pt/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Aprender com mensagens e dados digitados para melhorar sugestões"</string>
 </resources>
diff --git a/java/res/values-pt/strings.xml b/java/res/values-pt/strings.xml
index e8af37c..057c3b4 100644
--- a/java/res/values-pt/strings.xml
+++ b/java/res/values-pt/strings.xml
@@ -47,7 +47,6 @@
     <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_personalized_dicts" msgid="5167396352105467626">"Sugestões personalizadas"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Aprender com mensagens e dados digitados para melhorar sugestões"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Duplo espaço para ponto"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Toque duplo na barra de espaço insere um ponto seguido de espaço"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Capitalização automática"</string>
diff --git a/java/res/values-ro/strings-config-important-notice.xml b/java/res/values-ro/strings-config-important-notice.xml
index 3fe5cf8..bbd02e8 100644
--- a/java/res/values-ro/strings-config-important-notice.xml
+++ b/java/res/values-ro/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Utilizați comunic. și datele introd. pt. a îmbunătăți sugestiile"</string>
 </resources>
diff --git a/java/res/values-ro/strings.xml b/java/res/values-ro/strings.xml
index c94dc78..54354b1 100644
--- a/java/res/values-ro/strings.xml
+++ b/java/res/values-ro/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Sugeraţi nume din Agendă"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilizaţi numele din Agendă pentru sugestii şi corecţii"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Sugestii personalizate"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Utilizați comunic. și datele introd. pt. a îmbunătăți sugestiile"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Inserează punct spațiu"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Dubla atingere a barei de spațiu inserează punct urmat de spațiu"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Scriere automată cu majuscule"</string>
diff --git a/java/res/values-ru/strings-config-important-notice.xml b/java/res/values-ru/strings-config-important-notice.xml
index 3fe5cf8..01fa5bd 100644
--- a/java/res/values-ru/strings-config-important-notice.xml
+++ b/java/res/values-ru/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Устройство будет запоминать то, что вы вводите чаще всего"</string>
 </resources>
diff --git a/java/res/values-ru/strings.xml b/java/res/values-ru/strings.xml
index 5dacd77..05dd035 100644
--- a/java/res/values-ru/strings.xml
+++ b/java/res/values-ru/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Подсказывать имена"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Подсказывать исправления на основе имен из списка контактов"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Пользовательские словари"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Устройство будет запоминать то, что вы вводите чаще всего"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Ставить точки автоматически"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Вводить точку с пробелом двойным нажатием кнопки \"Пробел\"."</string>
     <string name="auto_cap" msgid="1719746674854628252">"Заглавные автоматически"</string>
diff --git a/java/res/values-sk/strings-config-important-notice.xml b/java/res/values-sk/strings-config-important-notice.xml
index 3fe5cf8..0cabcda 100644
--- a/java/res/values-sk/strings-config-important-notice.xml
+++ b/java/res/values-sk/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Zlepšovať návrhy na základe komunikácie a zadaných údajov"</string>
 </resources>
diff --git a/java/res/values-sk/strings.xml b/java/res/values-sk/strings.xml
index 80c8d9e..c4d3eca 100644
--- a/java/res/values-sk/strings.xml
+++ b/java/res/values-sk/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Navrhnúť mená kontaktov"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Používať mená z Kontaktov na návrhy a opravy"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Prispôsobené návrhy"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Zlepšovať návrhy na základe komunikácie a zadaných údajov"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Bodka s medzerou"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Dvojitým klepnutím na medzerník vložíte bodku a medzeru."</string>
     <string name="auto_cap" msgid="1719746674854628252">"Veľké písmená automaticky"</string>
diff --git a/java/res/values-sl/strings-config-important-notice.xml b/java/res/values-sl/strings-config-important-notice.xml
index 3fe5cf8..2bbdee3 100644
--- a/java/res/values-sl/strings-config-important-notice.xml
+++ b/java/res/values-sl/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Vaša sporočila in vnesene podatke uporabi za boljše predloge"</string>
 </resources>
diff --git a/java/res/values-sl/strings.xml b/java/res/values-sl/strings.xml
index 3704e2c..c100de7 100644
--- a/java/res/values-sl/strings.xml
+++ b/java/res/values-sl/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Predlagaj imena stikov"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Uporaba imen iz stikov za predloge in popravke"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Prilagojeni predlogi"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Vaša sporočila in vnesene podatke uporabi za boljše predloge"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Dva presl. za vnos pike"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Z dvojnim dotikom preslednice vstavite piko in za njo presledek"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Samod. velike začetnice"</string>
diff --git a/java/res/values-sr/strings-config-important-notice.xml b/java/res/values-sr/strings-config-important-notice.xml
index 3fe5cf8..0a4510b 100644
--- a/java/res/values-sr/strings-config-important-notice.xml
+++ b/java/res/values-sr/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Користи комуникације и унете податке ради побољшања предлога"</string>
 </resources>
diff --git a/java/res/values-sr/strings.xml b/java/res/values-sr/strings.xml
index 510a2e8..9ded43e 100644
--- a/java/res/values-sr/strings.xml
+++ b/java/res/values-sr/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Предложи имена контаката"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Користи имена из Контаката за предлоге и исправке"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Персонализовани предлози"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Користи комуникације и унете податке ради побољшања предлога"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Тачка и размак"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Двоструким додиром размака умеће се тачка праћена размаком"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Аутоматски унос великих слова"</string>
diff --git a/java/res/values-sv/strings-config-important-notice.xml b/java/res/values-sv/strings-config-important-notice.xml
index 3fe5cf8..bc56640 100644
--- a/java/res/values-sv/strings-config-important-notice.xml
+++ b/java/res/values-sv/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Få bättre förslag genom att använda tidigare angiven data och annan kommunikation"</string>
 </resources>
diff --git a/java/res/values-sv/strings.xml b/java/res/values-sv/strings.xml
index 0dcda09..2a9139f 100644
--- a/java/res/values-sv/strings.xml
+++ b/java/res/values-sv/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Föreslå kontaktnamn"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Använd namn från Kontakter för förslag och korrigeringar"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Anpassade förslag"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Få bättre förslag genom att använda tidigare angiven data och annan kommunikation"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Dubbelt blanksteg = punkt"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Dubbelt blanksteg ger en punkt följt av mellanslag"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Automatiska versaler"</string>
diff --git a/java/res/values-sw/strings-config-important-notice.xml b/java/res/values-sw/strings-config-important-notice.xml
index 3fe5cf8..b5aac5f 100644
--- a/java/res/values-sw/strings-config-important-notice.xml
+++ b/java/res/values-sw/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Jifunze kutoka kwa mawasiliano yako na data iliyocharazwa ili kuboresha mapendekezo"</string>
 </resources>
diff --git a/java/res/values-sw/strings.xml b/java/res/values-sw/strings.xml
index e7b051d..85af028 100644
--- a/java/res/values-sw/strings.xml
+++ b/java/res/values-sw/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Pendekeza majini ya Anwani"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Tumia majina kutoka kwa Anwani kwa mapendekezo na marekebisho"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Mapendekezo yaliyobadilishwa kukufaa"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Jifunze kutoka kwa mawasiliano yako na data iliyocharazwa ili kuboresha mapendekezo"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Kitone baada ya nafasi mbili"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Kugonga mara mbili kwenye upau nafasi kunaingiza kitone kikifuatiwa na nafasi"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Uwekaji wa herufi kubwa kiotomatiki"</string>
diff --git a/java/res/values-iw/config-spacing-and-punctuations.xml b/java/res/values-sw600dp/config-spacing-and-punctuations.xml
similarity index 72%
copy from java/res/values-iw/config-spacing-and-punctuations.xml
copy to java/res/values-sw600dp/config-spacing-and-punctuations.xml
index 9e637e4..9c12cf4 100644
--- a/java/res/values-iw/config-spacing-and-punctuations.xml
+++ b/java/res/values-sw600dp/config-spacing-and-punctuations.xml
@@ -2,7 +2,7 @@
 <!--
 /*
 **
-** Copyright 2012, The Android Open Source Project
+** Copyright 2014, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
@@ -18,8 +18,6 @@
 */
 -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- The all letters need to be mirrored are found at
-         http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt -->
     <!-- Symbols that are suggested between words -->
-    <string name="suggested_punctuations" translatable="false">!,?,\\,,:,;,\",(|),)|(,\',-,/,@,_</string>
+    <string name="suggested_punctuations" translatable="false">:,;,\",!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis,\',-,/,@,_</string>
 </resources>
diff --git a/java/res/values-th/strings-config-important-notice.xml b/java/res/values-th/strings-config-important-notice.xml
index 3fe5cf8..9fb02c4 100644
--- a/java/res/values-th/strings-config-important-notice.xml
+++ b/java/res/values-th/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"เรียนรู้จากการสื่อสารและข้อมูลที่พิมพ์ของคุณเพื่อปรับปรุงคำแนะนำ"</string>
 </resources>
diff --git a/java/res/values-th/strings.xml b/java/res/values-th/strings.xml
index a439537..2301c31 100644
--- a/java/res/values-th/strings.xml
+++ b/java/res/values-th/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"แนะนำชื่อผู้ติดต่อ"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"ใช้ชื่อจากรายชื่อติดต่อสำหรับคำแนะนำและการแก้ไข"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"คำแนะนำในแบบของคุณ"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"เรียนรู้จากการสื่อสารและข้อมูลที่พิมพ์ของคุณเพื่อปรับปรุงคำแนะนำ"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"แตะ Space สองครั้งแทรกจุด"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"แตะ Spacebar สองครั้งจะแทรกจุดตามด้วยช่องว่างหนึ่งช่อง"</string>
     <string name="auto_cap" msgid="1719746674854628252">"ปรับเป็นตัวพิมพ์ใหญ่อัตโนมัติ"</string>
diff --git a/java/res/values-tl/strings-config-important-notice.xml b/java/res/values-tl/strings-config-important-notice.xml
index 3fe5cf8..454208c 100644
--- a/java/res/values-tl/strings-config-important-notice.xml
+++ b/java/res/values-tl/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Pahusayin ang suhestiyon batay sa pag-uusap at na-type na data"</string>
 </resources>
diff --git a/java/res/values-tl/strings.xml b/java/res/values-tl/strings.xml
index 87a6f42..fd979cf 100644
--- a/java/res/values-tl/strings.xml
+++ b/java/res/values-tl/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Mungkahi pangalan Contact"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Gamitin pangalan mula Mga Contact sa mga mungkahi\'t pagwawasto"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Personalized suggestions"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Pahusayin ang suhestiyon batay sa pag-uusap at na-type na data"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Double-space period"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Naglalagay ng tuldok na may puwang ang pag-double tap sa spacebar"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Auto-capitalization"</string>
diff --git a/java/res/values-tr/strings-config-important-notice.xml b/java/res/values-tr/strings-config-important-notice.xml
index 3fe5cf8..3f15b82 100644
--- a/java/res/values-tr/strings-config-important-notice.xml
+++ b/java/res/values-tr/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Önerileri iyileştirmek için iletişimlerimden ve yazılan verilerden öğren"</string>
 </resources>
diff --git a/java/res/values-tr/strings.xml b/java/res/values-tr/strings.xml
index 18d4da0..c2cb428 100644
--- a/java/res/values-tr/strings.xml
+++ b/java/res/values-tr/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Kişi Adları öner"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Öneri ve düzeltmeler için Kişiler\'deki adları kullan"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Kişisel öneriler"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Önerileri iyileştirmek için iletişimlerimden ve yazılan verilerden öğren"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Çift boşlukla nokta ekleme"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Boşluk çubuğuna iki kez vurmak nokta ve ardından bir boşluk ekler"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Otomatik olarak büyük harf yap"</string>
diff --git a/java/res/values-uk/strings-config-important-notice.xml b/java/res/values-uk/strings-config-important-notice.xml
index 3fe5cf8..cb97f7f 100644
--- a/java/res/values-uk/strings-config-important-notice.xml
+++ b/java/res/values-uk/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Пристрій буде запам’ятовувати, що ви пишете, надсилаєте й отримуєте"</string>
 </resources>
diff --git a/java/res/values-uk/strings.xml b/java/res/values-uk/strings.xml
index b82913a..95bfa5b 100644
--- a/java/res/values-uk/strings.xml
+++ b/java/res/values-uk/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Пропон. імена контактів"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Використ. імена зі списку контактів для пропозицій і виправлень"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Персональні пропозиції"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Пристрій буде запам’ятовувати, що ви пишете, надсилаєте й отримуєте"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Крапка подвійним пробілом"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Подвійне натискання пробілу вставляє крапку з пробілом після неї"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Авто викор. вел. літер"</string>
diff --git a/java/res/values-vi/strings-config-important-notice.xml b/java/res/values-vi/strings-config-important-notice.xml
index 3fe5cf8..8586112 100644
--- a/java/res/values-vi/strings-config-important-notice.xml
+++ b/java/res/values-vi/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Tìm hiểu từ thông tin liên lạc và dữ liệu đã nhập của bạn để cải thiện đề xuất"</string>
 </resources>
diff --git a/java/res/values-vi/strings.xml b/java/res/values-vi/strings.xml
index dc2741d..1350572 100644
--- a/java/res/values-vi/strings.xml
+++ b/java/res/values-vi/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Đề xuất tên liên hệ"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Sử dụng tên từ Danh bạ cho các đề xuất và chỉnh sửa"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Đề xuất được cá nhân hóa"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Tìm hiểu từ thông tin liên lạc và dữ liệu đã nhập của bạn để cải thiện đề xuất"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Dấu cách đôi"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Nhấn đúp vào phím cách sẽ chèn thêm một dấu sau dấu cách"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Tự động viết hoa"</string>
diff --git a/java/res/values-zh-rCN/strings-config-important-notice.xml b/java/res/values-zh-rCN/strings-config-important-notice.xml
index 3fe5cf8..9ca18b5 100644
--- a/java/res/values-zh-rCN/strings-config-important-notice.xml
+++ b/java/res/values-zh-rCN/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"根据您的通信记录和以往输入的数据来完善建议"</string>
 </resources>
diff --git a/java/res/values-zh-rCN/strings.xml b/java/res/values-zh-rCN/strings.xml
index c4fd700..3a55366 100644
--- a/java/res/values-zh-rCN/strings.xml
+++ b/java/res/values-zh-rCN/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"联系人姓名建议"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"根据通讯录中的姓名提供建议和更正"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"个性化建议"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"根据您的通信记录和以往输入的数据来完善建议"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"双击空格插入句号"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"双击空格键可插入句号并后跟空格"</string>
     <string name="auto_cap" msgid="1719746674854628252">"自动大写"</string>
diff --git a/java/res/values-zh-rHK/strings-config-important-notice.xml b/java/res/values-zh-rHK/strings-config-important-notice.xml
index 3fe5cf8..6b38076 100644
--- a/java/res/values-zh-rHK/strings-config-important-notice.xml
+++ b/java/res/values-zh-rHK/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"根據您的通訊記錄和已輸入的資料改善建議"</string>
 </resources>
diff --git a/java/res/values-zh-rHK/strings.xml b/java/res/values-zh-rHK/strings.xml
index 0980205..3c8cd84 100644
--- a/java/res/values-zh-rHK/strings.xml
+++ b/java/res/values-zh-rHK/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"建議聯絡人名稱"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"使用「聯絡人」的名稱提供建議與修正"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"個人化建議"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"根據您的通訊記錄和已輸入的資料改善建議"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"按兩下空格鍵插入句號"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"只要輕按兩下空格鍵,即可插入句號並在後面加上一個空格"</string>
     <string name="auto_cap" msgid="1719746674854628252">"自動大寫"</string>
diff --git a/java/res/values-zh-rTW/strings-config-important-notice.xml b/java/res/values-zh-rTW/strings-config-important-notice.xml
index 3fe5cf8..a3948d2 100644
--- a/java/res/values-zh-rTW/strings-config-important-notice.xml
+++ b/java/res/values-zh-rTW/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"根據您的通訊紀錄和以往輸入的資料改善建議項目"</string>
 </resources>
diff --git a/java/res/values-zh-rTW/strings.xml b/java/res/values-zh-rTW/strings.xml
index 7073f21..1329482 100644
--- a/java/res/values-zh-rTW/strings.xml
+++ b/java/res/values-zh-rTW/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"聯絡人姓名建議"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"根據「聯絡人」名稱提供建議與修正"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"個人化建議"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"根據您的通訊紀錄和以往輸入的資料改善建議項目"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"輕按兩下空格鍵即插入句號"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"輕按兩下空格鍵可插入句號另加一個空格"</string>
     <string name="auto_cap" msgid="1719746674854628252">"自動大寫"</string>
diff --git a/java/res/values-zu/strings-config-important-notice.xml b/java/res/values-zu/strings-config-important-notice.xml
index 3fe5cf8..2e75539 100644
--- a/java/res/values-zu/strings-config-important-notice.xml
+++ b/java/res/values-zu/strings-config-important-notice.xml
@@ -22,4 +22,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="important_notice_title" msgid="1836002733109536160"></string>
     <string name="important_notice_contents" msgid="897137043719116217"></string>
+    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Funda kusuka kwezoxhumano zakho nedatha ethayiphiwe ukuze uthuthukise iziphakamiso"</string>
 </resources>
diff --git a/java/res/values-zu/strings.xml b/java/res/values-zu/strings.xml
index 2281933..1d21c4e 100644
--- a/java/res/values-zu/strings.xml
+++ b/java/res/values-zu/strings.xml
@@ -47,7 +47,6 @@
     <string name="use_contacts_dict" msgid="4435317977804180815">"Sikisela amagama Othintana nabo"</string>
     <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Amagama abasebenzisi kusuka Kothintana nabo bokusikisela nokulungisa"</string>
     <string name="use_personalized_dicts" msgid="5167396352105467626">"Iziphakamiso ezenziwe okomuntu siqu"</string>
-    <string name="use_personalized_dicts_summary" msgid="4331467814162666438">"Funda kusuka kwezoxhumano zakho nedatha ethayiphiwe ukuze uthuthukise iziphakamiso"</string>
     <string name="use_double_space_period" msgid="8781529969425082860">"Isikhathi se-Double-space"</string>
     <string name="use_double_space_period_summary" msgid="6532892187247952799">"Ukuthepha kabili kubha yesikhala kufaka isikhathi esilandelwa yisikhala"</string>
     <string name="auto_cap" msgid="1719746674854628252">"Ukwenza ofeleba okuzenzakalelayo"</string>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index 78cf34d..0550606 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -111,6 +111,7 @@
         <attr name="keyPreviewOffset" format="dimension" />
         <!-- Height of the key press feedback popup. -->
         <attr name="keyPreviewHeight" format="dimension" />
+        <!-- TODO: consolidate key preview linger timeout with the key preview animation parameters. -->
         <!-- Delay after key releasing and key press feedback dismissing in millisecond -->
         <attr name="keyPreviewLingerTimeout" format="integer" />
         <!-- Layout resource for more keys keyboard -->
diff --git a/java/res/values/config-common.xml b/java/res/values/config-common.xml
index 1b44bad..224aabd 100644
--- a/java/res/values/config-common.xml
+++ b/java/res/values/config-common.xml
@@ -35,10 +35,11 @@
 
     <integer name="config_ignore_alt_code_key_timeout">350</integer>
 
-    <integer name="config_key_preview_show_up_duration">35</integer>
-    <integer name="config_key_preview_dismiss_duration">40</integer>
-    <fraction name="config_key_preview_show_up_start_scale">70%</fraction>
-    <fraction name="config_key_preview_dismiss_end_scale">70%</fraction>
+    <integer name="config_key_preview_show_up_duration">0</integer>
+    <integer name="config_key_preview_dismiss_duration">70</integer>
+    <fraction name="config_key_preview_show_up_start_scale">100%</fraction>
+    <fraction name="config_key_preview_dismiss_end_scale">100%</fraction>
+    <!-- TODO: consolidate key preview linger timeout with the above animation parameters. -->
     <integer name="config_key_preview_linger_timeout">70</integer>
     <!-- Suppress showing key preview duration after batch input in millisecond -->
     <integer name="config_suppress_key_preview_after_batch_input_duration">1000</integer>
diff --git a/java/res/values/config-spacing-and-punctuations.xml b/java/res/values/config-spacing-and-punctuations.xml
index 2f52edd..1dd2e1f 100644
--- a/java/res/values/config-spacing-and-punctuations.xml
+++ b/java/res/values/config-spacing-and-punctuations.xml
@@ -21,14 +21,14 @@
     <!-- TODO: these settings depend on the language. They should be put either in the dictionary
          header, or in the subtype maybe? -->
     <!-- Symbols that are suggested between words -->
-    <string name="suggested_punctuations" translatable="false">!,?,\\,,:,;,\",(,),\',-,/,@,_</string>
+    <string name="suggested_punctuations" translatable="false">!,?,\\,,:,;,\",!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis,\',-,/,@,_</string>
     <!-- Symbols that are normally preceded by a space (used to add an auto-space before these) -->
     <string name="symbols_preceded_by_space" translatable="false">([{&amp;</string>
     <!-- Symbols that are normally followed by a space (used to add an auto-space after these) -->
     <string name="symbols_followed_by_space" translatable="false">.,;:!?)]}&amp;</string>
     <!-- Symbols that separate words -->
     <!-- Don't remove the enclosing double quotes, they protect whitespace (not just U+0020) -->
-    <string name="symbols_word_separators" translatable="false">"&#x0009;&#x0020;&#x000A;"()[]{}*&amp;&lt;&gt;+=|.,;:!?/_\"</string>
+    <string name="symbols_word_separators" translatable="false">"&#x0009;&#x0020;&#x000A;&#x00A0;"()[]{}*&amp;&lt;&gt;+=|.,;:!?/_\"</string>
     <!-- Word connectors -->
     <string name="symbols_word_connectors" translatable="false">\'-</string>
     <!-- The sentence separator code point, for capitalization -->
diff --git a/java/res/values/strings-config-important-notice.xml b/java/res/values/strings-config-important-notice.xml
index da206a3..6a9fe28 100644
--- a/java/res/values/strings-config-important-notice.xml
+++ b/java/res/values/strings-config-important-notice.xml
@@ -24,4 +24,6 @@
     <string name="important_notice_title"></string>
     <!-- The contents of the important notice. -->
     <string name="important_notice_contents"></string>
+    <!-- Description for option enabling the use by the keyboards of sent/received messages, e-mail and typing history to improve suggestion accuracy [CHAR LIMIT=68] -->
+    <string name="use_personalized_dicts_summary">Learn from your communications and typed data to improve suggestions</string>
 </resources>
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 1232bbd..ddff769 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -89,8 +89,6 @@
 
     <!-- Option name for enabling the use by the keyboards of sent/received messages, e-mail and typing history to improve suggestion accuracy [CHAR LIMIT=25] -->
     <string name="use_personalized_dicts">Personalized suggestions</string>
-    <!-- Description for option enabling the use by the keyboards of sent/received messages, e-mail and typing history to improve suggestion accuracy [CHAR LIMIT=68] -->
-    <string name="use_personalized_dicts_summary">Learn from your communications and typed data to improve suggestions</string>
 
     <!-- Option name for enabling or disabling the double-space period feature that lets double tap on spacebar insert a period followed by a space [CHAR LIMIT=30] -->
     <string name="use_double_space_period">Double-space period</string>
@@ -606,6 +604,8 @@
 
     <!-- Standard message to dismiss a dialog box -->
     <string name="cancel">Cancel</string>
+    <!-- Title of the button in a dialog box. The button takes the user to the keyboard settings. [CHAR LIMIT=15] -->
+    <string name="go_to_settings">Settings</string>
 
     <!-- Action to download and install a dictionary [CHAR_LIMIT=15] -->
     <string name="install_dict">Install</string>
diff --git a/java/res/values/themes-common.xml b/java/res/values/themes-common.xml
index fc96d19..eb6cdd9 100644
--- a/java/res/values/themes-common.xml
+++ b/java/res/values/themes-common.xml
@@ -77,6 +77,7 @@
         <item name="ignoreAltCodeKeyTimeout">@integer/config_ignore_alt_code_key_timeout</item>
         <item name="keyPreviewLayout">@layout/key_preview</item>
         <item name="keyPreviewHeight">@dimen/config_key_preview_height</item>
+        <!-- TODO: consolidate key preview linger timeout with the key preview animation parameters. -->
         <item name="keyPreviewLingerTimeout">@integer/config_key_preview_linger_timeout</item>
         <item name="moreKeysKeyboardLayout">@layout/more_keys_keyboard</item>
         <item name="showMoreKeysKeyboardAtTouchedPoint">@bool/config_show_more_keys_keyboard_at_touched_point</item>
diff --git a/java/res/xml-sw600dp/key_styles_common.xml b/java/res/xml-sw600dp/key_styles_common.xml
index 6a79c6f..aa64f85 100644
--- a/java/res/xml-sw600dp/key_styles_common.xml
+++ b/java/res/xml-sw600dp/key_styles_common.xml
@@ -161,7 +161,7 @@
         latin:parentStyle="baseForLayoutSwitchKeyStyle" />
     <key-style
         latin:styleName="comKeyStyle"
-        latin:keySpec="!text/keylabel_for_popular_domain|!text/keylabel_for_popular_domain"
+        latin:keySpec="!text/keylabel_for_popular_domain"
         latin:keyLabelFlags="autoXScale|fontNormal|hasPopupHint|preserveCase"
         latin:moreKeys="!text/more_keys_for_popular_domain" />
 </merge>
diff --git a/java/res/xml/key_styles_common.xml b/java/res/xml/key_styles_common.xml
index f04fc45..2330ecb 100644
--- a/java/res/xml/key_styles_common.xml
+++ b/java/res/xml/key_styles_common.xml
@@ -149,7 +149,7 @@
         latin:parentStyle="baseForLayoutSwitchKeyStyle" />
     <key-style
         latin:styleName="comKeyStyle"
-        latin:keySpec="!text/keylabel_for_popular_domain|!text/keylabel_for_popular_domain"
+        latin:keySpec="!text/keylabel_for_popular_domain"
         latin:keyLabelFlags="autoXScale|fontNormal|hasPopupHint|preserveCase"
         latin:moreKeys="!text/more_keys_for_popular_domain"
         latin:backgroundType="functional" />
diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml
index 5e38eb3..94327f9 100644
--- a/java/res/xml/method.xml
+++ b/java/res/xml/method.xml
@@ -55,7 +55,7 @@
     it: Italian/qwerty
     iw: Hebrew/hebrew        # "he" is official language code of Hebrew.
     ka_GE: Georgian (Georgia)/georgian
-    (kk: Kazakh/east_slavic) # disabled temporarily. waiting for string resources.
+    kk: Kazakh/east_slavic
     km_KH: Khmer (Cambodia)/khmer
     ky: Kyrgyz/east_slavic
     lo_LA: Lao (Laos)/lao
@@ -367,7 +367,6 @@
             android:imeSubtypeExtraValue="KeyboardLayoutSet=georgian,EmojiCapable"
             android:isAsciiCapable="false"
     />
-    <!--
     <subtype android:icon="@drawable/ic_ime_switcher_dark"
             android:label="@string/subtype_generic"
             android:subtypeId="0x2d73d2f6"
@@ -376,7 +375,6 @@
             android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic,EmojiCapable"
             android:isAsciiCapable="false"
     />
-    -->
     <subtype android:icon="@drawable/ic_ime_switcher_dark"
             android:label="@string/subtype_generic"
             android:subtypeId="0x1365683a"
diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index 49f0718..a39ce4a 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -175,6 +175,7 @@
                 android:fragment="com.android.inputmethod.latin.settings.AdditionalSubtypeSettings"
                 android:key="custom_input_styles"
                 android:title="@string/custom_input_styles_title" />
+            <!-- TODO: consolidate key preview dismiss delay with the key preview animation parameters. -->
             <ListPreference
                 android:key="pref_key_preview_popup_dismiss_delay"
                 android:title="@string/key_preview_popup_dismiss_delay" />
diff --git a/java/res/xml/row_pcqwerty5.xml b/java/res/xml/row_pcqwerty5.xml
index 0a3f4d2..a72f388 100644
--- a/java/res/xml/row_pcqwerty5.xml
+++ b/java/res/xml/row_pcqwerty5.xml
@@ -62,6 +62,7 @@
         </switch>
         <Key
             latin:keyStyle="defaultEnterKeyStyle"
+            latin:keySpec="!icon/enter_key|!code/key_enter"
             latin:keyWidth="15.384%p" />
         <switch>
             <case
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
index d0d5399..0043b78 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
@@ -204,19 +204,6 @@
     }
 
     /**
-     * Intercepts touch events before dispatch when touch exploration is turned on in ICS and
-     * higher.
-     *
-     * @param event The motion event being dispatched.
-     * @return {@code true} if the event is handled
-     */
-    public boolean dispatchTouchEvent(final MotionEvent event) {
-        // To avoid accidental key presses during touch exploration, always drop
-        // touch events generated by the user.
-        return false;
-    }
-
-    /**
      * Receives hover events when touch exploration is turned on in SDK versions ICS and higher.
      *
      * @param event The hover event.
diff --git a/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatUtils.java b/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatUtils.java
index b119d6c..4ea7fb8 100644
--- a/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatUtils.java
+++ b/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatUtils.java
@@ -19,7 +19,10 @@
 import android.os.Build;
 import android.view.inputmethod.InputMethodSubtype;
 
+import com.android.inputmethod.latin.Constants;
+
 import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
 
 public final class InputMethodSubtypeCompatUtils {
     private static final String TAG = InputMethodSubtypeCompatUtils.class.getSimpleName();
@@ -37,6 +40,12 @@
             }
         }
     }
+
+    // Note that {@link InputMethodSubtype#isAsciiCapable()} has been introduced in API level 19
+    // (Build.VERSION_CODE.KITKAT).
+    private static final Method METHOD_isAsciiCapable = CompatUtils.getMethod(
+            InputMethodSubtype.class, "isAsciiCapable");
+
     private InputMethodSubtypeCompatUtils() {
         // This utility class is not publicly instantiable.
     }
@@ -53,4 +62,9 @@
                 nameId, iconId, locale, mode, extraValue, isAuxiliary,
                 overridesImplicitlyEnabledSubtype, id);
     }
+
+    public static boolean isAsciiCapable(final InputMethodSubtype subtype) {
+        return (Boolean)CompatUtils.invoke(subtype, false, METHOD_isAsciiCapable)
+                || subtype.containsExtraValueKey(Constants.Subtype.ExtraValue.ASCII_CAPABLE);
+    }
 }
diff --git a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
index a32d76c..60f7e2d 100644
--- a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
+++ b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
@@ -23,7 +23,6 @@
 import android.text.TextUtils;
 import android.text.style.SuggestionSpan;
 
-import com.android.inputmethod.latin.Dictionary;
 import com.android.inputmethod.latin.LatinImeLogger;
 import com.android.inputmethod.latin.SuggestedWords;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
@@ -70,7 +69,7 @@
     public static CharSequence getTextWithSuggestionSpan(final Context context,
             final String pickedWord, final SuggestedWords suggestedWords) {
         if (TextUtils.isEmpty(pickedWord) || suggestedWords.isEmpty()
-                || suggestedWords.mIsPrediction || suggestedWords.mIsPunctuationSuggestions) {
+                || suggestedWords.mIsPrediction || suggestedWords.isPunctuationSuggestions()) {
             return pickedWord;
         }
 
diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java b/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java
index 7bbd041..d186397 100644
--- a/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java
+++ b/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java
@@ -317,15 +317,19 @@
                     final WordListPreference pref;
                     if (null != oldPreference
                             && oldPreference.mVersion == version
+                            && oldPreference.hasStatus(status)
                             && oldPreference.mLocale.equals(locale)) {
-                        // If the old preference has all the new attributes, reuse it. We test
-                        // for version and locale because although attributes other than status
-                        // need to be the same, others have been tested through the key of the
-                        // map. Also, status may differ so we don't want to use #equals() here.
+                        // If the old preference has all the new attributes, reuse it. Ideally, we
+                        // should reuse the old pref even if its status is different and call
+                        // setStatus here, but setStatus calls Preference#setSummary() which needs
+                        // to be done on the UI thread and we're not on the UI thread here. We
+                        // could do all this work on the UI thread, but in this case it's probably
+                        // lighter to stay on a background thread and throw this old preference out.
                         pref = oldPreference;
-                        pref.setStatus(status);
                     } else {
                         // Otherwise, discard it and create a new one instead.
+                        // TODO: when the status is different from the old one, we need to
+                        // animate the old one out before animating the new one in.
                         pref = new WordListPreference(activity, mDictionaryListInterfaceState,
                                 mClientId, wordlistId, version, locale, description, status,
                                 filesize);
diff --git a/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java b/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java
index ba1fce1..aea16af 100644
--- a/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java
+++ b/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java
@@ -98,6 +98,10 @@
         setSummary(getSummary(status));
     }
 
+    public boolean hasStatus(final int status) {
+        return status == mStatus;
+    }
+
     @Override
     public View onCreateView(final ViewGroup parent) {
         final View orphanedView = mInterfaceState.findFirstOrphanedView();
@@ -217,6 +221,7 @@
         progressBar.setIds(mClientId, mWordlistId);
         progressBar.setMax(mFilesize);
         final boolean showProgressBar = (MetadataDbHelper.STATUS_DOWNLOADING == mStatus);
+        setSummary(getSummary(mStatus));
         status.setVisibility(showProgressBar ? View.INVISIBLE : View.VISIBLE);
         progressBar.setVisibility(showProgressBar ? View.VISIBLE : View.INVISIBLE);
 
diff --git a/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java b/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java
index c344643..4c53b52 100644
--- a/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java
+++ b/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java
@@ -25,6 +25,7 @@
 import android.content.res.TypedArray;
 import android.graphics.Color;
 import android.graphics.Rect;
+import android.graphics.Typeface;
 import android.os.Build;
 import android.os.CountDownTimer;
 import android.preference.PreferenceManager;
@@ -34,6 +35,7 @@
 import android.util.Log;
 import android.util.Pair;
 import android.util.SparseArray;
+import android.util.TypedValue;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
@@ -84,6 +86,8 @@
     private EmojiPalettesAdapter mEmojiPalettesAdapter;
     private final EmojiLayoutParams mEmojiLayoutParams;
 
+    private TextView mAlphabetKeyLeft;
+    private TextView mAlphabetKeyRight;
     private TabHost mTabHost;
     private ViewPager mEmojiPager;
     private int mCurrentPagerPosition = 0;
@@ -487,20 +491,23 @@
         deleteKey.setTag(Constants.CODE_DELETE);
         deleteKey.setOnTouchListener(mDeleteKeyOnTouchListener);
 
-        // alphabetKey, alphabetKey2, and spaceKey depend on {@link View.OnClickListener} as well as
-        // {@link View.OnTouchListener}. {@link View.OnTouchListener} is used as the trigger of
-        // key-press, while {@link View.OnClickListener} is used as the trigger of key-release which
-        // does not occur if the event is canceled by moving off the finger from the view.
-        final ImageView alphabetKey = (ImageView)findViewById(R.id.emoji_keyboard_alphabet);
-        alphabetKey.setBackgroundResource(mEmojiFunctionalKeyBackgroundId);
-        alphabetKey.setTag(Constants.CODE_ALPHA_FROM_EMOJI);
-        alphabetKey.setOnTouchListener(this);
-        alphabetKey.setOnClickListener(this);
-        final ImageView alphabetKey2 = (ImageView)findViewById(R.id.emoji_keyboard_alphabet2);
-        alphabetKey2.setBackgroundResource(mEmojiFunctionalKeyBackgroundId);
-        alphabetKey2.setTag(Constants.CODE_ALPHA_FROM_EMOJI);
-        alphabetKey2.setOnTouchListener(this);
-        alphabetKey2.setOnClickListener(this);
+        // {@link #mAlphabetKeyLeft}, {@link #mAlphabetKeyRight, and spaceKey depend on
+        // {@link View.OnClickListener} as well as {@link View.OnTouchListener}.
+        // {@link View.OnTouchListener} is used as the trigger of key-press, while
+        // {@link View.OnClickListener} is used as the trigger of key-release which does not occur
+        // if the event is canceled by moving off the finger from the view.
+        // The text on alphabet keys are set at
+        // {@link #startEmojiPalettes(String,int,float,Typeface)}.
+        mAlphabetKeyLeft = (TextView)findViewById(R.id.emoji_keyboard_alphabet_left);
+        mAlphabetKeyLeft.setBackgroundResource(mEmojiFunctionalKeyBackgroundId);
+        mAlphabetKeyLeft.setTag(Constants.CODE_ALPHA_FROM_EMOJI);
+        mAlphabetKeyLeft.setOnTouchListener(this);
+        mAlphabetKeyLeft.setOnClickListener(this);
+        mAlphabetKeyRight = (TextView)findViewById(R.id.emoji_keyboard_alphabet_right);
+        mAlphabetKeyRight.setBackgroundResource(mEmojiFunctionalKeyBackgroundId);
+        mAlphabetKeyRight.setTag(Constants.CODE_ALPHA_FROM_EMOJI);
+        mAlphabetKeyRight.setOnTouchListener(this);
+        mAlphabetKeyRight.setOnClickListener(this);
         final ImageView spaceKey = (ImageView)findViewById(R.id.emoji_keyboard_space);
         spaceKey.setBackgroundResource(mKeyBackgroundId);
         spaceKey.setTag(Constants.CODE_SPACE);
@@ -627,10 +634,20 @@
         // TODO:
     }
 
-    public void startEmojiPalettes() {
+    // Hack: These parameters are hacky.
+    public void startEmojiPalettes(final String switchToAlphaLabel, final int switchToAlphaColor,
+            final float switchToAlphaSize, final Typeface switchToAlphaTypeface) {
         if (DEBUG_PAGER) {
             Log.d(TAG, "allocate emoji palettes memory " + mCurrentPagerPosition);
         }
+        mAlphabetKeyLeft.setText(switchToAlphaLabel);
+        mAlphabetKeyLeft.setTextColor(switchToAlphaColor);
+        mAlphabetKeyLeft.setTextSize(TypedValue.COMPLEX_UNIT_PX, switchToAlphaSize);
+        mAlphabetKeyLeft.setTypeface(switchToAlphaTypeface);
+        mAlphabetKeyRight.setText(switchToAlphaLabel);
+        mAlphabetKeyRight.setTextColor(switchToAlphaColor);
+        mAlphabetKeyRight.setTextSize(TypedValue.COMPLEX_UNIT_PX, switchToAlphaSize);
+        mAlphabetKeyRight.setTypeface(switchToAlphaTypeface);
         mEmojiPager.setAdapter(mEmojiPalettesAdapter);
         mEmojiPager.setCurrentItem(mCurrentPagerPosition);
     }
diff --git a/java/src/com/android/inputmethod/keyboard/KeyDetector.java b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
index 149f10f..282c8e8 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
@@ -18,7 +18,9 @@
 
 import com.android.inputmethod.latin.Constants;
 
-
+/**
+ * This class handles key detection.
+ */
 public class KeyDetector {
     private final int mKeyHysteresisDistanceSquared;
     private final int mKeyHysteresisDistanceForSlidingModifierSquared;
@@ -27,18 +29,12 @@
     private int mCorrectionX;
     private int mCorrectionY;
 
-    /**
-     * This class handles key detection.
-     *
-     * @param keyHysteresisDistance if the pointer movement distance is smaller than this, the
-     * movement will not be handled as meaningful movement. The unit is pixel.
-     */
-    public KeyDetector(float keyHysteresisDistance) {
-        this(keyHysteresisDistance, keyHysteresisDistance);
+    public KeyDetector() {
+        this(0.0f /* keyHysteresisDistance */, 0.0f /* keyHysteresisDistanceForSlidingModifier */);
     }
 
     /**
-     * This class handles key detection.
+     * Key detection object constructor with key hysteresis distances.
      *
      * @param keyHysteresisDistance if the pointer movement distance is smaller than this, the
      * movement will not be handled as meaningful movement. The unit is pixel.
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
index e5b814f..cde5091 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
@@ -20,7 +20,6 @@
 import static com.android.inputmethod.latin.Constants.ImeOption.NO_MICROPHONE;
 import static com.android.inputmethod.latin.Constants.ImeOption.NO_MICROPHONE_COMPAT;
 import static com.android.inputmethod.latin.Constants.ImeOption.NO_SETTINGS_KEY;
-import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.ASCII_CAPABLE;
 
 import android.content.Context;
 import android.content.res.Resources;
@@ -34,6 +33,7 @@
 import android.view.inputmethod.InputMethodSubtype;
 
 import com.android.inputmethod.compat.EditorInfoCompatUtils;
+import com.android.inputmethod.compat.InputMethodSubtypeCompatUtils;
 import com.android.inputmethod.keyboard.internal.KeyboardBuilder;
 import com.android.inputmethod.keyboard.internal.KeyboardParams;
 import com.android.inputmethod.keyboard.internal.KeysCache;
@@ -248,7 +248,7 @@
         }
 
         public Builder setSubtype(final InputMethodSubtype subtype) {
-            final boolean asciiCapable = subtype.containsExtraValueKey(ASCII_CAPABLE);
+            final boolean asciiCapable = InputMethodSubtypeCompatUtils.isAsciiCapable(subtype);
             @SuppressWarnings("deprecation")
             final boolean deprecatedForceAscii = InputAttributes.inPrivateImeOptions(
                     mPackageName, FORCE_ASCII, mParams.mEditorInfo);
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index aebba60..6215e27 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.content.res.Resources;
+import android.graphics.Paint;
 import android.preference.PreferenceManager;
 import android.util.Log;
 import android.view.ContextThemeWrapper;
@@ -30,6 +31,7 @@
 import com.android.inputmethod.compat.InputMethodServiceCompatUtils;
 import com.android.inputmethod.keyboard.KeyboardLayoutSet.KeyboardLayoutSetException;
 import com.android.inputmethod.keyboard.internal.KeyboardState;
+import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.InputView;
 import com.android.inputmethod.latin.LatinIME;
 import com.android.inputmethod.latin.LatinImeLogger;
@@ -74,13 +76,13 @@
     private MainKeyboardView mKeyboardView;
     private EmojiPalettesView mEmojiPalettesView;
     private LatinIME mLatinIME;
-    private Resources mResources;
     private boolean mIsHardwareAcceleratedDrawingEnabled;
 
     private KeyboardState mState;
 
     private KeyboardLayoutSet mKeyboardLayoutSet;
     private SettingsValues mCurrentSettingsValues;
+    private Key mSwitchToAlphaKey;
 
     /** mIsAutoCorrectionActive indicates that auto corrected word will be input instead of
      * what user actually typed. */
@@ -106,7 +108,6 @@
 
     private void initInternal(final LatinIME latinIme, final SharedPreferences prefs) {
         mLatinIME = latinIme;
-        mResources = latinIme.getResources();
         mPrefs = prefs;
         mSubtypeSwitcher = SubtypeSwitcher.getInstance();
         mState = new KeyboardState(this);
@@ -162,6 +163,8 @@
         mCurrentSettingsValues = settingsValues;
         try {
             mState.onLoadKeyboard();
+            final Keyboard symbols = mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_SYMBOLS);
+            mSwitchToAlphaKey = symbols.getKey(Constants.CODE_SWITCH_ALPHA_SYMBOL);
         } catch (KeyboardLayoutSetException e) {
             Log.w(TAG, "loading keyboard failed: " + e.mKeyboardId, e.getCause());
             LatinImeLogger.logOnException(e.mKeyboardId.toString(), e.getCause());
@@ -287,7 +290,10 @@
     @Override
     public void setEmojiKeyboard() {
         mMainKeyboardFrame.setVisibility(View.GONE);
-        mEmojiPalettesView.startEmojiPalettes();
+        final Paint paint = mKeyboardView.newLabelPaint(mSwitchToAlphaKey);
+        mEmojiPalettesView.startEmojiPalettes(
+                mSwitchToAlphaKey.getLabel(), paint.getColor(), paint.getTextSize(),
+                paint.getTypeface());
         mEmojiPalettesView.setVisibility(View.VISIBLE);
     }
 
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 422bd12..dd3ab9c 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -582,6 +582,7 @@
             paint.setTypeface(mKeyDrawParams.mTypeface);
             paint.setTextSize(mKeyDrawParams.mLabelSize);
         } else {
+            paint.setColor(key.selectTextColor(mKeyDrawParams));
             paint.setTypeface(key.selectTypeface(mKeyDrawParams));
             paint.setTextSize(key.selectTextSize(mKeyDrawParams));
         }
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index bd955ae..6c56b8a 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -726,14 +726,6 @@
     }
 
     @Override
-    public boolean dispatchTouchEvent(MotionEvent event) {
-        if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
-            return AccessibleKeyboardViewProxy.getInstance().dispatchTouchEvent(event);
-        }
-        return super.dispatchTouchEvent(event);
-    }
-
-    @Override
     public boolean onTouchEvent(final MotionEvent me) {
         if (getKeyboard() == null) {
             return false;
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java b/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java
index 81b8f04..4a80279 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java
@@ -21,7 +21,7 @@
     private final int mSlideAllowanceSquareTop;
 
     public MoreKeysDetector(float slideAllowance) {
-        super(/* keyHysteresisDistance */0);
+        super();
         mSlideAllowanceSquare = (int)(slideAllowance * slideAllowance);
         // Top slide allowance is slightly longer (sqrt(2) times) than other edges.
         mSlideAllowanceSquareTop = mSlideAllowanceSquare * 2;
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index b5d82fa..befc4e6 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -155,7 +155,7 @@
 
     // The {@link KeyDetector} is set whenever the down event is processed. Also this is updated
     // when new {@link Keyboard} is set by {@link #setKeyDetector(KeyDetector)}.
-    private KeyDetector mKeyDetector;
+    private KeyDetector mKeyDetector = new KeyDetector();
     private Keyboard mKeyboard;
     private int mPhantomSuddenMoveThreshold;
     private final BogusMoveEventDetector mBogusMoveEventDetector = new BogusMoveEventDetector();
@@ -1124,9 +1124,6 @@
 
     private boolean isMajorEnoughMoveToBeOnNewKey(final int x, final int y, final long eventTime,
             final Key newKey) {
-        if (mKeyDetector == null) {
-            throw new NullPointerException("keyboard and/or key detector not set");
-        }
         final Key curKey = mCurrentKey;
         if (newKey == curKey) {
             return false;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/EmojiPageKeyboardView.java b/java/src/com/android/inputmethod/keyboard/internal/EmojiPageKeyboardView.java
index be73965..e175a05 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/EmojiPageKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/EmojiPageKeyboardView.java
@@ -52,7 +52,7 @@
     };
 
     private OnKeyEventListener mListener = EMPTY_LISTENER;
-    private final KeyDetector mKeyDetector = new KeyDetector(0.0f /*keyHysteresisDistance */);
+    private final KeyDetector mKeyDetector = new KeyDetector();
     private final GestureDetector mGestureDetector;
 
     public EmojiPageKeyboardView(final Context context, final AttributeSet attrs) {
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
index 27e3e30..89221ba 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
@@ -85,13 +85,13 @@
         do {
             level++;
             if (level >= MAX_STRING_REFERENCE_INDIRECTION) {
-                throw new RuntimeException("too many @string/resource indirection: " + text);
+                throw new RuntimeException("Too many " + PREFIX_TEXT + "name indirection: " + text);
             }
 
             final int prefixLen = PREFIX_TEXT.length();
             final int size = text.length();
             if (size < prefixLen) {
-                return TextUtils.isEmpty(text) ? null : text;
+                break;
             }
 
             sb = null;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
index 1e021e5..93d80c9 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
@@ -43,22 +43,36 @@
 public final class KeyboardTextsTable {
     // Name to index map.
     private static final HashMap<String, Integer> sNameToIndexesMap = CollectionUtils.newHashMap();
-    // Language to texts map.
-    private static final HashMap<String, String[]> sLanguageToTextsMap =
+    // Language to texts table map.
+    private static final HashMap<String, String[]> sLanguageToTextsTableMap =
+            CollectionUtils.newHashMap();
+    // TODO: Remove this variable after debugging.
+    // Texts table to language maps.
+    private static final HashMap<String[], String> sTextsTableToLanguageMap =
             CollectionUtils.newHashMap();
 
     public static String getText(final String name, final String[] textsTable) {
         final Integer indexObj = sNameToIndexesMap.get(name);
         if (indexObj == null) {
-            throw new RuntimeException("Unknown text name: " + name);
+            throw new RuntimeException("Unknown text name=" + name + " language="
+                    + sTextsTableToLanguageMap.get(textsTable));
         }
         final int index = indexObj;
         final String text = (index < textsTable.length) ? textsTable[index] : null;
-        return (text != null) ? text : LANGUAGE_DEFAULT[index];
+        if (text != null) {
+            return text;
+        }
+        // Sanity check.
+        if (index >= 0 && index < LANGUAGE_DEFAULT.length) {
+            return LANGUAGE_DEFAULT[index];
+        }
+        // Throw exception for debugging purpose.
+        throw new RuntimeException("Illegal index=" + index + " for name=" + name
+                + " language=" + sTextsTableToLanguageMap.get(textsTable));
     }
 
     public static String[] getTextsTable(final String language) {
-        final String[] textsTable = sLanguageToTextsMap.get(language);
+        final String[] textsTable = sLanguageToTextsTableMap.get(language);
         return textsTable != null ? textsTable : LANGUAGE_DEFAULT;
     }
 
@@ -211,31 +225,30 @@
         /* 144: 0 */ "action_previous_as_more_key",
         /* 145: 0 */ "label_to_more_symbol_key",
         /* 146: 0 */ "label_to_more_symbol_for_tablet_key",
-        /* 147: 0 */ "label_tab_key",
-        /* 148: 0 */ "label_to_phone_numeric_key",
-        /* 149: 0 */ "label_to_phone_symbols_key",
-        /* 150: 0 */ "label_time_am",
-        /* 151: 0 */ "label_time_pm",
-        /* 152: 0 */ "keylabel_for_popular_domain",
-        /* 153: 0 */ "more_keys_for_popular_domain",
-        /* 154: 0 */ "keyspecs_for_left_parenthesis_more_keys",
-        /* 155: 0 */ "keyspecs_for_right_parenthesis_more_keys",
-        /* 156: 0 */ "single_laqm_raqm",
-        /* 157: 0 */ "single_raqm_laqm",
-        /* 158: 0 */ "double_laqm_raqm",
-        /* 159: 0 */ "double_raqm_laqm",
-        /* 160: 0 */ "single_lqm_rqm",
-        /* 161: 0 */ "single_9qm_lqm",
-        /* 162: 0 */ "single_9qm_rqm",
-        /* 163: 0 */ "single_rqm_9qm",
-        /* 164: 0 */ "double_lqm_rqm",
-        /* 165: 0 */ "double_9qm_lqm",
-        /* 166: 0 */ "double_9qm_rqm",
-        /* 167: 0 */ "double_rqm_9qm",
-        /* 168: 0 */ "more_keys_for_single_quote",
-        /* 169: 0 */ "more_keys_for_double_quote",
-        /* 170: 0 */ "more_keys_for_tablet_double_quote",
-        /* 171: 0 */ "emoji_key_as_more_key",
+        /* 147: 0 */ "label_to_phone_numeric_key",
+        /* 148: 0 */ "label_to_phone_symbols_key",
+        /* 149: 0 */ "label_time_am",
+        /* 150: 0 */ "label_time_pm",
+        /* 151: 0 */ "keylabel_for_popular_domain",
+        /* 152: 0 */ "more_keys_for_popular_domain",
+        /* 153: 0 */ "keyspecs_for_left_parenthesis_more_keys",
+        /* 154: 0 */ "keyspecs_for_right_parenthesis_more_keys",
+        /* 155: 0 */ "single_laqm_raqm",
+        /* 156: 0 */ "single_raqm_laqm",
+        /* 157: 0 */ "double_laqm_raqm",
+        /* 158: 0 */ "double_raqm_laqm",
+        /* 159: 0 */ "single_lqm_rqm",
+        /* 160: 0 */ "single_9qm_lqm",
+        /* 161: 0 */ "single_9qm_rqm",
+        /* 162: 0 */ "single_rqm_9qm",
+        /* 163: 0 */ "double_lqm_rqm",
+        /* 164: 0 */ "double_9qm_lqm",
+        /* 165: 0 */ "double_9qm_rqm",
+        /* 166: 0 */ "double_rqm_9qm",
+        /* 167: 0 */ "more_keys_for_single_quote",
+        /* 168: 0 */ "more_keys_for_double_quote",
+        /* 169: 0 */ "more_keys_for_tablet_double_quote",
+        /* 170: 0 */ "emoji_key_as_more_key",
     };
 
     private static final String EMPTY = "";
@@ -399,8 +412,6 @@
         /* label_to_more_symbol_key */ "= \\\\ <",
         // Label for "switch to more symbol" modifier key on tablets.  Must be short to fit on key!
         /* label_to_more_symbol_for_tablet_key */ "~ [ <",
-        // Label for "Tab" key.  Must be short to fit on key!
-        /* label_tab_key */ "Tab",
         // Label for "switch to phone numeric" key.  Must be short to fit on key!
         /* label_to_phone_numeric_key */ "123",
         // Label for "switch to phone symbols" key.  Must be short to fit on key!
@@ -3572,7 +3583,7 @@
     // Currently we are dropping the region from the key.
     private static final Object[] LANGUAGES_AND_TEXTS = {
     // "locale", TEXT_ARRAY,  /* numberOfNonNullText/lengthOf_TEXT_ARRAY localeName */
-        "DEFAULT", LANGUAGE_DEFAULT, /* 172/172 default */
+        "DEFAULT", LANGUAGE_DEFAULT, /* 171/171 default */
         "af", LANGUAGE_af,    /*   8/ 12 Afrikaans */
         "ar", LANGUAGE_ar,    /*  58/110 Arabic */
         "az", LANGUAGE_az_AZ, /*   8/ 17 Azerbaijani (Azerbaijan) */
@@ -3635,8 +3646,9 @@
 
         for (int i = 0; i < LANGUAGES_AND_TEXTS.length; i += 2) {
             final String language = (String)LANGUAGES_AND_TEXTS[i];
-            final String[] texts = (String[])LANGUAGES_AND_TEXTS[i + 1];
-            sLanguageToTextsMap.put(language, texts);
+            final String[] textsTable = (String[])LANGUAGES_AND_TEXTS[i + 1];
+            sLanguageToTextsTableMap.put(language, textsTable);
+            sTextsTableToLanguageMap.put(textsTable, language);
         }
     }
 }
diff --git a/java/src/com/android/inputmethod/latin/InputAttributes.java b/java/src/com/android/inputmethod/latin/InputAttributes.java
index b01bc4b..01c17f2 100644
--- a/java/src/com/android/inputmethod/latin/InputAttributes.java
+++ b/java/src/com/android/inputmethod/latin/InputAttributes.java
@@ -31,6 +31,7 @@
 
     final public String mTargetApplicationPackageName;
     final public boolean mInputTypeNoAutoCorrect;
+    final public boolean mIsPasswordField;
     final public boolean mIsSettingsSuggestionStripOn;
     final public boolean mApplicationSpecifiedCompletionOn;
     final public boolean mShouldInsertSpacesAutomatically;
@@ -56,6 +57,7 @@
                 Log.w(TAG, String.format("Unexpected input class: inputType=0x%08x"
                         + " imeOptions=0x%08x", inputType, editorInfo.imeOptions));
             }
+            mIsPasswordField = false;
             mIsSettingsSuggestionStripOn = false;
             mInputTypeNoAutoCorrect = false;
             mApplicationSpecifiedCompletionOn = false;
@@ -71,10 +73,11 @@
             final boolean flagAutoComplete =
                     0 != (inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE);
 
+            mIsPasswordField = InputTypeUtils.isPasswordInputType(inputType)
+                    || InputTypeUtils.isVisiblePasswordInputType(inputType);
             // TODO: Have a helper method in InputTypeUtils
             // Make sure that passwords are not displayed in {@link SuggestionStripView}.
-            if (InputTypeUtils.isPasswordInputType(inputType)
-                    || InputTypeUtils.isVisiblePasswordInputType(inputType)
+            if (mIsPasswordField
                     || InputTypeUtils.isEmailVariation(variation)
                     || InputType.TYPE_TEXT_VARIATION_URI == variation
                     || InputType.TYPE_TEXT_VARIATION_FILTER == variation
diff --git a/java/src/com/android/inputmethod/latin/InputView.java b/java/src/com/android/inputmethod/latin/InputView.java
index 76b0912..ea7859e 100644
--- a/java/src/com/android/inputmethod/latin/InputView.java
+++ b/java/src/com/android/inputmethod/latin/InputView.java
@@ -31,6 +31,7 @@
     private final Rect mInputViewRect = new Rect();
     private KeyboardTopPaddingForwarder mKeyboardTopPaddingForwarder;
     private MoreSuggestionsViewCanceler mMoreSuggestionsViewCanceler;
+    private MotionEventForwarder<?, ?> mActiveForwarder;
 
     public InputView(final Context context, final AttributeSet attrs) {
         super(context, attrs, 0);
@@ -53,42 +54,62 @@
     }
 
     @Override
-    public boolean dispatchTouchEvent(final MotionEvent me) {
+    public boolean onInterceptTouchEvent(final MotionEvent me) {
         final Rect rect = mInputViewRect;
         getGlobalVisibleRect(rect);
-        final int x = (int)me.getX() + rect.left;
-        final int y = (int)me.getY() + rect.top;
+        final int index = me.getActionIndex();
+        final int x = (int)me.getX(index) + rect.left;
+        final int y = (int)me.getY(index) + rect.top;
 
-        // The touch events that hit the top padding of keyboard should be
-        // forwarded to {@link SuggestionStripView}.
-        if (mKeyboardTopPaddingForwarder.dispatchTouchEvent(x, y, me)) {
+        // The touch events that hit the top padding of keyboard should be forwarded to
+        // {@link SuggestionStripView}.
+        if (mKeyboardTopPaddingForwarder.onInterceptTouchEvent(x, y, me)) {
+            mActiveForwarder = mKeyboardTopPaddingForwarder;
             return true;
         }
+
         // To cancel {@link MoreSuggestionsView}, we should intercept a touch event to
         // {@link MainKeyboardView} and dismiss the {@link MoreSuggestionsView}.
-        if (mMoreSuggestionsViewCanceler.dispatchTouchEvent(x, y, me)) {
+        if (mMoreSuggestionsViewCanceler.onInterceptTouchEvent(x, y, me)) {
+            mActiveForwarder = mMoreSuggestionsViewCanceler;
             return true;
         }
-        return super.dispatchTouchEvent(me);
+
+        mActiveForwarder = null;
+        return false;
+    }
+
+    @Override
+    public boolean onTouchEvent(final MotionEvent me) {
+        if (mActiveForwarder == null) {
+            return super.onTouchEvent(me);
+        }
+
+        final Rect rect = mInputViewRect;
+        getGlobalVisibleRect(rect);
+        final int index = me.getActionIndex();
+        final int x = (int)me.getX(index) + rect.left;
+        final int y = (int)me.getY(index) + rect.top;
+        return mActiveForwarder.onTouchEvent(x, y, me);
     }
 
     /**
-     * This class forwards series of {@link MotionEvent}s from <code>Forwarder</code> view to
-     * <code>Receiver</code> view.
+     * This class forwards series of {@link MotionEvent}s from <code>SenderView</code> to
+     * <code>ReceiverView</code>.
      *
-     * @param <Sender> a {@link View} that may send a {@link MotionEvent} to <Receiver>.
-     * @param <Receiver> a {@link View} that receives forwarded {@link MotionEvent} from
-     *     <Forwarder>.
+     * @param <SenderView> a {@link View} that may send a {@link MotionEvent} to <ReceiverView>.
+     * @param <ReceiverView> a {@link View} that receives forwarded {@link MotionEvent} from
+     *     <SenderView>.
      */
-    private static abstract class MotionEventForwarder<Sender extends View, Receiver extends View> {
-        protected final Sender mSenderView;
-        protected final Receiver mReceiverView;
+    private static abstract class
+            MotionEventForwarder<SenderView extends View, ReceiverView extends View> {
+        protected final SenderView mSenderView;
+        protected final ReceiverView mReceiverView;
 
-        private boolean mIsForwardingEvent;
         protected final Rect mEventSendingRect = new Rect();
         protected final Rect mEventReceivingRect = new Rect();
 
-        public MotionEventForwarder(final Sender senderView, final Receiver receiverView) {
+        public MotionEventForwarder(final SenderView senderView, final ReceiverView receiverView) {
             mSenderView = senderView;
             mReceiverView = receiverView;
         }
@@ -96,12 +117,12 @@
         // Return true if a touch event of global coordinate x, y needs to be forwarded.
         protected abstract boolean needsToForward(final int x, final int y);
 
-        // Translate global x-coordinate to <code>Receiver</code> local coordinate.
+        // Translate global x-coordinate to <code>ReceiverView</code> local coordinate.
         protected int translateX(final int x) {
             return x - mEventReceivingRect.left;
         }
 
-        // Translate global y-coordinate to <code>Receiver</code> local coordinate.
+        // Translate global y-coordinate to <code>ReceiverView</code> local coordinate.
         protected int translateY(final int y) {
             return y - mEventReceivingRect.top;
         }
@@ -109,49 +130,36 @@
         // Callback when a {@link MotionEvent} is forwarded.
         protected void onForwardingEvent(final MotionEvent me) {}
 
-        // Dispatches a {@link MotioneEvent} to <code>Receiver</code> if needed and returns true.
-        // Otherwise returns false.
-        public boolean dispatchTouchEvent(final int x, final int y, final MotionEvent me) {
-            // Forwards a {link MotionEvent} only if both <code>Sender</code> and
-            // <code>Receiver</code> are visible.
+        // Returns true if a {@link MotionEvent} is needed to be forwarded to
+        // <code>ReceiverView</code>. Otherwise returns false.
+        public boolean onInterceptTouchEvent(final int x, final int y, final MotionEvent me) {
+            // Forwards a {link MotionEvent} only if both <code>SenderView</code> and
+            // <code>ReceiverView</code> are visible.
             if (mSenderView.getVisibility() != View.VISIBLE ||
                     mReceiverView.getVisibility() != View.VISIBLE) {
                 return false;
             }
-            final Rect sendingRect = mEventSendingRect;
-            mSenderView.getGlobalVisibleRect(sendingRect);
-            if (!mIsForwardingEvent && !sendingRect.contains(x, y)) {
+            mSenderView.getGlobalVisibleRect(mEventSendingRect);
+            if (!mEventSendingRect.contains(x, y)) {
                 return false;
             }
 
-            boolean shouldForwardToReceiver = false;
-
-            switch (me.getActionMasked()) {
-            case MotionEvent.ACTION_DOWN:
-                // If the down event happens in the forwarding area, successive {@link MotionEvent}s
-                // should be forwarded.
+            if (me.getActionMasked() == MotionEvent.ACTION_DOWN) {
+                // If the down event happens in the forwarding area, successive
+                // {@link MotionEvent}s should be forwarded to <code>ReceiverView</code>.
                 if (needsToForward(x, y)) {
-                    mIsForwardingEvent = true;
-                    shouldForwardToReceiver = true;
+                    return true;
                 }
-                break;
-            case MotionEvent.ACTION_MOVE:
-                shouldForwardToReceiver = mIsForwardingEvent;
-                break;
-            case MotionEvent.ACTION_UP:
-            case MotionEvent.ACTION_CANCEL:
-                shouldForwardToReceiver = mIsForwardingEvent;
-                mIsForwardingEvent = false;
-                break;
             }
 
-            if (!shouldForwardToReceiver) {
-                return false;
-            }
+            return false;
+        }
 
-            final Rect receivingRect = mEventReceivingRect;
-            mReceiverView.getGlobalVisibleRect(receivingRect);
-            // Translate global coordinates to <code>Receiver</code> local coordinates.
+        // Returns true if a {@link MotionEvent} is forwarded to <code>ReceiverView</code>.
+        // Otherwise returns false.
+        public boolean onTouchEvent(final int x, final int y, final MotionEvent me) {
+            mReceiverView.getGlobalVisibleRect(mEventReceivingRect);
+            // Translate global coordinates to <code>ReceiverView</code> local coordinates.
             me.setLocation(translateX(x), translateY(y));
             mReceiverView.dispatchTouchEvent(me);
             onForwardingEvent(me);
@@ -189,8 +197,7 @@
         protected int translateY(final int y) {
             final int translatedY = super.translateY(y);
             if (isInKeyboardTopPadding(y)) {
-                // The forwarded event should have coordinates that are inside of
-                // the target.
+                // The forwarded event should have coordinates that are inside of the target.
                 return Math.min(translatedY, mEventReceivingRect.height() - 1);
             }
             return translatedY;
@@ -200,8 +207,8 @@
     /**
      * This class forwards {@link MotionEvent}s happened in the {@link MainKeyboardView} to
      * {@link SuggestionStripView} when the {@link MoreSuggestionsView} is showing.
-     * {@link SuggestionStripView} dismisses {@link MoreSuggestionsView} when it receives those
-     * events.
+     * {@link SuggestionStripView} dismisses {@link MoreSuggestionsView} when it receives any event
+     * outside of it.
      */
     private static class MoreSuggestionsViewCanceler
             extends MotionEventForwarder<MainKeyboardView, SuggestionStripView> {
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 7b72e80..1631a20 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1001,7 +1001,6 @@
                 applicationSuggestedWords, null /* rawSuggestions */,
                 false /* typedWordValid */,
                 false /* willAutoCorrect */,
-                false /* isPunctuationSuggestions */,
                 false /* isObsoleteSuggestions */,
                 false /* isPrediction */);
         // When in fullscreen mode, show completions generated by the application
@@ -1177,14 +1176,22 @@
             @Override
             public void onClick(final DialogInterface di, final int position) {
                 di.dismiss();
-                ImportantNoticeUtils.updateLastImportantNoticeVersion(context);
-                setNeutralSuggestionStrip();
+                if (position == DialogInterface.BUTTON_POSITIVE) {
+                    ImportantNoticeUtils.updateLastImportantNoticeVersion(context);
+                    setNeutralSuggestionStrip();
+                    return;
+                }
+                if (position == DialogInterface.BUTTON_NEGATIVE) {
+                    launchSettings();
+                    return;
+                }
             }
         };
         final AlertDialog.Builder builder =
                 new AlertDialog.Builder(context, AlertDialog.THEME_HOLO_DARK);
         builder.setMessage(R.string.important_notice_contents)
-                .setPositiveButton(android.R.string.ok, listener);
+                .setPositiveButton(android.R.string.ok, listener)
+                .setNegativeButton(R.string.go_to_settings, listener);
         showOptionDialog(builder.create(), true /* cancelable */);
     }
 
@@ -1320,10 +1327,10 @@
             return false;
         if (mSuggestionStripView.isShowingAddToDictionaryHint())
             return true;
-        if (ImportantNoticeUtils.hasNewImportantNoticeAndNotInSetupWizard(this))
-            return true;
         if (null == currentSettings)
             return false;
+        if (ImportantNoticeUtils.shouldShowImportantNotice(this, currentSettings.mInputAttributes))
+            return true;
         if (!currentSettings.isSuggestionStripVisible())
             return false;
         if (currentSettings.isApplicationSpecifiedCompletionsOn())
@@ -1352,11 +1359,13 @@
     public void setSuggestedWords(final SuggestedWords suggestedWords, final boolean shouldShow) {
         mInputLogic.setSuggestedWords(suggestedWords);
         if (mSuggestionStripView != null) {
+            final SettingsValues currentSettings = mSettings.getCurrent();
             final boolean showSuggestions;
             if (SuggestedWords.EMPTY == suggestedWords
-                    || suggestedWords.mIsPunctuationSuggestions
-                    || !mSettings.getCurrent().isSuggestionsRequested()) {
-                showSuggestions = !mSuggestionStripView.maybeShowImportantNoticeTitle();
+                    || suggestedWords.isPunctuationSuggestions()
+                    || !currentSettings.isSuggestionsRequested()) {
+                showSuggestions = !mSuggestionStripView.maybeShowImportantNoticeTitle(
+                        currentSettings.mInputAttributes);
             } else {
                 showSuggestions = true;
             }
@@ -1433,7 +1442,6 @@
             return new SuggestedWords(typedWordAndPreviousSuggestions, null /* rawSuggestions */,
                     false /* typedWordValid */,
                     false /* hasAutoCorrectionCandidate */,
-                    false /* isPunctuationSuggestions */,
                     true /* isObsoleteSuggestions */,
                     false /* isPrediction */);
         }
@@ -1614,13 +1622,6 @@
         launchSubActivity(SettingsActivity.class);
     }
 
-    public void launchKeyboardedDialogActivity(final Class<? extends Activity> activityClass) {
-        // Put the text in the attached EditText into a safe, saved state before switching to a
-        // new activity that will also use the soft keyboard.
-        mInputLogic.commitTyped(mSettings.getCurrent(), LastComposedWord.NOT_A_SEPARATOR);
-        launchSubActivity(activityClass);
-    }
-
     private void launchSubActivity(final Class<? extends Activity> activityClass) {
         Intent intent = new Intent();
         intent.setClass(LatinIME.this, activityClass);
diff --git a/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java b/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java
new file mode 100644
index 0000000..4911bcd
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java
@@ -0,0 +1,116 @@
+/*
+ * 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;
+
+import com.android.inputmethod.keyboard.internal.KeySpecParser;
+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;
+
+/**
+ * The extended {@link SuggestedWords} class to represent punctuation suggestions.
+ *
+ * Each punctuation specification string is the key specification that can be parsed by
+ * {@link KeySpecParser}.
+ */
+public final class PunctuationSuggestions extends SuggestedWords {
+    private PunctuationSuggestions(final ArrayList<SuggestedWordInfo> punctuationsList) {
+        super(punctuationsList,
+                null /* rawSuggestions */,
+                false /* typedWordValid */,
+                false /* hasAutoCorrectionCandidate */,
+                false /* isObsoleteSuggestions */,
+                false /* isPrediction */);
+    }
+
+    /**
+     * Create new instance of {@link PunctuationSuggestions} from the array of punctuation key
+     * specifications.
+     *
+     * @param punctuationSpecs The array of punctuation key specifications.
+     * @return The {@link PunctuationSuggestions} object.
+     */
+    public static PunctuationSuggestions newPunctuationSuggestions(
+            final String[] punctuationSpecs) {
+        final ArrayList<SuggestedWordInfo> puncuationsList = CollectionUtils.newArrayList();
+        for (final String puncSpec : punctuationSpecs) {
+            puncuationsList.add(newHardCodedWordInfo(puncSpec));
+        }
+        return new PunctuationSuggestions(puncuationsList);
+    }
+
+    /**
+     * {@inheritDoc}
+     * Note that {@link super#getWord(int)} returns a punctuation key specification text.
+     * The suggested punctuation should be gotten by parsing the key specification.
+     */
+    @Override
+    public String getWord(final int index) {
+        final String keySpec = super.getWord(index);
+        final int code = KeySpecParser.getCode(keySpec);
+        return (code == Constants.CODE_OUTPUT_TEXT)
+                ? KeySpecParser.getOutputText(keySpec)
+                : StringUtils.newSingleCodePointString(code);
+    }
+
+    /**
+     * {@inheritDoc}
+     * Note that {@link super#getWord(int)} returns a punctuation key specification text.
+     * The displayed text should be gotten by parsing the key specification.
+     */
+    @Override
+    public String getLabel(final int index) {
+        final String keySpec = super.getWord(index);
+        return KeySpecParser.getLabel(keySpec);
+    }
+
+    /**
+     * {@inheritDoc}
+     * Note that {@link #getWord(int)} returns a suggested punctuation. We should create a
+     * {@link SuggestedWordInfo} object that represents a hard coded word.
+     */
+    @Override
+    public SuggestedWordInfo getInfo(final int index) {
+        return newHardCodedWordInfo(getWord(index));
+    }
+
+    /**
+     * The predicator to tell whether this object represents punctuation suggestions.
+     * @return true if this object represents punctuation suggestions.
+     */
+    @Override
+    public boolean isPunctuationSuggestions() {
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "PunctuationSuggestions: "
+                + " words=" + Arrays.toString(mSuggestedWordInfoList.toArray());
+    }
+
+    private static SuggestedWordInfo newHardCodedWordInfo(final String keySpec) {
+        return new SuggestedWordInfo(keySpec, SuggestedWordInfo.MAX_SCORE,
+                SuggestedWordInfo.KIND_HARDCODED,
+                Dictionary.DICTIONARY_HARDCODED,
+                SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
+                SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */);
+    }
+}
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 5e74d75..abf831a 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -227,7 +227,6 @@
                 // rename the attribute or change the value.
                 !allowsToBeAutoCorrected /* typedWordValid */,
                 hasAutoCorrection, /* willAutoCorrect */
-                false /* isPunctuationSuggestions */,
                 false /* isObsoleteSuggestions */,
                 !wordComposer.isComposingWord() /* isPrediction */, sequenceNumber));
     }
@@ -289,7 +288,6 @@
         callback.onGetSuggestedWords(new SuggestedWords(suggestionsContainer, rawSuggestions,
                 true /* typedWordValid */,
                 false /* willAutoCorrect */,
-                false /* isPunctuationSuggestions */,
                 false /* isObsoleteSuggestions */,
                 false /* isPrediction */, sequenceNumber));
     }
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index b2efc4a..46df3e8 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -26,7 +26,7 @@
 import java.util.Arrays;
 import java.util.HashSet;
 
-public final class SuggestedWords {
+public class SuggestedWords {
     public static final int INDEX_OF_TYPED_WORD = 0;
     public static final int INDEX_OF_AUTO_CORRECTION = 1;
     public static final int NOT_A_SEQUENCE_NUMBER = -1;
@@ -37,7 +37,7 @@
     private static final ArrayList<SuggestedWordInfo> EMPTY_WORD_INFO_LIST =
             CollectionUtils.newArrayList(0);
     public static final SuggestedWords EMPTY = new SuggestedWords(
-            EMPTY_WORD_INFO_LIST, null /* rawSuggestions */, false, false, false, false, false);
+            EMPTY_WORD_INFO_LIST, null /* rawSuggestions */, false, false, false, false);
 
     public final String mTypedWord;
     public final boolean mTypedWordValid;
@@ -45,38 +45,34 @@
     // of what this flag means would be "the top suggestion is strong enough to auto-correct",
     // whether this exactly matches the user entry or not.
     public final boolean mWillAutoCorrect;
-    public final boolean mIsPunctuationSuggestions;
     public final boolean mIsObsoleteSuggestions;
     public final boolean mIsPrediction;
     public final int mSequenceNumber; // Sequence number for auto-commit.
-    private final ArrayList<SuggestedWordInfo> mSuggestedWordInfoList;
+    protected final ArrayList<SuggestedWordInfo> mSuggestedWordInfoList;
     public final ArrayList<SuggestedWordInfo> mRawSuggestions;
 
     public SuggestedWords(final ArrayList<SuggestedWordInfo> suggestedWordInfoList,
             final ArrayList<SuggestedWordInfo> rawSuggestions,
             final boolean typedWordValid,
             final boolean willAutoCorrect,
-            final boolean isPunctuationSuggestions,
             final boolean isObsoleteSuggestions,
             final boolean isPrediction) {
         this(suggestedWordInfoList, rawSuggestions, typedWordValid, willAutoCorrect,
-                isPunctuationSuggestions, isObsoleteSuggestions, isPrediction,
-                NOT_A_SEQUENCE_NUMBER);
+                isObsoleteSuggestions, isPrediction, NOT_A_SEQUENCE_NUMBER);
     }
 
     public SuggestedWords(final ArrayList<SuggestedWordInfo> suggestedWordInfoList,
             final ArrayList<SuggestedWordInfo> rawSuggestions,
             final boolean typedWordValid,
             final boolean willAutoCorrect,
-            final boolean isPunctuationSuggestions,
             final boolean isObsoleteSuggestions,
             final boolean isPrediction,
             final int sequenceNumber) {
         this(suggestedWordInfoList, rawSuggestions,
                 suggestedWordInfoList.isEmpty() ? null
                         : suggestedWordInfoList.get(INDEX_OF_TYPED_WORD).mWord,
-                typedWordValid, willAutoCorrect, isPunctuationSuggestions,
-                isObsoleteSuggestions, isPrediction, sequenceNumber);
+                typedWordValid, willAutoCorrect, isObsoleteSuggestions, isPrediction,
+                sequenceNumber);
     }
 
     public SuggestedWords(final ArrayList<SuggestedWordInfo> suggestedWordInfoList,
@@ -84,7 +80,6 @@
             final String typedWord,
             final boolean typedWordValid,
             final boolean willAutoCorrect,
-            final boolean isPunctuationSuggestions,
             final boolean isObsoleteSuggestions,
             final boolean isPrediction,
             final int sequenceNumber) {
@@ -92,7 +87,6 @@
         mRawSuggestions = rawSuggestions;
         mTypedWordValid = typedWordValid;
         mWillAutoCorrect = willAutoCorrect;
-        mIsPunctuationSuggestions = isPunctuationSuggestions;
         mIsObsoleteSuggestions = isObsoleteSuggestions;
         mIsPrediction = isPrediction;
         mSequenceNumber = sequenceNumber;
@@ -107,10 +101,32 @@
         return mSuggestedWordInfoList.size();
     }
 
+    /**
+     * Get suggested word at <code>index</code>.
+     * @param index The index of the suggested word.
+     * @return The suggested word.
+     */
     public String getWord(final int index) {
         return mSuggestedWordInfoList.get(index).mWord;
     }
 
+    /**
+     * Get displayed text at <code>index</code>.
+     * In RTL languages, the displayed text on the suggestion strip may be different from the
+     * suggested word that is returned from {@link #getWord(int)}. For example the displayed text
+     * of punctuation suggestion "(" should be ")".
+     * @param index The index of the text to display.
+     * @return The text to be displayed.
+     */
+    public String getLabel(final int index) {
+        return mSuggestedWordInfoList.get(index).mWord;
+    }
+
+    /**
+     * Get {@link SuggestedWordInfo} object at <code>index</code>.
+     * @param index The index of the {@link SuggestedWordInfo}.
+     * @return The {@link SuggestedWordInfo} object.
+     */
     public SuggestedWordInfo getInfo(final int index) {
         return mSuggestedWordInfoList.get(index);
     }
@@ -130,13 +146,20 @@
         return debugString;
     }
 
+    /**
+     * The predicator to tell whether this object represents punctuation suggestions.
+     * @return false if this object desn't represent punctuation suggestions.
+     */
+    public boolean isPunctuationSuggestions() {
+        return false;
+    }
+
     @Override
     public String toString() {
         // Pretty-print method to help debug
         return "SuggestedWords:"
                 + " mTypedWordValid=" + mTypedWordValid
                 + " mWillAutoCorrect=" + mWillAutoCorrect
-                + " mIsPunctuationSuggestions=" + mIsPunctuationSuggestions
                 + " words=" + Arrays.toString(mSuggestedWordInfoList.toArray());
     }
 
@@ -313,8 +336,8 @@
         // We should never autocorrect, so we say the typed word is valid. Also, in this case,
         // no auto-correction should take place hence willAutoCorrect = false.
         return new SuggestedWords(newSuggestions, null /* rawSuggestions */, typedWord,
-                true /* typedWordValid */, false /* willAutoCorrect */, mIsPunctuationSuggestions,
-                mIsObsoleteSuggestions, mIsPrediction, NOT_A_SEQUENCE_NUMBER);
+                true /* typedWordValid */, false /* willAutoCorrect */, mIsObsoleteSuggestions,
+                mIsPrediction, NOT_A_SEQUENCE_NUMBER);
     }
 
     // Creates a new SuggestedWordInfo from the currently suggested words that removes all but the
@@ -333,7 +356,6 @@
                     SuggestedWordInfo.NOT_A_CONFIDENCE));
         }
         return new SuggestedWords(newSuggestions, null /* rawSuggestions */, mTypedWordValid,
-                mWillAutoCorrect, mIsPunctuationSuggestions, mIsObsoleteSuggestions,
-                mIsPrediction);
+                mWillAutoCorrect, mIsObsoleteSuggestions, mIsPrediction);
     }
 }
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index bd114eb..6f73859 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -1341,8 +1341,8 @@
             final SuggestedWords suggestedWords = new SuggestedWords(suggestions,
                     null /* rawSuggestions */, typedWord,
                     true /* typedWordValid */, false /* willAutoCorrect */,
-                    false /* isPunctuationSuggestions */, false /* isObsoleteSuggestions */,
-                    false /* isPrediction */, SuggestedWords.NOT_A_SEQUENCE_NUMBER);
+                    false /* isObsoleteSuggestions */, false /* isPrediction */,
+                    SuggestedWords.NOT_A_SEQUENCE_NUMBER);
             mIsAutoCorrectionIndicatorOn = false;
             mLatinIME.mHandler.showSuggestionStrip(suggestedWords);
         }
diff --git a/java/src/com/android/inputmethod/latin/makedict/AbstractDictDecoder.java b/java/src/com/android/inputmethod/latin/makedict/AbstractDictDecoder.java
index 1bc3227..bc856f1 100644
--- a/java/src/com/android/inputmethod/latin/makedict/AbstractDictDecoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/AbstractDictDecoder.java
@@ -17,14 +17,10 @@
 package com.android.inputmethod.latin.makedict;
 
 import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding;
-import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer;
-import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.TreeMap;
 
 /**
@@ -35,34 +31,6 @@
     private static final int ERROR_CANNOT_READ = 1;
     private static final int ERROR_WRONG_FORMAT = 2;
 
-    protected DictionaryHeader readHeader(final DictBuffer headerBuffer)
-            throws IOException, UnsupportedFormatException {
-        if (headerBuffer == null) {
-            openDictBuffer();
-        }
-
-        final int version = HeaderReader.readVersion(headerBuffer);
-        if (version < FormatSpec.MINIMUM_SUPPORTED_VERSION
-                || version > FormatSpec.MAXIMUM_SUPPORTED_VERSION) {
-          throw new UnsupportedFormatException("Unsupported version : " + version);
-        }
-        // TODO: Remove this field.
-        HeaderReader.readOptionFlags(headerBuffer);
-        final int headerSize = HeaderReader.readHeaderSize(headerBuffer);
-        if (headerSize < 0) {
-            throw new UnsupportedFormatException("header size can't be negative.");
-        }
-
-        final HashMap<String, String> attributes = HeaderReader.readAttributes(headerBuffer,
-                headerSize);
-
-        final DictionaryHeader header = new DictionaryHeader(headerSize,
-                new FusionDictionary.DictionaryOptions(attributes),
-                new FormatOptions(version, DictionaryHeader.ATTRIBUTE_VALUE_TRUE.equals(
-                        attributes.get(DictionaryHeader.HAS_HISTORICAL_INFO_KEY))));
-        return header;
-    }
-
     @Override @UsedForTesting
     public int getTerminalPosition(final String word)
             throws IOException, UnsupportedFormatException {
@@ -84,38 +52,6 @@
     }
 
     /**
-     * A utility class for reading a file header.
-     */
-    protected static class HeaderReader {
-        protected static int readVersion(final DictBuffer dictBuffer)
-                throws IOException, UnsupportedFormatException {
-            return BinaryDictDecoderUtils.checkFormatVersion(dictBuffer);
-        }
-
-        protected static int readOptionFlags(final DictBuffer dictBuffer) {
-            return dictBuffer.readUnsignedShort();
-        }
-
-        protected static int readHeaderSize(final DictBuffer dictBuffer) {
-            return dictBuffer.readInt();
-        }
-
-        protected static HashMap<String, String> readAttributes(final DictBuffer dictBuffer,
-                final int headerSize) {
-            final HashMap<String, String> attributes = new HashMap<String, String>();
-            while (dictBuffer.position() < headerSize) {
-                // We can avoid an infinite loop here since dictBuffer.position() is always
-                // increased by calling CharEncoding.readString.
-                final String key = CharEncoding.readString(dictBuffer);
-                final String value = CharEncoding.readString(dictBuffer);
-                attributes.put(key, value);
-            }
-            dictBuffer.position(headerSize);
-            return attributes;
-        }
-    }
-
-    /**
      * Check whether the header contains the expected information. This is a no-error method,
      * that will return an error code and never throw a checked exception.
      * @return an error code, either ERROR_* or SUCCESS.
@@ -148,7 +84,7 @@
     }
 
     @Override
-    public PtNodeInfo readPtNode(final int ptNodePos, final FormatOptions options) {
+    public PtNodeInfo readPtNode(final int ptNodePos) {
         return null;
     }
 
@@ -165,14 +101,4 @@
     public int readPtNodeCount() {
         return 0;
     }
-
-    @Override
-    public boolean readAndFollowForwardLink() {
-        return false;
-    }
-
-    @Override
-    public boolean hasNextPtNodeArray() {
-        return false;
-    }
 }
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
index fc5788d..b534ebe 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
@@ -17,18 +17,12 @@
 package com.android.inputmethod.latin.makedict;
 
 import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
-import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
-import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
 import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
 
 import java.io.File;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.TreeMap;
 
 /**
  * Decodes binary files for a FusionDictionary.
@@ -47,8 +41,6 @@
         // This utility class is not publicly instantiable.
     }
 
-    private static final int MAX_JUMPS = 12;
-
     @UsedForTesting
     public interface DictBuffer {
         public int readUnsignedByte();
@@ -296,60 +288,21 @@
      * @param dictDecoder the dict decoder.
      * @param headerSize the size of the header.
      * @param pos the position to seek.
-     * @param formatOptions file format options.
      * @return the word with its frequency, as a weighted string.
      */
+    @UsedForTesting
     /* package for tests */ static WeightedString getWordAtPosition(final DictDecoder dictDecoder,
-            final int headerSize, final int pos, final FormatOptions formatOptions) {
+            final int headerSize, final int pos) {
         final WeightedString result;
         final int originalPos = dictDecoder.getPosition();
         dictDecoder.setPosition(pos);
-
-        if (BinaryDictIOUtils.supportsDynamicUpdate(formatOptions)) {
-            result = getWordAtPositionWithParentAddress(dictDecoder, pos, formatOptions);
-        } else {
-            result = getWordAtPositionWithoutParentAddress(dictDecoder, headerSize, pos,
-                    formatOptions);
-        }
-
+        result = getWordAtPositionWithoutParentAddress(dictDecoder, headerSize, pos);
         dictDecoder.setPosition(originalPos);
         return result;
     }
 
-    @SuppressWarnings("unused")
-    private static WeightedString getWordAtPositionWithParentAddress(final DictDecoder dictDecoder,
-            final int pos, final FormatOptions options) {
-        int currentPos = pos;
-        ProbabilityInfo probabilityInfo = null;
-        final StringBuilder builder = new StringBuilder();
-        // the length of the path from the root to the leaf is limited by MAX_WORD_LENGTH
-        for (int count = 0; count < FormatSpec.MAX_WORD_LENGTH; ++count) {
-            PtNodeInfo currentInfo;
-            int loopCounter = 0;
-            do {
-                dictDecoder.setPosition(currentPos);
-                currentInfo = dictDecoder.readPtNode(currentPos, options);
-                if (BinaryDictIOUtils.isMovedPtNode(currentInfo.mFlags, options)) {
-                    currentPos = currentInfo.mParentAddress + currentInfo.mOriginalAddress;
-                }
-                if (DBG && loopCounter++ > MAX_JUMPS) {
-                    MakedictLog.d("Too many jumps - probably a bug");
-                }
-            } while (BinaryDictIOUtils.isMovedPtNode(currentInfo.mFlags, options));
-            if (probabilityInfo == null) {
-                probabilityInfo = currentInfo.mProbabilityInfo;
-            }
-            builder.insert(0,
-                    new String(currentInfo.mCharacters, 0, currentInfo.mCharacters.length));
-            if (currentInfo.mParentAddress == FormatSpec.NO_PARENT_ADDRESS) break;
-            currentPos = currentInfo.mParentAddress + currentInfo.mOriginalAddress;
-        }
-        return new WeightedString(builder.toString(), probabilityInfo);
-    }
-
     private static WeightedString getWordAtPositionWithoutParentAddress(
-            final DictDecoder dictDecoder, final int headerSize, final int pos,
-            final FormatOptions options) {
+            final DictDecoder dictDecoder, final int headerSize, final int pos) {
         dictDecoder.setPosition(headerSize);
         final int count = dictDecoder.readPtNodeCount();
         int groupPos = dictDecoder.getPosition();
@@ -358,7 +311,7 @@
 
         PtNodeInfo last = null;
         for (int i = count - 1; i >= 0; --i) {
-            PtNodeInfo info = dictDecoder.readPtNode(groupPos, options);
+            PtNodeInfo info = dictDecoder.readPtNode(groupPos);
             groupPos = info.mEndAddress;
             if (info.mOriginalAddress == pos) {
                 builder.append(new String(info.mCharacters, 0, info.mCharacters.length));
@@ -390,159 +343,6 @@
     }
 
     /**
-     * Reads a single node array from a buffer.
-     *
-     * This methods reads the file at the current position. A node array is fully expected to start
-     * at the current position.
-     * This will recursively read other node arrays into the structure, populating the reverse
-     * maps on the fly and using them to keep track of already read nodes.
-     *
-     * @param dictDecoder the dict decoder, correctly positioned at the start of a node array.
-     * @param headerSize the size, in bytes, of the file header.
-     * @param reverseNodeArrayMap a mapping from addresses to already read node arrays.
-     * @param reversePtNodeMap a mapping from addresses to already read PtNodes.
-     * @param options file format options.
-     * @return the read node array with all his children already read.
-     */
-    private static PtNodeArray readNodeArray(final DictDecoder dictDecoder,
-            final int headerSize, final Map<Integer, PtNodeArray> reverseNodeArrayMap,
-            final Map<Integer, PtNode> reversePtNodeMap, final FormatOptions options)
-            throws IOException {
-        final ArrayList<PtNode> nodeArrayContents = new ArrayList<PtNode>();
-        final int nodeArrayOriginPos = dictDecoder.getPosition();
-
-        do { // Scan the linked-list node.
-            final int count = dictDecoder.readPtNodeCount();
-            int groupPos = dictDecoder.getPosition();
-            for (int i = count; i > 0; --i) { // Scan the array of PtNode.
-                PtNodeInfo info = dictDecoder.readPtNode(groupPos, options);
-                if (BinaryDictIOUtils.isMovedPtNode(info.mFlags, options)) continue;
-                ArrayList<WeightedString> shortcutTargets = info.mShortcutTargets;
-                ArrayList<WeightedString> bigrams = null;
-                if (null != info.mBigrams) {
-                    bigrams = new ArrayList<WeightedString>();
-                    for (PendingAttribute bigram : info.mBigrams) {
-                        final WeightedString word = getWordAtPosition(dictDecoder, headerSize,
-                                bigram.mAddress, options);
-                        final int reconstructedFrequency =
-                                BinaryDictIOUtils.reconstructBigramFrequency(word.getProbability(),
-                                        bigram.mFrequency);
-                        bigrams.add(new WeightedString(word.mWord, reconstructedFrequency));
-                    }
-                }
-                if (BinaryDictIOUtils.hasChildrenAddress(info.mChildrenAddress)) {
-                    PtNodeArray children = reverseNodeArrayMap.get(info.mChildrenAddress);
-                    if (null == children) {
-                        final int currentPosition = dictDecoder.getPosition();
-                        dictDecoder.setPosition(info.mChildrenAddress);
-                        children = readNodeArray(dictDecoder, headerSize, reverseNodeArrayMap,
-                                reversePtNodeMap, options);
-                        dictDecoder.setPosition(currentPosition);
-                    }
-                    nodeArrayContents.add(
-                            new PtNode(info.mCharacters, shortcutTargets, bigrams,
-                                    info.mProbabilityInfo,
-                                    0 != (info.mFlags & FormatSpec.FLAG_IS_NOT_A_WORD),
-                                    0 != (info.mFlags & FormatSpec.FLAG_IS_BLACKLISTED), children));
-                } else {
-                    nodeArrayContents.add(
-                            new PtNode(info.mCharacters, shortcutTargets, bigrams,
-                                    info.mProbabilityInfo,
-                                    0 != (info.mFlags & FormatSpec.FLAG_IS_NOT_A_WORD),
-                                    0 != (info.mFlags & FormatSpec.FLAG_IS_BLACKLISTED)));
-                }
-                groupPos = info.mEndAddress;
-            }
-
-            // reach the end of the array.
-            if (options.supportsDynamicUpdate()) {
-                final boolean hasValidForwardLink = dictDecoder.readAndFollowForwardLink();
-                if (!hasValidForwardLink) break;
-            }
-        } while (options.supportsDynamicUpdate() && dictDecoder.hasNextPtNodeArray());
-
-        final PtNodeArray nodeArray = new PtNodeArray(nodeArrayContents);
-        nodeArray.mCachedAddressBeforeUpdate = nodeArrayOriginPos;
-        nodeArray.mCachedAddressAfterUpdate = nodeArrayOriginPos;
-        reverseNodeArrayMap.put(nodeArray.mCachedAddressAfterUpdate, nodeArray);
-        return nodeArray;
-    }
-
-    /**
-     * Helper function to get the binary format version from the header.
-     * @throws IOException
-     */
-    private static int getFormatVersion(final DictBuffer dictBuffer)
-            throws IOException {
-        final int magic = dictBuffer.readInt();
-        if (FormatSpec.MAGIC_NUMBER == magic) return dictBuffer.readUnsignedShort();
-        return FormatSpec.NOT_A_VERSION_NUMBER;
-    }
-
-    /**
-     * Helper function to get and validate the binary format version.
-     * @throws UnsupportedFormatException
-     * @throws IOException
-     */
-    static int checkFormatVersion(final DictBuffer dictBuffer)
-            throws IOException, UnsupportedFormatException {
-        final int version = getFormatVersion(dictBuffer);
-        if (version < FormatSpec.MINIMUM_SUPPORTED_VERSION
-                || version > FormatSpec.MAXIMUM_SUPPORTED_VERSION) {
-            throw new UnsupportedFormatException("This file has version " + version
-                    + ", but this implementation does not support versions above "
-                    + FormatSpec.MAXIMUM_SUPPORTED_VERSION);
-        }
-        return version;
-    }
-
-    /**
-     * Reads a buffer and returns the memory representation of the dictionary.
-     *
-     * This high-level method takes a buffer and reads its contents, populating a
-     * FusionDictionary structure. The optional dict argument is an existing dictionary to
-     * which words from the buffer should be added. If it is null, a new dictionary is created.
-     *
-     * @param dictDecoder the dict decoder.
-     * @param dict an optional dictionary to add words to, or null.
-     * @return the created (or merged) dictionary.
-     */
-    @UsedForTesting
-    /* package */ static FusionDictionary readDictionaryBinary(final DictDecoder dictDecoder,
-            final FusionDictionary dict) throws IOException, UnsupportedFormatException {
-        // Read header
-        final DictionaryHeader fileHeader = dictDecoder.readHeader();
-
-        Map<Integer, PtNodeArray> reverseNodeArrayMapping = new TreeMap<Integer, PtNodeArray>();
-        Map<Integer, PtNode> reversePtNodeMapping = new TreeMap<Integer, PtNode>();
-        final PtNodeArray root = readNodeArray(dictDecoder, fileHeader.mBodyOffset,
-                reverseNodeArrayMapping, reversePtNodeMapping, fileHeader.mFormatOptions);
-
-        FusionDictionary newDict = new FusionDictionary(root, fileHeader.mDictionaryOptions);
-        if (null != dict) {
-            for (final WordProperty wordProperty : dict) {
-                if (wordProperty.mIsBlacklistEntry) {
-                    newDict.addBlacklistEntry(wordProperty.mWord, wordProperty.mShortcutTargets,
-                            wordProperty.mIsNotAWord);
-                } else {
-                    newDict.add(wordProperty.mWord, wordProperty.mProbabilityInfo,
-                            wordProperty.mShortcutTargets, wordProperty.mIsNotAWord);
-                }
-            }
-            for (final WordProperty wordProperty : dict) {
-                // By construction a binary dictionary may not have bigrams pointing to
-                // words that are not also registered as unigrams so we don't have to avoid
-                // them explicitly here.
-                for (final WeightedString bigram : wordProperty.mBigrams) {
-                    newDict.setBigram(wordProperty.mWord, bigram.mWord, bigram.mProbabilityInfo);
-                }
-            }
-        }
-
-        return newDict;
-    }
-
-    /**
      * Helper method to pass a file name instead of a File object to isBinaryDictionary.
      */
     public static boolean isBinaryDictionary(final String filename) {
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
index 9c5d1b9..1593dea 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
@@ -122,18 +122,13 @@
      * Compute the maximum size of a PtNode, assuming 3-byte addresses for everything.
      *
      * @param ptNode the PtNode to compute the size of.
-     * @param options file format options.
      * @return the maximum size of the PtNode.
      */
-    private static int getPtNodeMaximumSize(final PtNode ptNode, final FormatOptions options) {
-        int size = getNodeHeaderSize(ptNode, options);
+    private static int getPtNodeMaximumSize(final PtNode ptNode) {
+        int size = getNodeHeaderSize(ptNode);
         if (ptNode.isTerminal()) {
-            // If terminal, one byte for the frequency or four bytes for the terminal id.
-            if (options.mHasTerminalId) {
-                size += FormatSpec.PTNODE_TERMINAL_ID_SIZE;
-            } else {
-                size += FormatSpec.PTNODE_FREQUENCY_SIZE;
-            }
+            // If terminal, one byte for the frequency.
+            size += FormatSpec.PTNODE_FREQUENCY_SIZE;
         }
         size += FormatSpec.PTNODE_MAX_ADDRESS_SIZE; // For children address
         size += getShortcutListSize(ptNode.mShortcutTargets);
@@ -151,19 +146,14 @@
      * the containing node array, and cache it it its 'mCachedSize' member.
      *
      * @param ptNodeArray the node array to compute the maximum size of.
-     * @param options file format options.
      */
-    private static void calculatePtNodeArrayMaximumSize(final PtNodeArray ptNodeArray,
-            final FormatOptions options) {
+    private static void calculatePtNodeArrayMaximumSize(final PtNodeArray ptNodeArray) {
         int size = getPtNodeCountSize(ptNodeArray);
         for (PtNode node : ptNodeArray.mData) {
-            final int nodeSize = getPtNodeMaximumSize(node, options);
+            final int nodeSize = getPtNodeMaximumSize(node);
             node.mCachedSize = nodeSize;
             size += nodeSize;
         }
-        if (options.supportsDynamicUpdate()) {
-            size += FormatSpec.FORWARD_LINK_ADDRESS_SIZE;
-        }
         ptNodeArray.mCachedSize = size;
     }
 
@@ -171,15 +161,9 @@
      * Compute the size of the header (flag + [parent address] + characters size) of a PtNode.
      *
      * @param ptNode the PtNode of which to compute the size of the header
-     * @param options file format options.
      */
-    private static int getNodeHeaderSize(final PtNode ptNode, final FormatOptions options) {
-        if (BinaryDictIOUtils.supportsDynamicUpdate(options)) {
-            return FormatSpec.PTNODE_FLAGS_SIZE + FormatSpec.PARENT_ADDRESS_SIZE
-                    + getPtNodeCharactersSize(ptNode);
-        } else {
-            return FormatSpec.PTNODE_FLAGS_SIZE + getPtNodeCharactersSize(ptNode);
-        }
+    private static int getNodeHeaderSize(final PtNode ptNode) {
+        return FormatSpec.PTNODE_FLAGS_SIZE + getPtNodeCharactersSize(ptNode);
     }
 
     /**
@@ -379,11 +363,10 @@
      *
      * @param ptNodeArray the node array to compute the size of.
      * @param dict the dictionary in which the word/attributes are to be found.
-     * @param formatOptions file format options.
      * @return false if none of the cached addresses inside the node array changed, true otherwise.
      */
     private static boolean computeActualPtNodeArraySize(final PtNodeArray ptNodeArray,
-            final FusionDictionary dict, final FormatOptions formatOptions) {
+            final FusionDictionary dict) {
         boolean changed = false;
         int size = getPtNodeCountSize(ptNodeArray);
         for (PtNode ptNode : ptNodeArray.mData) {
@@ -391,37 +374,26 @@
             if (ptNode.mCachedAddressAfterUpdate != ptNode.mCachedAddressBeforeUpdate) {
                 changed = true;
             }
-            int nodeSize = getNodeHeaderSize(ptNode, formatOptions);
+            int nodeSize = getNodeHeaderSize(ptNode);
             if (ptNode.isTerminal()) {
-                if (formatOptions.mHasTerminalId) {
-                    nodeSize += FormatSpec.PTNODE_TERMINAL_ID_SIZE;
-                } else {
-                    nodeSize += FormatSpec.PTNODE_FREQUENCY_SIZE;
-                }
+                nodeSize += FormatSpec.PTNODE_FREQUENCY_SIZE;
             }
-            if (formatOptions.supportsDynamicUpdate()) {
-                nodeSize += FormatSpec.SIGNED_CHILDREN_ADDRESS_SIZE;
-            } else if (null != ptNode.mChildren) {
+            if (null != ptNode.mChildren) {
                 nodeSize += getByteSize(getOffsetToTargetNodeArrayDuringUpdate(ptNodeArray,
                         nodeSize + size, ptNode.mChildren));
             }
-            if (formatOptions.mVersion < FormatSpec.FIRST_VERSION_WITH_TERMINAL_ID) {
-                nodeSize += getShortcutListSize(ptNode.mShortcutTargets);
-                if (null != ptNode.mBigrams) {
-                    for (WeightedString bigram : ptNode.mBigrams) {
-                        final int offset = getOffsetToTargetPtNodeDuringUpdate(ptNodeArray,
-                                nodeSize + size + FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE,
-                                FusionDictionary.findWordInTree(dict.mRootNodeArray, bigram.mWord));
-                        nodeSize += getByteSize(offset) + FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE;
-                    }
+            nodeSize += getShortcutListSize(ptNode.mShortcutTargets);
+            if (null != ptNode.mBigrams) {
+                for (WeightedString bigram : ptNode.mBigrams) {
+                    final int offset = getOffsetToTargetPtNodeDuringUpdate(ptNodeArray,
+                            nodeSize + size + FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE,
+                            FusionDictionary.findWordInTree(dict.mRootNodeArray, bigram.mWord));
+                    nodeSize += getByteSize(offset) + FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE;
                 }
             }
             ptNode.mCachedSize = nodeSize;
             size += nodeSize;
         }
-        if (formatOptions.supportsDynamicUpdate()) {
-            size += FormatSpec.FORWARD_LINK_ADDRESS_SIZE;
-        }
         if (ptNodeArray.mCachedSize != size) {
             ptNodeArray.mCachedSize = size;
             changed = true;
@@ -433,11 +405,10 @@
      * Initializes the cached addresses of node arrays and their containing nodes from their size.
      *
      * @param flatNodes the list of node arrays.
-     * @param formatOptions file format options.
      * @return the byte size of the entire stack.
      */
-    private static int initializePtNodeArraysCachedAddresses(final ArrayList<PtNodeArray> flatNodes,
-            final FormatOptions formatOptions) {
+    private static int initializePtNodeArraysCachedAddresses(
+            final ArrayList<PtNodeArray> flatNodes) {
         int nodeArrayOffset = 0;
         for (final PtNodeArray nodeArray : flatNodes) {
             nodeArray.mCachedAddressBeforeUpdate = nodeArrayOffset;
@@ -468,28 +439,6 @@
     }
 
     /**
-     * Compute the cached parent addresses after all has been updated.
-     *
-     * The parent addresses are used by some binary formats at write-to-disk time. Not all formats
-     * need them. In particular, version 2 does not need them, and version 3 does.
-     *
-     * @param flatNodes the flat array of node arrays to fill in
-     */
-    private static void computeParentAddresses(final ArrayList<PtNodeArray> flatNodes) {
-        for (final PtNodeArray nodeArray : flatNodes) {
-            for (final PtNode ptNode : nodeArray.mData) {
-                if (null != ptNode.mChildren) {
-                    // Assign my address to children's parent address
-                    // Here BeforeUpdate and AfterUpdate addresses have the same value, so it
-                    // does not matter which we use.
-                    ptNode.mChildren.mCachedParentAddress = ptNode.mCachedAddressAfterUpdate
-                            - ptNode.mChildren.mCachedAddressAfterUpdate;
-                }
-            }
-        }
-    }
-
-    /**
      * Compute the addresses and sizes of an ordered list of PtNode arrays.
      *
      * This method takes a list of PtNode arrays and will update their cached address and size
@@ -501,14 +450,15 @@
      *
      * @param dict the dictionary
      * @param flatNodes the ordered list of PtNode arrays
-     * @param formatOptions file format options.
      * @return the same array it was passed. The nodes have been updated for address and size.
      */
     /* package */ static ArrayList<PtNodeArray> computeAddresses(final FusionDictionary dict,
-            final ArrayList<PtNodeArray> flatNodes, final FormatOptions formatOptions) {
+            final ArrayList<PtNodeArray> flatNodes) {
         // First get the worst possible sizes and offsets
-        for (final PtNodeArray n : flatNodes) calculatePtNodeArrayMaximumSize(n, formatOptions);
-        final int offset = initializePtNodeArraysCachedAddresses(flatNodes, formatOptions);
+        for (final PtNodeArray n : flatNodes) {
+            calculatePtNodeArrayMaximumSize(n);
+        }
+        final int offset = initializePtNodeArraysCachedAddresses(flatNodes);
 
         MakedictLog.i("Compressing the array addresses. Original size : " + offset);
         MakedictLog.i("(Recursively seen size : " + offset + ")");
@@ -521,8 +471,7 @@
             for (final PtNodeArray ptNodeArray : flatNodes) {
                 ptNodeArray.mCachedAddressAfterUpdate = ptNodeArrayStartOffset;
                 final int oldNodeArraySize = ptNodeArray.mCachedSize;
-                final boolean changed =
-                        computeActualPtNodeArraySize(ptNodeArray, dict, formatOptions);
+                final boolean changed = computeActualPtNodeArraySize(ptNodeArray, dict);
                 final int newNodeArraySize = ptNodeArray.mCachedSize;
                 if (oldNodeArraySize < newNodeArraySize) {
                     throw new RuntimeException("Increased size ?!");
@@ -535,9 +484,6 @@
             if (passes > MAX_PASSES) throw new RuntimeException("Too many passes - probably a bug");
         } while (changesDone);
 
-        if (formatOptions.supportsDynamicUpdate()) {
-            computeParentAddresses(flatNodes);
-        }
         final PtNodeArray lastPtNodeArray = flatNodes.get(flatNodes.size() - 1);
         MakedictLog.i("Compression complete in " + passes + " passes.");
         MakedictLog.i("After address compression : "
@@ -634,35 +580,29 @@
      * @param hasBigrams whether the PtNode has bigrams.
      * @param isNotAWord whether the PtNode is not a word.
      * @param isBlackListEntry whether the PtNode is a blacklist entry.
-     * @param formatOptions file format options.
      * @return the flags
      */
     static int makePtNodeFlags(final boolean hasMultipleChars, final boolean isTerminal,
             final int childrenAddressSize, final boolean hasShortcuts, final boolean hasBigrams,
-            final boolean isNotAWord, final boolean isBlackListEntry,
-            final FormatOptions formatOptions) {
+            final boolean isNotAWord, final boolean isBlackListEntry) {
         byte flags = 0;
         if (hasMultipleChars) flags |= FormatSpec.FLAG_HAS_MULTIPLE_CHARS;
         if (isTerminal) flags |= FormatSpec.FLAG_IS_TERMINAL;
-        if (formatOptions.supportsDynamicUpdate()) {
-            flags |= FormatSpec.FLAG_IS_NOT_MOVED;
-        } else if (true) {
-            switch (childrenAddressSize) {
-                case 1:
-                    flags |= FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_ONEBYTE;
-                    break;
-                case 2:
-                    flags |= FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_TWOBYTES;
-                    break;
-                case 3:
-                    flags |= FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_THREEBYTES;
-                    break;
-                case 0:
-                    flags |= FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_NOADDRESS;
-                    break;
-                default:
-                    throw new RuntimeException("Node with a strange address");
-            }
+        switch (childrenAddressSize) {
+            case 1:
+                flags |= FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_ONEBYTE;
+                break;
+            case 2:
+                flags |= FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_TWOBYTES;
+                break;
+            case 3:
+                flags |= FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_THREEBYTES;
+                break;
+            case 0:
+                flags |= FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_NOADDRESS;
+                break;
+            default:
+                throw new RuntimeException("Node with a strange address");
         }
         if (hasShortcuts) flags |= FormatSpec.FLAG_HAS_SHORTCUT_TARGETS;
         if (hasBigrams) flags |= FormatSpec.FLAG_HAS_BIGRAMS;
@@ -671,12 +611,12 @@
         return flags;
     }
 
-    /* package */ static byte makePtNodeFlags(final PtNode node, final int childrenOffset,
-            final FormatOptions formatOptions) {
+    /* package */ static byte makePtNodeFlags(final PtNode node, final int childrenOffset) {
         return (byte) makePtNodeFlags(node.mChars.length > 1, node.isTerminal(),
                 getByteSize(childrenOffset),
                 node.mShortcutTargets != null && !node.mShortcutTargets.isEmpty(),
-                node.mBigrams != null, node.mIsNotAWord, node.mIsBlacklistEntry, formatOptions);
+                node.mBigrams != null && !node.mBigrams.isEmpty(),
+                node.mIsNotAWord, node.mIsBlacklistEntry);
     }
 
     /**
@@ -767,38 +707,14 @@
                 + (frequency & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY);
     }
 
-    /* package */ static final int writeParentAddress(final byte[] buffer, final int index,
-            final int address, final FormatOptions formatOptions) {
-        if (BinaryDictIOUtils.supportsDynamicUpdate(formatOptions)) {
-            if (address == FormatSpec.NO_PARENT_ADDRESS) {
-                buffer[index] = buffer[index + 1] = buffer[index + 2] = 0;
-            } else {
-                final int absAddress = Math.abs(address);
-                assert(absAddress <= FormatSpec.SINT24_MAX);
-                buffer[index] = (byte)((address < 0 ? FormatSpec.MSB8 : 0)
-                        | ((absAddress >> 16) & 0xFF));
-                buffer[index + 1] = (byte)((absAddress >> 8) & 0xFF);
-                buffer[index + 2] = (byte)(absAddress & 0xFF);
-            }
-            return index + 3;
-        } else {
-            return index;
-        }
-    }
-
-    /* package */ static final int getChildrenPosition(final PtNode ptNode,
-            final FormatOptions formatOptions) {
+    /* package */ static final int getChildrenPosition(final PtNode ptNode) {
         int positionOfChildrenPosField = ptNode.mCachedAddressAfterUpdate
-                + getNodeHeaderSize(ptNode, formatOptions);
+                + getNodeHeaderSize(ptNode);
         if (ptNode.isTerminal()) {
-            // A terminal node has either the terminal id or the frequency.
+            // A terminal node has the frequency.
             // If positionOfChildrenPosField is incorrect, we may crash when jumping to the children
             // position.
-            if (formatOptions.mHasTerminalId) {
-                positionOfChildrenPosField += FormatSpec.PTNODE_TERMINAL_ID_SIZE;
-            } else {
-                positionOfChildrenPosField += FormatSpec.PTNODE_FREQUENCY_SIZE;
-            }
+            positionOfChildrenPosField += FormatSpec.PTNODE_FREQUENCY_SIZE;
         }
         return null == ptNode.mChildren ? FormatSpec.NO_CHILDREN_ADDRESS
                 : ptNode.mChildren.mCachedAddressAfterUpdate - positionOfChildrenPosField;
@@ -810,12 +726,10 @@
      * @param dict the dictionary the node array is a part of (for relative offsets).
      * @param dictEncoder the dictionary encoder.
      * @param ptNodeArray the node array to write.
-     * @param formatOptions file format options.
      */
     @SuppressWarnings("unused")
     /* package */ static void writePlacedPtNodeArray(final FusionDictionary dict,
-            final DictEncoder dictEncoder, final PtNodeArray ptNodeArray,
-            final FormatOptions formatOptions) {
+            final DictEncoder dictEncoder, final PtNodeArray ptNodeArray) {
         // TODO: Make the code in common with BinaryDictIOUtils#writePtNode
         dictEncoder.setPosition(ptNodeArray.mCachedAddressAfterUpdate);
 
@@ -838,10 +752,7 @@
                         + FormatSpec.MAX_TERMINAL_FREQUENCY
                         + " : " + ptNode.mProbabilityInfo.toString());
             }
-            dictEncoder.writePtNode(ptNode, parentPosition, formatOptions, dict);
-        }
-        if (formatOptions.supportsDynamicUpdate()) {
-            dictEncoder.writeForwardLinkAddress(FormatSpec.NO_FORWARD_LINK_ADDRESS);
+            dictEncoder.writePtNode(ptNode, dict);
         }
         if (dictEncoder.getPosition() != ptNodeArray.mCachedAddressAfterUpdate
                 + ptNodeArray.mCachedSize) {
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index 54446df..989ca4b 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -18,7 +18,6 @@
 
 import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding;
 import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer;
 import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
 import com.android.inputmethod.latin.utils.ByteArrayDictBuffer;
@@ -60,8 +59,7 @@
     private static void readUnigramsAndBigramsBinaryInner(final DictDecoder dictDecoder,
             final int bodyOffset, final Map<Integer, String> words,
             final Map<Integer, Integer> frequencies,
-            final Map<Integer, ArrayList<PendingAttribute>> bigrams,
-            final FormatOptions formatOptions) {
+            final Map<Integer, ArrayList<PendingAttribute>> bigrams) {
         int[] pushedChars = new int[FormatSpec.MAX_WORD_LENGTH + 1];
 
         Stack<Position> stack = new Stack<Position>();
@@ -90,17 +88,12 @@
                 stack.pop();
                 continue;
             }
-            final PtNodeInfo ptNodeInfo = dictDecoder.readPtNode(p.mAddress, formatOptions);
+            final PtNodeInfo ptNodeInfo = dictDecoder.readPtNode(p.mAddress);
             for (int i = 0; i < ptNodeInfo.mCharacters.length; ++i) {
                 pushedChars[index++] = ptNodeInfo.mCharacters[i];
             }
             p.mPosition++;
-
-            final boolean isMovedPtNode = isMovedPtNode(ptNodeInfo.mFlags,
-                    formatOptions);
-            final boolean isDeletedPtNode = isDeletedPtNode(ptNodeInfo.mFlags,
-                    formatOptions);
-            if (!isMovedPtNode && !isDeletedPtNode && ptNodeInfo.isTerminal()) {// found word
+            if (ptNodeInfo.isTerminal()) {// found word
                 words.put(ptNodeInfo.mOriginalAddress, new String(pushedChars, 0, index));
                 frequencies.put(
                         ptNodeInfo.mOriginalAddress, ptNodeInfo.mProbabilityInfo.mProbability);
@@ -110,25 +103,13 @@
             }
 
             if (p.mPosition == p.mNumOfPtNode) {
-                if (formatOptions.supportsDynamicUpdate()) {
-                    final boolean hasValidForwardLinkAddress =
-                            dictDecoder.readAndFollowForwardLink();
-                    if (hasValidForwardLinkAddress && dictDecoder.hasNextPtNodeArray()) {
-                        // The node array has a forward link.
-                        p.mNumOfPtNode = Position.NOT_READ_PTNODE_COUNT;
-                        p.mAddress = dictDecoder.getPosition();
-                    } else {
-                        stack.pop();
-                    }
-                } else {
-                    stack.pop();
-                }
+                stack.pop();
             } else {
-                // The Ptnode array has more PtNodes.
+                // The PtNode array has more PtNodes.
                 p.mAddress = dictDecoder.getPosition();
             }
 
-            if (!isMovedPtNode && hasChildrenAddress(ptNodeInfo.mChildrenAddress)) {
+            if (hasChildrenAddress(ptNodeInfo.mChildrenAddress)) {
                 final Position childrenPos = new Position(ptNodeInfo.mChildrenAddress, index);
                 stack.push(childrenPos);
             }
@@ -153,7 +134,7 @@
         // Read header
         final DictionaryHeader header = dictDecoder.readHeader();
         readUnigramsAndBigramsBinaryInner(dictDecoder, header.mBodyOffset, words,
-                frequencies, bigrams, header.mFormatOptions);
+            frequencies, bigrams);
     }
 
     /**
@@ -171,8 +152,7 @@
             final String word) throws IOException, UnsupportedFormatException {
         if (word == null) return FormatSpec.NOT_VALID_WORD;
         dictDecoder.setPosition(0);
-
-        final DictionaryHeader header = dictDecoder.readHeader();
+        dictDecoder.readHeader();
         int wordPos = 0;
         final int wordLen = word.codePointCount(0, word.length());
         for (int depth = 0; depth < Constants.DICTIONARY_MAX_WORD_LENGTH; ++depth) {
@@ -183,13 +163,7 @@
                 boolean foundNextPtNode = false;
                 for (int i = 0; i < ptNodeCount; ++i) {
                     final int ptNodePos = dictDecoder.getPosition();
-                    final PtNodeInfo currentInfo = dictDecoder.readPtNode(ptNodePos,
-                            header.mFormatOptions);
-                    final boolean isMovedNode = isMovedPtNode(currentInfo.mFlags,
-                            header.mFormatOptions);
-                    final boolean isDeletedNode = isDeletedPtNode(currentInfo.mFlags,
-                            header.mFormatOptions);
-                    if (isMovedNode) continue;
+                    final PtNodeInfo currentInfo = dictDecoder.readPtNode(ptNodePos);
                     boolean same = true;
                     for (int p = 0, j = word.offsetByCodePoints(0, wordPos);
                             p < currentInfo.mCharacters.length;
@@ -204,7 +178,7 @@
                     if (same) {
                         // found the PtNode matches the word.
                         if (wordPos + currentInfo.mCharacters.length == wordLen) {
-                            if (!currentInfo.isTerminal() || isDeletedNode) {
+                            if (!currentInfo.isTerminal()) {
                                 return FormatSpec.NOT_VALID_WORD;
                             } else {
                                 return ptNodePos;
@@ -219,65 +193,14 @@
                         break;
                     }
                 }
-
-                // If we found the next PtNode, it is under the file pointer.
-                // But if not, we are at the end of this node array so we expect to have
-                // a forward link address that we need to consult and possibly resume
-                // search on the next node array in the linked list.
                 if (foundNextPtNode) break;
-                if (!header.mFormatOptions.supportsDynamicUpdate()) {
-                    return FormatSpec.NOT_VALID_WORD;
-                }
-
-                final boolean hasValidForwardLinkAddress =
-                        dictDecoder.readAndFollowForwardLink();
-                if (!hasValidForwardLinkAddress || !dictDecoder.hasNextPtNodeArray()) {
-                    return FormatSpec.NOT_VALID_WORD;
-                }
+                return FormatSpec.NOT_VALID_WORD;
             } while(true);
         }
         return FormatSpec.NOT_VALID_WORD;
     }
 
     /**
-     * @return the size written, in bytes. Always 3 bytes.
-     */
-    @UsedForTesting
-    static int writeSInt24ToBuffer(final DictBuffer dictBuffer, final int value) {
-        final int absValue = Math.abs(value);
-        dictBuffer.put((byte)(((value < 0 ? 0x80 : 0) | (absValue >> 16)) & 0xFF));
-        dictBuffer.put((byte)((absValue >> 8) & 0xFF));
-        dictBuffer.put((byte)(absValue & 0xFF));
-        return 3;
-    }
-
-    /**
-     * @return the size written, in bytes. Always 3 bytes.
-     */
-    @UsedForTesting
-    static int writeSInt24ToStream(final OutputStream destination, final int value)
-            throws IOException {
-        final int absValue = Math.abs(value);
-        destination.write((byte)(((value < 0 ? 0x80 : 0) | (absValue >> 16)) & 0xFF));
-        destination.write((byte)((absValue >> 8) & 0xFF));
-        destination.write((byte)(absValue & 0xFF));
-        return 3;
-    }
-
-    @UsedForTesting
-    static void skipString(final DictBuffer dictBuffer,
-            final boolean hasMultipleChars) {
-        if (hasMultipleChars) {
-            int character = CharEncoding.readChar(dictBuffer);
-            while (character != FormatSpec.INVALID_CHARACTER) {
-                character = CharEncoding.readChar(dictBuffer);
-            }
-        } else {
-            CharEncoding.readChar(dictBuffer);
-        }
-    }
-
-    /**
      * Writes a PtNodeCount to the stream.
      *
      * @param destination the stream to write.
@@ -356,30 +279,6 @@
     }
 
     /**
-     * Helper method to check whether the node is moved.
-     */
-    public static boolean isMovedPtNode(final int flags, final FormatOptions options) {
-        return options.supportsDynamicUpdate()
-                && ((flags & FormatSpec.MASK_CHILDREN_ADDRESS_TYPE) == FormatSpec.FLAG_IS_MOVED);
-    }
-
-    /**
-     * Helper method to check whether the dictionary can be updated dynamically.
-     */
-    public static boolean supportsDynamicUpdate(final FormatOptions options) {
-        return options.mVersion >= FormatSpec.FIRST_VERSION_WITH_DYNAMIC_UPDATE
-                && options.supportsDynamicUpdate();
-    }
-
-    /**
-     * Helper method to check whether the node is deleted.
-     */
-    public static boolean isDeletedPtNode(final int flags, final FormatOptions formatOptions) {
-        return formatOptions.supportsDynamicUpdate()
-                && ((flags & FormatSpec.MASK_CHILDREN_ADDRESS_TYPE) == FormatSpec.FLAG_IS_DELETED);
-    }
-
-    /**
      * Compute the binary size of the node count
      * @param count the node count
      * @return the size of the node count, either 1 or 2 bytes.
@@ -396,9 +295,7 @@
         }
     }
 
-    static int getChildrenAddressSize(final int optionFlags,
-            final FormatOptions formatOptions) {
-        if (formatOptions.supportsDynamicUpdate()) return FormatSpec.SIGNED_CHILDREN_ADDRESS_SIZE;
+    static int getChildrenAddressSize(final int optionFlags) {
         switch (optionFlags & FormatSpec.MASK_CHILDREN_ADDRESS_TYPE) {
             case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_ONEBYTE:
                 return 1;
@@ -419,6 +316,7 @@
      * @param bigramFrequency compressed frequency
      * @return approximate bigram frequency
      */
+    @UsedForTesting
     public static int reconstructBigramFrequency(final int unigramFrequency,
             final int bigramFrequency) {
         final float stepSize = (FormatSpec.MAX_TERMINAL_FREQUENCY - unigramFrequency)
diff --git a/java/src/com/android/inputmethod/latin/makedict/DictDecoder.java b/java/src/com/android/inputmethod/latin/makedict/DictDecoder.java
index a93a8bb..a3b28a7 100644
--- a/java/src/com/android/inputmethod/latin/makedict/DictDecoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/DictDecoder.java
@@ -18,7 +18,6 @@
 
 import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer;
-import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
 import com.android.inputmethod.latin.utils.ByteArrayDictBuffer;
 
 import java.io.File;
@@ -45,27 +44,23 @@
     /**
      * Reads PtNode from ptNodePos.
      * @param ptNodePos the position of PtNode.
-     * @param formatOptions the format options.
      * @return PtNodeInfo.
      */
-    public PtNodeInfo readPtNode(final int ptNodePos, final FormatOptions formatOptions);
+    public PtNodeInfo readPtNode(final int ptNodePos);
 
     /**
      * Reads a buffer and returns the memory representation of the dictionary.
      *
      * This high-level method takes a buffer and reads its contents, populating a
-     * FusionDictionary structure. The optional dict argument is an existing dictionary to
-     * which words from the buffer should be added. If it is null, a new dictionary is created.
+     * FusionDictionary structure.
      *
-     * @param dict an optional dictionary to add words to, or null.
      * @param deleteDictIfBroken a flag indicating whether this method should remove the broken
      * dictionary or not.
-     * @return the created (or merged) dictionary.
+     * @return the created dictionary.
      */
     @UsedForTesting
-    public FusionDictionary readDictionaryBinary(final FusionDictionary dict,
-            final boolean deleteDictIfBroken)
-                    throws FileNotFoundException, IOException, UnsupportedFormatException;
+    public FusionDictionary readDictionaryBinary(final boolean deleteDictIfBroken)
+            throws FileNotFoundException, IOException, UnsupportedFormatException;
 
     /**
      * Gets the address of the last PtNode of the exact matching word in the dictionary.
@@ -116,14 +111,6 @@
     public int readPtNodeCount();
 
     /**
-     * Reads the forward link and advances the position.
-     *
-     * @return true if this method moves the file pointer, false otherwise.
-     */
-    public boolean readAndFollowForwardLink();
-    public boolean hasNextPtNodeArray();
-
-    /**
      * Opens the dictionary file and makes DictBuffer.
      */
     @UsedForTesting
diff --git a/java/src/com/android/inputmethod/latin/makedict/DictEncoder.java b/java/src/com/android/inputmethod/latin/makedict/DictEncoder.java
index ea5d492..a5dc456 100644
--- a/java/src/com/android/inputmethod/latin/makedict/DictEncoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/DictEncoder.java
@@ -32,7 +32,5 @@
     public int getPosition();
     public void writePtNodeCount(final int ptNodeCount);
     public void writeForwardLinkAddress(final int forwardLinkAddress);
-
-    public void writePtNode(final PtNode ptNode, final int parentPosition,
-            final FormatOptions formatOptions, final FusionDictionary dict);
+    public void writePtNode(final PtNode ptNode, final FusionDictionary dict);
 }
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index 5a38073..c7635ef 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -309,7 +309,6 @@
      */
     public static final class FormatOptions {
         public final int mVersion;
-        public final boolean mHasTerminalId;
         public final boolean mHasTimestamp;
 
         @UsedForTesting
@@ -319,13 +318,8 @@
 
         public FormatOptions(final int version, final boolean hasTimestamp) {
             mVersion = version;
-            mHasTerminalId = (version >= FIRST_VERSION_WITH_TERMINAL_ID);
             mHasTimestamp = hasTimestamp;
         }
-
-        public boolean supportsDynamicUpdate() {
-            return mVersion >= FIRST_VERSION_WITH_DYNAMIC_UPDATE;
-        }
     }
 
     /**
diff --git a/java/src/com/android/inputmethod/latin/makedict/PtNodeInfo.java b/java/src/com/android/inputmethod/latin/makedict/PtNodeInfo.java
index 4760aa8..f52117c 100644
--- a/java/src/com/android/inputmethod/latin/makedict/PtNodeInfo.java
+++ b/java/src/com/android/inputmethod/latin/makedict/PtNodeInfo.java
@@ -31,12 +31,11 @@
     public final int[] mCharacters;
     public final ProbabilityInfo mProbabilityInfo;
     public final int mChildrenAddress;
-    public final int mParentAddress;
     public final ArrayList<WeightedString> mShortcutTargets;
     public final ArrayList<PendingAttribute> mBigrams;
 
     public PtNodeInfo(final int originalAddress, final int endAddress, final int flags,
-            final int[] characters, final ProbabilityInfo probabilityInfo, final int parentAddress,
+            final int[] characters, final ProbabilityInfo probabilityInfo,
             final int childrenAddress, final ArrayList<WeightedString> shortcutTargets,
             final ArrayList<PendingAttribute> bigrams) {
         mOriginalAddress = originalAddress;
@@ -44,7 +43,6 @@
         mFlags = flags;
         mCharacters = characters;
         mProbabilityInfo = probabilityInfo;
-        mParentAddress = parentAddress;
         mChildrenAddress = childrenAddress;
         mShortcutTargets = shortcutTargets;
         mBigrams = bigrams;
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java
index fd6138d..315bd8e 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java
@@ -17,12 +17,11 @@
 package com.android.inputmethod.latin.makedict;
 
 import com.android.inputmethod.annotations.UsedForTesting;
+import com.android.inputmethod.latin.BinaryDictionary;
 import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding;
 import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer;
-import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
 import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
-
-import android.util.Log;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -33,6 +32,7 @@
 /**
  * An implementation of DictDecoder for version 2 binary dictionary.
  */
+// TODO: Separate logics that are used only for testing.
 @UsedForTesting
 public class Ver2DictDecoder extends AbstractDictDecoder {
     private static final String TAG = Ver2DictDecoder.class.getSimpleName();
@@ -116,12 +116,19 @@
     }
 
     protected final File mDictionaryBinaryFile;
+    // TODO: Remove mBufferFactory and mDictBuffer from this class members because they are now
+    // used only for testing.
     private final DictionaryBufferFactory mBufferFactory;
     protected DictBuffer mDictBuffer;
+    private final BinaryDictionary mBinaryDictionary;
 
     /* package */ Ver2DictDecoder(final File file, final int factoryFlag) {
         mDictionaryBinaryFile = file;
         mDictBuffer = null;
+        // dictType is not being used in dicttool. Passing an empty string.
+        mBinaryDictionary = new BinaryDictionary(file.getAbsolutePath(),
+                0 /* offset */, file.length() /* length */, true /* useFullEditDistance */,
+                null /* locale */, "" /* dictType */, false /* isUpdatable */);
 
         if ((factoryFlag & MASK_DICTBUFFER) == USE_READONLY_BYTEBUFFER) {
             mBufferFactory = new DictionaryBufferFromReadOnlyByteBufferFactory();
@@ -137,6 +144,10 @@
     /* package */ Ver2DictDecoder(final File file, final DictionaryBufferFactory factory) {
         mDictionaryBinaryFile = file;
         mBufferFactory = factory;
+        // dictType is not being used in dicttool. Passing an empty string.
+        mBinaryDictionary = new BinaryDictionary(file.getAbsolutePath(),
+                0 /* offset */, file.length() /* length */, true /* useFullEditDistance */,
+                null /* locale */, "" /* dictType */, false /* isUpdatable */);
     }
 
     @Override
@@ -161,21 +172,23 @@
 
     @Override
     public DictionaryHeader readHeader() throws IOException, UnsupportedFormatException {
-        if (mDictBuffer == null) {
+        final DictionaryHeader header = mBinaryDictionary.getHeader();
+        if (header.mFormatOptions.mVersion != FormatSpec.VERSION2) {
+            throw new UnsupportedFormatException("File header has a wrong version : "
+                    + header.mFormatOptions.mVersion);
+        }
+        if (!isDictBufferOpen()) {
             openDictBuffer();
         }
-        final DictionaryHeader header = super.readHeader(mDictBuffer);
-        final int version = header.mFormatOptions.mVersion;
-        if (version != FormatSpec.VERSION2) {
-            throw new UnsupportedFormatException("File header has a wrong version : " + version);
-        }
+        // Advance buffer reading position to the head of dictionary body.
+        setPosition(header.mBodyOffset);
         return header;
     }
 
     // TODO: Make this buffer multi thread safe.
     private final int[] mCharacterBuffer = new int[FormatSpec.MAX_WORD_LENGTH];
     @Override
-    public PtNodeInfo readPtNode(final int ptNodePos, final FormatOptions options) {
+    public PtNodeInfo readPtNode(final int ptNodePos) {
         int addressPointer = ptNodePos;
         final int flags = PtNodeReader.readPtNodeOptionFlags(mDictBuffer);
         addressPointer += FormatSpec.PTNODE_FLAGS_SIZE;
@@ -209,7 +222,7 @@
         if (childrenAddress != FormatSpec.NO_CHILDREN_ADDRESS) {
             childrenAddress += addressPointer;
         }
-        addressPointer += BinaryDictIOUtils.getChildrenAddressSize(flags, options);
+        addressPointer += BinaryDictIOUtils.getChildrenAddressSize(flags);
         final ArrayList<WeightedString> shortcutTargets;
         if (0 != (flags & FormatSpec.FLAG_HAS_SHORTCUT_TARGETS)) {
             // readShortcut will add shortcuts to shortcutTargets.
@@ -232,31 +245,53 @@
             bigrams = null;
         }
         return new PtNodeInfo(ptNodePos, addressPointer, flags, characters, probabilityInfo,
-                FormatSpec.NO_PARENT_ADDRESS, childrenAddress, shortcutTargets, bigrams);
+                childrenAddress, shortcutTargets, bigrams);
     }
 
     @Override
-    public FusionDictionary readDictionaryBinary(final FusionDictionary dict,
-            final boolean deleteDictIfBroken)
+    public FusionDictionary readDictionaryBinary(final boolean deleteDictIfBroken)
             throws FileNotFoundException, IOException, UnsupportedFormatException {
-        if (mDictBuffer == null) {
-            openDictBuffer();
-        }
-        try {
-            return BinaryDictDecoderUtils.readDictionaryBinary(this, dict);
-        } catch (IOException e) {
-            Log.e(TAG, "The dictionary " + mDictionaryBinaryFile.getName() + " is broken.", e);
-            if (deleteDictIfBroken && !mDictionaryBinaryFile.delete()) {
-                Log.e(TAG, "Failed to delete the broken dictionary.");
+        final DictionaryHeader header = readHeader();
+        final FusionDictionary fusionDict =
+                new FusionDictionary(new FusionDictionary.PtNodeArray(), header.mDictionaryOptions);
+        int token = 0;
+        final ArrayList<WordProperty> wordProperties = CollectionUtils.newArrayList();
+        do {
+            final BinaryDictionary.GetNextWordPropertyResult result =
+                    mBinaryDictionary.getNextWordProperty(token);
+            final WordProperty wordProperty = result.mWordProperty;
+            if (wordProperty == null) {
+                if (deleteDictIfBroken) {
+                    mBinaryDictionary.close();
+                    mDictionaryBinaryFile.delete();
+                }
+                return null;
             }
-            throw e;
-        } catch (UnsupportedFormatException e) {
-            Log.e(TAG, "The dictionary " + mDictionaryBinaryFile.getName() + " is broken.", e);
-            if (deleteDictIfBroken && !mDictionaryBinaryFile.delete()) {
-                Log.e(TAG, "Failed to delete the broken dictionary.");
+            wordProperties.add(wordProperty);
+            token = result.mNextToken;
+        } while (token != 0);
+
+        // Insert unigrams into the fusion dictionary.
+        for (final WordProperty wordProperty : wordProperties) {
+            if (wordProperty.mIsBlacklistEntry) {
+                fusionDict.addBlacklistEntry(wordProperty.mWord, wordProperty.mShortcutTargets,
+                        wordProperty.mIsNotAWord);
+            } else {
+                fusionDict.add(wordProperty.mWord, wordProperty.mProbabilityInfo,
+                        wordProperty.mShortcutTargets, wordProperty.mIsNotAWord);
             }
-            throw e;
         }
+        // Insert bigrams into the fusion dictionary.
+        for (final WordProperty wordProperty : wordProperties) {
+            if (wordProperty.mBigrams == null) {
+                continue;
+            }
+            final String word0 = wordProperty.mWord;
+            for (final WeightedString bigram : wordProperty.mBigrams) {
+                fusionDict.setBigram(word0, bigram.mWord, bigram.mProbabilityInfo);
+            }
+        }
+        return fusionDict;
     }
 
     @Override
@@ -273,19 +308,4 @@
     public int readPtNodeCount() {
         return BinaryDictDecoderUtils.readPtNodeCount(mDictBuffer);
     }
-
-    @Override
-    public boolean readAndFollowForwardLink() {
-        final int nextAddress = mDictBuffer.readUnsignedInt24();
-        if (nextAddress >= 0 && nextAddress < mDictBuffer.limit()) {
-            mDictBuffer.position(nextAddress);
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public boolean hasNextPtNodeArray() {
-        return mDictBuffer.position() != FormatSpec.NO_FORWARD_LINK_ADDRESS;
-    }
 }
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java
index 634f631..e247f01 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java
@@ -95,7 +95,7 @@
         ArrayList<PtNodeArray> flatNodes = BinaryDictEncoderUtils.flattenTree(dict.mRootNodeArray);
 
         MakedictLog.i("Computing addresses...");
-        BinaryDictEncoderUtils.computeAddresses(dict, flatNodes, formatOptions);
+        BinaryDictEncoderUtils.computeAddresses(dict, flatNodes);
         MakedictLog.i("Checking PtNode array...");
         if (MakedictLog.DBG) BinaryDictEncoderUtils.checkFlatPtNodeArrayList(flatNodes);
 
@@ -107,7 +107,7 @@
         MakedictLog.i("Writing file...");
 
         for (PtNodeArray nodeArray : flatNodes) {
-            BinaryDictEncoderUtils.writePlacedPtNodeArray(dict, this, nodeArray, formatOptions);
+            BinaryDictEncoderUtils.writePlacedPtNodeArray(dict, this, nodeArray);
         }
         if (MakedictLog.DBG) BinaryDictEncoderUtils.showStatistics(flatNodes);
         mOutStream.write(mBuffer, 0, mPosition);
@@ -139,24 +139,13 @@
                 countSize);
     }
 
-    private void writePtNodeFlags(final PtNode ptNode, final FormatOptions formatOptions) {
-        final int childrenPos = BinaryDictEncoderUtils.getChildrenPosition(ptNode, formatOptions);
+    private void writePtNodeFlags(final PtNode ptNode) {
+        final int childrenPos = BinaryDictEncoderUtils.getChildrenPosition(ptNode);
         mPosition = BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, mPosition,
-                BinaryDictEncoderUtils.makePtNodeFlags(ptNode, childrenPos, formatOptions),
+                BinaryDictEncoderUtils.makePtNodeFlags(ptNode, childrenPos),
                 FormatSpec.PTNODE_FLAGS_SIZE);
     }
 
-    private void writeParentPosition(final int parentPosition, final PtNode ptNode,
-            final FormatOptions formatOptions) {
-        if (parentPosition == FormatSpec.NO_PARENT_ADDRESS) {
-            mPosition = BinaryDictEncoderUtils.writeParentAddress(mBuffer, mPosition,
-                    parentPosition, formatOptions);
-        } else {
-            mPosition = BinaryDictEncoderUtils.writeParentAddress(mBuffer, mPosition,
-                    parentPosition - ptNode.mCachedAddressAfterUpdate, formatOptions);
-        }
-    }
-
     private void writeCharacters(final int[] codePoints, final boolean hasSeveralChars) {
         mPosition = CharEncoding.writeCharArray(codePoints, mBuffer, mPosition);
         if (hasSeveralChars) {
@@ -171,15 +160,10 @@
         }
     }
 
-    private void writeChildrenPosition(final PtNode ptNode, final FormatOptions formatOptions) {
-        final int childrenPos = BinaryDictEncoderUtils.getChildrenPosition(ptNode, formatOptions);
-        if (formatOptions.supportsDynamicUpdate()) {
-            mPosition += BinaryDictEncoderUtils.writeSignedChildrenPosition(mBuffer, mPosition,
-                    childrenPos);
-        } else {
-            mPosition += BinaryDictEncoderUtils.writeChildrenPosition(mBuffer, mPosition,
-                    childrenPos);
-        }
+    private void writeChildrenPosition(final PtNode ptNode) {
+        final int childrenPos = BinaryDictEncoderUtils.getChildrenPosition(ptNode);
+        mPosition += BinaryDictEncoderUtils.writeChildrenPosition(mBuffer, mPosition,
+                childrenPos);
     }
 
     /**
@@ -246,13 +230,11 @@
     }
 
     @Override
-    public void writePtNode(final PtNode ptNode, final int parentPosition,
-            final FormatOptions formatOptions, final FusionDictionary dict) {
-        writePtNodeFlags(ptNode, formatOptions);
-        writeParentPosition(parentPosition, ptNode, formatOptions);
+    public void writePtNode(final PtNode ptNode, final FusionDictionary dict) {
+        writePtNodeFlags(ptNode);
         writeCharacters(ptNode.mChars, ptNode.hasSeveralChars());
         writeFrequency(ptNode.getProbability());
-        writeChildrenPosition(ptNode, formatOptions);
+        writeChildrenPosition(ptNode);
         writeShortcuts(ptNode.mShortcutTargets);
         writeBigrams(ptNode.mBigrams, dict);
     }
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java
index 1c74852..23aa05d 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java
@@ -45,6 +45,7 @@
     @UsedForTesting
     /* package */ Ver4DictDecoder(final File dictDirectory, final DictionaryBufferFactory factory) {
         mDictDirectory = dictDirectory;
+        // dictType is not being used in dicttool. Passing an empty string.
         mBinaryDictionary = new BinaryDictionary(dictDirectory.getAbsolutePath(),
                 0 /* offset */, 0 /* length */, true /* useFullEditDistance */, null /* locale */,
                 "" /* dictType */, true /* isUpdatable */);
@@ -56,11 +57,10 @@
     }
 
     @Override
-    public FusionDictionary readDictionaryBinary(final FusionDictionary dict,
-            final boolean deleteDictIfBroken)
+    public FusionDictionary readDictionaryBinary(final boolean deleteDictIfBroken)
             throws FileNotFoundException, IOException, UnsupportedFormatException {
         final DictionaryHeader header = readHeader();
-        final FusionDictionary fusionDict = dict != null ? dict :
+        final FusionDictionary fusionDict =
                 new FusionDictionary(new FusionDictionary.PtNodeArray(), header.mDictionaryOptions);
         int token = 0;
         final ArrayList<WordProperty> wordProperties = CollectionUtils.newArrayList();
@@ -79,7 +79,7 @@
             token = result.mNextToken;
         } while (token != 0);
 
-        // Insert unigrams to the fusion dictionary.
+        // Insert unigrams into the fusion dictionary.
         for (final WordProperty wordProperty : wordProperties) {
             if (wordProperty.mIsBlacklistEntry) {
                 fusionDict.addBlacklistEntry(wordProperty.mWord, wordProperty.mShortcutTargets,
@@ -89,7 +89,7 @@
                         wordProperty.mShortcutTargets, wordProperty.mIsNotAWord);
             }
         }
-        // Insert bigrams to the fusion dictionary.
+        // Insert bigrams into the fusion dictionary.
         for (final WordProperty wordProperty : wordProperties) {
             if (wordProperty.mBigrams == null) {
                 continue;
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java
index 147844f..1050d1b 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java
@@ -122,7 +122,6 @@
     }
 
     @Override
-    public void writePtNode(
-            PtNode ptNode, int parentPosition, FormatOptions formatOptions, FusionDictionary dict) {
+    public void writePtNode(PtNode ptNode, FusionDictionary dict) {
     }
 }
diff --git a/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java b/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java
index 4bf524c..6dae620 100644
--- a/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java
+++ b/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java
@@ -16,8 +16,6 @@
 
 package com.android.inputmethod.latin.settings;
 
-import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.ASCII_CAPABLE;
-
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.content.Context;
@@ -44,6 +42,8 @@
 import android.widget.SpinnerAdapter;
 import android.widget.Toast;
 
+import com.android.inputmethod.compat.InputMethodSubtypeCompatUtils;
+import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.RichInputMethodManager;
 import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
@@ -111,7 +111,7 @@
                             subtype.getLocale(), subtype.hashCode(), subtype.hashCode(),
                             SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype)));
                 }
-                if (subtype.containsExtraValueKey(ASCII_CAPABLE)) {
+                if (InputMethodSubtypeCompatUtils.isAsciiCapable(subtype)) {
                     items.add(createItem(context, subtype.getLocale()));
                 }
             }
@@ -287,7 +287,7 @@
                 final KeyboardLayoutSetItem layout =
                         (KeyboardLayoutSetItem) mKeyboardLayoutSetSpinner.getSelectedItem();
                 final InputMethodSubtype subtype = AdditionalSubtypeUtils.createAdditionalSubtype(
-                        locale.first, layout.first, ASCII_CAPABLE);
+                        locale.first, layout.first, Constants.Subtype.ExtraValue.ASCII_CAPABLE);
                 setSubtype(subtype);
                 notifyChanged();
                 if (isEditing) {
diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java
index 45c5b73..b51c765 100644
--- a/java/src/com/android/inputmethod/latin/settings/Settings.java
+++ b/java/src/com/android/inputmethod/latin/settings/Settings.java
@@ -66,6 +66,7 @@
             "pref_include_other_imes_in_language_switch_list";
     public static final String PREF_KEYBOARD_LAYOUT = "pref_keyboard_layout_20110916";
     public static final String PREF_CUSTOM_INPUT_STYLES = "custom_input_styles";
+    // TODO: consolidate key preview dismiss delay with the key preview animation parameters.
     public static final String PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY =
             "pref_key_preview_popup_dismiss_delay";
     public static final String PREF_BIGRAM_PREDICTIONS = "next_word_prediction";
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
index 67017a4..bb5547f 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
@@ -169,6 +169,7 @@
             removePreference(Settings.PREF_VIBRATION_DURATION_SETTINGS, advancedSettings);
         }
 
+        // TODO: consolidate key preview dismiss delay with the key preview animation parameters.
         if (!Settings.readFromBuildConfigIfToShowKeyPreviewPopupOption(res)) {
             removePreference(Settings.PREF_POPUP_ON, generalSettings);
             removePreference(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY, advancedSettings);
diff --git a/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java b/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java
index 03883a4..5954758 100644
--- a/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java
+++ b/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java
@@ -18,17 +18,13 @@
 
 import android.content.res.Resources;
 
-import com.android.inputmethod.keyboard.internal.KeySpecParser;
+import com.android.inputmethod.keyboard.internal.KeyboardTextsSet;
 import com.android.inputmethod.keyboard.internal.MoreKeySpec;
 import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.Dictionary;
+import com.android.inputmethod.latin.PunctuationSuggestions;
 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;
 import java.util.Locale;
 
@@ -37,7 +33,7 @@
     private final int[] mSortedSymbolsFollowedBySpace;
     private final int[] mSortedWordConnectors;
     public final int[] mSortedWordSeparators;
-    public final SuggestedWords mSuggestPuncList;
+    public final PunctuationSuggestions mSuggestPuncList;
     private final int mSentenceSeparator;
     public final String mSentenceSeparatorAndSpace;
     public final boolean mCurrentLanguageHasSpaces;
@@ -56,9 +52,6 @@
                 res.getString(R.string.symbols_word_connectors));
         mSortedWordSeparators = StringUtils.toSortedCodePointArray(
                 res.getString(R.string.symbols_word_separators));
-        final String[] suggestPuncsSpec = MoreKeySpec.splitKeySpecs(res.getString(
-                R.string.suggested_punctuations));
-        mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec);
         mSentenceSeparator = res.getInteger(R.integer.sentence_separator);
         mSentenceSeparatorAndSpace = new String(new int[] {
                 mSentenceSeparator, Constants.CODE_SPACE }, 0, 2);
@@ -68,28 +61,11 @@
         // English variants. German rules (not "German typography") also have small gotchas.
         mUsesAmericanTypography = Locale.ENGLISH.getLanguage().equals(locale.getLanguage());
         mUsesGermanRules = Locale.GERMAN.getLanguage().equals(locale.getLanguage());
-    }
-
-    // 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 KeySpecParser.getLabel().
-                // TODO: Punctuation suggestions should honor RTL languages.
-                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, null /* rawSuggestions */,
-                false /* typedWordValid */,
-                false /* hasAutoCorrectionCandidate */,
-                true /* isPunctuationSuggestions */,
-                false /* isObsoleteSuggestions */,
-                false /* isPrediction */);
+        final KeyboardTextsSet textsSet = new KeyboardTextsSet();
+        textsSet.setLocale(locale);
+        final String[] suggestPuncsSpec = MoreKeySpec.splitKeySpecs(
+                textsSet.resolveTextReference(res.getString(R.string.suggested_punctuations)));
+        mSuggestPuncList = PunctuationSuggestions.newPunctuationSuggestions(suggestPuncsSpec);
     }
 
     public boolean isWordSeparator(final int code) {
diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
index 2f4c183..a104baa 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
@@ -74,7 +74,7 @@
             int rowStartIndex = fromIndex;
             final int size = Math.min(suggestedWords.size(), SuggestedWords.MAX_SUGGESTIONS);
             while (index < size) {
-                final String word = suggestedWords.getWord(index);
+                final String word = suggestedWords.getLabel(index);
                 // TODO: Should take care of text x-scaling.
                 mWidths[index] = (int)(TypefaceUtils.getStringWidth(word, paint) + padding);
                 final int numColumn = index - rowStartIndex + 1;
@@ -206,7 +206,7 @@
                 final int x = params.getX(index);
                 final int y = params.getY(index);
                 final int width = params.getWidth(index);
-                final String word = mSuggestedWords.getWord(index);
+                final String word = mSuggestedWords.getLabel(index);
                 final String info = mSuggestedWords.getDebugString(index);
                 final int indexInMoreSuggestions = index + SUGGESTION_CODE_BASE;
                 final Key key = new Key(word, KeyboardIconsSet.ICON_UNDEFINED,
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
index 5f05b48..e77c550 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
@@ -44,8 +44,8 @@
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
-import com.android.inputmethod.compat.TextViewCompatUtils;
 import com.android.inputmethod.latin.LatinImeLogger;
+import com.android.inputmethod.latin.PunctuationSuggestions;
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.SuggestedWords;
 import com.android.inputmethod.latin.utils.AutoCorrectionUtils;
@@ -199,7 +199,7 @@
         if (indexInSuggestedWords >= suggestedWords.size()) {
             return null;
         }
-        final String word = suggestedWords.getWord(indexInSuggestedWords);
+        final String word = suggestedWords.getLabel(indexInSuggestedWords);
         final boolean isAutoCorrect = indexInSuggestedWords == 1
                 && suggestedWords.mWillAutoCorrect;
         final boolean isTypedWordValid = indexInSuggestedWords == 0
@@ -264,8 +264,8 @@
             // is in slot 1.
             if (positionInStrip == mCenterPositionInStrip
                     && AutoCorrectionUtils.shouldBlockAutoCorrectionBySafetyNet(
-                            suggestedWords.getWord(SuggestedWords.INDEX_OF_AUTO_CORRECTION),
-                            suggestedWords.getWord(SuggestedWords.INDEX_OF_TYPED_WORD))) {
+                            suggestedWords.getLabel(SuggestedWords.INDEX_OF_AUTO_CORRECTION),
+                            suggestedWords.getLabel(SuggestedWords.INDEX_OF_TYPED_WORD))) {
                 return 0xFFFF0000;
             }
         }
@@ -299,9 +299,9 @@
      */
     public int layoutAndReturnSuggestionCountInStrip(final SuggestedWords suggestedWords,
             final ViewGroup stripView, final ViewGroup placerView) {
-        if (suggestedWords.mIsPunctuationSuggestions) {
+        if (suggestedWords.isPunctuationSuggestions()) {
             return layoutPunctuationSuggestionsAndReturnSuggestionCountInStrip(
-                    suggestedWords, stripView);
+                    (PunctuationSuggestions)suggestedWords, stripView);
         }
 
         setupWordViewsTextAndColor(suggestedWords, mSuggestionsCountInStrip);
@@ -447,8 +447,8 @@
     }
 
     private int layoutPunctuationSuggestionsAndReturnSuggestionCountInStrip(
-            final SuggestedWords suggestedWords, final ViewGroup stripView) {
-        final int countInStrip = Math.min(suggestedWords.size(), PUNCTUATIONS_IN_STRIP);
+            final PunctuationSuggestions punctuationSuggestions, final ViewGroup stripView) {
+        final int countInStrip = Math.min(punctuationSuggestions.size(), PUNCTUATIONS_IN_STRIP);
         for (int positionInStrip = 0; positionInStrip < countInStrip; positionInStrip++) {
             if (positionInStrip != 0) {
                 // Add divider if this isn't the left most suggestion in suggestions strip.
@@ -461,13 +461,13 @@
             // {@link TextView#getTag()} is used to get the index in suggestedWords at
             // {@link SuggestionStripView#onClick(View)}.
             wordView.setTag(positionInStrip);
-            wordView.setText(suggestedWords.getWord(positionInStrip));
+            wordView.setText(punctuationSuggestions.getLabel(positionInStrip));
             wordView.setTextScaleX(1.0f);
             wordView.setCompoundDrawables(null, null, null, null);
             stripView.addView(wordView);
             setLayoutWeight(wordView, 1.0f, mSuggestionsStripHeight);
         }
-        mMoreSuggestionsAvailable = (suggestedWords.size() > countInStrip);
+        mMoreSuggestionsAvailable = (punctuationSuggestions.size() > countInStrip);
         return countInStrip;
     }
 
@@ -505,15 +505,10 @@
     }
 
     public void layoutImportantNotice(final View importantNoticeStrip, final int stripWidth) {
-        final Resources res = importantNoticeStrip.getResources();
-        final Drawable infoIcon = res.getDrawable(R.drawable.sym_keyboard_info_holo_dark);
-        final Drawable moreIcon = res.getDrawable(R.drawable.sym_keyboard_more_holo_dark);
-        final int width = stripWidth - infoIcon.getIntrinsicWidth() - moreIcon.getIntrinsicWidth();
         final TextView titleView = (TextView)importantNoticeStrip.findViewById(
                 R.id.important_notice_title);
+        final int width = stripWidth - titleView.getPaddingLeft() - titleView.getPaddingRight();
         titleView.setTextColor(mColorAutoCorrect);
-        TextViewCompatUtils.setCompoundDrawablesRelativeWithIntrinsicBounds(
-                titleView, infoIcon, null, moreIcon, null);
         final CharSequence importantNoticeTitle = titleView.getText();
         titleView.setTextScaleX(1.0f); // Reset textScaleX.
         final float titleScaleX = getTextScaleX(
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
index cf0a7a2..90b9692 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
@@ -39,11 +39,13 @@
 import com.android.inputmethod.keyboard.MoreKeysPanel;
 import com.android.inputmethod.latin.AudioAndHapticFeedbackManager;
 import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.InputAttributes;
 import com.android.inputmethod.latin.LatinImeLogger;
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.SuggestedWords;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
 import com.android.inputmethod.latin.define.ProductionFlag;
+import com.android.inputmethod.latin.settings.Settings;
 import com.android.inputmethod.latin.suggestions.MoreSuggestions.MoreSuggestionsListener;
 import com.android.inputmethod.latin.utils.CollectionUtils;
 import com.android.inputmethod.latin.utils.ImportantNoticeUtils;
@@ -226,8 +228,8 @@
     // This method checks if we should show the important notice (checks on permanent storage if
     // it has been shown once already or not, and if in the setup wizard). If applicable, it shows
     // the notice. In all cases, it returns true if it was shown, false otherwise.
-    public boolean maybeShowImportantNoticeTitle() {
-        if (!ImportantNoticeUtils.hasNewImportantNoticeAndNotInSetupWizard(getContext())) {
+    public boolean maybeShowImportantNoticeTitle(final InputAttributes inputAttributes) {
+        if (!ImportantNoticeUtils.shouldShowImportantNotice(getContext(), inputAttributes)) {
             return false;
         }
         final int width = getWidth();
@@ -325,7 +327,6 @@
         final int pointY = -layoutHelper.mMoreSuggestionsBottomGap;
         moreKeysPanel.showMoreKeysPanel(this, mMoreSuggestionsController, pointX, pointY,
                 mMoreSuggestionsListener);
-        mMoreSuggestionsMode = MORE_SUGGESTIONS_CHECKING_MODAL_OR_SLIDING;
         mOriginX = mLastX;
         mOriginY = mLastY;
         for (int i = 0; i < mSuggestionsCountInStrip; i++) {
@@ -334,11 +335,8 @@
         return true;
     }
 
-    // Working variables for onLongClick and dispatchTouchEvent.
-    private int mMoreSuggestionsMode = MORE_SUGGESTIONS_IN_MODAL_MODE;
-    private static final int MORE_SUGGESTIONS_IN_MODAL_MODE = 0;
-    private static final int MORE_SUGGESTIONS_CHECKING_MODAL_OR_SLIDING = 1;
-    private static final int MORE_SUGGESTIONS_IN_SLIDING_MODE = 2;
+    // Working variables for {@link #onLongClick(View)} and
+    // {@link onInterceptTouchEvent(MotionEvent)}.
     private int mLastX;
     private int mLastY;
     private int mOriginX;
@@ -358,36 +356,39 @@
     };
 
     @Override
-    public boolean dispatchTouchEvent(final MotionEvent me) {
+    public boolean onInterceptTouchEvent(final MotionEvent me) {
         if (!mMoreSuggestionsView.isShowingInParent()) {
             mLastX = (int)me.getX();
             mLastY = (int)me.getY();
-            if (mMoreSuggestionsSlidingDetector.onTouchEvent(me)) {
-                return true;
-            }
-            return super.dispatchTouchEvent(me);
+            return mMoreSuggestionsSlidingDetector.onTouchEvent(me);
         }
 
         final int action = me.getAction();
         final int index = me.getActionIndex();
         final int x = (int)me.getX(index);
         final int y = (int)me.getY(index);
-
-        if (mMoreSuggestionsMode == MORE_SUGGESTIONS_CHECKING_MODAL_OR_SLIDING) {
-            if (Math.abs(x - mOriginX) >= mMoreSuggestionsModalTolerance
-                    || mOriginY - y >= mMoreSuggestionsModalTolerance) {
-                // Decided to be in the sliding input mode only when the touch point has been moved
-                // upward.
-                mMoreSuggestionsMode = MORE_SUGGESTIONS_IN_SLIDING_MODE;
-            } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP) {
-                // Decided to be in the modal input mode
-                mMoreSuggestionsMode = MORE_SUGGESTIONS_IN_MODAL_MODE;
-                mMoreSuggestionsView.adjustVerticalCorrectionForModalMode();
-            }
+        if (Math.abs(x - mOriginX) >= mMoreSuggestionsModalTolerance
+                || mOriginY - y >= mMoreSuggestionsModalTolerance) {
+            // Decided to be in the sliding input mode only when the touch point has been moved
+            // upward. Further {@link MotionEvent}s will be delivered to
+            // {@link #onTouchEvent(MotionEvent)}.
             return true;
         }
 
-        // MORE_SUGGESTIONS_IN_SLIDING_MODE
+        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP) {
+            // Decided to be in the modal input mode.
+            mMoreSuggestionsView.adjustVerticalCorrectionForModalMode();
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onTouchEvent(final MotionEvent me) {
+        // In the sliding input mode. {@link MotionEvent} should be forwarded to
+        // {@link MoreSuggestionsView}.
+        final int index = me.getActionIndex();
+        final int x = (int)me.getX(index);
+        final int y = (int)me.getY(index);
         me.setLocation(mMoreSuggestionsView.translateX(x), mMoreSuggestionsView.translateY(y));
         mMoreSuggestionsView.onTouchEvent(me);
         return true;
@@ -431,6 +432,6 @@
     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
         // Called by the framework when the size is known. Show the important notice if applicable.
         // This may be overriden by showing suggestions later, if applicable.
-        maybeShowImportantNoticeTitle();
+        maybeShowImportantNoticeTitle(Settings.getInstance().getCurrent().mInputAttributes);
     }
 }
diff --git a/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java b/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java
index 604c364..50a9423 100644
--- a/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java
@@ -22,6 +22,7 @@
 import android.provider.Settings.SettingNotFoundException;
 import android.util.Log;
 
+import com.android.inputmethod.latin.InputAttributes;
 import com.android.inputmethod.latin.R;
 
 public final class ImportantNoticeUtils {
@@ -62,11 +63,18 @@
         return context.getResources().getInteger(R.integer.config_important_notice_version);
     }
 
-    public static boolean hasNewImportantNoticeAndNotInSetupWizard(final Context context) {
+    private static boolean hasNewImportantNotice(final Context context) {
         final SharedPreferences prefs = getImportantNoticePreferences(context);
         final int lastVersion = prefs.getInt(KEY_IMPORTANT_NOTICE_VERSION, 0);
-        return getCurrentImportantNoticeVersion(context) > lastVersion
-                && !isInSystemSetupWizard(context);
+        return getCurrentImportantNoticeVersion(context) > lastVersion;
+    }
+
+    public static boolean shouldShowImportantNotice(final Context context,
+            final InputAttributes inputAttributes) {
+        if (inputAttributes == null || inputAttributes.mIsPasswordField) {
+            return false;
+        }
+        return hasNewImportantNotice(context) && !isInSystemSetupWizard(context);
     }
 
     public static void updateLastImportantNoticeVersion(final Context context) {
diff --git a/java/src/com/android/inputmethod/research/JsonUtils.java b/java/src/com/android/inputmethod/research/JsonUtils.java
index 2beebdf..6170b43 100644
--- a/java/src/com/android/inputmethod/research/JsonUtils.java
+++ b/java/src/com/android/inputmethod/research/JsonUtils.java
@@ -91,7 +91,7 @@
         jsonWriter.name("willAutoCorrect")
                 .value(words.mWillAutoCorrect);
         jsonWriter.name("isPunctuationSuggestions")
-                .value(words.mIsPunctuationSuggestions);
+                .value(words.isPunctuationSuggestions());
         jsonWriter.name("isObsoleteSuggestions").value(words.mIsObsoleteSuggestions);
         jsonWriter.name("isPrediction").value(words.mIsPrediction);
         jsonWriter.name("suggestedWords");
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/pt_node_params.h b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/pt_node_params.h
index faaf441..e4847fc 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/pt_node_params.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/pt_node_params.h
@@ -30,18 +30,19 @@
 class PtNodeParams {
  public:
     // Invalid PtNode.
-    PtNodeParams() : mHeadPos(NOT_A_DICT_POS), mFlags(0), mParentPos(NOT_A_DICT_POS),
-            mCodePointCount(0), mCodePoints(), mTerminalIdFieldPos(NOT_A_DICT_POS),
-            mTerminalId(Ver4DictConstants::NOT_A_TERMINAL_ID), mProbabilityFieldPos(NOT_A_DICT_POS),
-            mProbability(NOT_A_PROBABILITY), mChildrenPosFieldPos(NOT_A_DICT_POS),
-            mChildrenPos(NOT_A_DICT_POS), mBigramLinkedNodePos(NOT_A_DICT_POS),
-            mShortcutPos(NOT_A_DICT_POS), mBigramPos(NOT_A_DICT_POS),
-            mSiblingPos(NOT_A_DICT_POS) {}
+    PtNodeParams() : mHeadPos(NOT_A_DICT_POS), mFlags(0), mHasMovedFlag(false),
+            mParentPos(NOT_A_DICT_POS), mCodePointCount(0), mCodePoints(),
+            mTerminalIdFieldPos(NOT_A_DICT_POS), mTerminalId(Ver4DictConstants::NOT_A_TERMINAL_ID),
+            mProbabilityFieldPos(NOT_A_DICT_POS), mProbability(NOT_A_PROBABILITY),
+            mChildrenPosFieldPos(NOT_A_DICT_POS), mChildrenPos(NOT_A_DICT_POS),
+            mBigramLinkedNodePos(NOT_A_DICT_POS), mShortcutPos(NOT_A_DICT_POS),
+            mBigramPos(NOT_A_DICT_POS), mSiblingPos(NOT_A_DICT_POS) {}
 
     PtNodeParams(const PtNodeParams& ptNodeParams)
             : mHeadPos(ptNodeParams.mHeadPos), mFlags(ptNodeParams.mFlags),
-              mParentPos(ptNodeParams.mParentPos), mCodePointCount(ptNodeParams.mCodePointCount),
-              mCodePoints(), mTerminalIdFieldPos(ptNodeParams.mTerminalIdFieldPos),
+              mHasMovedFlag(ptNodeParams.mHasMovedFlag), mParentPos(ptNodeParams.mParentPos),
+              mCodePointCount(ptNodeParams.mCodePointCount), mCodePoints(),
+              mTerminalIdFieldPos(ptNodeParams.mTerminalIdFieldPos),
               mTerminalId(ptNodeParams.mTerminalId),
               mProbabilityFieldPos(ptNodeParams.mProbabilityFieldPos),
               mProbability(ptNodeParams.mProbability),
@@ -58,7 +59,7 @@
             const int codePointCount, const int *const codePoints, const int probability,
             const int childrenPos, const int shortcutPos, const int bigramPos,
             const int siblingPos)
-            : mHeadPos(headPos), mFlags(flags), mParentPos(NOT_A_DICT_POS),
+            : mHeadPos(headPos), mFlags(flags), mHasMovedFlag(false), mParentPos(NOT_A_DICT_POS),
               mCodePointCount(codePointCount), mCodePoints(), mTerminalIdFieldPos(NOT_A_DICT_POS),
               mTerminalId(Ver4DictConstants::NOT_A_TERMINAL_ID),
               mProbabilityFieldPos(NOT_A_DICT_POS), mProbability(probability),
@@ -73,7 +74,7 @@
             const int parentPos, const int codePointCount, const int *const codePoints,
             const int terminalIdFieldPos, const int terminalId, const int probability,
             const int childrenPosFieldPos, const int childrenPos, const int siblingPos)
-            : mHeadPos(headPos), mFlags(flags), mParentPos(parentPos),
+            : mHeadPos(headPos), mFlags(flags), mHasMovedFlag(true), mParentPos(parentPos),
               mCodePointCount(codePointCount), mCodePoints(),
               mTerminalIdFieldPos(terminalIdFieldPos), mTerminalId(terminalId),
               mProbabilityFieldPos(NOT_A_DICT_POS), mProbability(probability),
@@ -87,8 +88,8 @@
     PtNodeParams(const PtNodeParams *const ptNodeParams,
             const PatriciaTrieReadingUtils::NodeFlags flags, const int parentPos,
             const int codePointCount, const int *const codePoints, const int probability)
-            : mHeadPos(ptNodeParams->getHeadPos()), mFlags(flags), mParentPos(parentPos),
-              mCodePointCount(codePointCount), mCodePoints(),
+            : mHeadPos(ptNodeParams->getHeadPos()), mFlags(flags), mHasMovedFlag(true),
+              mParentPos(parentPos), mCodePointCount(codePointCount), mCodePoints(),
               mTerminalIdFieldPos(ptNodeParams->getTerminalIdFieldPos()),
               mTerminalId(ptNodeParams->getTerminalId()),
               mProbabilityFieldPos(ptNodeParams->getProbabilityFieldPos()),
@@ -104,7 +105,7 @@
 
     PtNodeParams(const PatriciaTrieReadingUtils::NodeFlags flags, const int parentPos,
             const int codePointCount, const int *const codePoints, const int probability)
-            : mHeadPos(NOT_A_DICT_POS), mFlags(flags), mParentPos(parentPos),
+            : mHeadPos(NOT_A_DICT_POS), mFlags(flags), mHasMovedFlag(true), mParentPos(parentPos),
               mCodePointCount(codePointCount), mCodePoints(),
               mTerminalIdFieldPos(NOT_A_DICT_POS),
               mTerminalId(Ver4DictConstants::NOT_A_TERMINAL_ID),
@@ -126,11 +127,11 @@
 
     // Flags
     AK_FORCE_INLINE bool isDeleted() const {
-        return DynamicPtReadingUtils::isDeleted(mFlags);
+        return mHasMovedFlag && DynamicPtReadingUtils::isDeleted(mFlags);
     }
 
     AK_FORCE_INLINE bool willBecomeNonTerminal() const {
-        return DynamicPtReadingUtils::willBecomeNonTerminal(mFlags);
+        return mHasMovedFlag && DynamicPtReadingUtils::willBecomeNonTerminal(mFlags);
     }
 
     AK_FORCE_INLINE bool hasChildren() const {
@@ -224,6 +225,7 @@
 
     const int mHeadPos;
     const PatriciaTrieReadingUtils::NodeFlags mFlags;
+    const bool mHasMovedFlag;
     const int mParentPos;
     const uint8_t mCodePointCount;
     int mCodePoints[MAX_WORD_LENGTH];
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp
index 8172e70..fa59930 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp
@@ -20,6 +20,7 @@
 #include "defines.h"
 #include "suggest/core/dicnode/dic_node.h"
 #include "suggest/core/dicnode/dic_node_vector.h"
+#include "suggest/core/dictionary/binary_dictionary_bigrams_iterator.h"
 #include "suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_reading_helper.h"
 #include "suggest/policyimpl/dictionary/structure/v2/patricia_trie_reading_utils.h"
 #include "suggest/policyimpl/dictionary/utils/probability_utils.h"
@@ -303,4 +304,92 @@
     return siblingPos;
 }
 
+const WordProperty PatriciaTriePolicy::getWordProperty(const int *const codePoints,
+        const int codePointCount) const {
+    const int ptNodePos = getTerminalPtNodePositionOfWord(codePoints, codePointCount,
+            false /* forceLowerCaseSearch */);
+    if (ptNodePos == NOT_A_DICT_POS) {
+        AKLOGE("getWordProperty was called for invalid word.");
+        return WordProperty();
+    }
+    const PtNodeParams ptNodeParams = mPtNodeReader.fetchNodeInfoInBufferFromPtNodePos(ptNodePos);
+    std::vector<int> codePointVector(ptNodeParams.getCodePoints(),
+            ptNodeParams.getCodePoints() + ptNodeParams.getCodePointCount());
+    // Fetch bigram information.
+    std::vector<WordProperty::BigramProperty> bigrams;
+    const int bigramListPos = getBigramsPositionOfPtNode(ptNodePos);
+    int bigramWord1CodePoints[MAX_WORD_LENGTH];
+    BinaryDictionaryBigramsIterator bigramsIt(getBigramsStructurePolicy(), bigramListPos);
+    while (bigramsIt.hasNext()) {
+        // Fetch the next bigram information and forward the iterator.
+        bigramsIt.next();
+        // Skip the entry if the entry has been deleted. This never happens for ver2 dicts.
+        if (bigramsIt.getBigramPos() != NOT_A_DICT_POS) {
+            int word1Probability = NOT_A_PROBABILITY;
+            int word1CodePointCount = getCodePointsAndProbabilityAndReturnCodePointCount(
+                    bigramsIt.getBigramPos(), MAX_WORD_LENGTH, bigramWord1CodePoints,
+                    &word1Probability);
+            std::vector<int> word1(bigramWord1CodePoints,
+                    bigramWord1CodePoints + word1CodePointCount);
+            bigrams.push_back(WordProperty::BigramProperty(&word1, bigramsIt.getProbability(),
+                    NOT_A_TIMESTAMP /* timestamp */, 0 /* level */, 0 /* count */));
+        }
+    }
+    // Fetch shortcut information.
+    std::vector<WordProperty::ShortcutProperty> shortcuts;
+    int shortcutPos = getShortcutPositionOfPtNode(ptNodePos);
+    if (shortcutPos != NOT_A_DICT_POS) {
+        int shortcutTargetCodePoints[MAX_WORD_LENGTH];
+        ShortcutListReadingUtils::getShortcutListSizeAndForwardPointer(mDictRoot, &shortcutPos);
+        bool hasNext = true;
+        while (hasNext) {
+            const ShortcutListReadingUtils::ShortcutFlags shortcutFlags =
+                    ShortcutListReadingUtils::getFlagsAndForwardPointer(mDictRoot, &shortcutPos);
+            hasNext = ShortcutListReadingUtils::hasNext(shortcutFlags);
+            const int shortcutTargetLength = ShortcutListReadingUtils::readShortcutTarget(
+                    mDictRoot, MAX_WORD_LENGTH, shortcutTargetCodePoints, &shortcutPos);
+            std::vector<int> shortcutTarget(shortcutTargetCodePoints,
+                    shortcutTargetCodePoints + shortcutTargetLength);
+            const int shortcutProbability =
+                    ShortcutListReadingUtils::getProbabilityFromFlags(shortcutFlags);
+            shortcuts.push_back(
+                    WordProperty::ShortcutProperty(&shortcutTarget, shortcutProbability));
+        }
+    }
+    return WordProperty(&codePointVector, ptNodeParams.isNotAWord(),
+            ptNodeParams.isBlacklisted(), ptNodeParams.hasBigrams(),
+            ptNodeParams.hasShortcutTargets(), ptNodeParams.getProbability(),
+            NOT_A_TIMESTAMP /* timestamp */, 0 /* level */, 0 /* count */,
+            &bigrams, &shortcuts);
+}
+
+int PatriciaTriePolicy::getNextWordAndNextToken(const int token, int *const outCodePoints) {
+    if (token == 0) {
+        // Start iterating the dictionary.
+        mTerminalPtNodePositionsForIteratingWords.clear();
+        DynamicPtReadingHelper::TraversePolicyToGetAllTerminalPtNodePositions traversePolicy(
+                &mTerminalPtNodePositionsForIteratingWords);
+        DynamicPtReadingHelper readingHelper(&mPtNodeReader, &mPtNodeArrayReader);
+        readingHelper.initWithPtNodeArrayPos(getRootPosition());
+        readingHelper.traverseAllPtNodesInPostorderDepthFirstManner(&traversePolicy);
+    }
+    const int terminalPtNodePositionsVectorSize =
+            static_cast<int>(mTerminalPtNodePositionsForIteratingWords.size());
+    if (token < 0 || token >= terminalPtNodePositionsVectorSize) {
+        AKLOGE("Given token %d is invalid.", token);
+        return 0;
+    }
+    const int terminalPtNodePos = mTerminalPtNodePositionsForIteratingWords[token];
+    int unigramProbability = NOT_A_PROBABILITY;
+    getCodePointsAndProbabilityAndReturnCodePointCount(terminalPtNodePos, MAX_WORD_LENGTH,
+            outCodePoints, &unigramProbability);
+    const int nextToken = token + 1;
+    if (nextToken >= terminalPtNodePositionsVectorSize) {
+        // All words have been iterated.
+        mTerminalPtNodePositionsForIteratingWords.clear();
+        return 0;
+    }
+    return nextToken;
+}
+
 } // namespace latinime
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h
index 1ce7f85..8fbca26 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h
@@ -18,6 +18,7 @@
 #define LATINIME_PATRICIA_TRIE_POLICY_H
 
 #include <stdint.h>
+#include <vector>
 
 #include "defines.h"
 #include "suggest/core/policy/dictionary_structure_with_buffer_policy.h"
@@ -44,7 +45,8 @@
                       - mHeaderPolicy.getSize()),
               mBigramListPolicy(mDictRoot), mShortcutListPolicy(mDictRoot),
               mPtNodeReader(mDictRoot, mDictBufferSize, &mBigramListPolicy, &mShortcutListPolicy),
-              mPtNodeArrayReader(mDictRoot, mDictBufferSize) {}
+              mPtNodeArrayReader(mDictRoot, mDictBufferSize),
+              mTerminalPtNodePositionsForIteratingWords() {}
 
     AK_FORCE_INLINE int getRootPosition() const {
         return 0;
@@ -128,15 +130,9 @@
     }
 
     const WordProperty getWordProperty(const int *const codePoints,
-            const int codePointCount) const {
-        // getWordProperty is not supported.
-        return WordProperty();
-    }
+            const int codePointCount) const;
 
-    int getNextWordAndNextToken(const int token, int *const outCodePoints) {
-        // getNextWordAndNextToken is not supported.
-        return 0;
-    }
+    int getNextWordAndNextToken(const int token, int *const outCodePoints);
 
  private:
     DISALLOW_IMPLICIT_CONSTRUCTORS(PatriciaTriePolicy);
@@ -149,6 +145,7 @@
     const ShortcutListPolicy mShortcutListPolicy;
     const Ver2ParticiaTrieNodeReader mPtNodeReader;
     const Ver2PtNodeArrayReader mPtNodeArrayReader;
+    std::vector<int> mTerminalPtNodePositionsForIteratingWords;
 
     int createAndGetLeavingChildNode(const DicNode *const dicNode, const int ptNodePos,
             DicNodeVector *const childDicNodes) const;
diff --git a/native/jni/src/utils/char_utils.cpp b/native/jni/src/utils/char_utils.cpp
index d41fc89..adc474b 100644
--- a/native/jni/src/utils/char_utils.cpp
+++ b/native/jni/src/utils/char_utils.cpp
@@ -1118,7 +1118,8 @@
     /* U+0118 */ 0x0045, 0x0065, 0x0045, 0x0065, 0x0047, 0x0067, 0x0047, 0x0067,
     /* U+0120 */ 0x0047, 0x0067, 0x0047, 0x0067, 0x0048, 0x0068, 0x0126, 0x0127,
     /* U+0128 */ 0x0049, 0x0069, 0x0049, 0x0069, 0x0049, 0x0069, 0x0049, 0x0069,
-    /* U+0130 */ 0x0049, 0x0131, 0x0049, 0x0069, 0x004A, 0x006A, 0x004B, 0x006B,
+        // U+0131: Manually changed from 0131 to 0049
+    /* U+0130 */ 0x0049, 0x0049, 0x0049, 0x0069, 0x004A, 0x006A, 0x004B, 0x006B,
     /* U+0138 */ 0x0138, 0x004C, 0x006C, 0x004C, 0x006C, 0x004C, 0x006C, 0x004C,
     /* U+0140 */ 0x006C, 0x004C, 0x006C, 0x004E, 0x006E, 0x004E, 0x006E, 0x004E,
         // U+0141: Manually changed from 0141 to 004C
diff --git a/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java b/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java
index 5702a62..f4b16a7 100644
--- a/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java
+++ b/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java
@@ -152,8 +152,8 @@
 
         final DictDecoder dictDecoder = FormatSpec.getDictDecoder(dictFile);
         try {
-            final FusionDictionary dict = dictDecoder.readDictionaryBinary(null,
-                    false /* deleteDictIfBroken */);
+            final FusionDictionary dict =
+                    dictDecoder.readDictionaryBinary(false /* deleteDictIfBroken */);
             PtNode ptNode = FusionDictionary.findWordInTree(dict.mRootNodeArray, "a");
             assertNotNull(ptNode);
             assertTrue(ptNode.isTerminal());
diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
index 06b64b4..4b157e7 100644
--- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java
+++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
@@ -35,6 +35,7 @@
 import android.widget.EditText;
 import android.widget.FrameLayout;
 
+import com.android.inputmethod.compat.InputMethodSubtypeCompatUtils;
 import com.android.inputmethod.keyboard.Key;
 import com.android.inputmethod.keyboard.Keyboard;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
@@ -290,17 +291,25 @@
 
     protected void changeLanguageWithoutWait(final String locale) {
         mEditText.mCurrentLocale = LocaleUtils.constructLocaleFromString(locale);
-        final InputMethodSubtype subtype = new InputMethodSubtype(
-            R.string.subtype_no_language_qwerty, R.drawable.ic_ime_switcher_dark,
-            locale, "keyboard", "KeyboardLayoutSet="
-                    // TODO: this is forcing a QWERTY keyboard for all locales, which is wrong.
-                    // It's still better than using whatever keyboard is the current one, but we
-                    // should actually use the default keyboard for this locale.
-                    + SubtypeLocaleUtils.QWERTY
-                    + "," + Constants.Subtype.ExtraValue.ASCII_CAPABLE
-                    + "," + Constants.Subtype.ExtraValue.ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE
-                    + "," + Constants.Subtype.ExtraValue.EMOJI_CAPABLE,
-                    false /* isAuxiliary */, false /* overridesImplicitlyEnabledSubtype */);
+        // TODO: this is forcing a QWERTY keyboard for all locales, which is wrong.
+        // It's still better than using whatever keyboard is the current one, but we
+        // should actually use the default keyboard for this locale.
+        // TODO: Use {@link InputMethodSubtype.InputMethodSubtypeBuilder} directly or indirectly so
+        // that {@link InputMethodSubtype#isAsciiCapable} can return the correct value.
+        final String EXTRA_VALUE_FOR_TEST =
+                "KeyboardLayoutSet=" + SubtypeLocaleUtils.QWERTY
+                + "," + Constants.Subtype.ExtraValue.ASCII_CAPABLE
+                + "," + Constants.Subtype.ExtraValue.ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE
+                + "," + Constants.Subtype.ExtraValue.EMOJI_CAPABLE;
+        final InputMethodSubtype subtype = InputMethodSubtypeCompatUtils.newInputMethodSubtype(
+                R.string.subtype_no_language_qwerty,
+                R.drawable.ic_ime_switcher_dark,
+                locale,
+                Constants.Subtype.KEYBOARD_MODE,
+                EXTRA_VALUE_FOR_TEST,
+                false /* isAuxiliary */,
+                false /* overridesImplicitlyEnabledSubtype */,
+                0 /* id */);
         SubtypeSwitcher.getInstance().forceSubtype(subtype);
         mLatinIME.loadKeyboard();
         runMessages();
diff --git a/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java b/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java
index 53839b6..8fe4735 100644
--- a/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java
+++ b/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java
@@ -49,7 +49,6 @@
                 list, null /* rawSuggestions */,
                 false /* typedWordValid */,
                 false /* willAutoCorrect */,
-                false /* isPunctuationSuggestions */,
                 false /* isObsoleteSuggestions */,
                 false /* isPrediction*/);
         assertEquals(NUMBER_OF_ADDED_SUGGESTIONS + 1, words.size());
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
index 141730d..e21e340 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
@@ -19,6 +19,7 @@
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
+import android.util.Pair;
 import android.util.SparseArray;
 
 import com.android.inputmethod.latin.BinaryDictionary;
@@ -39,6 +40,7 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map.Entry;
 import java.util.Random;
 import java.util.Set;
@@ -251,7 +253,7 @@
         try {
             final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file, bufferType);
             now = System.currentTimeMillis();
-            dict = dictDecoder.readDictionaryBinary(null, false /* deleteDictIfBroken */);
+            dict = dictDecoder.readDictionaryBinary(false /* deleteDictIfBroken */);
             diff  = System.currentTimeMillis() - now;
         } catch (IOException e) {
             Log.e(TAG, "IOException while reading dictionary", e);
@@ -499,7 +501,7 @@
         }
         if (fileHeader == null) return null;
         return BinaryDictDecoderUtils.getWordAtPosition(dictDecoder, fileHeader.mBodyOffset,
-                address, fileHeader.mFormatOptions).mWord;
+                address).mWord;
     }
 
     private long checkGetTerminalPosition(final DictDecoder dictDecoder, final String word,
@@ -596,4 +598,101 @@
             Log.d(TAG, result);
         }
     }
+
+    public void testVer2DictGetWordProperty() {
+        final FormatOptions formatOptions = BinaryDictUtils.VERSION2_OPTIONS;
+        final ArrayList<String> words = sWords;
+        final HashMap<String, List<String>> shortcuts = sShortcuts;
+        final String dictName = "testGetWordProperty";
+        final String dictVersion = Long.toString(System.currentTimeMillis());
+        final FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
+                BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion, formatOptions));
+        addUnigrams(words.size(), dict, words, shortcuts);
+        addBigrams(dict, words, sEmptyBigrams);
+        final File file = BinaryDictUtils.getDictFile(dictName, dictVersion, formatOptions,
+                getContext().getCacheDir());
+        file.delete();
+        timeWritingDictToFile(file, dict, formatOptions);
+        final BinaryDictionary binaryDictionary = new BinaryDictionary(file.getAbsolutePath(),
+                0 /* offset */, file.length(), true /* useFullEditDistance */,
+                Locale.ENGLISH, dictName, false /* isUpdatable */);
+        for (final String word : words) {
+            final WordProperty wordProperty = binaryDictionary.getWordProperty(word);
+            assertEquals(word, wordProperty.mWord);
+            assertEquals(UNIGRAM_FREQ, wordProperty.getProbability());
+            if (shortcuts.containsKey(word)) {
+                assertEquals(shortcuts.get(word).size(), wordProperty.mShortcutTargets.size());
+                final List<String> shortcutList = shortcuts.get(word);
+                assertTrue(wordProperty.mHasShortcuts);
+                for (final WeightedString shortcutTarget : wordProperty.mShortcutTargets) {
+                    assertTrue(shortcutList.contains(shortcutTarget.mWord));
+                    assertEquals(UNIGRAM_FREQ, shortcutTarget.getProbability());
+                    shortcutList.remove(shortcutTarget.mWord);
+                }
+                assertTrue(shortcutList.isEmpty());
+            }
+        }
+    }
+
+    public void testVer2DictIteration() {
+        final FormatOptions formatOptions = BinaryDictUtils.VERSION2_OPTIONS;
+        final ArrayList<String> words = sWords;
+        final HashMap<String, List<String>> shortcuts = sShortcuts;
+        final SparseArray<List<Integer>> bigrams = sEmptyBigrams;
+        final String dictName = "testGetWordProperty";
+        final String dictVersion = Long.toString(System.currentTimeMillis());
+        final FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
+                BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion, formatOptions));
+        addUnigrams(words.size(), dict, words, shortcuts);
+        addBigrams(dict, words, bigrams);
+        final File file = BinaryDictUtils.getDictFile(dictName, dictVersion, formatOptions,
+                getContext().getCacheDir());
+        timeWritingDictToFile(file, dict, formatOptions);
+        Log.d(TAG, file.getAbsolutePath());
+        final BinaryDictionary binaryDictionary = new BinaryDictionary(file.getAbsolutePath(),
+                0 /* offset */, file.length(), true /* useFullEditDistance */,
+                Locale.ENGLISH, dictName, false /* isUpdatable */);
+
+        final HashSet<String> wordSet = new HashSet<String>(words);
+        final HashSet<Pair<String, String>> bigramSet = new HashSet<Pair<String,String>>();
+
+        for (int i = 0; i < words.size(); i++) {
+            final List<Integer> bigramList = bigrams.get(i);
+            if (bigramList != null) {
+                for (final Integer word1Index : bigramList) {
+                    final String word1 = words.get(word1Index);
+                    bigramSet.add(new Pair<String, String>(words.get(i), word1));
+                }
+            }
+        }
+        int token = 0;
+        do {
+            final BinaryDictionary.GetNextWordPropertyResult result =
+                    binaryDictionary.getNextWordProperty(token);
+            final WordProperty wordProperty = result.mWordProperty;
+            final String word0 = wordProperty.mWord;
+            assertEquals(UNIGRAM_FREQ, wordProperty.mProbabilityInfo.mProbability);
+            wordSet.remove(word0);
+            if (shortcuts.containsKey(word0)) {
+                assertEquals(shortcuts.get(word0).size(), wordProperty.mShortcutTargets.size());
+                final List<String> shortcutList = shortcuts.get(word0);
+                assertNotNull(wordProperty.mShortcutTargets);
+                for (final WeightedString shortcutTarget : wordProperty.mShortcutTargets) {
+                    assertTrue(shortcutList.contains(shortcutTarget.mWord));
+                    assertEquals(UNIGRAM_FREQ, shortcutTarget.getProbability());
+                    shortcutList.remove(shortcutTarget.mWord);
+                }
+                assertTrue(shortcutList.isEmpty());
+            }
+            for (int j = 0; j < wordProperty.mBigrams.size(); j++) {
+                final String word1 = wordProperty.mBigrams.get(j).mWord;
+                final Pair<String, String> bigram = new Pair<String, String>(word0, word1);
+                assertTrue(bigramSet.contains(bigram));
+                bigramSet.remove(bigram);
+            }
+            token = result.mNextToken;
+        } while (token != 0);
+        assertTrue(wordSet.isEmpty());
+        assertTrue(bigramSet.isEmpty());
+    }
 }
diff --git a/tests/src/com/android/inputmethod/latin/settings/SpacingAndPunctuationsTests.java b/tests/src/com/android/inputmethod/latin/settings/SpacingAndPunctuationsTests.java
index 424e7ff..24af094 100644
--- a/tests/src/com/android/inputmethod/latin/settings/SpacingAndPunctuationsTests.java
+++ b/tests/src/com/android/inputmethod/latin/settings/SpacingAndPunctuationsTests.java
@@ -373,29 +373,53 @@
         assertTrue(SWISS_GERMAN.mUsesGermanRules);
     }
 
-    private static void testingStandardPunctuationSuggestions(final SpacingAndPunctuations sp) {
+    private static final String[] PUNCTUATION_LABELS_LTR = {
+        "!", "?", ",", ":", ";", "\"", "(", ")", "'", "-", "/", "@", "_"
+    };
+    private static final String[] PUNCTUATION_WORDS_LTR = PUNCTUATION_LABELS_LTR;
+    private static final String[] PUNCTUATION_WORDS_HEBREW = {
+        "!", "?", ",", ":", ";", "\"", ")", "(", "'", "-", "/", "@", "_"
+    };
+    // U+061F: "؟" ARABIC QUESTION MARK
+    // U+060C: "،" ARABIC COMMA
+    // U+061B: "؛" ARABIC SEMICOLON
+    private static final String[] PUNCTUATION_LABELS_ARABIC_PERSIAN = {
+        "!", "\u061F", "\u060C", ":", "\u061B", "\"", "(", ")", "'", "-", "/", "@", "_"
+    };
+    private static final String[] PUNCTUATION_WORDS_ARABIC_PERSIAN = {
+        "!", "\u061F", "\u060C", ":", "\u061B", "\"", ")", "(", "'", "-", "/", "@", "_"
+    };
+
+    private static void testingStandardPunctuationSuggestions(final SpacingAndPunctuations sp,
+            final String[] punctuationLabels, final String[] punctuationWords) {
         final SuggestedWords suggestedWords = sp.mSuggestPuncList;
         assertFalse("typedWordValid", suggestedWords.mTypedWordValid);
         assertFalse("willAutoCorrect", suggestedWords.mWillAutoCorrect);
-        assertTrue("isPunctuationSuggestions", suggestedWords.mIsPunctuationSuggestions);
+        assertTrue("isPunctuationSuggestions", suggestedWords.isPunctuationSuggestions());
         assertFalse("isObsoleteSuggestions", suggestedWords.mIsObsoleteSuggestions);
         assertFalse("isPrediction", suggestedWords.mIsPrediction);
-        final String[] punctuations = {
-            "!", "?", ",", ":", ";", "\"", "(", ")", "'", "-", "/", "@", "_"
-        };
-        assertEquals("size", punctuations.length, suggestedWords.size());
-        for (int index = 0; index < punctuations.length; index++) {
-            assertEquals("punctuation at " + index,
-                    punctuations[index], suggestedWords.getWord(index));
+        assertEquals("size", punctuationLabels.length, suggestedWords.size());
+        for (int index = 0; index < suggestedWords.size(); index++) {
+            assertEquals("punctuation label at " + index,
+                    punctuationLabels[index], suggestedWords.getLabel(index));
+            assertEquals("punctuation word at " + index,
+                    punctuationWords[index], suggestedWords.getWord(index));
         }
     }
+
+    // TODO: Add tests for tablet as well
     public void testPunctuationSuggestions() {
-        testingStandardPunctuationSuggestions(ENGLISH);
-        testingStandardPunctuationSuggestions(FRENCH);
-        testingStandardPunctuationSuggestions(GERMAN);
-        // TODO: Should fix these RTL languages
-        testingStandardPunctuationSuggestions(ARABIC);
-        testingStandardPunctuationSuggestions(PERSIAN);
-        testingStandardPunctuationSuggestions(HEBREW);
+        testingStandardPunctuationSuggestions(ENGLISH,
+                PUNCTUATION_LABELS_LTR, PUNCTUATION_WORDS_LTR);
+        testingStandardPunctuationSuggestions(FRENCH,
+                PUNCTUATION_LABELS_LTR, PUNCTUATION_WORDS_LTR);
+        testingStandardPunctuationSuggestions(GERMAN,
+                PUNCTUATION_LABELS_LTR, PUNCTUATION_WORDS_LTR);
+        testingStandardPunctuationSuggestions(ARABIC,
+                PUNCTUATION_LABELS_ARABIC_PERSIAN, PUNCTUATION_WORDS_ARABIC_PERSIAN);
+        testingStandardPunctuationSuggestions(PERSIAN,
+                PUNCTUATION_LABELS_ARABIC_PERSIAN, PUNCTUATION_WORDS_ARABIC_PERSIAN);
+        testingStandardPunctuationSuggestions(HEBREW,
+                PUNCTUATION_LABELS_LTR, PUNCTUATION_WORDS_HEBREW);
     }
 }
diff --git a/tools/dicttool/compat/android/util/Pair.java b/tools/dicttool/compat/android/util/Pair.java
new file mode 100644
index 0000000..5bf3484
--- /dev/null
+++ b/tools/dicttool/compat/android/util/Pair.java
@@ -0,0 +1,43 @@
+/*
+ * 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 android.util;
+
+import java.util.Arrays;
+
+public class Pair<T1, T2> {
+    public final T1 mFirst;
+    public final T2 mSecond;
+
+    public Pair(final T1 first, final T2 second) {
+        mFirst = first;
+        mSecond = second;
+    }
+
+    @Override
+    public int hashCode() {
+        return Arrays.hashCode(new Object[] { mFirst, mSecond });
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) return true;
+        if (!(o instanceof Pair)) return false;
+        Pair<?, ?> p = (Pair<?, ?>)o;
+        return ((mFirst == null && p.mFirst == null) || mFirst.equals(p.mFirst))
+                && ((mSecond == null && p.mSecond == null) || mSecond.equals(p.mSecond));
+    }
+}
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java
index e571bc2..d1df81b 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java
@@ -198,7 +198,7 @@
                         System.out.println("Packaging : " + decodedSpec.describeChain());
                         System.out.println("Uncompressed size : " + decodedSpec.mFile.length());
                     }
-                    return dictDecoder.readDictionaryBinary(null, false /* deleteDictIfBroken */);
+                    return dictDecoder.readDictionaryBinary(false /* deleteDictIfBroken */);
                 }
             }
         } catch (IOException e) {
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/DictionaryMaker.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/DictionaryMaker.java
index 143bce5..80d71fc 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/DictionaryMaker.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/DictionaryMaker.java
@@ -265,7 +265,7 @@
             throws FileNotFoundException, IOException, UnsupportedFormatException {
         final File file = new File(binaryFilename);
         final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file);
-        return dictDecoder.readDictionaryBinary(null, false /* deleteDictIfBroken */);
+        return dictDecoder.readDictionaryBinary(false /* deleteDictIfBroken */);
     }
 
     /**
diff --git a/tools/dicttool/tests/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtilsTests.java b/tools/dicttool/tests/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtilsTests.java
index 69b49f0..7a4f6f7 100644
--- a/tools/dicttool/tests/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtilsTests.java
+++ b/tools/dicttool/tests/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtilsTests.java
@@ -78,9 +78,8 @@
         }
         assertEquals("Wrong decode spec", 3, decodeSpec.mDecoderSpec.size());
         final DictDecoder dictDecoder = FormatSpec.getDictDecoder(decodeSpec.mFile);
-        final FusionDictionary resultDict = dictDecoder.readDictionaryBinary(
-                null /* dict : an optional dictionary to add words to, or null */,
-                false /* deleteDictIfBroken */);
+        final FusionDictionary resultDict =
+                dictDecoder.readDictionaryBinary(false /* deleteDictIfBroken */);
         assertEquals("Wrong version attribute", VERSION, resultDict.mOptions.mAttributes.get(
                 DictionaryHeader.DICTIONARY_VERSION_KEY));
         assertEquals("Wrong locale attribute", LOCALE, resultDict.mOptions.mAttributes.get(
diff --git a/tools/make-keyboard-text/res/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.tmpl b/tools/make-keyboard-text/res/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.tmpl
index f56cfd9..7ec42ce 100644
--- a/tools/make-keyboard-text/res/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.tmpl
+++ b/tools/make-keyboard-text/res/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.tmpl
@@ -43,22 +43,36 @@
 public final class KeyboardTextsTable {
     // Name to index map.
     private static final HashMap<String, Integer> sNameToIndexesMap = CollectionUtils.newHashMap();
-    // Language to texts map.
-    private static final HashMap<String, String[]> sLanguageToTextsMap =
+    // Language to texts table map.
+    private static final HashMap<String, String[]> sLanguageToTextsTableMap =
+            CollectionUtils.newHashMap();
+    // TODO: Remove this variable after debugging.
+    // Texts table to language maps.
+    private static final HashMap<String[], String> sTextsTableToLanguageMap =
             CollectionUtils.newHashMap();
 
     public static String getText(final String name, final String[] textsTable) {
         final Integer indexObj = sNameToIndexesMap.get(name);
         if (indexObj == null) {
-            throw new RuntimeException("Unknown text name: " + name);
+            throw new RuntimeException("Unknown text name=" + name + " language="
+                    + sTextsTableToLanguageMap.get(textsTable));
         }
         final int index = indexObj;
         final String text = (index < textsTable.length) ? textsTable[index] : null;
-        return (text != null) ? text : LANGUAGE_DEFAULT[index];
+        if (text != null) {
+            return text;
+        }
+        // Sanity check.
+        if (index >= 0 && index < LANGUAGE_DEFAULT.length) {
+            return LANGUAGE_DEFAULT[index];
+        }
+        // Throw exception for debugging purpose.
+        throw new RuntimeException("Illegal index=" + index + " for name=" + name
+                + " language=" + sTextsTableToLanguageMap.get(textsTable));
     }
 
     public static String[] getTextsTable(final String language) {
-        final String[] textsTable = sLanguageToTextsMap.get(language);
+        final String[] textsTable = sLanguageToTextsTableMap.get(language);
         return textsTable != null ? textsTable : LANGUAGE_DEFAULT;
     }
 
@@ -89,8 +103,9 @@
 
         for (int i = 0; i < LANGUAGES_AND_TEXTS.length; i += 2) {
             final String language = (String)LANGUAGES_AND_TEXTS[i];
-            final String[] texts = (String[])LANGUAGES_AND_TEXTS[i + 1];
-            sLanguageToTextsMap.put(language, texts);
+            final String[] textsTable = (String[])LANGUAGES_AND_TEXTS[i + 1];
+            sLanguageToTextsTableMap.put(language, textsTable);
+            sTextsTableToLanguageMap.put(textsTable, language);
         }
     }
 }
diff --git a/tools/make-keyboard-text/res/values-ar/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-ar/donottranslate-more-keys.xml
index 9b0a059..d997685 100644
--- a/tools/make-keyboard-text/res/values-ar/donottranslate-more-keys.xml
+++ b/tools/make-keyboard-text/res/values-ar/donottranslate-more-keys.xml
@@ -75,7 +75,7 @@
     <!-- U+066A: "٪" ARABIC PERCENT SIGN -->
     <string name="keylabel_for_symbols_percent">&#x066A;</string>
     <!-- U+00BF: "¿" INVERTED QUESTION MARK -->
-    <string name="more_keys_for_question">\?,&#x00BF;</string>
+    <string name="more_keys_for_question">?,&#x00BF;</string>
     <string name="more_keys_for_symbols_semicolon">;</string>
     <!-- U+2030: "‰" PER MILLE SIGN -->
     <string name="more_keys_for_symbols_percent">\\%,&#x2030;</string>
@@ -85,7 +85,7 @@
     <string name="keylabel_for_tablet_comma">"&#x060C;"</string>
     <string name="keyhintlabel_for_tablet_comma">"&#x061F;"</string>
     <string name="more_keys_for_tablet_comma">"!fixedColumnOrder!4,:,!,&#x061F;,&#x061B;,-,/,\",\'"</string>
-    <string name="more_keys_for_punctuation">"!fixedColumnOrder!8,\",\',#,-,:,!,&#x060C;,&#x061F;,\@,&amp;,\\%,+,&#x061B;,/,(|),)|("</string>
+    <string name="more_keys_for_punctuation">"!fixedColumnOrder!8,\",\',#,-,:,!,&#x060C;,&#x061F;,@,&amp;,\\%,+,&#x061B;,/,(|),)|("</string>
     <!-- U+266A: "♪" EIGHTH NOTE -->
     <string name="more_keys_for_bullet">&#x266A;</string>
     <!-- U+2605: "★" BLACK STAR
diff --git a/tools/make-keyboard-text/res/values-ca/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-ca/donottranslate-more-keys.xml
index f63e85b..8865a60 100644
--- a/tools/make-keyboard-text/res/values-ca/donottranslate-more-keys.xml
+++ b/tools/make-keyboard-text/res/values-ca/donottranslate-more-keys.xml
@@ -71,8 +71,8 @@
          U+0142: "ł" LATIN SMALL LETTER L WITH STROKE -->
     <string name="more_keys_for_l">l&#x00B7;l,&#x0142;</string>
     <!-- U+00B7: "·" MIDDLE DOT -->
-    <string name="more_keys_for_punctuation">"!fixedColumnOrder!9,;,/,(,),#,&#x00B7;,!,\\,,\?,&amp;,\\%,+,\",-,:,',\@"</string>
-    <string name="more_keys_for_tablet_punctuation">"!fixedColumnOrder!8,;,/,(,),#,&#x00B7;,',\\,,&amp;,\\%,+,\",-,:,\@"</string>
+    <string name="more_keys_for_punctuation">"!fixedColumnOrder!9,;,/,(,),#,&#x00B7;,!,\\,,?,&amp;,\\%,+,\",-,:,',@"</string>
+    <string name="more_keys_for_tablet_punctuation">"!fixedColumnOrder!8,;,/,(,),#,&#x00B7;,',\\,,&amp;,\\%,+,\",-,:,@"</string>
     <!-- U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA -->
     <string name="keylabel_for_spanish_row2_10">&#x00E7;</string>
 </resources>
diff --git a/tools/make-keyboard-text/res/values-es/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-es/donottranslate-more-keys.xml
index f4fe7f7..453d5c1 100644
--- a/tools/make-keyboard-text/res/values-es/donottranslate-more-keys.xml
+++ b/tools/make-keyboard-text/res/values-es/donottranslate-more-keys.xml
@@ -69,5 +69,5 @@
     <string name="more_keys_for_c">&#x00E7;,&#x0107;,&#x010D;</string>
     <!-- U+00A1: "¡" INVERTED EXCLAMATION MARK
          U+00BF: "¿" INVERTED QUESTION MARK -->
-    <string name="more_keys_for_punctuation">"!fixedColumnOrder!9,&#x00A1;,;,/,(,),#,!,\\,,\?,&#x00BF;,&amp;,\\%,+,\",-,:,',\@"</string>
+    <string name="more_keys_for_punctuation">"!fixedColumnOrder!9,&#x00A1;,;,/,(,),#,!,\\,,?,&#x00BF;,&amp;,\\%,+,\",-,:,',@"</string>
 </resources>
diff --git a/tools/make-keyboard-text/res/values-fa/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-fa/donottranslate-more-keys.xml
index 3f12784..6ea0433 100644
--- a/tools/make-keyboard-text/res/values-fa/donottranslate-more-keys.xml
+++ b/tools/make-keyboard-text/res/values-fa/donottranslate-more-keys.xml
@@ -75,7 +75,7 @@
     <!-- U+066A: "٪" ARABIC PERCENT SIGN -->
     <string name="keylabel_for_symbols_percent">&#x066A;</string>
     <!-- U+00BF: "¿" INVERTED QUESTION MARK -->
-    <string name="more_keys_for_question">\?,&#x00BF;</string>
+    <string name="more_keys_for_question">?,&#x00BF;</string>
     <string name="more_keys_for_symbols_semicolon">;</string>
     <!-- U+2030: "‰" PER MILLE SIGN -->
     <string name="more_keys_for_symbols_percent">\\%,&#x2030;</string>
@@ -92,7 +92,7 @@
     <!-- U+061F: "؟" ARABIC QUESTION MARK
          U+060C: "،" ARABIC COMMA
          U+061B: "؛" ARABIC SEMICOLON -->
-    <string name="more_keys_for_punctuation">"!fixedColumnOrder!8,\",\',#,-,:,!,&#x060C;,&#x061F;,\@,&amp;,\\%,+,&#x061B;,/,!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis"</string>
+    <string name="more_keys_for_punctuation">"!fixedColumnOrder!8,\",\',#,-,:,!,&#x060C;,&#x061F;,@,&amp;,\\%,+,&#x061B;,/,!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis"</string>
     <!-- U+266A: "♪" EIGHTH NOTE -->
     <string name="more_keys_for_bullet">&#x266A;</string>
     <!-- U+2605: "★" BLACK STAR
diff --git a/tools/make-keyboard-text/res/values-hi/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-hi/donottranslate-more-keys.xml
index b0d010f..de10a01 100644
--- a/tools/make-keyboard-text/res/values-hi/donottranslate-more-keys.xml
+++ b/tools/make-keyboard-text/res/values-hi/donottranslate-more-keys.xml
@@ -44,7 +44,7 @@
     <!-- U+0966: "०" DEVANAGARI DIGIT ZERO -->
     <string name="keylabel_for_symbols_0">&#x0966;</string>
     <!-- Label for "switch to symbols" key. -->
-    <string name="label_to_symbol_key">\?&#x0967;&#x0968;&#x0969;</string>
+    <string name="label_to_symbol_key">?&#x0967;&#x0968;&#x0969;</string>
     <!-- Label for "switch to symbols with microphone" key. This string shouldn't include the "mic"
          part because it'll be appended by the code. -->
     <string name="label_to_symbol_with_microphone_key">&#x0967;&#x0968;&#x0969;</string>
diff --git a/tools/make-keyboard-text/res/values-ne-rNP/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-ne-rNP/donottranslate-more-keys.xml
index 9205e53..e92a87e 100644
--- a/tools/make-keyboard-text/res/values-ne-rNP/donottranslate-more-keys.xml
+++ b/tools/make-keyboard-text/res/values-ne-rNP/donottranslate-more-keys.xml
@@ -44,7 +44,7 @@
     <!-- U+0966: "०" DEVANAGARI DIGIT ZERO -->
     <string name="keylabel_for_symbols_0">&#x0966;</string>
     <!-- Label for "switch to symbols" key. -->
-    <string name="label_to_symbol_key">\?&#x0967;&#x0968;&#x0969;</string>
+    <string name="label_to_symbol_key">?&#x0967;&#x0968;&#x0969;</string>
     <!-- Label for "switch to symbols with microphone" key. This string shouldn't include the "mic"
          part because it'll be appended by the code. -->
     <string name="label_to_symbol_with_microphone_key">&#x0967;&#x0968;&#x0969;</string>
diff --git a/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml
index 8d3d61c..9cdcb46 100644
--- a/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml
+++ b/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml
@@ -83,8 +83,8 @@
     <string name="more_keys_for_currency_dollar">&#x00A2;,&#x00A3;,&#x20AC;,&#x00A5;,&#x20B1;</string>
     <string name="keylabel_for_currency">$</string>
     <string name="more_keys_for_currency">$,&#x00A2;,&#x20AC;,&#x00A3;,&#x00A5;,&#x20B1;</string>
-    <string name="more_keys_for_punctuation">"!fixedColumnOrder!8,;,/,!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis,#,!,\\,,\?,&amp;,\\%,+,\",-,:,',\@"</string>
-    <string name="more_keys_for_tablet_punctuation">"!fixedColumnOrder!7,;,/,!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis,#,',\\,,&amp;,\\%,+,\",-,:,\@"</string>
+    <string name="more_keys_for_punctuation">"!fixedColumnOrder!8,;,/,!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis,#,!,\\,,?,&amp;,\\%,+,\",-,:,',@"</string>
+    <string name="more_keys_for_tablet_punctuation">"!fixedColumnOrder!7,;,/,!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis,#,',\\,,&amp;,\\%,+,\",-,:,@"</string>
     <!-- U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE -->
     <string name="keylabel_for_spanish_row2_10">&#x00F1;</string>
     <!-- U+2020: "†" DAGGER
@@ -115,7 +115,7 @@
     <string name="keylabel_for_symbols_9">9</string>
     <string name="keylabel_for_symbols_0">0</string>
     <!-- Label for "switch to symbols" key. -->
-    <string name="label_to_symbol_key">\?123</string>
+    <string name="label_to_symbol_key">?123</string>
     <!-- Label for "switch to symbols with microphone" key. This string shouldn't include the "mic"
          part because it'll be appended by the code. -->
     <string name="label_to_symbol_with_microphone_key">123</string>
@@ -189,7 +189,7 @@
     <string name="keylabel_for_tablet_period">.</string>
     <string name="keyhintlabel_for_tablet_period"></string>
     <string name="more_keys_for_tablet_period">!text/more_keys_for_tablet_punctuation</string>
-    <string name="keylabel_for_symbols_question">\?</string>
+    <string name="keylabel_for_symbols_question">?</string>
     <string name="keylabel_for_symbols_semicolon">;</string>
     <string name="keylabel_for_symbols_percent">%</string>
     <!-- U+00A1: "¡" INVERTED EXCLAMATION MARK -->
@@ -205,17 +205,15 @@
     <string name="keylabel_for_w">w</string>
     <string name="keylabel_for_y">y</string>
     <string name="keylabel_for_x">x</string>
-    <string name="more_keys_for_am_pm">!fixedColumnOrder!2,!hasLabels!,\@string/label_time_am,\@string/label_time_pm</string>
+    <string name="more_keys_for_am_pm">!fixedColumnOrder!2,!hasLabels!,!text/label_time_am,!text/label_time_pm</string>
     <string name="settings_as_more_key">!icon/settings_key|!code/key_settings</string>
     <string name="shortcut_as_more_key">!icon/shortcut_key|!code/key_shortcut</string>
-    <string name="action_next_as_more_key">!hasLabels!,\@string/label_next_key|!code/key_action_next</string>
-    <string name="action_previous_as_more_key">!hasLabels!,\@string/label_previous_key|!code/key_action_previous</string>
+    <string name="action_next_as_more_key">!hasLabels!,!text/label_next_key|!code/key_action_next</string>
+    <string name="action_previous_as_more_key">!hasLabels!,!text/label_previous_key|!code/key_action_previous</string>
     <!-- Label for "switch to more symbol" modifier key ("= \ <"). Must be short to fit on key! -->
     <string name="label_to_more_symbol_key">= \\\\ &lt;</string>
     <!-- Label for "switch to more symbol" modifier key on tablets.  Must be short to fit on key! -->
     <string name="label_to_more_symbol_for_tablet_key">~ [ &lt;</string>
-    <!-- Label for "Tab" key.  Must be short to fit on key! -->
-    <string name="label_tab_key">Tab</string>
     <!-- Label for "switch to phone numeric" key.  Must be short to fit on key! -->
     <string name="label_to_phone_numeric_key">123</string>
     <!-- Label for "switch to phone symbols" key.  Must be short to fit on key! -->
diff --git a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MoreKeysResources.java b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MoreKeysResources.java
index 872ef19..e9d6c86 100644
--- a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MoreKeysResources.java
+++ b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MoreKeysResources.java
@@ -29,6 +29,7 @@
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.jar.JarFile;
+import java.util.regex.Pattern;
 
 public class MoreKeysResources {
     private static final String TEXT_RESOURCE_NAME = "donottranslate-more-keys.xml";
@@ -287,23 +288,7 @@
                 sb.append(String.format("\\u%04X", (int)c));
             }
         }
-        return replaceIncompatibleEscape(sb.toString());
-    }
-
-    private static String replaceIncompatibleEscape(final String text) {
-        String t = text;
-        t = replaceAll(t, "\\?", "?");
-        t = replaceAll(t, "\\@", "@");
-        t = replaceAll(t, "@string/", "!text/");
-        return t;
-    }
-
-    private static String replaceAll(final String text, final String target, final String replace) {
-        String t = text;
-        while (t.indexOf(target) >= 0) {
-            t = t.replace(target, replace);
-        }
-        return t;
+        return sb.toString();
     }
 
     private static void close(final Closeable stream) {