Merge "Use C++ template for min/max"
diff --git a/java/res/values-af/strings.xml b/java/res/values-af/strings.xml
index 400dbcc..081f604 100644
--- a/java/res/values-af/strings.xml
+++ b/java/res/values-af/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Steminvoering"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Glimlag-gesiggie"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Punt"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Steminvoering"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Steminvoering vir jou taal word nie tans ondersteun nie, maar werk wel in Engels."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Steminvoer gebruik Google se spraakherkenning. "<a href="http://m.google.com/privacy">"Die Mobiel-privaatheidsbeleid"</a>" is van toepassing."</string>
diff --git a/java/res/values-am/strings.xml b/java/res/values-am/strings.xml
index f3af078..b45e1c3 100644
--- a/java/res/values-am/strings.xml
+++ b/java/res/values-am/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"የድምፅ ግቤ ት"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"የፈገግታ ፊት"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"ተመለስ"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"ነጥብ"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"የድምፅ ግቤ ት"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"የድምፅ ግቤት በአሁኑ ጊዜ ለእርስዎን ቋንቋ አይደግፍም፣ ግን በእንግሊዘኛ ይሰራል።"</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"የድምፅ ግቤት የGoogleን ንግግር ለይቶ ማወቂያ ይጠቀማል።"<a href="http://m.google.com/privacy">"የተንቀሳቃሽ ስልክ ግላዊ ፖሊሲ"</a>" ይተገበራል።"</string>
diff --git a/java/res/values-ar/strings.xml b/java/res/values-ar/strings.xml
index 30aa215..80d4b0d 100644
--- a/java/res/values-ar/strings.xml
+++ b/java/res/values-ar/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"إدخال صوتي"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"وجه مبتسم"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"رجوع"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"نقطة"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"الإدخال الصوتي"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"الإدخال الصوتي غير معتمد حاليًا للغتك، ولكنه يعمل باللغة الإنجليزية."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"يستخدم الإدخال الصوتي خاصية التعرف على الكلام من Google. تنطبق "<a href="http://m.google.com/privacy">"سياسة خصوصية الجوال"</a>"."</string>
diff --git a/java/res/values-be/strings.xml b/java/res/values-be/strings.xml
index 19290b5..6682128 100644
--- a/java/res/values-be/strings.xml
+++ b/java/res/values-be/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Галасавы ўвод"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Смайлік"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Увод"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Кропка"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Галасавы ўвод"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Галасавы ўвод пакуль не падтрымліваецца для вашай мовы, але працуе на англійскай мове."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Галасавы набор выкарыстоўвае распазнанне гаворкі Google. Ужываецца "<a href="http://m.google.com/privacy">"палiтыка прыватнасцi для мабiльных прылад"</a>"."</string>
diff --git a/java/res/values-bg/strings.xml b/java/res/values-bg/strings.xml
index 6a39af2..5a3b60f 100644
--- a/java/res/values-bg/strings.xml
+++ b/java/res/values-bg/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Гласово въвеждане"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Усмивка"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Точка"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Гласово въвеждане"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"За вашия език понастоящем не се поддържа гласово въвеждане, но можете да го използвате на английски."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Гласовото въвеждане използва функцията на Google за разпознаване на говор. В сила е "<a href="http://m.google.com/privacy">"Декларацията за поверителност за мобилни устройства"</a>"."</string>
diff --git a/java/res/values-ca/strings.xml b/java/res/values-ca/strings.xml
index a8f77ca..149867f 100644
--- a/java/res/values-ca/strings.xml
+++ b/java/res/values-ca/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Entrada de veu"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Cara somrient"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Retorn"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Punt"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Entrada de veu"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Actualment, l\'entrada de veu no és compatible amb el vostre idioma, però funciona en anglès."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"L\'entrada de veu utilitza el reconeixement de veu de Google. S\'hi aplica la "<a href="http://m.google.com/privacy">"Política de privadesa de Google per a mòbils"</a>"."</string>
diff --git a/java/res/values-cs/strings.xml b/java/res/values-cs/strings.xml
index e03ffe8..6b7842c 100644
--- a/java/res/values-cs/strings.xml
+++ b/java/res/values-cs/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Hlasový vstup"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Smajlík"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Tečka"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Hlasový vstup"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Pro váš jazyk aktuálně není hlasový vstup podporován, ale funguje v angličtině."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Hlasový vstup používá rozpoznávání hlasu Google a vztahují se na něj "<a href="http://m.google.com/privacy">"Zásady ochrany osobních údajů pro mobilní služby"</a>"."</string>
diff --git a/java/res/values-da/strings.xml b/java/res/values-da/strings.xml
index b4fc35e..a046d61 100644
--- a/java/res/values-da/strings.xml
+++ b/java/res/values-da/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Stemmeinput"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Smiley"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Tilbage"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Punktum"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Stemmeinput"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Stemmeinput understøttes i øjeblikket ikke for dit sprog, men fungerer på engelsk."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Stemmeinput anvender Googles stemmegenkendelse. "<a href="http://m.google.com/privacy">"Fortrolighedspolitikken for mobilenheder"</a>" gælder."</string>
diff --git a/java/res/values-de/strings.xml b/java/res/values-de/strings.xml
index 2e4dab1..eb0a3fb 100644
--- a/java/res/values-de/strings.xml
+++ b/java/res/values-de/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Spracheingabe"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Smiley"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Eingabe"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Aufzählungspunkt"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Spracheingabe"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Spracheingaben werden zurzeit nicht für Ihre Sprache unterstützt, funktionieren jedoch in Englisch."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Die Spracheingabe verwendet die Spracherkennung von Google. Es gelten die "<a href="http://m.google.com/privacy">"Google Mobile-Datenschutzbestimmungen"</a>"."</string>
diff --git a/java/res/values-el/strings.xml b/java/res/values-el/strings.xml
index 1ef69c0..9ca1c4e 100644
--- a/java/res/values-el/strings.xml
+++ b/java/res/values-el/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Μικρόφωνο"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Smiley"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Πλήκτρο Return"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Κουκκίδα"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Φωνητική είσοδος"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Η φωνητική είσοδος δεν υποστηρίζεται αυτή τη στιγμή για τη γλώσσα σας, ωστόσο λειτουργεί στα Αγγλικά."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Οι φωνητικές εντολές χρησιμοποιούν την τεχνολογία αναγνώρισης φωνής της Google. Ισχύει "<a href="http://m.google.com/privacy">"η Πολιτική Απορρήτου για κινητά"</a>"."</string>
diff --git a/java/res/values-en-rGB/strings.xml b/java/res/values-en-rGB/strings.xml
index 708cd6b..9e0f150 100644
--- a/java/res/values-en-rGB/strings.xml
+++ b/java/res/values-en-rGB/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Voice input"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Smiley face"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Dot"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Voice input"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Voice input is not currently supported for your language, but does work in English."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Voice input uses Google\'s speech recognition. "<a href="http://m.google.com/privacy">"The Mobile Privacy Policy"</a>" applies."</string>
diff --git a/java/res/values-es-rUS/strings.xml b/java/res/values-es-rUS/strings.xml
index 11403eb..f4c2b45 100644
--- a/java/res/values-es-rUS/strings.xml
+++ b/java/res/values-es-rUS/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Entrada de voz"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Carita sonriente"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Volver"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Punto"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Entrada por voz"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"La entrada por voz no está admitida en tu idioma, pero sí funciona en inglés."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"La entrada de voz usa el reconocimiento de voz de Google. "<a href="http://m.google.com/privacy">"Se aplica la política de privacidad para"</a>" celulares."</string>
diff --git a/java/res/values-es/strings.xml b/java/res/values-es/strings.xml
index e2fab89..675a426 100644
--- a/java/res/values-es/strings.xml
+++ b/java/res/values-es/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Entrada de voz"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Emoticono"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Tecla Intro"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Punto"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Introducción de voz"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Actualmente la introducción de voz no está disponible en tu idioma, pero se puede utilizar en inglés."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"La entrada de voz utiliza el reconocimiento de voz de Google. Se aplica la "<a href="http://m.google.com/privacy">"Política de privacidad de Google para móviles"</a>"."</string>
diff --git a/java/res/values-et/strings.xml b/java/res/values-et/strings.xml
index c0a7c08..84f4b7f 100644
--- a/java/res/values-et/strings.xml
+++ b/java/res/values-et/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Kõnesisend"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Naerunägu"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Tagasi"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Punkt"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Kõnesisend"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Kõnesisendit ei toetata praegu teie keeles, kuid see töötab inglise keeles."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Kõnesisend kasutab Google\'i kõnetuvastust. Kehtivad "<a href="http://m.google.com/privacy">"Mobile\'i privaatsuseeskirjad"</a>"."</string>
diff --git a/java/res/values-fa/strings.xml b/java/res/values-fa/strings.xml
index 3bf72cb..05f3a7a 100644
--- a/java/res/values-fa/strings.xml
+++ b/java/res/values-fa/strings.xml
@@ -93,6 +93,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"ورودی صدا"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"صورت متبسم"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"نقطه"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"ورودی صوتی"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"ورودی صوتی در حال حاضر برای زبان شما پشتیبانی نمی شود اما برای زبان انگلیسی فعال است."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"ورودی صوتی از تشخیص صدای Google استفاده می کند. "<a href="http://m.google.com/privacy">"خط مشی رازداری Mobile "</a>" اعمال می شود."</string>
diff --git a/java/res/values-fi/strings.xml b/java/res/values-fi/strings.xml
index afa0ef6..f77604d 100644
--- a/java/res/values-fi/strings.xml
+++ b/java/res/values-fi/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Puheohjaus"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Hymiö"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Piste"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Äänisyöte"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Äänisyötettä ei vielä tueta kielelläsi, mutta voit käyttää sitä englanniksi."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Äänisyöte käyttää Googlen puheentunnistusta. "<a href="http://m.google.com/privacy">"Mobile-tietosuojakäytäntö"</a>" on voimassa."</string>
diff --git a/java/res/values-fr/strings.xml b/java/res/values-fr/strings.xml
index c52a92b..4eaac40 100644
--- a/java/res/values-fr/strings.xml
+++ b/java/res/values-fr/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Saisie vocale"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Émoticône"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Entrée"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Point"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Saisie vocale"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"La saisie vocale n\'est pas encore prise en charge pour votre langue, mais elle fonctionne en anglais."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"La saisie vocale fait appel à la reconnaissance vocale de Google. Les "<a href="http://m.google.com/privacy">"Règles de confidentialité Google Mobile"</a>" s\'appliquent."</string>
diff --git a/java/res/values-hi/strings.xml b/java/res/values-hi/strings.xml
index 924b208..229bb8a 100644
--- a/java/res/values-hi/strings.xml
+++ b/java/res/values-hi/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"ध्‍वनि इनपुट"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"मुस्कुराता चेहरा"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"रिटर्न"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"बिंदु"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"ध्‍वनि इनपुट"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"ध्‍वनि इनपुट आपकी भाषा के लिए अभी समर्थित नहीं है, पर अंग्रेज़ी में कार्य करता है."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"ध्‍वनि इनपुट Google की वाक् पहचान का उपयोग करता है. "<a href="http://m.google.com/privacy">"मोबाइल गोपनीयता नीति"</a>" लागू होती है."</string>
diff --git a/java/res/values-hr/strings.xml b/java/res/values-hr/strings.xml
index a5b3c48..8fa730f 100644
--- a/java/res/values-hr/strings.xml
+++ b/java/res/values-hr/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Glasovni unos"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Smješko"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Točka"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Glasovni ulaz"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Vaš jezik trenutno nije podržan za glasovni unos, ali radi za engleski."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Glasovni unos upotrebljava Googleovo prepoznavanje govora. Primjenjuju se "<a href="http://m.google.com/privacy">"Pravila o privatnosti za uslugu Mobile"</a>"."</string>
diff --git a/java/res/values-hu/strings.xml b/java/res/values-hu/strings.xml
index dea39f4..f397e0b 100644
--- a/java/res/values-hu/strings.xml
+++ b/java/res/values-hu/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Hangbevitel"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Mosolygós arc"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Pont"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Hangbevitel"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"A hangbevitel szolgáltatás jelenleg nem támogatja az Ön nyelvét, ám angolul működik."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"A hangbevitel a Google beszédfelismerő technológiáját használja, amelyre a "<a href="http://m.google.com/privacy">"Mobil adatvédelmi irányelvek"</a>" érvényesek."</string>
diff --git a/java/res/values-in/strings.xml b/java/res/values-in/strings.xml
index 38bbf41..6096cc1 100644
--- a/java/res/values-in/strings.xml
+++ b/java/res/values-in/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Masukan suara"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Wajah tersenyum"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Kembali"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Titik"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Masukan suara"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Masukan suara saat ini tidak didukung untuk bahasa Anda, tetapi bekerja dalam Bahasa Inggris."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Masukan suara menggunakan pengenalan ucapan Google. "<a href="http://m.google.com/privacy">"Kebijakan Privasi Seluler"</a>" berlaku."</string>
diff --git a/java/res/values-it/strings.xml b/java/res/values-it/strings.xml
index acb2441..6c34bee 100644
--- a/java/res/values-it/strings.xml
+++ b/java/res/values-it/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Input vocale"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Smile"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Invio"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Pallino"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Comandi vocali"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"I comandi vocali non sono attualmente supportati per la tua lingua ma funzionano in inglese."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"L\'input vocale utilizza il riconoscimento vocale di Google. Sono valide le "<a href="http://m.google.com/privacy">"norme sulla privacy di Google Mobile"</a>"."</string>
diff --git a/java/res/values-iw/strings.xml b/java/res/values-iw/strings.xml
index 0a9ae30..dea0b41 100644
--- a/java/res/values-iw/strings.xml
+++ b/java/res/values-iw/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"קלט קולי"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"פרצוף סמיילי"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"חזור"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"נקודה"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"קלט קולי"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"קלט קולי אינו נתמך בשלב זה בשפתך, אך הוא פועל באנגלית."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"קלט קולי משתמש בזיהוי דיבור של Google.‏ "<a href="http://m.google.com/privacy">"מדיניות הפרטיות של \'Google לנייד\'"</a>" חלה במקרה זה."</string>
diff --git a/java/res/values-ja/strings.xml b/java/res/values-ja/strings.xml
index 08b51c2..d6f967a 100644
--- a/java/res/values-ja/strings.xml
+++ b/java/res/values-ja/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"音声入力"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"顔文字"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"中点"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"音声入力"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"音声入力は現在英語には対応していますが、日本語には対応していません。"</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"音声入力ではGoogleの音声認識技術を利用します。"<a href="http://m.google.com/privacy">"モバイルプライバシーポリシー"</a>"が適用されます。"</string>
diff --git a/java/res/values-ko/strings.xml b/java/res/values-ko/strings.xml
index cbc0780..7382a0c 100644
--- a/java/res/values-ko/strings.xml
+++ b/java/res/values-ko/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"음성 입력"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"웃는 얼굴"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"리턴 키"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"점"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"음성 입력"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"음성 입력은 현재 자국어로 지원되지 않으며 영어로 작동됩니다."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"음성 입력에서는 Google의 음성 인식 기능을 사용합니다. "<a href="http://m.google.com/privacy">"모바일 개인정보취급방침"</a>"이 적용됩니다."</string>
diff --git a/java/res/values-lt/strings.xml b/java/res/values-lt/strings.xml
index 53f834d..646548d 100644
--- a/java/res/values-lt/strings.xml
+++ b/java/res/values-lt/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Įvestis balsu"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Šypsenėlė"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Grįžti"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Taškas"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Balso įvestis"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Šiuo metu balso įvestis jūsų kompiuteryje nepalaikoma, bet ji veikia anglų k."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Balso įvesčiai naudojamas „Google“ kalbos atpažinimas. Taikoma "<a href="http://m.google.com/privacy">"privatumo politika mobiliesiems"</a>"."</string>
diff --git a/java/res/values-lv/strings.xml b/java/res/values-lv/strings.xml
index 8711c08..b3406c3 100644
--- a/java/res/values-lv/strings.xml
+++ b/java/res/values-lv/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Balss ievade"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Smaidoša seja"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Ievadīšanas taustiņš"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Punkts"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Balss ievade"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Balss ievade jūsu valodā pašlaik netiek atbalstīta, taču tā ir pieejama angļu valodā."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Balss ievadei tiek izmantota Google runas atpazīšanas funkcija. Uz šīs funkcijas lietošanu attiecas "<a href="http://m.google.com/privacy">"mobilo sakaru ierīču lietošanas konfidencialitātes politika"</a>"."</string>
diff --git a/java/res/values-ms/strings.xml b/java/res/values-ms/strings.xml
index ecd9730..2a9f516 100644
--- a/java/res/values-ms/strings.xml
+++ b/java/res/values-ms/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Input suara"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Muka senyum"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Titik"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Input suara"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Input suara tidak disokong untuk bahasa anda pada masa ini tetapi ia berfungsi dalam bahasa Inggeris."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Input suara menggunakan pengecaman pertuturan Google. "<a href="http://m.google.com/privacy">"Dasar Privasi Mudah Alih"</a>" digunakan."</string>
diff --git a/java/res/values-nb/strings.xml b/java/res/values-nb/strings.xml
index 415ec7f..413c7ae 100644
--- a/java/res/values-nb/strings.xml
+++ b/java/res/values-nb/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Taleinndata"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Smilefjes"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Prikk"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Stemmedata"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Stemmedata håndteres foreløpig ikke på ditt språk, men fungerer på engelsk."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Google Voice bruker Googles talegjenkjenning. "<a href="http://m.google.com/privacy">"Personvernreglene for mobil"</a>" gjelder."</string>
diff --git a/java/res/values-nl/strings.xml b/java/res/values-nl/strings.xml
index 6d71199..ba6dd40 100644
--- a/java/res/values-nl/strings.xml
+++ b/java/res/values-nl/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Spraakinvoer"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Smiley-gezichtje"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Stip"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Spraakinvoer"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Spraakinvoer wordt momenteel niet ondersteund in uw taal, maar is wel beschikbaar in het Engels."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Spraakinvoer maakt gebruik van de spraakherkenning van Google. Het "<a href="http://m.google.com/privacy">"Privacybeleid van Google Mobile"</a>" is van toepassing."</string>
diff --git a/java/res/values-pl/strings.xml b/java/res/values-pl/strings.xml
index 395241e..3ad3831 100644
--- a/java/res/values-pl/strings.xml
+++ b/java/res/values-pl/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Wprowadzanie głosowe"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Uśmiechnięta buźka"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Punkt"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Wprowadzanie głosowe"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Wprowadzanie głosowe obecnie nie jest obsługiwane w Twoim języku, ale działa w języku angielskim."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Funkcja wprowadzania głosowego wykorzystuje mechanizm rozpoznawania mowy. Obowiązuje "<a href="http://m.google.com/privacy">"Polityka prywatności w usługach mobilnych"</a>"."</string>
diff --git a/java/res/values-pt-rPT/strings.xml b/java/res/values-pt-rPT/strings.xml
index 6301e7a..ae7443a 100644
--- a/java/res/values-pt-rPT/strings.xml
+++ b/java/res/values-pt-rPT/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Entrada de voz"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Cara sorridente"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Ponto"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Entrada de voz"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Actualmente, a entrada de voz não é suportada para o seu idioma, mas funciona em inglês."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"A entrada de voz utiliza o reconhecimento de voz da Google. É aplicável a "<a href="http://m.google.com/privacy">"Política de privacidade do Google Mobile"</a>"."</string>
diff --git a/java/res/values-pt/strings.xml b/java/res/values-pt/strings.xml
index e71fe89..16003f6 100644
--- a/java/res/values-pt/strings.xml
+++ b/java/res/values-pt/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Entrada de voz"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Carinha sorridente"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Voltar"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Ponto"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Entrada de voz"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"A entrada de voz não é suportada no momento para o seu idioma, mas funciona em inglês."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"A entrada de texto por voz usa o reconhecimento de voz do Google. "<a href="http://m.google.com/privacy">"A política de privacidade para celulares"</a>" é aplicada."</string>
diff --git a/java/res/values-rm/strings.xml b/java/res/values-rm/strings.xml
index 2900339..57173af 100644
--- a/java/res/values-rm/strings.xml
+++ b/java/res/values-rm/strings.xml
@@ -146,6 +146,8 @@
     <skip />
     <!-- no translation found for spoken_description_return (8178083177238315647) -->
     <skip />
+    <!-- no translation found for spoken_description_dot (40711082435231673) -->
+    <skip />
     <string name="voice_warning_title" msgid="4419354150908395008">"Cumonds vocals"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"\"Cumonds vocals en Vossa lingua na vegnan actualmain betg sustegnids, ma la funcziun è disponibla per englais.\""</string>
     <!-- no translation found for voice_warning_may_not_understand (5596289095878251072) -->
diff --git a/java/res/values-ro/strings.xml b/java/res/values-ro/strings.xml
index 91743e6..3971dc8 100644
--- a/java/res/values-ro/strings.xml
+++ b/java/res/values-ro/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Intrare vocală"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Faţă zâmbitoare"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Punct"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Intrare voce"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Intrarea vocală nu este acceptată în prezent pentru limba dvs., însă funcţionează în limba engleză."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Intrarea vocală utilizează funcţia Google de recunoaştere vocală. Se aplică "<a href="http://m.google.com/privacy">"Politica de confidenţialitate Google Mobil"</a>"."</string>
diff --git a/java/res/values-ru/strings.xml b/java/res/values-ru/strings.xml
index 0708579..62f84d4 100644
--- a/java/res/values-ru/strings.xml
+++ b/java/res/values-ru/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Голосовой ввод"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Смайлик"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Клавиша \"Ввод\""</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Точка"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Голосовой ввод"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"В настоящее время функция голосового ввода не поддерживает ваш язык, но вы можете пользоваться ей на английском."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Голосовой ввод использует алгоритмы распознавания речи Google. Действует "<a href="http://m.google.com/privacy">"политика конфиденциальности для мобильных устройств"</a>"."</string>
diff --git a/java/res/values-sk/strings.xml b/java/res/values-sk/strings.xml
index 48987c7..188c3b6 100644
--- a/java/res/values-sk/strings.xml
+++ b/java/res/values-sk/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Hlasový vstup"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Usmiata tvár"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Bodka"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Hlasový vstup"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Pre váš jazyk aktuálne nie je hlasový vstup podporovaný, ale funguje v angličtine."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Hlasový vstup používa rozpoznávanie hlasu Google. Na používanie hlasového vstupu sa vzťahujú "<a href="http://m.google.com/privacy">"Pravidlá ochrany osobných údajov pre mobilné služby"</a>"."</string>
diff --git a/java/res/values-sl/strings.xml b/java/res/values-sl/strings.xml
index 055823c..cea30bb 100644
--- a/java/res/values-sl/strings.xml
+++ b/java/res/values-sl/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Glasovni vnos"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Smeško"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Vračalka"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Pika"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Glasovni vnos"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Glasovni vnos trenutno ni podprt v vašem jeziku, deluje pa v angleščini."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Glasovni vnos uporablja Googlovo prepoznavanje govora. Zanj velja "<a href="http://m.google.com/privacy">"pravilnik o zasebnosti za mobilne naprave"</a>"."</string>
diff --git a/java/res/values-sr/strings.xml b/java/res/values-sr/strings.xml
index 835c6c2..b66bf05 100644
--- a/java/res/values-sr/strings.xml
+++ b/java/res/values-sr/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Гласовни унос"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Смајли"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Тачка"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Гласовни унос"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Гласовни унос тренутно није подржан за ваш језик, али функционише на енглеском."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Гласовни унос користи Google-ову функцију за препознавање гласа. Примењује се "<a href="http://m.google.com/privacy">"политика приватности за мобилне уређаје"</a>"."</string>
diff --git a/java/res/values-sv/strings.xml b/java/res/values-sv/strings.xml
index 57ab263..06f706a 100644
--- a/java/res/values-sv/strings.xml
+++ b/java/res/values-sv/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Röstinmatning"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Uttryckssymbol"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Retur"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Punkt"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Röstindata"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Röstindata stöds inte på ditt språk än, men tjänsten fungerar på engelska."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Röstinmatning använder sig av Googles tjänst för taligenkänning. "<a href="http://m.google.com/privacy">"Sekretesspolicyn för mobila enheter"</a>" gäller."</string>
diff --git a/java/res/values-sw/strings.xml b/java/res/values-sw/strings.xml
index 39b9ca3..c50c910 100644
--- a/java/res/values-sw/strings.xml
+++ b/java/res/values-sw/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Uingizaji sauti"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Uso wenye tabasamu"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Rudi"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Nukta"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Uingizaji wa sauti"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Uingizaji wa sauti hauhimiliwi kwa lugha yako kwa sasa, lakini inafanya kazi kwa Kiingereza."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Uingizaji wa sauti hutumia utambuaji wa usemi wa Google. "<a href="http://m.google.com/privacy">"Sera ya Faragha ya Simu za mkononi "</a>" hutumika."</string>
diff --git a/java/res/values-th/strings.xml b/java/res/values-th/strings.xml
index dd05e6b..64d6c3f 100644
--- a/java/res/values-th/strings.xml
+++ b/java/res/values-th/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"การป้อนข้อมูลด้วยเสียง"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"หน้ายิ้ม"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"เครื่องหมายจุด"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"การป้อนข้อมูลด้วยเสียง"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"ขณะนี้การป้อนข้อมูลด้วยเสียงยังไม่ได้รับการสนับสนุนในภาษาของคุณ แต่ใช้ได้ในภาษาอังกฤษ"</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"ป้อนข้อมูลด้วยเสียงใช้การจดจำคำพูดของ Google "<a href="http://m.google.com/privacy">" นโยบายส่วนบุคคลของมือถือ"</a>"มีผลบังคับใช้"</string>
diff --git a/java/res/values-tl/strings.xml b/java/res/values-tl/strings.xml
index 54628e7..7f8f056 100644
--- a/java/res/values-tl/strings.xml
+++ b/java/res/values-tl/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Input ng boses"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Smiley na mukha"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Bumalik"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Tuldok"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Pag-input ng boses"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Hindi kasalukuyang suportado ang pag-input ng boses para sa iyong wika, ngunit gumagana sa Ingles."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Gumagamit ang pag-input ng boses ng speech recognition ng Google. Nalalapat "<a href="http://m.google.com/privacy">"Ang Patakaran sa Privacy ng Mobile"</a>"."</string>
diff --git a/java/res/values-tr/strings.xml b/java/res/values-tr/strings.xml
index c00a9c6..1295fb6 100644
--- a/java/res/values-tr/strings.xml
+++ b/java/res/values-tr/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Ses girişi"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Gülen yüz"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Nokta"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Ses girişi"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Ses girişi, şu anda sizin diliniz için desteklenmiyor ama İngilizce dilinde kullanılabilir."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Ses girişi Google\'ın konuşma tanıma işlevini kullanır. "<a href="http://m.google.com/privacy">" Mobil Gizlilik Politikası"</a>" geçerlidir."</string>
diff --git a/java/res/values-uk/strings.xml b/java/res/values-uk/strings.xml
index 201aa19..4716800 100644
--- a/java/res/values-uk/strings.xml
+++ b/java/res/values-uk/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Голосовий ввід"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Смайлик"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Клавіша Return"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Крапка"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Голос. ввід"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Голос. ввід наразі не підтрим. для вашої мови, але можна користуватися англійською."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Голосовий ввід використовує розпізнавання мовлення Google. Застосовується "<a href="http://m.google.com/privacy">"Політика конфіденційності для мобільних пристроїв"</a>"."</string>
diff --git a/java/res/values-vi/strings.xml b/java/res/values-vi/strings.xml
index 10d906b..343a12a 100644
--- a/java/res/values-vi/strings.xml
+++ b/java/res/values-vi/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Nhập dữ liệu bằng giọng nói"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Mặt cười"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Quay lại"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Dấu chấm"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Nhập liệu bằng giọng nói"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Nhập liệu bằng giọng nói hiện không được hỗ trợ cho ngôn ngữ của bạn nhưng hoạt động với ngôn ngữ tiếng Anh."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Nhập liệu bằng giọng nói sử dụng nhận dạng giọng nói của Google. Áp dụng "<a href="http://m.google.com/privacy">"Chính sách bảo mật dành cho điện thoại di động"</a>"."</string>
diff --git a/java/res/values-zh-rCN/strings.xml b/java/res/values-zh-rCN/strings.xml
index 7558282..a2a0928 100644
--- a/java/res/values-zh-rCN/strings.xml
+++ b/java/res/values-zh-rCN/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"语音输入"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"笑脸"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"返回"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"点"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"语音输入"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"语音输入功能当前还不支持您的语言,您只能输入英语语音。"</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"语音输入采用了 Google 的语音识别技术,因此请遵守"<a href="http://m.google.com/privacy">"“Google 移动”隐私权政策"</a>"。"</string>
diff --git a/java/res/values-zh-rTW/strings.xml b/java/res/values-zh-rTW/strings.xml
index aa6fb0a..f393589 100644
--- a/java/res/values-zh-rTW/strings.xml
+++ b/java/res/values-zh-rTW/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"語音輸入"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"笑臉"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"返回"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"點"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"語音輸入"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"語音輸入目前不支援您的語言,但是可以辨識英文。"</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"語音輸入使用 Google 的語音辨識功能,並遵循《"<a href="http://m.google.com/privacy">"行動服務隱私權政策"</a>"》。"</string>
diff --git a/java/res/values-zu/strings.xml b/java/res/values-zu/strings.xml
index c0cf268..d1dbeac 100644
--- a/java/res/values-zu/strings.xml
+++ b/java/res/values-zu/strings.xml
@@ -89,6 +89,7 @@
     <string name="spoken_description_mic" msgid="615536748882611950">"Okungenayo kwezwi"</string>
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Ubuso-obumomothekayo"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Buyisela"</string>
+    <string name="spoken_description_dot" msgid="40711082435231673">"Icashazi"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Okufakwa ngezwi"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Okufakwa ngezwi akusekelwa olimini lwakho, kodwa kuyasebenza nge-English."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Okufakwayo ngezwi kusebenzisa ukufanisa izwi kwe-Google. "<a href="http://m.google.com/privacy">"Inqubomgomo Yobumfihlo Yefoni"</a>" iyasebenza."</string>
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
index dce2c37..6e13b95 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
@@ -48,14 +48,17 @@
      *            presses of a key adjacent to the intended key.
      * @param x x-coordinate pixel of touched event. If {@link #onCodeInput} is not called by
      *            {@link PointerTracker#onTouchEvent} or so, the value should be
-     *            {@link #NOT_A_TOUCH_COORDINATE}.
+     *            {@link #NOT_A_TOUCH_COORDINATE}. If it's called on insertion from the suggestion
+     *            strip, it should be {@link #SUGGESTION_STRIP_COORDINATE}.
      * @param y y-coordinate pixel of touched event. If {@link #onCodeInput} is not called by
      *            {@link PointerTracker#onTouchEvent} or so, the value should be
-     *            {@link #NOT_A_TOUCH_COORDINATE}.
+     *            {@link #NOT_A_TOUCH_COORDINATE}. If it's called on insertion from the suggestion
+     *            strip, it should be {@link #SUGGESTION_STRIP_COORDINATE}.
      */
     public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y);
 
     public static final int NOT_A_TOUCH_COORDINATE = -1;
+    public static final int SUGGESTION_STRIP_COORDINATE = -2;
 
     /**
      * Sends a sequence of characters to the listener.
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
index adb5f47..e3c5da4 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
@@ -43,6 +43,8 @@
 public class KeySpecParser {
     private static final boolean DEBUG = LatinImeLogger.sDBG;
 
+    private static final int MAX_STRING_REFERENCE_INDIRECTION = 10;
+
     // Constants for parsing.
     private static int COMMA = ',';
     private static final char ESCAPE_CHAR = '\\';
@@ -274,35 +276,51 @@
         return resId;
     }
 
-    private static String resolveStringResource(String text, Resources res, int packageNameResId) {
-        final int size = text.length();
-        if (size < PREFIX_STRING.length()) {
-            return text;
-        }
-
-        StringBuilder sb = null;
-        for (int pos = 0; pos < size; pos++) {
-            final char c = text.charAt(pos);
-            if (c == PREFIX_AT && text.startsWith(PREFIX_STRING, pos)) {
-                if (sb == null) {
-                    sb = new StringBuilder(text.substring(0, pos));
-                }
-                final int end = searchResourceNameEnd(text, pos + PREFIX_STRING.length());
-                final String resName = text.substring(pos + 1, end);
-                final int resId = getResourceId(res, resName, packageNameResId);
-                sb.append(res.getString(resId));
-                pos = end - 1;
-            } else if (c == ESCAPE_CHAR) {
-                if (sb != null) {
-                    // Append both escape character and escaped character.
-                    sb.append(text.substring(pos, Math.min(pos + 2, size)));
-                }
-                pos++;
-            } else if (sb != null) {
-                sb.append(c);
+    private static String resolveStringResource(String rawText, Resources res,
+            int packageNameResId) {
+        int level = 0;
+        String text = rawText;
+        StringBuilder sb;
+        do {
+            level++;
+            if (level >= MAX_STRING_REFERENCE_INDIRECTION) {
+                throw new RuntimeException("too many @string/resource indirection: " + text);
             }
-        }
-        return (sb == null) ? text : sb.toString();
+
+            final int size = text.length();
+            if (size < PREFIX_STRING.length()) {
+                return text;
+            }
+
+            sb = null;
+            for (int pos = 0; pos < size; pos++) {
+                final char c = text.charAt(pos);
+                if (c == PREFIX_AT && text.startsWith(PREFIX_STRING, pos)) {
+                    if (sb == null) {
+                        sb = new StringBuilder(text.substring(0, pos));
+                    }
+                    final int end = searchResourceNameEnd(text, pos + PREFIX_STRING.length());
+                    final String resName = text.substring(pos + 1, end);
+                    final int resId = getResourceId(res, resName, packageNameResId);
+                    sb.append(res.getString(resId));
+                    pos = end - 1;
+                } else if (c == ESCAPE_CHAR) {
+                    if (sb != null) {
+                        // Append both escape character and escaped character.
+                        sb.append(text.substring(pos, Math.min(pos + 2, size)));
+                    }
+                    pos++;
+                } else if (sb != null) {
+                    sb.append(c);
+                }
+            }
+
+            if (sb != null) {
+                text = sb.toString();
+            }
+        } while (sb != null);
+
+        return text;
     }
 
     private static int searchResourceNameEnd(String text, int start) {
diff --git a/java/src/com/android/inputmethod/latin/InputAttributes.java b/java/src/com/android/inputmethod/latin/InputAttributes.java
index f5cf953..3de5c1d 100644
--- a/java/src/com/android/inputmethod/latin/InputAttributes.java
+++ b/java/src/com/android/inputmethod/latin/InputAttributes.java
@@ -28,7 +28,6 @@
 public class InputAttributes {
     private final String TAG = InputAttributes.class.getSimpleName();
 
-    final public boolean mInsertSpaceOnPickSuggestionManually;
     final public boolean mInputTypeNoAutoCorrect;
     final public boolean mIsSettingsSuggestionStripOn;
     final public boolean mApplicationSpecifiedCompletionOn;
@@ -52,7 +51,6 @@
                         + " imeOptions=0x%08x",
                         inputType, editorInfo.imeOptions));
             }
-            mInsertSpaceOnPickSuggestionManually = false;
             mIsSettingsSuggestionStripOn = false;
             mInputTypeNoAutoCorrect = false;
             mApplicationSpecifiedCompletionOn = false;
@@ -80,15 +78,6 @@
                 mIsSettingsSuggestionStripOn = true;
             }
 
-            if (InputTypeCompatUtils.isEmailVariation(variation)
-                    || variation == InputType.TYPE_TEXT_VARIATION_PERSON_NAME) {
-                // The point in turning this off is that we don't want to insert a space after
-                // a name when filling a form: we can't delete trailing spaces when changing fields
-                mInsertSpaceOnPickSuggestionManually = false;
-            } else {
-                mInsertSpaceOnPickSuggestionManually = true;
-            }
-
             // If it's a browser edit field and auto correct is not ON explicitly, then
             // disable auto correction, but keep suggestions on.
             // If NO_SUGGESTIONS is set, don't do prediction.
@@ -109,8 +98,7 @@
     // Pretty print
     @Override
     public String toString() {
-        return "\n mInsertSpaceOnPickSuggestionManually = " + mInsertSpaceOnPickSuggestionManually
-                + "\n mInputTypeNoAutoCorrect = " + mInputTypeNoAutoCorrect
+        return "\n mInputTypeNoAutoCorrect = " + mInputTypeNoAutoCorrect
                 + "\n mIsSettingsSuggestionStripOn = " + mIsSettingsSuggestionStripOn
                 + "\n mApplicationSpecifiedCompletionOn = " + mApplicationSpecifiedCompletionOn;
     }
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 1bc55a5..24007f9 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -160,18 +160,21 @@
         SUGGESTION_VISIBILILTY_HIDE_VALUE
     };
 
-    // Magic space: a space that should disappear on space/apostrophe insertion, move after the
-    // punctuation on punctuation insertion, and become a real space on alpha char insertion.
-    // Weak space: a space that should be swapped only by suggestion strip punctuation.
+    private static final int SPACE_STATE_NONE = 0;
     // Double space: the state where the user pressed space twice quickly, which LatinIME
     // resolved as period-space. Undoing this converts the period to a space.
+    private static final int SPACE_STATE_DOUBLE = 1;
     // Swap punctuation: the state where a (weak or magic) space and a punctuation from the
     // suggestion strip have just been swapped. Undoing this swaps them back.
-    private static final int SPACE_STATE_NONE = 0;
-    private static final int SPACE_STATE_DOUBLE = 1;
     private static final int SPACE_STATE_SWAP_PUNCTUATION = 2;
-    private static final int SPACE_STATE_MAGIC = 3;
-    private static final int SPACE_STATE_WEAK = 4;
+    // Weak space: a space that should be swapped only by suggestion strip punctuation. Weak
+    // spaces happen when the user presses space, accepting the current suggestion (whether
+    // it's an auto-correction or not).
+    private static final int SPACE_STATE_WEAK = 3;
+    // Phantom space: a not-yet-inserted space that should get inserted on the next input,
+    // character provided it's not a separator. If it's a separator, the phantom space is dropped.
+    // Phantom spaces happen when a user chooses a word from the suggestion strip.
+    private static final int SPACE_STATE_PHANTOM = 4;
 
     // Current space state of the input method. This can be any of the above constants.
     private int mSpaceState;
@@ -1162,18 +1165,6 @@
         return false;
     }
 
-    // "ic" must not be null
-    private static void maybeRemovePreviousPeriod(final InputConnection ic, CharSequence text) {
-        // When the text's first character is '.', remove the previous period
-        // if there is one.
-        final CharSequence lastOne = ic.getTextBeforeCursor(1, 0);
-        if (lastOne != null && lastOne.length() == 1
-                && lastOne.charAt(0) == Keyboard.CODE_PERIOD
-                && text.charAt(0) == Keyboard.CODE_PERIOD) {
-            ic.deleteSurroundingText(1, 0);
-        }
-    }
-
     // "ic" may be null
     private static void removeTrailingSpaceWhileInBatchEdit(final InputConnection ic) {
         if (ic == null) return;
@@ -1234,26 +1225,9 @@
     }
 
     private void insertPunctuationFromSuggestionStrip(final InputConnection ic, final int code) {
-        final CharSequence beforeText = ic != null ? ic.getTextBeforeCursor(1, 0) : null;
-        final int toLeft = TextUtils.isEmpty(beforeText) ? 0 : beforeText.charAt(0);
-        final boolean shouldRegisterSwapPunctuation;
-        // If we have a space left of the cursor and it's a weak or a magic space, then we should
-        // swap it, and override the space state with SPACESTATE_SWAP_PUNCTUATION.
-        // To swap it, we fool handleSeparator to think the previous space state was a
-        // magic space.
-        if (Keyboard.CODE_SPACE == toLeft && mSpaceState == SPACE_STATE_WEAK
-                && mSettingsValues.isMagicSpaceSwapper(code)) {
-            mSpaceState = SPACE_STATE_MAGIC;
-            shouldRegisterSwapPunctuation = true;
-        } else {
-            shouldRegisterSwapPunctuation = false;
-        }
         onCodeInput(code, new int[] { code },
-                KeyboardActionListener.NOT_A_TOUCH_COORDINATE,
-                KeyboardActionListener.NOT_A_TOUCH_COORDINATE);
-        if (shouldRegisterSwapPunctuation) {
-            mSpaceState = SPACE_STATE_SWAP_PUNCTUATION;
-        }
+                KeyboardActionListener.SUGGESTION_STRIP_COORDINATE,
+                KeyboardActionListener.SUGGESTION_STRIP_COORDINATE);
     }
 
     // Implementation of {@link KeyboardActionListener}.
@@ -1331,7 +1305,10 @@
         if (ic == null) return;
         ic.beginBatchEdit();
         commitTyped(ic);
-        maybeRemovePreviousPeriod(ic, text);
+        text = specificTldProcessingOnTextInput(ic, text);
+        if (SPACE_STATE_PHANTOM == mSpaceState) {
+            sendKeyChar((char)Keyboard.CODE_SPACE);
+        }
         ic.commitText(text, 1);
         ic.endBatchEdit();
         mKeyboardSwitcher.updateShiftState();
@@ -1341,6 +1318,24 @@
         resetComposingState(true /* alsoResetLastComposedWord */);
     }
 
+    // ic may not be null
+    private CharSequence specificTldProcessingOnTextInput(final InputConnection ic,
+            final CharSequence text) {
+        if (text.length() <= 1 || text.charAt(0) != Keyboard.CODE_PERIOD
+                || !Character.isLetter(text.charAt(1))) {
+            // Not a tld: do nothing.
+            return text;
+        }
+        final CharSequence lastOne = ic.getTextBeforeCursor(1, 0);
+        if (lastOne != null && lastOne.length() == 1
+                && lastOne.charAt(0) == Keyboard.CODE_PERIOD) {
+            mSpaceState = SPACE_STATE_NONE;
+            return text.subSequence(1, text.length());
+        } else {
+            return text;
+        }
+    }
+
     @Override
     public void onCancelInput() {
         // User released a finger outside any key
@@ -1492,13 +1487,18 @@
     // "ic" may be null without this crashing, but the behavior will be really strange
     private void handleCharacterWhileInBatchEdit(final int primaryCode, final int[] keyCodes,
             final int x, final int y, final int spaceState, final InputConnection ic) {
-        if (SPACE_STATE_MAGIC == spaceState
-                && mSettingsValues.isMagicSpaceStripper(primaryCode)) {
-            if (null != ic) removeTrailingSpaceWhileInBatchEdit(ic);
-        }
-
         boolean isComposingWord = mWordComposer.isComposingWord();
         int code = primaryCode;
+
+        if (SPACE_STATE_PHANTOM == spaceState &&
+                !mSettingsValues.isSymbolExcludedFromWordSeparators(primaryCode)) {
+            if (isComposingWord) {
+                // Sanity check
+                throw new RuntimeException("Should not be composing here");
+            }
+            sendKeyChar((char)Keyboard.CODE_SPACE);
+        }
+
         if ((isAlphabet(code) || mSettingsValues.isSymbolExcludedFromWordSeparators(code))
                 && isSuggestionsRequested() && !isCursorTouchingWord()) {
             if (!isComposingWord) {
@@ -1530,10 +1530,6 @@
         } else {
             sendKeyChar((char)code);
         }
-        if (SPACE_STATE_MAGIC == spaceState
-                && mSettingsValues.isMagicSpaceSwapper(primaryCode)) {
-            if (null != ic) swapSwapperAndSpaceWhileInBatchEdit(ic);
-        }
 
         if (mSettingsValues.isWordSeparator(code)) {
             Utils.Stats.onSeparator((char)code, x, y);
@@ -1575,24 +1571,28 @@
             }
         }
 
-        final boolean swapMagicSpace;
-        if (Keyboard.CODE_ENTER == primaryCode && (SPACE_STATE_MAGIC == spaceState
-                || SPACE_STATE_SWAP_PUNCTUATION == spaceState)) {
+        final boolean swapWeakSpace;
+        if (Keyboard.CODE_ENTER == primaryCode && SPACE_STATE_SWAP_PUNCTUATION == spaceState) {
             removeTrailingSpaceWhileInBatchEdit(ic);
-            swapMagicSpace = false;
-        } else if (SPACE_STATE_MAGIC == spaceState) {
+            swapWeakSpace = false;
+        } else if ((SPACE_STATE_WEAK == spaceState || SPACE_STATE_SWAP_PUNCTUATION == spaceState)
+                && KeyboardActionListener.SUGGESTION_STRIP_COORDINATE == x) {
             if (mSettingsValues.isMagicSpaceSwapper(primaryCode)) {
-                swapMagicSpace = true;
+                swapWeakSpace = true;
             } else {
-                swapMagicSpace = false;
+                swapWeakSpace = false;
                 if (mSettingsValues.isMagicSpaceStripper(primaryCode)) {
                     removeTrailingSpaceWhileInBatchEdit(ic);
                 }
             }
         } else {
-            swapMagicSpace = false;
+            swapWeakSpace = false;
         }
 
+        // TODO: rethink interactions of sendKeyChar, commitText("\n") and actions. sendKeyChar
+        // with a CODE_ENTER parameter will have the default InputMethodService implementation
+        // possibly redirect on the keyboard action. That may be the right thing to do, but
+        // on Shift+Enter, it's generally not, so we may want to do the redirection right here.
         sendKeyChar((char)primaryCode);
 
         if (Keyboard.CODE_SPACE == primaryCode) {
@@ -1610,9 +1610,17 @@
                 mHandler.postUpdateBigramPredictions();
             }
         } else {
-            if (swapMagicSpace) {
+            if (swapWeakSpace) {
                 swapSwapperAndSpaceWhileInBatchEdit(ic);
-                mSpaceState = SPACE_STATE_MAGIC;
+                mSpaceState = SPACE_STATE_WEAK;
+            } else if (SPACE_STATE_PHANTOM == spaceState) {
+                // If we are in phantom space state, and the user presses a separator, we want to
+                // stay in phantom space state so that the next keypress has a chance to add the
+                // space. For example, if I type "Good dat", pick "day" from the suggestion strip
+                // then insert a comma and go on to typing the next word, I want the space to be
+                // inserted automatically before the next word, the same way it is when I don't
+                // input the comma.
+                mSpaceState = SPACE_STATE_PHANTOM;
             }
 
             // Set punctuation right away. onUpdateSelection will fire but tests whether it is
@@ -1921,10 +1929,9 @@
         } else {
             addToOnlyBigramDictionary(suggestion, 1);
         }
-        // Follow it with a space
-        if (mInputAttributes.mInsertSpaceOnPickSuggestionManually) {
-            sendMagicSpace();
-        }
+        mSpaceState = SPACE_STATE_PHANTOM;
+        // TODO: is this necessary?
+        mKeyboardSwitcher.updateShiftState();
 
         // We should show the "Touch again to save" hint if the user pressed the first entry
         // AND either:
@@ -2259,12 +2266,6 @@
         return mSettingsValues.isWordSeparator(code);
     }
 
-    private void sendMagicSpace() {
-        sendKeyChar((char)Keyboard.CODE_SPACE);
-        mSpaceState = SPACE_STATE_MAGIC;
-        mKeyboardSwitcher.updateShiftState();
-    }
-
     public boolean preferCapitalization() {
         return mWordComposer.isFirstCharCapitalized();
     }
diff --git a/native/src/correction.cpp b/native/src/correction.cpp
index a71a599..4df1c4e 100644
--- a/native/src/correction.cpp
+++ b/native/src/correction.cpp
@@ -211,6 +211,7 @@
 
     mMatching = false;
     mProximityMatching = false;
+    mAdditionalProximityMatching = false;
     mTransposing = false;
     mExceeding = false;
     mSkipping = false;
@@ -257,6 +258,7 @@
 
     mCorrectionStates[mOutputIndex].mMatching = mMatching;
     mCorrectionStates[mOutputIndex].mProximityMatching = mProximityMatching;
+    mCorrectionStates[mOutputIndex].mAdditionalProximityMatching = mAdditionalProximityMatching;
     mCorrectionStates[mOutputIndex].mTransposing = mTransposing;
     mCorrectionStates[mOutputIndex].mExceeding = mExceeding;
     mCorrectionStates[mOutputIndex].mSkipping = mSkipping;
@@ -305,6 +307,11 @@
     return type == ProximityInfo::EQUIVALENT_CHAR;
 }
 
+inline bool isProximityCharOrEquivalentChar(ProximityInfo::ProximityType type) {
+    return type == ProximityInfo::EQUIVALENT_CHAR
+            || type == ProximityInfo::NEAR_PROXIMITY_CHAR;
+}
+
 Correction::CorrectionType Correction::processCharAndCalcState(
         const int32_t c, const bool isTerminal) {
     const int correctionCount = (mSkippedCount + mExcessiveCount + mTransposedCount);
@@ -439,6 +446,9 @@
 
     if (ProximityInfo::UNRELATED_CHAR == matchedProximityCharId
             || ProximityInfo::ADDITIONAL_PROXIMITY_CHAR == matchedProximityCharId) {
+        if (ProximityInfo::ADDITIONAL_PROXIMITY_CHAR == matchedProximityCharId) {
+            mAdditionalProximityMatching = true;
+        }
         // TODO: Optimize
         // As the current char turned out to be an unrelated char,
         // we will try other correction-types. Please note that mCorrectionStates[mOutputIndex]
@@ -480,6 +490,18 @@
             ++mSkippedCount;
             --mProximityCount;
             return processSkipChar(c, isTerminal, false);
+        } else if (mInputIndex - 1 < mInputLength
+                && mSkippedCount > 0
+                && mCorrectionStates[mOutputIndex].mSkipping
+                && mCorrectionStates[mOutputIndex].mAdditionalProximityMatching
+                && isProximityCharOrEquivalentChar(
+                        mProximityInfo->getMatchedProximityId(mInputIndex + 1, c, false))) {
+            // Conversion s->a
+            incrementInputIndex();
+            --mSkippedCount;
+            mProximityMatching = true;
+            ++mProximityCount;
+            mDistances[mOutputIndex] = ADDITIONAL_PROXIMITY_CHAR_DISTANCE_INFO;
         } else if ((mExceeding || mTransposing) && mInputIndex - 1 < mInputLength
                 && isEquivalentChar(
                         mProximityInfo->getMatchedProximityId(mInputIndex + 1, c, false))) {
@@ -667,6 +689,10 @@
 
     int finalFreq = freq;
 
+    if (DEBUG_CORRECTION_FREQ
+            && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == inputLength)) {
+        AKLOGI("FinalFreq0: %d", finalFreq);
+    }
     // TODO: Optimize this.
     if (transposedCount > 0 || proximityMatchedCount > 0 || skipped || excessiveCount > 0) {
         ed = getCurrentEditDistance(editDistanceTable, correction->mInputLength, outputLength,
@@ -682,12 +708,15 @@
         }
 
         ed = max(0, ed - quoteDiffCount);
-
+        adjustedProximityMatchedCount = min(max(0, ed - (outputLength - inputLength)),
+                proximityMatchedCount);
         if (transposedCount < 1) {
             if (ed == 1 && (inputLength == outputLength - 1 || inputLength == outputLength + 1)) {
                 // Promote a word with just one skipped or excessive char
                 if (sameLength) {
-                    multiplyRate(WORDS_WITH_JUST_ONE_CORRECTION_PROMOTION_RATE, &finalFreq);
+                    multiplyRate(WORDS_WITH_JUST_ONE_CORRECTION_PROMOTION_RATE
+                            + WORDS_WITH_JUST_ONE_CORRECTION_PROMOTION_MULTIPLIER * outputLength,
+                            &finalFreq);
                 } else {
                     multiplyIntCapped(typedLetterMultiplier, &finalFreq);
                 }
@@ -696,8 +725,6 @@
                 sameLength = true;
             }
         }
-        adjustedProximityMatchedCount = min(max(0, ed - (outputLength - inputLength)),
-                proximityMatchedCount);
     } else {
         const int matchWeight = powerIntCapped(typedLetterMultiplier, matchCount);
         multiplyIntCapped(matchWeight, &finalFreq);
@@ -745,6 +772,7 @@
                         && skippedCount == 0 && excessiveCount == 0 && transposedCount == 0;
     // Score calibration by touch coordinates is being done only for pure-fat finger typing error
     // cases.
+    int additionalProximityCount = 0;
     // TODO: Remove this constraint.
     if (performTouchPositionCorrection) {
         for (int i = 0; i < outputLength; ++i) {
@@ -777,12 +805,12 @@
             } else if (squaredDistance == PROXIMITY_CHAR_WITHOUT_DISTANCE_INFO) {
                 multiplyRate(WORDS_WITH_PROXIMITY_CHARACTER_DEMOTION_RATE, &finalFreq);
             } else if (squaredDistance == ADDITIONAL_PROXIMITY_CHAR_DISTANCE_INFO) {
+                ++additionalProximityCount;
                 multiplyRate(WORDS_WITH_ADDITIONAL_PROXIMITY_CHARACTER_DEMOTION_RATE, &finalFreq);
             }
         }
     } else {
         // Demote additional proximity characters
-        int additionalProximityCount = 0;
         for (int i = 0; i < outputLength; ++i) {
             const int squaredDistance = correction->mDistances[i];
             if (squaredDistance == ADDITIONAL_PROXIMITY_CHAR_DISTANCE_INFO) {
@@ -804,6 +832,13 @@
         }
     }
 
+    // If the user types too many(three or more) proximity characters with additional proximity
+    // character,do not treat as the same length word.
+    if (sameLength && additionalProximityCount > 0 && (adjustedProximityMatchedCount >= 3
+            || transposedCount > 0 || skipped || excessiveCount > 0)) {
+        sameLength = false;
+    }
+
     const int errorCount = adjustedProximityMatchedCount > 0
             ? adjustedProximityMatchedCount
             : (proximityMatchedCount + transposedCount);
@@ -814,13 +849,14 @@
     if (ed == 0) {
         // Full exact match
         if (sameLength && transposedCount == 0 && !skipped && excessiveCount == 0
-                && quoteDiffCount == 0) {
+                && quoteDiffCount == 0 && additionalProximityCount == 0) {
             finalFreq = capped255MultForFullMatchAccentsOrCapitalizationDifference(finalFreq);
         }
     }
 
     // Promote a word with no correction
-    if (proximityMatchedCount == 0 && transposedCount == 0 && !skipped && excessiveCount == 0) {
+    if (proximityMatchedCount == 0 && transposedCount == 0 && !skipped && excessiveCount == 0
+            && additionalProximityCount == 0) {
         multiplyRate(FULL_MATCHED_WORDS_PROMOTION_RATE, &finalFreq);
     }
 
@@ -864,10 +900,11 @@
 
     if (DEBUG_CORRECTION_FREQ
             && (INPUTLENGTH_FOR_DEBUG <= 0 || INPUTLENGTH_FOR_DEBUG == inputLength)) {
+        DUMP_WORD(proximityInfo->getPrimaryInputWord(), inputLength);
         DUMP_WORD(correction->mWord, outputLength);
-        AKLOGI("FinalFreq: [P%d, S%d, T%d, E%d] %d, %d, %d, %d, %d, %d", proximityMatchedCount,
-                skippedCount, transposedCount, excessiveCount, outputLength, lastCharExceeded,
-                sameLength, quoteDiffCount, ed, finalFreq);
+        AKLOGI("FinalFreq: [P%d, S%d, T%d, E%d, A%d] %d, %d, %d, %d, %d, %d", proximityMatchedCount,
+                skippedCount, transposedCount, excessiveCount, additionalProximityCount,
+                outputLength, lastCharExceeded, sameLength, quoteDiffCount, ed, finalFreq);
     }
 
     return finalFreq;
diff --git a/native/src/correction.h b/native/src/correction.h
index a711c99..398e7e7 100644
--- a/native/src/correction.h
+++ b/native/src/correction.h
@@ -221,6 +221,7 @@
 
     bool mMatching;
     bool mProximityMatching;
+    bool mAdditionalProximityMatching;
     bool mExceeding;
     bool mTransposing;
     bool mSkipping;
diff --git a/native/src/correction_state.h b/native/src/correction_state.h
index c04146e..5b2cbd3 100644
--- a/native/src/correction_state.h
+++ b/native/src/correction_state.h
@@ -47,9 +47,9 @@
     bool mExceeding;
     bool mSkipping;
     bool mProximityMatching;
+    bool mAdditionalProximityMatching;
 
     bool mNeedsToTraverseAllNodes;
-
 };
 
 inline static void initCorrectionState(CorrectionState *state, const int rootPos,
@@ -77,7 +77,7 @@
     state->mTransposing = false;
     state->mExceeding = false;
     state->mSkipping = false;
-
+    state->mAdditionalProximityMatching = false;
 }
 
 } // namespace latinime
diff --git a/native/src/defines.h b/native/src/defines.h
index 9f237c5..5b5c548 100644
--- a/native/src/defines.h
+++ b/native/src/defines.h
@@ -195,9 +195,10 @@
 #define WORDS_WITH_TRANSPOSED_CHARACTERS_DEMOTION_RATE 70
 #define FULL_MATCHED_WORDS_PROMOTION_RATE 120
 #define WORDS_WITH_PROXIMITY_CHARACTER_DEMOTION_RATE 90
-#define WORDS_WITH_ADDITIONAL_PROXIMITY_CHARACTER_DEMOTION_RATE 30
+#define WORDS_WITH_ADDITIONAL_PROXIMITY_CHARACTER_DEMOTION_RATE 70
 #define WORDS_WITH_MATCH_SKIP_PROMOTION_RATE 105
-#define WORDS_WITH_JUST_ONE_CORRECTION_PROMOTION_RATE 160
+#define WORDS_WITH_JUST_ONE_CORRECTION_PROMOTION_RATE 148
+#define WORDS_WITH_JUST_ONE_CORRECTION_PROMOTION_MULTIPLIER 3
 #define CORRECTION_COUNT_RATE_DEMOTION_RATE_BASE 45
 #define INPUT_EXCEEDS_OUTPUT_DEMOTION_RATE 70
 #define FIRST_CHAR_DIFFERENT_DEMOTION_RATE 96
@@ -247,7 +248,7 @@
 #define NEUTRAL_AREA_RADIUS_RATIO 1.3f
 
 // DEBUG
-#define INPUTLENGTH_FOR_DEBUG -1
+#define INPUTLENGTH_FOR_DEBUG 10
 #define MIN_OUTPUT_INDEX_FOR_DEBUG -1
 
 #endif // LATINIME_DEFINES_H
diff --git a/tests/res/values/donottranslate.xml b/tests/res/values/donottranslate.xml
index d0cde71..1ca4451 100644
--- a/tests/res/values/donottranslate.xml
+++ b/tests/res/values/donottranslate.xml
@@ -50,4 +50,7 @@
     <string name="multiple_labels_with_escape_surrounded_by_spaces">" \\abc , d\\ef , gh\\i "</string>
     <string name="multiple_labels_with_comma_and_escape">"ab\\\\,d\\\\\\,,g\\,i"</string>
     <string name="multiple_labels_with_comma_and_escape_surrounded_by_spaces">" ab\\\\ , d\\\\\\, , g\\,i "</string>
+    <string name="indirect_string">@string/multiple_chars</string>
+    <string name="indirect_string_with_literal">x,@string/multiple_chars,y</string>
+    <string name="infinite_indirection">infinite,@string/infinite_indirection,loop</string>
 </resources>
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserCsvTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserCsvTests.java
index a0ce86d..e090031 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserCsvTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserCsvTests.java
@@ -288,4 +288,16 @@
                 "abc@string/multiple_labels",
                 "abcabc", "def", "ghi");
     }
+
+    public void testParseIndirectReference() {
+        assertTextArray("Indirect",
+                "@string/indirect_string", "a", "b", "c");
+        assertTextArray("Indirect with literal",
+                "1,@string/indirect_string_with_literal,2", "1", "x", "a", "b", "c", "y", "2");
+    }
+
+    public void testParseInfiniteIndirectReference() {
+        assertError("Infinite indirection",
+                "1,@string/infinite_indirection,2", "1", "infinite", "<infinite>", "loop", "2");
+    }
 }
diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTests.java b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
index ee3a97f..693352c 100644
--- a/tests/src/com/android/inputmethod/latin/InputLogicTests.java
+++ b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
@@ -186,7 +186,7 @@
     }
 
     public void testCancelDoubleSpace() {
-        final String STRING_TO_TYPE = "tgis  ";
+        final String STRING_TO_TYPE = "this  ";
         final String EXPECTED_RESULT = "this  ";
         type(STRING_TO_TYPE);
         type(Keyboard.CODE_DELETE);
@@ -202,7 +202,7 @@
         mInputConnection.setSelection(NEW_CURSOR_POSITION, NEW_CURSOR_POSITION);
         mLatinIME.onUpdateSelection(0, 0, NEW_CURSOR_POSITION, NEW_CURSOR_POSITION, -1, -1);
         type(Keyboard.CODE_DELETE);
-        assertEquals("auto correct then move curor to start of line then backspace",
+        assertEquals("auto correct then move cursor to start of line then backspace",
                 EXPECTED_RESULT, mTextView.getText().toString());
     }
 
@@ -215,7 +215,7 @@
         mInputConnection.setSelection(NEW_CURSOR_POSITION, NEW_CURSOR_POSITION);
         mLatinIME.onUpdateSelection(0, 0, NEW_CURSOR_POSITION, NEW_CURSOR_POSITION, -1, -1);
         type(Keyboard.CODE_DELETE);
-        assertEquals("auto correct then move curor then backspace",
+        assertEquals("auto correct then move cursor then backspace",
                 EXPECTED_RESULT, mTextView.getText().toString());
     }