Merge "Plumbing for ProductionFlag.USES_CURSOR_ANCHOR_MONITOR"
diff --git a/java/res/values-in/strings.xml b/java/res/values-in/strings.xml
index 3b5cf91..c5f0fc3 100644
--- a/java/res/values-in/strings.xml
+++ b/java/res/values-in/strings.xml
@@ -194,7 +194,7 @@
     <string name="dictionary_provider_name" msgid="3027315045397363079">"Penyedia Kamus"</string>
     <string name="dictionary_service_name" msgid="6237472350693511448">"Layanan Kamus"</string>
     <string name="download_description" msgid="6014835283119198591">"Informasi pembaruan kamus"</string>
-    <string name="dictionary_settings_title" msgid="8091417676045693313">"Kamus add-on"</string>
+    <string name="dictionary_settings_title" msgid="8091417676045693313">"Kamus pengaya"</string>
     <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"Kamus yang tersedia"</string>
     <string name="dictionary_settings_summary" msgid="5305694987799824349">"Setelan untuk kamus"</string>
     <string name="user_dictionaries" msgid="3582332055892252845">"Kamus pengguna"</string>
diff --git a/java/res/values-ja/strings.xml b/java/res/values-ja/strings.xml
index 4567ec9..c4b1852 100644
--- a/java/res/values-ja/strings.xml
+++ b/java/res/values-ja/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"英語(英国)(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"英語(米国)(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"スペイン語(米国)(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>(繁体)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>(伝統言語)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"言語なし(アルファベット)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"アルファベット(QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"アルファベット(QWERTZ)"</string>
diff --git a/java/res/values-ms-rMY/strings.xml b/java/res/values-ms-rMY/strings.xml
index 96735c0..294dd7f 100644
--- a/java/res/values-ms-rMY/strings.xml
+++ b/java/res/values-ms-rMY/strings.xml
@@ -135,8 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Bahasa Inggeris (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Bahasa Inggeris (AS) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Bahasa Sepanyol (AS) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <!-- no translation found for subtype_generic_traditional (8584594350973800586) -->
-    <skip />
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Tradisional)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Tiada bahasa (Abjad)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Abjad (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Abjad (QWERTZ)"</string>
diff --git a/java/res/values-nb/strings.xml b/java/res/values-nb/strings.xml
index fe38a86..02cc7de 100644
--- a/java/res/values-nb/strings.xml
+++ b/java/res/values-nb/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Engelsk (Storbritannia) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Engelsk (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spansk (USA) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradisjonell)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradisjonelt)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Ingen språk (alfabet)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabet (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabet (QWERTZ)"</string>
diff --git a/java/res/values-ne-rNP/strings.xml b/java/res/values-ne-rNP/strings.xml
index 2bf1fb7..055d16c 100644
--- a/java/res/values-ne-rNP/strings.xml
+++ b/java/res/values-ne-rNP/strings.xml
@@ -167,7 +167,7 @@
     <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"स्थापना गर्न कुनै शब्दकोश फाइल चयन गर्नुहोस्"</string>
     <string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"वास्तवमै <xliff:g id="LANGUAGE_NAME">%s</xliff:g> को लागि यो फाइल स्थापना गर्नुहुन्छ?"</string>
     <string name="error" msgid="8940763624668513648">"कुनै त्रुटि भयो"</string>
-    <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"सम्पर्क शब्दकोश डम्प गर्नुहोस्"</string>
+    <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"सम्पर्क शब्दकोश भेला गर्नुहोस्"</string>
     <string name="prefs_dump_user_dict" msgid="294870685041741951">"व्यक्तिगत शब्दकोश डम्प गर्नुहोस्"</string>
     <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"प्रयोगकर्ता इतिहास शब्दकोश डम्प गर"</string>
     <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"निजीकरण शब्दकोश डम्प गर्नुहोस्"</string>
diff --git a/java/res/values-ro/strings.xml b/java/res/values-ro/strings.xml
index 2d5fd1f..96a7744 100644
--- a/java/res/values-ro/strings.xml
+++ b/java/res/values-ro/strings.xml
@@ -135,8 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"Engleză (Regatul Unit) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"Engleză (S.U.A.) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spaniolă (S.U.A.) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
-    <!-- no translation found for subtype_generic_traditional (8584594350973800586) -->
-    <skip />
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradițională)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Nicio limbă (alfabet)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabet (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabet (QWERTZ)"</string>
diff --git a/java/res/values-zu/strings.xml b/java/res/values-zu/strings.xml
index e499bd9..1fd1e03 100644
--- a/java/res/values-zu/strings.xml
+++ b/java/res/values-zu/strings.xml
@@ -135,7 +135,7 @@
     <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"I-English (UK) ( <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g> )"</string>
     <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"I-English (US) ( <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g> )"</string>
     <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Isi-Spanish (US) ( <xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g> )"</string>
-    <string name="subtype_generic_traditional" msgid="8584594350973800586">"Isi-<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Eyosiko)"</string>
+    <string name="subtype_generic_traditional" msgid="8584594350973800586">"Isi-<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Tradition)"</string>
     <string name="subtype_no_language" msgid="7137390094240139495">"Alikho ulimi (Alfabhethi)"</string>
     <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabhethi (QWERTY)"</string>
     <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabhethi (QWERTZ)"</string>
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 937a799..a4e2d29 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -365,18 +365,12 @@
          (Compact) can be an abbreviation to fit in the CHAR LIMIT.
          TODO: Remove translatable=false once we are settled down with the naming. -->
     <string name="subtype_generic_compact" translatable="false"><xliff:g id="LANGUAGE_NAME" example="Hindi">%s</xliff:g> (Compact)</string>
-    <!-- TODO: Uncomment once we can handle IETF language tag with script name specified.
-         Description for Serbian Cyrillic keyboard subtype [CHAR LIMIT=25]
-         (Cyrillic) can be an abbreviation to fit in the CHAR LIMIT.
-    <string name="subtype_serbian_cyrillic">Serbian (Cyrillic)</string>
-         Description for Serbian Latin keyboard subtype [CHAR LIMIT=25]
-         (Latin) can be an abbreviation to fit in the CHAR LIMIT.
-    <string name="subtype_serbian_latin">Serbian (Latin)</string>
-         Description for Serbian Latin keyboard subtype with explicit keyboard layout [CHAR LIMIT=25]
-         (Latin) can be an abbreviation to fit in the CHAR LIMIT.
-         This should be identical to subtype_serbian_latin aside from the trailing (%s).
-    <string name="subtype_with_layout_sr-Latn">Serbian (Latin) (<xliff:g id="KEYBOARD_LAYOUT" example="QWERTY">%s</xliff:g>)</string>
-    -->
+    <!-- Description for "LANGUAGE_NAME" (Cyrillic) keyboard subtype [CHAR LIMIT=25]
+         (Cyrillic) can be an abbreviation to fit in the CHAR LIMIT. -->
+    <string name="subtype_generic_cyrillic"><xliff:g id="LANGUAGE_NAME" example="Serbian">%s</xliff:g> (Cyrillic)</string>
+    <!-- Description for "LANGUAGE_NAME" (Latin) keyboard subtype [CHAR LIMIT=25]
+         (Latin) can be an abbreviation to fit in the CHAR LIMIT. -->
+    <string name="subtype_generic_latin"><xliff:g id="LANGUAGE_NAME" example="Serbian">%s</xliff:g> (Latin)</string>
     <!-- This string is displayed in a language list that allows to choose a language for
 suggestions in a software keyboard. This setting won't give suggestions in any particular
 language, hence "No language".
diff --git a/java/res/xml-sw600dp/rows_myanmar.xml b/java/res/xml-sw600dp/rows_myanmar.xml
index 778b330..8eedf9d 100644
--- a/java/res/xml-sw600dp/rows_myanmar.xml
+++ b/java/res/xml-sw600dp/rows_myanmar.xml
@@ -24,7 +24,7 @@
     <include
         latin:keyboardLayout="@xml/key_styles_common" />
     <Row
-        latin:keyWidth="8.1818%p"
+        latin:keyWidth="9.0%p"
     >
         <include
             latin:keyboardLayout="@xml/rowkeys_myanmar1" />
@@ -33,40 +33,30 @@
             latin:keyWidth="fillRight" />
         </Row>
     <Row
-        latin:keyWidth="8.1818%p"
+        latin:keyWidth="9.0%p"
     >
         <include
             latin:keyboardLayout="@xml/rowkeys_myanmar2" />
     </Row>
     <Row
-        latin:keyWidth="8.1818%p"
+        latin:keyWidth="9.0%p"
     >
         <include
-            latin:keyXPos="4.0909%p"
             latin:keyboardLayout="@xml/rowkeys_myanmar3" />
         <Key
             latin:keyStyle="enterKeyStyle"
             latin:keyWidth="fillRight" />
     </Row>
     <Row
-        latin:keyWidth="8.1818%p"
+        latin:keyWidth="9.0%p"
     >
         <Key
             latin:keyStyle="shiftKeyStyle"
             latin:keyWidth="10.0%p" />
         <include
             latin:keyboardLayout="@xml/rowkeys_myanmar4" />
-        <switch>
-            <case
-                latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
-            >
-                <Spacer />
-            </case>
-            <default>
-                <include
-                    latin:keyboardLayout="@xml/keys_exclamation_question" />
-            </default>
-        </switch>
+        <include
+            latin:keyboardLayout="@xml/keys_exclamation_question" />
     </Row>
     <include
         latin:keyboardLayout="@xml/row_qwerty4" />
diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml
index 6d8f787..28eceb8 100644
--- a/java/res/xml/method.xml
+++ b/java/res/xml/method.xml
@@ -57,6 +57,7 @@
     in: Indonesian/qwerty    # "id" is the official language code of Indonesian.
     is: Icelandic/qwerty
     it: Italian/qwerty
+    it_CH: Italian (Switzerland)/swiss
     iw: Hebrew/hebrew        # "he" is the official language code of Hebrew.
     ka_GE: Georgian (Georgia)/georgian
     kk: Kazakh/east_slavic
@@ -328,6 +329,8 @@
             android:imeSubtypeExtraValue="KeyboardLayoutSet=hindi,EmojiCapable"
             android:isAsciiCapable="false"
     />
+    <!-- TODO: This hindi_compact keyboard is a preliminary layout.
+               This isn't based on the final specification. -->
     <subtype android:icon="@drawable/ic_ime_switcher_dark"
             android:label="@string/subtype_generic_compact"
             android:subtypeId="0xe49c89a1"
@@ -385,6 +388,14 @@
             android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
             android:isAsciiCapable="true"
     />
+    <subtype android:icon="@drawable/ic_ime_switcher_dark"
+            android:label="@string/subtype_generic"
+            android:subtypeId="0xd914fe1a"
+            android:imeSubtypeLocale="it_CH"
+            android:imeSubtypeMode="keyboard"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=swiss,AsciiCapable,EmojiCapable"
+            android:isAsciiCapable="true"
+    />
     <!-- Java uses the deprecated "iw" code instead of the standard "he" code for Hebrew. -->
     <subtype android:icon="@drawable/ic_ime_switcher_dark"
             android:label="@string/subtype_generic"
@@ -466,8 +477,6 @@
             android:imeSubtypeExtraValue="KeyboardLayoutSet=mongolian,EmojiCapable"
             android:isAsciiCapable="false"
     />
-    <!-- TODO: This Myanmar keyboard is a preliminary layout.
-               This isn't based on the final specification. -->
     <subtype android:icon="@drawable/ic_ime_switcher_dark"
             android:label="@string/subtype_generic"
             android:subtypeId="0x84c87c61"
@@ -476,6 +485,8 @@
             android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
             android:isAsciiCapable="true"
     />
+    <!-- TODO: This Myanmar keyboard is a preliminary layout.
+               This isn't based on the final specification. -->
     <subtype android:icon="@drawable/ic_ime_switcher_dark"
             android:label="@string/subtype_generic"
             android:subtypeId="0xea266ea4"
diff --git a/java/res/xml/rowkeys_greek1.xml b/java/res/xml/rowkeys_greek1.xml
index c5033d0..6d76779 100644
--- a/java/res/xml/rowkeys_greek1.xml
+++ b/java/res/xml/rowkeys_greek1.xml
@@ -69,7 +69,7 @@
         latin:keySpec="&#x03B5;"
         latin:keyHintLabel="3"
         latin:additionalMoreKeys="3"
-        latin:moreKeys="&#x03AD;" />
+        latin:moreKeys="&#x03AD;,%" />
     <!-- U+03C1: "ρ" GREEK SMALL LETTER RHO -->
     <Key
         latin:keySpec="&#x03C1;"
@@ -88,7 +88,7 @@
         latin:keySpec="&#x03C5;"
         latin:keyHintLabel="6"
         latin:additionalMoreKeys="6"
-        latin:moreKeys="&#x03CD;,&#x03CB;,&#x03B0;" />
+        latin:moreKeys="&#x03CD;,%,&#x03CB;,&#x03B0;" />
     <!-- U+03B8: "θ" GREEK SMALL LETTER THETA -->
     <Key
         latin:keySpec="&#x03B8;"
@@ -102,14 +102,14 @@
         latin:keySpec="&#x03B9;"
         latin:keyHintLabel="8"
         latin:additionalMoreKeys="8"
-        latin:moreKeys="&#x03AF;,&#x03CA;,&#x0390;" />
+        latin:moreKeys="&#x03AF;,%,&#x03CA;,&#x0390;" />
     <!-- U+03BF: "ο" GREEK SMALL LETTER OMICRON
          U+03CC: "ό" GREEK SMALL LETTER OMICRON WITH TONOS -->
     <Key
         latin:keySpec="&#x03BF;"
         latin:keyHintLabel="9"
         latin:additionalMoreKeys="9"
-        latin:moreKeys="&#x03CC;" />
+        latin:moreKeys="&#x03CC;,%" />
     <!-- U+03C0: "π" GREEK SMALL LETTER PI -->
     <Key
         latin:keySpec="&#x03C0;"
diff --git a/java/res/xml/rowkeys_myanmar1.xml b/java/res/xml/rowkeys_myanmar1.xml
index 6460af5..b7c8209 100644
--- a/java/res/xml/rowkeys_myanmar1.xml
+++ b/java/res/xml/rowkeys_myanmar1.xml
@@ -25,50 +25,49 @@
         <case
             latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
         >
-            <!-- U+100E: "ဎ" MYANMAR LETTER DDHA -->
+            <!-- U+1027: "ဧ" MYANMAR LETTER E -->
             <Key
-                latin:keySpec="&#x100E;"
+                latin:keySpec="&#x1027;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+100D: "ဍ" MYANMAR LETTER DDA -->
+            <!-- U+104F: "၏" MYANMAR SYMBOL GENITIVE -->
             <Key
-                latin:keySpec="&#x100D;"
+                latin:keySpec="&#x104F;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+1052: "ၒ" MYANMAR LETTER VOCALIC R -->
+            <!-- U+1024: "ဤ" MYANMAR LETTER II -->
             <Key
-                latin:keySpec="&#x1052;"
+                latin:keySpec="&#x1024;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+100B: "ဋ" MYANMAR LETTER TTA -->
+            <!-- U+1023: "ဣ" MYANMAR LETTER I -->
             <Key
-                latin:keySpec="&#x100B;"
+                latin:keySpec="&#x1023;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+1053: "ၓ" MYANMAR LETTER VOCALIC RR -->
+            <!-- U+104E: "၎" MYANMAR SYMBOL AFOREMENTIONED -->
             <Key
-                latin:keySpec="&#x1053;"
+                latin:keySpec="&#x104E;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+1054: "ၔ" MYANMAR LETTER VOCALIC L -->
+            <!-- U+1000/U+103B/U+1015/U+103A: "ကျပ်"
+                 MYANMAR LETTER KA/MYANMAR CONSONANT SIGN MEDIAL YA/MYANMAR LETTER PA/MYANMAR SIGN ASAT -->
             <Key
-                latin:keySpec="&#x1054;"
+                latin:keySpec="&#x1000;&#x103B;&#x1015;&#x103A;"
+                latin:keyLabelFlags="fontNormal|followKeyLetterRatio|autoScale" />
+            <!-- U+1029: "ဩ" MYANMAR LETTER O -->
+            <Key
+                latin:keySpec="&#x1029;"
+                latin:keyLabelFlags="fontNormal|autoScale" />
+            <!-- U+102A: "ဪ" MYANMAR LETTER AU -->
+            <Key
+                latin:keySpec="&#x102A;"
+                latin:keyLabelFlags="fontNormal|autoScale" />
+            <!-- U+104D: "၍" MYANMAR SYMBOL COMPLETED -->
+            <Key
+                latin:keySpec="&#x104D;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+1055: "ၕ" MYANMAR LETTER VOCALIC LL -->
+            <!-- U+104C: "၌" MYANMAR SYMBOL LOCATIVE -->
             <Key
-                latin:keySpec="&#x1055;"
+                latin:keySpec="&#x104C;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+101B: "ရ" MYANMAR LETTER RA -->
-            <Key
-                latin:keySpec="&#x101B;"
-                latin:keyLabelFlags="fontNormal" />
-            <Key
-                latin:keySpec="*" />
-            <Key
-                latin:keySpec="(" />
-            <Key
-                latin:keySpec=")" />
         </case>
         <default>
-            <!-- U+1050: "ၐ" MYANMAR LETTER SHA -->
-            <Key
-                latin:keySpec="&#x1050;"
-                latin:keyLabelFlags="fontNormal" />
             <!-- U+1041: "၁" MYANMAR DIGIT ONE -->
             <Key
                 latin:keySpec="&#x1041;"
diff --git a/java/res/xml/rowkeys_myanmar2.xml b/java/res/xml/rowkeys_myanmar2.xml
index 558c38d..5f0115f 100644
--- a/java/res/xml/rowkeys_myanmar2.xml
+++ b/java/res/xml/rowkeys_myanmar2.xml
@@ -25,49 +25,45 @@
         <case
             latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
         >
-            <!-- U+1008: "ဈ" MYANMAR LETTER JHA -->
+            <!-- U+1017: "ဗ" MYANMAR LETTER BA -->
             <Key
-                latin:keySpec="&#x1008;"
+                latin:keySpec="&#x1017;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+101D: "ဝ" MYANMAR LETTER WA -->
+            <!-- U+1012: "ဒ" MYANMAR LETTER DA -->
             <Key
-                latin:keySpec="&#x101D;"
+                latin:keySpec="&#x1012;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+1023: "ဣ" MYANMAR LETTER I -->
+            <!-- U+1013: "ဓ" MYANMAR LETTER DHA -->
             <Key
-                latin:keySpec="&#x1023;"
+                latin:keySpec="&#x1013;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+104E: "၎" MYANMAR SYMBOL AFOREMENTIONED -->
+            <!-- U+1003: "ဃ" MYANMAR LETTER GHA -->
             <Key
-                latin:keySpec="&#x104E;"
+                latin:keySpec="&#x1003;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+1024: "ဤ" MYANMAR LETTER II -->
+            <!-- U+100E: "ဎ" MYANMAR LETTER DDHA -->
             <Key
-                latin:keySpec="&#x1024;"
-                latin:keyLabelFlags="fontNormal" />
-            <!-- U+104C: "၌" MYANMAR SYMBOL LOCATIVE -->
-            <Key
-                latin:keySpec="&#x104C;"
-                latin:keyLabelFlags="fontNormal" />
-            <!-- U+1025: "ဥ" MYANMAR LETTER U -->
-            <Key
-                latin:keySpec="&#x1025;"
-                latin:keyLabelFlags="fontNormal" />
-            <!-- U+104D: "၍" MYANMAR SYMBOL COMPLETED -->
-            <Key
-                latin:keySpec="&#x104D;"
+                latin:keySpec="&#x100E;"
                 latin:keyLabelFlags="fontNormal" />
             <!-- U+103F: "ဿ" MYANMAR LETTER GREAT SA -->
             <Key
                 latin:keySpec="&#x103F;"
-                latin:keyLabelFlags="fontNormal|autoXScale" />
+                latin:keyLabelFlags="fontNormal" />
             <!-- U+100F: "ဏ" MYANMAR LETTER NNA -->
             <Key
                 latin:keySpec="&#x100F;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+1027: "ဧ" MYANMAR LETTER E -->
+            <!-- U+1008: "ဈ" MYANMAR LETTER JHA -->
             <Key
-                latin:keySpec="&#x1027;"
+                latin:keySpec="&#x1008;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1007: "ဇ" MYANMAR LETTER JA -->
+            <Key
+                latin:keySpec="&#x1007;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1002: "ဂ" MYANMAR LETTER GA -->
+            <Key
+                latin:keySpec="&#x1002;"
                 latin:keyLabelFlags="fontNormal" />
         </case>
         <default>
@@ -111,10 +107,6 @@
             <Key
                 latin:keySpec="&#x1005;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+101F: "ဟ" MYANMAR LETTER HA -->
-            <Key
-                latin:keySpec="&#x101F;"
-                latin:keyLabelFlags="fontNormal" />
         </default>
     </switch>
 </merge>
diff --git a/java/res/xml/rowkeys_myanmar3.xml b/java/res/xml/rowkeys_myanmar3.xml
index 2d0d48c..612bcd3 100644
--- a/java/res/xml/rowkeys_myanmar3.xml
+++ b/java/res/xml/rowkeys_myanmar3.xml
@@ -25,10 +25,18 @@
         <case
             latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
         >
-            <!-- U+1017: "ဗ" MYANMAR LETTER BA -->
+            <!-- U+101A: "ယ" MYANMAR LETTER YA -->
             <Key
-                latin:keySpec="&#x1017;"
+                latin:keySpec="&#x101A;"
                 latin:keyLabelFlags="fontNormal" />
+            <!-- U+1039: "္" MYANMAR SIGN VIRAMA -->
+            <Key
+                latin:keySpec="&#x1039;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1004/U+103A/U+1039: "င်္င" MYANMAR LETTER NGA/MYANMAR SIGN ASAT/MYANMAR SIGN VIRAMA -->
+            <Key
+                latin:keySpec="&#x1004;&#x103A;&#x1039;"
+                latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
             <!-- U+103E: "ှ" MYANMAR CONSONANT SIGN MEDIAL HA -->
             <Key
                 latin:keySpec="&#x103E;"
@@ -37,33 +45,25 @@
             <Key
                 latin:keySpec="&#x102E;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+1039: "္" MYANMAR SIGN VIRAMA -->
+            <!-- U+1030: "ူ" MYANMAR VOWEL SIGN UU -->
             <Key
-                latin:keySpec="&#x1039;"
+                latin:keySpec="&#x1030;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+103D: "ွ" MYANMAR CONSONANT SIGN MEDIAL WA -->
+            <!-- U+102B: "ါ" MYANMAR VOWEL SIGN TALL AA -->
             <Key
-                latin:keySpec="&#x103D;"
-                latin:keyLabelFlags="fontNormal" />
-            <!-- U+1036: "ံ" MYANMAR SIGN ANUSVARA -->
-            <Key
-                latin:keySpec="&#x1036;"
+                latin:keySpec="&#x102B;"
                 latin:keyLabelFlags="fontNormal" />
             <!-- U+1032: "ဲ" MYANMAR VOWEL SIGN AI -->
             <Key
                 latin:keySpec="&#x1032;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+1012: "ဒ" MYANMAR LETTER DA -->
+            <!-- U+1036: "ံ" MYANMAR SIGN ANUSVARA -->
             <Key
-                latin:keySpec="&#x1012;"
+                latin:keySpec="&#x1036;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+1013: "ဓ" MYANMAR LETTER DHA -->
+            <!-- U+101F: "ဟ" MYANMAR LETTER HA -->
             <Key
-                latin:keySpec="&#x1013;"
-                latin:keyLabelFlags="fontNormal" />
-            <!-- U+1002: "ဂ" MYANMAR LETTER GA -->
-            <Key
-                latin:keySpec="&#x1002;"
+                latin:keySpec="&#x101F;"
                 latin:keyLabelFlags="fontNormal" />
         </case>
         <default>
@@ -75,33 +75,44 @@
             <Key
                 latin:keySpec="&#x103B;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+102D: "ိ" MYANMAR VOWEL SIGN I -->
-            <Key
-                latin:keySpec="&#x102D;"
-                latin:keyLabelFlags="fontNormal" />
-            <!-- U+103A: "်" MYANMAR SIGN ASAT -->
-            <Key
-                latin:keySpec="&#x103A;"
-                latin:keyLabelFlags="fontNormal" />
-            <!-- U+102B: "ါ" MYANMAR VOWEL SIGN TALL AA -->
-            <Key
-                latin:keySpec="&#x102B;"
-                latin:keyLabelFlags="fontNormal" />
-            <!-- U+1037: "့" MYANMAR SIGN DOT BELOW -->
-            <Key
-                latin:keySpec="&#x1037;"
-                latin:keyLabelFlags="fontNormal" />
             <!-- U+103C: "ြ" MYANMAR CONSONANT SIGN MEDIAL RA -->
             <Key
                 latin:keySpec="&#x103C;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+102F: "ု" MYANMAR VOWEL SIGN U -->
+            <!-- U+103D: "ွ" MYANMAR CONSONANT SIGN MEDIAL WA
+                 U+103E: "ှ" MYANMAR CONSONANT SIGN MEDIAL HA
+                 U+103D/U+103E: "ွှ" MYANMAR CONSONANT SIGN MEDIAL WA/MYANMAR CONSONANT SIGN MEDIAL HA -->
+            <Key
+                latin:keySpec="&#x103D;"
+                latin:moreKeys="&#x103E;,&#x103D;&#x103E;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+102D: "ိ" MYANMAR VOWEL SIGN I
+                 U+102E: "ီ" MYANMAR VOWEL SIGN II -->
+            <Key
+                latin:keySpec="&#x102D;"
+                latin:moreKeys="&#x102E;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+102F: "ု" MYANMAR VOWEL SIGN U
+                 U+1030: "ူ" MYANMAR VOWEL SIGN UU -->
             <Key
                 latin:keySpec="&#x102F;"
+                latin:moreKeys="&#x1030;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+1030: "ူ" MYANMAR VOWEL SIGN UU -->
+            <!-- U+102C: "ာ" MYANMAR VOWEL SIGN AA -->
             <Key
-                latin:keySpec="&#x1030;"
+                latin:keySpec="&#x102C;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+103A: "်" MYANMAR SIGN ASAT
+                 U+1032: "ဲ" MYANMAR VOWEL SIGN AI -->
+            <Key
+                latin:keySpec="&#x103A;"
+                latin:moreKeys="&#x1032;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1037: "့" MYANMAR SIGN DOT BELOW
+                 U+1036: "ံ" MYANMAR SIGN ANUSVARA -->
+            <Key
+                latin:keySpec="&#x1037;"
+                latin:moreKeys="&#x1036;"
                 latin:keyLabelFlags="fontNormal" />
             <!-- U+1038: "း" MYANMAR SIGN VISARGA -->
             <Key
diff --git a/java/res/xml/rowkeys_myanmar4.xml b/java/res/xml/rowkeys_myanmar4.xml
index cfd1112..57466c5 100644
--- a/java/res/xml/rowkeys_myanmar4.xml
+++ b/java/res/xml/rowkeys_myanmar4.xml
@@ -25,42 +25,40 @@
         <case
             latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
         >
-            <!-- U+1007: "ဇ" MYANMAR LETTER JA -->
+            <!-- U+1025: "ဥ" MYANMAR LETTER U -->
             <Key
-                latin:keySpec="&#x1007;"
-                latin:keyLabelFlags="fontNormal" />
-            <!-- U+100C: "ဌ" MYANMAR LETTER TTHA -->
-            <Key
-                latin:keySpec="&#x100C;"
-                latin:keyLabelFlags="fontNormal" />
-            <!-- U+1003: "ဃ" MYANMAR LETTER GHA -->
-            <Key
-                latin:keySpec="&#x1003;"
-                latin:keyLabelFlags="fontNormal" />
-            <!-- U+1020: "ဠ" MYANMAR LETTER LLA -->
-            <Key
-                latin:keySpec="&#x1020;"
-                latin:keyLabelFlags="fontNormal" />
-            <!-- U+101A: "ယ" MYANMAR LETTER YA -->
-            <Key
-                latin:keySpec="&#x101A;"
-                latin:keyLabelFlags="fontNormal" />
-            <!-- U+1009: "ဉ" MYANMAR LETTER NYA -->
-            <Key
-                latin:keySpec="&#x1009;"
+                latin:keySpec="&#x1025;"
                 latin:keyLabelFlags="fontNormal" />
             <!-- U+1026: "ဦ" MYANMAR LETTER UU -->
             <Key
                 latin:keySpec="&#x1026;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+102A: "ဪ" MYANMAR LETTER AU -->
+            <!-- U+100C: "ဌ" MYANMAR LETTER TTHA -->
             <Key
-                latin:keySpec="&#x102A;"
-                latin:keyLabelFlags="fontNormal|autoXScale" />
-            <!-- U+1051: "ၑ" MYANMAR LETTER SSA -->
-            <Key
-                latin:keySpec="&#x1051;"
+                latin:keySpec="&#x100C;"
                 latin:keyLabelFlags="fontNormal" />
+            <!-- U+100B: "ဋ" MYANMAR LETTER TTA -->
+            <Key
+                latin:keySpec="&#x100B;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+100D: "ဍ" MYANMAR LETTER DDA -->
+            <Key
+                latin:keySpec="&#x100D;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1020: "ဠ" MYANMAR LETTER LLA -->
+            <Key
+                latin:keySpec="&#x1020;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+100B/U+1039/U+100C: "ဋ္ဌ" MYANMAR LETTER TTA/MYANMAR SIGN VIRAMA/MYANMAR LETTER TTHA -->
+            <Key
+                latin:keySpec="&#x100B;&#x1039;&#x100C;"
+                latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+            <!-- U+100F/U+1039/U+100D: "ဏ္ဍ" MYANMAR LETTER NNA/MYANMAR SIGN VIRAMA/MYANMAR LETTER DDA
+                 U+100F/U+1039/U+100C: "ဏ္ဌ" MYANMAR LETTER NNA/MYANMAR SIGN VIRAMA/MYANMAR LETTER TTHA -->
+            <Key
+                latin:keySpec="&#x100F;&#x1039;&#x100D;"
+                latin:moreKeys="&#x100F;&#x1039;&#x100C;"
+                latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
         </case>
         <default>
             <!-- U+1016: "ဖ" MYANMAR LETTER PHA -->
@@ -83,21 +81,19 @@
             <Key
                 latin:keySpec="&#x1018;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+100A: "ည" MYANMAR LETTER NNYA -->
+            <!-- U+100A: "ည" MYANMAR LETTER NNYA
+                 U+1009: "ဉ" MYANMAR LETTER NYA -->
             <Key
                 latin:keySpec="&#x100A;"
+                latin:moreKeys="&#x1009;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+102C: "ာ" MYANMAR VOWEL SIGN AA -->
+            <!-- U+101B: "ရ" MYANMAR LETTER RA -->
             <Key
-                latin:keySpec="&#x102C;"
+                latin:keySpec="&#x101B;"
                 latin:keyLabelFlags="fontNormal" />
-            <!-- U+1029: "ဩ" MYANMAR LETTER O -->
+            <!-- U+101D: "ဝ" MYANMAR LETTER WA -->
             <Key
-                latin:keySpec="&#x1029;"
-                latin:keyLabelFlags="fontNormal" />
-            <!-- U+104F: "၏" MYANMAR SYMBOL GENITIVE -->
-            <Key
-                latin:keySpec="&#x104F;"
+                latin:keySpec="&#x101D;"
                 latin:keyLabelFlags="fontNormal" />
         </default>
     </switch>
diff --git a/java/res/xml/rows_myanmar.xml b/java/res/xml/rows_myanmar.xml
index 32c923d..5de47f7 100644
--- a/java/res/xml/rows_myanmar.xml
+++ b/java/res/xml/rows_myanmar.xml
@@ -24,26 +24,25 @@
     <include
         latin:keyboardLayout="@xml/key_styles_common" />
     <Row
-        latin:keyWidth="9.0909%p"
+        latin:keyWidth="10.0%p"
     >
         <include
             latin:keyboardLayout="@xml/rowkeys_myanmar1" />
     </Row>
     <Row
-        latin:keyWidth="9.0909%p"
+        latin:keyWidth="10.0%p"
     >
         <include
             latin:keyboardLayout="@xml/rowkeys_myanmar2" />
     </Row>
     <Row
-        latin:keyWidth="9.0909%p"
+        latin:keyWidth="10.0%p"
     >
         <include
-            latin:keyXPos="4.5454%p"
             latin:keyboardLayout="@xml/rowkeys_myanmar3" />
     </Row>
     <Row
-        latin:keyWidth="9.0909%p"
+        latin:keyWidth="10.0%p"
     >
         <Key
             latin:keyStyle="shiftKeyStyle" />
diff --git a/java/src/com/android/inputmethod/compat/LooperCompatUtils.java b/java/src/com/android/inputmethod/compat/LooperCompatUtils.java
new file mode 100644
index 0000000..d647dbb
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/LooperCompatUtils.java
@@ -0,0 +1,42 @@
+/*
+ * 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.compat;
+
+import android.os.Looper;
+
+import java.lang.reflect.Method;
+
+/**
+ * Helper to call Looper#quitSafely, which was introduced in API
+ * level 18 (Build.VERSION_CODES.JELLY_BEAN_MR2).
+ *
+ * In unit tests, we create lots of instances of LatinIME, which means we need to clean up
+ * some Loopers lest we leak file descriptors. In normal use on a device though, this is never
+ * necessary (although it does not hurt).
+ */
+public final class LooperCompatUtils {
+    private static final Method METHOD_quitSafely = CompatUtils.getMethod(
+            Looper.class, "quitSafely");
+
+    public static void quitSafely(final Looper looper) {
+        if (null != METHOD_quitSafely) {
+            CompatUtils.invoke(looper, null /* default return value */, METHOD_quitSafely);
+        } else {
+            looper.quit();
+        }
+    }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 2e4a090..949f037 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -297,12 +297,19 @@
     }
 
     // Implements {@link KeyboardState.SwitchActions}.
+    // TODO[IL]: merge the two following methods; remove the one without args.
     @Override
     public void requestUpdatingShiftState() {
         mState.onUpdateShiftState(mLatinIME.getCurrentAutoCapsState(),
                 mLatinIME.getCurrentRecapitalizeState());
     }
 
+    // Future method for requesting an updating to the shift state.
+    public void requestUpdatingShiftState(final int currentAutoCapsState,
+            final int currentRecapitalizeState) {
+        mState.onUpdateShiftState(currentAutoCapsState, currentRecapitalizeState);
+    }
+
     // Implements {@link KeyboardState.SwitchActions}.
     @Override
     public void startDoubleTapShiftKeyTimer() {
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
index f0356df..14fa767 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
@@ -120,98 +120,98 @@
         /*  30: 5 */ "keyspec_east_slavic_row3_5",
         /*  31: 5 */ "morekeys_cyrillic_soft_sign",
         /*  32: 4 */ "morekeys_nordic_row2_11",
-        /*  33: 4 */ "keyspec_symbols_1",
-        /*  34: 4 */ "keyspec_symbols_2",
-        /*  35: 4 */ "keyspec_symbols_3",
-        /*  36: 4 */ "keyspec_symbols_4",
-        /*  37: 4 */ "keyspec_symbols_5",
-        /*  38: 4 */ "keyspec_symbols_6",
-        /*  39: 4 */ "keyspec_symbols_7",
-        /*  40: 4 */ "keyspec_symbols_8",
-        /*  41: 4 */ "keyspec_symbols_9",
-        /*  42: 4 */ "keyspec_symbols_0",
-        /*  43: 4 */ "keylabel_to_symbol",
-        /*  44: 4 */ "additional_morekeys_symbols_1",
-        /*  45: 4 */ "additional_morekeys_symbols_2",
-        /*  46: 4 */ "additional_morekeys_symbols_3",
-        /*  47: 4 */ "additional_morekeys_symbols_4",
-        /*  48: 4 */ "additional_morekeys_symbols_5",
-        /*  49: 4 */ "additional_morekeys_symbols_6",
-        /*  50: 4 */ "additional_morekeys_symbols_7",
-        /*  51: 4 */ "additional_morekeys_symbols_8",
-        /*  52: 4 */ "additional_morekeys_symbols_9",
-        /*  53: 4 */ "additional_morekeys_symbols_0",
-        /*  54: 3 */ "morekeys_punctuation",
-        /*  55: 3 */ "morekeys_star",
-        /*  56: 3 */ "keyspec_left_parenthesis",
-        /*  57: 3 */ "keyspec_right_parenthesis",
-        /*  58: 3 */ "keyspec_left_square_bracket",
-        /*  59: 3 */ "keyspec_right_square_bracket",
-        /*  60: 3 */ "keyspec_left_curly_bracket",
-        /*  61: 3 */ "keyspec_right_curly_bracket",
-        /*  62: 3 */ "keyspec_less_than",
-        /*  63: 3 */ "keyspec_greater_than",
-        /*  64: 3 */ "keyspec_less_than_equal",
-        /*  65: 3 */ "keyspec_greater_than_equal",
-        /*  66: 3 */ "keyspec_left_double_angle_quote",
-        /*  67: 3 */ "keyspec_right_double_angle_quote",
-        /*  68: 3 */ "keyspec_left_single_angle_quote",
-        /*  69: 3 */ "keyspec_right_single_angle_quote",
-        /*  70: 3 */ "keyspec_tablet_comma",
-        /*  71: 3 */ "morekeys_tablet_period",
-        /*  72: 3 */ "morekeys_question",
-        /*  73: 2 */ "morekeys_h",
-        /*  74: 2 */ "morekeys_w",
-        /*  75: 2 */ "morekeys_east_slavic_row2_2",
-        /*  76: 2 */ "morekeys_cyrillic_u",
-        /*  77: 2 */ "morekeys_cyrillic_en",
-        /*  78: 2 */ "morekeys_cyrillic_ghe",
-        /*  79: 2 */ "morekeys_cyrillic_o",
-        /*  80: 2 */ "morekeys_cyrillic_i",
-        /*  81: 2 */ "keyspec_south_slavic_row1_6",
-        /*  82: 2 */ "keyspec_south_slavic_row2_11",
-        /*  83: 2 */ "keyspec_south_slavic_row3_1",
-        /*  84: 2 */ "keyspec_south_slavic_row3_8",
-        /*  85: 2 */ "keyspec_swiss_row1_11",
-        /*  86: 2 */ "keyspec_swiss_row2_10",
-        /*  87: 2 */ "keyspec_swiss_row2_11",
-        /*  88: 2 */ "morekeys_swiss_row1_11",
-        /*  89: 2 */ "morekeys_swiss_row2_10",
-        /*  90: 2 */ "morekeys_swiss_row2_11",
-        /*  91: 2 */ "keyspec_spanish_row2_10",
-        /*  92: 2 */ "morekeys_bullet",
-        /*  93: 2 */ "morekeys_left_parenthesis",
-        /*  94: 2 */ "morekeys_right_parenthesis",
-        /*  95: 2 */ "morekeys_arabic_diacritics",
-        /*  96: 2 */ "keyspec_comma",
-        /*  97: 2 */ "keyhintlabel_tablet_comma",
-        /*  98: 2 */ "morekeys_tablet_comma",
-        /*  99: 2 */ "keyhintlabel_period",
-        /* 100: 2 */ "morekeys_period",
-        /* 101: 2 */ "keyhintlabel_tablet_period",
-        /* 102: 2 */ "keyspec_symbols_question",
-        /* 103: 2 */ "keyspec_symbols_semicolon",
-        /* 104: 2 */ "keyspec_symbols_percent",
-        /* 105: 2 */ "morekeys_symbols_semicolon",
-        /* 106: 2 */ "morekeys_symbols_percent",
-        /* 107: 1 */ "morekeys_v",
-        /* 108: 1 */ "morekeys_j",
-        /* 109: 1 */ "morekeys_q",
-        /* 110: 1 */ "morekeys_x",
-        /* 111: 1 */ "keyspec_q",
-        /* 112: 1 */ "keyspec_w",
-        /* 113: 1 */ "keyspec_y",
-        /* 114: 1 */ "keyspec_x",
-        /* 115: 1 */ "morekeys_east_slavic_row2_11",
-        /* 116: 1 */ "morekeys_cyrillic_ka",
-        /* 117: 1 */ "morekeys_cyrillic_a",
-        /* 118: 1 */ "morekeys_currency_dollar",
-        /* 119: 1 */ "morekeys_tablet_punctuation",
-        /* 120: 1 */ "morekeys_plus",
-        /* 121: 1 */ "morekeys_less_than",
-        /* 122: 1 */ "morekeys_greater_than",
-        /* 123: 1 */ "keyspec_period",
-        /* 124: 1 */ "keyspec_tablet_period",
+        /*  33: 4 */ "morekeys_punctuation",
+        /*  34: 4 */ "keyspec_symbols_1",
+        /*  35: 4 */ "keyspec_symbols_2",
+        /*  36: 4 */ "keyspec_symbols_3",
+        /*  37: 4 */ "keyspec_symbols_4",
+        /*  38: 4 */ "keyspec_symbols_5",
+        /*  39: 4 */ "keyspec_symbols_6",
+        /*  40: 4 */ "keyspec_symbols_7",
+        /*  41: 4 */ "keyspec_symbols_8",
+        /*  42: 4 */ "keyspec_symbols_9",
+        /*  43: 4 */ "keyspec_symbols_0",
+        /*  44: 4 */ "keylabel_to_symbol",
+        /*  45: 4 */ "additional_morekeys_symbols_1",
+        /*  46: 4 */ "additional_morekeys_symbols_2",
+        /*  47: 4 */ "additional_morekeys_symbols_3",
+        /*  48: 4 */ "additional_morekeys_symbols_4",
+        /*  49: 4 */ "additional_morekeys_symbols_5",
+        /*  50: 4 */ "additional_morekeys_symbols_6",
+        /*  51: 4 */ "additional_morekeys_symbols_7",
+        /*  52: 4 */ "additional_morekeys_symbols_8",
+        /*  53: 4 */ "additional_morekeys_symbols_9",
+        /*  54: 4 */ "additional_morekeys_symbols_0",
+        /*  55: 4 */ "keyspec_tablet_comma",
+        /*  56: 3 */ "keyspec_swiss_row1_11",
+        /*  57: 3 */ "keyspec_swiss_row2_10",
+        /*  58: 3 */ "keyspec_swiss_row2_11",
+        /*  59: 3 */ "morekeys_swiss_row1_11",
+        /*  60: 3 */ "morekeys_swiss_row2_10",
+        /*  61: 3 */ "morekeys_swiss_row2_11",
+        /*  62: 3 */ "morekeys_star",
+        /*  63: 3 */ "keyspec_left_parenthesis",
+        /*  64: 3 */ "keyspec_right_parenthesis",
+        /*  65: 3 */ "keyspec_left_square_bracket",
+        /*  66: 3 */ "keyspec_right_square_bracket",
+        /*  67: 3 */ "keyspec_left_curly_bracket",
+        /*  68: 3 */ "keyspec_right_curly_bracket",
+        /*  69: 3 */ "keyspec_less_than",
+        /*  70: 3 */ "keyspec_greater_than",
+        /*  71: 3 */ "keyspec_less_than_equal",
+        /*  72: 3 */ "keyspec_greater_than_equal",
+        /*  73: 3 */ "keyspec_left_double_angle_quote",
+        /*  74: 3 */ "keyspec_right_double_angle_quote",
+        /*  75: 3 */ "keyspec_left_single_angle_quote",
+        /*  76: 3 */ "keyspec_right_single_angle_quote",
+        /*  77: 3 */ "morekeys_tablet_comma",
+        /*  78: 3 */ "keyhintlabel_period",
+        /*  79: 3 */ "morekeys_tablet_period",
+        /*  80: 3 */ "morekeys_question",
+        /*  81: 2 */ "morekeys_h",
+        /*  82: 2 */ "morekeys_w",
+        /*  83: 2 */ "morekeys_east_slavic_row2_2",
+        /*  84: 2 */ "morekeys_cyrillic_u",
+        /*  85: 2 */ "morekeys_cyrillic_en",
+        /*  86: 2 */ "morekeys_cyrillic_ghe",
+        /*  87: 2 */ "morekeys_cyrillic_o",
+        /*  88: 2 */ "morekeys_cyrillic_i",
+        /*  89: 2 */ "keyspec_south_slavic_row1_6",
+        /*  90: 2 */ "keyspec_south_slavic_row2_11",
+        /*  91: 2 */ "keyspec_south_slavic_row3_1",
+        /*  92: 2 */ "keyspec_south_slavic_row3_8",
+        /*  93: 2 */ "morekeys_tablet_punctuation",
+        /*  94: 2 */ "keyspec_spanish_row2_10",
+        /*  95: 2 */ "morekeys_bullet",
+        /*  96: 2 */ "morekeys_left_parenthesis",
+        /*  97: 2 */ "morekeys_right_parenthesis",
+        /*  98: 2 */ "morekeys_arabic_diacritics",
+        /*  99: 2 */ "keyspec_comma",
+        /* 100: 2 */ "keyhintlabel_tablet_comma",
+        /* 101: 2 */ "keyspec_period",
+        /* 102: 2 */ "morekeys_period",
+        /* 103: 2 */ "keyspec_tablet_period",
+        /* 104: 2 */ "keyhintlabel_tablet_period",
+        /* 105: 2 */ "keyspec_symbols_question",
+        /* 106: 2 */ "keyspec_symbols_semicolon",
+        /* 107: 2 */ "keyspec_symbols_percent",
+        /* 108: 2 */ "morekeys_symbols_semicolon",
+        /* 109: 2 */ "morekeys_symbols_percent",
+        /* 110: 1 */ "morekeys_v",
+        /* 111: 1 */ "morekeys_j",
+        /* 112: 1 */ "morekeys_q",
+        /* 113: 1 */ "morekeys_x",
+        /* 114: 1 */ "keyspec_q",
+        /* 115: 1 */ "keyspec_w",
+        /* 116: 1 */ "keyspec_y",
+        /* 117: 1 */ "keyspec_x",
+        /* 118: 1 */ "morekeys_east_slavic_row2_11",
+        /* 119: 1 */ "morekeys_cyrillic_ka",
+        /* 120: 1 */ "morekeys_cyrillic_a",
+        /* 121: 1 */ "morekeys_currency_dollar",
+        /* 122: 1 */ "morekeys_plus",
+        /* 123: 1 */ "morekeys_less_than",
+        /* 124: 1 */ "morekeys_greater_than",
         /* 125: 1 */ "morekeys_exclamation",
         /* 126: 0 */ "morekeys_currency",
         /* 127: 0 */ "morekeys_symbols_1",
@@ -278,6 +278,7 @@
         /* morekeys_r ~ */
         EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
         /* ~ morekeys_nordic_row2_11 */
+        /* morekeys_punctuation */ "!autoColumnOrder!8,\\,,?,!,#,!text/keyspec_right_parenthesis,!text/keyspec_left_parenthesis,/,;,',@,:,-,\",+,\\%,&",
         /* keyspec_symbols_1 */ "1",
         /* keyspec_symbols_2 */ "2",
         /* keyspec_symbols_3 */ "3",
@@ -293,7 +294,10 @@
         /* additional_morekeys_symbols_1 ~ */
         EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
         /* ~ additional_morekeys_symbols_0 */
-        /* morekeys_punctuation */ "!autoColumnOrder!8,\\,,?,!,#,!text/keyspec_right_parenthesis,!text/keyspec_left_parenthesis,/,;,',@,:,-,\",+,\\%,&",
+        /* keyspec_tablet_comma */ ",",
+        /* keyspec_swiss_row1_11 ~ */
+        EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
+        /* ~ morekeys_swiss_row2_11 */
         // U+2020: "†" DAGGER
         // U+2021: "‡" DOUBLE DAGGER
         // U+2605: "★" BLACK STAR
@@ -320,14 +324,15 @@
         /* keyspec_right_double_angle_quote */ "\u00BB",
         /* keyspec_left_single_angle_quote */ "\u2039",
         /* keyspec_right_single_angle_quote */ "\u203A",
-        /* keyspec_tablet_comma */ ",",
+        /* morekeys_tablet_comma */ EMPTY,
+        /* keyhintlabel_period */ EMPTY,
         /* morekeys_tablet_period */ "!text/morekeys_tablet_punctuation",
         // U+00BF: "¿" INVERTED QUESTION MARK
         /* morekeys_question */ "\u00BF",
         /* morekeys_h ~ */
-        EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-        EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-        /* ~ morekeys_swiss_row2_11 */
+        EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
+        /* ~ keyspec_south_slavic_row3_8 */
+        /* morekeys_tablet_punctuation */ "!autoColumnOrder!7,\\,,',#,!text/keyspec_right_parenthesis,!text/keyspec_left_parenthesis,/,;,@,:,-,\",+,\\%,&",
         // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
         /* keyspec_spanish_row2_10 */ "\u00F1",
         // U+266A: "♪" EIGHTH NOTE
@@ -341,10 +346,11 @@
         /* morekeys_arabic_diacritics */ EMPTY,
         // Comma key
         /* keyspec_comma */ ",",
-        /* keyhintlabel_tablet_comma ~ */
-        EMPTY, EMPTY, EMPTY,
-        /* ~ keyhintlabel_period */
+        /* keyhintlabel_tablet_comma */ EMPTY,
+        // Period key
+        /* keyspec_period */ ".",
         /* morekeys_period */ "!text/morekeys_punctuation",
+        /* keyspec_tablet_period */ ".",
         /* keyhintlabel_tablet_period */ EMPTY,
         /* keyspec_symbols_question */ "?",
         /* keyspec_symbols_semicolon */ ";",
@@ -368,14 +374,10 @@
         // U+00A5: "¥" YEN SIGN
         // U+20B1: "₱" PESO SIGN
         /* morekeys_currency_dollar */ "\u00A2,\u00A3,\u20AC,\u00A5,\u20B1",
-        /* morekeys_tablet_punctuation */ "!autoColumnOrder!7,\\,,',#,!text/keyspec_right_parenthesis,!text/keyspec_left_parenthesis,/,;,@,:,-,\",+,\\%,&",
         // U+00B1: "±" PLUS-MINUS SIGN
         /* morekeys_plus */ "\u00B1",
         /* morekeys_less_than */ "!fixedColumnOrder!3,!text/keyspec_left_single_angle_quote,!text/keyspec_less_than_equal,!text/keyspec_left_double_angle_quote",
         /* morekeys_greater_than */ "!fixedColumnOrder!3,!text/keyspec_right_single_angle_quote,!text/keyspec_greater_than_equal,!text/keyspec_right_double_angle_quote",
-        // Period key
-        /* keyspec_period */ ".",
-        /* keyspec_tablet_period */ ".",
         // U+00A1: "¡" INVERTED EXCLAMATION MARK
         /* morekeys_exclamation */ "\u00A1",
         /* morekeys_currency */ "$,\u00A2,\u20AC,\u00A3,\u00A5,\u20B1",
@@ -534,8 +536,8 @@
         /* keylabel_to_alpha */ "\u0623\u200C\u0628\u200C\u062C",
         /* morekeys_s ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null,
-        /* ~ morekeys_nordic_row2_11 */
+        null, null, null, null, null, null, null, null, null,
+        /* ~ morekeys_punctuation */
         // U+0661: "١" ARABIC-INDIC DIGIT ONE
         /* keyspec_symbols_1 */ "\u0661",
         // U+0662: "٢" ARABIC-INDIC DIGIT TWO
@@ -571,7 +573,13 @@
         // U+066B: "٫" ARABIC DECIMAL SEPARATOR
         // U+066C: "٬" ARABIC THOUSANDS SEPARATOR
         /* additional_morekeys_symbols_0 */ "0,\u066B,\u066C",
-        /* morekeys_punctuation */ null,
+        // U+061F: "؟" ARABIC QUESTION MARK
+        // U+060C: "،" ARABIC COMMA
+        // U+061B: "؛" ARABIC SEMICOLON
+        /* keyspec_tablet_comma */ "\u060C",
+        /* keyspec_swiss_row1_11 ~ */
+        null, null, null, null, null, null,
+        /* ~ morekeys_swiss_row2_11 */
         // U+2605: "★" BLACK STAR
         // U+066D: "٭" ARABIC FIVE POINTED STAR
         /* morekeys_star */ "\u2605,\u066D",
@@ -595,16 +603,14 @@
         /* keyspec_right_double_angle_quote */ "\u00BB|\u00AB",
         /* keyspec_left_single_angle_quote */ "\u2039|\u203A",
         /* keyspec_right_single_angle_quote */ "\u203A|\u2039",
-        // U+061F: "؟" ARABIC QUESTION MARK
-        // U+060C: "،" ARABIC COMMA
-        // U+061B: "؛" ARABIC SEMICOLON
-        /* keyspec_tablet_comma */ "\u060C",
+        /* morekeys_tablet_comma */ "!fixedColumnOrder!4,:,!,\u061F,\u061B,-,/,\",\'",
+        // U+0651: "ّ" ARABIC SHADDA
+        /* keyhintlabel_period */ "\u0651",
         /* morekeys_tablet_period */ "!text/morekeys_arabic_diacritics",
         // U+00BF: "¿" INVERTED QUESTION MARK
         /* morekeys_question */ "?,\u00BF",
         /* morekeys_h ~ */
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         /* ~ keyspec_spanish_row2_10 */
         // U+266A: "♪" EIGHTH NOTE
         /* morekeys_bullet */ "\u266A",
@@ -634,10 +640,9 @@
         // U+060C: "،" ARABIC COMMA
         /* keyspec_comma */ "\u060C",
         /* keyhintlabel_tablet_comma */ "\u061F",
-        /* morekeys_tablet_comma */ "!fixedColumnOrder!4,:,!,\u061F,\u061B,-,/,\",\'",
-        // U+0651: "ّ" ARABIC SHADDA
-        /* keyhintlabel_period */ "\u0651",
+        /* keyspec_period */ null,
         /* morekeys_period */ "!text/morekeys_arabic_diacritics",
+        /* keyspec_tablet_period */ null,
         /* keyhintlabel_tablet_period */ "\u0651",
         /* keyspec_symbols_question */ "\u061F",
         /* keyspec_symbols_semicolon */ "\u061B",
@@ -805,23 +810,19 @@
         /* morekeys_l */ "l\u00B7l,\u0142",
         /* morekeys_g ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null,
-        /* ~ additional_morekeys_symbols_0 */
+        null, null,
+        /* ~ morekeys_nordic_row2_11 */
         // U+00B7: "·" MIDDLE DOT
         /* morekeys_punctuation */ "!autoColumnOrder!9,\\,,?,!,\u00B7,#,),(,/,;,',@,:,-,\",+,\\%,&",
-        /* morekeys_star ~ */
+        /* keyspec_symbols_1 ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null,
-        /* ~ morekeys_swiss_row2_11 */
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        /* ~ keyspec_south_slavic_row3_8 */
+        /* morekeys_tablet_punctuation */ "!autoColumnOrder!8,\\,,',\u00B7,#,),(,/,;,@,:,-,\",+,\\%,&",
         // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
         /* keyspec_spanish_row2_10 */ "\u00E7",
-        /* morekeys_bullet ~ */
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null,
-        /* ~ morekeys_currency_dollar */
-        /* morekeys_tablet_punctuation */ "!autoColumnOrder!8,\\,,',\u00B7,#,),(,/,;,@,:,-,\",+,\\%,&",
     };
 
     /* Locale cs: Czech */
@@ -981,7 +982,7 @@
         // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE
         // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
         // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON
-        /* morekeys_a */ "\u00E4,\u00E2,\u00E0,\u00E1,\u00E6,\u00E3,\u00E5,\u0101",
+        /* morekeys_a */ "\u00E4,%,\u00E2,\u00E0,\u00E1,\u00E6,\u00E3,\u00E5,\u0101",
         // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
         // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
         // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
@@ -990,13 +991,13 @@
         // U+0153: "œ" LATIN SMALL LIGATURE OE
         // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
         // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
-        /* morekeys_o */ "\u00F6,\u00F4,\u00F2,\u00F3,\u00F5,\u0153,\u00F8,\u014D",
+        /* morekeys_o */ "\u00F6,%,\u00F4,\u00F2,\u00F3,\u00F5,\u0153,\u00F8,\u014D",
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
-        /* morekeys_u */ "\u00FC,\u00FB,\u00F9,\u00FA,\u016B",
+        /* morekeys_u */ "\u00FC,%,\u00FB,\u00F9,\u00FA,\u016B",
         // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
         // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
         // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
@@ -1023,10 +1024,8 @@
         /* keyspec_currency ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null,
-        /* ~ keyspec_south_slavic_row3_8 */
+        null, null, null, null, null, null, null,
+        /* ~ keyspec_tablet_comma */
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         /* keyspec_swiss_row1_11 */ "\u00FC",
         // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
@@ -1220,7 +1219,7 @@
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         /* ~ morekeys_question */
         // U+0125: "ĥ" LATIN SMALL LETTER H WITH CIRCUMFLEX
         // U+0127: "ħ" LATIN SMALL LETTER H WITH STROKE
@@ -1228,9 +1227,8 @@
         // U+0175: "ŵ" LATIN SMALL LETTER W WITH CIRCUMFLEX
         /* morekeys_w */ "w,\u0175",
         /* morekeys_east_slavic_row2_2 ~ */
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null,
-        /* ~ morekeys_swiss_row2_11 */
+        null, null, null, null, null, null, null, null, null, null, null,
+        /* ~ morekeys_tablet_punctuation */
         // U+0135: "ĵ" LATIN SMALL LETTER J WITH CIRCUMFLEX
         /* keyspec_spanish_row2_10 */ "\u0135",
         /* morekeys_bullet ~ */
@@ -1305,10 +1303,8 @@
         /* morekeys_n */ "\u00F1,\u0144",
         /* single_quotes ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null,
-        /* ~ additional_morekeys_symbols_0 */
+        null, null, null, null, null, null, null, null, null, null,
+        /* ~ morekeys_nordic_row2_11 */
         // U+00A1: "¡" INVERTED EXCLAMATION MARK
         // U+00BF: "¿" INVERTED QUESTION MARK
         /* morekeys_punctuation */ "!autoColumnOrder!9,\\,,?,!,#,),(,/,;,\u00A1,',@,:,-,\",+,\\%,&,\u00BF",
@@ -1488,8 +1484,8 @@
         // U+FDFC: "﷼" RIAL SIGN
         /* keyspec_currency */ "\uFDFC",
         /* morekeys_r ~ */
-        null, null, null, null, null, null, null, null, null, null, null, null, null,
-        /* ~ morekeys_nordic_row2_11 */
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        /* ~ morekeys_punctuation */
         // U+06F1: "۱" EXTENDED ARABIC-INDIC DIGIT ONE
         /* keyspec_symbols_1 */ "\u06F1",
         // U+06F2: "۲" EXTENDED ARABIC-INDIC DIGIT TWO
@@ -1525,7 +1521,15 @@
         // U+066B: "٫" ARABIC DECIMAL SEPARATOR
         // U+066C: "٬" ARABIC THOUSANDS SEPARATOR
         /* additional_morekeys_symbols_0 */ "0,\u066B,\u066C",
-        /* morekeys_punctuation */ null,
+        // U+060C: "،" ARABIC COMMA
+        // U+061B: "؛" ARABIC SEMICOLON
+        // U+061F: "؟" ARABIC QUESTION MARK
+        // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+        // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+        /* keyspec_tablet_comma */ "\u060C",
+        /* keyspec_swiss_row1_11 ~ */
+        null, null, null, null, null, null,
+        /* ~ morekeys_swiss_row2_11 */
         // U+2605: "★" BLACK STAR
         // U+066D: "٭" ARABIC FIVE POINTED STAR
         /* morekeys_star */ "\u2605,\u066D",
@@ -1543,18 +1547,14 @@
         /* keyspec_right_double_angle_quote */ "\u00BB|\u00AB",
         /* keyspec_left_single_angle_quote */ "\u2039|\u203A",
         /* keyspec_right_single_angle_quote */ "\u203A|\u2039",
-        // U+060C: "،" ARABIC COMMA
-        // U+061B: "؛" ARABIC SEMICOLON
-        // U+061F: "؟" ARABIC QUESTION MARK
-        // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
-        // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
-        /* keyspec_tablet_comma */ "\u060C",
+        /* morekeys_tablet_comma */ "!fixedColumnOrder!4,:,!,\u061F,\u061B,-,/,!text/keyspec_left_double_angle_quote,!text/keyspec_right_double_angle_quote",
+        // U+064B: "ً" ARABIC FATHATAN
+        /* keyhintlabel_period */ "\u064B",
         /* morekeys_tablet_period */ "!text/morekeys_arabic_diacritics",
         // U+00BF: "¿" INVERTED QUESTION MARK
         /* morekeys_question */ "?,\u00BF",
         /* morekeys_h ~ */
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         /* ~ keyspec_spanish_row2_10 */
         // U+266A: "♪" EIGHTH NOTE
         /* morekeys_bullet */ "\u266A",
@@ -1584,10 +1584,9 @@
         // U+060C: "،" ARABIC COMMA
         /* keyspec_comma */ "\u060C",
         /* keyhintlabel_tablet_comma */ "\u061F",
-        /* morekeys_tablet_comma */ "!fixedColumnOrder!4,:,!,\u061F,\u061B,-,/,!text/keyspec_left_double_angle_quote,!text/keyspec_right_double_angle_quote",
-        // U+064B: "ً" ARABIC FATHATAN
-        /* keyhintlabel_period */ "\u064B",
+        /* keyspec_period */ null,
         /* morekeys_period */ "!text/morekeys_arabic_diacritics",
+        /* keyspec_tablet_period */ null,
         /* keyhintlabel_tablet_period */ "\u064B",
         /* keyspec_symbols_question */ "\u061F",
         /* keyspec_symbols_semicolon */ "\u061B",
@@ -1597,7 +1596,7 @@
         // U+2030: "‰" PER MILLE SIGN
         /* morekeys_symbols_percent */ "\\%,\u2030",
         /* morekeys_v ~ */
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null,
         /* ~ morekeys_plus */
         // U+2264: "≤" LESS-THAN OR EQUAL TO
         // U+2265: "≥" GREATER-THAN EQUAL TO
@@ -1714,10 +1713,8 @@
         /* morekeys_d ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null, null,
-        /* ~ keyspec_south_slavic_row3_8 */
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        /* ~ keyspec_tablet_comma */
         // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
         /* keyspec_swiss_row1_11 */ "\u00E8",
         // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
@@ -1802,8 +1799,8 @@
         // U+20B9: "₹" INDIAN RUPEE SIGN
         /* keyspec_currency */ "\u20B9",
         /* morekeys_r ~ */
-        null, null, null, null, null, null, null, null, null, null, null, null, null,
-        /* ~ morekeys_nordic_row2_11 */
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        /* ~ morekeys_punctuation */
         // U+0967: "१" DEVANAGARI DIGIT ONE
         /* keyspec_symbols_1 */ "\u0967",
         // U+0968: "२" DEVANAGARI DIGIT TWO
@@ -1937,9 +1934,8 @@
         /* keylabel_to_alpha */ "\u0531\u0532\u0533",
         /* morekeys_s ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        /* ~ additional_morekeys_symbols_0 */
+        null, null, null, null, null, null, null, null,
+        /* ~ morekeys_nordic_row2_11 */
         // U+055E: "՞" ARMENIAN QUESTION MARK
         // U+055C: "՜" ARMENIAN EXCLAMATION MARK
         // U+055A: "՚" ARMENIAN APOSTROPHE
@@ -1951,28 +1947,36 @@
         // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
         // U+055F: "՟" ARMENIAN ABBREVIATION MARK
         /* morekeys_punctuation */ "!autoColumnOrder!8,\\,,\u055E,\u055C,.,\u055A,\u0559,?,!,\u055D,\u055B,\u058A,\u00BB,\u00AB,\u055F,;,:",
-        /* morekeys_star ~ */
+        /* keyspec_symbols_1 ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        /* ~ keyspec_right_single_angle_quote */
+        null, null, null, null, null, null,
+        /* ~ additional_morekeys_symbols_0 */
         // U+058F: "֏" ARMENIAN DRAM SIGN
         // TODO: Enable this when we have glyph for the following letter
         // <string name="keyspec_currency">&#x058F;</string>
         // 
         // U+055D: "՝" ARMENIAN COMMA
         /* keyspec_tablet_comma */ "\u055D",
+        /* keyspec_swiss_row1_11 ~ */
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null,
+        /* ~ keyhintlabel_period */
         /* morekeys_tablet_period */ "!text/morekeys_punctuation",
         // U+055E: "՞" ARMENIAN QUESTION MARK
         // U+00BF: "¿" INVERTED QUESTION MARK
         /* morekeys_question */ "\u055E,\u00BF",
         /* morekeys_h ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null,
-        /* ~ morekeys_greater_than */
+        /* ~ keyhintlabel_tablet_comma */
         // U+0589: "։" ARMENIAN FULL STOP
         /* keyspec_period */ "\u0589",
+        /* morekeys_period */ null,
         /* keyspec_tablet_period */ "\u0589",
+        /* keyhintlabel_tablet_period ~ */
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null,
+        /* ~ morekeys_greater_than */
         // U+055C: "՜" ARMENIAN EXCLAMATION MARK
         // U+00A1: "¡" INVERTED EXCLAMATION MARK
         /* morekeys_exclamation */ "\u055C,\u00A1",
@@ -2078,6 +2082,24 @@
         // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
         // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
         /* morekeys_i */ "\u00EC,\u00ED,\u00EE,\u00EF,\u012F,\u012B",
+        /* morekeys_c ~ */
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null,
+        /* ~ keyspec_tablet_comma */
+        // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
+        /* keyspec_swiss_row1_11 */ "\u00FC",
+        // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
+        /* keyspec_swiss_row2_10 */ "\u00F6",
+        // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
+        /* keyspec_swiss_row2_11 */ "\u00E4",
+        // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
+        /* morekeys_swiss_row1_11 */ "\u00E8",
+        // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
+        /* morekeys_swiss_row2_10 */ "\u00E9",
+        // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
+        /* morekeys_swiss_row2_11 */ "\u00E0",
     };
 
     /* Locale iw: Hebrew */
@@ -2101,8 +2123,8 @@
         /* morekeys_r ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null,
-        /* ~ morekeys_punctuation */
+        null, null, null, null, null, null, null, null, null, null, null, null,
+        /* ~ morekeys_swiss_row2_11 */
         // U+2605: "★" BLACK STAR
         /* morekeys_star */ "\u2605",
         // The all letters need to be mirrored are found at
@@ -2127,12 +2149,11 @@
         /* keyspec_right_double_angle_quote */ "\u00BB|\u00AB",
         /* keyspec_left_single_angle_quote */ "\u2039|\u203A",
         /* keyspec_right_single_angle_quote */ "\u203A|\u2039",
-        /* keyspec_tablet_comma ~ */
+        /* morekeys_tablet_comma ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null,
-        /* ~ morekeys_tablet_punctuation */
+        /* ~ morekeys_currency_dollar */
         // U+00B1: "±" PLUS-MINUS SIGN
         // U+FB29: "﬩" HEBREW LETTER ALTERNATIVE PLUS SIGN
         /* morekeys_plus */ "\u00B1,\uFB29",
@@ -2184,7 +2205,8 @@
         /* morekeys_nordic_row2_11 ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null,
         /* ~ morekeys_w */
         // U+0456: "і" CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
         /* morekeys_east_slavic_row2_2 */ "\u0456",
@@ -2200,7 +2222,6 @@
         /* morekeys_cyrillic_i ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null,
         /* ~ keyspec_x */
         // U+04BB: "һ" CYRILLIC SMALL LETTER SHHA
         /* morekeys_east_slavic_row2_11 */ "\u04BB",
@@ -2228,7 +2249,7 @@
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null,
+        null, null, null, null, null, null,
         /* ~ morekeys_cyrillic_a */
         // U+17DB: "៛" KHMER CURRENCY SYMBOL RIEL
         /* morekeys_currency_dollar */ "\u17DB,\u00A2,\u00A3,\u20AC,\u00A5,\u20B1",
@@ -2265,7 +2286,8 @@
         /* morekeys_nordic_row2_11 ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null,
         /* ~ morekeys_east_slavic_row2_2 */
         // U+04AF: "ү" CYRILLIC SMALL LETTER STRAIGHT U
         /* morekeys_cyrillic_u */ "\u04AF",
@@ -2504,7 +2526,8 @@
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null,
         /* ~ morekeys_cyrillic_o */
         // U+045D: "ѝ" CYRILLIC SMALL LETTER I WITH GRAVE
         /* morekeys_cyrillic_i */ "\u045D",
@@ -2545,6 +2568,34 @@
         // U+1001: "ခ" MYANMAR LETTER KHA
         // U+1002: "ဂ" MYANMAR LETTER GA
         /* keylabel_to_alpha */ "\u1000\u1001\u1002",
+        /* morekeys_s ~ */
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null,
+        /* ~ morekeys_nordic_row2_11 */
+        /* morekeys_punctuation */ "!autoColumnOrder!9,\u104A,.,?,!,#,),(,/,;,...,',@,:,-,\",+,\\%,&",
+        /* keyspec_symbols_1 ~ */
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null,
+        /* ~ additional_morekeys_symbols_0 */
+        // U+104A: "၊" MYANMAR SIGN LITTLE SECTION
+        // U+104B: "။" MYANMAR SIGN SECTION
+        /* keyspec_tablet_comma */ "\u104A",
+        /* keyspec_swiss_row1_11 ~ */
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null,
+        /* ~ keyspec_right_single_angle_quote */
+        /* morekeys_tablet_comma */ "\\,",
+        /* keyhintlabel_period */ "\u104A",
+        /* morekeys_tablet_period ~ */
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        /* ~ keyspec_south_slavic_row3_8 */
+        /* morekeys_tablet_punctuation */ "!autoColumnOrder!8,.,',#,),(,/,;,@,...,:,-,\",+,\\%,&",
+        /* keyspec_spanish_row2_10 ~ */
+        null, null, null, null, null, null, null,
+        /* ~ keyhintlabel_tablet_comma */
+        /* keyspec_period */ "\u104B",
+        /* morekeys_period */ null,
+        /* keyspec_tablet_period */ "\u104B",
     };
 
     /* Locale nb: Norwegian Bokmål */
@@ -2617,8 +2668,8 @@
         // U+0930/U+0941/U+002E "रु." NEPALESE RUPEE SIGN
         /* keyspec_currency */ "\u0930\u0941.",
         /* morekeys_r ~ */
-        null, null, null, null, null, null, null, null, null, null, null, null, null,
-        /* ~ morekeys_nordic_row2_11 */
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        /* ~ morekeys_punctuation */
         // U+0967: "१" DEVANAGARI DIGIT ONE
         /* keyspec_symbols_1 */ "\u0967",
         // U+0968: "२" DEVANAGARI DIGIT TWO
@@ -3045,7 +3096,8 @@
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null,
         /* ~ morekeys_cyrillic_o */
         // U+045D: "ѝ" CYRILLIC SMALL LETTER I WITH GRAVE
         /* morekeys_cyrillic_i */ "\u045D",
@@ -3369,7 +3421,8 @@
         /* morekeys_nordic_row2_11 ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null,
         /* ~ morekeys_w */
         // U+0457: "ї" CYRILLIC SMALL LETTER YI
         /* morekeys_east_slavic_row2_2 */ "\u0457",
@@ -3639,7 +3692,7 @@
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         /* ~ morekeys_question */
         // U+0125: "ĥ" LATIN SMALL LETTER H WITH CIRCUMFLEX
         /* morekeys_h */ "\u0125",
@@ -3647,8 +3700,7 @@
         /* morekeys_w */ "\u0175",
         /* morekeys_east_slavic_row2_2 ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null,
         /* ~ morekeys_v */
         // U+0135: "ĵ" LATIN SMALL LETTER J WITH CIRCUMFLEX
         /* morekeys_j */ "\u0135",
@@ -3658,43 +3710,43 @@
     // "locale", TEXT_ARRAY,  /* numberOfNonNullText/lengthOf_TEXT_ARRAY localeName */
         "DEFAULT", TEXTS_DEFAULT, /* 168/168 DEFAULT */
         "af"     , TEXTS_af,    /*   7/ 12 Afrikaans */
-        "ar"     , TEXTS_ar,    /*  55/107 Arabic */
+        "ar"     , TEXTS_ar,    /*  55/110 Arabic */
         "az_AZ"  , TEXTS_az_AZ, /*   8/ 17 Azerbaijani (Azerbaijan) */
         "be_BY"  , TEXTS_be_BY, /*   9/ 32 Belarusian (Belarus) */
         "bg"     , TEXTS_bg,    /*   2/ 10 Bulgarian */
-        "ca"     , TEXTS_ca,    /*  11/120 Catalan */
+        "ca"     , TEXTS_ca,    /*  11/ 95 Catalan */
         "cs"     , TEXTS_cs,    /*  17/ 21 Czech */
         "da"     , TEXTS_da,    /*  19/ 33 Danish */
-        "de"     , TEXTS_de,    /*  16/ 91 German */
+        "de"     , TEXTS_de,    /*  16/ 62 German */
         "el"     , TEXTS_el,    /*   1/ 10 Greek */
         "en"     , TEXTS_en,    /*   8/ 11 English */
-        "eo"     , TEXTS_eo,    /*  26/115 Esperanto */
-        "es"     , TEXTS_es,    /*   8/ 55 Spanish */
+        "eo"     , TEXTS_eo,    /*  26/118 Esperanto */
+        "es"     , TEXTS_es,    /*   8/ 34 Spanish */
         "et_EE"  , TEXTS_et_EE, /*  22/ 27 Estonian (Estonia) */
         "eu_ES"  , TEXTS_eu_ES, /*   7/  8 Basque (Spain) */
-        "fa"     , TEXTS_fa,    /*  58/123 Persian */
+        "fa"     , TEXTS_fa,    /*  58/125 Persian */
         "fi"     , TEXTS_fi,    /*  10/ 33 Finnish */
-        "fr"     , TEXTS_fr,    /*  13/ 91 French */
+        "fr"     , TEXTS_fr,    /*  13/ 62 French */
         "gl_ES"  , TEXTS_gl_ES, /*   7/  8 Gallegan (Spain) */
-        "hi"     , TEXTS_hi,    /*  23/ 54 Hindi */
+        "hi"     , TEXTS_hi,    /*  23/ 55 Hindi */
         "hr"     , TEXTS_hr,    /*   9/ 19 Croatian */
         "hu"     , TEXTS_hu,    /*   9/ 19 Hungarian */
         "hy_AM"  , TEXTS_hy_AM, /*   8/126 Armenian (Armenia) */
         "is"     , TEXTS_is,    /*  10/ 15 Icelandic */
-        "it"     , TEXTS_it,    /*   5/  5 Italian */
-        "iw"     , TEXTS_iw,    /*  20/121 Hebrew */
+        "it"     , TEXTS_it,    /*  11/ 62 Italian */
+        "iw"     , TEXTS_iw,    /*  20/123 Hebrew */
         "ka_GE"  , TEXTS_ka_GE, /*   3/ 10 Georgian (Georgia) */
-        "kk"     , TEXTS_kk,    /*  15/118 Kazakh */
-        "km_KH"  , TEXTS_km_KH, /*   2/119 Khmer (Cambodia) */
-        "ky"     , TEXTS_ky,    /*  10/ 80 Kirghiz */
+        "kk"     , TEXTS_kk,    /*  15/121 Kazakh */
+        "km_KH"  , TEXTS_km_KH, /*   2/122 Khmer (Cambodia) */
+        "ky"     , TEXTS_ky,    /*  10/ 88 Kirghiz */
         "lo_LA"  , TEXTS_lo_LA, /*   2/ 20 Lao (Laos) */
         "lt"     , TEXTS_lt,    /*  18/ 22 Lithuanian */
         "lv"     , TEXTS_lv,    /*  18/ 22 Latvian */
-        "mk"     , TEXTS_mk,    /*   9/ 85 Macedonian */
+        "mk"     , TEXTS_mk,    /*   9/ 93 Macedonian */
         "mn_MN"  , TEXTS_mn_MN, /*   2/ 20 Mongolian (Mongolia) */
-        "my_MM"  , TEXTS_my_MM, /*   1/ 10 Burmese (Myanmar) */
+        "my_MM"  , TEXTS_my_MM, /*   8/104 Burmese (Myanmar) */
         "nb"     , TEXTS_nb,    /*  11/ 33 Norwegian Bokmål */
-        "ne_NP"  , TEXTS_ne_NP, /*  23/ 54 Nepali (Nepal) */
+        "ne_NP"  , TEXTS_ne_NP, /*  23/ 55 Nepali (Nepal) */
         "nl"     , TEXTS_nl,    /*   9/ 12 Dutch */
         "pl"     , TEXTS_pl,    /*  10/ 16 Polish */
         "pt"     , TEXTS_pt,    /*   6/  6 Portuguese */
@@ -3703,16 +3755,16 @@
         "ru"     , TEXTS_ru,    /*   9/ 32 Russian */
         "sk"     , TEXTS_sk,    /*  20/ 22 Slovak */
         "sl"     , TEXTS_sl,    /*   8/ 19 Slovenian */
-        "sr"     , TEXTS_sr,    /*  11/ 85 Serbian */
+        "sr"     , TEXTS_sr,    /*  11/ 93 Serbian */
         "sv"     , TEXTS_sv,    /*  21/ 33 Swedish */
         "sw"     , TEXTS_sw,    /*   9/ 17 Swahili */
         "th"     , TEXTS_th,    /*   2/ 20 Thai */
         "tl"     , TEXTS_tl,    /*   7/  8 Tagalog */
         "tr"     , TEXTS_tr,    /*   7/ 17 Turkish */
-        "uk"     , TEXTS_uk,    /*  11/ 79 Ukrainian */
+        "uk"     , TEXTS_uk,    /*  11/ 87 Ukrainian */
         "vi"     , TEXTS_vi,    /*   8/ 20 Vietnamese */
         "zu"     , TEXTS_zu,    /*   8/ 11 Zulu */
-        "zz"     , TEXTS_zz,    /*  19/109 Alphabet */
+        "zz"     , TEXTS_zz,    /*  19/112 Alphabet */
     };
 
     static {
diff --git a/java/src/com/android/inputmethod/latin/LastComposedWord.java b/java/src/com/android/inputmethod/latin/LastComposedWord.java
index 2a16ab5..232bf74 100644
--- a/java/src/com/android/inputmethod/latin/LastComposedWord.java
+++ b/java/src/com/android/inputmethod/latin/LastComposedWord.java
@@ -44,7 +44,6 @@
 
     public static final String NOT_A_SEPARATOR = "";
 
-    public final int[] mPrimaryKeyCodes;
     public final ArrayList<Event> mEvents;
     public final String mTypedWord;
     public final CharSequence mCommittedWord;
@@ -57,16 +56,15 @@
     private boolean mActive;
 
     public static final LastComposedWord NOT_A_COMPOSED_WORD =
-            new LastComposedWord(null, new ArrayList<Event>(), null, "", "",
+            new LastComposedWord(new ArrayList<Event>(), null, "", "",
             NOT_A_SEPARATOR, null, WordComposer.CAPS_MODE_OFF);
 
     // Warning: this is using the passed objects as is and fully expects them to be
     // immutable. Do not fiddle with their contents after you passed them to this constructor.
-    public LastComposedWord(final int[] primaryKeyCodes, final ArrayList<Event> events,
+    public LastComposedWord(final ArrayList<Event> events,
             final InputPointers inputPointers, final String typedWord,
             final CharSequence committedWord, final String separatorString,
             final String prevWord, final int capitalizedMode) {
-        mPrimaryKeyCodes = primaryKeyCodes;
         if (inputPointers != null) {
             mInputPointers.copy(inputPointers);
         }
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 2cfecd7..059f362 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -199,7 +199,8 @@
                         latinIme.mSettings.getCurrent());
                 break;
             case MSG_UPDATE_SHIFT_STATE:
-                switcher.requestUpdatingShiftState();
+                switcher.requestUpdatingShiftState(latinIme.getCurrentAutoCapsState(),
+                        latinIme.getCurrentRecapitalizeState());
                 break;
             case MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP:
                 if (msg.arg1 == ARG1_NOT_GESTURE_INPUT) {
@@ -641,6 +642,11 @@
         super.onDestroy();
     }
 
+    @UsedForTesting
+    public void recycle() {
+        mInputLogic.recycle();
+    }
+
     @Override
     public void onConfigurationChanged(final Configuration conf) {
         // If orientation changed while predicting, commit the change
@@ -844,7 +850,8 @@
             // we need to re-evaluate the shift state, but not the whole layout which would be
             // disruptive.
             // Space state must be updated before calling updateShiftState
-            switcher.requestUpdatingShiftState();
+            switcher.requestUpdatingShiftState(getCurrentAutoCapsState(),
+                    getCurrentRecapitalizeState());
         }
         // This will set the punctuation suggestions if next word suggestion is off;
         // otherwise it will clear the suggestion strip.
@@ -923,7 +930,8 @@
         // TODO: find a better way to simulate actual execution.
         if (isInputViewShown() &&
                 mInputLogic.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd)) {
-            mKeyboardSwitcher.requestUpdatingShiftState();
+            mKeyboardSwitcher.requestUpdatingShiftState(getCurrentAutoCapsState(),
+                    getCurrentRecapitalizeState());
         }
 
         mSubtypeState.currentSubtypeUsed();
@@ -1275,7 +1283,8 @@
         // TODO: have the keyboard pass the correct key code when we need it.
         final Event event = Event.createSoftwareTextEvent(rawText, Event.NOT_A_KEY_CODE);
         mInputLogic.onTextInput(mSettings.getCurrent(), event, mHandler);
-        mKeyboardSwitcher.requestUpdatingShiftState();
+        mKeyboardSwitcher.requestUpdatingShiftState(getCurrentAutoCapsState(),
+                getCurrentRecapitalizeState());
         mKeyboardSwitcher.onCodeInput(Constants.CODE_OUTPUT_TEXT, getCurrentAutoCapsState());
     }
 
@@ -1519,7 +1528,8 @@
             mHandler.postUpdateShiftState();
             break;
         case InputTransaction.SHIFT_UPDATE_NOW:
-            mKeyboardSwitcher.requestUpdatingShiftState();
+            mKeyboardSwitcher.requestUpdatingShiftState(getCurrentAutoCapsState(),
+                    getCurrentRecapitalizeState());
             break;
         default: // SHIFT_NO_UPDATE
         }
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index 02f18cd..1268e5a 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -42,11 +42,6 @@
 
     private CombinerChain mCombinerChain;
 
-    // An array of code points representing the characters typed so far.
-    // The array is limited to MAX_WORD_LENGTH code points, but mTypedWord extends past that
-    // and mCodePointSize can go past that. If mCodePointSize is greater than MAX_WORD_LENGTH,
-    // this just does not contain the associated code points past MAX_WORD_LENGTH.
-    private int[] mPrimaryKeyCodes;
     // The list of events that served to compose this string.
     private final ArrayList<Event> mEvents;
     private final InputPointers mInputPointers = new InputPointers(MAX_WORD_LENGTH);
@@ -71,7 +66,6 @@
     private int mCapsCount;
     private int mDigitsCount;
     private int mCapitalizedMode;
-    private int mTrailingSingleQuotesCount;
     // This is the number of code points entered so far. This is not limited to MAX_WORD_LENGTH.
     // In general, this contains the size of mPrimaryKeyCodes, except when this is greater than
     // MAX_WORD_LENGTH in which case mPrimaryKeyCodes only contain the first MAX_WORD_LENGTH
@@ -86,10 +80,8 @@
 
     public WordComposer() {
         mCombinerChain = new CombinerChain();
-        mPrimaryKeyCodes = new int[MAX_WORD_LENGTH];
         mEvents = CollectionUtils.newArrayList();
         mAutoCorrection = null;
-        mTrailingSingleQuotesCount = 0;
         mIsResumed = false;
         mIsBatchMode = false;
         mCursorPositionWithinWord = 0;
@@ -108,7 +100,6 @@
         mCapsCount = 0;
         mDigitsCount = 0;
         mIsFirstCharCapitalized = false;
-        mTrailingSingleQuotesCount = 0;
         mIsResumed = false;
         mIsBatchMode = false;
         mCursorPositionWithinWord = 0;
@@ -143,10 +134,7 @@
      */
     public int copyCodePointsExceptTrailingSingleQuotesAndReturnCodePointCount(
             final int[] destination, final int maxSize) {
-        int i = mTypedWordCache.length() - 1;
-        while (i >= 0 && mTypedWordCache.charAt(i) == Constants.CODE_SINGLE_QUOTE) {
-            --i;
-        }
+        final int i = mTypedWordCache.length() - 1 - trailingSingleQuotesCount();
         if (i < 0) {
             // The string is empty or contains only single quotes.
             return 0;
@@ -198,28 +186,8 @@
         if (0 == mCodePointSize) {
             mIsFirstCharCapitalized = false;
         }
-        if (Constants.CODE_DELETE == event.mKeyCode) {
-            if (mTrailingSingleQuotesCount > 0) {
-                --mTrailingSingleQuotesCount;
-            } else {
-                // Delete, but we didn't end in a quote: must recompute mTrailingSingleQuotesCount
-                // We're only searching for single quotes, so no need to account for code points
-                for (int i = mTypedWordCache.length() - 1; i > 0; --i) {
-                    if (Constants.CODE_SINGLE_QUOTE != mTypedWordCache.charAt(i)) {
-                        break;
-                    }
-                    ++mTrailingSingleQuotesCount;
-                }
-            }
-        } else {
-            if (Constants.CODE_SINGLE_QUOTE == primaryCode) {
-                ++mTrailingSingleQuotesCount;
-            } else {
-                mTrailingSingleQuotesCount = 0;
-            }
+        if (Constants.CODE_DELETE != event.mKeyCode) {
             if (newIndex < MAX_WORD_LENGTH) {
-                mPrimaryKeyCodes[newIndex] = primaryCode >= Constants.CODE_SPACE
-                        ? Character.toLowerCase(primaryCode) : primaryCode;
                 // In the batch input mode, the {@code mInputPointers} holds batch input points and
                 // shouldn't be overridden by the "typed key" coordinates
                 // (See {@link #setBatchInputWord}).
@@ -263,15 +231,8 @@
         mCombinerChain.reset();
         int actualMoveAmountWithinWord = 0;
         int cursorPos = mCursorPositionWithinWord;
-        final int[] codePoints;
-        if (mCodePointSize >= MAX_WORD_LENGTH) {
-            // If we have more than MAX_WORD_LENGTH characters, we don't have everything inside
-            // mPrimaryKeyCodes. This should be rare enough that we can afford to just compute
-            // the array on the fly when this happens.
-            codePoints = StringUtils.toCodePointArray(mTypedWordCache);
-        } else {
-            codePoints = mPrimaryKeyCodes;
-        }
+        // TODO: Don't make that copy. We can do this directly from mTypedWordCache.
+        final int[] codePoints = StringUtils.toCodePointArray(mTypedWordCache);
         if (expectedMoveAmount >= 0) {
             // Moving the cursor forward for the expected amount or until the end of the word has
             // been reached, whichever comes first.
@@ -353,7 +314,12 @@
     }
 
     public int trailingSingleQuotesCount() {
-        return mTrailingSingleQuotesCount;
+        final int lastIndex = mTypedWordCache.length() - 1;
+        int i = lastIndex;
+        while (i >= 0 && mTypedWordCache.charAt(i) == Constants.CODE_SINGLE_QUOTE) {
+            --i;
+        }
+        return lastIndex - i;
     }
 
     /**
@@ -443,9 +409,7 @@
         // Note: currently, we come here whenever we commit a word. If it's a MANUAL_PICK
         // or a DECIDED_WORD we may cancel the commit later; otherwise, we should deactivate
         // the last composed word to ensure this does not happen.
-        final int[] primaryKeyCodes = mPrimaryKeyCodes;
-        mPrimaryKeyCodes = new int[MAX_WORD_LENGTH];
-        final LastComposedWord lastComposedWord = new LastComposedWord(primaryKeyCodes, mEvents,
+        final LastComposedWord lastComposedWord = new LastComposedWord(mEvents,
                 mInputPointers, mTypedWordCache.toString(), committedWord, separatorString,
                 prevWord, mCapitalizedMode);
         mInputPointers.reset();
@@ -460,7 +424,6 @@
         mCombinerChain.reset();
         mEvents.clear();
         mCodePointSize = 0;
-        mTrailingSingleQuotesCount = 0;
         mIsFirstCharCapitalized = false;
         mCapitalizedMode = CAPS_MODE_OFF;
         refreshTypedWordCache();
@@ -480,7 +443,6 @@
 
     public void resumeSuggestionOnLastComposedWord(final LastComposedWord lastComposedWord,
             final String previousWord) {
-        mPrimaryKeyCodes = lastComposedWord.mPrimaryKeyCodes;
         mEvents.clear();
         Collections.copy(mEvents, lastComposedWord.mEvents);
         mInputPointers.set(lastComposedWord.mInputPointers);
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 7cf8c5e..bf8467e 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -148,6 +148,17 @@
         mInputLogicHandler.reset();
     }
 
+    // Normally this class just gets out of scope after the process ends, but in unit tests, we
+    // create several instances of LatinIME in the same process, which results in several
+    // instances of InputLogic. This cleans up the associated handler so that tests don't leak
+    // handlers.
+    public void recycle() {
+        final InputLogicHandler inputLogicHandler = mInputLogicHandler;
+        mInputLogicHandler = InputLogicHandler.NULL_HANDLER;
+        inputLogicHandler.destroy();
+        mSuggest.mDictionaryFacilitator.closeDictionaries();
+    }
+
     /**
      * React to a string input.
      *
@@ -537,7 +548,8 @@
                 // after typing some letters and a period, then gesturing; the keyboard is not in
                 // caps mode yet, but since a gesture is starting, it should go in caps mode,
                 // unless the user explictly said it should not.
-                keyboardSwitcher.requestUpdatingShiftState();
+                keyboardSwitcher.requestUpdatingShiftState(getCurrentAutoCapsState(settingsValues),
+                        getCurrentRecapitalizeState());
             }
         }
         mConnection.endBatchEdit();
@@ -579,7 +591,8 @@
                     promotePhantomSpace(settingsValues);
                     mConnection.commitText(commitParts[0], 0);
                     mSpaceState = SpaceState.PHANTOM;
-                    keyboardSwitcher.requestUpdatingShiftState();
+                    keyboardSwitcher.requestUpdatingShiftState(
+                            getCurrentAutoCapsState(settingsValues), getCurrentRecapitalizeState());
                     mWordComposer.setCapitalizedModeAndPreviousWordAtStartComposingTime(
                             getActualCapsMode(settingsValues,
                                     keyboardSwitcher.getKeyboardShiftMode()), commitParts[0]);
@@ -1819,7 +1832,8 @@
         }
         // Space state must be updated before calling updateShiftState
         mSpaceState = SpaceState.PHANTOM;
-        keyboardSwitcher.requestUpdatingShiftState();
+        keyboardSwitcher.requestUpdatingShiftState(getCurrentAutoCapsState(settingsValues),
+                getCurrentRecapitalizeState());
     }
 
     /**
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java
index e3b8ab4..64bba68 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java
@@ -20,6 +20,7 @@
 import android.os.HandlerThread;
 import android.os.Message;
 
+import com.android.inputmethod.compat.LooperCompatUtils;
 import com.android.inputmethod.latin.InputPointers;
 import com.android.inputmethod.latin.LatinIME;
 import com.android.inputmethod.latin.Suggest;
@@ -80,6 +81,12 @@
         mNonUIThreadHandler.removeCallbacksAndMessages(null);
     }
 
+    // In unit tests, we create several instances of LatinIME, which results in several instances
+    // of InputLogicHandler. To avoid these handlers lingering, we call this.
+    public void destroy() {
+        LooperCompatUtils.quitSafely(mNonUIThreadHandler.getLooper());
+    }
+
     /**
      * Handle a message.
      * @see android.os.Handler.Callback#handleMessage(android.os.Message)
diff --git a/java/src/com/android/inputmethod/latin/utils/SpacebarLanguageUtils.java b/java/src/com/android/inputmethod/latin/utils/SpacebarLanguageUtils.java
index 89837c6..1ca895f 100644
--- a/java/src/com/android/inputmethod/latin/utils/SpacebarLanguageUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/SpacebarLanguageUtils.java
@@ -18,8 +18,6 @@
 
 import android.view.inputmethod.InputMethodSubtype;
 
-import java.util.Locale;
-
 public final class SpacebarLanguageUtils {
     private SpacebarLanguageUtils() {
         // Intentional empty constructor for utility class.
@@ -55,7 +53,6 @@
         if (SubtypeLocaleUtils.isNoLanguage(subtype)) {
             return SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(subtype);
         }
-        final Locale locale = SubtypeLocaleUtils.getSubtypeLocale(subtype);
-        return SubtypeLocaleUtils.getSubtypeLocaleDisplayName(locale.getLanguage());
+        return SubtypeLocaleUtils.getSubtypeLanguageDisplayName(subtype.getLocale());
     }
 }
diff --git a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
index 2452864..b37779b 100644
--- a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
@@ -25,7 +25,7 @@
 import android.util.Log;
 import android.view.inputmethod.InputMethodSubtype;
 
-import com.android.inputmethod.latin.DictionaryFactory;
+import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.R;
 
 import java.util.Arrays;
@@ -33,10 +33,10 @@
 import java.util.Locale;
 
 public final class SubtypeLocaleUtils {
-    static final String TAG = SubtypeLocaleUtils.class.getSimpleName();
-    // This class must be located in the same package as LatinIME.java.
-    private static final String RESOURCE_PACKAGE_NAME =
-            DictionaryFactory.class.getPackage().getName();
+    private static final String TAG = SubtypeLocaleUtils.class.getSimpleName();
+
+    // This reference class {@link Constants} must be located in the same package as LatinIME.java.
+    private static final String RESOURCE_PACKAGE_NAME = Constants.class.getPackage().getName();
 
     // Special language code to represent "no language".
     public static final String NO_LANGUAGE = "zz";
@@ -44,7 +44,8 @@
     public static final String EMOJI = "emoji";
     public static final int UNKNOWN_KEYBOARD_LAYOUT = R.string.subtype_generic;
 
-    private static boolean sInitialized = false;
+    private static volatile boolean sInitialized = false;
+    private static final Object sInitializeLock = new Object();
     private static Resources sResources;
     private static String[] sPredefinedKeyboardLayoutSet;
     // Keyboard layout to its display name map.
@@ -77,9 +78,16 @@
     }
 
     // Note that this initialization method can be called multiple times.
-    public static synchronized void init(final Context context) {
-        if (sInitialized) return;
+    public static void init(final Context context) {
+        synchronized (sInitializeLock) {
+            if (sInitialized == false) {
+                initLocked(context);
+                sInitialized = true;
+            }
+        }
+    }
 
+    private static void initLocked(final Context context) {
         final Resources res = context.getResources();
         sResources = res;
 
@@ -122,8 +130,6 @@
             final String keyboardLayoutSet = keyboardLayoutSetMap[i + 1];
             sLocaleAndExtraValueToKeyboardLayoutSetMap.put(key, keyboardLayoutSet);
         }
-
-        sInitialized = true;
     }
 
     public static String[] getPredefinedKeyboardLayoutSet() {
@@ -167,8 +173,18 @@
         return getSubtypeLocaleDisplayNameInternal(localeString, displayLocale);
     }
 
+    public static String getSubtypeLanguageDisplayName(final String localeString) {
+        final Locale locale = LocaleUtils.constructLocaleFromString(localeString);
+        final Locale displayLocale = getDisplayLocaleOfSubtypeLocale(localeString);
+        return getSubtypeLocaleDisplayNameInternal(locale.getLanguage(), displayLocale);
+    }
+
     private static String getSubtypeLocaleDisplayNameInternal(final String localeString,
             final Locale displayLocale) {
+        if (NO_LANGUAGE.equals(localeString)) {
+            // No language subtype should be displayed in system locale.
+            return sResources.getString(R.string.subtype_no_language);
+        }
         final Integer exceptionalNameResId = sExceptionalLocaleToNameIdsMap.get(localeString);
         final String displayName;
         if (exceptionalNameResId != null) {
@@ -179,9 +195,6 @@
                 }
             };
             displayName = getExceptionalName.runInLocale(sResources, displayLocale);
-        } else if (NO_LANGUAGE.equals(localeString)) {
-            // No language subtype should be displayed in system locale.
-            return sResources.getString(R.string.subtype_no_language);
         } else {
             final Locale locale = LocaleUtils.constructLocaleFromString(localeString);
             displayName = locale.getDisplayName(displayLocale);
diff --git a/native/jni/src/suggest/core/dictionary/multi_bigram_map.cpp b/native/jni/src/suggest/core/dictionary/multi_bigram_map.cpp
index 49d82e6..1052241 100644
--- a/native/jni/src/suggest/core/dictionary/multi_bigram_map.cpp
+++ b/native/jni/src/suggest/core/dictionary/multi_bigram_map.cpp
@@ -17,6 +17,7 @@
 #include "suggest/core/dictionary/multi_bigram_map.h"
 
 #include <cstddef>
+#include <unordered_map>
 
 namespace latinime {
 
@@ -35,7 +36,7 @@
 int MultiBigramMap::getBigramProbability(
         const DictionaryStructureWithBufferPolicy *const structurePolicy,
         const int wordPosition, const int nextWordPosition, const int unigramProbability) {
-    hash_map_compat<int, BigramMap>::const_iterator mapPosition =
+    std::unordered_map<int, BigramMap>::const_iterator mapPosition =
             mBigramMaps.find(wordPosition);
     if (mapPosition != mBigramMaps.end()) {
         return mapPosition->second.getBigramProbability(structurePolicy, nextWordPosition,
@@ -70,7 +71,7 @@
         const int nextWordPosition, const int unigramProbability) const {
     int bigramProbability = NOT_A_PROBABILITY;
     if (mBloomFilter.isInFilter(nextWordPosition)) {
-        const hash_map_compat<int, int>::const_iterator bigramProbabilityIt =
+        const std::unordered_map<int, int>::const_iterator bigramProbabilityIt =
                 mBigramMap.find(nextWordPosition);
         if (bigramProbabilityIt != mBigramMap.end()) {
             bigramProbability = bigramProbabilityIt->second;
diff --git a/native/jni/src/suggest/core/dictionary/multi_bigram_map.h b/native/jni/src/suggest/core/dictionary/multi_bigram_map.h
index 421b268..195b5e2 100644
--- a/native/jni/src/suggest/core/dictionary/multi_bigram_map.h
+++ b/native/jni/src/suggest/core/dictionary/multi_bigram_map.h
@@ -18,12 +18,12 @@
 #define LATINIME_MULTI_BIGRAM_MAP_H
 
 #include <cstddef>
+#include <unordered_map>
 
 #include "defines.h"
 #include "suggest/core/dictionary/binary_dictionary_bigrams_iterator.h"
 #include "suggest/core/dictionary/bloom_filter.h"
 #include "suggest/core/policy/dictionary_structure_with_buffer_policy.h"
-#include "utils/hash_map_compat.h"
 
 namespace latinime {
 
@@ -63,7 +63,7 @@
         // NOTE: The BigramMap class doesn't use DISALLOW_COPY_AND_ASSIGN() because its default
         // copy constructor is needed for use in hash_map.
         static const int DEFAULT_HASH_MAP_SIZE_FOR_EACH_BIGRAM_MAP;
-        hash_map_compat<int, int> mBigramMap;
+        std::unordered_map<int, int> mBigramMap;
         BloomFilter mBloomFilter;
     };
 
@@ -75,7 +75,7 @@
             const int nextWordPosition, const int unigramProbability);
 
     static const size_t MAX_CACHED_PREV_WORDS_IN_BIGRAM_MAP;
-    hash_map_compat<int, BigramMap> mBigramMaps;
+    std::unordered_map<int, BigramMap> mBigramMaps;
 };
 } // namespace latinime
 #endif // LATINIME_MULTI_BIGRAM_MAP_H
diff --git a/native/jni/src/suggest/core/layout/proximity_info.h b/native/jni/src/suggest/core/layout/proximity_info.h
index b72c293..56711d1 100644
--- a/native/jni/src/suggest/core/layout/proximity_info.h
+++ b/native/jni/src/suggest/core/layout/proximity_info.h
@@ -17,10 +17,11 @@
 #ifndef LATINIME_PROXIMITY_INFO_H
 #define LATINIME_PROXIMITY_INFO_H
 
+#include <unordered_map>
+
 #include "defines.h"
 #include "jni.h"
 #include "suggest/core/layout/proximity_info_utils.h"
-#include "utils/hash_map_compat.h"
 
 namespace latinime {
 
@@ -114,7 +115,7 @@
     // Sweet spots for geometric input. Note that we have extra sweet spots only for Y coordinates.
     float mSweetSpotCenterYsG[MAX_KEY_COUNT_IN_A_KEYBOARD];
     float mSweetSpotRadii[MAX_KEY_COUNT_IN_A_KEYBOARD];
-    hash_map_compat<int, int> mLowerCodePointToKeyMap;
+    std::unordered_map<int, int> mLowerCodePointToKeyMap;
     int mKeyIndexToOriginalCodePoint[MAX_KEY_COUNT_IN_A_KEYBOARD];
     int mKeyIndexToLowerCodePointG[MAX_KEY_COUNT_IN_A_KEYBOARD];
     int mCenterXsG[MAX_KEY_COUNT_IN_A_KEYBOARD];
diff --git a/native/jni/src/suggest/core/layout/proximity_info_state.cpp b/native/jni/src/suggest/core/layout/proximity_info_state.cpp
index e585f90..91469e2 100644
--- a/native/jni/src/suggest/core/layout/proximity_info_state.cpp
+++ b/native/jni/src/suggest/core/layout/proximity_info_state.cpp
@@ -21,6 +21,7 @@
 #include <algorithm>
 #include <cstring> // for memset() and memmove()
 #include <sstream> // for debug prints
+#include <unordered_map>
 #include <vector>
 
 #include "defines.h"
@@ -296,7 +297,7 @@
 // Returns a probability of mapping index to keyIndex.
 float ProximityInfoState::getProbability(const int index, const int keyIndex) const {
     ASSERT(0 <= index && index < mSampledInputSize);
-    hash_map_compat<int, float>::const_iterator it = mCharProbabilities[index].find(keyIndex);
+    std::unordered_map<int, float>::const_iterator it = mCharProbabilities[index].find(keyIndex);
     if (it != mCharProbabilities[index].end()) {
         return it->second;
     }
diff --git a/native/jni/src/suggest/core/layout/proximity_info_state.h b/native/jni/src/suggest/core/layout/proximity_info_state.h
index d66121b..6b1a319 100644
--- a/native/jni/src/suggest/core/layout/proximity_info_state.h
+++ b/native/jni/src/suggest/core/layout/proximity_info_state.h
@@ -18,12 +18,12 @@
 #define LATINIME_PROXIMITY_INFO_STATE_H
 
 #include <cstring> // for memset()
+#include <unordered_map>
 #include <vector>
 
 #include "defines.h"
 #include "suggest/core/layout/proximity_info_params.h"
 #include "suggest/core/layout/proximity_info_state_utils.h"
-#include "utils/hash_map_compat.h"
 
 namespace latinime {
 
@@ -215,7 +215,7 @@
     std::vector<float> mSpeedRates;
     std::vector<float> mDirections;
     // probabilities of skipping or mapping to a key for each point.
-    std::vector<hash_map_compat<int, float> > mCharProbabilities;
+    std::vector<std::unordered_map<int, float> > mCharProbabilities;
     // The vector for the key code set which holds nearby keys of some trailing sampled input points
     // for each sampled input point. These nearby keys contain the next characters which can be in
     // the dictionary. Specifically, currently we are looking for keys nearby trailing sampled
diff --git a/native/jni/src/suggest/core/layout/proximity_info_state_utils.cpp b/native/jni/src/suggest/core/layout/proximity_info_state_utils.cpp
index 72bb68f..ea3b022 100644
--- a/native/jni/src/suggest/core/layout/proximity_info_state_utils.cpp
+++ b/native/jni/src/suggest/core/layout/proximity_info_state_utils.cpp
@@ -20,6 +20,7 @@
 #include <cmath>
 #include <cstring> // for memset()
 #include <sstream> // for debug prints
+#include <unordered_map>
 #include <vector>
 
 #include "defines.h"
@@ -620,7 +621,7 @@
         const std::vector<int> *const sampledLengthCache,
         const std::vector<float> *const sampledNormalizedSquaredLengthCache,
         const ProximityInfo *const proximityInfo,
-        std::vector<hash_map_compat<int, float> > *charProbabilities) {
+        std::vector<std::unordered_map<int, float> > *charProbabilities) {
     charProbabilities->resize(sampledInputSize);
     // Calculates probabilities of using a point as a correlated point with the character
     // for each point.
@@ -762,7 +763,7 @@
             sstream << "Speed: "<< (*sampledSpeedRates)[i] << ", ";
             sstream << "Angle: "<< getPointAngle(sampledInputXs, sampledInputYs, i) << ", \n";
 
-            for (hash_map_compat<int, float>::iterator it = (*charProbabilities)[i].begin();
+            for (std::unordered_map<int, float>::iterator it = (*charProbabilities)[i].begin();
                     it != (*charProbabilities)[i].end(); ++it) {
                 if (it->first == NOT_AN_INDEX) {
                     sstream << it->first
@@ -804,7 +805,7 @@
     // Converting from raw probabilities to log probabilities to calculate spatial distance.
     for (int i = start; i < sampledInputSize; ++i) {
         for (int j = 0; j < keyCount; ++j) {
-            hash_map_compat<int, float>::iterator it = (*charProbabilities)[i].find(j);
+            std::unordered_map<int, float>::iterator it = (*charProbabilities)[i].find(j);
             if (it == (*charProbabilities)[i].end()){
                 continue;
             } else if(it->second < ProximityInfoParams::MIN_PROBABILITY) {
@@ -821,7 +822,7 @@
 /* static */ void ProximityInfoStateUtils::updateSampledSearchKeySets(
         const ProximityInfo *const proximityInfo, const int sampledInputSize,
         const int lastSavedInputSize, const std::vector<int> *const sampledLengthCache,
-        const std::vector<hash_map_compat<int, float> > *const charProbabilities,
+        const std::vector<std::unordered_map<int, float> > *const charProbabilities,
         std::vector<NearKeycodesSet> *sampledSearchKeySets,
         std::vector<std::vector<int> > *sampledSearchKeyVectors) {
     sampledSearchKeySets->resize(sampledInputSize);
@@ -867,7 +868,7 @@
 /* static */ bool ProximityInfoStateUtils::suppressCharProbabilities(const int mostCommonKeyWidth,
         const int sampledInputSize, const std::vector<int> *const lengthCache,
         const int index0, const int index1,
-        std::vector<hash_map_compat<int, float> > *charProbabilities) {
+        std::vector<std::unordered_map<int, float> > *charProbabilities) {
     ASSERT(0 <= index0 && index0 < sampledInputSize);
     ASSERT(0 <= index1 && index1 < sampledInputSize);
     const float keyWidthFloat = static_cast<float>(mostCommonKeyWidth);
@@ -878,9 +879,9 @@
     const float suppressionRate = ProximityInfoParams::MIN_SUPPRESSION_RATE
             + diff / keyWidthFloat / ProximityInfoParams::SUPPRESSION_LENGTH_WEIGHT
                     * ProximityInfoParams::SUPPRESSION_WEIGHT;
-    for (hash_map_compat<int, float>::iterator it = (*charProbabilities)[index0].begin();
+    for (std::unordered_map<int, float>::iterator it = (*charProbabilities)[index0].begin();
             it != (*charProbabilities)[index0].end(); ++it) {
-        hash_map_compat<int, float>::iterator it2 =  (*charProbabilities)[index1].find(it->first);
+        std::unordered_map<int, float>::iterator it2 = (*charProbabilities)[index1].find(it->first);
         if (it2 != (*charProbabilities)[index1].end() && it->second < it2->second) {
             const float newProbability = it->second * suppressionRate;
             const float suppression = it->second - newProbability;
@@ -932,7 +933,7 @@
 // returns probability of generating the word.
 /* static */ float ProximityInfoStateUtils::getMostProbableString(
         const ProximityInfo *const proximityInfo, const int sampledInputSize,
-        const std::vector<hash_map_compat<int, float> > *const charProbabilities,
+        const std::vector<std::unordered_map<int, float> > *const charProbabilities,
         int *const codePointBuf) {
     ASSERT(sampledInputSize >= 0);
     memset(codePointBuf, 0, sizeof(codePointBuf[0]) * MAX_WORD_LENGTH);
@@ -942,7 +943,7 @@
     for (int i = 0; i < sampledInputSize && index < MAX_WORD_LENGTH - 1; ++i) {
         float minLogProbability = static_cast<float>(MAX_VALUE_FOR_WEIGHTING);
         int character = NOT_AN_INDEX;
-        for (hash_map_compat<int, float>::const_iterator it = (*charProbabilities)[i].begin();
+        for (std::unordered_map<int, float>::const_iterator it = (*charProbabilities)[i].begin();
                 it != (*charProbabilities)[i].end(); ++it) {
             const float logProbability = (it->first != NOT_AN_INDEX)
                     ? it->second + ProximityInfoParams::DEMOTION_LOG_PROBABILITY : it->second;
diff --git a/native/jni/src/suggest/core/layout/proximity_info_state_utils.h b/native/jni/src/suggest/core/layout/proximity_info_state_utils.h
index 7aa20c3..71e83a8 100644
--- a/native/jni/src/suggest/core/layout/proximity_info_state_utils.h
+++ b/native/jni/src/suggest/core/layout/proximity_info_state_utils.h
@@ -18,10 +18,10 @@
 #define LATINIME_PROXIMITY_INFO_STATE_UTILS_H
 
 #include <bitset>
+#include <unordered_map>
 #include <vector>
 
 #include "defines.h"
-#include "utils/hash_map_compat.h"
 
 namespace latinime {
 class ProximityInfo;
@@ -29,7 +29,7 @@
 
 class ProximityInfoStateUtils {
  public:
-    typedef hash_map_compat<int, float> NearKeysDistanceMap;
+    typedef std::unordered_map<int, float> NearKeysDistanceMap;
     typedef std::bitset<MAX_KEY_COUNT_IN_A_KEYBOARD> NearKeycodesSet;
 
     static int trimLastTwoTouchPoints(std::vector<int> *sampledInputXs,
@@ -72,11 +72,11 @@
             const std::vector<int> *const sampledLengthCache,
             const std::vector<float> *const sampledNormalizedSquaredLengthCache,
             const ProximityInfo *const proximityInfo,
-            std::vector<hash_map_compat<int, float> > *charProbabilities);
+            std::vector<std::unordered_map<int, float> > *charProbabilities);
     static void updateSampledSearchKeySets(const ProximityInfo *const proximityInfo,
             const int sampledInputSize, const int lastSavedInputSize,
             const std::vector<int> *const sampledLengthCache,
-            const std::vector<hash_map_compat<int, float> > *const charProbabilities,
+            const std::vector<std::unordered_map<int, float> > *const charProbabilities,
             std::vector<NearKeycodesSet> *sampledSearchKeySets,
             std::vector<std::vector<int> > *sampledSearchKeyVectors);
     static float getPointToKeyByIdLength(const float maxPointToKeyLength,
@@ -105,7 +105,7 @@
     // TODO: Move to most_probable_string_utils.h
     static float getMostProbableString(const ProximityInfo *const proximityInfo,
             const int sampledInputSize,
-            const std::vector<hash_map_compat<int, float> > *const charProbabilities,
+            const std::vector<std::unordered_map<int, float> > *const charProbabilities,
             int *const codePointBuf);
 
  private:
@@ -147,7 +147,7 @@
             const int index2);
     static bool suppressCharProbabilities(const int mostCommonKeyWidth,
             const int sampledInputSize, const std::vector<int> *const lengthCache, const int index0,
-            const int index1, std::vector<hash_map_compat<int, float> > *charProbabilities);
+            const int index1, std::vector<std::unordered_map<int, float> > *charProbabilities);
     static float calculateSquaredDistanceFromSweetSpotCenter(
             const ProximityInfo *const proximityInfo, const std::vector<int> *const sampledInputXs,
             const std::vector<int> *const sampledInputYs, const int keyIndex,
diff --git a/native/jni/src/suggest/core/layout/proximity_info_utils.h b/native/jni/src/suggest/core/layout/proximity_info_utils.h
index c273ef4..178aada 100644
--- a/native/jni/src/suggest/core/layout/proximity_info_utils.h
+++ b/native/jni/src/suggest/core/layout/proximity_info_utils.h
@@ -18,18 +18,18 @@
 #define LATINIME_PROXIMITY_INFO_UTILS_H
 
 #include <cmath>
+#include <unordered_map>
 
 #include "defines.h"
 #include "suggest/core/layout/additional_proximity_chars.h"
 #include "suggest/core/layout/geometry_utils.h"
 #include "utils/char_utils.h"
-#include "utils/hash_map_compat.h"
 
 namespace latinime {
 class ProximityInfoUtils {
  public:
     static AK_FORCE_INLINE int getKeyIndexOf(const int keyCount, const int c,
-            const hash_map_compat<int, int> *const codeToKeyMap) {
+            const std::unordered_map<int, int> *const codeToKeyMap) {
         if (keyCount == 0) {
             // We do not have the coordinate data
             return NOT_AN_INDEX;
@@ -38,7 +38,7 @@
             return NOT_AN_INDEX;
         }
         const int lowerCode = CharUtils::toLowerCase(c);
-        hash_map_compat<int, int>::const_iterator mapPos = codeToKeyMap->find(lowerCode);
+        std::unordered_map<int, int>::const_iterator mapPos = codeToKeyMap->find(lowerCode);
         if (mapPos != codeToKeyMap->end()) {
             return mapPos->second;
         }
@@ -52,7 +52,7 @@
             const int *const proximityCharsArray, const int cellHeight, const int cellWidth,
             const int gridWidth, const int mostCommonKeyWidth, const int keyCount,
             const char *const localeStr,
-            const hash_map_compat<int, int> *const codeToKeyMap, int *inputProximities) {
+            const std::unordered_map<int, int> *const codeToKeyMap, int *inputProximities) {
         // Initialize
         // - mInputCodes
         // - mNormalizedSquaredDistances
@@ -144,7 +144,7 @@
             const int *const proximityCharsArray, const int cellHeight, const int cellWidth,
             const int gridWidth, const int mostCommonKeyWidth, const int keyCount,
             const int x, const int y, const int primaryKey, const char *const localeStr,
-            const hash_map_compat<int, int> *const codeToKeyMap, int *proximities) {
+            const std::unordered_map<int, int> *const codeToKeyMap, int *proximities) {
         const int mostCommonKeyWidthSquare = mostCommonKeyWidth * mostCommonKeyWidth;
         int insertPos = 0;
         proximities[insertPos++] = primaryKey;
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_gc_event_listeners.h b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_gc_event_listeners.h
index d886775..2aa4027 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_gc_event_listeners.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_gc_event_listeners.h
@@ -23,7 +23,6 @@
 #include "suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_reading_helper.h"
 #include "suggest/policyimpl/dictionary/structure/pt_common/pt_node_writer.h"
 #include "suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h"
-#include "utils/hash_map_compat.h"
 
 namespace latinime {
 
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.h b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.h
index f703baf..9b28152 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.h
@@ -19,7 +19,6 @@
 
 #include "defines.h"
 #include "suggest/policyimpl/dictionary/structure/pt_common/pt_node_params.h"
-#include "utils/hash_map_compat.h"
 
 namespace latinime {
 
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/pt_node_writer.h b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/pt_node_writer.h
index 84dd687..e843f07 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/pt_node_writer.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/pt_node_writer.h
@@ -17,18 +17,18 @@
 #ifndef LATINIME_PT_NODE_WRITER_H
 #define LATINIME_PT_NODE_WRITER_H
 
-#include "defines.h"
+#include <unordered_map>
 
+#include "defines.h"
 #include "suggest/policyimpl/dictionary/structure/pt_common/pt_node_params.h"
-#include "utils/hash_map_compat.h"
 
 namespace latinime {
 
 // Interface class used to write PtNode information.
 class PtNodeWriter {
  public:
-    typedef hash_map_compat<int, int> PtNodeArrayPositionRelocationMap;
-    typedef hash_map_compat<int, int> PtNodePositionRelocationMap;
+    typedef std::unordered_map<int, int> PtNodeArrayPositionRelocationMap;
+    typedef std::unordered_map<int, int> PtNodePositionRelocationMap;
     struct DictPositionRelocationMap {
      public:
         DictPositionRelocationMap()
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/terminal_position_lookup_table.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/terminal_position_lookup_table.h
index f73e227..8160595 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/terminal_position_lookup_table.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/terminal_position_lookup_table.h
@@ -17,16 +17,17 @@
 #ifndef LATINIME_TERMINAL_POSITION_LOOKUP_TABLE_H
 #define LATINIME_TERMINAL_POSITION_LOOKUP_TABLE_H
 
+#include <unordered_map>
+
 #include "defines.h"
 #include "suggest/policyimpl/dictionary/structure/v4/content/single_dict_content.h"
 #include "suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.h"
-#include "utils/hash_map_compat.h"
 
 namespace latinime {
 
 class TerminalPositionLookupTable : public SingleDictContent {
  public:
-    typedef hash_map_compat<int, int> TerminalIdMap;
+    typedef std::unordered_map<int, int> TerminalIdMap;
 
     TerminalPositionLookupTable(const char *const dictPath, const bool isUpdatable)
             : SingleDictContent(dictPath,
diff --git a/native/jni/src/utils/hash_map_compat.h b/native/jni/src/utils/hash_map_compat.h
deleted file mode 100644
index 7bf35a6..0000000
--- a/native/jni/src/utils/hash_map_compat.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef LATINIME_HASH_MAP_COMPAT_H
-#define LATINIME_HASH_MAP_COMPAT_H
-
-#include <unordered_map>
-
-#define hash_map_compat std::unordered_map
-
-#if 0 // TODO: Use this instead of the above macro.
-template <typename TKey, typename TValue> using hash_map_compat = std::unordered_map<TKey, TValue>;
-#endif
-
-#endif // LATINIME_HASH_MAP_COMPAT_H
diff --git a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetSubtypesCountTests.java b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetSubtypesCountTests.java
index 18390b2..e4aaf03 100644
--- a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetSubtypesCountTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetSubtypesCountTests.java
@@ -25,8 +25,8 @@
 
 @SmallTest
 public class KeyboardLayoutSetSubtypesCountTests extends KeyboardLayoutSetTestsBase {
-    private static final int NUMBER_OF_SUBTYPES = 69;
-    private static final int NUMBER_OF_ASCII_CAPABLE_SUBTYPES = 44;
+    private static final int NUMBER_OF_SUBTYPES = 70;
+    private static final int NUMBER_OF_ASCII_CAPABLE_SUBTYPES = 45;
     private static final int NUMBER_OF_PREDEFINED_ADDITIONAL_SUBTYPES = 2;
 
     private static String toString(final ArrayList<InputMethodSubtype> subtypeList) {
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Greek.java b/tests/src/com/android/inputmethod/keyboard/layout/Greek.java
index 0ec9f4c..475052c 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/Greek.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Greek.java
@@ -85,7 +85,7 @@
                     key(ROW1_2, moreKey("2")),
                     // U+03B5: "ε" GREEK SMALL LETTER EPSILON
                     // U+03AD: "έ" GREEK SMALL LETTER EPSILON WITH TONOS
-                    key("\u03B5", joinMoreKeys("3", "\u03AD")),
+                    key("\u03B5", joinMoreKeys("\u03AD", "3")),
                     // U+03C1: "ρ" GREEK SMALL LETTER RHO
                     key("\u03C1", moreKey("4")),
                     // U+03C4: "τ" GREEK SMALL LETTER TAU
@@ -94,17 +94,17 @@
                     // U+03CD: "ύ" GREEK SMALL LETTER UPSILON WITH TONOS
                     // U+03CB: "ϋ" GREEK SMALL LETTER UPSILON WITH DIALYTIKA
                     // U+03B0: "ΰ" GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
-                    key("\u03C5", joinMoreKeys("6", "\u03CD", "\u03CB", "\u03B0")),
+                    key("\u03C5", joinMoreKeys("\u03CD", "6", "\u03CB", "\u03B0")),
                     // U+03B8: "θ" GREEK SMALL LETTER THETA
                     key("\u03B8", moreKey("7")),
                     // U+03B9: "ι" GREEK SMALL LETTER IOTA
                     // U+03AF: "ί" GREEK SMALL LETTER IOTA WITH TONOS
                     // U+03CA: "ϊ" GREEK SMALL LETTER IOTA WITH DIALYTIKA
                     // U+0390: "ΐ" GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
-                    key("\u03B9", joinMoreKeys("8", "\u03AF", "\u03CA", "\u0390")),
+                    key("\u03B9", joinMoreKeys("\u03AF", "8", "\u03CA", "\u0390")),
                     // U+03BF: "ο" GREEK SMALL LETTER OMICRON
                     // U+03CC: "ό" GREEK SMALL LETTER OMICRON WITH TONOS
-                    key("\u03BF", joinMoreKeys("9", "\u03CC")),
+                    key("\u03BF", joinMoreKeys("\u03CC", "9")),
                     // U+03C0: "π" GREEK SMALL LETTER PI
                     key("\u03C0", moreKey("0")))
             .setKeysOfRow(2,
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Myanmar.java b/tests/src/com/android/inputmethod/keyboard/layout/Myanmar.java
new file mode 100644
index 0000000..2d1c901
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Myanmar.java
@@ -0,0 +1,252 @@
+/*
+ * 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.keyboard.layout;
+
+import com.android.inputmethod.keyboard.KeyboardId;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+import com.android.inputmethod.latin.Constants;
+
+import java.util.Locale;
+
+/**
+ * The Myanmar alphabet keyboard.
+ */
+public final class Myanmar extends LayoutBase {
+    private static final String LAYOUT_NAME = "myanmar";
+
+    public Myanmar(final LayoutCustomizer customizer) {
+        super(customizer, Symbols.class, SymbolsShifted.class);
+    }
+
+    @Override
+    public String getName() { return LAYOUT_NAME; }
+
+    public static class MyanmarCustomizer extends LayoutCustomizer {
+        public MyanmarCustomizer(final Locale locale) { super(locale); }
+
+        @Override
+        public ExpectedKey getAlphabetKey() { return MYANMAR_ALPHABET_KEY; }
+
+        @Override
+        public ExpectedKey[] getRightShiftKeys(final boolean isPhone) {
+            return isPhone ? EMPTY_KEYS : EXCLAMATION_AND_QUESTION_MARKS;
+        }
+
+        @Override
+        public ExpectedKey[] getKeysRightToSpacebar(final boolean isPhone) {
+            // U+104B: "။" MYANMAR SIGN SECTION
+            // U+104A: "၊" MYANMAR SIGN LITTLE SECTION
+            final ExpectedKey periodKey = key("\u104B", getPunctuationMoreKeys(isPhone));
+            final ExpectedKey commaKey = key("\u104A", moreKey(","));
+            return isPhone ? joinKeys(periodKey) : joinKeys(commaKey, periodKey);
+        }
+
+        @Override
+        public ExpectedKey[] getPunctuationMoreKeys(final boolean isPhone) {
+            return isPhone ? MYANMAR_PHONE_PUNCTUATION_MORE_KEYS
+                    : MYANMAR_TABLET_PUNCTUATION_MORE_KEYS;
+        }
+
+        // U+1000: "က" MYANMAR LETTER KA
+        // U+1001: "ခ" MYANMAR LETTER KHA
+        // U+1002: "ဂ" MYANMAR LETTER GA
+        private static final ExpectedKey MYANMAR_ALPHABET_KEY = key(
+                "\u1000\u1001\u1002", Constants.CODE_SWITCH_ALPHA_SYMBOL);
+
+        // U+104A: "၊" MYANMAR SIGN LITTLE SECTION
+        // Punctuation more keys for phone form factor.
+        private static final ExpectedKey[] MYANMAR_PHONE_PUNCTUATION_MORE_KEYS = joinKeys(
+                "\u104A", ".", "?", "!", "#", ")", "(", "/", ";",
+                "...", "'", "@", ":", "-", "\"", "+", "%", "&");
+        // Punctuation more keys for tablet form factor.
+        private static final ExpectedKey[] MYANMAR_TABLET_PUNCTUATION_MORE_KEYS = joinKeys(
+                ".", "'", "#", ")", "(", "/", ";", "@",
+                "...", ":", "-", "\"", "+", "%", "&");
+    }
+
+    @Override
+    ExpectedKey[][] getCommonAlphabetLayout(final boolean isPhone) { return ALPHABET_COMMON; }
+
+    @Override
+    public ExpectedKey[][] getCommonAlphabetShiftLayout(final boolean isPhone,
+            final int elementId) {
+        if (elementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED) {
+            return getCommonAlphabetLayout(isPhone);
+        }
+        return ALPHABET_SHIFTED_COMMON;
+    }
+
+    // Helper method to create alphabet layout by adding special function keys.
+    @Override
+    ExpectedKeyboardBuilder convertCommonLayoutToKeyboard(final ExpectedKeyboardBuilder builder,
+            final boolean isPhone) {
+        final LayoutCustomizer customizer = getCustomizer();
+        builder.setKeysOfRow(5, (Object[])customizer.getSpaceKeys(isPhone));
+        builder.addKeysOnTheLeftOfRow(5, (Object[])customizer.getKeysLeftToSpacebar(isPhone));
+        builder.addKeysOnTheRightOfRow(5, (Object[])customizer.getKeysRightToSpacebar(isPhone));
+        if (isPhone) {
+            builder.addKeysOnTheRightOfRow(4, DELETE_KEY)
+                    .addKeysOnTheLeftOfRow(5, customizer.getSymbolsKey())
+                    .addKeysOnTheRightOfRow(5, key(ENTER_KEY, EMOJI_KEY));
+        } else {
+            builder.addKeysOnTheRightOfRow(1, DELETE_KEY)
+                    .addKeysOnTheRightOfRow(3, ENTER_KEY)
+                    .addKeysOnTheLeftOfRow(5, customizer.getSymbolsKey(), SETTINGS_KEY)
+                    .addKeysOnTheRightOfRow(5, EMOJI_KEY);
+        }
+        builder.addKeysOnTheLeftOfRow(4, (Object[])customizer.getLeftShiftKeys(isPhone))
+                .addKeysOnTheRightOfRow(4, (Object[])customizer.getRightShiftKeys(isPhone));
+        return builder;
+    }
+
+    private static final ExpectedKey[][] ALPHABET_COMMON = new ExpectedKeyboardBuilder()
+            .setKeysOfRow(1,
+                    // U+1041: "၁" MYANMAR DIGIT ONE
+                    key("\u1041", moreKey("1")),
+                    // U+1042: "၂" MYANMAR DIGIT TWO
+                    key("\u1042", moreKey("2")),
+                    // U+1043: "၃" MYANMAR DIGIT THREE
+                    key("\u1043", moreKey("3")),
+                    // U+1044: "၄" MYANMAR DIGIT FOUR
+                    key("\u1044", moreKey("4")),
+                    // U+1045: "၅" MYANMAR DIGIT FIVE
+                    key("\u1045", moreKey("5")),
+                    // U+1046: "၆" MYANMAR DIGIT SIX
+                    key("\u1046", moreKey("6")),
+                    // U+1047: "၇" MYANMAR DIGIT SEVEN
+                    key("\u1047", moreKey("7")),
+                    // U+1048: "၈" MYANMAR DIGIT EIGHT
+                    key("\u1048", moreKey("8")),
+                    // U+1049: "၉" MYANMAR DIGIT NINE
+                    key("\u1049", moreKey("9")),
+                    // U+1040: "၀" MYANMAR DIGIT ZERO
+                    key("\u1040", moreKey("0")))
+            .setKeysOfRow(2,
+                    // U+1006: "ဆ" MYANMAR LETTER CHA
+                    // U+1010: "တ" MYANMAR LETTER TA
+                    // U+1014: "န" MYANMAR LETTER NA
+                    // U+1019: "မ" MYANMAR LETTER MA
+                    // U+1021: "အ" MYANMAR LETTER A
+                    // U+1015: "ပ" MYANMAR LETTER PA
+                    // U+1000: "က" MYANMAR LETTER KA
+                    // U+1004: "င" MYANMAR LETTER NGA
+                    // U+101E: "သ" MYANMAR LETTER SA
+                    // U+1005: "စ" MYANMAR LETTER CA
+                    "\u1006", "\u1010", "\u1014", "\u1019", "\u1021", "\u1015", "\u1000", "\u1004",
+                    "\u101E", "\u1005")
+            .setKeysOfRow(3,
+                    // U+1031: "ေ" MYANMAR VOWEL SIGN E
+                    // U+103B: "ျ" MYANMAR CONSONANT SIGN MEDIAL YA
+                    // U+103C: "ြ" MYANMAR CONSONANT SIGN MEDIAL RA
+                    "\u1031", "\u103B", "\u103C",
+                    // U+103D: "ွ" MYANMAR CONSONANT SIGN MEDIAL WA
+                    // U+103E: "ှ" MYANMAR CONSONANT SIGN MEDIAL HA
+                    // U+103D/U+103E:
+                    //     "ွှ" MYANMAR CONSONANT SIGN MEDIAL WA/MYANMAR CONSONANT SIGN MEDIAL HA
+                    key("\u103D", joinMoreKeys("\u103E", "\u103D\u103E")),
+                    // U+102D: "ိ" MYANMAR VOWEL SIGN I
+                    // U+102E: "ီ" MYANMAR VOWEL SIGN II
+                    key("\u102D", moreKey("\u102E")),
+                    // U+102F: "ု" MYANMAR VOWEL SIGN U
+                    // U+1030: "ူ" MYANMAR VOWEL SIGN UU
+                    key("\u102F", moreKey("\u1030")),
+                    // U+102C: "ာ" MYANMAR VOWEL SIGN AA
+                    "\u102C",
+                    // U+103A: "်" MYANMAR SIGN ASAT
+                    // U+1032: "ဲ" MYANMAR VOWEL SIGN AI
+                    key("\u103A", moreKey("\u1032")),
+                    // U+1037: "့" MYANMAR SIGN DOT BELOW
+                    // U+1036: "ံ" MYANMAR SIGN ANUSVARA
+                    key("\u1037", moreKey("\u1036")),
+                    // U+1038: "း" MYANMAR SIGN VISARGA
+                    "\u1038")
+            .setKeysOfRow(4,
+                    // U+1016: "ဖ" MYANMAR LETTER PHA
+                    // U+1011: "ထ" MYANMAR LETTER THA
+                    // U+1001: "ခ" MYANMAR LETTER KHA
+                    // U+101C: "လ" MYANMAR LETTER LA
+                    // U+1018: "ဘ" MYANMAR LETTER BHA
+                    "\u1016", "\u1011", "\u1001", "\u101C", "\u1018",
+                    // U+100A: "ည" MYANMAR LETTER NNYA
+                    // U+1009: "ဉ" MYANMAR LETTER NYA
+                    key("\u100A", moreKey("\u1009")),
+                    // U+101B: "ရ" MYANMAR LETTER RA
+                    // U+101D: "ဝ" MYANMAR LETTER WA
+                    "\u101B", "\u101D")
+            .build();
+
+    private static final ExpectedKey[][] ALPHABET_SHIFTED_COMMON = new ExpectedKeyboardBuilder()
+            .setKeysOfRow(1,
+                    // U+1027: "ဧ" MYANMAR LETTER E
+                    // U+104F: "၏" MYANMAR SYMBOL GENITIVE
+                    // U+1024: "ဤ" MYANMAR LETTER II
+                    // U+1023: "ဣ" MYANMAR LETTER I
+                    // U+104E: "၎" MYANMAR SYMBOL AFOREMENTIONED
+                    // U+1000/U+103B/U+1015/U+103A: "ကျပ်" MYANMAR LETTER KA
+                    //     /MYANMAR CONSONANT SIGN MEDIAL YA/MYANMAR LETTER PA/MYANMAR SIGN ASAT
+                    // U+1029: "ဩ" MYANMAR LETTER O
+                    // U+102A: "ဪ" MYANMAR LETTER AU
+                    // U+104D: "၍" MYANMAR SYMBOL COMPLETED
+                    // U+104C: "၌" MYANMAR SYMBOL LOCATIVE
+                    "\u1027", "\u104F", "\u1024", "\u1023", "\u104E", "\u1000\u103B\u1015\u103A",
+                    "\u1029", "\u102A", "\u104D", "\u104C")
+            .setKeysOfRow(2,
+                    // U+1017: "ဗ" MYANMAR LETTER BA
+                    // U+1012: "ဒ" MYANMAR LETTER DA
+                    // U+1013: "ဓ" MYANMAR LETTER DHA
+                    // U+1003: "ဃ" MYANMAR LETTER GHA
+                    // U+100E: "ဎ" MYANMAR LETTER DDHA
+                    // U+103F: "ဿ" MYANMAR LETTER GREAT SA
+                    // U+100F: "ဏ" MYANMAR LETTER NNA
+                    // U+1008: "ဈ" MYANMAR LETTER JHA
+                    // U+1007: "ဇ" MYANMAR LETTER JA
+                    // U+1002: "ဂ" MYANMAR LETTER GA
+                    "\u1017", "\u1012", "\u1013", "\u1003", "\u100E", "\u103F", "\u100F", "\u1008",
+                    "\u1007", "\u1002")
+            .setKeysOfRow(3,
+                    // U+101A: "ယ" MYANMAR LETTER YA
+                    // U+1039: "္" MYANMAR SIGN VIRAMA
+                    // U+1004/U+103A/U+1039: "င်္င" MYANMAR LETTER NGA
+                    //     /MYANMAR SIGN ASAT/MYANMAR SIGN VIRAMA
+                    // U+103E: "ှ" MYANMAR CONSONANT SIGN MEDIAL HA
+                    // U+102E: "ီ" MYANMAR VOWEL SIGN II
+                    // U+1030: "ူ" MYANMAR VOWEL SIGN UU
+                    // U+102B: "ါ" MYANMAR VOWEL SIGN TALL AA
+                    // U+1032: "ဲ" MYANMAR VOWEL SIGN AI
+                    // U+1036: "ံ" MYANMAR SIGN ANUSVARA
+                    // U+101F: "ဟ" MYANMAR LETTER HA
+                    "\u101A", "\u1039", "\u1004\u103A\u1039", "\u103E", "\u102E", "\u1030",
+                    "\u102B", "\u1032", "\u1036", "\u101F")
+            .setKeysOfRow(4,
+                    // U+1025: "ဥ" MYANMAR LETTER U
+                    // U+1026: "ဦ" MYANMAR LETTER UU
+                    // U+100C: "ဌ" MYANMAR LETTER TTHA
+                    // U+100B: "ဋ" MYANMAR LETTER TTA
+                    // U+100D: "ဍ" MYANMAR LETTER DDA
+                    // U+1020: "ဠ" MYANMAR LETTER LLA
+                    // U+100B/U+1039/U+100C: "ဋ္ဌ" MYANMAR LETTER TTA
+                    //     /MYANMAR SIGN VIRAMA/MYANMAR LETTER TTHA
+                    "\u1025", "\u1026", "\u100C", "\u100B", "\u100D", "\u1020",
+                    "\u100B\u1039\u100C",
+                    // U+100F/U+1039/U+100D: "ဏ္ဍ" MYANMAR LETTER NNA
+                    //     /MYANMAR SIGN VIRAMA/MYANMAR LETTER DDA
+                    // U+100F/U+1039/U+100C: "ဏ္ဌ" MYANMAR LETTER NNA
+                    //     /MYANMAR SIGN VIRAMA/MYANMAR LETTER TTHA
+                    key("\u100F\u1039\u100D", moreKey("\u100F\u1039\u100C")))
+            .build();
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/GermanCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/GermanCustomizer.java
index cd88140..6d38937 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/GermanCustomizer.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/GermanCustomizer.java
@@ -53,6 +53,7 @@
                 // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
                 // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
                 .setMoreKeysOf("u", "\u00FC", "\u00FB", "\u00F9", "\u00FA", "\u016B")
+                .setAdditionalMoreKeysPositionOf("u", 2)
                 // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
                 // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
                 // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
@@ -64,6 +65,7 @@
                 .setMoreKeysOf("o",
                         "\u00F6", "\u00F4", "\u00F2", "\u00F3", "\u00F5", "\u0153", "\u00F8",
                         "\u014D")
+                .setAdditionalMoreKeysPositionOf("o", 2)
                 // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
                 // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
                 // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
@@ -75,6 +77,7 @@
                 .setMoreKeysOf("a",
                         "\u00E4", "\u00E2", "\u00E0", "\u00E1", "\u00E6", "\u00E3", "\u00E5",
                         "\u0101")
+                .setAdditionalMoreKeysPositionOf("a", 2)
                 // U+00DF: "ß" LATIN SMALL LETTER SHARP S
                 // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
                 // U+0161: "š" LATIN SMALL LETTER S WITH CARON
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/ItalianCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/ItalianCustomizer.java
new file mode 100644
index 0000000..7350709
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/ItalianCustomizer.java
@@ -0,0 +1,77 @@
+/*
+ * 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.keyboard.layout.tests;
+
+import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+
+import java.util.Locale;
+
+class ItalianCustomizer extends LayoutCustomizer {
+    public ItalianCustomizer(final Locale locale) { super(locale); }
+
+    @Override
+    public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
+        return builder
+                // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
+                // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
+                // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
+                // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
+                // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK
+                // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
+                // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
+                .setMoreKeysOf("e",
+                        "\u00E8", "\u00E9", "\u00EA", "\u00EB", "\u0119", "\u0117", "\u0113")
+                // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
+                // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
+                // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
+                // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
+                // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
+                .setMoreKeysOf("u", "\u00F9", "\u00FA", "\u00FB", "\u00FC", "\u016B")
+                // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
+                // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
+                // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
+                // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
+                // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
+                // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
+                .setMoreKeysOf("i", "\u00EC", "\u00ED", "\u00EE", "\u00EF", "\u012F", "\u012B")
+                // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
+                // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
+                // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
+                // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
+                // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
+                // U+0153: "œ" LATIN SMALL LIGATURE OE
+                // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
+                // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
+                // U+00BA: "º" MASCULINE ORDINAL INDICATOR
+                .setMoreKeysOf("o",
+                        "\u00F2", "\u00F3", "\u00F4", "\u00F6", "\u00F5", "\u0153", "\u00F8",
+                        "\u014D", "\u00BA")
+                // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
+                // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
+                // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
+                // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
+                // U+00E6: "æ" LATIN SMALL LETTER AE
+                // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE
+                // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
+                // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON
+                // U+00AA: "ª" FEMININE ORDINAL INDICATOR
+                .setMoreKeysOf("a",
+                        "\u00E0", "\u00E1", "\u00E2", "\u00E4", "\u00E6", "\u00E3", "\u00E5",
+                        "\u0101", "\u00AA");
+    }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsItalian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsItalian.java
index 4a22003..f3c610c 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsItalian.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsItalian.java
@@ -31,63 +31,22 @@
 @SmallTest
 public final class TestsItalian extends LayoutTestsBase {
     private static final Locale LOCALE = new Locale("it");
-    private static final LayoutBase LAYOUT = new Qwerty(new ItalianCustomizer(LOCALE));
+    private static final LayoutBase LAYOUT = new Qwerty(new ItalianITCustomizer(LOCALE));
 
     @Override
     LayoutBase getLayout() { return LAYOUT; }
 
-    private static class ItalianCustomizer extends EuroCustomizer {
-        public ItalianCustomizer(final Locale locale) { super(locale); }
+    private static class ItalianITCustomizer extends EuroCustomizer {
+        private final ItalianCustomizer mItalianCustomizer;
+
+        public ItalianITCustomizer(final Locale locale) {
+            super(locale);
+            mItalianCustomizer = new ItalianCustomizer(locale);
+        }
 
         @Override
         public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
-            return builder
-                    // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
-                    // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
-                    // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
-                    // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
-                    // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK
-                    // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
-                    // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
-                    .setMoreKeysOf("e",
-                            "\u00E8", "\u00E9", "\u00EA", "\u00EB", "\u0119", "\u0117", "\u0113")
-                    // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
-                    // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
-                    // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
-                    // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
-                    // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
-                    .setMoreKeysOf("u", "\u00F9", "\u00FA", "\u00FB", "\u00FC", "\u016B")
-                    // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
-                    // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
-                    // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
-                    // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
-                    // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
-                    // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
-                    .setMoreKeysOf("i", "\u00EC", "\u00ED", "\u00EE", "\u00EF", "\u012F", "\u012B")
-                    // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
-                    // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
-                    // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
-                    // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
-                    // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
-                    // U+0153: "œ" LATIN SMALL LIGATURE OE
-                    // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
-                    // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
-                    // U+00BA: "º" MASCULINE ORDINAL INDICATOR
-                    .setMoreKeysOf("o",
-                            "\u00F2", "\u00F3", "\u00F4", "\u00F6", "\u00F5", "\u0153", "\u00F8",
-                            "\u014D", "\u00BA")
-                    // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
-                    // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
-                    // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
-                    // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
-                    // U+00E6: "æ" LATIN SMALL LETTER AE
-                    // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE
-                    // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
-                    // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON
-                    // U+00AA: "ª" FEMININE ORDINAL INDICATOR
-                    .setMoreKeysOf("a",
-                            "\u00E0", "\u00E1", "\u00E2", "\u00E4", "\u00E6", "\u00E3", "\u00E5",
-                            "\u0101", "\u00AA");
+            return mItalianCustomizer.setAccentedLetters(builder);
         }
     }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsItalianCH.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsItalianCH.java
new file mode 100644
index 0000000..d32f9e9
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsItalianCH.java
@@ -0,0 +1,56 @@
+/*
+ * 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.keyboard.layout.tests;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.inputmethod.keyboard.layout.LayoutBase;
+import com.android.inputmethod.keyboard.layout.Swiss;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+
+import java.util.Locale;
+
+/**
+ * it_CH: Italian (Switzerland)/swiss
+ */
+@SmallTest
+public final class TestsItalianCH extends LayoutTestsBase {
+    private static final Locale LOCALE = new Locale("it", "CH");
+    private static final LayoutBase LAYOUT = new Swiss(new ItalianCHCustomizer(LOCALE));
+
+    @Override
+    LayoutBase getLayout() { return LAYOUT; }
+
+    private static class ItalianCHCustomizer extends ItalianCustomizer {
+        public ItalianCHCustomizer(final Locale locale) { super(locale); }
+
+        @Override
+        public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
+            super.setAccentedLetters(builder);
+            return builder
+                    // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
+                    // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
+                    .replaceKeyOfLabel(Swiss.ROW1_11, key("\u00FC", moreKey("\u00E8")))
+                    // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
+                    // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
+                    .replaceKeyOfLabel(Swiss.ROW2_10, key("\u00F6", moreKey("\u00E9")))
+                    // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
+                    // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
+                    .replaceKeyOfLabel(Swiss.ROW2_11, key("\u00E4", moreKey("\u00E0")));
+        }
+    }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMyanmarMM.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMyanmarMM.java
new file mode 100644
index 0000000..e6d3b3b
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMyanmarMM.java
@@ -0,0 +1,37 @@
+/*
+ * 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.keyboard.layout.tests;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.inputmethod.keyboard.layout.LayoutBase;
+import com.android.inputmethod.keyboard.layout.Myanmar;
+import com.android.inputmethod.keyboard.layout.Myanmar.MyanmarCustomizer;
+
+import java.util.Locale;
+
+/**
+ * my_MM: Myanmar (Myanmar)/myanmar
+ */
+@SmallTest
+public final class TestsMyanmarMM extends LayoutTestsBase {
+    private static final Locale LOCALE = new Locale("my", "MM");
+    private static final LayoutBase LAYOUT = new Myanmar(new MyanmarCustomizer(LOCALE));
+
+    @Override
+    LayoutBase getLayout() { return LAYOUT; }
+}
diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
index 1383ff9..e5f111a 100644
--- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java
+++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
@@ -213,13 +213,18 @@
 
     @Override
     protected void tearDown() throws Exception {
+        mLatinIME.onFinishInputView(true);
+        mLatinIME.onFinishInput();
+        runMessages();
         mLatinIME.mHandler.removeAllMessages();
         setBooleanPreference(Settings.PREF_BIGRAM_PREDICTIONS, mPreviousBigramPredictionSettings,
                 true /* defaultValue */);
         setStringPreference(Settings.PREF_AUTO_CORRECTION_THRESHOLD, mPreviousAutoCorrectSetting,
                 DEFAULT_AUTO_CORRECTION_THRESHOLD);
         setDebugMode(false);
+        mLatinIME.recycle();
         super.tearDown();
+        mLatinIME = null;
     }
 
     // We need to run the messages added to the handler from LatinIME. The only way to do
diff --git a/tools/make-keyboard-text/res/values-de/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-de/donottranslate-more-keys.xml
index 94b1724..0c6d3ad 100644
--- a/tools/make-keyboard-text/res/values-de/donottranslate-more-keys.xml
+++ b/tools/make-keyboard-text/res/values-de/donottranslate-more-keys.xml
@@ -26,7 +26,7 @@
          U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE
          U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
          U+0101: "ā" LATIN SMALL LETTER A WITH MACRON -->
-    <string name="morekeys_a">&#x00E4;,&#x00E2;,&#x00E0;,&#x00E1;,&#x00E6;,&#x00E3;,&#x00E5;,&#x0101;</string>
+    <string name="morekeys_a">&#x00E4;,%,&#x00E2;,&#x00E0;,&#x00E1;,&#x00E6;,&#x00E3;,&#x00E5;,&#x0101;</string>
     <!-- U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
          U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
          U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
@@ -41,13 +41,13 @@
          U+0153: "œ" LATIN SMALL LIGATURE OE
          U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
          U+014D: "ō" LATIN SMALL LETTER O WITH MACRON -->
-    <string name="morekeys_o">&#x00F6;,&#x00F4;,&#x00F2;,&#x00F3;,&#x00F5;,&#x0153;,&#x00F8;,&#x014D;</string>
+    <string name="morekeys_o">&#x00F6;,%,&#x00F4;,&#x00F2;,&#x00F3;,&#x00F5;,&#x0153;,&#x00F8;,&#x014D;</string>
     <!-- U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
          U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
          U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
          U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
          U+016B: "ū" LATIN SMALL LETTER U WITH MACRON -->
-    <string name="morekeys_u">&#x00FC;,&#x00FB;,&#x00F9;,&#x00FA;,&#x016B;</string>
+    <string name="morekeys_u">&#x00FC;,%,&#x00FB;,&#x00F9;,&#x00FA;,&#x016B;</string>
     <!-- U+00DF: "ß" LATIN SMALL LETTER SHARP S
          U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
          U+0161: "š" LATIN SMALL LETTER S WITH CARON -->
diff --git a/tools/make-keyboard-text/res/values-it/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-it/donottranslate-more-keys.xml
index 6492553..e809f48 100644
--- a/tools/make-keyboard-text/res/values-it/donottranslate-more-keys.xml
+++ b/tools/make-keyboard-text/res/values-it/donottranslate-more-keys.xml
@@ -59,4 +59,16 @@
          U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
          U+016B: "ū" LATIN SMALL LETTER U WITH MACRON -->
     <string name="morekeys_u">&#x00F9;,&#x00FA;,&#x00FB;,&#x00FC;,&#x016B;</string>
+    <!-- U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS -->
+    <string name="keyspec_swiss_row1_11">&#x00FC;</string>
+    <!-- U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE -->
+    <string name="morekeys_swiss_row1_11">&#x00E8;</string>
+    <!-- U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS -->
+    <string name="keyspec_swiss_row2_10">&#x00F6;</string>
+    <!-- U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE -->
+    <string name="morekeys_swiss_row2_10">&#x00E9;</string>
+    <!-- U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS -->
+    <string name="keyspec_swiss_row2_11">&#x00E4;</string>
+    <!-- U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE -->
+    <string name="morekeys_swiss_row2_11">&#x00E0;</string>
 </resources>
diff --git a/tools/make-keyboard-text/res/values-my-rMM/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-my-rMM/donottranslate-more-keys.xml
index f6186ff..f408f58 100644
--- a/tools/make-keyboard-text/res/values-my-rMM/donottranslate-more-keys.xml
+++ b/tools/make-keyboard-text/res/values-my-rMM/donottranslate-more-keys.xml
@@ -23,4 +23,13 @@
          U+1001: "ခ" MYANMAR LETTER KHA
          U+1002: "ဂ" MYANMAR LETTER GA -->
     <string name="keylabel_to_alpha">&#x1000;&#x1001;&#x1002;</string>
+    <!-- U+104A: "၊" MYANMAR SIGN LITTLE SECTION
+         U+104B: "။" MYANMAR SIGN SECTION -->
+    <string name="keyspec_tablet_comma">&#x104A;</string>
+    <string name="morekeys_tablet_comma">"\\,"</string>
+    <string name="keyspec_tablet_period">&#x104B;</string>
+    <string name="keyspec_period">&#x104B;</string>
+    <string name="keyhintlabel_period">&#x104A;</string>
+    <string name="morekeys_punctuation">"!autoColumnOrder!9,&#x104A;,.,?,!,#,),(,/,;,...,',@,:,-,\",+,\\%,&amp;"</string>
+    <string name="morekeys_tablet_punctuation">"!autoColumnOrder!8,.,',#,),(,/,;,@,...,:,-,\",+,\\%,&amp;"</string>
 </resources>