Merge "Rework the logic that tells if the cursor touches words"
diff --git a/java/res/values-iw-sw600dp/config-spacing-and-punctuations.xml b/java/res/values-iw-sw600dp/config-spacing-and-punctuations.xml
new file mode 100644
index 0000000..b562b18
--- /dev/null
+++ b/java/res/values-iw-sw600dp/config-spacing-and-punctuations.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** 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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- The all letters need to be mirrored are found at
+         http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt -->
+    <!-- Symbols that are suggested between words -->
+    <string name="suggested_punctuations" translatable="false">:,;,\",(|),)|(,\',-,/,@,_</string>
+</resources>
diff --git a/java/res/values-iw/config-spacing-and-punctuations.xml b/java/res/values-iw/config-spacing-and-punctuations.xml
new file mode 100644
index 0000000..9a9e6ee
--- /dev/null
+++ b/java/res/values-iw/config-spacing-and-punctuations.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** 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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- The all letters need to be mirrored are found at
+         http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt -->
+    <!-- Symbols that are suggested between words -->
+    <string name="suggested_punctuations" translatable="false">!,?,\\,,:,;,\",(|),)|(,\',-,/,@,_</string>
+</resources>
diff --git a/java/res/values-sw600dp/config-spacing-and-punctuations.xml b/java/res/values-sw600dp/config-spacing-and-punctuations.xml
index 9c12cf4..4d19412 100644
--- a/java/res/values-sw600dp/config-spacing-and-punctuations.xml
+++ b/java/res/values-sw600dp/config-spacing-and-punctuations.xml
@@ -19,5 +19,5 @@
 -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <!-- Symbols that are suggested between words -->
-    <string name="suggested_punctuations" translatable="false">:,;,\",!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis,\',-,/,@,_</string>
+    <string name="suggested_punctuations" translatable="false">:,;,\",(,),\',-,/,@,_</string>
 </resources>
diff --git a/java/res/values/config-spacing-and-punctuations.xml b/java/res/values/config-spacing-and-punctuations.xml
index 1dd2e1f..ad5663d 100644
--- a/java/res/values/config-spacing-and-punctuations.xml
+++ b/java/res/values/config-spacing-and-punctuations.xml
@@ -21,7 +21,7 @@
     <!-- TODO: these settings depend on the language. They should be put either in the dictionary
          header, or in the subtype maybe? -->
     <!-- Symbols that are suggested between words -->
-    <string name="suggested_punctuations" translatable="false">!,?,\\,,:,;,\",!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis,\',-,/,@,_</string>
+    <string name="suggested_punctuations" translatable="false">!,?,\\,,:,;,\",(,),\',-,/,@,_</string>
     <!-- Symbols that are normally preceded by a space (used to add an auto-space before these) -->
     <string name="symbols_preceded_by_space" translatable="false">([{&amp;</string>
     <!-- Symbols that are normally followed by a space (used to add an auto-space after these) -->
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 5efa733..bd18e55 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -337,29 +337,39 @@
     <!-- Title of the item to change the keyboard theme [CHAR LIMIT=20]-->
     <string name="keyboard_layout">Keyboard theme</string>
 
-    <!-- Description for English (United Kingdom) keyboard subtype [CHAR LIMIT=25] -->
+    <!-- Description for English (UK) keyboard subtype [CHAR LIMIT=25]
+         (UK) should be an abbreviation of United Kingdom to fit in the CHAR LIMIT. -->
     <string name="subtype_en_GB">English (UK)</string>
-    <!-- Description for English (United States) keyboard subtype [CHAR LIMIT=25] -->
+    <!-- Description for English (US) keyboard subtype [CHAR LIMIT=25]
+         (US) should be an abbreviation of United States to fit in the CHAR LIMIT. -->
     <string name="subtype_en_US">English (US)</string>
-    <!-- Description for Spanish (United States) keyboard subtype [CHAR LIMIT=25] -->
+    <!-- Description for Spanish (US) keyboard subtype [CHAR LIMIT=25]
+         (US) should be an abbreviation of United States to fit in the CHAR LIMIT. -->
     <string name="subtype_es_US">Spanish (US)</string>
-    <!-- Description for English (United Kingdom) keyboard subtype with explicit keyboard layout [CHAR LIMIT=25]
+    <!-- Description for English (UK) keyboard subtype with explicit keyboard layout [CHAR LIMIT=25]
+         (UK) should be an abbreviation of United Kingdom to fit in the CHAR LIMIT.
          This should be identical to subtype_en_GB aside from the trailing (%s). -->
     <string name="subtype_with_layout_en_GB">English (UK) (<xliff:g id="KEYBOARD_LAYOUT" example="QWERTY">%s</xliff:g>)</string>
-    <!-- Description for English (United States) keyboard subtype with explicit keyboard layout [CHAR LIMIT=25]
+    <!-- Description for English (US) keyboard subtype with explicit keyboard layout [CHAR LIMIT=25]
+         (US) should be an abbreviation of United States to fit in the CHAR LIMIT.
          This should be identical to subtype_en_US aside from the trailing (%s). -->
     <string name="subtype_with_layout_en_US">English (US) (<xliff:g id="KEYBOARD_LAYOUT" example="QWERTY">%s</xliff:g>)</string>
-    <!-- Description for Spanish (United States) keyboard subtype with explicit keyboard layout [CHAR LIMIT=25]
+    <!-- Description for Spanish (US) keyboard subtype with explicit keyboard layout [CHAR LIMIT=25]
+         (US) should be an abbreviation of United Statesn to fit in the CHAR LIMIT.
          This should be identical to subtype_es_US aside from the trailing (%s). -->
     <string name="subtype_with_layout_es_US">Spanish (US) (<xliff:g id="KEYBOARD_LAYOUT" example="QWERTY">%s</xliff:g>)</string>
-    <!-- Description for Nepali (Traditional) keyboard subtype [CHAR LIMIT=25] -->
+    <!-- Description for Nepali (Traditional) keyboard subtype [CHAR LIMIT=25]
+         (Traditional) can be an abbreviation to fit in the CHAR LIMIT. -->
     <string name="subtype_nepali_traditional"><xliff:g id="LANGUAGE_NAME" example="Nepali">%s</xliff:g> (Traditional)</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>
     -->
diff --git a/java/res/xml-sw600dp/key_styles_enter.xml b/java/res/xml-sw600dp/key_styles_enter.xml
index 38a38fd..05762ad 100644
--- a/java/res/xml-sw600dp/key_styles_enter.xml
+++ b/java/res/xml-sw600dp/key_styles_enter.xml
@@ -112,7 +112,7 @@
         >
             <key-style
                 latin:styleName="enterKeyStyle"
-                latin:keySpec="!text/label_go_key|!code/key_shift_enter"
+                latin:keySpec="!icon/enter_key|!code/key_shift_enter"
                 latin:parentStyle="defaultEnterKeyStyle" />
         </case>
         <case
diff --git a/java/res/xml-sw600dp/keys_pcqwerty2_right3.xml b/java/res/xml-sw600dp/keys_pcqwerty2_right3.xml
index ab99ec5..76ac6bb 100644
--- a/java/res/xml-sw600dp/keys_pcqwerty2_right3.xml
+++ b/java/res/xml-sw600dp/keys_pcqwerty2_right3.xml
@@ -23,7 +23,7 @@
 >
     <switch>
         <case
-            latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted"
+            latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted|alphabetShiftLocked"
         >
             <Key
                 latin:keySpec="["
diff --git a/java/res/xml-sw600dp/keys_pcqwerty3_right2.xml b/java/res/xml-sw600dp/keys_pcqwerty3_right2.xml
index 5443396..f18fb50 100644
--- a/java/res/xml-sw600dp/keys_pcqwerty3_right2.xml
+++ b/java/res/xml-sw600dp/keys_pcqwerty3_right2.xml
@@ -23,7 +23,7 @@
 >
     <switch>
         <case
-            latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted"
+            latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted|alphabetShiftLocked"
         >
             <Key
                 latin:keySpec=";"
diff --git a/java/res/xml-sw600dp/keys_pcqwerty4_right3.xml b/java/res/xml-sw600dp/keys_pcqwerty4_right3.xml
index c95ca2e..ff1a2c8 100644
--- a/java/res/xml-sw600dp/keys_pcqwerty4_right3.xml
+++ b/java/res/xml-sw600dp/keys_pcqwerty4_right3.xml
@@ -23,7 +23,7 @@
 >
     <switch>
         <case
-            latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted"
+            latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted|alphabetShiftLocked"
         >
             <Key
                 latin:keySpec=","
diff --git a/java/res/xml-sw600dp/row_pcqwerty5.xml b/java/res/xml-sw600dp/row_pcqwerty5.xml
index b854f10..52b581a 100644
--- a/java/res/xml-sw600dp/row_pcqwerty5.xml
+++ b/java/res/xml-sw600dp/row_pcqwerty5.xml
@@ -24,37 +24,32 @@
     <Row
         latin:keyWidth="7.0%p"
     >
+        <include
+            latin:keyWidth="9.0%p"
+            latin:keyboardLayout="@xml/key_shortcut" />
         <switch>
             <case
                 latin:languageSwitchKeyEnabled="true"
             >
                 <Key
                     latin:keyStyle="languageSwitchKeyStyle"
-                    latin:keyWidth="9.0%p"
-                    latin:backgroundType="functional" />
+                    latin:keyXPos="22.0%p"
+                    latin:keyWidth="9.0%p" />
+                <Key
+                    latin:keyStyle="spaceKeyStyle"
+                    latin:keyWidth="40.0%p" />
             </case>
-        </switch>
-        <Key
-            latin:keyStyle="spaceKeyStyle"
-            latin:keyXPos="25.5%p"
-            latin:keyWidth="49.0%p" />
-        <switch>
-            <case
-                latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted"
-            >
-                <include
-                    latin:keyXPos="-9.0%p"
-                    latin:keyWidth="9.0%p"
-                    latin:keyboardLayout="@xml/key_shortcut" />
-            </case>
-            <!-- keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted" -->
             <default>
-                <include
-                    latin:keyXPos="-9.0%p"
-                    latin:keyWidth="9.0%p"
-                    latin:backgroundType="functional"
-                    latin:keyboardLayout="@xml/key_f2" />
+                <Key
+                    latin:keyStyle="spaceKeyStyle"
+                    latin:keyXPos="29.0%p"
+                    latin:keyWidth="42.0%p" />
             </default>
         </switch>
+        <include
+            latin:keyXPos="-9.0%p"
+            latin:keyWidth="9.0%p"
+            latin:backgroundType="functional"
+            latin:keyboardLayout="@xml/key_f2" />
     </Row>
 </merge>
diff --git a/java/res/xml-sw600dp/rowkeys_pcqwerty1.xml b/java/res/xml-sw600dp/rowkeys_pcqwerty1.xml
index 5389e22..5c7506e 100644
--- a/java/res/xml-sw600dp/rowkeys_pcqwerty1.xml
+++ b/java/res/xml-sw600dp/rowkeys_pcqwerty1.xml
@@ -21,87 +21,98 @@
 <merge
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
 >
-    <Key
-        latin:keySpec="`"
-        latin:keyHintLabel="~"
-        latin:additionalMoreKeys="~"
-        latin:keyStyle="hasShiftedLetterHintStyle" />
-    <Key
-        latin:keySpec="1"
-        latin:keyHintLabel="!"
-        latin:additionalMoreKeys="!"
-        latin:keyStyle="hasShiftedLetterHintStyle"
-        latin:moreKeys="!text/more_keys_for_exclamation,!text/more_keys_for_symbols_1" />
-    <Key
-        latin:keySpec="2"
-        latin:keyHintLabel="\@"
-        latin:additionalMoreKeys="\@"
-        latin:keyStyle="hasShiftedLetterHintStyle"
-        latin:moreKeys="!text/more_keys_for_symbols_2" />
-    <Key
-        latin:keySpec="3"
-        latin:keyHintLabel="\#"
-        latin:additionalMoreKeys="\#"
-        latin:keyStyle="hasShiftedLetterHintStyle"
-        latin:moreKeys="!text/more_keys_for_symbols_3" />
-    <Key
-        latin:keySpec="4"
-        latin:keyHintLabel="$"
-        latin:additionalMoreKeys="$"
-        latin:keyStyle="hasShiftedLetterHintStyle"
-        latin:moreKeys="!text/more_keys_for_symbols_4" />
-    <Key
-        latin:keySpec="5"
-        latin:keyHintLabel="%"
-        latin:additionalMoreKeys="\\%"
-        latin:keyStyle="hasShiftedLetterHintStyle"
-        latin:moreKeys="!text/more_keys_for_symbols_5" />
-    <Key
-        latin:keySpec="6"
-        latin:keyHintLabel="^"
-        latin:additionalMoreKeys="^"
-        latin:keyStyle="hasShiftedLetterHintStyle"
-        latin:moreKeys="!text/more_keys_for_symbols_6" />
-    <Key
-        latin:keySpec="7"
-        latin:keyHintLabel="&amp;"
-        latin:additionalMoreKeys="&amp;"
-        latin:keyStyle="hasShiftedLetterHintStyle"
-        latin:moreKeys="!text/more_keys_for_symbols_7" />
-    <Key
-        latin:keySpec="8"
-        latin:keyHintLabel="*"
-        latin:additionalMoreKeys="*"
-        latin:keyStyle="hasShiftedLetterHintStyle"
-        latin:moreKeys="!text/more_keys_for_symbols_8" />
-    <Key
-        latin:keySpec="9"
-        latin:keyHintLabel="("
-        latin:additionalMoreKeys="("
-        latin:keyStyle="hasShiftedLetterHintStyle"
-        latin:moreKeys="!text/more_keys_for_symbols_9" />
-    <Key
-        latin:keySpec="0"
-        latin:keyHintLabel=")"
-        latin:additionalMoreKeys=")"
-        latin:keyStyle="hasShiftedLetterHintStyle"
-        latin:moreKeys="!text/more_keys_for_symbols_0" />
-    <!-- U+2013: "–" EN DASH
-         U+2014: "—" EM DASH
-         U+00B7: "·" MIDDLE DOT -->
-    <Key
-        latin:keySpec="-"
-        latin:keyHintLabel="_"
-        latin:additionalMoreKeys="_"
-        latin:keyStyle="hasShiftedLetterHintStyle"
-        latin:moreKeys="&#x2013;,&#x2014;,&#x00B7;" />
-    <!-- U+221E: "∞" INFINITY
-         U+2260: "≠" NOT EQUAL TO
-         U+2248: "≈" ALMOST EQUAL TO -->
-    <Key
-        latin:keySpec="="
-        latin:keyHintLabel="+"
-        latin:additionalMoreKeys="+"
-        latin:keyStyle="hasShiftedLetterHintStyle"
-        latin:moreKeys="&#x221E;,&#x2260;,&#x2248;" />
+    <switch>
+        <case
+            latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted|alphabetShiftLocked"
+        >
+            <Key
+                latin:keySpec="`"
+                latin:keyHintLabel="~"
+                latin:additionalMoreKeys="~"
+                latin:keyStyle="hasShiftedLetterHintStyle" />
+            <Key
+                latin:keySpec="1"
+                latin:keyHintLabel="!"
+                latin:additionalMoreKeys="!"
+                latin:keyStyle="hasShiftedLetterHintStyle"
+                latin:moreKeys="!text/more_keys_for_exclamation,!text/more_keys_for_symbols_1" />
+            <Key
+                latin:keySpec="2"
+                latin:keyHintLabel="\@"
+                latin:additionalMoreKeys="\@"
+                latin:keyStyle="hasShiftedLetterHintStyle"
+                latin:moreKeys="!text/more_keys_for_symbols_2" />
+            <Key
+                latin:keySpec="3"
+                latin:keyHintLabel="\#"
+                latin:additionalMoreKeys="\#"
+                latin:keyStyle="hasShiftedLetterHintStyle"
+                latin:moreKeys="!text/more_keys_for_symbols_3" />
+            <Key
+                latin:keySpec="4"
+                latin:keyHintLabel="$"
+                latin:additionalMoreKeys="$"
+                latin:keyStyle="hasShiftedLetterHintStyle"
+                latin:moreKeys="!text/more_keys_for_symbols_4" />
+            <Key
+                latin:keySpec="5"
+                latin:keyHintLabel="%"
+                latin:additionalMoreKeys="\\%"
+                latin:keyStyle="hasShiftedLetterHintStyle"
+                latin:moreKeys="!text/more_keys_for_symbols_5" />
+            <Key
+                latin:keySpec="6"
+                latin:keyHintLabel="^"
+                latin:additionalMoreKeys="^"
+                latin:keyStyle="hasShiftedLetterHintStyle"
+                latin:moreKeys="!text/more_keys_for_symbols_6" />
+            <Key
+                latin:keySpec="7"
+                latin:keyHintLabel="&amp;"
+                latin:additionalMoreKeys="&amp;"
+                latin:keyStyle="hasShiftedLetterHintStyle"
+                latin:moreKeys="!text/more_keys_for_symbols_7" />
+            <Key
+                latin:keySpec="8"
+                latin:keyHintLabel="*"
+                latin:additionalMoreKeys="*"
+                latin:keyStyle="hasShiftedLetterHintStyle"
+                latin:moreKeys="!text/more_keys_for_symbols_8" />
+            <Key
+                latin:keySpec="9"
+                latin:keyHintLabel="("
+                latin:additionalMoreKeys="("
+                latin:keyStyle="hasShiftedLetterHintStyle"
+                latin:moreKeys="!text/more_keys_for_symbols_9" />
+            <Key
+                latin:keySpec="0"
+                latin:keyHintLabel=")"
+                latin:additionalMoreKeys=")"
+                latin:keyStyle="hasShiftedLetterHintStyle"
+                latin:moreKeys="!text/more_keys_for_symbols_0" />
+            <!-- U+2013: "–" EN DASH
+                 U+2014: "—" EM DASH
+                 U+00B7: "·" MIDDLE DOT -->
+            <Key
+                latin:keySpec="-"
+                latin:keyHintLabel="_"
+                latin:additionalMoreKeys="_"
+                latin:keyStyle="hasShiftedLetterHintStyle"
+                latin:moreKeys="&#x2013;,&#x2014;,&#x00B7;" />
+            <!-- U+221E: "∞" INFINITY
+                 U+2260: "≠" NOT EQUAL TO
+                 U+2248: "≈" ALMOST EQUAL TO -->
+            <Key
+                latin:keySpec="="
+                latin:keyHintLabel="+"
+                latin:additionalMoreKeys="+"
+                latin:keyStyle="hasShiftedLetterHintStyle"
+                latin:moreKeys="&#x221E;,&#x2260;,&#x2248;" />
+        </case>
+        <!-- keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLockShifted" -->
+        <default>
+            <include
+                 latin:keyboardLayout="@xml/rowkeys_pcqwerty1_shift" />
+        </default>
+    </switch>
 </merge>
diff --git a/java/res/xml-sw600dp/rows_colemak.xml b/java/res/xml-sw600dp/rows_colemak.xml
index ab059da..7559bfb 100644
--- a/java/res/xml-sw600dp/rows_colemak.xml
+++ b/java/res/xml-sw600dp/rows_colemak.xml
@@ -28,8 +28,6 @@
     >
         <include
             latin:keyboardLayout="@xml/rowkeys_colemak1" />
-        <include
-            latin:keyboardLayout="@xml/key_colemak_colon" />
         <Key
             latin:keyStyle="deleteKeyStyle"
             latin:keyWidth="fillRight" />
diff --git a/java/res/xml-sw600dp/rows_myanmar.xml b/java/res/xml-sw600dp/rows_myanmar.xml
new file mode 100644
index 0000000..778b330
--- /dev/null
+++ b/java/res/xml-sw600dp/rows_myanmar.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** 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.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <include
+        latin:keyboardLayout="@xml/key_styles_common" />
+    <Row
+        latin:keyWidth="8.1818%p"
+    >
+        <include
+            latin:keyboardLayout="@xml/rowkeys_myanmar1" />
+        <Key
+            latin:keyStyle="deleteKeyStyle"
+            latin:keyWidth="fillRight" />
+        </Row>
+    <Row
+        latin:keyWidth="8.1818%p"
+    >
+        <include
+            latin:keyboardLayout="@xml/rowkeys_myanmar2" />
+    </Row>
+    <Row
+        latin:keyWidth="8.1818%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"
+    >
+        <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>
+    </Row>
+    <include
+        latin:keyboardLayout="@xml/row_qwerty4" />
+</merge>
diff --git a/java/res/xml-sw600dp/rows_pcqwerty.xml b/java/res/xml-sw600dp/rows_pcqwerty.xml
index 8714815..73b7e47 100644
--- a/java/res/xml-sw600dp/rows_pcqwerty.xml
+++ b/java/res/xml-sw600dp/rows_pcqwerty.xml
@@ -26,19 +26,8 @@
     <Row
         latin:keyWidth="7.0%p"
     >
-        <switch>
-            <case
-                latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted"
-            >
-                <include
-                    latin:keyboardLayout="@xml/rowkeys_pcqwerty1" />
-            </case>
-            <!-- keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted" -->
-            <default>
-                <include
-                     latin:keyboardLayout="@xml/rowkeys_pcqwerty1_shift" />
-            </default>
-        </switch>
+        <include
+            latin:keyboardLayout="@xml/rowkeys_pcqwerty1" />
         <Key
             latin:keyStyle="deleteKeyStyle"
             latin:keyWidth="fillRight" />
@@ -56,7 +45,7 @@
         latin:keyWidth="7.0%p"
     >
         <Spacer
-            latin:keyWidth="12.0%p" />
+            latin:keyWidth="10.0%p" />
         <include
             latin:keyboardLayout="@xml/rowkeys_pcqwerty3" />
         <Key
diff --git a/java/res/xml/kbd_myanmar.xml b/java/res/xml/kbd_myanmar.xml
new file mode 100644
index 0000000..af997b1
--- /dev/null
+++ b/java/res/xml/kbd_myanmar.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** 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.
+*/
+-->
+
+<Keyboard
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+    latin:rowHeight="20%p"
+    latin:verticalGap="@fraction/config_key_vertical_gap_5row"
+    latin:keyLetterSize="@fraction/config_key_letter_ratio_5row"
+    latin:keyShiftedLetterHintRatio="@fraction/config_key_shifted_letter_hint_ratio_5row"
+    latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
+>
+    <include
+        latin:keyboardLayout="@xml/rows_myanmar" />
+</Keyboard>
diff --git a/java/res/xml/key_colemak_colon.xml b/java/res/xml/key_colemak_colon.xml
deleted file mode 100644
index 9330be9..0000000
--- a/java/res/xml/key_colemak_colon.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
--->
-
-<merge
-    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
-    <switch>
-        <case
-            latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLockShifted"
-        >
-            <Key
-                latin:keySpec=";"
-                latin:keyHintLabel="0"
-                latin:additionalMoreKeys="0" />
-        </case>
-        <default>
-            <Key
-                latin:keySpec=":"
-                latin:keyHintLabel="0"
-                latin:additionalMoreKeys="0"
-                latin:moreKeys=";" />
-        </default>
-    </switch>
-</merge>
diff --git a/java/res/xml/key_f1.xml b/java/res/xml/key_f1.xml
index d3a7539..0a89fe3 100644
--- a/java/res/xml/key_f1.xml
+++ b/java/res/xml/key_f1.xml
@@ -42,7 +42,6 @@
             <Key
                 latin:keySpec="!text/keylabel_for_comma"
                 latin:keyLabelFlags="hasPopupHint"
-                latin:additionalMoreKeys="!text/more_keys_for_comma"
                 latin:keyStyle="f1MoreKeysStyle" />
         </case>
         <!-- latin:supportsSwitchingToShortcutIme="true" -->
@@ -57,7 +56,7 @@
             <Key
                 latin:keySpec="!text/keylabel_for_comma"
                 latin:keyLabelFlags="hasPopupHint"
-                latin:additionalMoreKeys="!text/more_keys_for_comma,!text/shortcut_as_more_key"
+                latin:additionalMoreKeys="!text/shortcut_as_more_key"
                 latin:keyStyle="f1MoreKeysStyle" />
         </default>
     </switch>
diff --git a/java/res/xml/key_styles_currency.xml b/java/res/xml/key_styles_currency.xml
index ed40ebc..0888cc3 100644
--- a/java/res/xml/key_styles_currency.xml
+++ b/java/res/xml/key_styles_currency.xml
@@ -50,7 +50,7 @@
              19. San Marino (it_SM)
              20. Slovakia (sk_SK)
              21. Slovenia (sl_SI)
-             22. Spain (es_ES, ca_ES)
+             22. Spain (es_ES, ca_ES, eu_ES, gl_ES)
              23. Vatican City (it_VA) -->
         <case
             latin:countryCode="AD|AT|BE|CY|EE|FI|FR|DE|GR|IE|IT|XK|LU|MT|MO|ME|NL|PT|SM|SK|SI|ES|VA"
diff --git a/java/res/xml/keyboard_layout_set_myanmar.xml b/java/res/xml/keyboard_layout_set_myanmar.xml
new file mode 100644
index 0000000..5c823b2
--- /dev/null
+++ b/java/res/xml/keyboard_layout_set_myanmar.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** 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.
+*/
+-->
+
+<KeyboardLayoutSet
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin">
+    <Element
+        latin:elementName="alphabet"
+        latin:elementKeyboard="@xml/kbd_myanmar"
+        latin:enableProximityCharsCorrection="true" />
+    <Element
+        latin:elementName="alphabetAutomaticShifted"
+        latin:elementKeyboard="@xml/kbd_myanmar"
+        latin:enableProximityCharsCorrection="true" />
+    <!-- On these shifted alphabet layouts the proximity characters correction should be disabled
+         because the letters on these layouts aren't the ones in different case of the above
+         unshifted layouts. -->
+    <Element
+        latin:elementName="alphabetManualShifted"
+        latin:elementKeyboard="@xml/kbd_myanmar" />
+    <Element
+        latin:elementName="alphabetShiftLocked"
+        latin:elementKeyboard="@xml/kbd_myanmar" />
+    <Element
+        latin:elementName="alphabetShiftLockShifted"
+        latin:elementKeyboard="@xml/kbd_myanmar" />
+    <Element
+        latin:elementName="symbols"
+        latin:elementKeyboard="@xml/kbd_symbols" />
+    <Element
+        latin:elementName="symbolsShifted"
+        latin:elementKeyboard="@xml/kbd_symbols_shift" />
+    <Element
+        latin:elementName="phone"
+        latin:elementKeyboard="@xml/kbd_phone" />
+    <Element
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
+    <Element
+        latin:elementName="number"
+        latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardLayoutSet>
diff --git a/java/res/xml/keys_comma_period_symbols.xml b/java/res/xml/keys_comma_period_symbols.xml
index 5221d34..53c3343 100644
--- a/java/res/xml/keys_comma_period_symbols.xml
+++ b/java/res/xml/keys_comma_period_symbols.xml
@@ -22,8 +22,7 @@
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
 >
     <Key
-        latin:keySpec="!text/keylabel_for_comma"
-        latin:moreKeys="!text/more_keys_for_comma" />
+        latin:keySpec="!text/keylabel_for_comma" />
     <!-- U+2026: "…" HORIZONTAL ELLIPSIS -->
     <Key
         latin:keySpec="."
diff --git a/java/res/xml/keys_pcqwerty2_right3.xml b/java/res/xml/keys_pcqwerty2_right3.xml
index 9e62b09..b188cff 100644
--- a/java/res/xml/keys_pcqwerty2_right3.xml
+++ b/java/res/xml/keys_pcqwerty2_right3.xml
@@ -23,7 +23,7 @@
 >
     <switch>
         <case
-            latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted"
+            latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted|alphabetShiftLocked"
         >
             <Key
                 latin:keySpec="["
diff --git a/java/res/xml/keys_pcqwerty3_right2.xml b/java/res/xml/keys_pcqwerty3_right2.xml
index d889216..8a1f60f 100644
--- a/java/res/xml/keys_pcqwerty3_right2.xml
+++ b/java/res/xml/keys_pcqwerty3_right2.xml
@@ -23,7 +23,7 @@
 >
     <switch>
         <case
-            latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted"
+            latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted|alphabetShiftLocked"
         >
             <Key
                 latin:keySpec=";"
diff --git a/java/res/xml/keys_pcqwerty4_right3.xml b/java/res/xml/keys_pcqwerty4_right3.xml
index f32d809..6beba20 100644
--- a/java/res/xml/keys_pcqwerty4_right3.xml
+++ b/java/res/xml/keys_pcqwerty4_right3.xml
@@ -23,7 +23,7 @@
 >
     <switch>
         <case
-            latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted"
+            latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted|alphabetShiftLocked"
         >
             <Key
                 latin:keySpec=","
diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml
index deef9d1..c64b3a4 100644
--- a/java/res/xml/method.xml
+++ b/java/res/xml/method.xml
@@ -41,11 +41,13 @@
     es_US: Spanish (United States)/spanish
     (es_419: Spanish (Latin America)/qwerty)
     et_EE: Estonian (Estonia)/nordic
+    eu_ES: Basque (Spain)/spanish
     fa: Persian/farsi
     fi: Finnish/nordic
     fr: French/azerty
     fr_CA: French (Canada)/qwerty
     fr_CH: French (Switzerland)/swiss
+    gl_ES: Galician (Spain)/spanish
     hi: Hindi/hindi
     hr: Croatian/qwertz
     hu: Hungarian/qwertz
@@ -64,6 +66,7 @@
     mk: Macedonian/south_slavic
     mn_MN: Mongolian (Mongolia)/mongolian
     ms_MY: Malay (Malaysia)/qwerty
+    (my_MM: Myanmar (Myanmar)/myanmar) # This is a preliminary keyboard layout.
     nb: Norwegian Bokmål/nordic
     ne_NP: Nepali (Nepal) Romanized/nepali_romanized
     ne_NP: Nepali (Nepal) Traditional/nepali_traditional
@@ -255,6 +258,14 @@
     />
     <subtype android:icon="@drawable/ic_ime_switcher_dark"
             android:label="@string/subtype_generic"
+            android:subtypeId="0x070e5c07"
+            android:imeSubtypeLocale="eu_ES"
+            android:imeSubtypeMode="keyboard"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable,EmojiCapable"
+            android:isAsciiCapable="true"
+    />
+    <subtype android:icon="@drawable/ic_ime_switcher_dark"
+            android:label="@string/subtype_generic"
             android:subtypeId="0xbe66c254"
             android:imeSubtypeLocale="fa"
             android:imeSubtypeMode="keyboard"
@@ -295,6 +306,14 @@
     />
     <subtype android:icon="@drawable/ic_ime_switcher_dark"
             android:label="@string/subtype_generic"
+            android:subtypeId="0xb939573c"
+            android:imeSubtypeLocale="gl_ES"
+            android:imeSubtypeMode="keyboard"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable,EmojiCapable"
+            android:isAsciiCapable="true"
+    />
+    <subtype android:icon="@drawable/ic_ime_switcher_dark"
+            android:label="@string/subtype_generic"
             android:subtypeId="0x39753b7f"
             android:imeSubtypeLocale="hi"
             android:imeSubtypeMode="keyboard"
@@ -431,6 +450,8 @@
             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"
@@ -441,6 +462,14 @@
     />
     <subtype android:icon="@drawable/ic_ime_switcher_dark"
             android:label="@string/subtype_generic"
+            android:subtypeId="0xea266ea4"
+            android:imeSubtypeLocale="my_MM"
+            android:imeSubtypeMode="keyboard"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=myanmar,EmojiCapable"
+            android:isAsciiCapable="false"
+    />
+    <subtype android:icon="@drawable/ic_ime_switcher_dark"
+            android:label="@string/subtype_generic"
             android:subtypeId="0x3f12ee14"
             android:imeSubtypeLocale="nb"
             android:imeSubtypeMode="keyboard"
diff --git a/java/res/xml/row_pcqwerty5.xml b/java/res/xml/row_pcqwerty5.xml
index f6438ab..3782763 100644
--- a/java/res/xml/row_pcqwerty5.xml
+++ b/java/res/xml/row_pcqwerty5.xml
@@ -24,23 +24,21 @@
     <Row
         latin:keyWidth="7.692%p"
     >
-        <Spacer
-            latin:keyWidth="11.538%p" />
         <switch>
             <case
-                latin:supportsSwitchingToShortcutIme="true"
+                latin:hasShortcutKey="true"
             >
                 <Key
                     latin:keyStyle="shortcutKeyStyle"
                     latin:keyWidth="11.538%p" />
-                </case>
+            </case>
             <case
                 latin:clobberSettingsKey="false"
             >
                 <Key
                     latin:keyStyle="settingsKeyStyle"
                     latin:keyWidth="11.538%p" />
-                </case>
+            </case>
         </switch>
         <switch>
             <case
@@ -48,24 +46,23 @@
             >
                 <Key
                     latin:keyStyle="languageSwitchKeyStyle"
+                    latin:keyXPos="19.231%p"
                     latin:keyWidth="11.538%p" />
                 <Key
                     latin:keyStyle="spaceKeyStyle"
-                    latin:keyWidth="38.464%p" />
-                </case>
+                    latin:keyWidth="42.308%p" />
+            </case>
             <!-- languageSwitchKeyEnabled="false" -->
             <default>
                 <Key
                     latin:keyStyle="spaceKeyStyle"
-                    latin:keyWidth="50.002%p" />
+                    latin:keyXPos="26.923%p"
+                    latin:keyWidth="46.154%p" />
             </default>
         </switch>
         <Key
-            latin:keyStyle="defaultEnterKeyStyle"
-            latin:keySpec="!icon/enter_key|!code/key_enter"
-            latin:keyWidth="15.384%p" />
-        <Key
-            latin:keyStyle="emojiKeyStyle"
+            latin:keyStyle="enterKeyStyle"
+            latin:keyXPos="-19.231%p"
             latin:keyWidth="fillRight" />
     </Row>
 </merge>
diff --git a/java/res/xml/rowkeys_colemak1.xml b/java/res/xml/rowkeys_colemak1.xml
index 819a69d..2f2ade4 100644
--- a/java/res/xml/rowkeys_colemak1.xml
+++ b/java/res/xml/rowkeys_colemak1.xml
@@ -63,4 +63,21 @@
         latin:keyHintLabel="9"
         latin:additionalMoreKeys="9"
         latin:moreKeys="!text/more_keys_for_y" />
+    <switch>
+        <case
+            latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLockShifted"
+        >
+            <Key
+                latin:keySpec=":"
+                latin:keyHintLabel="0"
+                latin:additionalMoreKeys="0" />
+        </case>
+        <default>
+            <Key
+                latin:keySpec=";"
+                latin:keyHintLabel="0"
+                latin:additionalMoreKeys="0"
+                latin:moreKeys=":" />
+        </default>
+    </switch>
 </merge>
diff --git a/java/res/xml/rowkeys_myanmar1.xml b/java/res/xml/rowkeys_myanmar1.xml
new file mode 100644
index 0000000..6460af5
--- /dev/null
+++ b/java/res/xml/rowkeys_myanmar1.xml
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** 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.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <switch>
+        <case
+            latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+        >
+            <!-- U+100E: "ဎ" MYANMAR LETTER DDHA -->
+            <Key
+                latin:keySpec="&#x100E;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+100D: "ဍ" MYANMAR LETTER DDA -->
+            <Key
+                latin:keySpec="&#x100D;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1052: "ၒ" MYANMAR LETTER VOCALIC R -->
+            <Key
+                latin:keySpec="&#x1052;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+100B: "ဋ" MYANMAR LETTER TTA -->
+            <Key
+                latin:keySpec="&#x100B;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1053: "ၓ" MYANMAR LETTER VOCALIC RR -->
+            <Key
+                latin:keySpec="&#x1053;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1054: "ၔ" MYANMAR LETTER VOCALIC L -->
+            <Key
+                latin:keySpec="&#x1054;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1055: "ၕ" MYANMAR LETTER VOCALIC LL -->
+            <Key
+                latin:keySpec="&#x1055;"
+                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;"
+                latin:keyHintLabel="1"
+                latin:additionalMoreKeys="1"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1042: "၂" MYANMAR DIGIT TWO -->
+            <Key
+                latin:keySpec="&#x1042;"
+                latin:keyHintLabel="2"
+                latin:additionalMoreKeys="2"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1043: "၃" MYANMAR DIGIT THREE -->
+            <Key
+                latin:keySpec="&#x1043;"
+                latin:keyHintLabel="3"
+                latin:additionalMoreKeys="3"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1044: "၄" MYANMAR DIGIT FOUR -->
+            <Key
+                latin:keySpec="&#x1044;"
+                latin:keyHintLabel="4"
+                latin:additionalMoreKeys="4"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1045: "၅" MYANMAR DIGIT FIVE -->
+            <Key
+                latin:keySpec="&#x1045;"
+                latin:keyHintLabel="5"
+                latin:additionalMoreKeys="5"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1046: "၆" MYANMAR DIGIT SIX -->
+            <Key
+                latin:keySpec="&#x1046;"
+                latin:keyHintLabel="6"
+                latin:additionalMoreKeys="6"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1047: "၇" MYANMAR DIGIT SEVEN -->
+            <Key
+                latin:keySpec="&#x1047;"
+                latin:keyHintLabel="7"
+                latin:additionalMoreKeys="7"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1048: "၈" MYANMAR DIGIT EIGHT -->
+            <Key
+                latin:keySpec="&#x1048;"
+                latin:keyHintLabel="8"
+                latin:additionalMoreKeys="8"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1049: "၉" MYANMAR DIGIT NINE -->
+            <Key
+                latin:keySpec="&#x1049;"
+                latin:keyHintLabel="9"
+                latin:additionalMoreKeys="9"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1040: "၀" MYANMAR DIGIT ZERO -->
+            <Key
+                latin:keySpec="&#x1040;"
+                latin:keyHintLabel="0"
+                latin:additionalMoreKeys="0"
+                latin:keyLabelFlags="fontNormal" />
+        </default>
+    </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_myanmar2.xml b/java/res/xml/rowkeys_myanmar2.xml
new file mode 100644
index 0000000..558c38d
--- /dev/null
+++ b/java/res/xml/rowkeys_myanmar2.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** 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.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <switch>
+        <case
+            latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+        >
+            <!-- U+1008: "ဈ" MYANMAR LETTER JHA -->
+            <Key
+                latin:keySpec="&#x1008;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+101D: "ဝ" MYANMAR LETTER WA -->
+            <Key
+                latin:keySpec="&#x101D;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1023: "ဣ" MYANMAR LETTER I -->
+            <Key
+                latin:keySpec="&#x1023;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+104E: "၎" MYANMAR SYMBOL AFOREMENTIONED -->
+            <Key
+                latin:keySpec="&#x104E;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1024: "ဤ" MYANMAR LETTER II -->
+            <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:keyLabelFlags="fontNormal" />
+            <!-- U+103F: "ဿ" MYANMAR LETTER GREAT SA -->
+            <Key
+                latin:keySpec="&#x103F;"
+                latin:keyLabelFlags="fontNormal|autoXScale" />
+            <!-- U+100F: "ဏ" MYANMAR LETTER NNA -->
+            <Key
+                latin:keySpec="&#x100F;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1027: "ဧ" MYANMAR LETTER E -->
+            <Key
+                latin:keySpec="&#x1027;"
+                latin:keyLabelFlags="fontNormal" />
+        </case>
+        <default>
+            <!-- U+1006: "ဆ" MYANMAR LETTER CHA -->
+            <Key
+                latin:keySpec="&#x1006;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1010: "တ" MYANMAR LETTER TA -->
+            <Key
+                latin:keySpec="&#x1010;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1014: "န" MYANMAR LETTER NA -->
+            <Key
+                latin:keySpec="&#x1014;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1019: "မ" MYANMAR LETTER MA -->
+            <Key
+                latin:keySpec="&#x1019;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1021: "အ" MYANMAR LETTER A -->
+            <Key
+                latin:keySpec="&#x1021;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1015: "ပ" MYANMAR LETTER PA -->
+            <Key
+                latin:keySpec="&#x1015;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1000: "က" MYANMAR LETTER KA -->
+            <Key
+                latin:keySpec="&#x1000;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1004: "င" MYANMAR LETTER NGA -->
+            <Key
+                latin:keySpec="&#x1004;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+101E: "သ" MYANMAR LETTER SA -->
+            <Key
+                latin:keySpec="&#x101E;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1005: "စ" MYANMAR LETTER CA -->
+            <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
new file mode 100644
index 0000000..2d0d48c
--- /dev/null
+++ b/java/res/xml/rowkeys_myanmar3.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** 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.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <switch>
+        <case
+            latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+        >
+            <!-- U+1017: "ဗ" MYANMAR LETTER BA -->
+            <Key
+                latin:keySpec="&#x1017;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+103E: "ှ" MYANMAR CONSONANT SIGN MEDIAL HA -->
+            <Key
+                latin:keySpec="&#x103E;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+102E: "ီ" MYANMAR VOWEL SIGN II -->
+            <Key
+                latin:keySpec="&#x102E;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1039: "္" MYANMAR SIGN VIRAMA -->
+            <Key
+                latin:keySpec="&#x1039;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+103D: "ွ" MYANMAR CONSONANT SIGN MEDIAL WA -->
+            <Key
+                latin:keySpec="&#x103D;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1036: "ံ" MYANMAR SIGN ANUSVARA -->
+            <Key
+                latin:keySpec="&#x1036;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1032: "ဲ" MYANMAR VOWEL SIGN AI -->
+            <Key
+                latin:keySpec="&#x1032;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1012: "ဒ" MYANMAR LETTER DA -->
+            <Key
+                latin:keySpec="&#x1012;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1013: "ဓ" MYANMAR LETTER DHA -->
+            <Key
+                latin:keySpec="&#x1013;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1002: "ဂ" MYANMAR LETTER GA -->
+            <Key
+                latin:keySpec="&#x1002;"
+                latin:keyLabelFlags="fontNormal" />
+        </case>
+        <default>
+            <!-- U+1031: "ေ" MYANMAR VOWEL SIGN E -->
+            <Key
+                latin:keySpec="&#x1031;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+103B: "ျ" MYANMAR CONSONANT SIGN MEDIAL YA -->
+            <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 -->
+            <Key
+                latin:keySpec="&#x102F;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1030: "ူ" MYANMAR VOWEL SIGN UU -->
+            <Key
+                latin:keySpec="&#x1030;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1038: "း" MYANMAR SIGN VISARGA -->
+            <Key
+                latin:keySpec="&#x1038;"
+                latin:keyLabelFlags="fontNormal" />
+        </default>
+    </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_myanmar4.xml b/java/res/xml/rowkeys_myanmar4.xml
new file mode 100644
index 0000000..cfd1112
--- /dev/null
+++ b/java/res/xml/rowkeys_myanmar4.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** 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.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <switch>
+        <case
+            latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+        >
+            <!-- U+1007: "ဇ" MYANMAR LETTER JA -->
+            <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:keyLabelFlags="fontNormal" />
+            <!-- U+1026: "ဦ" MYANMAR LETTER UU -->
+            <Key
+                latin:keySpec="&#x1026;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+102A: "ဪ" MYANMAR LETTER AU -->
+            <Key
+                latin:keySpec="&#x102A;"
+                latin:keyLabelFlags="fontNormal|autoXScale" />
+            <!-- U+1051: "ၑ" MYANMAR LETTER SSA -->
+            <Key
+                latin:keySpec="&#x1051;"
+                latin:keyLabelFlags="fontNormal" />
+        </case>
+        <default>
+            <!-- U+1016: "ဖ" MYANMAR LETTER PHA -->
+            <Key
+                latin:keySpec="&#x1016;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1011: "ထ" MYANMAR LETTER THA -->
+            <Key
+                latin:keySpec="&#x1011;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1001: "ခ" MYANMAR LETTER KHA -->
+            <Key
+                latin:keySpec="&#x1001;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+101C: "လ" MYANMAR LETTER LA -->
+            <Key
+                latin:keySpec="&#x101C;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1018: "ဘ" MYANMAR LETTER BHA -->
+            <Key
+                latin:keySpec="&#x1018;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+100A: "ည" MYANMAR LETTER NNYA -->
+            <Key
+                latin:keySpec="&#x100A;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+102C: "ာ" MYANMAR VOWEL SIGN AA -->
+            <Key
+                latin:keySpec="&#x102C;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+1029: "ဩ" MYANMAR LETTER O -->
+            <Key
+                latin:keySpec="&#x1029;"
+                latin:keyLabelFlags="fontNormal" />
+            <!-- U+104F: "၏" MYANMAR SYMBOL GENITIVE -->
+            <Key
+                latin:keySpec="&#x104F;"
+                latin:keyLabelFlags="fontNormal" />
+        </default>
+    </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_pcqwerty1.xml b/java/res/xml/rowkeys_pcqwerty1.xml
index fdb5072..3695733 100644
--- a/java/res/xml/rowkeys_pcqwerty1.xml
+++ b/java/res/xml/rowkeys_pcqwerty1.xml
@@ -21,61 +21,72 @@
 <merge
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
 >
-    <Key
-        latin:keySpec="`"
-        latin:additionalMoreKeys="~" />
-    <Key
-        latin:keySpec="1"
-        latin:additionalMoreKeys="!,!text/more_keys_for_exclamation"
-        latin:moreKeys="!text/more_keys_for_symbols_1" />
-    <Key
-        latin:keySpec="2"
-        latin:additionalMoreKeys="\@"
-        latin:moreKeys="!text/more_keys_for_symbols_2" />
-    <Key
-        latin:keySpec="3"
-        latin:additionalMoreKeys="\#"
-        latin:moreKeys="!text/more_keys_for_symbols_3" />
-    <Key
-        latin:keySpec="4"
-        latin:additionalMoreKeys="$"
-        latin:moreKeys="!text/more_keys_for_symbols_4" />
-    <Key
-        latin:keySpec="5"
-        latin:additionalMoreKeys="\\%"
-        latin:moreKeys="!text/more_keys_for_symbols_5" />
-    <Key
-        latin:keySpec="6"
-        latin:additionalMoreKeys="^"
-        latin:moreKeys="!text/more_keys_for_symbols_6" />
-    <Key
-        latin:keySpec="7"
-        latin:additionalMoreKeys="&amp;"
-        latin:moreKeys="!text/more_keys_for_symbols_7" />
-    <Key
-        latin:keySpec="8"
-        latin:additionalMoreKeys="*"
-        latin:moreKeys="!text/more_keys_for_symbols_8" />
-    <Key
-        latin:keySpec="9"
-        latin:additionalMoreKeys="("
-        latin:moreKeys="!text/more_keys_for_symbols_9" />
-    <Key
-        latin:keySpec="0"
-        latin:additionalMoreKeys=")"
-        latin:moreKeys="!text/more_keys_for_symbols_0" />
-    <!-- U+2013: "–" EN DASH
-         U+2014: "—" EM DASH
-         U+00B7: "·" MIDDLE DOT -->
-    <Key
-        latin:keySpec="-"
-        latin:additionalMoreKeys="_"
-        latin:moreKeys="&#x2013;,&#x2014;,&#x00B7;" />
-    <!-- U+221E: "∞" INFINITY
-         U+2260: "≠" NOT EQUAL TO
-         U+2248: "≈" ALMOST EQUAL TO -->
-    <Key
-        latin:keySpec="="
-        latin:additionalMoreKeys="+"
-        latin:moreKeys="!fixedColumnOrder!4,&#x221E;,&#x2260;,&#x2248;,%" />
+    <switch>
+        <case
+            latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted|alphabetShiftLocked"
+        >
+            <Key
+                latin:keySpec="`"
+                latin:additionalMoreKeys="~" />
+            <Key
+                latin:keySpec="1"
+                latin:additionalMoreKeys="!,!text/more_keys_for_exclamation"
+                latin:moreKeys="!text/more_keys_for_symbols_1" />
+            <Key
+                latin:keySpec="2"
+                latin:additionalMoreKeys="\@"
+                latin:moreKeys="!text/more_keys_for_symbols_2" />
+            <Key
+                latin:keySpec="3"
+                latin:additionalMoreKeys="\#"
+                latin:moreKeys="!text/more_keys_for_symbols_3" />
+            <Key
+                latin:keySpec="4"
+                latin:additionalMoreKeys="$"
+                latin:moreKeys="!text/more_keys_for_symbols_4" />
+            <Key
+                latin:keySpec="5"
+                latin:additionalMoreKeys="\\%"
+                latin:moreKeys="!text/more_keys_for_symbols_5" />
+            <Key
+                latin:keySpec="6"
+                latin:additionalMoreKeys="^"
+                latin:moreKeys="!text/more_keys_for_symbols_6" />
+            <Key
+                latin:keySpec="7"
+                latin:additionalMoreKeys="&amp;"
+                latin:moreKeys="!text/more_keys_for_symbols_7" />
+            <Key
+                latin:keySpec="8"
+                latin:additionalMoreKeys="*"
+                latin:moreKeys="!text/more_keys_for_symbols_8" />
+            <Key
+                latin:keySpec="9"
+                latin:additionalMoreKeys="("
+                latin:moreKeys="!text/more_keys_for_symbols_9" />
+            <Key
+                latin:keySpec="0"
+                latin:additionalMoreKeys=")"
+                latin:moreKeys="!text/more_keys_for_symbols_0" />
+            <!-- U+2013: "–" EN DASH
+                 U+2014: "—" EM DASH
+                 U+00B7: "·" MIDDLE DOT -->
+            <Key
+                latin:keySpec="-"
+                latin:additionalMoreKeys="_"
+                latin:moreKeys="&#x2013;,&#x2014;,&#x00B7;" />
+            <!-- U+221E: "∞" INFINITY
+                 U+2260: "≠" NOT EQUAL TO
+                 U+2248: "≈" ALMOST EQUAL TO -->
+            <Key
+                latin:keySpec="="
+                latin:additionalMoreKeys="+"
+                latin:moreKeys="!fixedColumnOrder!4,&#x221E;,&#x2260;,&#x2248;,%" />
+        </case>
+        <!-- keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLockShifted" -->
+        <default>
+            <include
+                 latin:keyboardLayout="@xml/rowkeys_pcqwerty1_shift" />
+        </default>
+    </switch>
 </merge>
diff --git a/java/res/xml/rowkeys_pcqwerty1_shift.xml b/java/res/xml/rowkeys_pcqwerty1_shift.xml
index b9597c0..6a5f00c 100644
--- a/java/res/xml/rowkeys_pcqwerty1_shift.xml
+++ b/java/res/xml/rowkeys_pcqwerty1_shift.xml
@@ -49,12 +49,11 @@
         latin:keySpec=")" />
     <Key
         latin:keySpec="_" />
-    <!-- U+00B1: "±" PLUS-MINUS SIGN
-         U+00D7: "×" MULTIPLICATION SIGN
+    <!-- U+00D7: "×" MULTIPLICATION SIGN
          U+00F7: "÷" DIVISION SIGN
          U+221A: "√" SQUARE ROOT -->
     <Key
         latin:keySpec="+"
         latin:additionalMoreKeys="!text/more_keys_for_plus"
-        latin:moreKeys="&#x00B1;,&#x00D7;,&#x00F7;,&#x221A;" />
+        latin:moreKeys="&#x00D7;,&#x00F7;,&#x221A;" />
 </merge>
diff --git a/java/res/xml/rows_colemak.xml b/java/res/xml/rows_colemak.xml
index d74c2c9..ec553c2 100644
--- a/java/res/xml/rows_colemak.xml
+++ b/java/res/xml/rows_colemak.xml
@@ -28,8 +28,6 @@
     >
         <include
             latin:keyboardLayout="@xml/rowkeys_colemak1" />
-        <include
-            latin:keyboardLayout="@xml/key_colemak_colon" />
     </Row>
     <Row
         latin:keyWidth="10%p"
diff --git a/java/res/xml/rows_myanmar.xml b/java/res/xml/rows_myanmar.xml
new file mode 100644
index 0000000..32c923d
--- /dev/null
+++ b/java/res/xml/rows_myanmar.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** 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.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <include
+        latin:keyboardLayout="@xml/key_styles_common" />
+    <Row
+        latin:keyWidth="9.0909%p"
+    >
+        <include
+            latin:keyboardLayout="@xml/rowkeys_myanmar1" />
+    </Row>
+    <Row
+        latin:keyWidth="9.0909%p"
+    >
+        <include
+            latin:keyboardLayout="@xml/rowkeys_myanmar2" />
+    </Row>
+    <Row
+        latin:keyWidth="9.0909%p"
+    >
+        <include
+            latin:keyXPos="4.5454%p"
+            latin:keyboardLayout="@xml/rowkeys_myanmar3" />
+    </Row>
+    <Row
+        latin:keyWidth="9.0909%p"
+    >
+        <Key
+            latin:keyStyle="shiftKeyStyle" />
+        <include
+            latin:keyboardLayout="@xml/rowkeys_myanmar4" />
+        <Key
+            latin:keyStyle="deleteKeyStyle" />
+    </Row>
+    <include
+        latin:keyboardLayout="@xml/row_qwerty4" />
+</merge>
diff --git a/java/res/xml/rows_pcqwerty.xml b/java/res/xml/rows_pcqwerty.xml
index 8846989..a5ed745 100644
--- a/java/res/xml/rows_pcqwerty.xml
+++ b/java/res/xml/rows_pcqwerty.xml
@@ -26,19 +26,8 @@
     <Row
         latin:keyWidth="7.692%p"
     >
-        <switch>
-            <case
-                latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted"
-            >
-                <include
-                    latin:keyboardLayout="@xml/rowkeys_pcqwerty1" />
-            </case>
-            <!-- keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted" -->
-            <default>
-                <include
-                     latin:keyboardLayout="@xml/rowkeys_pcqwerty1_shift" />
-            </default>
-        </switch>
+        <include
+            latin:keyboardLayout="@xml/rowkeys_pcqwerty1" />
     </Row>
     <Row
         latin:keyWidth="7.692%p"
diff --git a/java/src/com/android/inputmethod/event/Combiner.java b/java/src/com/android/inputmethod/event/Combiner.java
index ab6b70c..c3869a2 100644
--- a/java/src/com/android/inputmethod/event/Combiner.java
+++ b/java/src/com/android/inputmethod/event/Combiner.java
@@ -16,14 +16,22 @@
 
 package com.android.inputmethod.event;
 
+import java.util.ArrayList;
+
 /**
- * A generic interface for combiners.
+ * A generic interface for combiners. Combiners are objects that transform chains of input events
+ * into committable strings and manage feedback to show to the user on the combining state.
  */
 public interface Combiner {
     /**
-     * Combine an event with the existing state and return the new event.
+     * Process an event, possibly combining it with the existing state and return the new event.
+     *
+     * If this event does not result in any new event getting passed down the chain, this method
+     * returns null. It may also modify the previous event list if appropriate.
+     *
+     * @param previousEvents the previous events in this composition.
      * @param event the event to combine with the existing state.
      * @return the resulting event.
      */
-    Event combine(Event event);
+    Event processEvent(ArrayList<Event> previousEvents, Event event);
 }
diff --git a/java/src/com/android/inputmethod/event/CombinerChain.java b/java/src/com/android/inputmethod/event/CombinerChain.java
new file mode 100644
index 0000000..0e01c81
--- /dev/null
+++ b/java/src/com/android/inputmethod/event/CombinerChain.java
@@ -0,0 +1,69 @@
+/*
+ * 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.event;
+
+import com.android.inputmethod.latin.utils.CollectionUtils;
+
+import java.util.ArrayList;
+
+/**
+ * This class implements the logic chain between receiving events and generating code points.
+ *
+ * Event sources are multiple. It may be a hardware keyboard, a D-PAD, a software keyboard,
+ * or any exotic input source.
+ * This class will orchestrate the composing chain that starts with an event as its input. Each
+ * composer will be given turns one after the other.
+ * The output is composed of two sequences of code points: the first, representing the already
+ * finished combining part, will be shown normally as the composing string, while the second is
+ * feedback on the composing state and will typically be shown with different styling such as
+ * a colored background.
+ */
+public class CombinerChain {
+    // TODO: Create an object type to represent input material + visual feedback + decoding state
+
+    private final ArrayList<Combiner> mCombiners;
+
+    /**
+     * Create an combiner chain.
+     *
+     * The combiner chain takes events as inputs and outputs code points and combining state.
+     * For example, if the input language is Japanese, the combining chain will typically perform
+     * kana conversion.
+     *
+     * @param combinerList A list of combiners to be applied in order.
+     */
+    public CombinerChain(final Combiner... combinerList) {
+        mCombiners = CollectionUtils.newArrayList();
+        // The dead key combiner is always active, and always first
+        mCombiners.add(new DeadKeyCombiner());
+    }
+
+    // Pass a new event through the whole chain.
+    public void processEvent(final ArrayList<Event> previousEvents, final Event newEvent) {
+        final ArrayList<Event> modifiablePreviousEvents = new ArrayList<Event>(previousEvents);
+        Event event = newEvent;
+        for (final Combiner combiner : mCombiners) {
+            // A combiner can never return more than one event; it can return several
+            // code points, but they should be encapsulated within one event.
+            event = combiner.processEvent(modifiablePreviousEvents, event);
+            if (null == event) {
+                // Combiners return null if they eat the event.
+                return;
+            }
+        }
+    }
+}
diff --git a/java/src/com/android/inputmethod/event/DeadKeyCombiner.java b/java/src/com/android/inputmethod/event/DeadKeyCombiner.java
index ae86397..f77ce63 100644
--- a/java/src/com/android/inputmethod/event/DeadKeyCombiner.java
+++ b/java/src/com/android/inputmethod/event/DeadKeyCombiner.java
@@ -21,14 +21,17 @@
 
 import com.android.inputmethod.latin.Constants;
 
+import java.util.ArrayList;
+
 /**
  * A combiner that handles dead keys.
  */
 public class DeadKeyCombiner implements Combiner {
+    // TODO: make this a list of events instead
     final StringBuilder mDeadSequence = new StringBuilder();
 
     @Override
-    public Event combine(final Event event) {
+    public Event processEvent(final ArrayList<Event> previousEvents, final Event event) {
         if (null == event) return null; // Just in case some combiner is broken
         if (TextUtils.isEmpty(mDeadSequence)) {
             if (event.isDead()) {
diff --git a/java/src/com/android/inputmethod/event/Event.java b/java/src/com/android/inputmethod/event/Event.java
index 41bf36b..db40234 100644
--- a/java/src/com/android/inputmethod/event/Event.java
+++ b/java/src/com/android/inputmethod/event/Event.java
@@ -17,6 +17,7 @@
 package com.android.inputmethod.event;
 
 import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
 
 /**
  * Class representing a generic input event as handled by Latin IME.
@@ -49,6 +50,10 @@
     final public static int EVENT_MODE_KEY = 3;
     // An event corresponding to a gesture.
     final public static int EVENT_GESTURE = 4;
+    // An event corresponding to the manual pick of a suggestion.
+    final public static int EVENT_SUGGESTION_PICKED = 5;
+    // An event corresponding to a string generated by some software process.
+    final public static int EVENT_SOFTWARE_GENERATED_STRING = 6;
 
     // 0 is a valid code point, so we use -1 here.
     final public static int NOT_A_CODE_POINT = -1;
@@ -68,6 +73,9 @@
     // it's not relevant.
     final public int mCodePoint;
 
+    // If applicable, this contains the string that should be input.
+    final public CharSequence mText;
+
     // The key code associated with the event, if relevant. This is relevant whenever this event
     // has been triggered by a key press, but not for a gesture for example. This has conceptually
     // no link to the code point, although keys that enter a straight code point may often set
@@ -85,39 +93,60 @@
     // Some flags that can't go into the key code. It's a bit field of FLAG_*
     final private int mFlags;
 
+    // If this is of type EVENT_SUGGESTION_PICKED, this must not be null (and must be null in
+    // other cases).
+    final public SuggestedWordInfo mSuggestedWordInfo;
+
     // The next event, if any. Null if there is no next event yet.
     final public Event mNextEvent;
 
     // This method is private - to create a new event, use one of the create* utility methods.
-    private Event(final int type, final int codePoint, final int keyCode, final int x, final int y,
-            final int flags, final Event next) {
+    private Event(final int type, final CharSequence text, final int codePoint, final int keyCode,
+            final int x, final int y, final SuggestedWordInfo suggestedWordInfo, final int flags,
+            final Event next) {
         mType = type;
+        mText = text;
         mCodePoint = codePoint;
         mKeyCode = keyCode;
         mX = x;
         mY = y;
+        mSuggestedWordInfo = suggestedWordInfo;
         mFlags = flags;
         mNextEvent = next;
+        // Sanity checks
+        // mSuggestedWordInfo is non-null if and only if the type is SUGGESTION_PICKED
+        if (EVENT_SUGGESTION_PICKED == mType) {
+            if (null == mSuggestedWordInfo) {
+                throw new RuntimeException("Wrong event: SUGGESTION_PICKED event must have a "
+                        + "non-null SuggestedWordInfo");
+            }
+        } else {
+            if (null != mSuggestedWordInfo) {
+                throw new RuntimeException("Wrong event: only SUGGESTION_PICKED events may have " +
+                        "a non-null SuggestedWordInfo");
+            }
+        }
     }
 
     public static Event createSoftwareKeypressEvent(final int codePoint, final int keyCode,
             final int x, final int y) {
-        return new Event(EVENT_INPUT_KEYPRESS, codePoint, keyCode, x, y, FLAG_NONE, null);
+        return new Event(EVENT_INPUT_KEYPRESS, null /* text */, codePoint, keyCode, x, y,
+                null /* suggestedWordInfo */, FLAG_NONE, null);
     }
 
     public static Event createHardwareKeypressEvent(final int codePoint, final int keyCode,
             final Event next) {
-        return new Event(EVENT_INPUT_KEYPRESS, codePoint, keyCode,
+        return new Event(EVENT_INPUT_KEYPRESS, null /* text */, codePoint, keyCode,
                 Constants.EXTERNAL_KEYBOARD_COORDINATE, Constants.EXTERNAL_KEYBOARD_COORDINATE,
-                FLAG_NONE, next);
+                null /* suggestedWordInfo */, FLAG_NONE, next);
     }
 
     // This creates an input event for a dead character. @see {@link #FLAG_DEAD}
     public static Event createDeadEvent(final int codePoint, final int keyCode, final Event next) {
         // TODO: add an argument or something if we ever create a software layout with dead keys.
-        return new Event(EVENT_INPUT_KEYPRESS, codePoint, keyCode,
+        return new Event(EVENT_INPUT_KEYPRESS, null /* text */, codePoint, keyCode,
                 Constants.EXTERNAL_KEYBOARD_COORDINATE, Constants.EXTERNAL_KEYBOARD_COORDINATE,
-                FLAG_DEAD, next);
+                null /* suggestedWordInfo */, FLAG_DEAD, next);
     }
 
     /**
@@ -129,8 +158,9 @@
      */
     public static Event createEventForCodePointFromUnknownSource(final int codePoint) {
         // TODO: should we have a different type of event for this? After all, it's not a key press.
-        return new Event(EVENT_INPUT_KEYPRESS, codePoint, NOT_A_KEY_CODE,
-                Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, FLAG_NONE, null /* next */);
+        return new Event(EVENT_INPUT_KEYPRESS, null /* text */, codePoint, NOT_A_KEY_CODE,
+                Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE,
+                null /* suggestedWordInfo */, FLAG_NONE, null /* next */);
     }
 
     /**
@@ -144,13 +174,39 @@
     public static Event createEventForCodePointFromAlreadyTypedText(final int codePoint,
             final int x, final int y) {
         // TODO: should we have a different type of event for this? After all, it's not a key press.
-        return new Event(EVENT_INPUT_KEYPRESS, codePoint, NOT_A_KEY_CODE, x, y, FLAG_NONE,
-                null /* next */);
+        return new Event(EVENT_INPUT_KEYPRESS, null /* text */, codePoint, NOT_A_KEY_CODE, x, y,
+                null /* suggestedWordInfo */, FLAG_NONE, null /* next */);
+    }
+
+    /**
+     * Creates an input event representing the manual pick of a suggestion.
+     * @return an event for this suggestion pick.
+     */
+    public static Event createSuggestionPickedEvent(final SuggestedWordInfo suggestedWordInfo) {
+        return new Event(EVENT_SUGGESTION_PICKED, suggestedWordInfo.mWord,
+                NOT_A_CODE_POINT, NOT_A_KEY_CODE,
+                Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE,
+                suggestedWordInfo, FLAG_NONE, null);
+    }
+
+    /**
+     * Creates an input event with a CharSequence. This is used by some software processes whose
+     * output is a string, possibly with styling. Examples include press on a multi-character key,
+     * or combination that outputs a string.
+     * @param text the CharSequence associated with this event.
+     * @param keyCode the key code, or NOT_A_KEYCODE if not applicable.
+     * @return an event for this text.
+     */
+    public static Event createSoftwareTextEvent(final CharSequence text, final int keyCode) {
+        return new Event(EVENT_SOFTWARE_GENERATED_STRING, text, NOT_A_CODE_POINT, keyCode,
+                Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE,
+                null /* suggestedWordInfo */, FLAG_NONE, null /* next */);
     }
 
     public static Event createNotHandledEvent() {
-        return new Event(EVENT_NOT_HANDLED, NOT_A_CODE_POINT, NOT_A_KEY_CODE,
-                Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, FLAG_NONE, null);
+        return new Event(EVENT_NOT_HANDLED, null /* text */, NOT_A_CODE_POINT, NOT_A_KEY_CODE,
+                Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE,
+                null /* suggestedWordInfo */, FLAG_NONE, null);
     }
 
     // Returns whether this event is for a dead character. @see {@link #FLAG_DEAD}
@@ -164,11 +220,6 @@
         return EVENT_INPUT_KEYPRESS == mType && Constants.SUGGESTION_STRIP_COORDINATE == mX;
     }
 
-    // TODO: remove this method - we should not have to test this
-    public boolean isCommittable() {
-        return EVENT_INPUT_KEYPRESS == mType || EVENT_MODE_KEY == mType || EVENT_TOGGLE == mType;
-    }
-
     public boolean isHandled() {
         return EVENT_NOT_HANDLED != mType;
     }
diff --git a/java/src/com/android/inputmethod/event/EventInterpreter.java b/java/src/com/android/inputmethod/event/EventInterpreter.java
deleted file mode 100644
index bcf10fc..0000000
--- a/java/src/com/android/inputmethod/event/EventInterpreter.java
+++ /dev/null
@@ -1,58 +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.
- */
-
-package com.android.inputmethod.event;
-
-import com.android.inputmethod.latin.utils.CollectionUtils;
-
-import java.util.ArrayList;
-
-/**
- * This class implements the logic between receiving events and generating code points.
- *
- * Event sources are multiple. It may be a hardware keyboard, a D-PAD, a software keyboard,
- * or any exotic input source.
- * This class will orchestrate the decoding chain that starts with an event and ends up with
- * a stream of code points + decoding state.
- */
-public class EventInterpreter {
-    // TODO: Implement an object pool for events, as we'll create a lot of them
-    // TODO: Create a combiner
-    // TODO: Create an object type to represent input material + visual feedback + decoding state
-
-    private final EventDecoderSpec mDecoderSpec;
-    private final ArrayList<Combiner> mCombiners;
-
-    /**
-     * Create an event interpreter according to a specification.
-     *
-     * The specification contains information about what to do with events. Typically, it will
-     * contain information about the type of keyboards - for example, if hardware keyboard(s) is/are
-     * attached, their type will be included here so that the decoder knows what to do with each
-     * keypress (a 10-key keyboard is not handled like a qwerty-ish keyboard).
-     * It also contains information for combining characters. For example, if the input language
-     * is Japanese, the specification will typically request kana conversion.
-     * Also note that the specification can be null. This means that we need to create a default
-     * interpreter that does no specific combining, and assumes the most common cases.
-     *
-     * @param specification the specification for event interpretation. null for default.
-     */
-    public EventInterpreter(final EventDecoderSpec specification) {
-        mDecoderSpec = null != specification ? specification : new EventDecoderSpec();
-        mCombiners = CollectionUtils.newArrayList();
-        mCombiners.add(new DeadKeyCombiner());
-    }
-}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 2711d24..2dfde94 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -60,7 +60,7 @@
     public static final int THEME_INDEX_ICS = 0;
     public static final int THEME_INDEX_GB = 1;
     public static final int THEME_INDEX_KLP = 2;
-    public static final int THEME_INDEX_DEFAULT = THEME_INDEX_KLP;
+    public static final int DEFAULT_THEME_INDEX = THEME_INDEX_KLP;
     public static final KeyboardTheme[] KEYBOARD_THEMES = {
         new KeyboardTheme(THEME_INDEX_ICS, R.style.KeyboardTheme_ICS),
         new KeyboardTheme(THEME_INDEX_GB, R.style.KeyboardTheme_GB),
@@ -88,7 +88,7 @@
      * what user actually typed. */
     private boolean mIsAutoCorrectionActive;
 
-    private KeyboardTheme mKeyboardTheme = KEYBOARD_THEMES[THEME_INDEX_DEFAULT];
+    private KeyboardTheme mKeyboardTheme = KEYBOARD_THEMES[DEFAULT_THEME_INDEX];
     private Context mThemeContext;
 
     private static final KeyboardSwitcher sInstance = new KeyboardSwitcher();
@@ -163,7 +163,7 @@
         mCurrentSettingsValues = settingsValues;
         try {
             mState.onLoadKeyboard();
-            mKeyboardTextsSet.setLocale(mSubtypeSwitcher.getCurrentSubtypeLocale());
+            mKeyboardTextsSet.setLocale(mSubtypeSwitcher.getCurrentSubtypeLocale(), mThemeContext);
         } catch (KeyboardLayoutSetException e) {
             Log.w(TAG, "loading keyboard failed: " + e.mKeyboardId, e.getCause());
             LatinImeLogger.logOnException(e.mKeyboardId.toString(), e.getCause());
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
index 81a8e71..dfe0df0 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
@@ -34,7 +34,6 @@
 import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.utils.ResourceUtils;
-import com.android.inputmethod.latin.utils.RunInLocale;
 import com.android.inputmethod.latin.utils.StringUtils;
 import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
 import com.android.inputmethod.latin.utils.XmlParseUtils;
@@ -45,7 +44,6 @@
 
 import java.io.IOException;
 import java.util.Arrays;
-import java.util.Locale;
 
 /**
  * Keyboard Building helper.
@@ -278,18 +276,7 @@
 
             params.mThemeId = keyboardAttr.getInt(R.styleable.Keyboard_themeId, 0);
             params.mIconsSet.loadIcons(keyboardAttr);
-            final Locale locale = params.mId.mLocale;
-            params.mTextsSet.setLocale(locale);
-            final RunInLocale<Void> job = new RunInLocale<Void>() {
-                @Override
-                protected Void job(final Resources res) {
-                    params.mTextsSet.loadStringResources(mContext);
-                    return null;
-                }
-            };
-            // Null means the current system locale.
-            job.runInLocale(mResources,
-                    SubtypeLocaleUtils.isNoLanguage(params.mId.mSubtype) ? null : locale);
+            params.mTextsSet.setLocale(params.mId.mLocale, mContext);
 
             final int resourceId = keyboardAttr.getResourceId(
                     R.styleable.Keyboard_touchPositionCorrectionData, 0);
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
index 976038c..044cd11 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
@@ -23,6 +23,8 @@
 import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.RunInLocale;
+import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
 
 import java.util.HashMap;
 import java.util.Locale;
@@ -38,23 +40,29 @@
     // Resource name to text map.
     private HashMap<String, String> mResourceNameToTextsMap = CollectionUtils.newHashMap();
 
-    public void setLocale(final Locale locale) {
+    public void setLocale(final Locale locale, final Context context) {
         final String language = locale.getLanguage();
         mTextsTable = KeyboardTextsTable.getTextsTable(language);
-    }
-
-    public void loadStringResources(final Context context) {
+        final Resources res = context.getResources();
         final int referenceId = context.getApplicationInfo().labelRes;
-        loadStringResourcesInternal(context, RESOURCE_NAMES, referenceId);
+        final String resourcePackageName = res.getResourcePackageName(referenceId);
+        final RunInLocale<Void> job = new RunInLocale<Void>() {
+            @Override
+            protected Void job(final Resources resource) {
+                loadStringResourcesInternal(res, RESOURCE_NAMES, resourcePackageName);
+                return null;
+            }
+        };
+        // Null means the current system locale.
+        job.runInLocale(res,
+                SubtypeLocaleUtils.NO_LANGUAGE.equals(locale.toString()) ? null : locale);
     }
 
     @UsedForTesting
-    void loadStringResourcesInternal(final Context context, final String[] resourceNames,
-            final int referenceId) {
-        final Resources res = context.getResources();
-        final String packageName = res.getResourcePackageName(referenceId);
+    void loadStringResourcesInternal(final Resources res, final String[] resourceNames,
+            final String resourcePackageName) {
         for (final String resName : resourceNames) {
-            final int resId = res.getIdentifier(resName, "string", packageName);
+            final int resId = res.getIdentifier(resName, "string", resourcePackageName);
             mResourceNameToTextsMap.put(resName, res.getString(resId));
         }
     }
@@ -77,6 +85,7 @@
         return size;
     }
 
+    // TODO: Resolve text reference when creating {@link KeyboardTextsTable} class.
     public String resolveTextReference(final String rawText) {
         if (TextUtils.isEmpty(rawText)) {
             return null;
@@ -127,7 +136,7 @@
 
     // These texts' name should be aligned with the @string/<name> in
     // values*/strings-action-keys.xml.
-    private static final String[] RESOURCE_NAMES = {
+    static final String[] RESOURCE_NAMES = {
         // Labels for action.
         "label_go_key",
         "label_send_key",
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
index 7a0161e..1d9ee90 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
@@ -79,17 +79,17 @@
 
     private static final String[] NAMES = {
     //  /* index:histogram */ "name",
-        /*   0:30 */ "more_keys_for_a",
-        /*   1:30 */ "more_keys_for_o",
-        /*   2:28 */ "more_keys_for_u",
-        /*   3:27 */ "more_keys_for_e",
-        /*   4:26 */ "more_keys_for_i",
-        /*   5:23 */ "double_quotes",
-        /*   6:22 */ "single_quotes",
-        /*   7:21 */ "more_keys_for_c",
-        /*   8:20 */ "more_keys_for_s",
-        /*   9:20 */ "more_keys_for_n",
-        /*  10:20 */ "label_to_alpha_key",
+        /*   0:32 */ "more_keys_for_a",
+        /*   1:32 */ "more_keys_for_o",
+        /*   2:30 */ "more_keys_for_u",
+        /*   3:29 */ "more_keys_for_e",
+        /*   4:28 */ "more_keys_for_i",
+        /*   5:23 */ "more_keys_for_c",
+        /*   6:23 */ "double_quotes",
+        /*   7:22 */ "more_keys_for_n",
+        /*   8:22 */ "single_quotes",
+        /*   9:21 */ "label_to_alpha_key",
+        /*  10:20 */ "more_keys_for_s",
         /*  11:14 */ "more_keys_for_y",
         /*  12:13 */ "more_keys_for_d",
         /*  13:12 */ "more_keys_for_z",
@@ -111,30 +111,30 @@
         /*  29: 5 */ "keylabel_for_east_slavic_row2_11",
         /*  30: 5 */ "keylabel_for_east_slavic_row3_5",
         /*  31: 5 */ "more_keys_for_cyrillic_soft_sign",
-        /*  32: 5 */ "more_keys_for_punctuation",
-        /*  33: 4 */ "more_keys_for_nordic_row2_11",
-        /*  34: 4 */ "keylabel_for_symbols_1",
-        /*  35: 4 */ "keylabel_for_symbols_2",
-        /*  36: 4 */ "keylabel_for_symbols_3",
-        /*  37: 4 */ "keylabel_for_symbols_4",
-        /*  38: 4 */ "keylabel_for_symbols_5",
-        /*  39: 4 */ "keylabel_for_symbols_6",
-        /*  40: 4 */ "keylabel_for_symbols_7",
-        /*  41: 4 */ "keylabel_for_symbols_8",
-        /*  42: 4 */ "keylabel_for_symbols_9",
-        /*  43: 4 */ "keylabel_for_symbols_0",
-        /*  44: 4 */ "label_to_symbol_key",
-        /*  45: 4 */ "label_to_symbol_with_microphone_key",
-        /*  46: 4 */ "additional_more_keys_for_symbols_1",
-        /*  47: 4 */ "additional_more_keys_for_symbols_2",
-        /*  48: 4 */ "additional_more_keys_for_symbols_3",
-        /*  49: 4 */ "additional_more_keys_for_symbols_4",
-        /*  50: 4 */ "additional_more_keys_for_symbols_5",
-        /*  51: 4 */ "additional_more_keys_for_symbols_6",
-        /*  52: 4 */ "additional_more_keys_for_symbols_7",
-        /*  53: 4 */ "additional_more_keys_for_symbols_8",
-        /*  54: 4 */ "additional_more_keys_for_symbols_9",
-        /*  55: 4 */ "additional_more_keys_for_symbols_0",
+        /*  32: 4 */ "more_keys_for_nordic_row2_11",
+        /*  33: 4 */ "keylabel_for_symbols_1",
+        /*  34: 4 */ "keylabel_for_symbols_2",
+        /*  35: 4 */ "keylabel_for_symbols_3",
+        /*  36: 4 */ "keylabel_for_symbols_4",
+        /*  37: 4 */ "keylabel_for_symbols_5",
+        /*  38: 4 */ "keylabel_for_symbols_6",
+        /*  39: 4 */ "keylabel_for_symbols_7",
+        /*  40: 4 */ "keylabel_for_symbols_8",
+        /*  41: 4 */ "keylabel_for_symbols_9",
+        /*  42: 4 */ "keylabel_for_symbols_0",
+        /*  43: 4 */ "label_to_symbol_key",
+        /*  44: 4 */ "label_to_symbol_with_microphone_key",
+        /*  45: 4 */ "additional_more_keys_for_symbols_1",
+        /*  46: 4 */ "additional_more_keys_for_symbols_2",
+        /*  47: 4 */ "additional_more_keys_for_symbols_3",
+        /*  48: 4 */ "additional_more_keys_for_symbols_4",
+        /*  49: 4 */ "additional_more_keys_for_symbols_5",
+        /*  50: 4 */ "additional_more_keys_for_symbols_6",
+        /*  51: 4 */ "additional_more_keys_for_symbols_7",
+        /*  52: 4 */ "additional_more_keys_for_symbols_8",
+        /*  53: 4 */ "additional_more_keys_for_symbols_9",
+        /*  54: 4 */ "additional_more_keys_for_symbols_0",
+        /*  55: 3 */ "more_keys_for_punctuation",
         /*  56: 3 */ "more_keys_for_star",
         /*  57: 3 */ "keyspec_left_parenthesis",
         /*  58: 3 */ "keyspec_right_parenthesis",
@@ -177,78 +177,77 @@
         /*  95: 2 */ "more_keys_for_right_parenthesis",
         /*  96: 2 */ "more_keys_for_arabic_diacritics",
         /*  97: 2 */ "keylabel_for_comma",
-        /*  98: 2 */ "more_keys_for_comma",
-        /*  99: 2 */ "keyhintlabel_for_tablet_comma",
-        /* 100: 2 */ "more_keys_for_tablet_comma",
-        /* 101: 2 */ "keyhintlabel_for_period",
-        /* 102: 2 */ "more_keys_for_period",
-        /* 103: 2 */ "keyhintlabel_for_tablet_period",
-        /* 104: 2 */ "keylabel_for_symbols_question",
-        /* 105: 2 */ "keylabel_for_symbols_semicolon",
-        /* 106: 2 */ "keylabel_for_symbols_percent",
-        /* 107: 2 */ "more_keys_for_symbols_semicolon",
-        /* 108: 2 */ "more_keys_for_symbols_percent",
-        /* 109: 1 */ "more_keys_for_v",
-        /* 110: 1 */ "more_keys_for_j",
-        /* 111: 1 */ "more_keys_for_cyrillic_ka",
-        /* 112: 1 */ "more_keys_for_cyrillic_a",
-        /* 113: 1 */ "more_keys_for_east_slavic_row2_11",
-        /* 114: 1 */ "more_keys_for_currency_dollar",
-        /* 115: 1 */ "more_keys_for_tablet_punctuation",
-        /* 116: 1 */ "more_keys_for_plus",
-        /* 117: 1 */ "more_keys_for_less_than",
-        /* 118: 1 */ "more_keys_for_greater_than",
-        /* 119: 1 */ "keylabel_for_period",
-        /* 120: 1 */ "keylabel_for_tablet_period",
-        /* 121: 1 */ "more_keys_for_exclamation",
-        /* 122: 1 */ "more_keys_for_q",
-        /* 123: 1 */ "more_keys_for_x",
-        /* 124: 1 */ "keylabel_for_q",
-        /* 125: 1 */ "keylabel_for_w",
-        /* 126: 1 */ "keylabel_for_y",
-        /* 127: 1 */ "keylabel_for_x",
-        /* 128: 0 */ "more_keys_for_currency",
-        /* 129: 0 */ "more_keys_for_symbols_1",
-        /* 130: 0 */ "more_keys_for_symbols_2",
-        /* 131: 0 */ "more_keys_for_symbols_3",
-        /* 132: 0 */ "more_keys_for_symbols_4",
-        /* 133: 0 */ "more_keys_for_symbols_5",
-        /* 134: 0 */ "more_keys_for_symbols_6",
-        /* 135: 0 */ "more_keys_for_symbols_7",
-        /* 136: 0 */ "more_keys_for_symbols_8",
-        /* 137: 0 */ "more_keys_for_symbols_9",
-        /* 138: 0 */ "more_keys_for_symbols_0",
-        /* 139: 0 */ "more_keys_for_am_pm",
-        /* 140: 0 */ "settings_as_more_key",
-        /* 141: 0 */ "shortcut_as_more_key",
-        /* 142: 0 */ "action_next_as_more_key",
-        /* 143: 0 */ "action_previous_as_more_key",
-        /* 144: 0 */ "label_to_more_symbol_key",
-        /* 145: 0 */ "label_to_more_symbol_for_tablet_key",
-        /* 146: 0 */ "label_to_phone_numeric_key",
-        /* 147: 0 */ "label_to_phone_symbols_key",
-        /* 148: 0 */ "label_time_am",
-        /* 149: 0 */ "label_time_pm",
-        /* 150: 0 */ "keylabel_for_popular_domain",
-        /* 151: 0 */ "more_keys_for_popular_domain",
-        /* 152: 0 */ "keyspecs_for_left_parenthesis_more_keys",
-        /* 153: 0 */ "keyspecs_for_right_parenthesis_more_keys",
-        /* 154: 0 */ "single_laqm_raqm",
-        /* 155: 0 */ "single_raqm_laqm",
-        /* 156: 0 */ "double_laqm_raqm",
-        /* 157: 0 */ "double_raqm_laqm",
-        /* 158: 0 */ "single_lqm_rqm",
-        /* 159: 0 */ "single_9qm_lqm",
-        /* 160: 0 */ "single_9qm_rqm",
-        /* 161: 0 */ "single_rqm_9qm",
-        /* 162: 0 */ "double_lqm_rqm",
-        /* 163: 0 */ "double_9qm_lqm",
-        /* 164: 0 */ "double_9qm_rqm",
-        /* 165: 0 */ "double_rqm_9qm",
-        /* 166: 0 */ "more_keys_for_single_quote",
-        /* 167: 0 */ "more_keys_for_double_quote",
-        /* 168: 0 */ "more_keys_for_tablet_double_quote",
-        /* 169: 0 */ "emoji_key_as_more_key",
+        /*  98: 2 */ "keyhintlabel_for_tablet_comma",
+        /*  99: 2 */ "more_keys_for_tablet_comma",
+        /* 100: 2 */ "keyhintlabel_for_period",
+        /* 101: 2 */ "more_keys_for_period",
+        /* 102: 2 */ "keyhintlabel_for_tablet_period",
+        /* 103: 2 */ "keylabel_for_symbols_question",
+        /* 104: 2 */ "keylabel_for_symbols_semicolon",
+        /* 105: 2 */ "keylabel_for_symbols_percent",
+        /* 106: 2 */ "more_keys_for_symbols_semicolon",
+        /* 107: 2 */ "more_keys_for_symbols_percent",
+        /* 108: 1 */ "more_keys_for_v",
+        /* 109: 1 */ "more_keys_for_j",
+        /* 110: 1 */ "more_keys_for_cyrillic_ka",
+        /* 111: 1 */ "more_keys_for_cyrillic_a",
+        /* 112: 1 */ "more_keys_for_east_slavic_row2_11",
+        /* 113: 1 */ "more_keys_for_currency_dollar",
+        /* 114: 1 */ "more_keys_for_tablet_punctuation",
+        /* 115: 1 */ "more_keys_for_plus",
+        /* 116: 1 */ "more_keys_for_less_than",
+        /* 117: 1 */ "more_keys_for_greater_than",
+        /* 118: 1 */ "keylabel_for_period",
+        /* 119: 1 */ "keylabel_for_tablet_period",
+        /* 120: 1 */ "more_keys_for_exclamation",
+        /* 121: 1 */ "more_keys_for_q",
+        /* 122: 1 */ "more_keys_for_x",
+        /* 123: 1 */ "keylabel_for_q",
+        /* 124: 1 */ "keylabel_for_w",
+        /* 125: 1 */ "keylabel_for_y",
+        /* 126: 1 */ "keylabel_for_x",
+        /* 127: 0 */ "more_keys_for_currency",
+        /* 128: 0 */ "more_keys_for_symbols_1",
+        /* 129: 0 */ "more_keys_for_symbols_2",
+        /* 130: 0 */ "more_keys_for_symbols_3",
+        /* 131: 0 */ "more_keys_for_symbols_4",
+        /* 132: 0 */ "more_keys_for_symbols_5",
+        /* 133: 0 */ "more_keys_for_symbols_6",
+        /* 134: 0 */ "more_keys_for_symbols_7",
+        /* 135: 0 */ "more_keys_for_symbols_8",
+        /* 136: 0 */ "more_keys_for_symbols_9",
+        /* 137: 0 */ "more_keys_for_symbols_0",
+        /* 138: 0 */ "more_keys_for_am_pm",
+        /* 139: 0 */ "settings_as_more_key",
+        /* 140: 0 */ "shortcut_as_more_key",
+        /* 141: 0 */ "action_next_as_more_key",
+        /* 142: 0 */ "action_previous_as_more_key",
+        /* 143: 0 */ "label_to_more_symbol_key",
+        /* 144: 0 */ "label_to_more_symbol_for_tablet_key",
+        /* 145: 0 */ "label_to_phone_numeric_key",
+        /* 146: 0 */ "label_to_phone_symbols_key",
+        /* 147: 0 */ "label_time_am",
+        /* 148: 0 */ "label_time_pm",
+        /* 149: 0 */ "keylabel_for_popular_domain",
+        /* 150: 0 */ "more_keys_for_popular_domain",
+        /* 151: 0 */ "keyspecs_for_left_parenthesis_more_keys",
+        /* 152: 0 */ "keyspecs_for_right_parenthesis_more_keys",
+        /* 153: 0 */ "single_laqm_raqm",
+        /* 154: 0 */ "single_raqm_laqm",
+        /* 155: 0 */ "double_laqm_raqm",
+        /* 156: 0 */ "double_raqm_laqm",
+        /* 157: 0 */ "single_lqm_rqm",
+        /* 158: 0 */ "single_9qm_lqm",
+        /* 159: 0 */ "single_9qm_rqm",
+        /* 160: 0 */ "single_rqm_9qm",
+        /* 161: 0 */ "double_lqm_rqm",
+        /* 162: 0 */ "double_9qm_lqm",
+        /* 163: 0 */ "double_9qm_rqm",
+        /* 164: 0 */ "double_rqm_9qm",
+        /* 165: 0 */ "more_keys_for_single_quote",
+        /* 166: 0 */ "more_keys_for_double_quote",
+        /* 167: 0 */ "more_keys_for_tablet_double_quote",
+        /* 168: 0 */ "emoji_key_as_more_key",
     };
 
     private static final String EMPTY = "";
@@ -256,26 +255,22 @@
     /* Default texts */
     private static final String[] LANGUAGE_DEFAULT = {
         /* more_keys_for_a ~ */
-        EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-        /* ~ more_keys_for_i */
+        EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
+        /* ~ more_keys_for_c */
         /* double_quotes */ "!text/double_lqm_rqm",
+        /* more_keys_for_n */ EMPTY,
         /* single_quotes */ "!text/single_lqm_rqm",
-        /* more_keys_for_c ~ */
-        EMPTY, EMPTY, EMPTY,
-        /* ~ more_keys_for_n */
         // Label for "switch to alphabetic" key.
         /* label_to_alpha_key */ "ABC",
-        /* more_keys_for_y ~ */
-        EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
+        /* more_keys_for_s ~ */
+        EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
         /* ~ more_keys_for_g */
         /* single_angle_quotes */ "!text/single_laqm_raqm",
         /* double_angle_quotes */ "!text/double_laqm_raqm",
         /* keylabel_for_currency */ "$",
         /* more_keys_for_r ~ */
-        EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-        /* ~ more_keys_for_cyrillic_soft_sign */
-        /* more_keys_for_punctuation */ "!fixedColumnOrder!8,;,/,!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis,#,!,\\,,?,&,\\%,+,\",-,:,',@",
-        /* more_keys_for_nordic_row2_11 */ EMPTY,
+        EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
+        /* ~ more_keys_for_nordic_row2_11 */
         /* keylabel_for_symbols_1 */ "1",
         /* keylabel_for_symbols_2 */ "2",
         /* keylabel_for_symbols_3 */ "3",
@@ -294,6 +289,7 @@
         /* additional_more_keys_for_symbols_1 ~ */
         EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
         /* ~ additional_more_keys_for_symbols_0 */
+        /* more_keys_for_punctuation */ "!autoColumnOrder!8,\\,,?,!,#,!text/keyspec_right_parenthesis,!text/keyspec_left_parenthesis,/,;,',@,:,-,\",+,\\%,&",
         // U+2020: "†" DAGGER
         // U+2021: "‡" DOUBLE DAGGER
         // U+2605: "★" BLACK STAR
@@ -341,8 +337,8 @@
         /* more_keys_for_arabic_diacritics */ EMPTY,
         // Comma key
         /* keylabel_for_comma */ ",",
-        /* more_keys_for_comma ~ */
-        EMPTY, EMPTY, EMPTY, EMPTY,
+        /* keyhintlabel_for_tablet_comma ~ */
+        EMPTY, EMPTY, EMPTY,
         /* ~ keyhintlabel_for_period */
         /* more_keys_for_period */ "!text/more_keys_for_punctuation",
         /* keyhintlabel_for_tablet_period */ EMPTY,
@@ -361,7 +357,7 @@
         // U+00A5: "¥" YEN SIGN
         // U+20B1: "₱" PESO SIGN
         /* more_keys_for_currency_dollar */ "\u00A2,\u00A3,\u20AC,\u00A5,\u20B1",
-        /* more_keys_for_tablet_punctuation */ "!fixedColumnOrder!7,;,/,!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis,#,',\\,,&,\\%,+,\",-,:,@",
+        /* more_keys_for_tablet_punctuation */ "!autoColumnOrder!7,\\,,',#,!text/keyspec_right_parenthesis,!text/keyspec_left_parenthesis,/,;,@,:,-,\",+,\\%,&",
         // U+00B1: "±" PLUS-MINUS SIGN
         /* more_keys_for_plus */ "\u00B1",
         /* more_keys_for_less_than */ "!fixedColumnOrder!3,!text/keyspec_left_single_angle_quote,!text/keyspec_less_than_equal,!text/keyspec_left_double_angle_quote",
@@ -507,13 +503,14 @@
         // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
         // U+0133: "ij" LATIN SMALL LIGATURE IJ
         /* more_keys_for_i */ "\u00ED,\u00EC,\u00EF,\u00EE,\u012F,\u012B,\u0133",
-        /* double_quotes ~ */
-        null, null, null, null,
-        /* ~ more_keys_for_s */
+        /* more_keys_for_c */ null,
+        /* double_quotes */ null,
         // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
         // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
         /* more_keys_for_n */ "\u00F1,\u0144",
-        /* label_to_alpha_key */ null,
+        /* single_quotes ~ */
+        null, null, null,
+        /* ~ more_keys_for_s */
         // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
         // U+0133: "ij" LATIN SMALL LIGATURE IJ
         /* more_keys_for_y */ "\u00FD,\u0133",
@@ -522,20 +519,18 @@
     /* Language ar: Arabic */
     private static final String[] LANGUAGE_ar = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null, null, null, null, null, null,
-        /* ~ more_keys_for_n */
+        null, null, null, null, null, null, null, null, null,
+        /* ~ single_quotes */
         // Label for "switch to alphabetic" key.
         // U+0623: "أ" ARABIC LETTER ALEF WITH HAMZA ABOVE
         // U+200C: ZERO WIDTH NON-JOINER
         // U+0628: "ب" ARABIC LETTER BEH
         // U+062C: "ج" ARABIC LETTER JEEM
         /* label_to_alpha_key */ "\u0623\u200C\u0628\u200C\u062C",
-        /* more_keys_for_y ~ */
+        /* more_keys_for_s ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null,
-        /* ~ more_keys_for_cyrillic_soft_sign */
-        /* more_keys_for_punctuation */ "!fixedColumnOrder!8,\",\',#,-,:,!,\u060C,\u061F,@,&,\\%,+,\u061B,/,(|),)|(",
-        /* more_keys_for_nordic_row2_11 */ null,
+        null, null, null, null, null, null, null, null,
+        /* ~ more_keys_for_nordic_row2_11 */
         // U+0661: "١" ARABIC-INDIC DIGIT ONE
         /* keylabel_for_symbols_1 */ "\u0661",
         // U+0662: "٢" ARABIC-INDIC DIGIT TWO
@@ -574,6 +569,7 @@
         // U+066B: "٫" ARABIC DECIMAL SEPARATOR
         // U+066C: "٬" ARABIC THOUSANDS SEPARATOR
         /* additional_more_keys_for_symbols_0 */ "0,\u066B,\u066C",
+        /* more_keys_for_punctuation */ null,
         // U+2605: "★" BLACK STAR
         // U+066D: "٭" ARABIC FIVE POINTED STAR
         /* more_keys_for_star */ "\u2605,\u066D",
@@ -635,7 +631,6 @@
         /* more_keys_for_arabic_diacritics */ "!fixedColumnOrder!7, \u0655|\u0655, \u0654|\u0654, \u0652|\u0652, \u064D|\u064D, \u064C|\u064C, \u064B|\u064B, \u0651|\u0651, \u0656|\u0656, \u0670|\u0670, \u0653|\u0653, \u0650|\u0650, \u064F|\u064F, \u064E|\u064E,\u0640\u0640\u0640|\u0640",
         // U+060C: "،" ARABIC COMMA
         /* keylabel_for_comma */ "\u060C",
-        /* more_keys_for_comma */ "\\,",
         /* keyhintlabel_for_tablet_comma */ "\u061F",
         /* more_keys_for_tablet_comma */ "!fixedColumnOrder!4,:,!,\u061F,\u061B,-,/,\",\'",
         // U+0651: "ّ" ARABIC SHADDA
@@ -680,19 +675,20 @@
         // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
         // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
         /* more_keys_for_i */ "\u0131,\u00EE,\u00EF,\u00EC,\u00ED,\u012F,\u012B",
-        /* double_quotes */ null,
-        /* single_quotes */ null,
         // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
         // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
         // U+010D: "č" LATIN SMALL LETTER C WITH CARON
         /* more_keys_for_c */ "\u00E7,\u0107,\u010D",
+        /* double_quotes ~ */
+        null, null, null, null,
+        /* ~ label_to_alpha_key */
         // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA
         // U+00DF: "ß" LATIN SMALL LETTER SHARP S
         // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
         // U+0161: "š" LATIN SMALL LETTER S WITH CARON
         /* more_keys_for_s */ "\u015F,\u00DF,\u015B,\u0161",
-        /* more_keys_for_n ~ */
-        null, null, null, null, null, null, null,
+        /* more_keys_for_y ~ */
+        null, null, null, null, null,
         /* ~ more_keys_for_l */
         // U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE
         /* more_keys_for_g */ "\u011F",
@@ -701,20 +697,18 @@
     /* Language be_BY: Belarusian (Belarus) */
     private static final String[] LANGUAGE_be_BY = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null,
-        /* ~ more_keys_for_i */
+        null, null, null, null, null, null,
+        /* ~ more_keys_for_c */
         /* double_quotes */ "!text/double_9qm_lqm",
+        /* more_keys_for_n */ null,
         /* single_quotes */ "!text/single_9qm_lqm",
-        /* more_keys_for_c ~ */
-        null, null, null,
-        /* ~ more_keys_for_n */
         // Label for "switch to alphabetic" key.
         // U+0410: "А" CYRILLIC CAPITAL LETTER A
         // U+0411: "Б" CYRILLIC CAPITAL LETTER BE
         // U+0412: "В" CYRILLIC CAPITAL LETTER VE
         /* label_to_alpha_key */ "\u0410\u0411\u0412",
-        /* more_keys_for_y ~ */
-        null, null, null, null, null, null, null, null, null, null, null,
+        /* more_keys_for_s ~ */
+        null, null, null, null, null, null, null, null, null, null, null, null,
         /* ~ more_keys_for_k */
         // U+0451: "ё" CYRILLIC SMALL LETTER IO
         /* more_keys_for_cyrillic_ie */ "\u0451",
@@ -736,13 +730,12 @@
     /* Language bg: Bulgarian */
     private static final String[] LANGUAGE_bg = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null,
-        /* ~ more_keys_for_i */
+        null, null, null, null, null, null,
+        /* ~ more_keys_for_c */
         // single_quotes of Bulgarian is default single_quotes_right_left.
         /* double_quotes */ "!text/double_9qm_lqm",
-        /* single_quotes ~ */
-        null, null, null, null,
-        /* ~ more_keys_for_n */
+        /* more_keys_for_n */ null,
+        /* single_quotes */ null,
         // Label for "switch to alphabetic" key.
         // U+0410: "А" CYRILLIC CAPITAL LETTER A
         // U+0411: "Б" CYRILLIC CAPITAL LETTER BE
@@ -794,41 +787,39 @@
         // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
         // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
         /* more_keys_for_i */ "\u00ED,\u00EF,\u00EC,\u00EE,\u012F,\u012B",
-        /* double_quotes */ null,
-        /* single_quotes */ null,
         // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
         // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
         // U+010D: "č" LATIN SMALL LETTER C WITH CARON
         /* more_keys_for_c */ "\u00E7,\u0107,\u010D",
-        /* more_keys_for_s */ null,
+        /* double_quotes */ null,
         // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
         // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
         /* more_keys_for_n */ "\u00F1,\u0144",
-        /* label_to_alpha_key ~ */
-        null, null, null, null, null,
+        /* single_quotes ~ */
+        null, null, null, null, null, null, null,
         /* ~ more_keys_for_t */
         // U+00B7: "·" MIDDLE DOT
         // U+0142: "ł" LATIN SMALL LETTER L WITH STROKE
         /* more_keys_for_l */ "l\u00B7l,\u0142",
         /* more_keys_for_g ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null,
-        /* ~ more_keys_for_cyrillic_soft_sign */
+        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_more_keys_for_symbols_0 */
         // U+00B7: "·" MIDDLE DOT
-        /* more_keys_for_punctuation */ "!fixedColumnOrder!9,;,/,(,),#,\u00B7,!,\\,,?,&,\\%,+,\",-,:,',@",
-        /* more_keys_for_nordic_row2_11 ~ */
+        /* more_keys_for_punctuation */ "!autoColumnOrder!9,\\,,?,!,\u00B7,#,),(,/,;,',@,:,-,\",+,\\%,&",
+        /* more_keys_for_star ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null,
         /* ~ more_keys_for_swiss_row2_11 */
         // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
         /* keylabel_for_spanish_row2_10 */ "\u00E7",
         /* more_keys_for_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, null,
         /* ~ more_keys_for_currency_dollar */
-        /* more_keys_for_tablet_punctuation */ "!fixedColumnOrder!8,;,/,(,),#,\u00B7,',\\,,&,\\%,+,\",-,:,@",
+        /* more_keys_for_tablet_punctuation */ "!autoColumnOrder!8,\\,,',\u00B7,#,),(,/,;,@,:,-,\",+,\\%,&",
     };
 
     /* Language cs: Czech */
@@ -874,21 +865,21 @@
         // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
         // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
         /* more_keys_for_i */ "\u00ED,\u00EE,\u00EF,\u00EC,\u012F,\u012B",
-        /* double_quotes */ "!text/double_9qm_lqm",
-        /* single_quotes */ "!text/single_9qm_lqm",
         // U+010D: "č" LATIN SMALL LETTER C WITH CARON
         // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
         // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
         /* more_keys_for_c */ "\u010D,\u00E7,\u0107",
-        // U+0161: "š" LATIN SMALL LETTER S WITH CARON
-        // U+00DF: "ß" LATIN SMALL LETTER SHARP S
-        // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
-        /* more_keys_for_s */ "\u0161,\u00DF,\u015B",
+        /* double_quotes */ "!text/double_9qm_lqm",
         // U+0148: "ň" LATIN SMALL LETTER N WITH CARON
         // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
         // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
         /* more_keys_for_n */ "\u0148,\u00F1,\u0144",
+        /* single_quotes */ "!text/single_9qm_lqm",
         /* label_to_alpha_key */ null,
+        // U+0161: "š" LATIN SMALL LETTER S WITH CARON
+        // U+00DF: "ß" LATIN SMALL LETTER SHARP S
+        // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
+        /* more_keys_for_s */ "\u0161,\u00DF,\u015B",
         // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
         // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
         /* more_keys_for_y */ "\u00FD,\u00FF",
@@ -937,17 +928,17 @@
         // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
         /* more_keys_for_i */ "\u00ED,\u00EF",
-        /* double_quotes */ "!text/double_9qm_lqm",
-        /* single_quotes */ "!text/single_9qm_lqm",
         /* more_keys_for_c */ null,
+        /* double_quotes */ "!text/double_9qm_lqm",
+        // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
+        // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
+        /* more_keys_for_n */ "\u00F1,\u0144",
+        /* single_quotes */ "!text/single_9qm_lqm",
+        /* label_to_alpha_key */ null,
         // U+00DF: "ß" LATIN SMALL LETTER SHARP S
         // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
         // U+0161: "š" LATIN SMALL LETTER S WITH CARON
         /* more_keys_for_s */ "\u00DF,\u015B,\u0161",
-        // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
-        // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
-        /* more_keys_for_n */ "\u00F1,\u0144",
-        /* label_to_alpha_key */ null,
         // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
         // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
         /* more_keys_for_y */ "\u00FD,\u00FF",
@@ -972,8 +963,8 @@
         // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
         /* more_keys_for_nordic_row2_10 */ "\u00E4",
         /* keylabel_for_east_slavic_row1_9 ~ */
-        null, null, null, null, null, null,
-        /* ~ more_keys_for_punctuation */
+        null, null, null, null, null,
+        /* ~ more_keys_for_cyrillic_soft_sign */
         // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
         /* more_keys_for_nordic_row2_11 */ "\u00F6",
     };
@@ -1011,18 +1002,19 @@
         // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
         /* more_keys_for_e */ "\u00E9,\u00E8,\u00EA,\u00EB,\u0117",
         /* more_keys_for_i */ null,
-        /* double_quotes */ "!text/double_9qm_lqm",
-        /* single_quotes */ "!text/single_9qm_lqm",
         /* more_keys_for_c */ null,
+        /* double_quotes */ "!text/double_9qm_lqm",
+        // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
+        // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
+        /* more_keys_for_n */ "\u00F1,\u0144",
+        /* single_quotes */ "!text/single_9qm_lqm",
+        /* label_to_alpha_key */ null,
         // U+00DF: "ß" LATIN SMALL LETTER SHARP S
         // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
         // U+0161: "š" LATIN SMALL LETTER S WITH CARON
         /* more_keys_for_s */ "\u00DF,\u015B,\u0161",
-        // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
-        // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
-        /* more_keys_for_n */ "\u00F1,\u0144",
-        /* label_to_alpha_key ~ */
-        null, null, null, null, null, null, null,
+        /* more_keys_for_y ~ */
+        null, null, null, null, null, null,
         /* ~ more_keys_for_g */
         /* single_angle_quotes */ "!text/single_raqm_laqm",
         /* double_angle_quotes */ "!text/double_raqm_laqm",
@@ -1050,8 +1042,8 @@
     /* Language el: Greek */
     private static final String[] LANGUAGE_el = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null, null, null, null, null, null,
-        /* ~ more_keys_for_n */
+        null, null, null, null, null, null, null, null, null,
+        /* ~ single_quotes */
         // Label for "switch to alphabetic" key.
         // U+0391: "Α" GREEK CAPITAL LETTER ALPHA
         // U+0392: "Β" GREEK CAPITAL LETTER BETA
@@ -1097,14 +1089,15 @@
         // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
         // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
         /* more_keys_for_i */ "\u00EE,\u00EF,\u00ED,\u012B,\u00EC",
-        /* double_quotes */ null,
-        /* single_quotes */ null,
         // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
         /* more_keys_for_c */ "\u00E7",
-        // U+00DF: "ß" LATIN SMALL LETTER SHARP S
-        /* more_keys_for_s */ "\u00DF",
+        /* double_quotes */ null,
         // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
         /* more_keys_for_n */ "\u00F1",
+        /* single_quotes */ null,
+        /* label_to_alpha_key */ null,
+        // U+00DF: "ß" LATIN SMALL LETTER SHARP S
+        /* more_keys_for_s */ "\u00DF",
     };
 
     /* Language eo: Esperanto */
@@ -1162,19 +1155,12 @@
         // U+0131: "ı" LATIN SMALL LETTER DOTLESS I
         // U+0133: "ij" LATIN SMALL LIGATURE IJ
         /* more_keys_for_i */ "\u00ED,\u00EE,\u00EF,\u0129,\u00EC,\u012F,\u012B,\u0131,\u0133",
-        /* double_quotes */ null,
-        /* single_quotes */ null,
         // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
         // U+010D: "č" LATIN SMALL LETTER C WITH CARON
         // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
         // U+010B: "ċ" LATIN SMALL LETTER C WITH DOT ABOVE
         /* more_keys_for_c */ "\u0107,\u010D,\u00E7,\u010B",
-        // U+00DF: "ß" LATIN SMALL LETTER SHARP S
-        // U+0161: "š" LATIN SMALL LETTER S WITH CARON
-        // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
-        // U+0219: "ș" LATIN SMALL LETTER S WITH COMMA BELOW
-        // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA
-        /* more_keys_for_s */ "\u00DF,\u0161,\u015B,\u0219,\u015F",
+        /* double_quotes */ null,
         // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
         // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
         // U+0146: "ņ" LATIN SMALL LETTER N WITH CEDILLA
@@ -1182,7 +1168,14 @@
         // U+0149: "ʼn" LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
         // U+014B: "ŋ" LATIN SMALL LETTER ENG
         /* more_keys_for_n */ "\u00F1,\u0144,\u0146,\u0148,\u0149,\u014B",
+        /* single_quotes */ null,
         /* label_to_alpha_key */ null,
+        // U+00DF: "ß" LATIN SMALL LETTER SHARP S
+        // U+0161: "š" LATIN SMALL LETTER S WITH CARON
+        // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
+        // U+0219: "ș" LATIN SMALL LETTER S WITH COMMA BELOW
+        // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA
+        /* more_keys_for_s */ "\u00DF,\u0161,\u015B,\u0219,\u015F",
         // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
         // U+0177: "ŷ" LATIN SMALL LETTER Y WITH CIRCUMFLEX
         // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
@@ -1240,7 +1233,6 @@
         /* keylabel_for_spanish_row2_10 */ "\u0135",
         /* more_keys_for_bullet ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null,
         /* ~ more_keys_for_symbols_percent */
         // U+0175: "ŵ" LATIN SMALL LETTER W WITH CIRCUMFLEX
         /* more_keys_for_v */ "w,\u0175",
@@ -1303,23 +1295,23 @@
         // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
         // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
         /* more_keys_for_i */ "\u00ED,\u00EF,\u00EC,\u00EE,\u012F,\u012B",
-        /* double_quotes */ null,
-        /* single_quotes */ null,
         // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
         // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
         // U+010D: "č" LATIN SMALL LETTER C WITH CARON
         /* more_keys_for_c */ "\u00E7,\u0107,\u010D",
-        /* more_keys_for_s */ null,
+        /* double_quotes */ null,
         // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
         // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
         /* more_keys_for_n */ "\u00F1,\u0144",
-        /* label_to_alpha_key ~ */
+        /* single_quotes ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null,
-        /* ~ more_keys_for_cyrillic_soft_sign */
+        null, null, null, null, null, null, null, null, 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_more_keys_for_symbols_0 */
         // U+00A1: "¡" INVERTED EXCLAMATION MARK
         // U+00BF: "¿" INVERTED QUESTION MARK
-        /* more_keys_for_punctuation */ "!fixedColumnOrder!9,\u00A1,;,/,(,),#,!,\\,,?,\u00BF,&,\\%,+,\",-,:,',@",
+        /* more_keys_for_punctuation */ "!autoColumnOrder!9,\\,,?,!,#,),(,/,;,\u00A1,',@,:,-,\",+,\\%,&,\u00BF",
     };
 
     /* Language et_EE: Estonian (Estonia) */
@@ -1369,22 +1361,22 @@
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
         // U+0131: "ı" LATIN SMALL LETTER DOTLESS I
         /* more_keys_for_i */ "\u012B,\u00EC,\u012F,\u00ED,\u00EE,\u00EF,\u0131",
-        /* double_quotes */ "!text/double_9qm_lqm",
-        /* single_quotes */ "!text/single_9qm_lqm",
         // U+010D: "č" LATIN SMALL LETTER C WITH CARON
         // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
         // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
         /* more_keys_for_c */ "\u010D,\u00E7,\u0107",
+        /* double_quotes */ "!text/double_9qm_lqm",
+        // U+0146: "ņ" LATIN SMALL LETTER N WITH CEDILLA
+        // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
+        // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
+        /* more_keys_for_n */ "\u0146,\u00F1,\u0144",
+        /* single_quotes */ "!text/single_9qm_lqm",
+        /* label_to_alpha_key */ null,
         // U+0161: "š" LATIN SMALL LETTER S WITH CARON
         // U+00DF: "ß" LATIN SMALL LETTER SHARP S
         // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
         // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA
         /* more_keys_for_s */ "\u0161,\u00DF,\u015B,\u015F",
-        // U+0146: "ņ" LATIN SMALL LETTER N WITH CEDILLA
-        // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
-        // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
-        /* more_keys_for_n */ "\u0146,\u00F1,\u0144",
-        /* label_to_alpha_key */ null,
         // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
         // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
         /* more_keys_for_y */ "\u00FD,\u00FF",
@@ -1425,30 +1417,79 @@
         /* more_keys_for_nordic_row2_10 */ "\u00F5",
     };
 
+    /* Language eu_ES: Basque (Spain) */
+    private static final String[] LANGUAGE_eu_ES = {
+        // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
+        // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
+        // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
+        // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
+        // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE
+        // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
+        // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK
+        // U+00E6: "æ" LATIN SMALL LETTER AE
+        // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON
+        // U+00AA: "ª" FEMININE ORDINAL INDICATOR
+        /* more_keys_for_a */ "\u00E1,\u00E0,\u00E4,\u00E2,\u00E3,\u00E5,\u0105,\u00E6,\u0101,\u00AA",
+        // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
+        // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
+        // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
+        // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
+        // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
+        // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
+        // U+0153: "œ" LATIN SMALL LIGATURE OE
+        // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
+        // U+00BA: "º" MASCULINE ORDINAL INDICATOR
+        /* more_keys_for_o */ "\u00F3,\u00F2,\u00F6,\u00F4,\u00F5,\u00F8,\u0153,\u014D,\u00BA",
+        // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
+        // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
+        // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
+        // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
+        // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
+        /* more_keys_for_u */ "\u00FA,\u00FC,\u00F9,\u00FB,\u016B",
+        // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
+        // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
+        // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
+        // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
+        // 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
+        /* more_keys_for_e */ "\u00E9,\u00E8,\u00EB,\u00EA,\u0119,\u0117,\u0113",
+        // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
+        // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
+        // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
+        // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
+        // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
+        // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
+        /* more_keys_for_i */ "\u00ED,\u00EF,\u00EC,\u00EE,\u012F,\u012B",
+        // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
+        // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
+        // U+010D: "č" LATIN SMALL LETTER C WITH CARON
+        /* more_keys_for_c */ "\u00E7,\u0107,\u010D",
+        /* double_quotes */ null,
+        // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
+        // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
+        /* more_keys_for_n */ "\u00F1,\u0144",
+    };
+
     /* Language fa: Persian */
     private static final String[] LANGUAGE_fa = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null, null, null, null, null, null,
-        /* ~ more_keys_for_n */
+        null, null, null, null, null, null, null, null, null,
+        /* ~ single_quotes */
         // Label for "switch to alphabetic" key.
         // U+0627: "ا" ARABIC LETTER ALEF
         // U+200C: ZERO WIDTH NON-JOINER
         // U+0628: "ب" ARABIC LETTER BEH
         // U+067E: "پ" ARABIC LETTER PEH
         /* label_to_alpha_key */ "\u0627\u200C\u0628\u200C\u067E",
-        /* more_keys_for_y ~ */
-        null, null, null, null, null, null, null, null,
+        /* more_keys_for_s ~ */
+        null, null, null, null, null, null, null, null, null,
         /* ~ double_angle_quotes */
         // U+FDFC: "﷼" RIAL SIGN
         /* keylabel_for_currency */ "\uFDFC",
         /* more_keys_for_r ~ */
-        null, null, null, null, null, null, null, null, null, null, null, null,
-        /* ~ more_keys_for_cyrillic_soft_sign */
-        // U+061F: "؟" ARABIC QUESTION MARK
-        // U+060C: "،" ARABIC COMMA
-        // U+061B: "؛" ARABIC SEMICOLON
-        /* more_keys_for_punctuation */ "!fixedColumnOrder!8,\",\',#,-,:,!,\u060C,\u061F,@,&,\\%,+,\u061B,/,!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis",
-        /* more_keys_for_nordic_row2_11 */ null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null,
+        /* ~ more_keys_for_nordic_row2_11 */
         // U+06F1: "۱" EXTENDED ARABIC-INDIC DIGIT ONE
         /* keylabel_for_symbols_1 */ "\u06F1",
         // U+06F2: "۲" EXTENDED ARABIC-INDIC DIGIT TWO
@@ -1487,6 +1528,7 @@
         // U+066B: "٫" ARABIC DECIMAL SEPARATOR
         // U+066C: "٬" ARABIC THOUSANDS SEPARATOR
         /* additional_more_keys_for_symbols_0 */ "0,\u066B,\u066C",
+        /* more_keys_for_punctuation */ null,
         // U+2605: "★" BLACK STAR
         // U+066D: "٭" ARABIC FIVE POINTED STAR
         /* more_keys_for_star */ "\u2605,\u066D",
@@ -1544,7 +1586,6 @@
         /* more_keys_for_arabic_diacritics */ "!fixedColumnOrder!7, \u0655|\u0655, \u0652|\u0652, \u0651|\u0651, \u064C|\u064C, \u064D|\u064D, \u064B|\u064B, \u0654|\u0654, \u0656|\u0656, \u0670|\u0670, \u0653|\u0653, \u064F|\u064F, \u0650|\u0650, \u064E|\u064E,\u0640\u0640\u0640|\u0640",
         // U+060C: "،" ARABIC COMMA
         /* keylabel_for_comma */ "\u060C",
-        /* more_keys_for_comma */ "\\,",
         /* keyhintlabel_for_tablet_comma */ "\u061F",
         /* more_keys_for_tablet_comma */ "!fixedColumnOrder!4,:,!,\u061F,\u061B,-,/,!text/keyspec_left_double_angle_quote,!text/keyspec_right_double_angle_quote",
         // U+064B: "ً" ARABIC FATHATAN
@@ -1591,15 +1632,14 @@
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         /* more_keys_for_u */ "\u00FC",
         /* more_keys_for_e ~ */
-        null, null, null, null, null,
-        /* ~ more_keys_for_c */
+        null, null, null, null, null, null, null,
+        /* ~ label_to_alpha_key */
         // U+0161: "š" LATIN SMALL LETTER S WITH CARON
         // U+00DF: "ß" LATIN SMALL LETTER SHARP S
         // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
         /* more_keys_for_s */ "\u0161,\u00DF,\u015B",
-        /* more_keys_for_n ~ */
-        null, null, null, null,
-        /* ~ more_keys_for_d */
+        /* more_keys_for_y */ null,
+        /* more_keys_for_d */ null,
         // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON
         // U+017A: "ź" LATIN SMALL LETTER Z WITH ACUTE
         // U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE
@@ -1616,8 +1656,8 @@
         // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
         /* more_keys_for_nordic_row2_10 */ "\u00F8",
         /* keylabel_for_east_slavic_row1_9 ~ */
-        null, null, null, null, null, null,
-        /* ~ more_keys_for_punctuation */
+        null, null, null, null, null,
+        /* ~ more_keys_for_cyrillic_soft_sign */
         // U+00E6: "æ" LATIN SMALL LETTER AE
         /* more_keys_for_nordic_row2_11 */ "\u00E6",
     };
@@ -1665,15 +1705,13 @@
         // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
         // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
         /* more_keys_for_i */ "\u00EE,%,\u00EF,\u00EC,\u00ED,\u012F,\u012B",
-        /* double_quotes */ null,
-        /* single_quotes */ null,
         // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
         // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
         // U+010D: "č" LATIN SMALL LETTER C WITH CARON
-        /* more_keys_for_c */ "\u00E7,\u0107,\u010D",
-        /* more_keys_for_s ~ */
-        null, null, null,
-        /* ~ label_to_alpha_key */
+        /* more_keys_for_c */ "\u00E7,%,\u0107,\u010D",
+        /* double_quotes ~ */
+        null, null, null, null, null,
+        /* ~ more_keys_for_s */
         // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
         /* more_keys_for_y */ "%,\u00FF",
         /* more_keys_for_d ~ */
@@ -1697,23 +1735,77 @@
         /* more_keys_for_swiss_row2_11 */ "\u00E4",
     };
 
+    /* Language gl_ES: Gallegan (Spain) */
+    private static final String[] LANGUAGE_gl_ES = {
+        // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
+        // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
+        // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
+        // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
+        // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE
+        // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
+        // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK
+        // U+00E6: "æ" LATIN SMALL LETTER AE
+        // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON
+        // U+00AA: "ª" FEMININE ORDINAL INDICATOR
+        /* more_keys_for_a */ "\u00E1,\u00E0,\u00E4,\u00E2,\u00E3,\u00E5,\u0105,\u00E6,\u0101,\u00AA",
+        // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
+        // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
+        // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
+        // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
+        // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
+        // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
+        // U+0153: "œ" LATIN SMALL LIGATURE OE
+        // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
+        // U+00BA: "º" MASCULINE ORDINAL INDICATOR
+        /* more_keys_for_o */ "\u00F3,\u00F2,\u00F6,\u00F4,\u00F5,\u00F8,\u0153,\u014D,\u00BA",
+        // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
+        // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
+        // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
+        // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
+        // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
+        /* more_keys_for_u */ "\u00FA,\u00FC,\u00F9,\u00FB,\u016B",
+        // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
+        // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
+        // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
+        // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
+        // 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
+        /* more_keys_for_e */ "\u00E9,\u00E8,\u00EB,\u00EA,\u0119,\u0117,\u0113",
+        // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
+        // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
+        // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
+        // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
+        // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
+        // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
+        /* more_keys_for_i */ "\u00ED,\u00EF,\u00EC,\u00EE,\u012F,\u012B",
+        // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
+        // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
+        // U+010D: "č" LATIN SMALL LETTER C WITH CARON
+        /* more_keys_for_c */ "\u00E7,\u0107,\u010D",
+        /* double_quotes */ null,
+        // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
+        // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
+        /* more_keys_for_n */ "\u00F1,\u0144",
+    };
+
     /* Language hi: Hindi */
     private static final String[] LANGUAGE_hi = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null, null, null, null, null, null,
-        /* ~ more_keys_for_n */
+        null, null, null, null, null, null, null, null, null,
+        /* ~ single_quotes */
         // Label for "switch to alphabetic" key.
         // U+0915: "क" DEVANAGARI LETTER KA
         // U+0916: "ख" DEVANAGARI LETTER KHA
         // U+0917: "ग" DEVANAGARI LETTER GA
         /* label_to_alpha_key */ "\u0915\u0916\u0917",
-        /* more_keys_for_y ~ */
-        null, null, null, null, null, null, null, null,
+        /* more_keys_for_s ~ */
+        null, null, null, null, null, null, null, null, null,
         /* ~ double_angle_quotes */
         // U+20B9: "₹" INDIAN RUPEE SIGN
         /* keylabel_for_currency */ "\u20B9",
         /* more_keys_for_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,
         /* ~ more_keys_for_nordic_row2_11 */
         // U+0967: "१" DEVANAGARI DIGIT ONE
         /* keylabel_for_symbols_1 */ "\u0967",
@@ -1757,20 +1849,20 @@
         /* more_keys_for_a ~ */
         null, null, null, null, null,
         /* ~ more_keys_for_i */
-        /* double_quotes */ "!text/double_9qm_rqm",
-        /* single_quotes */ "!text/single_9qm_rqm",
         // U+010D: "č" LATIN SMALL LETTER C WITH CARON
         // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
         // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
         /* more_keys_for_c */ "\u010D,\u0107,\u00E7",
+        /* double_quotes */ "!text/double_9qm_rqm",
+        // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
+        // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
+        /* more_keys_for_n */ "\u00F1,\u0144",
+        /* single_quotes */ "!text/single_9qm_rqm",
+        /* label_to_alpha_key */ null,
         // U+0161: "š" LATIN SMALL LETTER S WITH CARON
         // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
         // U+00DF: "ß" LATIN SMALL LETTER SHARP S
         /* more_keys_for_s */ "\u0161,\u015B,\u00DF",
-        // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
-        // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
-        /* more_keys_for_n */ "\u00F1,\u0144",
-        /* label_to_alpha_key */ null,
         /* more_keys_for_y */ null,
         // U+0111: "đ" LATIN SMALL LETTER D WITH STROKE
         /* more_keys_for_d */ "\u0111",
@@ -1828,10 +1920,12 @@
         // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
         // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
         /* more_keys_for_i */ "\u00ED,\u00EE,\u00EF,\u00EC,\u012F,\u012B",
+        /* more_keys_for_c */ null,
         /* double_quotes */ "!text/double_9qm_rqm",
+        /* more_keys_for_n */ null,
         /* single_quotes */ "!text/single_9qm_rqm",
-        /* more_keys_for_c ~ */
-        null, null, null, null, null, null, null, null, null, null,
+        /* label_to_alpha_key ~ */
+        null, null, null, null, null, null, null, null,
         /* ~ more_keys_for_g */
         /* single_angle_quotes */ "!text/single_raqm_laqm",
         /* double_angle_quotes */ "!text/double_raqm_laqm",
@@ -1840,30 +1934,31 @@
     /* Language hy_AM: Armenian (Armenia) */
     private static final String[] LANGUAGE_hy_AM = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null, null, null, null, null, null,
-        /* ~ more_keys_for_n */
+        null, null, null, null, null, null, null, null, null,
+        /* ~ single_quotes */
         // Label for "switch to alphabetic" key.
         // U+0531: "Ա" ARMENIAN CAPITAL LETTER AYB
         // U+0532: "Բ" ARMENIAN CAPITAL LETTER BEN
         // U+0533: "Գ" ARMENIAN CAPITAL LETTER GIM
         /* label_to_alpha_key */ "\u0531\u0532\u0533",
-        /* more_keys_for_y ~ */
+        /* more_keys_for_s ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null,
-        /* ~ more_keys_for_cyrillic_soft_sign */
-        // U+058A: "֊" ARMENIAN HYPHEN
-        // U+055C: "՜" ARMENIAN EXCLAMATION MARK
-        // U+055D: "՝" ARMENIAN 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,
+        /* ~ additional_more_keys_for_symbols_0 */
         // U+055E: "՞" ARMENIAN QUESTION MARK
-        // U+0559: "ՙ" ARMENIAN MODIFIER LETTER LEFT HALF RING
+        // U+055C: "՜" ARMENIAN EXCLAMATION MARK
         // U+055A: "՚" ARMENIAN APOSTROPHE
+        // U+0559: "ՙ" ARMENIAN MODIFIER LETTER LEFT HALF RING
+        // U+055D: "՝" ARMENIAN COMMA
         // U+055B: "՛" ARMENIAN EMPHASIS MARK
+        // U+058A: "֊" ARMENIAN HYPHEN
+        // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+        // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
         // U+055F: "՟" ARMENIAN ABBREVIATION MARK
-        /* more_keys_for_punctuation */ "!fixedColumnOrder!8,!,?,\u0559,\u055A,.,\u055C,\\,,\u055E,:,;,\u055F,\u00AB,\u00BB,\u058A,\u055D,\u055B",
-        /* more_keys_for_nordic_row2_11 ~ */
+        /* more_keys_for_punctuation */ "!autoColumnOrder!8,\\,,\u055E,\u055C,.,\u055A,\u0559,?,!,\u055D,\u055B,\u058A,\u00BB,\u00AB,\u055F,;,:",
+        /* more_keys_for_star ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, 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_right_single_angle_quote */
         // U+058F: "֏" ARMENIAN DRAM SIGN
         // TODO: Enable this when we have glyph for the following letter
@@ -1878,7 +1973,7 @@
         /* more_keys_for_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, null, null, null, null, null, null, null, null, null,
         /* ~ more_keys_for_greater_than */
         // U+0589: "։" ARMENIAN FULL STOP
         /* keylabel_for_period */ "\u0589",
@@ -1929,11 +2024,12 @@
         // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
         // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
         /* more_keys_for_i */ "\u00ED,\u00EF,\u00EE,\u00EC,\u012F,\u012B",
+        /* more_keys_for_c */ null,
         /* double_quotes */ "!text/double_9qm_lqm",
+        /* more_keys_for_n */ null,
         /* single_quotes */ "!text/single_9qm_lqm",
-        /* more_keys_for_c ~ */
-        null, null, null, null,
-        /* ~ label_to_alpha_key */
+        /* label_to_alpha_key */ null,
+        /* more_keys_for_s */ null,
         // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
         // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
         /* more_keys_for_y */ "\u00FD,\u00FF",
@@ -1992,20 +2088,18 @@
     /* Language iw: Hebrew */
     private static final String[] LANGUAGE_iw = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null,
-        /* ~ more_keys_for_i */
+        null, null, null, null, null, null,
+        /* ~ more_keys_for_c */
         /* double_quotes */ "!text/double_rqm_9qm",
+        /* more_keys_for_n */ null,
         /* single_quotes */ "!text/single_rqm_9qm",
-        /* more_keys_for_c ~ */
-        null, null, null,
-        /* ~ more_keys_for_n */
         // Label for "switch to alphabetic" key.
         // U+05D0: "א" HEBREW LETTER ALEF
         // U+05D1: "ב" HEBREW LETTER BET
         // U+05D2: "ג" HEBREW LETTER GIMEL
         /* label_to_alpha_key */ "\u05D0\u05D1\u05D2",
-        /* more_keys_for_y ~ */
-        null, null, null, null, null, null, null, null,
+        /* more_keys_for_s ~ */
+        null, null, null, null, null, null, null, null, null,
         /* ~ double_angle_quotes */
         // U+20AA: "₪" NEW SHEQEL SIGN
         /* keylabel_for_currency */ "\u20AA",
@@ -2013,7 +2107,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,
-        /* ~ additional_more_keys_for_symbols_0 */
+        /* ~ more_keys_for_punctuation */
         // U+2605: "★" BLACK STAR
         /* more_keys_for_star */ "\u2605",
         // The all letters need to be mirrored are found at
@@ -2041,7 +2135,7 @@
         /* keylabel_for_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, null, null, null, null, null, null, null, null, null,
         /* ~ more_keys_for_tablet_punctuation */
         // U+00B1: "±" PLUS-MINUS SIGN
         // U+FB29: "﬩" HEBREW LETTER ALTERNATIVE PLUS SIGN
@@ -2051,13 +2145,11 @@
     /* Language ka_GE: Georgian (Georgia) */
     private static final String[] LANGUAGE_ka_GE = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null,
-        /* ~ more_keys_for_i */
+        null, null, null, null, null, null,
+        /* ~ more_keys_for_c */
         /* double_quotes */ "!text/double_9qm_lqm",
+        /* more_keys_for_n */ null,
         /* single_quotes */ "!text/single_9qm_lqm",
-        /* more_keys_for_c ~ */
-        null, null, null,
-        /* ~ more_keys_for_n */
         // Label for "switch to alphabetic" key.
         // U+10D0: "ა" GEORGIAN LETTER AN
         // U+10D1: "ბ" GEORGIAN LETTER BAN
@@ -2068,15 +2160,15 @@
     /* Language kk: Kazakh */
     private static final String[] LANGUAGE_kk = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null, null, null, null, null, null,
-        /* ~ more_keys_for_n */
+        null, null, null, null, null, null, null, null, null,
+        /* ~ single_quotes */
         // Label for "switch to alphabetic" key.
         // U+0410: "А" CYRILLIC CAPITAL LETTER A
         // U+0411: "Б" CYRILLIC CAPITAL LETTER BE
         // U+0412: "В" CYRILLIC CAPITAL LETTER VE
         /* label_to_alpha_key */ "\u0410\u0411\u0412",
-        /* more_keys_for_y ~ */
-        null, null, null, null, null, null, null, null, null, null, null,
+        /* more_keys_for_s ~ */
+        null, null, null, null, null, null, null, null, null, null, null, null,
         /* ~ more_keys_for_k */
         // U+0451: "ё" CYRILLIC SMALL LETTER IO
         /* more_keys_for_cyrillic_ie */ "\u0451",
@@ -2093,7 +2185,7 @@
         /* keylabel_for_east_slavic_row3_5 */ "\u0438",
         // U+044A: "ъ" CYRILLIC SMALL LETTER HARD SIGN
         /* more_keys_for_cyrillic_soft_sign */ "\u044A",
-        /* more_keys_for_punctuation ~ */
+        /* more_keys_for_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,
@@ -2111,7 +2203,7 @@
         /* more_keys_for_cyrillic_o */ "\u04E9",
         /* keylabel_for_south_slavic_row1_6 ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         /* ~ more_keys_for_j */
         // U+049B: "қ" CYRILLIC SMALL LETTER KA WITH DESCENDER
         /* more_keys_for_cyrillic_ka */ "\u049B",
@@ -2124,14 +2216,14 @@
     /* Language km_KH: Khmer (Cambodia) */
     private static final String[] LANGUAGE_km_KH = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null, null, null, null, null, null,
-        /* ~ more_keys_for_n */
+        null, null, null, null, null, null, null, null, null,
+        /* ~ single_quotes */
         // Label for "switch to alphabetic" key.
         // U+1780: "ក" KHMER LETTER KA
         // U+1781: "ខ" KHMER LETTER KHA
         // U+1782: "គ" KHMER LETTER KO
         /* label_to_alpha_key */ "\u1780\u1781\u1782",
-        /* more_keys_for_y ~ */
+        /* more_keys_for_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, null,
@@ -2147,15 +2239,15 @@
     /* Language ky: Kirghiz */
     private static final String[] LANGUAGE_ky = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null, null, null, null, null, null,
-        /* ~ more_keys_for_n */
+        null, null, null, null, null, null, null, null, null,
+        /* ~ single_quotes */
         // Label for "switch to alphabetic" key.
         // U+0410: "А" CYRILLIC CAPITAL LETTER A
         // U+0411: "Б" CYRILLIC CAPITAL LETTER BE
         // U+0412: "В" CYRILLIC CAPITAL LETTER VE
         /* label_to_alpha_key */ "\u0410\u0411\u0412",
-        /* more_keys_for_y ~ */
-        null, null, null, null, null, null, null, null, null, null, null,
+        /* more_keys_for_s ~ */
+        null, null, null, null, null, null, null, null, null, null, null, null,
         /* ~ more_keys_for_k */
         // U+0451: "ё" CYRILLIC SMALL LETTER IO
         /* more_keys_for_cyrillic_ie */ "\u0451",
@@ -2172,7 +2264,7 @@
         /* keylabel_for_east_slavic_row3_5 */ "\u0438",
         // U+044A: "ъ" CYRILLIC SMALL LETTER HARD SIGN
         /* more_keys_for_cyrillic_soft_sign */ "\u044A",
-        /* more_keys_for_punctuation ~ */
+        /* more_keys_for_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,
@@ -2190,15 +2282,15 @@
     /* Language lo_LA: Lao (Laos) */
     private static final String[] LANGUAGE_lo_LA = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null, null, null, null, null, null,
-        /* ~ more_keys_for_n */
+        null, null, null, null, null, null, null, null, null,
+        /* ~ single_quotes */
         // Label for "switch to alphabetic" key.
         // U+0E81: "ກ" LAO LETTER KO
         // U+0E82: "ຂ" LAO LETTER KHO SUNG
         // U+0E84: "ຄ" LAO LETTER KHO TAM
         /* label_to_alpha_key */ "\u0E81\u0E82\u0E84",
-        /* more_keys_for_y ~ */
-        null, null, null, null, null, null, null, null,
+        /* more_keys_for_s ~ */
+        null, null, null, null, null, null, null, null, null,
         /* ~ double_angle_quotes */
         // U+20AD: "₭" KIP SIGN
         /* keylabel_for_currency */ "\u20AD",
@@ -2252,22 +2344,22 @@
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
         // U+0131: "ı" LATIN SMALL LETTER DOTLESS I
         /* more_keys_for_i */ "\u012F,\u012B,\u00EC,\u00ED,\u00EE,\u00EF,\u0131",
-        /* double_quotes */ "!text/double_9qm_lqm",
-        /* single_quotes */ "!text/single_9qm_lqm",
         // U+010D: "č" LATIN SMALL LETTER C WITH CARON
         // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
         // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
         /* more_keys_for_c */ "\u010D,\u00E7,\u0107",
+        /* double_quotes */ "!text/double_9qm_lqm",
+        // U+0146: "ņ" LATIN SMALL LETTER N WITH CEDILLA
+        // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
+        // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
+        /* more_keys_for_n */ "\u0146,\u00F1,\u0144",
+        /* single_quotes */ "!text/single_9qm_lqm",
+        /* label_to_alpha_key */ null,
         // U+0161: "š" LATIN SMALL LETTER S WITH CARON
         // U+00DF: "ß" LATIN SMALL LETTER SHARP S
         // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
         // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA
         /* more_keys_for_s */ "\u0161,\u00DF,\u015B,\u015F",
-        // U+0146: "ņ" LATIN SMALL LETTER N WITH CEDILLA
-        // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
-        // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
-        /* more_keys_for_n */ "\u0146,\u00F1,\u0144",
-        /* label_to_alpha_key */ null,
         // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
         // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
         /* more_keys_for_y */ "\u00FD,\u00FF",
@@ -2346,22 +2438,22 @@
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
         // U+0131: "ı" LATIN SMALL LETTER DOTLESS I
         /* more_keys_for_i */ "\u012B,\u012F,\u00EC,\u00ED,\u00EE,\u00EF,\u0131",
-        /* double_quotes */ "!text/double_9qm_lqm",
-        /* single_quotes */ "!text/single_9qm_lqm",
         // U+010D: "č" LATIN SMALL LETTER C WITH CARON
         // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
         // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
         /* more_keys_for_c */ "\u010D,\u00E7,\u0107",
+        /* double_quotes */ "!text/double_9qm_lqm",
+        // U+0146: "ņ" LATIN SMALL LETTER N WITH CEDILLA
+        // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
+        // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
+        /* more_keys_for_n */ "\u0146,\u00F1,\u0144",
+        /* single_quotes */ "!text/single_9qm_lqm",
+        /* label_to_alpha_key */ null,
         // U+0161: "š" LATIN SMALL LETTER S WITH CARON
         // U+00DF: "ß" LATIN SMALL LETTER SHARP S
         // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
         // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA
         /* more_keys_for_s */ "\u0161,\u00DF,\u015B,\u015F",
-        // U+0146: "ņ" LATIN SMALL LETTER N WITH CEDILLA
-        // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
-        // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
-        /* more_keys_for_n */ "\u0146,\u00F1,\u0144",
-        /* label_to_alpha_key */ null,
         // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
         // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
         /* more_keys_for_y */ "\u00FD,\u00FF",
@@ -2396,20 +2488,18 @@
     /* Language mk: Macedonian */
     private static final String[] LANGUAGE_mk = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null,
-        /* ~ more_keys_for_i */
+        null, null, null, null, null, null,
+        /* ~ more_keys_for_c */
         /* double_quotes */ "!text/double_9qm_lqm",
+        /* more_keys_for_n */ null,
         /* single_quotes */ "!text/single_9qm_lqm",
-        /* more_keys_for_c ~ */
-        null, null, null,
-        /* ~ more_keys_for_n */
         // Label for "switch to alphabetic" key.
         // U+0410: "А" CYRILLIC CAPITAL LETTER A
         // U+0411: "Б" CYRILLIC CAPITAL LETTER BE
         // U+0412: "В" CYRILLIC CAPITAL LETTER VE
         /* label_to_alpha_key */ "\u0410\u0411\u0412",
-        /* more_keys_for_y ~ */
-        null, null, null, null, null, null, null, null, null, null, null,
+        /* more_keys_for_s ~ */
+        null, null, null, null, null, null, null, null, null, null, null, null,
         /* ~ more_keys_for_k */
         // U+0450: "ѐ" CYRILLIC SMALL LETTER IE WITH GRAVE
         /* more_keys_for_cyrillic_ie */ "\u0450",
@@ -2434,20 +2524,32 @@
     /* Language mn_MN: Mongolian (Mongolia) */
     private static final String[] LANGUAGE_mn_MN = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null, null, null, null, null, null,
-        /* ~ more_keys_for_n */
+        null, null, null, null, null, null, null, null, null,
+        /* ~ single_quotes */
         // Label for "switch to alphabetic" key.
         // U+0410: "А" CYRILLIC CAPITAL LETTER A
         // U+0411: "Б" CYRILLIC CAPITAL LETTER BE
         // U+0412: "В" CYRILLIC CAPITAL LETTER VE
         /* label_to_alpha_key */ "\u0410\u0411\u0412",
-        /* more_keys_for_y ~ */
-        null, null, null, null, null, null, null, null,
+        /* more_keys_for_s ~ */
+        null, null, null, null, null, null, null, null, null,
         /* ~ double_angle_quotes */
         // U+20AE: "₮" TUGRIK SIGN
         /* keylabel_for_currency */ "\u20AE",
     };
 
+    /* Language my_MM: Burmese (Myanmar) */
+    private static final String[] LANGUAGE_my_MM = {
+        /* more_keys_for_a ~ */
+        null, null, null, null, null, null, null, null, null,
+        /* ~ single_quotes */
+        // Label for "switch to alphabetic" key.
+        // U+1000: "က" MYANMAR LETTER KA
+        // U+1001: "ခ" MYANMAR LETTER KHA
+        // U+1002: "ဂ" MYANMAR LETTER GA
+        /* label_to_alpha_key */ "\u1000\u1001\u1002",
+    };
+
     /* Language nb: Norwegian Bokmål */
     private static final String[] LANGUAGE_nb = {
         // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
@@ -2480,11 +2582,12 @@
         // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
         /* more_keys_for_e */ "\u00E9,\u00E8,\u00EA,\u00EB,\u0119,\u0117,\u0113",
         /* more_keys_for_i */ null,
+        /* more_keys_for_c */ null,
         /* double_quotes */ "!text/double_9qm_rqm",
+        /* more_keys_for_n */ null,
         /* single_quotes */ "!text/single_9qm_rqm",
-        /* more_keys_for_c ~ */
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null,
+        /* label_to_alpha_key ~ */
+        null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         /* ~ more_keys_for_cyrillic_ie */
         // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
         /* keylabel_for_nordic_row1_11 */ "\u00E5",
@@ -2495,8 +2598,8 @@
         // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
         /* more_keys_for_nordic_row2_10 */ "\u00F6",
         /* keylabel_for_east_slavic_row1_9 ~ */
-        null, null, null, null, null, null,
-        /* ~ more_keys_for_punctuation */
+        null, null, null, null, null,
+        /* ~ more_keys_for_cyrillic_soft_sign */
         // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
         /* more_keys_for_nordic_row2_11 */ "\u00E4",
     };
@@ -2504,20 +2607,20 @@
     /* Language ne_NP: Nepali (Nepal) */
     private static final String[] LANGUAGE_ne_NP = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null, null, null, null, null, null,
-        /* ~ more_keys_for_n */
+        null, null, null, null, null, null, null, null, null,
+        /* ~ single_quotes */
         // Label for "switch to alphabetic" key.
         // U+0915: "क" DEVANAGARI LETTER KA
         // U+0916: "ख" DEVANAGARI LETTER KHA
         // U+0917: "ग" DEVANAGARI LETTER GA
         /* label_to_alpha_key */ "\u0915\u0916\u0917",
-        /* more_keys_for_y ~ */
-        null, null, null, null, null, null, null, null,
+        /* more_keys_for_s ~ */
+        null, null, null, null, null, null, null, null, null,
         /* ~ double_angle_quotes */
         // U+0930/U+0941/U+002E "रु." NEPALESE RUPEE SIGN
         /* keylabel_for_currency */ "\u0930\u0941.",
         /* more_keys_for_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,
         /* ~ more_keys_for_nordic_row2_11 */
         // U+0967: "१" DEVANAGARI DIGIT ONE
         /* keylabel_for_symbols_1 */ "\u0967",
@@ -2598,14 +2701,14 @@
         // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
         // U+0133: "ij" LATIN SMALL LIGATURE IJ
         /* more_keys_for_i */ "\u00ED,\u00EF,\u00EC,\u00EE,\u012F,\u012B,\u0133",
-        /* double_quotes */ "!text/double_9qm_rqm",
-        /* single_quotes */ "!text/single_9qm_rqm",
         /* more_keys_for_c */ null,
-        /* more_keys_for_s */ null,
+        /* double_quotes */ "!text/double_9qm_rqm",
         // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
         // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
         /* more_keys_for_n */ "\u00F1,\u0144",
+        /* single_quotes */ "!text/single_9qm_rqm",
         /* label_to_alpha_key */ null,
+        /* more_keys_for_s */ null,
         // U+0133: "ij" LATIN SMALL LIGATURE IJ
         /* more_keys_for_y */ "\u0133",
     };
@@ -2641,22 +2744,22 @@
         // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
         /* more_keys_for_e */ "\u0119,\u00E8,\u00E9,\u00EA,\u00EB,\u0117,\u0113",
         /* more_keys_for_i */ null,
-        /* double_quotes */ "!text/double_9qm_rqm",
-        /* single_quotes */ "!text/single_9qm_rqm",
         // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
         // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
         // U+010D: "č" LATIN SMALL LETTER C WITH CARON
         /* more_keys_for_c */ "\u0107,\u00E7,\u010D",
+        /* double_quotes */ "!text/double_9qm_rqm",
+        // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
+        // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
+        /* more_keys_for_n */ "\u0144,\u00F1",
+        /* single_quotes */ "!text/single_9qm_rqm",
+        /* label_to_alpha_key */ null,
         // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
         // U+00DF: "ß" LATIN SMALL LETTER SHARP S
         // U+0161: "š" LATIN SMALL LETTER S WITH CARON
         /* more_keys_for_s */ "\u015B,\u00DF,\u0161",
-        // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
-        // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
-        /* more_keys_for_n */ "\u0144,\u00F1",
-        /* label_to_alpha_key ~ */
-        null, null, null,
-        /* ~ more_keys_for_d */
+        /* more_keys_for_y */ null,
+        /* more_keys_for_d */ null,
         // U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE
         // U+017A: "ź" LATIN SMALL LETTER Z WITH ACUTE
         // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON
@@ -2708,8 +2811,6 @@
         // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
         // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
         /* more_keys_for_i */ "\u00ED,\u00EE,\u00EC,\u00EF,\u012F,\u012B",
-        /* double_quotes */ null,
-        /* single_quotes */ null,
         // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
         // U+010D: "č" LATIN SMALL LETTER C WITH CARON
         // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
@@ -2751,16 +2852,18 @@
         // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
         // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
         /* more_keys_for_i */ "\u00EE,\u00EF,\u00EC,\u00ED,\u012F,\u012B",
-        /* double_quotes */ "!text/double_9qm_rqm",
-        /* single_quotes */ "!text/single_9qm_rqm",
         /* more_keys_for_c */ null,
+        /* double_quotes */ "!text/double_9qm_rqm",
+        /* more_keys_for_n */ null,
+        /* single_quotes */ "!text/single_9qm_rqm",
+        /* label_to_alpha_key */ null,
         // U+0219: "ș" LATIN SMALL LETTER S WITH COMMA BELOW
         // U+00DF: "ß" LATIN SMALL LETTER SHARP S
         // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
         // U+0161: "š" LATIN SMALL LETTER S WITH CARON
         /* more_keys_for_s */ "\u0219,\u00DF,\u015B,\u0161",
-        /* more_keys_for_n ~ */
-        null, null, null, null, null,
+        /* more_keys_for_y ~ */
+        null, null, null,
         /* ~ more_keys_for_z */
         // U+021B: "ț" LATIN SMALL LETTER T WITH COMMA BELOW
         /* more_keys_for_t */ "\u021B",
@@ -2769,20 +2872,18 @@
     /* Language ru: Russian */
     private static final String[] LANGUAGE_ru = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null,
-        /* ~ more_keys_for_i */
+        null, null, null, null, null, null,
+        /* ~ more_keys_for_c */
         /* double_quotes */ "!text/double_9qm_lqm",
+        /* more_keys_for_n */ null,
         /* single_quotes */ "!text/single_9qm_lqm",
-        /* more_keys_for_c ~ */
-        null, null, null,
-        /* ~ more_keys_for_n */
         // Label for "switch to alphabetic" key.
         // U+0410: "А" CYRILLIC CAPITAL LETTER A
         // U+0411: "Б" CYRILLIC CAPITAL LETTER BE
         // U+0412: "В" CYRILLIC CAPITAL LETTER VE
         /* label_to_alpha_key */ "\u0410\u0411\u0412",
-        /* more_keys_for_y ~ */
-        null, null, null, null, null, null, null, null, null, null, null,
+        /* more_keys_for_s ~ */
+        null, null, null, null, null, null, null, null, null, null, null, null,
         /* ~ more_keys_for_k */
         // U+0451: "ё" CYRILLIC SMALL LETTER IO
         /* more_keys_for_cyrillic_ie */ "\u0451",
@@ -2848,23 +2949,23 @@
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
         // U+0131: "ı" LATIN SMALL LETTER DOTLESS I
         /* more_keys_for_i */ "\u00ED,\u012B,\u012F,\u00EC,\u00EE,\u00EF,\u0131",
-        /* double_quotes */ "!text/double_9qm_lqm",
-        /* single_quotes */ "!text/single_9qm_lqm",
         // U+010D: "č" LATIN SMALL LETTER C WITH CARON
         // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
         // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
         /* more_keys_for_c */ "\u010D,\u00E7,\u0107",
-        // U+0161: "š" LATIN SMALL LETTER S WITH CARON
-        // U+00DF: "ß" LATIN SMALL LETTER SHARP S
-        // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
-        // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA
-        /* more_keys_for_s */ "\u0161,\u00DF,\u015B,\u015F",
+        /* double_quotes */ "!text/double_9qm_lqm",
         // U+0148: "ň" LATIN SMALL LETTER N WITH CARON
         // U+0146: "ņ" LATIN SMALL LETTER N WITH CEDILLA
         // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
         // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
         /* more_keys_for_n */ "\u0148,\u0146,\u00F1,\u0144",
+        /* single_quotes */ "!text/single_9qm_lqm",
         /* label_to_alpha_key */ null,
+        // U+0161: "š" LATIN SMALL LETTER S WITH CARON
+        // U+00DF: "ß" LATIN SMALL LETTER SHARP S
+        // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
+        // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA
+        /* more_keys_for_s */ "\u0161,\u00DF,\u015B,\u015F",
         // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
         // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
         /* more_keys_for_y */ "\u00FD,\u00FF",
@@ -2901,16 +3002,16 @@
         /* more_keys_for_a ~ */
         null, null, null, null, null,
         /* ~ more_keys_for_i */
-        /* double_quotes */ "!text/double_9qm_lqm",
-        /* single_quotes */ "!text/single_9qm_lqm",
         // U+010D: "č" LATIN SMALL LETTER C WITH CARON
         // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
         /* more_keys_for_c */ "\u010D,\u0107",
+        /* double_quotes */ "!text/double_9qm_lqm",
+        /* more_keys_for_n */ null,
+        /* single_quotes */ "!text/single_9qm_lqm",
+        /* label_to_alpha_key */ null,
         // U+0161: "š" LATIN SMALL LETTER S WITH CARON
         /* more_keys_for_s */ "\u0161",
-        /* more_keys_for_n ~ */
-        null, null, null,
-        /* ~ more_keys_for_y */
+        /* more_keys_for_y */ null,
         // U+0111: "đ" LATIN SMALL LETTER D WITH STROKE
         /* more_keys_for_d */ "\u0111",
         // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON
@@ -2925,21 +3026,19 @@
     /* Language sr: Serbian */
     private static final String[] LANGUAGE_sr = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null,
-        /* ~ more_keys_for_i */
+        null, null, null, null, null, null,
+        /* ~ more_keys_for_c */
         /* double_quotes */ "!text/double_9qm_lqm",
+        /* more_keys_for_n */ null,
         /* single_quotes */ "!text/single_9qm_lqm",
-        /* more_keys_for_c ~ */
-        null, null, null,
-        /* ~ more_keys_for_n */
         // END: More keys definitions for Serbian (Cyrillic)
         // Label for "switch to alphabetic" key.
         // U+0410: "А" CYRILLIC CAPITAL LETTER A
         // U+0411: "Б" CYRILLIC CAPITAL LETTER BE
         // U+0412: "В" CYRILLIC CAPITAL LETTER VE
         /* label_to_alpha_key */ "\u0410\u0411\u0412",
-        /* more_keys_for_y ~ */
-        null, null, null, null, null, null,
+        /* more_keys_for_s ~ */
+        null, null, null, null, null, null, null,
         /* ~ more_keys_for_g */
         /* single_angle_quotes */ "!text/single_raqm_laqm",
         /* double_angle_quotes */ "!text/double_raqm_laqm",
@@ -3015,22 +3114,22 @@
         // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
         /* more_keys_for_i */ "\u00ED,\u00EC,\u00EE,\u00EF",
-        /* double_quotes */ null,
-        /* single_quotes */ null,
         // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
         // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
         // U+010D: "č" LATIN SMALL LETTER C WITH CARON
         /* more_keys_for_c */ "\u00E7,\u0107,\u010D",
+        /* double_quotes */ null,
+        // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
+        // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
+        // U+0148: "ň" LATIN SMALL LETTER N WITH CARON
+        /* more_keys_for_n */ "\u0144,\u00F1,\u0148",
+        /* single_quotes */ null,
+        /* label_to_alpha_key */ null,
         // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
         // U+0161: "š" LATIN SMALL LETTER S WITH CARON
         // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA
         // U+00DF: "ß" LATIN SMALL LETTER SHARP S
         /* more_keys_for_s */ "\u015B,\u0161,\u015F,\u00DF",
-        // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
-        // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
-        // U+0148: "ň" LATIN SMALL LETTER N WITH CARON
-        /* more_keys_for_n */ "\u0144,\u00F1,\u0148",
-        /* label_to_alpha_key */ null,
         // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
         // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
         /* more_keys_for_y */ "\u00FD,\u00FF",
@@ -3064,8 +3163,8 @@
         // U+0153: "œ" LATIN SMALL LIGATURE OE
         /* more_keys_for_nordic_row2_10 */ "\u00F8,\u0153",
         /* keylabel_for_east_slavic_row1_9 ~ */
-        null, null, null, null, null, null,
-        /* ~ more_keys_for_punctuation */
+        null, null, null, null, null,
+        /* ~ more_keys_for_cyrillic_soft_sign */
         // U+00E6: "æ" LATIN SMALL LETTER AE
         /* more_keys_for_nordic_row2_11 */ "\u00E6",
     };
@@ -3109,16 +3208,17 @@
         // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
         // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
         /* more_keys_for_i */ "\u00EE,\u00EF,\u00ED,\u012B,\u00EC",
-        /* double_quotes */ null,
-        /* single_quotes */ null,
         // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
         /* more_keys_for_c */ "\u00E7",
-        // U+00DF: "ß" LATIN SMALL LETTER SHARP S
-        /* more_keys_for_s */ "\u00DF",
+        /* double_quotes */ null,
         // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
         /* more_keys_for_n */ "\u00F1",
-        /* label_to_alpha_key ~ */
-        null, null, null, null, null, null,
+        /* single_quotes */ null,
+        /* label_to_alpha_key */ null,
+        // U+00DF: "ß" LATIN SMALL LETTER SHARP S
+        /* more_keys_for_s */ "\u00DF",
+        /* more_keys_for_y ~ */
+        null, null, null, null, null,
         /* ~ more_keys_for_l */
         /* more_keys_for_g */ "g\'",
     };
@@ -3126,15 +3226,15 @@
     /* Language th: Thai */
     private static final String[] LANGUAGE_th = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null, null, null, null, null, null,
-        /* ~ more_keys_for_n */
+        null, null, null, null, null, null, null, null, null,
+        /* ~ single_quotes */
         // Label for "switch to alphabetic" key.
         // U+0E01: "ก" THAI CHARACTER KO KAI
         // U+0E02: "ข" THAI CHARACTER KHO KHAI
         // U+0E04: "ค" THAI CHARACTER KHO KHWAI
         /* label_to_alpha_key */ "\u0E01\u0E02\u0E04",
-        /* more_keys_for_y ~ */
-        null, null, null, null, null, null, null, null,
+        /* more_keys_for_s ~ */
+        null, null, null, null, null, null, null, null, null,
         /* ~ double_angle_quotes */
         // U+0E3F: "฿" THAI CURRENCY SYMBOL BAHT
         /* keylabel_for_currency */ "\u0E3F",
@@ -3184,13 +3284,11 @@
         // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
         // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
         /* more_keys_for_i */ "\u00ED,\u00EF,\u00EC,\u00EE,\u012F,\u012B",
-        /* double_quotes */ null,
-        /* single_quotes */ null,
         // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
         // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
         // U+010D: "č" LATIN SMALL LETTER C WITH CARON
         /* more_keys_for_c */ "\u00E7,\u0107,\u010D",
-        /* more_keys_for_s */ null,
+        /* double_quotes */ null,
         // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
         // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
         /* more_keys_for_n */ "\u00F1,\u0144",
@@ -3224,19 +3322,20 @@
         // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
         // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
         /* more_keys_for_i */ "\u0131,\u00EE,\u00EF,\u00EC,\u00ED,\u012F,\u012B",
-        /* double_quotes */ null,
-        /* single_quotes */ null,
         // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
         // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
         // U+010D: "č" LATIN SMALL LETTER C WITH CARON
         /* more_keys_for_c */ "\u00E7,\u0107,\u010D",
+        /* double_quotes ~ */
+        null, null, null, null,
+        /* ~ label_to_alpha_key */
         // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA
         // U+00DF: "ß" LATIN SMALL LETTER SHARP S
         // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
         // U+0161: "š" LATIN SMALL LETTER S WITH CARON
         /* more_keys_for_s */ "\u015F,\u00DF,\u015B,\u0161",
-        /* more_keys_for_n ~ */
-        null, null, null, null, null, null, null,
+        /* more_keys_for_y ~ */
+        null, null, null, null, null,
         /* ~ more_keys_for_l */
         // U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE
         /* more_keys_for_g */ "\u011F",
@@ -3245,20 +3344,18 @@
     /* Language uk: Ukrainian */
     private static final String[] LANGUAGE_uk = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null,
-        /* ~ more_keys_for_i */
+        null, null, null, null, null, null,
+        /* ~ more_keys_for_c */
         /* double_quotes */ "!text/double_9qm_lqm",
+        /* more_keys_for_n */ null,
         /* single_quotes */ "!text/single_9qm_lqm",
-        /* more_keys_for_c ~ */
-        null, null, null,
-        /* ~ more_keys_for_n */
         // Label for "switch to alphabetic" key.
         // U+0410: "А" CYRILLIC CAPITAL LETTER A
         // U+0411: "Б" CYRILLIC CAPITAL LETTER BE
         // U+0412: "В" CYRILLIC CAPITAL LETTER VE
         /* label_to_alpha_key */ "\u0410\u0411\u0412",
-        /* more_keys_for_y ~ */
-        null, null, null, null, null, null, null, null,
+        /* more_keys_for_s ~ */
+        null, null, null, null, null, null, null, null, null,
         /* ~ double_angle_quotes */
         // U+20B4: "₴" HRYVNIA SIGN
         /* keylabel_for_currency */ "\u20B4",
@@ -3275,7 +3372,7 @@
         /* keylabel_for_east_slavic_row3_5 */ "\u0438",
         // U+044A: "ъ" CYRILLIC SMALL LETTER HARD SIGN
         /* more_keys_for_cyrillic_soft_sign */ "\u044A",
-        /* more_keys_for_punctuation ~ */
+        /* more_keys_for_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,
@@ -3355,9 +3452,9 @@
         // U+0129: "ĩ" LATIN SMALL LETTER I WITH TILDE
         // U+1ECB: "ị" LATIN SMALL LETTER I WITH DOT BELOW
         /* more_keys_for_i */ "\u00EC,\u00ED,\u1EC9,\u0129,\u1ECB",
-        /* double_quotes ~ */
+        /* more_keys_for_c ~ */
         null, null, null, null, null, null,
-        /* ~ label_to_alpha_key */
+        /* ~ more_keys_for_s */
         // U+1EF3: "ỳ" LATIN SMALL LETTER Y WITH GRAVE
         // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
         // U+1EF7: "ỷ" LATIN SMALL LETTER Y WITH HOOK ABOVE
@@ -3412,14 +3509,15 @@
         // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
         // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
         /* more_keys_for_i */ "\u00EE,\u00EF,\u00ED,\u012B,\u00EC",
-        /* double_quotes */ null,
-        /* single_quotes */ null,
         // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
         /* more_keys_for_c */ "\u00E7",
-        // U+00DF: "ß" LATIN SMALL LETTER SHARP S
-        /* more_keys_for_s */ "\u00DF",
+        /* double_quotes */ null,
         // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
         /* more_keys_for_n */ "\u00F1",
+        /* single_quotes */ null,
+        /* label_to_alpha_key */ null,
+        // U+00DF: "ß" LATIN SMALL LETTER SHARP S
+        /* more_keys_for_s */ "\u00DF",
     };
 
     /* Language zz: Alphabet */
@@ -3480,21 +3578,13 @@
         // U+0131: "ı" LATIN SMALL LETTER DOTLESS I
         // U+0133: "ij" LATIN SMALL LIGATURE IJ
         /* more_keys_for_i */ "\u00EC,\u00ED,\u00EE,\u00EF,\u0129,\u012B,\u012D,\u012F,\u0131,\u0133",
-        /* double_quotes */ null,
-        /* single_quotes */ null,
         // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
         // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
         // U+0109: "ĉ" LATIN SMALL LETTER C WITH CIRCUMFLEX
         // U+010B: "ċ" LATIN SMALL LETTER C WITH DOT ABOVE
         // U+010D: "č" LATIN SMALL LETTER C WITH CARON
         /* more_keys_for_c */ "\u00E7,\u0107,\u0109,\u010B,\u010D",
-        // U+00DF: "ß" LATIN SMALL LETTER SHARP S
-        // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
-        // U+015D: "ŝ" LATIN SMALL LETTER S WITH CIRCUMFLEX
-        // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA
-        // U+0161: "š" LATIN SMALL LETTER S WITH CARON
-        // U+017F: "ſ" LATIN SMALL LETTER LONG S
-        /* more_keys_for_s */ "\u00DF,\u015B,\u015D,\u015F,\u0161,\u017F",
+        /* double_quotes */ null,
         // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
         // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
         // U+0146: "ņ" LATIN SMALL LETTER N WITH CEDILLA
@@ -3502,7 +3592,15 @@
         // U+0149: "ʼn" LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
         // U+014B: "ŋ" LATIN SMALL LETTER ENG
         /* more_keys_for_n */ "\u00F1,\u0144,\u0146,\u0148,\u0149,\u014B",
+        /* single_quotes */ null,
         /* label_to_alpha_key */ null,
+        // U+00DF: "ß" LATIN SMALL LETTER SHARP S
+        // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
+        // U+015D: "ŝ" LATIN SMALL LETTER S WITH CIRCUMFLEX
+        // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA
+        // U+0161: "š" LATIN SMALL LETTER S WITH CARON
+        // U+017F: "ſ" LATIN SMALL LETTER LONG S
+        /* more_keys_for_s */ "\u00DF,\u015B,\u015D,\u015F,\u0161,\u017F",
         // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
         // U+0177: "ŷ" LATIN SMALL LETTER Y WITH CIRCUMFLEX
         // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
@@ -3555,7 +3653,7 @@
         /* more_keys_for_cyrillic_u ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null,
+        null, null, null,
         /* ~ more_keys_for_v */
         // U+0135: "ĵ" LATIN SMALL LETTER J WITH CIRCUMFLEX
         /* more_keys_for_j */ "\u0135",
@@ -3565,60 +3663,63 @@
     // Currently we are dropping the region from the key.
     private static final Object[] LANGUAGES_AND_TEXTS = {
     // "locale", TEXT_ARRAY,  /* numberOfNonNullText/lengthOf_TEXT_ARRAY localeName */
-        "DEFAULT", LANGUAGE_DEFAULT, /* 170/170 default */
+        "DEFAULT", LANGUAGE_DEFAULT, /* 169/169 default */
         "af", LANGUAGE_af,    /*   7/ 12 Afrikaans */
-        "ar", LANGUAGE_ar,    /*  58/109 Arabic */
+        "ar", LANGUAGE_ar,    /*  56/108 Arabic */
         "az", LANGUAGE_az_AZ, /*   8/ 17 Azerbaijani (Azerbaijan) */
         "be", LANGUAGE_be_BY, /*   9/ 32 Belarusian (Belarus) */
-        "bg", LANGUAGE_bg,    /*   2/ 11 Bulgarian */
-        "ca", LANGUAGE_ca,    /*  11/116 Catalan */
+        "bg", LANGUAGE_bg,    /*   2/ 10 Bulgarian */
+        "ca", LANGUAGE_ca,    /*  11/115 Catalan */
         "cs", LANGUAGE_cs,    /*  17/ 21 Czech */
-        "da", LANGUAGE_da,    /*  19/ 34 Danish */
+        "da", LANGUAGE_da,    /*  19/ 33 Danish */
         "de", LANGUAGE_de,    /*  16/ 92 German */
-        "el", LANGUAGE_el,    /*   1/ 11 Greek */
-        "en", LANGUAGE_en,    /*   8/ 10 English */
-        "eo", LANGUAGE_eo,    /*  26/128 Esperanto */
-        "es", LANGUAGE_es,    /*   8/ 33 Spanish */
+        "el", LANGUAGE_el,    /*   1/ 10 Greek */
+        "en", LANGUAGE_en,    /*   8/ 11 English */
+        "eo", LANGUAGE_eo,    /*  26/127 Esperanto */
+        "es", LANGUAGE_es,    /*   8/ 56 Spanish */
         "et", LANGUAGE_et_EE, /*  22/ 27 Estonian (Estonia) */
-        "fa", LANGUAGE_fa,    /*  61/119 Persian */
-        "fi", LANGUAGE_fi,    /*  10/ 34 Finnish */
+        "eu", LANGUAGE_eu_ES, /*   7/  8 Basque (Spain) */
+        "fa", LANGUAGE_fa,    /*  59/118 Persian */
+        "fi", LANGUAGE_fi,    /*  10/ 33 Finnish */
         "fr", LANGUAGE_fr,    /*  13/ 92 French */
-        "hi", LANGUAGE_hi,    /*  24/ 56 Hindi */
+        "gl", LANGUAGE_gl_ES, /*   7/  8 Gallegan (Spain) */
+        "hi", LANGUAGE_hi,    /*  24/ 55 Hindi */
         "hr", LANGUAGE_hr,    /*   9/ 19 Croatian */
         "hu", LANGUAGE_hu,    /*   9/ 19 Hungarian */
-        "hy", LANGUAGE_hy_AM, /*   8/122 Armenian (Armenia) */
+        "hy", LANGUAGE_hy_AM, /*   8/121 Armenian (Armenia) */
         "is", LANGUAGE_is,    /*  10/ 15 Icelandic */
         "it", LANGUAGE_it,    /*   5/  5 Italian */
-        "iw", LANGUAGE_iw,    /*  20/117 Hebrew */
-        "ka", LANGUAGE_ka_GE, /*   3/ 11 Georgian (Georgia) */
-        "kk", LANGUAGE_kk,    /*  15/114 Kazakh */
-        "km", LANGUAGE_km_KH, /*   2/115 Khmer (Cambodia) */
+        "iw", LANGUAGE_iw,    /*  20/116 Hebrew */
+        "ka", LANGUAGE_ka_GE, /*   3/ 10 Georgian (Georgia) */
+        "kk", LANGUAGE_kk,    /*  15/113 Kazakh */
+        "km", LANGUAGE_km_KH, /*   2/114 Khmer (Cambodia) */
         "ky", LANGUAGE_ky,    /*  10/ 81 Kirghiz */
         "lo", LANGUAGE_lo_LA, /*   2/ 20 Lao (Laos) */
         "lt", LANGUAGE_lt,    /*  18/ 22 Lithuanian */
         "lv", LANGUAGE_lv,    /*  18/ 22 Latvian */
         "mk", LANGUAGE_mk,    /*   9/ 86 Macedonian */
         "mn", LANGUAGE_mn_MN, /*   2/ 20 Mongolian (Mongolia) */
-        "nb", LANGUAGE_nb,    /*  11/ 34 Norwegian Bokmål */
-        "ne", LANGUAGE_ne_NP, /*  24/ 56 Nepali (Nepal) */
+        "my", LANGUAGE_my_MM, /*   1/ 10 Burmese (Myanmar) */
+        "nb", LANGUAGE_nb,    /*  11/ 33 Norwegian Bokmål */
+        "ne", LANGUAGE_ne_NP, /*  24/ 55 Nepali (Nepal) */
         "nl", LANGUAGE_nl,    /*   9/ 12 Dutch */
         "pl", LANGUAGE_pl,    /*  10/ 16 Polish */
-        "pt", LANGUAGE_pt,    /*   6/  8 Portuguese */
+        "pt", LANGUAGE_pt,    /*   6/  6 Portuguese */
         "rm", LANGUAGE_rm,    /*   1/  2 Raeto-Romance */
         "ro", LANGUAGE_ro,    /*   6/ 15 Romanian */
         "ru", LANGUAGE_ru,    /*   9/ 32 Russian */
         "sk", LANGUAGE_sk,    /*  20/ 22 Slovak */
         "sl", LANGUAGE_sl,    /*   8/ 19 Slovenian */
         "sr", LANGUAGE_sr,    /*  11/ 86 Serbian */
-        "sv", LANGUAGE_sv,    /*  21/ 34 Swedish */
+        "sv", LANGUAGE_sv,    /*  21/ 33 Swedish */
         "sw", LANGUAGE_sw,    /*   9/ 17 Swahili */
         "th", LANGUAGE_th,    /*   2/ 20 Thai */
-        "tl", LANGUAGE_tl,    /*   7/ 10 Tagalog */
+        "tl", LANGUAGE_tl,    /*   7/  8 Tagalog */
         "tr", LANGUAGE_tr,    /*   7/ 17 Turkish */
         "uk", LANGUAGE_uk,    /*  11/ 80 Ukrainian */
         "vi", LANGUAGE_vi,    /*   8/ 20 Vietnamese */
-        "zu", LANGUAGE_zu,    /*   8/ 10 Zulu */
-        "zz", LANGUAGE_zz,    /*  19/111 Alphabet */
+        "zu", LANGUAGE_zu,    /*   8/ 11 Zulu */
+        "zz", LANGUAGE_zz,    /*  19/110 Alphabet */
     };
 
     static {
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 544fd03..0aa34e8 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -161,9 +161,9 @@
     private static native int getNextWordNative(long dict, int token, int[] outCodePoints);
     private static native void getSuggestionsNative(long dict, long proximityInfo,
             long traverseSession, int[] xCoordinates, int[] yCoordinates, int[] times,
-            int[] pointerIds, int[] inputCodePoints, int inputSize, int commitPoint,
-            int[] suggestOptions, int[] prevWordCodePointArray, int[] outputSuggestionCount,
-            int[] outputCodePoints, int[] outputScores, int[] outputIndices, int[] outputTypes,
+            int[] pointerIds, int[] inputCodePoints, int inputSize, int[] suggestOptions,
+            int[] prevWordCodePointArray, int[] outputSuggestionCount, int[] outputCodePoints,
+            int[] outputScores, int[] outputIndices, int[] outputTypes,
             int[] outputAutoCommitFirstWordConfidence);
     private static native void addUnigramWordNative(long dict, int[] word, int probability,
             int[] shortcutTarget, int shortcutProbability, boolean isNotAWord,
@@ -262,7 +262,7 @@
         getSuggestionsNative(mNativeDict, proximityInfo.getNativeProximityInfo(),
                 getTraverseSession(sessionId).getSession(), ips.getXCoordinates(),
                 ips.getYCoordinates(), ips.getTimes(), ips.getPointerIds(), mInputCodePoints,
-                inputSize, 0 /* commitPoint */, mNativeSuggestOptions.getOptions(),
+                inputSize, mNativeSuggestOptions.getOptions(),
                 prevWordCodePointArray, mOutputSuggestionCount, mOutputCodePoints, mOutputScores,
                 mSpaceIndices, mOutputTypes, mOutputAutoCommitFirstWordConfidence);
         final int count = mOutputSuggestionCount[0];
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 4a18c2b..38e3864 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -169,8 +169,6 @@
 
         private int mDelayUpdateSuggestions;
         private int mDelayUpdateShiftState;
-        private long mDoubleSpacePeriodTimeout;
-        private long mDoubleSpacePeriodTimerStart;
 
         public UIHandler(final LatinIME ownerInstance) {
             super(ownerInstance);
@@ -184,8 +182,6 @@
             final Resources res = latinIme.getResources();
             mDelayUpdateSuggestions = res.getInteger(R.integer.config_delay_update_suggestions);
             mDelayUpdateShiftState = res.getInteger(R.integer.config_delay_update_shift_state);
-            mDoubleSpacePeriodTimeout =
-                    res.getInteger(R.integer.config_double_space_period_timeout);
         }
 
         @Override
@@ -286,10 +282,6 @@
             sendMessageDelayed(obtainMessage(MSG_UPDATE_SHIFT_STATE), mDelayUpdateShiftState);
         }
 
-        public void cancelUpdateShiftState() {
-            removeMessages(MSG_UPDATE_SHIFT_STATE);
-        }
-
         @UsedForTesting
         public void removeAllMessages() {
             for (int i = 0; i <= MSG_LAST; ++i) {
@@ -317,19 +309,6 @@
             obtainMessage(MSG_ON_END_BATCH_INPUT, suggestedWords).sendToTarget();
         }
 
-        public void startDoubleSpacePeriodTimer() {
-            mDoubleSpacePeriodTimerStart = SystemClock.uptimeMillis();
-        }
-
-        public void cancelDoubleSpacePeriodTimer() {
-            mDoubleSpacePeriodTimerStart = 0;
-        }
-
-        public boolean isAcceptingDoubleSpacePeriod() {
-            return SystemClock.uptimeMillis() - mDoubleSpacePeriodTimerStart
-                    < mDoubleSpacePeriodTimeout;
-        }
-
         // Working variables for the following methods.
         private boolean mIsOrientationChanging;
         private boolean mPendingSuccessiveImsCallback;
@@ -885,7 +864,6 @@
         setNeutralSuggestionStrip();
 
         mHandler.cancelUpdateSuggestionStrip();
-        mHandler.cancelDoubleSpacePeriodTimer();
 
         mainKeyboardView.setMainDictionaryAvailability(null != suggest
                 ? suggest.mDictionaryFacilitator.hasMainDictionary() : false);
@@ -1276,15 +1254,7 @@
         final InputTransaction completeInputTransaction =
                 mInputLogic.onCodeInput(mSettings.getCurrent(), event,
                         mKeyboardSwitcher.getKeyboardShiftMode(), mHandler);
-        switch (completeInputTransaction.getRequiredShiftUpdate()) {
-            case InputTransaction.SHIFT_UPDATE_LATER:
-                mHandler.postUpdateShiftState();
-                break;
-            case InputTransaction.SHIFT_UPDATE_NOW:
-                mKeyboardSwitcher.updateShiftState();
-                break;
-            default: // SHIFT_NO_UPDATE
-        }
+        updateShiftModeAfterInputTransaction(completeInputTransaction.getRequiredShiftUpdate());
         mKeyboardSwitcher.onCodeInput(codePoint);
     }
 
@@ -1307,7 +1277,9 @@
     // Called from PointerTracker through the KeyboardActionListener interface
     @Override
     public void onTextInput(final String rawText) {
-        mInputLogic.onTextInput(mSettings.getCurrent(), rawText, mHandler);
+        // 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.updateShiftState();
         mKeyboardSwitcher.onCodeInput(Constants.CODE_OUTPUT_TEXT);
     }
@@ -1500,8 +1472,10 @@
     // interface
     @Override
     public void pickSuggestionManually(final int index, final SuggestedWordInfo suggestionInfo) {
-        mInputLogic.onPickSuggestionManually(mSettings.getCurrent(), index, suggestionInfo,
-                mHandler, mKeyboardSwitcher);
+        final InputTransaction completeInputTransaction = mInputLogic.onPickSuggestionManually(
+                mSettings.getCurrent(), index, suggestionInfo,
+                mKeyboardSwitcher.getKeyboardShiftMode(), mHandler);
+        updateShiftModeAfterInputTransaction(completeInputTransaction.getRequiredShiftUpdate());
     }
 
     @Override
@@ -1539,6 +1513,18 @@
         }
     }
 
+    private void updateShiftModeAfterInputTransaction(final int requiredShiftUpdate) {
+        switch (requiredShiftUpdate) {
+        case InputTransaction.SHIFT_UPDATE_LATER:
+            mHandler.postUpdateShiftState();
+            break;
+        case InputTransaction.SHIFT_UPDATE_NOW:
+            mKeyboardSwitcher.updateShiftState();
+            break;
+        default: // SHIFT_NO_UPDATE
+        }
+    }
+
     private void hapticAndAudioFeedback(final int code, final int repeatCount) {
         final MainKeyboardView keyboardView = mKeyboardSwitcher.getMainKeyboardView();
         if (keyboardView != null && keyboardView.isInDraggingFinger()) {
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index 2ac11aa..29382fe 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -16,6 +16,7 @@
 
 package com.android.inputmethod.latin;
 
+import com.android.inputmethod.event.CombinerChain;
 import com.android.inputmethod.event.Event;
 import com.android.inputmethod.latin.utils.CollectionUtils;
 import com.android.inputmethod.latin.utils.CoordinateUtils;
@@ -40,6 +41,8 @@
     public static final int CAPS_MODE_AUTO_SHIFTED = 0x5;
     public static final int CAPS_MODE_AUTO_SHIFT_LOCKED = 0x7;
 
+    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,
@@ -87,6 +90,7 @@
     private boolean mIsFirstCharCapitalized;
 
     public WordComposer() {
+        mCombinerChain = new CombinerChain();
         mPrimaryKeyCodes = new int[MAX_WORD_LENGTH];
         mEvents = CollectionUtils.newArrayList();
         mTypedWord = new StringBuilder(MAX_WORD_LENGTH);
@@ -101,6 +105,7 @@
     }
 
     public WordComposer(final WordComposer source) {
+        mCombinerChain = source.mCombinerChain;
         mPrimaryKeyCodes = Arrays.copyOf(source.mPrimaryKeyCodes, source.mPrimaryKeyCodes.length);
         mEvents = new ArrayList<Event>(source.mEvents);
         mTypedWord = new StringBuilder(source.mTypedWord);
@@ -187,6 +192,7 @@
         final int keyX = event.mX;
         final int keyY = event.mY;
         final int newIndex = size();
+        mCombinerChain.processEvent(mEvents, event);
         mTypedWord.appendCodePoint(primaryCode);
         mEvents.add(event);
         refreshSize();
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index fa7c4b4..36b30ea 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -28,7 +28,6 @@
 
 import com.android.inputmethod.compat.SuggestionSpanUtils;
 import com.android.inputmethod.event.Event;
-import com.android.inputmethod.event.EventInterpreter;
 import com.android.inputmethod.event.InputTransaction;
 import com.android.inputmethod.keyboard.KeyboardSwitcher;
 import com.android.inputmethod.latin.Constants;
@@ -96,6 +95,7 @@
     // TODO: This boolean is persistent state and causes large side effects at unexpected times.
     // Find a way to remove it for readability.
     private boolean mIsAutoCorrectionIndicatorOn;
+    private long mDoubleSpacePeriodCountdownStart;
 
     public InputLogic(final LatinIME latinIME,
             final SuggestionStripViewAccessor suggestionStripViewAccessor) {
@@ -138,6 +138,7 @@
         // In some cases (namely, after rotation of the device) editorInfo.initialSelStart is lying
         // so we try using some heuristics to find out about these and fix them.
         mConnection.tryFixLyingCursorPosition();
+        cancelDoubleSpacePeriodCountdown();
         mInputLogicHandler = new InputLogicHandler(mLatinIME, this);
     }
 
@@ -160,11 +161,12 @@
      * some additional keys for example.
      *
      * @param settingsValues the current values of the settings.
-     * @param rawText the text to input.
+     * @param event the input event containing the data.
      */
-    public void onTextInput(final SettingsValues settingsValues, final String rawText,
+    public void onTextInput(final SettingsValues settingsValues, final Event event,
             // TODO: remove this argument
             final LatinIME.UIHandler handler) {
+        final String rawText = event.mText.toString();
         mConnection.beginBatchEdit();
         if (mWordComposer.isComposingWord()) {
             commitCurrentAutoCorrection(settingsValues, rawText, handler);
@@ -196,13 +198,16 @@
      * @param settingsValues the current values of the settings.
      * @param index the index of the suggestion.
      * @param suggestionInfo the suggestion info.
+     * @param keyboardShiftState the shift state of the keyboard, as returned by
+     *     {@link com.android.inputmethod.keyboard.KeyboardSwitcher#getKeyboardShiftMode()}
+     * @return the complete transaction object
      */
     // Called from {@link SuggestionStripView} through the {@link SuggestionStripView#Listener}
     // interface
-    public void onPickSuggestionManually(final SettingsValues settingsValues,
-            final int index, final SuggestedWordInfo suggestionInfo,
-            // TODO: remove these two arguments
-            final LatinIME.UIHandler handler, final KeyboardSwitcher keyboardSwitcher) {
+    public InputTransaction onPickSuggestionManually(final SettingsValues settingsValues,
+            final int index, final SuggestedWordInfo suggestionInfo, final int keyboardShiftState,
+            // TODO: remove this argument
+            final LatinIME.UIHandler handler) {
         final SuggestedWords suggestedWords = mSuggestedWords;
         final String suggestion = suggestionInfo.mWord;
         // If this is a punctuation picked from the suggestion strip, pass it to onCodeInput
@@ -212,16 +217,26 @@
             LatinImeLogger.logOnManualSuggestion("", suggestion, index, suggestedWords);
             // Rely on onCodeInput to do the complicated swapping/stripping logic consistently.
             final int primaryCode = suggestion.charAt(0);
-            final Event event = Event.createSoftwareKeypressEvent(primaryCode, Event.NOT_A_KEY_CODE,
-                    Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE);
-            onCodeInput(settingsValues, event, keyboardSwitcher.getKeyboardShiftMode(), handler);
+            // TODO: we should be using createSuggestionPickedEvent here, but for legacy reasons,
+            // onCodeInput is expected a software keypress event for a suggested punctuation
+            // because the current code is descended from a time where this information used not
+            // to be available. Fix this.
+            final Event event = Event.createSoftwareKeypressEvent(primaryCode,
+                    Event.NOT_A_KEY_CODE /* keyCode*/,
+                    Constants.SUGGESTION_STRIP_COORDINATE /* x */,
+                    Constants.SUGGESTION_STRIP_COORDINATE /* y */);
+            final InputTransaction completeTransaction = onCodeInput(settingsValues, event,
+                    keyboardShiftState, handler);
             if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
                 ResearchLogger.latinIME_punctuationSuggestion(index, suggestion,
                         false /* isBatchMode */, suggestedWords.mIsPrediction);
             }
-            return;
+            return completeTransaction;
         }
 
+        final Event event = Event.createSuggestionPickedEvent(suggestionInfo);
+        final InputTransaction inputTransaction = new InputTransaction(settingsValues,
+                event, SystemClock.uptimeMillis(), mSpaceState, keyboardShiftState);
         mConnection.beginBatchEdit();
         if (SpaceState.PHANTOM == mSpaceState && suggestion.length() > 0
                 // In the batch input mode, a manually picked suggested word should just replace
@@ -241,11 +256,11 @@
         if (SuggestedWordInfo.KIND_APP_DEFINED == suggestionInfo.mKind) {
             mSuggestedWords = SuggestedWords.EMPTY;
             mSuggestionStripViewAccessor.setNeutralSuggestionStrip();
-            keyboardSwitcher.updateShiftState();
+            inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
             resetComposingState(true /* alsoResetLastComposedWord */);
             mConnection.commitCompletion(suggestionInfo.mApplicationSpecifiedCompletionInfo);
             mConnection.endBatchEdit();
-            return;
+            return inputTransaction;
         }
 
         // We need to log before we commit, because the word composer will store away the user
@@ -264,7 +279,7 @@
         mLastComposedWord.deactivate();
         // Space state must be updated before calling updateShiftState
         mSpaceState = SpaceState.PHANTOM;
-        keyboardSwitcher.updateShiftState();
+        inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
 
         // We should show the "Touch again to save" hint if the user pressed the first entry
         // AND it's in none of our current dictionaries (main, user or otherwise).
@@ -290,6 +305,7 @@
             // If we're not showing the "Touch again to save", then update the suggestion strip.
             handler.postUpdateSuggestionStrip();
         }
+        return inputTransaction;
     }
 
     /**
@@ -392,7 +408,7 @@
 
         // TODO: Consolidate the double-space period timer, mLastKeyTime, and the space state.
         if (event.mCodePoint != Constants.CODE_SPACE) {
-            handler.cancelDoubleSpacePeriodTimer();
+            cancelDoubleSpacePeriodCountdown();
         }
 
         boolean didAutoCorrect = false;
@@ -833,7 +849,7 @@
 
         if (Constants.CODE_SPACE == codePoint) {
             if (inputTransaction.mSettingsValues.isSuggestionsRequested()) {
-                if (maybeDoubleSpacePeriod(inputTransaction.mSettingsValues, handler)) {
+                if (maybeDoubleSpacePeriod(inputTransaction)) {
                     inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
                     mSpaceState = SpaceState.DOUBLE;
                 } else if (!mSuggestedWords.isPunctuationSuggestions()) {
@@ -841,7 +857,7 @@
                 }
             }
 
-            handler.startDoubleSpacePeriodTimer();
+            startDoubleSpacePeriodCountdown(inputTransaction);
             handler.postUpdateSuggestionStrip();
         } else {
             if (swapWeakSpace) {
@@ -938,7 +954,7 @@
                 return;
             }
             if (SpaceState.DOUBLE == inputTransaction.mSpaceState) {
-                handler.cancelDoubleSpacePeriodTimer();
+                cancelDoubleSpacePeriodCountdown();
                 if (mConnection.revertDoubleSpacePeriod()) {
                     // No need to reset mSpaceState, it has already be done (that's why we
                     // receive it as a parameter)
@@ -1086,6 +1102,19 @@
         return false;
     }
 
+    public void startDoubleSpacePeriodCountdown(final InputTransaction inputTransaction) {
+        mDoubleSpacePeriodCountdownStart = inputTransaction.mTimestamp;
+    }
+
+    public void cancelDoubleSpacePeriodCountdown() {
+        mDoubleSpacePeriodCountdownStart = 0;
+    }
+
+    public boolean isDoubleSpacePeriodCountdownActive(final InputTransaction inputTransaction) {
+        return inputTransaction.mTimestamp - mDoubleSpacePeriodCountdownStart
+                < inputTransaction.mSettingsValues.mDoubleSpacePeriodTimeout;
+    }
+
     /**
      * Apply the double-space-to-period transformation if applicable.
      *
@@ -1098,14 +1127,12 @@
      * method applies the transformation and returns true. Otherwise, it does nothing and
      * returns false.
      *
-     * @param settingsValues the current values of the settings.
+     * @param inputTransaction The transaction in progress.
      * @return true if we applied the double-space-to-period transformation, false otherwise.
      */
-    private boolean maybeDoubleSpacePeriod(final SettingsValues settingsValues,
-            // TODO: remove this argument
-            final LatinIME.UIHandler handler) {
-        if (!settingsValues.mUseDoubleSpacePeriod) return false;
-        if (!handler.isAcceptingDoubleSpacePeriod()) return false;
+    private boolean maybeDoubleSpacePeriod(final InputTransaction inputTransaction) {
+        if (!inputTransaction.mSettingsValues.mUseDoubleSpacePeriod) return false;
+        if (!isDoubleSpacePeriodCountdownActive(inputTransaction)) return false;
         // We only do this when we see two spaces and an accepted code point before the cursor.
         // The code point may be a surrogate pair but the two spaces may not, so we need 4 chars.
         final CharSequence lastThree = mConnection.getTextBeforeCursor(4, 0);
@@ -1121,10 +1148,10 @@
                 Character.isSurrogatePair(lastThree.charAt(0), lastThree.charAt(1)) ?
                         Character.codePointAt(lastThree, 0) : lastThree.charAt(length - 3);
         if (canBeFollowedByDoubleSpacePeriod(firstCodePoint)) {
-            handler.cancelDoubleSpacePeriodTimer();
+            cancelDoubleSpacePeriodCountdown();
             mConnection.deleteSurroundingText(2, 0);
-            final String textToInsert =
-                    settingsValues.mSpacingAndPunctuations.mSentenceSeparatorAndSpace;
+            final String textToInsert = inputTransaction.mSettingsValues.mSpacingAndPunctuations
+                    .mSentenceSeparatorAndSpace;
             mConnection.commitText(textToInsert, 1);
             if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
                 ResearchLogger.latinIME_maybeDoubleSpacePeriod(textToInsert,
diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java
index b51c765..964bf22 100644
--- a/java/src/com/android/inputmethod/latin/settings/Settings.java
+++ b/java/src/com/android/inputmethod/latin/settings/Settings.java
@@ -23,6 +23,7 @@
 import android.preference.PreferenceManager;
 import android.util.Log;
 
+import com.android.inputmethod.keyboard.KeyboardSwitcher;
 import com.android.inputmethod.latin.AudioAndHapticFeedbackManager;
 import com.android.inputmethod.latin.InputAttributes;
 import com.android.inputmethod.latin.R;
@@ -270,25 +271,36 @@
     }
 
     public static int readKeyboardThemeIndex(final SharedPreferences prefs, final Resources res) {
-        final String defaultThemeIndex = res.getString(
-                R.string.config_default_keyboard_theme_index);
-        final String themeIndex = prefs.getString(PREF_KEYBOARD_LAYOUT, defaultThemeIndex);
+        final int defaultThemeIndex = readDefaultKeyboardThemeIndex(res);
+        final String themeIndexString = prefs.getString(PREF_KEYBOARD_LAYOUT, null);
         try {
-            return Integer.valueOf(themeIndex);
+            return Integer.parseInt(themeIndexString);
         } catch (final NumberFormatException e) {
             // Format error, returns default keyboard theme index.
-            Log.e(TAG, "Illegal keyboard theme in preference: " + themeIndex + ", default to "
+            Log.e(TAG, "Illegal keyboard theme in preference: " + themeIndexString + ", default to "
                     + defaultThemeIndex, e);
-            return Integer.valueOf(defaultThemeIndex);
+        }
+        return defaultThemeIndex;
+    }
+
+    private static int readDefaultKeyboardThemeIndex(final Resources res) {
+        final String defaultThemeIndexString = res.getString(
+                R.string.config_default_keyboard_theme_index);
+        try {
+            return Integer.parseInt(defaultThemeIndexString);
+        } catch (final NumberFormatException e) {
+            final int defaultThemeIndex = KeyboardSwitcher.DEFAULT_THEME_INDEX;
+            Log.e(TAG, "Corrupted default keyoard theme in resource: " + defaultThemeIndexString
+                    + ", default to " + defaultThemeIndex, e);
+            return defaultThemeIndex;
         }
     }
 
     public static int resetAndGetDefaultKeyboardThemeIndex(final SharedPreferences prefs,
             final Resources res) {
-        final String defaultThemeIndex = res.getString(
-                R.string.config_default_keyboard_theme_index);
-        prefs.edit().putString(PREF_KEYBOARD_LAYOUT, defaultThemeIndex).apply();
-        return Integer.valueOf(defaultThemeIndex);
+        final int defaultThemeIndex = readDefaultKeyboardThemeIndex(res);
+        prefs.edit().putString(PREF_KEYBOARD_LAYOUT, Integer.toString(defaultThemeIndex)).apply();
+        return defaultThemeIndex;
     }
 
     public static String readPrefAdditionalSubtypes(final SharedPreferences prefs,
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
index 50fbbb1..d47a61e 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
@@ -50,6 +50,7 @@
     // From resources:
     public final SpacingAndPunctuations mSpacingAndPunctuations;
     public final int mDelayUpdateOldSuggestions;
+    public final long mDoubleSpacePeriodTimeout;
 
     // From preferences, in the same order as xml/prefs.xml:
     public final boolean mAutoCap;
@@ -132,6 +133,7 @@
         mBlockPotentiallyOffensive = Settings.readBlockPotentiallyOffensive(prefs, res);
         mAutoCorrectEnabled = Settings.readAutoCorrectEnabled(autoCorrectionThresholdRawValue, res);
         mBigramPredictionEnabled = readBigramPredictionEnabled(prefs, res);
+        mDoubleSpacePeriodTimeout = res.getInteger(R.integer.config_double_space_period_timeout);
 
         // Compute other readable settings
         mKeyLongpressTimeout = Settings.readKeyLongpressTimeout(prefs, res);
@@ -285,7 +287,7 @@
         // When autoCorrectionThreshold is greater than 1.0, it's like auto correction is off.
         final float autoCorrectionThreshold;
         try {
-            final int arrayIndex = Integer.valueOf(currentAutoCorrectionSetting);
+            final int arrayIndex = Integer.parseInt(currentAutoCorrectionSetting);
             if (arrayIndex >= 0 && arrayIndex < autoCorrectionThresholdValues.length) {
                 final String val = autoCorrectionThresholdValues[arrayIndex];
                 if (FLOAT_MAX_VALUE_MARKER_STRING.equals(val)) {
diff --git a/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java b/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java
index 5954758..796921f 100644
--- a/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java
+++ b/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java
@@ -18,7 +18,6 @@
 
 import android.content.res.Resources;
 
-import com.android.inputmethod.keyboard.internal.KeyboardTextsSet;
 import com.android.inputmethod.keyboard.internal.MoreKeySpec;
 import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.PunctuationSuggestions;
@@ -61,10 +60,8 @@
         // English variants. German rules (not "German typography") also have small gotchas.
         mUsesAmericanTypography = Locale.ENGLISH.getLanguage().equals(locale.getLanguage());
         mUsesGermanRules = Locale.GERMAN.getLanguage().equals(locale.getLanguage());
-        final KeyboardTextsSet textsSet = new KeyboardTextsSet();
-        textsSet.setLocale(locale);
         final String[] suggestPuncsSpec = MoreKeySpec.splitKeySpecs(
-                textsSet.resolveTextReference(res.getString(R.string.suggested_punctuations)));
+                res.getString(R.string.suggested_punctuations));
         mSuggestPuncList = PunctuationSuggestions.newPunctuationSuggestions(suggestPuncsSpec);
     }
 
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
index c26e223..1d84bb5 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
@@ -507,7 +507,7 @@
                 hintView, 1.0f - mCenterSuggestionWeight, ViewGroup.LayoutParams.MATCH_PARENT);
     }
 
-    public void layoutImportantNotice(final View importantNoticeStrip, final int stripWidth,
+    public void layoutImportantNotice(final View importantNoticeStrip,
             final String importantNoticeTitle) {
         final TextView titleView = (TextView)importantNoticeStrip.findViewById(
                 R.id.important_notice_title);
@@ -516,8 +516,7 @@
         titleView.setTextColor(mColorAutoCorrect);
         titleView.setText(importantNoticeTitle);
         titleView.setTextScaleX(1.0f); // Reset textScaleX.
-        final float titleScaleX = getTextScaleX(
-                importantNoticeTitle, width, titleView.getPaint());
+        final float titleScaleX = getTextScaleX(importantNoticeTitle, width, titleView.getPaint());
         titleView.setTextScaleX(titleScaleX);
     }
 
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
index 43cb11b..3cdd073 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
@@ -232,8 +232,7 @@
         if (!ImportantNoticeUtils.shouldShowImportantNotice(getContext(), inputAttributes)) {
             return false;
         }
-        final int width = getWidth();
-        if (width <= 0) {
+        if (getWidth() <= 0) {
             return false;
         }
         final String importantNoticeTitle = ImportantNoticeUtils.getNextImportantNoticeTitle(
@@ -241,7 +240,7 @@
         if (TextUtils.isEmpty(importantNoticeTitle)) {
             return false;
         }
-        mLayoutHelper.layoutImportantNotice(mImportantNoticeStrip, width, importantNoticeTitle);
+        mLayoutHelper.layoutImportantNotice(mImportantNoticeStrip, importantNoticeTitle);
         mStripVisibilityGroup.showImportantNoticeStrip();
         mImportantNoticeStrip.setOnClickListener(this);
         return true;
diff --git a/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java b/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java
index ca8bef3..7d937a9 100644
--- a/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java
@@ -20,6 +20,7 @@
 import android.content.SharedPreferences;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
+import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.inputmethod.latin.InputAttributes;
@@ -82,7 +83,17 @@
         if (inputAttributes == null || inputAttributes.mIsPasswordField) {
             return false;
         }
-        return hasNewImportantNotice(context) && !isInSystemSetupWizard(context);
+        if (isInSystemSetupWizard(context)) {
+            return false;
+        }
+        if (!hasNewImportantNotice(context)) {
+            return false;
+        }
+        final String importantNoticeTitle = getNextImportantNoticeTitle(context);
+        if (TextUtils.isEmpty(importantNoticeTitle)) {
+            return false;
+        }
+        return true;
     }
 
     public static void updateLastImportantNoticeVersion(final Context context) {
diff --git a/native/jni/Android.mk b/native/jni/Android.mk
index 9657b9d..afb32d1 100644
--- a/native/jni/Android.mk
+++ b/native/jni/Android.mk
@@ -29,7 +29,7 @@
 
 LOCAL_CFLAGS += -Werror -Wall -Wextra -Weffc++ -Wformat=2 -Wcast-qual -Wcast-align \
     -Wwrite-strings -Wfloat-equal -Wpointer-arith -Winit-self -Wredundant-decls \
-    -Woverloaded-virtual -Wstrict-null-sentinel -Wsign-promo -Wno-system-headers
+    -Woverloaded-virtual -Wsign-promo -Wno-system-headers
 
 # To suppress compiler warnings for unused variables/functions used for debug features etc.
 LOCAL_CFLAGS += -Wno-unused-parameter -Wno-unused-function
@@ -60,8 +60,9 @@
 LOCAL_MODULE := libjni_latinime_common_static
 LOCAL_MODULE_TAGS := optional
 
+LOCAL_CLANG := true
 LOCAL_SDK_VERSION := 14
-LOCAL_NDK_STL_VARIANT := gnustl_static
+LOCAL_NDK_STL_VARIANT := c++_static
 
 include $(BUILD_STATIC_LIBRARY)
 ######################################
@@ -83,8 +84,9 @@
 LOCAL_MODULE := libjni_latinime
 LOCAL_MODULE_TAGS := optional
 
+LOCAL_CLANG := true
 LOCAL_SDK_VERSION := 14
-LOCAL_NDK_STL_VARIANT := gnustl_static
+LOCAL_NDK_STL_VARIANT := c++_static
 LOCAL_LDFLAGS += -ldl
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
index eec354a..ac0b4ab 100644
--- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
+++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
@@ -143,7 +143,7 @@
 static void latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jclass clazz, jlong dict,
         jlong proximityInfo, jlong dicTraverseSession, jintArray xCoordinatesArray,
         jintArray yCoordinatesArray, jintArray timesArray, jintArray pointerIdsArray,
-        jintArray inputCodePointsArray, jint inputSize, jint commitPoint, jintArray suggestOptions,
+        jintArray inputCodePointsArray, jint inputSize, jintArray suggestOptions,
         jintArray prevWordCodePointsForBigrams, jintArray outSuggestionCount,
         jintArray outCodePointsArray, jintArray outScoresArray, jintArray outSpaceIndicesArray,
         jintArray outTypesArray, jintArray outAutoCommitFirstWordConfidenceArray) {
@@ -220,7 +220,7 @@
         // TODO: Use SuggestionResults to return suggestions.
         count = dictionary->getSuggestions(pInfo, traverseSession, xCoordinates, yCoordinates,
                 times, pointerIds, inputCodePoints, inputSize, prevWordCodePoints,
-                prevWordCodePointsLength, commitPoint, &givenSuggestOptions, outputCodePoints,
+                prevWordCodePointsLength, &givenSuggestOptions, outputCodePoints,
                 scores, spaceIndices, outputTypes, outputAutoCommitFirstWordConfidence);
     } else {
         SuggestionResults suggestionResults(MAX_RESULTS);
@@ -506,7 +506,7 @@
     },
     {
         const_cast<char *>("getSuggestionsNative"),
-        const_cast<char *>("(JJJ[I[I[I[I[III[I[I[I[I[I[I[I[I)V"),
+        const_cast<char *>("(JJJ[I[I[I[I[II[I[I[I[I[I[I[I[I)V"),
         reinterpret_cast<void *>(latinime_BinaryDictionary_getSuggestions)
     },
     {
diff --git a/native/jni/src/suggest/core/dicnode/dic_node.h b/native/jni/src/suggest/core/dicnode/dic_node.h
index 65dad56..ae228fb 100644
--- a/native/jni/src/suggest/core/dicnode/dic_node.h
+++ b/native/jni/src/suggest/core/dicnode/dic_node.h
@@ -270,9 +270,10 @@
 
     bool hasMatchedOrProximityCodePoints() const {
         // This DicNode does not have matched or proximity code points when all code points have
-        // been handled as edit corrections so far.
-        return mDicNodeState.mDicNodeStateScoring.getEditCorrectionCount()
-                < getNodeCodePointCount();
+        // been handled as edit corrections or completion so far.
+        const int editCorrectionCount = mDicNodeState.mDicNodeStateScoring.getEditCorrectionCount();
+        const int completionCount = mDicNodeState.mDicNodeStateScoring.getCompletionCount();
+        return (editCorrectionCount + completionCount) < getNodeCodePointCount();
     }
 
     bool isTotalInputSizeExceedingLimit() const {
@@ -283,33 +284,6 @@
         return prevWordsLen + currentWordDepth > MAX_WORD_LENGTH - 3;
     }
 
-    // TODO: This may be defective. Needs to be revised.
-    bool truncateNode(const DicNode *const topNode, const int inputCommitPoint) {
-        const int prevWordLenOfTop = mDicNodeState.mDicNodeStatePrevWord.getPrevWordLength();
-        int newPrevWordStartIndex = inputCommitPoint;
-        int charCount = 0;
-        // Find new word start index
-        for (int i = 0; i < prevWordLenOfTop; ++i) {
-            const int c = mDicNodeState.mDicNodeStatePrevWord.getPrevWordCodePointAt(i);
-            // TODO: Check other separators.
-            if (c != KEYCODE_SPACE && c != KEYCODE_SINGLE_QUOTE) {
-                if (charCount == inputCommitPoint) {
-                    newPrevWordStartIndex = i;
-                    break;
-                }
-                ++charCount;
-            }
-        }
-        if (!mDicNodeState.mDicNodeStatePrevWord.startsWith(
-                &topNode->mDicNodeState.mDicNodeStatePrevWord, newPrevWordStartIndex - 1)) {
-            // Node mismatch.
-            return false;
-        }
-        mDicNodeState.mDicNodeStateInput.truncate(inputCommitPoint);
-        mDicNodeState.mDicNodeStatePrevWord.truncate(newPrevWordStartIndex);
-        return true;
-    }
-
     void outputResult(int *dest) const {
         const uint16_t prevWordLength = mDicNodeState.mDicNodeStatePrevWord.getPrevWordLength();
         const uint16_t currentDepth = getNodeCodePointCount();
diff --git a/native/jni/src/suggest/core/dicnode/dic_nodes_cache.cpp b/native/jni/src/suggest/core/dicnode/dic_nodes_cache.cpp
index b6be47e..ef4a6b5 100644
--- a/native/jni/src/suggest/core/dicnode/dic_nodes_cache.cpp
+++ b/native/jni/src/suggest/core/dicnode/dic_nodes_cache.cpp
@@ -28,37 +28,4 @@
 // Capacity for reducing memory footprint.
 const int DicNodesCache::SMALL_PRIORITY_QUEUE_CAPACITY = 100;
 
-/**
- * Truncates all of the dicNodes so that they start at the given commit point.
- * Only called for multi-word typing input.
- */
-DicNode *DicNodesCache::setCommitPoint(int commitPoint) {
-    std::list<DicNode> dicNodesList;
-    while (mCachedDicNodesForContinuousSuggestion->getSize() > 0) {
-        DicNode dicNode;
-        mCachedDicNodesForContinuousSuggestion->copyPop(&dicNode);
-        dicNodesList.push_front(dicNode);
-    }
-
-    // Get the starting words of the top scoring dicNode (last dicNode popped from priority queue)
-    // up to the commit point. These words have already been committed to the text view.
-    DicNode *topDicNode = &dicNodesList.front();
-    DicNode topDicNodeCopy;
-    DicNodeUtils::initByCopy(topDicNode, &topDicNodeCopy);
-
-    // Keep only those dicNodes that match the same starting words.
-    std::list<DicNode>::iterator iter;
-    for (iter = dicNodesList.begin(); iter != dicNodesList.end(); iter++) {
-        DicNode *dicNode = &*iter;
-        if (dicNode->truncateNode(&topDicNodeCopy, commitPoint)) {
-            mCachedDicNodesForContinuousSuggestion->copyPush(dicNode);
-        } else {
-            // Top dicNode should be reprocessed.
-            ASSERT(dicNode != topDicNode);
-            DicNode::managedDelete(dicNode);
-        }
-    }
-    mInputIndex -= commitPoint;
-    return topDicNode;
-}
 }  // namespace latinime
diff --git a/native/jni/src/suggest/core/dicnode/dic_nodes_cache.h b/native/jni/src/suggest/core/dicnode/dic_nodes_cache.h
index c31c056..d4769e7 100644
--- a/native/jni/src/suggest/core/dicnode/dic_nodes_cache.h
+++ b/native/jni/src/suggest/core/dicnode/dic_nodes_cache.h
@@ -76,8 +76,6 @@
                 moveNodesAndReturnReusableEmptyQueue(mNextActiveDicNodes, &mActiveDicNodes);
     }
 
-    DicNode *setCommitPoint(int commitPoint);
-
     int activeSize() const { return mActiveDicNodes->getSize(); }
     int terminalSize() const { return mTerminalDicNodes->getSize(); }
     bool isLookAheadCorrectionInputIndex(const int inputIndex) const {
diff --git a/native/jni/src/suggest/core/dicnode/internal/dic_node_state_input.h b/native/jni/src/suggest/core/dicnode/internal/dic_node_state_input.h
index 3d78811..03042a8 100644
--- a/native/jni/src/suggest/core/dicnode/internal/dic_node_state_input.h
+++ b/native/jni/src/suggest/core/dicnode/internal/dic_node_state_input.h
@@ -27,11 +27,6 @@
     DicNodeStateInput() {}
     ~DicNodeStateInput() {}
 
-    // TODO: Merge into DicNodeStatePrevWord::truncate
-    void truncate(const int commitPoint) {
-        mInputIndex[0] -= commitPoint;
-    }
-
     void init() {
         for (int i = 0; i < MAX_POINTER_COUNT_G; i++) {
             // TODO: The initial value for mInputIndex should be -1?
diff --git a/native/jni/src/suggest/core/dicnode/internal/dic_node_state_prevword.h b/native/jni/src/suggest/core/dicnode/internal/dic_node_state_prevword.h
index f2b1ce8..409841e 100644
--- a/native/jni/src/suggest/core/dicnode/internal/dic_node_state_prevword.h
+++ b/native/jni/src/suggest/core/dicnode/internal/dic_node_state_prevword.h
@@ -70,18 +70,6 @@
         mSecondWordFirstInputIndex = prevWordSecondWordFirstInputIndex;
     }
 
-    void truncate(const int offset) {
-        // TODO: memmove
-        if (mPrevWordLength < offset) {
-            memset(mPrevWord, 0, sizeof(mPrevWord));
-            mPrevWordLength = 0;
-            return;
-        }
-        const int newPrevWordLength = mPrevWordLength - offset;
-        memmove(mPrevWord, &mPrevWord[offset], newPrevWordLength * sizeof(mPrevWord[0]));
-        mPrevWordLength = newPrevWordLength;
-    }
-
     void setSecondWordFirstInputIndex(const int inputIndex) {
         mSecondWordFirstInputIndex = inputIndex;
     }
@@ -111,18 +99,6 @@
         return mPrevWord[id];
     }
 
-    bool startsWith(const DicNodeStatePrevWord *const prefix, const int prefixLen) const {
-        if (prefixLen > mPrevWordLength) {
-            return false;
-        }
-        for (int i = 0; i < prefixLen; ++i) {
-            if (mPrevWord[i] != prefix->mPrevWord[i]) {
-                return false;
-            }
-        }
-        return true;
-    }
-
     const int *getPrevWordBuf() const {
         return mPrevWord;
     }
diff --git a/native/jni/src/suggest/core/dicnode/internal/dic_node_state_scoring.h b/native/jni/src/suggest/core/dicnode/internal/dic_node_state_scoring.h
index 458eac8..b0db55f 100644
--- a/native/jni/src/suggest/core/dicnode/internal/dic_node_state_scoring.h
+++ b/native/jni/src/suggest/core/dicnode/internal/dic_node_state_scoring.h
@@ -31,7 +31,7 @@
     AK_FORCE_INLINE DicNodeStateScoring()
             : mDoubleLetterLevel(NOT_A_DOUBLE_LETTER),
               mDigraphIndex(DigraphUtils::NOT_A_DIGRAPH_INDEX),
-              mEditCorrectionCount(0), mProximityCorrectionCount(0),
+              mEditCorrectionCount(0), mProximityCorrectionCount(0), mCompletionCount(0),
               mNormalizedCompoundDistance(0.0f), mSpatialDistance(0.0f), mLanguageDistance(0.0f),
               mRawLength(0.0f), mContainedErrorTypes(ErrorTypeUtils::NOT_AN_ERROR),
               mNormalizedCompoundDistanceAfterFirstWord(MAX_VALUE_FOR_WEIGHTING) {
@@ -42,6 +42,7 @@
     void init() {
         mEditCorrectionCount = 0;
         mProximityCorrectionCount = 0;
+        mCompletionCount = 0;
         mNormalizedCompoundDistance = 0.0f;
         mSpatialDistance = 0.0f;
         mLanguageDistance = 0.0f;
@@ -55,6 +56,7 @@
     AK_FORCE_INLINE void init(const DicNodeStateScoring *const scoring) {
         mEditCorrectionCount = scoring->mEditCorrectionCount;
         mProximityCorrectionCount = scoring->mProximityCorrectionCount;
+        mCompletionCount = scoring->mCompletionCount;
         mNormalizedCompoundDistance = scoring->mNormalizedCompoundDistance;
         mSpatialDistance = scoring->mSpatialDistance;
         mLanguageDistance = scoring->mLanguageDistance;
@@ -77,6 +79,9 @@
         if (ErrorTypeUtils::isProximityCorrectionError(errorType)) {
             ++mProximityCorrectionCount;
         }
+        if (ErrorTypeUtils::isCompletion(errorType)) {
+            ++mCompletionCount;
+        }
     }
 
     // Saves the current normalized distance for space-aware gestures.
@@ -129,6 +134,10 @@
         return mProximityCorrectionCount;
     }
 
+    int16_t getCompletionCount() const {
+        return mCompletionCount;
+    }
+
     float getRawLength() const {
         return mRawLength;
     }
@@ -182,6 +191,7 @@
 
     int16_t mEditCorrectionCount;
     int16_t mProximityCorrectionCount;
+    int16_t mCompletionCount;
 
     float mNormalizedCompoundDistance;
     float mSpatialDistance;
diff --git a/native/jni/src/suggest/core/dictionary/dictionary.cpp b/native/jni/src/suggest/core/dictionary/dictionary.cpp
index c26e3aa..07b07f7 100644
--- a/native/jni/src/suggest/core/dictionary/dictionary.cpp
+++ b/native/jni/src/suggest/core/dictionary/dictionary.cpp
@@ -45,7 +45,7 @@
 
 int Dictionary::getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession *traverseSession,
         int *xcoordinates, int *ycoordinates, int *times, int *pointerIds, int *inputCodePoints,
-        int inputSize, int *prevWordCodePoints, int prevWordLength, int commitPoint,
+        int inputSize, int *prevWordCodePoints, int prevWordLength,
         const SuggestOptions *const suggestOptions, int *outWords, int *outputScores,
         int *spaceIndices, int *outputTypes, int *outputAutoCommitFirstWordConfidence) const {
     TimeKeeper::setCurrentTime();
@@ -54,7 +54,7 @@
         DicTraverseSession::initSessionInstance(
                 traverseSession, this, prevWordCodePoints, prevWordLength, suggestOptions);
         result = mGestureSuggest->getSuggestions(proximityInfo, traverseSession, xcoordinates,
-                ycoordinates, times, pointerIds, inputCodePoints, inputSize, commitPoint, outWords,
+                ycoordinates, times, pointerIds, inputCodePoints, inputSize, outWords,
                 outputScores, spaceIndices, outputTypes, outputAutoCommitFirstWordConfidence);
         if (DEBUG_DICT) {
             DUMP_RESULT(outWords, outputScores);
@@ -64,7 +64,7 @@
         DicTraverseSession::initSessionInstance(
                 traverseSession, this, prevWordCodePoints, prevWordLength, suggestOptions);
         result = mTypingSuggest->getSuggestions(proximityInfo, traverseSession, xcoordinates,
-                ycoordinates, times, pointerIds, inputCodePoints, inputSize, commitPoint,
+                ycoordinates, times, pointerIds, inputCodePoints, inputSize,
                 outWords, outputScores, spaceIndices, outputTypes,
                 outputAutoCommitFirstWordConfidence);
         if (DEBUG_DICT) {
diff --git a/native/jni/src/suggest/core/dictionary/dictionary.h b/native/jni/src/suggest/core/dictionary/dictionary.h
index ce032fc..4d482e7 100644
--- a/native/jni/src/suggest/core/dictionary/dictionary.h
+++ b/native/jni/src/suggest/core/dictionary/dictionary.h
@@ -64,7 +64,7 @@
 
     int getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession *traverseSession,
             int *xcoordinates, int *ycoordinates, int *times, int *pointerIds, int *inputCodePoints,
-            int inputSize, int *prevWordCodePoints, int prevWordLength, int commitPoint,
+            int inputSize, int *prevWordCodePoints, int prevWordLength,
             const SuggestOptions *const suggestOptions, int *outWords, int *outputScores,
             int *spaceIndices, int *outputTypes, int *outputAutoCommitFirstWordConfidence) const;
 
diff --git a/native/jni/src/suggest/core/dictionary/error_type_utils.h b/native/jni/src/suggest/core/dictionary/error_type_utils.h
index 1122291..cc77867 100644
--- a/native/jni/src/suggest/core/dictionary/error_type_utils.h
+++ b/native/jni/src/suggest/core/dictionary/error_type_utils.h
@@ -59,6 +59,10 @@
         return (errorType & PROXIMITY_CORRECTION) != 0;
     }
 
+    static bool isCompletion(const ErrorType errorType) {
+        return (errorType & COMPLETION) != 0;
+    }
+
  private:
     DISALLOW_IMPLICIT_CONSTRUCTORS(ErrorTypeUtils);
 
diff --git a/native/jni/src/suggest/core/suggest.cpp b/native/jni/src/suggest/core/suggest.cpp
index f60a210..f6de571 100644
--- a/native/jni/src/suggest/core/suggest.cpp
+++ b/native/jni/src/suggest/core/suggest.cpp
@@ -44,7 +44,7 @@
  */
 int Suggest::getSuggestions(ProximityInfo *pInfo, void *traverseSession,
         int *inputXs, int *inputYs, int *times, int *pointerIds, int *inputCodePoints,
-        int inputSize, int commitPoint, int *outWords, int *outputScores, int *outputIndices,
+        int inputSize, int *outWords, int *outputScores, int *outputIndices,
         int *outputTypes, int *outputAutoCommitFirstWordConfidence) const {
     PROF_OPEN;
     PROF_START(0);
@@ -54,7 +54,7 @@
             pointerIds, maxSpatialDistance, TRAVERSAL->getMaxPointerCount());
     // TODO: Add the way to evaluate cache
 
-    initializeSearch(tSession, commitPoint);
+    initializeSearch(tSession);
     PROF_END(0);
     PROF_START(1);
 
@@ -77,27 +77,15 @@
  * Initializes the search at the root of the lexicon trie. Note that when possible the search will
  * continue suggestion from where it left off during the last call.
  */
-void Suggest::initializeSearch(DicTraverseSession *traverseSession, int commitPoint) const {
+void Suggest::initializeSearch(DicTraverseSession *traverseSession) const {
     if (!traverseSession->getProximityInfoState(0)->isUsed()) {
         return;
     }
 
-    // Never auto partial commit for now.
-    commitPoint = 0;
-
     if (traverseSession->getInputSize() > MIN_CONTINUOUS_SUGGESTION_INPUT_SIZE
             && traverseSession->isContinuousSuggestionPossible()) {
-        if (commitPoint == 0) {
-            // Continue suggestion
-            traverseSession->getDicTraverseCache()->continueSearch();
-        } else {
-            // Continue suggestion after partial commit.
-            DicNode *topDicNode =
-                    traverseSession->getDicTraverseCache()->setCommitPoint(commitPoint);
-            traverseSession->setPrevWordPtNodePos(topDicNode->getPrevWordPtNodePos());
-            traverseSession->getDicTraverseCache()->continueSearch();
-            traverseSession->setPartiallyCommited();
-        }
+        // Continue suggestion
+        traverseSession->getDicTraverseCache()->continueSearch();
     } else {
         // Restart recognition at the root.
         traverseSession->resetCache(TRAVERSAL->getMaxCacheSize(traverseSession->getInputSize()),
diff --git a/native/jni/src/suggest/core/suggest.h b/native/jni/src/suggest/core/suggest.h
index c42986a..33ea0b6 100644
--- a/native/jni/src/suggest/core/suggest.h
+++ b/native/jni/src/suggest/core/suggest.h
@@ -47,15 +47,15 @@
               WEIGHTING(suggestPolicy ? suggestPolicy->getWeighting() : nullptr) {}
     AK_FORCE_INLINE virtual ~Suggest() {}
     int getSuggestions(ProximityInfo *pInfo, void *traverseSession, int *inputXs, int *inputYs,
-            int *times, int *pointerIds, int *inputCodePoints, int inputSize, int commitPoint,
-            int *outWords, int *outputScores, int *outputIndices, int *outputTypes,
+            int *times, int *pointerIds, int *inputCodePoints, int inputSize, int *outWords,
+            int *outputScores, int *outputIndices, int *outputTypes,
             int *outputAutoCommitFirstWordConfidence) const;
 
  private:
     DISALLOW_IMPLICIT_CONSTRUCTORS(Suggest);
     void createNextWordDicNode(DicTraverseSession *traverseSession, DicNode *dicNode,
             const bool spaceSubstitution) const;
-    void initializeSearch(DicTraverseSession *traverseSession, int commitPoint) const;
+    void initializeSearch(DicTraverseSession *traverseSession) const;
     void expandCurrentDicNodes(DicTraverseSession *traverseSession) const;
     void processTerminalDicNode(DicTraverseSession *traverseSession, DicNode *dicNode) const;
     void processExpandedDicNode(DicTraverseSession *traverseSession, DicNode *dicNode) const;
diff --git a/native/jni/src/suggest/core/suggest_interface.h b/native/jni/src/suggest/core/suggest_interface.h
index 9a07580..f10db83 100644
--- a/native/jni/src/suggest/core/suggest_interface.h
+++ b/native/jni/src/suggest/core/suggest_interface.h
@@ -27,8 +27,8 @@
  public:
     virtual int getSuggestions(ProximityInfo *pInfo, void *traverseSession, int *inputXs,
             int *inputYs, int *times, int *pointerIds, int *inputCodePoints, int inputSize,
-            int commitPoint, int *outWords, int *outputScores, int *outputIndices,
-            int *outputTypes, int *outputAutoCommitFirstWordConfidence) const = 0;
+            int *outWords, int *outputScores, int *outputIndices, int *outputTypes,
+            int *outputAutoCommitFirstWordConfidence) const = 0;
     SuggestInterface() {}
     virtual ~SuggestInterface() {}
  private:
diff --git a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetSubtypesCountTests.java b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetSubtypesCountTests.java
index e691639..bbffc8d 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 = 63;
-    private static final int NUMBER_OF_ASCII_CAPABLE_SUBTYPES = 40;
+    private static final int NUMBER_OF_SUBTYPES = 66;
+    private static final int NUMBER_OF_ASCII_CAPABLE_SUBTYPES = 42;
     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/KeyboardLayoutSetTestsBase.java b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetTestsBase.java
index 0993c4b..a4c69e0 100644
--- a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetTestsBase.java
+++ b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetTestsBase.java
@@ -42,7 +42,7 @@
 @SmallTest
 public class KeyboardLayoutSetTestsBase extends AndroidTestCase {
     private static final KeyboardTheme DEFAULT_KEYBOARD_THEME =
-            KeyboardSwitcher.KEYBOARD_THEMES[KeyboardSwitcher.THEME_INDEX_DEFAULT];
+            KeyboardSwitcher.KEYBOARD_THEMES[KeyboardSwitcher.DEFAULT_THEME_INDEX];
 
     // All input method subtypes of LatinIME.
     private final ArrayList<InputMethodSubtype> mAllSubtypesList = CollectionUtils.newArrayList();
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTestsBase.java b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTestsBase.java
index c342533..7923afc 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTestsBase.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTestsBase.java
@@ -22,12 +22,8 @@
 import static com.android.inputmethod.latin.Constants.CODE_OUTPUT_TEXT;
 import static com.android.inputmethod.latin.Constants.CODE_UNSPECIFIED;
 
-import android.content.Context;
-import android.content.res.Resources;
 import android.test.AndroidTestCase;
 
-import com.android.inputmethod.latin.utils.RunInLocale;
-
 import java.util.Locale;
 
 abstract class KeySpecParserTestsBase extends AndroidTestCase {
@@ -51,16 +47,7 @@
     protected void setUp() throws Exception {
         super.setUp();
 
-        mTextsSet.setLocale(TEST_LOCALE);
-        final Context context = getContext();
-        new RunInLocale<Void>() {
-            @Override
-            protected Void job(final Resources res) {
-                mTextsSet.loadStringResources(context);
-                return null;
-            }
-        }.runInLocale(context.getResources(), TEST_LOCALE);
-
+        mTextsSet.setLocale(TEST_LOCALE, getContext());
         mCodeSettings = KeyboardCodesSet.getCode(CODE_SETTINGS_NAME);
         mCodeActionNext = KeyboardCodesSet.getCode("key_action_next");
         mSettingsIconId = KeyboardIconsSet.getIconId(ICON_SETTINGS_NAME);
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSetTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSetTests.java
index 17d7687..eb906cd 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSetTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSetTests.java
@@ -17,7 +17,6 @@
 package com.android.inputmethod.keyboard.internal;
 
 import android.content.Context;
-import android.content.res.Resources;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.view.inputmethod.InputMethodInfo;
@@ -25,7 +24,6 @@
 
 import com.android.inputmethod.latin.RichInputMethodManager;
 import com.android.inputmethod.latin.utils.CollectionUtils;
-import com.android.inputmethod.latin.utils.RunInLocale;
 import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
 
 import java.util.ArrayList;
@@ -58,10 +56,11 @@
     // subtypes. The text is needed to implement Emoji Keyboard, see
     // {@link KeyboardSwitcher#setEmojiKeyboard()}.
     public void testSwitchToAlphaKeyLabel() {
+        final Context context = getContext();
         final KeyboardTextsSet textsSet = new KeyboardTextsSet();
         for (final InputMethodSubtype subtype : mAllSubtypesList) {
             final Locale locale = SubtypeLocaleUtils.getSubtypeLocale(subtype);
-            textsSet.setLocale(locale);
+            textsSet.setLocale(locale, context);
             final String switchToAlphaKeyLabel = textsSet.getText(
                     KeyboardTextsSet.SWITCH_TO_ALPHA_KEY_LABEL);
             assertNotNull("Switch to alpha key label of " + locale, switchToAlphaKeyLabel);
@@ -87,15 +86,7 @@
         final KeyboardTextsSet textsSet = new KeyboardTextsSet();
         for (final InputMethodSubtype subtype : mAllSubtypesList) {
             final Locale locale = SubtypeLocaleUtils.getSubtypeLocale(subtype);
-            textsSet.setLocale(locale);
-            final RunInLocale<Void> job = new RunInLocale<Void>() {
-                @Override
-                protected Void job(final Resources res) {
-                    textsSet.loadStringResources(context);
-                    return null;
-                }
-            };
-            job.runInLocale(context.getResources(), locale);
+            textsSet.setLocale(locale, context);
             for (final String name : TEXT_NAMES_FROM_RESOURCE) {
                 final String text = textsSet.getText(name);
                 assertNotNull(name + " of " + locale, text);
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecSplitTests.java b/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecSplitTests.java
index 42a94f4..a193307 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecSplitTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecSplitTests.java
@@ -23,7 +23,6 @@
 import android.test.suitebuilder.annotation.MediumTest;
 
 import com.android.inputmethod.latin.utils.CollectionUtils;
-import com.android.inputmethod.latin.utils.RunInLocale;
 
 import java.lang.reflect.Field;
 import java.util.ArrayList;
@@ -41,20 +40,16 @@
 
         final Instrumentation instrumentation = getInstrumentation();
         final Context targetContext = instrumentation.getTargetContext();
-        mTextsSet.setLocale(TEST_LOCALE);
-        new RunInLocale<Void>() {
-            @Override
-            protected Void job(final Resources res) {
-                mTextsSet.loadStringResources(targetContext);
-                return null;
-            }
-        }.runInLocale(targetContext.getResources(), TEST_LOCALE);
+        mTextsSet.setLocale(TEST_LOCALE, targetContext);
         final String[] testResourceNames = getAllResourceIdNames(
                 com.android.inputmethod.latin.tests.R.string.class);
-        mTextsSet.loadStringResourcesInternal(instrumentation.getContext(), testResourceNames,
+        final Context testContext = instrumentation.getContext();
+        final Resources testRes = testContext.getResources();
+        final String testResPackageName = testRes.getResourcePackageName(
                 // This dummy raw resource is needed to be able to load string resources from a test
                 // APK successfully.
                 com.android.inputmethod.latin.tests.R.raw.dummy_resource_for_testing);
+        mTextsSet.loadStringResourcesInternal(testRes, testResourceNames, testResPackageName);
     }
 
     private static String[] getAllResourceIdNames(final Class<?> resourceIdClass) {
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Arabic.java b/tests/src/com/android/inputmethod/keyboard/layout/Arabic.java
index 444730a..b0493d3 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/Arabic.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Arabic.java
@@ -72,7 +72,7 @@
         public ExpectedKey[] getKeysLeftToSpacebar(final boolean isPhone) {
             if (isPhone) {
                 // U+060C: "،" ARABIC COMMA
-                return joinKeys(key("\u060C", joinMoreKeys(",", SETTINGS_KEY)));
+                return joinKeys(key("\u060C", SETTINGS_KEY));
             }
             return super.getKeysLeftToSpacebar(isPhone);
         }
@@ -142,7 +142,7 @@
         } else {
             final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(ALPHABET_COMMON);
             // U+0626: "ئ" ARABIC LETTER YEH WITH HAMZA ABOVE
-            builder.insertKeysAtRow(3, 2, key("\u0626"));
+            builder.insertKeysAtRow(3, 2, "\u0626");
             return builder.build();
         }
     }
@@ -198,7 +198,7 @@
                     // U+069C: "ڜ" ARABIC LETTER SEEN WITH THREE DOTS BELOW AND THREE DOTS ABOVE
                     key("\u0634", moreKey("\u069C")),
                     // U+0633: "س" ARABIC LETTER SEEN
-                    key("\u0633"),
+                    "\u0633",
                     // U+064A: "ي" ARABIC LETTER YEH
                     // U+0626: "ئ" ARABIC LETTER YEH WITH HAMZA ABOVE
                     // U+0649: "ى" ARABIC LETTER ALEF MAKSURA
@@ -226,18 +226,16 @@
                     // U+0671: "ٱ" ARABIC LETTER ALEF WASLA
                     key("\u0627", joinMoreKeys("\u0622", "\u0621", "\u0623", "\u0625", "\u0671")),
                     // U+062A: "ت" ARABIC LETTER TEH
-                    key("\u062A"),
                     // U+0646: "ن" ARABIC LETTER NOON
-                    key("\u0646"),
                     // U+0645: "م" ARABIC LETTER MEEM
-                    key("\u0645"),
+                    "\u062A", "\u0646", "\u0645",
                     // U+0643: "ك" ARABIC LETTER KAF
                     // U+06AF: "گ" ARABIC LETTER GAF
                     // U+06A9: "ک" ARABIC LETTER KEHEH
                     key("\u0643", joinMoreKeys("\u06AF", "\u06A9")),
                     // U+0637: "ط" ARABIC LETTER TAH
-                    key("\u0637"))
-            .setKeysOfRow(3, joinKeys(
+                    "\u0637")
+            .setKeysOfRow(3,
                     // U+0630: "ذ" ARABIC LETTER THAL
                     // U+0621: "ء" ARABIC LETTER HAMZA
                     // U+0624: "ؤ" ARABIC LETTER WAW WITH HAMZA ABOVE
@@ -254,7 +252,7 @@
                     key("\u0632", moreKey("\u0698")),
                     // U+0638: "ظ" ARABIC LETTER ZAH
                     // U+062F: "د" ARABIC LETTER DAL
-                    "\u0638", "\u062F"))
+                    "\u0638", "\u062F")
             .build();
 
     private static class ArabicSymbols extends RtlSymbols {
@@ -314,7 +312,7 @@
                     // U+00BF: "¿" INVERTED QUESTION MARK
                     .replaceKeyOfLabel("?", key("\u061F", joinMoreKeys("?", "\u00BF")))
                     // U+060C: "،" ARABIC COMMA
-                    .replaceKeyOfLabel(",", key("\u060C", moreKey(",")))
+                    .replaceKeyOfLabel(",", "\u060C")
                     // U+FD3E: "﴾" ORNATE LEFT PARENTHESIS
                     // U+FD3F: "﴿" ORNATE RIGHT PARENTHESIS
                     .replaceKeyOfLabel("(", key("(", ")",
@@ -344,7 +342,7 @@
                     // U+266A: "♪" EIGHTH NOTE
                     .setMoreKeysOf("\u2022", "\u266A")
                     // U+060C: "،" ARABIC COMMA
-                    .replaceKeyOfLabel(",", key("\u060C", moreKey(",")))
+                    .replaceKeyOfLabel(",", "\u060C")
                     .build();
         }
     }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/ArmenianPhonetic.java b/tests/src/com/android/inputmethod/keyboard/layout/ArmenianPhonetic.java
new file mode 100644
index 0000000..204bb01
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/ArmenianPhonetic.java
@@ -0,0 +1,208 @@
+/*
+ * 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.layout.expected.ExpectedKey;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+import com.android.inputmethod.latin.Constants;
+
+import java.util.Locale;
+
+/**
+ * The Armenian Phonetic alphabet keyboard.
+ */
+public final class ArmenianPhonetic extends LayoutBase {
+    private static final String LAYOUT_NAME = "armenian_phonetic";
+
+    public ArmenianPhonetic(final LayoutCustomizer customizer) {
+        super(customizer, ArmenianSymbols.class, SymbolsShifted.class);
+    }
+
+    @Override
+    public String getName() { return LAYOUT_NAME; }
+
+    public static class ArmenianPhoneticCustomizer extends LayoutCustomizer {
+        public ArmenianPhoneticCustomizer(final Locale locale) { super(locale); }
+
+        @Override
+        public ExpectedKey getAlphabetKey() { return ARMENIAN_ALPHABET_KEY; }
+
+        @Override
+        public ExpectedKey[] getRightShiftKeys(final boolean isPhone) {
+            if (isPhone) {
+                return EMPTY_KEYS;
+            }
+            // U+055C: "՜" ARMENIAN EXCLAMATION MARK
+            // U+00A1: "¡" INVERTED EXCLAMATION MARK
+            // U+055E: "՞" ARMENIAN QUESTION MARK
+            // U+00BF: "¿" INVERTED QUESTION MARK
+            return joinKeys(key("!", joinMoreKeys("\u055C", "\u00A1")),
+                    key("?", joinMoreKeys("\u055E", "\u00BF")),
+                    SHIFT_KEY);
+        }
+
+        @Override
+        public ExpectedKey[] getKeysRightToSpacebar(final boolean isPhone) {
+            // U+0589: "։" ARMENIAN FULL STOP
+            // U+055D: "՝" ARMENIAN COMMA
+            final ExpectedKey fullStopKey = key("\u0589", getPunctuationMoreKeys(isPhone));
+            return isPhone ? joinKeys(fullStopKey) : joinKeys("\u055D", fullStopKey);
+        }
+
+        @Override
+        public ExpectedKey[] getPunctuationMoreKeys(final boolean isPhone) {
+            return ARMENIAN_PUNCTUATION_MORE_KEYS;
+        }
+
+        // U+0531: "Ա" ARMENIAN CAPITAL LETTER AYB
+        // U+0532: "Բ" ARMENIAN CAPITAL LETTER BEN
+        // U+0533: "Գ" ARMENIAN CAPITAL LETTER GIM
+        private static final ExpectedKey ARMENIAN_ALPHABET_KEY = key(
+                "\u0531\u0532\u0533", Constants.CODE_SWITCH_ALPHA_SYMBOL);
+
+        // U+055E: "՞" ARMENIAN QUESTION MARK
+        // U+055C: "՜" ARMENIAN EXCLAMATION MARK
+        // U+055A: "՚" ARMENIAN APOSTROPHE
+        // U+0559: "ՙ" ARMENIAN MODIFIER LETTER LEFT HALF RING
+        // U+055D: "՝" ARMENIAN COMMA
+        // U+055B: "՛" ARMENIAN EMPHASIS MARK
+        // U+058A: "֊" ARMENIAN HYPHEN
+        // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+        // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+        // U+055F: "՟" ARMENIAN ABBREVIATION MARK
+        private static final ExpectedKey[] ARMENIAN_PUNCTUATION_MORE_KEYS = joinMoreKeys(
+                ",", "\u055E", "\u055C", ".", "\u055A", "\u0559", "?", "!",
+                "\u055D", "\u055B", "\u058A", "\u00BB", "\u00AB", "\u055F", ";", ":");
+    }
+
+    @Override
+    ExpectedKey[][] getCommonAlphabetLayout(final boolean isPhone) {
+        final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(ALPHABET_COMMON);
+        if (isPhone) {
+            // U+056D: "խ" ARMENIAN SMALL LETTER XEH
+            // U+0577: "շ" ARMENIAN SMALL LETTER SHA
+            builder.addKeysOnTheRightOfRow(3, "\u056D")
+                    .addKeysOnTheRightOfRow(4, "\u0577");
+        } else {
+            // U+056D: "խ" ARMENIAN SMALL LETTER XEH
+            // U+0577: "շ" ARMENIAN SMALL LETTER SHA
+            builder.addKeysOnTheRightOfRow(2, "\u056D")
+                    .addKeysOnTheRightOfRow(3, "\u0577");
+        }
+        return builder.build();
+    }
+
+    // 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+0567: "է" ARMENIAN SMALL LETTER EH
+                    key("\u0567", moreKey("1")),
+                    // U+0569: "թ" ARMENIAN SMALL LETTER TO
+                    key("\u0569", moreKey("2")),
+                    // U+0583: "փ" ARMENIAN SMALL LETTER PIWR
+                    key("\u0583", moreKey("3")),
+                    // U+0571: "ձ" ARMENIAN SMALL LETTER JA
+                    key("\u0571", moreKey("4")),
+                    // U+057B: "ջ" ARMENIAN SMALL LETTER JHEH
+                    key("\u057B", moreKey("5")),
+                    // U+0580: "ր" ARMENIAN SMALL LETTER REH
+                    key("\u0580", moreKey("6")),
+                    // U+0579: "չ" ARMENIAN SMALL LETTER CHA
+                    key("\u0579", moreKey("7")),
+                    // U+0573: "ճ" ARMENIAN SMALL LETTER CHEH
+                    key("\u0573", moreKey("8")),
+                    // U+056A: "ժ" ARMENIAN SMALL LETTER ZHE
+                    key("\u056A", moreKey("9")),
+                    // U+056E: "ծ" ARMENIAN SMALL LETTER CA
+                    key("\u056E", moreKey("0")))
+            .setKeysOfRow(2,
+                    // U+0584: "ք" ARMENIAN SMALL LETTER KEH
+                    // U+0578: "ո" ARMENIAN SMALL LETTER VO
+                    "\u0584", "\u0578",
+                    // U+0565: "ե" ARMENIAN SMALL LETTER ECH
+                    // U+0587: "և" ARMENIAN SMALL LIGATURE ECH YIWN
+                    key("\u0565", moreKey("\u0587")),
+                    // U+057C: "ռ" ARMENIAN SMALL LETTER RA
+                    // U+057F: "տ" ARMENIAN SMALL LETTER TIWN
+                    // U+0568: "ը" ARMENIAN SMALL LETTER ET
+                    // U+0582: "ւ" ARMENIAN SMALL LETTER YIWN
+                    // U+056B: "ի" ARMENIAN SMALL LETTER INI
+                    // U+0585: "օ" ARMENIAN SMALL LETTER OH
+                    // U+057A: "պ" ARMENIAN SMALL LETTER PEH
+                    "\u057C", "\u057F", "\u0568", "\u0582", "\u056B", "\u0585", "\u057A")
+            .setKeysOfRow(3,
+                    // U+0561: "ա" ARMENIAN SMALL LETTER AYB
+                    // U+057D: "ս" ARMENIAN SMALL LETTER SEH
+                    // U+0564: "դ" ARMENIAN SMALL LETTER DA
+                    // U+0586: "ֆ" ARMENIAN SMALL LETTER FEH
+                    // U+0563: "գ" ARMENIAN SMALL LETTER GIM
+                    // U+0570: "հ" ARMENIAN SMALL LETTER HO
+                    // U+0575: "յ" ARMENIAN SMALL LETTER YI
+                    // U+056F: "կ" ARMENIAN SMALL LETTER KEN
+                    // U+056C: "լ" ARMENIAN SMALL LETTER LIWN
+                    "\u0561", "\u057D", "\u0564", "\u0586", "\u0563", "\u0570", "\u0575", "\u056F",
+                    "\u056C")
+            .setKeysOfRow(4,
+                    // U+0566: "զ" ARMENIAN SMALL LETTER ZA
+                    // U+0572: "ղ" ARMENIAN SMALL LETTER GHAD
+                    // U+0581: "ց" ARMENIAN SMALL LETTER CO
+                    // U+057E: "վ" ARMENIAN SMALL LETTER VEW
+                    // U+0562: "բ" ARMENIAN SMALL LETTER BEN
+                    // U+0576: "ն" ARMENIAN SMALL LETTER NOW
+                    // U+0574: "մ" ARMENIAN SMALL LETTER MEN
+                    "\u0566", "\u0572", "\u0581", "\u057E", "\u0562", "\u0576", "\u0574")
+            .build();
+
+    private static final class ArmenianSymbols extends Symbols {
+        public ArmenianSymbols(final LayoutCustomizer customizer) { super(customizer); }
+
+        @Override
+        public ExpectedKey[][] getLayout(final boolean isPhone) {
+            final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(
+                    super.getLayout(isPhone));
+            // U+055C: "՜" ARMENIAN EXCLAMATION MARK
+            // U+00A1: "¡" INVERTED EXCLAMATION MARK
+            // U+055E: "՞" ARMENIAN QUESTION MARK
+            // U+00BF: "¿" INVERTED QUESTION MARK
+            builder.setMoreKeysOf("!", "\u055C", "\u00A1")
+                    .setMoreKeysOf("?", "\u055E", "\u00BF");
+            return builder.build();
+        }
+    }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Azerty.java b/tests/src/com/android/inputmethod/keyboard/layout/Azerty.java
index 24d85cf..a094963 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/Azerty.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Azerty.java
@@ -51,7 +51,7 @@
         } else {
             builder = new ExpectedKeyboardBuilder(ALPHABET_COMMON);
             getCustomizer().setAccentedLetters(builder);
-            builder.replaceKeyOfLabel(ROW3_QUOTE, key("?"));
+            builder.replaceKeyOfLabel(ROW3_QUOTE, "?");
         }
         builder.toUpperCase(getLocale());
         return builder.build();
@@ -61,17 +61,17 @@
 
     private static final ExpectedKey[][] ALPHABET_COMMON = new ExpectedKeyboardBuilder()
             .setKeysOfRow(1,
-                    key("a", moreKey("1")),
-                    key("z", moreKey("2")),
-                    key("e", moreKey("3")),
-                    key("r", moreKey("4")),
-                    key("t", moreKey("5")),
-                    key("y", moreKey("6")),
-                    key("u", moreKey("7")),
-                    key("i", moreKey("8")),
-                    key("o", moreKey("9")),
-                    key("p", moreKey("0")))
-            .setLabelsOfRow(2, "q", "s", "d", "f", "g", "h", "j", "k", "l", "m")
-            .setLabelsOfRow(3, "w", "x", "c", "v", "b", "n", ROW3_QUOTE)
+                    key("a", additionalMoreKey("1")),
+                    key("z", additionalMoreKey("2")),
+                    key("e", additionalMoreKey("3")),
+                    key("r", additionalMoreKey("4")),
+                    key("t", additionalMoreKey("5")),
+                    key("y", additionalMoreKey("6")),
+                    key("u", additionalMoreKey("7")),
+                    key("i", additionalMoreKey("8")),
+                    key("o", additionalMoreKey("9")),
+                    key("p", additionalMoreKey("0")))
+            .setKeysOfRow(2, "q", "s", "d", "f", "g", "h", "j", "k", "l", "m")
+            .setKeysOfRow(3, "w", "x", "c", "v", "b", "n", ROW3_QUOTE)
             .build();
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Bulgarian.java b/tests/src/com/android/inputmethod/keyboard/layout/Bulgarian.java
index a1ad549..3282e44 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/Bulgarian.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Bulgarian.java
@@ -76,30 +76,30 @@
                     // U+043F: "п" CYRILLIC SMALL LETTER PE
                     key("\u043F", moreKey("0")),
                     // U+0447: "ч" CYRILLIC SMALL LETTER CHE
-                    key("\u0447"))
-            // U+0430: "а" CYRILLIC SMALL LETTER A
-            // U+0441: "с" CYRILLIC SMALL LETTER ES
-            // U+0434: "д" CYRILLIC SMALL LETTER DE
-            // U+0444: "ф" CYRILLIC SMALL LETTER EF
-            // U+0433: "г" CYRILLIC SMALL LETTER GHE
-            // U+0445: "х" CYRILLIC SMALL LETTER HA
-            // U+0439: "й" CYRILLIC SMALL LETTER SHORT I
-            // U+043A: "к" CYRILLIC SMALL LETTER KA
-            // U+043B: "л" CYRILLIC SMALL LETTER EL
-            // U+0448: "ш" CYRILLIC SMALL LETTER SHA
-            // U+0449: "щ" CYRILLIC SMALL LETTER SHCHA
-            .setLabelsOfRow(2,
+                    "\u0447")
+            .setKeysOfRow(2,
+                    // U+0430: "а" CYRILLIC SMALL LETTER A
+                    // U+0441: "с" CYRILLIC SMALL LETTER ES
+                    // U+0434: "д" CYRILLIC SMALL LETTER DE
+                    // U+0444: "ф" CYRILLIC SMALL LETTER EF
+                    // U+0433: "г" CYRILLIC SMALL LETTER GHE
+                    // U+0445: "х" CYRILLIC SMALL LETTER HA
+                    // U+0439: "й" CYRILLIC SMALL LETTER SHORT I
+                    // U+043A: "к" CYRILLIC SMALL LETTER KA
+                    // U+043B: "л" CYRILLIC SMALL LETTER EL
+                    // U+0448: "ш" CYRILLIC SMALL LETTER SHA
+                    // U+0449: "щ" CYRILLIC SMALL LETTER SHCHA
                     "\u0430", "\u0441", "\u0434", "\u0444", "\u0433", "\u0445", "\u0439", "\u043A",
                     "\u043B", "\u0448", "\u0449")
-            // U+0437: "з" CYRILLIC SMALL LETTER ZE
-            // U+044C: "ь" CYRILLIC SMALL LETTER SOFT SIGN
-            // U+0446: "ц" CYRILLIC SMALL LETTER TSE
-            // U+0436: "ж" CYRILLIC SMALL LETTER ZHE
-            // U+0431: "б" CYRILLIC SMALL LETTER BE
-            // U+043D: "н" CYRILLIC SMALL LETTER EN
-            // U+043C: "м" CYRILLIC SMALL LETTER EM
-            // U+044E: "ю" CYRILLIC SMALL LETTER YU
-            .setLabelsOfRow(3,
+            .setKeysOfRow(3,
+                    // U+0437: "з" CYRILLIC SMALL LETTER ZE
+                    // U+044C: "ь" CYRILLIC SMALL LETTER SOFT SIGN
+                    // U+0446: "ц" CYRILLIC SMALL LETTER TSE
+                    // U+0436: "ж" CYRILLIC SMALL LETTER ZHE
+                    // U+0431: "б" CYRILLIC SMALL LETTER BE
+                    // U+043D: "н" CYRILLIC SMALL LETTER EN
+                    // U+043C: "м" CYRILLIC SMALL LETTER EM
+                    // U+044E: "ю" CYRILLIC SMALL LETTER YU
                     "\u0437", "\u044C", "\u0446", "\u0436", "\u0431", "\u043D", "\u043C", "\u044E")
             .build();
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/BulgarianBds.java b/tests/src/com/android/inputmethod/keyboard/layout/BulgarianBds.java
index b47b592..20a5f7d 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/BulgarianBds.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/BulgarianBds.java
@@ -66,31 +66,31 @@
                     // U+0446: "ц" CYRILLIC SMALL LETTER TSE
                     key("\u0446", moreKey("0")),
                     // U+0431: "б" CYRILLIC SMALL LETTER BE
-                    key("\u0431"))
-            // U+044C: "ь" CYRILLIC SMALL LETTER SOFT SIGN
-            // U+044F: "я" CYRILLIC SMALL LETTER YA
-            // U+0430: "а" CYRILLIC SMALL LETTER A
-            // U+043E: "о" CYRILLIC SMALL LETTER O
-            // U+0436: "ж" CYRILLIC SMALL LETTER ZHE
-            // U+0433: "г" CYRILLIC SMALL LETTER GHE
-            // U+0442: "т" CYRILLIC SMALL LETTER TE
-            // U+043D: "н" CYRILLIC SMALL LETTER EN
-            // U+0432: "в" CYRILLIC SMALL LETTER VE
-            // U+043C: "м" CYRILLIC SMALL LETTER EM
-            // U+0447: "ч" CYRILLIC SMALL LETTER CHE
-            .setLabelsOfRow(2,
+                    "\u0431")
+            .setKeysOfRow(2,
+                    // U+044C: "ь" CYRILLIC SMALL LETTER SOFT SIGN
+                    // U+044F: "я" CYRILLIC SMALL LETTER YA
+                    // U+0430: "а" CYRILLIC SMALL LETTER A
+                    // U+043E: "о" CYRILLIC SMALL LETTER O
+                    // U+0436: "ж" CYRILLIC SMALL LETTER ZHE
+                    // U+0433: "г" CYRILLIC SMALL LETTER GHE
+                    // U+0442: "т" CYRILLIC SMALL LETTER TE
+                    // U+043D: "н" CYRILLIC SMALL LETTER EN
+                    // U+0432: "в" CYRILLIC SMALL LETTER VE
+                    // U+043C: "м" CYRILLIC SMALL LETTER EM
+                    // U+0447: "ч" CYRILLIC SMALL LETTER CHE
                     "\u044C", "\u044F", "\u0430", "\u043E", "\u0436", "\u0433", "\u0442", "\u043D",
                     "\u0432", "\u043C", "\u0447")
-            // U+044E: "ю" CYRILLIC SMALL LETTER YU
-            // U+0439: "й" CYRILLIC SMALL LETTER SHORT I
-            // U+044A: "ъ" CYRILLIC SMALL LETTER HARD SIGN
-            // U+044D: "э" CYRILLIC SMALL LETTER E
-            // U+0444: "ф" CYRILLIC SMALL LETTER EF
-            // U+0445: "х" CYRILLIC SMALL LETTER HA
-            // U+043F: "п" CYRILLIC SMALL LETTER PE
-            // U+0440: "р" CYRILLIC SMALL LETTER ER
-            // U+043B: "л" CYRILLIC SMALL LETTER EL
-            .setLabelsOfRow(3,
+            .setKeysOfRow(3,
+                    // U+044E: "ю" CYRILLIC SMALL LETTER YU
+                    // U+0439: "й" CYRILLIC SMALL LETTER SHORT I
+                    // U+044A: "ъ" CYRILLIC SMALL LETTER HARD SIGN
+                    // U+044D: "э" CYRILLIC SMALL LETTER E
+                    // U+0444: "ф" CYRILLIC SMALL LETTER EF
+                    // U+0445: "х" CYRILLIC SMALL LETTER HA
+                    // U+043F: "п" CYRILLIC SMALL LETTER PE
+                    // U+0440: "р" CYRILLIC SMALL LETTER ER
+                    // U+043B: "л" CYRILLIC SMALL LETTER EL
                     "\u044E", "\u0439", "\u044A", "\u044D", "\u0444", "\u0445", "\u043F", "\u0440",
                     "\u043B")
             .build();
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Colemak.java b/tests/src/com/android/inputmethod/keyboard/layout/Colemak.java
new file mode 100644
index 0000000..a4a9701
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Colemak.java
@@ -0,0 +1,76 @@
+/*
+ * 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;
+
+/**
+ * The Colemak alphabet keyboard.
+ */
+public final class Colemak extends LayoutBase {
+    private static final String LAYOUT_NAME = "colemak";
+
+    public Colemak(final LayoutCustomizer customizer) {
+        super(customizer, Symbols.class, SymbolsShifted.class);
+    }
+
+    @Override
+    public String getName() { return LAYOUT_NAME; }
+
+    @Override
+    ExpectedKey[][] getCommonAlphabetLayout(final boolean isPhone) {
+        final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(ALPHABET_COMMON);
+        getCustomizer().setAccentedLetters(builder);
+        builder.replaceKeyOfLabel(ROW1_10, key(";", additionalMoreKey("0"), moreKey(":")));
+        return builder.build();
+    }
+
+    @Override
+    ExpectedKey[][] getCommonAlphabetShiftLayout(final boolean isPhone, final int elementId) {
+        final ExpectedKeyboardBuilder builder;
+        if (elementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED
+                || elementId == KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED) {
+            builder = new ExpectedKeyboardBuilder(getCommonAlphabetLayout(isPhone));
+        } else {
+            builder = new ExpectedKeyboardBuilder(ALPHABET_COMMON);
+            getCustomizer().setAccentedLetters(builder);
+            builder.replaceKeyOfLabel(ROW1_10, key(":", additionalMoreKey("0")));
+        }
+        builder.toUpperCase(getLocale());
+        return builder.build();
+    }
+
+    private static final String ROW1_10 = "ROW1_10";
+
+    private static final ExpectedKey[][] ALPHABET_COMMON = new ExpectedKeyboardBuilder()
+            .setKeysOfRow(1,
+                    key("q", additionalMoreKey("1")),
+                    key("w", additionalMoreKey("2")),
+                    key("f", additionalMoreKey("3")),
+                    key("p", additionalMoreKey("4")),
+                    key("g", additionalMoreKey("5")),
+                    key("j", additionalMoreKey("6")),
+                    key("l", additionalMoreKey("7")),
+                    key("u", additionalMoreKey("8")),
+                    key("y", additionalMoreKey("9")),
+                    ROW1_10)
+            .setKeysOfRow(2, "a", "r", "s", "t", "d", "h", "n", "e", "i", "o")
+            .setKeysOfRow(3, "z", "x", "c", "v", "b", "k", "m")
+            .build();
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Dvorak.java b/tests/src/com/android/inputmethod/keyboard/layout/Dvorak.java
new file mode 100644
index 0000000..99cf6e5
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Dvorak.java
@@ -0,0 +1,121 @@
+/*
+ * 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.keyboard.layout.expected.ExpectedKey.ExpectedAdditionalMoreKey;
+
+import java.util.Locale;
+
+/**
+ * The QWERTY alphabet keyboard.
+ */
+public final class Dvorak extends LayoutBase {
+    private static final String LAYOUT_NAME = "dvorak";
+
+    public Dvorak(final LayoutCustomizer customizer) {
+        super(customizer, Symbols.class, SymbolsShifted.class);
+    }
+
+    @Override
+    public String getName() { return LAYOUT_NAME; }
+
+    public static class DvorakCustomizer extends LayoutCustomizer {
+        public DvorakCustomizer(final Locale locale) { super(locale); }
+
+        @Override
+        public ExpectedKey[] getLeftShiftKeys(final boolean isPhone) {
+            return isPhone ? joinKeys(SHIFT_KEY): joinKeys(SHIFT_KEY, key("q"));
+        }
+
+        @Override
+        public ExpectedKey[] getRightShiftKeys(final boolean isPhone) {
+            return isPhone ? EMPTY_KEYS : joinKeys(key("z"), SHIFT_KEY);
+        }
+
+        @Override
+        public ExpectedKey[] getKeysLeftToSpacebar(final boolean isPhone) {
+            return isPhone ? joinKeys(key("q", SHORTCUT_KEY, SETTINGS_KEY)) : joinKeys(key("/"));
+        }
+
+        @Override
+        public ExpectedKey[] getKeysRightToSpacebar(final boolean isPhone) {
+            final ExpectedAdditionalMoreKey[] punctuationMoreKeys =
+                    convertToAdditionalMoreKeys(getPunctuationMoreKeys(isPhone));
+            return isPhone
+                    ? joinKeys(key("z", punctuationMoreKeys))
+                    : joinKeys(key("?", moreKey("!")), key("-", moreKey("_")));
+        }
+
+        private static ExpectedAdditionalMoreKey[] convertToAdditionalMoreKeys(
+                final ExpectedKey ... moreKeys) {
+            final ExpectedAdditionalMoreKey[] additionalMoreKeys =
+                    new ExpectedAdditionalMoreKey[moreKeys.length];
+            for (int index = 0; index < moreKeys.length; index++) {
+                additionalMoreKeys[index] = ExpectedAdditionalMoreKey.newInstance(moreKeys[index]);
+            }
+            return additionalMoreKeys;
+        }
+    }
+
+    @Override
+    ExpectedKey[][] getCommonAlphabetLayout(final boolean isPhone) { return ALPHABET_COMMON; }
+
+    @Override
+    public ExpectedKey[][] getLayout(final boolean isPhone, final int elementId) {
+        if (elementId == KeyboardId.ELEMENT_SYMBOLS
+                || elementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED) {
+            return super.getLayout(isPhone, elementId);
+        }
+        final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(
+                getCommonAlphabetLayout(isPhone));
+        if (elementId == KeyboardId.ELEMENT_ALPHABET
+                || elementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED) {
+            builder.addKeysOnTheLeftOfRow(1,
+                    key("'", joinMoreKeys(additionalMoreKey("1"), "!", "\"")),
+                    key(",", joinMoreKeys(additionalMoreKey("2"), "?", "<")),
+                    key(".", joinMoreKeys(additionalMoreKey("3"), ">")));
+        } else {
+            builder.addKeysOnTheLeftOfRow(1,
+                    key("\"", additionalMoreKey("1")),
+                    key("<", additionalMoreKey("2")),
+                    key(">", additionalMoreKey("3")));
+        }
+        convertCommonLayoutToKeyboard(builder, isPhone);
+        getCustomizer().setAccentedLetters(builder);
+        if (elementId != KeyboardId.ELEMENT_ALPHABET) {
+            builder.toUpperCase(getLocale());
+            builder.replaceKeysOfAll(SHIFT_KEY, SHIFTED_SHIFT_KEY);
+        }
+        return builder.build();
+    }
+
+    private static final ExpectedKey[][] ALPHABET_COMMON = new ExpectedKeyboardBuilder()
+            .setKeysOfRow(1,
+                    key("p", additionalMoreKey("4")),
+                    key("y", additionalMoreKey("5")),
+                    key("f", additionalMoreKey("6")),
+                    key("g", additionalMoreKey("7")),
+                    key("c", additionalMoreKey("8")),
+                    key("r", additionalMoreKey("9")),
+                    key("l", additionalMoreKey("0")))
+            .setKeysOfRow(2, "a", "o", "e", "u", "i", "d", "h", "t", "n", "s")
+            .setKeysOfRow(3, "j", "k", "x", "b", "m", "w", "v")
+            .build();
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/EastSlavic.java b/tests/src/com/android/inputmethod/keyboard/layout/EastSlavic.java
index 6d2e245..7fcc974 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/EastSlavic.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/EastSlavic.java
@@ -63,47 +63,47 @@
     private static final ExpectedKey[][] ALPHABET_COMMON = new ExpectedKeyboardBuilder()
             .setKeysOfRow(1,
                     // U+0443: "у" CYRILLIC SMALL LETTER U
-                    key("\u0439", moreKey("1")),
+                    key("\u0439", additionalMoreKey("1")),
                     // U+0446: "ц" CYRILLIC SMALL LETTER TSE
-                    key("\u0446", moreKey("2")),
+                    key("\u0446", additionalMoreKey("2")),
                     // U+0439: "й" CYRILLIC SMALL LETTER SHORT I
-                    key("\u0443", moreKey("3")),
+                    key("\u0443", additionalMoreKey("3")),
                     // U+043A: "к" CYRILLIC SMALL LETTER KA
-                    key("\u043A", moreKey("4")),
+                    key("\u043A", additionalMoreKey("4")),
                     // U+0435: "е" CYRILLIC SMALL LETTER IE
-                    key("\u0435", moreKey("5")),
+                    key("\u0435", additionalMoreKey("5")),
                     // U+043D: "н" CYRILLIC SMALL LETTER EN
-                    key("\u043D", moreKey("6")),
+                    key("\u043D", additionalMoreKey("6")),
                     // U+0433: "г" CYRILLIC SMALL LETTER GHE
-                    key("\u0433", moreKey("7")),
+                    key("\u0433", additionalMoreKey("7")),
                     // U+0448: "ш" CYRILLIC SMALL LETTER SHA
-                    key("\u0448", moreKey("8")),
-                    key(ROW1_9, moreKey("9")),
+                    key("\u0448", additionalMoreKey("8")),
+                    key(ROW1_9, additionalMoreKey("9")),
                     // U+0437: "з" CYRILLIC SMALL LETTER ZE
-                    key("\u0437", moreKey("0")),
+                    key("\u0437", additionalMoreKey("0")),
                     // U+0445: "х" CYRILLIC SMALL LETTER HA
-                    key("\u0445"))
-            // U+0444: "ф" CYRILLIC SMALL LETTER EF
-            // U+0432: "в" CYRILLIC SMALL LETTER VE
-            // U+0430: "а" CYRILLIC SMALL LETTER A
-            // U+043F: "п" CYRILLIC SMALL LETTER PE
-            // U+0440: "р" CYRILLIC SMALL LETTER ER
-            // U+043E: "о" CYRILLIC SMALL LETTER O
-            // U+043B: "л" CYRILLIC SMALL LETTER EL
-            // U+0434: "д" CYRILLIC SMALL LETTER DE
-            // U+0436: "ж" CYRILLIC SMALL LETTER ZHE
-            .setLabelsOfRow(2,
+                    "\u0445")
+            .setKeysOfRow(2,
+                    // U+0444: "ф" CYRILLIC SMALL LETTER EF
+                    // U+0432: "в" CYRILLIC SMALL LETTER VE
+                    // U+0430: "а" CYRILLIC SMALL LETTER A
+                    // U+043F: "п" CYRILLIC SMALL LETTER PE
+                    // U+0440: "р" CYRILLIC SMALL LETTER ER
+                    // U+043E: "о" CYRILLIC SMALL LETTER O
+                    // U+043B: "л" CYRILLIC SMALL LETTER EL
+                    // U+0434: "д" CYRILLIC SMALL LETTER DE
+                    // U+0436: "ж" CYRILLIC SMALL LETTER ZHE
                     "\u0444", ROW2_2, "\u0432", "\u0430", "\u043F", "\u0440", "\u043E", "\u043B",
                     "\u0434", "\u0436", ROW2_11)
-            // U+044F: "я" CYRILLIC SMALL LETTER YA
-            // U+0447: "ч" CYRILLIC SMALL LETTER CHE
-            // U+0441: "с" CYRILLIC SMALL LETTER ES
-            // U+043C: "м" CYRILLIC SMALL LETTER EM
-            // U+0442: "т" CYRILLIC SMALL LETTER TE
-            // U+044C: "ь" CYRILLIC SMALL LETTER SOFT SIGN
-            // U+0431: "б" CYRILLIC SMALL LETTER BE
-            // U+044E: "ю" CYRILLIC SMALL LETTER YU
-            .setLabelsOfRow(3,
+            .setKeysOfRow(3,
+                    // U+044F: "я" CYRILLIC SMALL LETTER YA
+                    // U+0447: "ч" CYRILLIC SMALL LETTER CHE
+                    // U+0441: "с" CYRILLIC SMALL LETTER ES
+                    // U+043C: "м" CYRILLIC SMALL LETTER EM
+                    // U+0442: "т" CYRILLIC SMALL LETTER TE
+                    // U+044C: "ь" CYRILLIC SMALL LETTER SOFT SIGN
+                    // U+0431: "б" CYRILLIC SMALL LETTER BE
+                    // U+044E: "ю" CYRILLIC SMALL LETTER YU
                     "\u044F", "\u0447", "\u0441", "\u043C", ROW3_5, "\u0442", "\u044C", "\u0431",
                     "\u044E")
             .build();
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Farsi.java b/tests/src/com/android/inputmethod/keyboard/layout/Farsi.java
index afec463..a007089 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/Farsi.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Farsi.java
@@ -70,7 +70,7 @@
         public ExpectedKey[] getKeysLeftToSpacebar(final boolean isPhone) {
             if (isPhone) {
                 // U+060C: "،" ARABIC COMMA
-                return joinKeys(key("\u060C", joinMoreKeys(",", SETTINGS_KEY)));
+                return joinKeys(key("\u060C", SETTINGS_KEY));
             }
             return super.getKeysLeftToSpacebar(isPhone);
         }
@@ -148,7 +148,7 @@
         }
         final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(ALPHABET_COMMON);
         // U+0622: "آ" ARABIC LETTER ALEF WITH MADDA ABOVE
-        builder.insertKeysAtRow(3, 10, key("\u0622"));
+        builder.insertKeysAtRow(3, 10, "\u0622");
         return builder.build();
     }
 
@@ -195,12 +195,11 @@
                     // U+06F0: "۰" EXTENDED ARABIC-INDIC DIGIT ZERO
                     key("\u062D", joinMoreKeys("\u06F0", "0")),
                     // U+062C: "ج" ARABIC LETTER JEEM
-                    key("\u062C"))
+                    "\u062C")
             .setKeysOfRow(2,
                     // U+0634: "ش" ARABIC LETTER SHEEN
-                    key("\u0634"),
                     // U+0633: "س" ARABIC LETTER SEEN
-                    key("\u0633"),
+                    "\u0634", "\u0633",
                     // U+06CC: "ی" ARABIC LETTER FARSI YEH
                     // U+0626: "ئ" ARABIC LETTER YEH WITH HAMZA ABOVE
                     // U+064A: "ي" ARABIC LETTER YEH
@@ -208,9 +207,8 @@
                     // U+0649: "ى" ARABIC LETTER ALEF MAKSURA
                     key("\u06CC", joinMoreKeys("\u0626", "\u064A", moreKey("\uFBE8", "\u0649"))),
                     // U+0628: "ب" ARABIC LETTER BEH
-                    key("\u0628"),
                     // U+0644: "ل" ARABIC LETTER LAM
-                    key("\u0644"),
+                    "\u0628", "\u0644",
                     // U+0627: "ا" ARABIC LETTER ALEF
                     // U+0671: "ٱ" ARABIC LETTER ALEF WASLA
                     // U+0621: "ء" ARABIC LETTER HAMZA
@@ -222,15 +220,14 @@
                     // U+0629: "ة": ARABIC LETTER TEH MARBUTA
                     key("\u062A", moreKey("\u0629")),
                     // U+0646: "ن" ARABIC LETTER NOON
-                    key("\u0646"),
                     // U+0645: "م" ARABIC LETTER MEEM
-                    key("\u0645"),
+                    "\u0646", "\u0645",
                     // U+06A9: "ک" ARABIC LETTER KEHEH
                     // U+0643: "ك" ARABIC LETTER KAF
                     key("\u06A9", moreKey("\u0643")),
                     // U+06AF: "گ" ARABIC LETTER GAF
-                    key("\u06AF"))
-            .setKeysOfRow(3, joinKeys(
+                    "\u06AF")
+            .setKeysOfRow(3,
                     // U+0638: "ظ" ARABIC LETTER ZAH
                     // U+0637: "ط" ARABIC LETTER TAH
                     // U+0698: "ژ" ARABIC LETTER JEH
@@ -244,7 +241,7 @@
                     // U+0624: "ؤ" ARABIC LETTER WAW WITH HAMZA ABOVE
                     key("\u0648", moreKey("\u0624")),
                     // U+0686: "چ" ARABIC LETTER TCHEH
-                    "\u0686"))
+                    "\u0686")
             .build();
 
     private static class FarsiSymbols extends RtlSymbols {
@@ -318,7 +315,7 @@
                     // U+00BF: "¿" INVERTED QUESTION MARK
                     .replaceKeyOfLabel("?", key("\u061F", joinMoreKeys("?", "\u00BF")))
                     // U+060C: "،" ARABIC COMMA
-                    .replaceKeyOfLabel(",", key("\u060C", moreKey(",")))
+                    .replaceKeyOfLabel(",", "\u060C")
                     // U+FD3E: "﴾" ORNATE LEFT PARENTHESIS
                     // U+FD3F: "﴿" ORNATE RIGHT PARENTHESIS
                     .replaceKeyOfLabel("(", key("(", ")",
@@ -348,7 +345,7 @@
                     // U+266A: "♪" EIGHTH NOTE
                     .setMoreKeysOf("\u2022", "\u266A")
                     // U+060C: "،" ARABIC COMMA
-                    .replaceKeyOfLabel(",", key("\u060C", moreKey(",")))
+                    .replaceKeyOfLabel(",", "\u060C")
                     // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
                     // U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
                     // U+2264: "≤" LESS-THAN OR EQUAL TO
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Georgian.java b/tests/src/com/android/inputmethod/keyboard/layout/Georgian.java
index ad87c3b..6f20dfc 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/Georgian.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Georgian.java
@@ -99,9 +99,8 @@
                     // U+10FA: "ჺ" GEORGIAN LETTER AIN
                     key("\u10D0", moreKey("\u10FA")),
                     // U+10E1: "ს" GEORGIAN LETTER SAN
-                    key("\u10E1"),
                     // U+10D3: "დ" GEORGIAN LETTER DON
-                    key("\u10D3"),
+                    "\u10E1", "\u10D3",
                     // U+10E4: "ფ" GEORGIAN LETTER PHAR
                     // U+10F6: "ჶ" GEORGIAN LETTER FI
                     key("\u10E4", moreKey("\u10F6")),
@@ -115,27 +114,26 @@
                     // U+10F7: "ჷ" GEORGIAN LETTER YN
                     key("\u10EF", moreKey("\u10F7")),
                     // U+10D9: "კ" GEORGIAN LETTER KAN
-                    key("\u10D9"),
                     // U+10DA: "ლ" GEORGIAN LETTER LAS
-                    key("\u10DA"))
+                    "\u10D9", "\u10DA")
             .setKeysOfRow(3,
                     // U+10D6: "ზ" GEORGIAN LETTER ZEN
-                    key("\u10D6"),
+                    "\u10D6",
                     // U+10EE: "ხ" GEORGIAN LETTER XAN
                     // U+10F4: "ჴ" GEORGIAN LETTER HAR
                     key("\u10EE", moreKey("\u10F4")),
                     // U+10EA: "ც" GEORGIAN LETTER CAN
-                    key("\u10EA"),
+                    "\u10EA",
                     // U+10D5: "ვ" GEORGIAN LETTER VIN
                     // U+10F3: "ჳ" GEORGIAN LETTER WE
                     key("\u10D5", moreKey("\u10F3")),
                     // U+10D1: "ბ" GEORGIAN LETTER BAN
-                    key("\u10D1"),
+                    "\u10D1",
                     // U+10DC: "ნ" GEORGIAN LETTER NAR
                     // U+10FC: "ჼ" MODIFIER LETTER GEORGIAN NAR
                     key("\u10DC", moreKey("\u10FC")),
                     // U+10DB: "მ" GEORGIAN LETTER MAN
-                    key("\u10DB"))
+                    "\u10DB")
             .build();
 
     private static final ExpectedKey[][] ALPHABET_SHIFTED_COMMON = new ExpectedKeyboardBuilder()
@@ -154,26 +152,12 @@
                     key("O", moreKey("9")),
                     key("P", moreKey("0")))
             .setKeysOfRow(2,
-                    key("A"),
                     // U+10E8: "შ" GEORGIAN LETTER SHIN
-                    key("\u10E8"),
-                    key("D"),
-                    key("F"),
-                    key("G"),
-                    key("H"),
                     // U+10DF: "ჟ" GEORGIAN LETTER ZHAR
-                    key("\u10DF"),
-                    key("K"),
-                    key("L"))
+                    "A", "\u10E8", "D", "F", "G", "H", "\u10DF", "K", "L")
             .setKeysOfRow(3,
                     // U+10EB: "ძ" GEORGIAN LETTER JIL
-                    key("\u10EB"),
-                    key("X"),
                     // U+10E9: "ჩ" GEORGIAN LETTER CHIN
-                    key("\u10E9"),
-                    key("V"),
-                    key("B"),
-                    key("N"),
-                    key("M"))
+                    "\u10EB", "X", "\u10E9", "V", "B", "N", "M")
             .build();
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Greek.java b/tests/src/com/android/inputmethod/keyboard/layout/Greek.java
index 762170b..0ec9f4c 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/Greek.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Greek.java
@@ -36,7 +36,7 @@
     @Override
     public String getName() { return LAYOUT_NAME; }
 
-    public static class GreekCustomizer extends EuroLayoutCustomizer {
+    public static class GreekCustomizer extends EuroCustomizer {
         public GreekCustomizer(final Locale locale) { super(locale); }
 
         @Override
@@ -112,37 +112,28 @@
                     // U+03AC: "ά" GREEK SMALL LETTER ALPHA WITH TONOS
                     key("\u03B1", moreKey("\u03AC")),
                     // U+03C3: "σ" GREEK SMALL LETTER SIGMA
-                    key("\u03C3"),
                     // U+03B4: "δ" GREEK SMALL LETTER DELTA
-                    key("\u03B4"),
                     // U+03C6: "φ" GREEK SMALL LETTER PHI
-                    key("\u03C6"),
                     // U+03B3: "γ" GREEK SMALL LETTER GAMMA
-                    key("\u03B3"),
+                    "\u03C3", "\u03B4", "\u03C6", "\u03B3",
                     // U+03B7: "η" GREEK SMALL LETTER ETA
                     // U+03AE: "ή" GREEK SMALL LETTER ETA WITH TONOS
                     key("\u03B7", moreKey("\u03AE")),
                     // U+03BE: "ξ" GREEK SMALL LETTER XI
-                    key("\u03BE"),
                     // U+03BA: "κ" GREEK SMALL LETTER KAPPA
-                    key("\u03BA"),
                     // U+03BB: "λ" GREEK SMALL LETTER LAMDA
-                    key("\u03BB"))
+                    "\u03BE", "\u03BA", "\u03BB")
             .setKeysOfRow(3,
                     // U+03B6: "ζ" GREEK SMALL LETTER ZETA
-                    key("\u03B6"),
                     // U+03C7: "χ" GREEK SMALL LETTER CHI
-                    key("\u03C7"),
                     // U+03C8: "ψ" GREEK SMALL LETTER PSI
-                    key("\u03C8"),
+                    "\u03B6", "\u03C7", "\u03C8",
                     // U+03C9: "ω" GREEK SMALL LETTER OMEGA
                     // U+03CE: "ώ" GREEK SMALL LETTER OMEGA WITH TONOS
                     key("\u03C9", moreKey("\u03CE")),
                     // U+03B2: "β" GREEK SMALL LETTER BETA
-                    key("\u03B2"),
                     // U+03BD: "ν" GREEK SMALL LETTER NU
-                    key("\u03BD"),
                     // U+03BC: "μ" GREEK SMALL LETTER MU
-                    key("\u03BC"))
+                    "\u03B2", "\u03BD", "\u03BC")
             .build();
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Hebrew.java b/tests/src/com/android/inputmethod/keyboard/layout/Hebrew.java
index a5befab..552f0d3 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/Hebrew.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Hebrew.java
@@ -91,12 +91,12 @@
         private static final ExpectedKey CURRENCY_NEW_SHEQEL = key("\u20AA",
                 Symbols.CURRENCY_GENERIC_MORE_KEYS);
         private static final ExpectedKey[] RTL_PHONE_PUNCTUATION_MORE_KEYS = joinKeys(
-                ";", "/", key("(", ")"), key(")", "("), "#", "!", ",", "?",
-                "&", "%", "+", "\"", "-", ":", "'", "@");
+                ",", "?", "!", "#", key(")", "("), key("(", ")"), "/", ";",
+                "'", "@", ":", "-", "\"", "+", "%", "&");
         // Punctuation more keys for tablet form factor.
         private static final ExpectedKey[] RTL_TABLET_PUNCTUATION_MORE_KEYS = joinKeys(
-                ";", "/", key("(", ")"), key(")", "("), "#", "'", ",",
-                "&", "%", "+", "\"", "-", ":", "@");
+                ",", "'", "#", key(")", "("), key("(", ")"), "/", ";",
+                "@", ":", "-", "\"", "+", "%", "&");
     }
 
     @Override
@@ -129,16 +129,14 @@
                     key("\u05E4", moreKey("0")))
             .setKeysOfRow(2,
                     // U+05E9: "ש" HEBREW LETTER SHIN
-                    key("\u05E9"),
                     // U+05D3: "ד" HEBREW LETTER DALET
-                    key("\u05D3"),
+                    "\u05E9", "\u05D3",
                     // U+05D2: "ג" HEBREW LETTER GIMEL
                     // U+05D2 U+05F3: "ג׳" HEBREW LETTER GIMEL + HEBREW PUNCTUATION GERESH
                     key("\u05D2", moreKey("\u05D2\u05F3")),
                     // U+05DB: "כ" HEBREW LETTER KAF
-                    key("\u05DB"),
                     // U+05E2: "ע" HEBREW LETTER AYIN
-                    key("\u05E2"),
+                    "\u05DB", "\u05E2",
                     // U+05D9: "י" HEBREW LETTER YOD
                     // U+05F2 U+05B7: "ײַ" HEBREW LIGATURE YIDDISH DOUBLE YOD + HEBREW POINT PATAH
                     key("\u05D9", moreKey("\u05F2\u05B7")),
@@ -146,25 +144,19 @@
                     // U+05D7 U+05F3: "ח׳" HEBREW LETTER HET + HEBREW PUNCTUATION GERESH
                     key("\u05D7", moreKey("\u05D7\u05F3")),
                     // U+05DC: "ל" HEBREW LETTER LAMED
-                    key("\u05DC"),
                     // U+05DA: "ך" HEBREW LETTER FINAL KAF
-                    key("\u05DA"),
                     // U+05E3: "ף" HEBREW LETTER FINAL PE
-                    key("\u05E3"))
+                    "\u05DC", "\u05DA", "\u05E3")
             .setKeysOfRow(3,
                     // U+05D6: "ז" HEBREW LETTER ZAYIN
                     // U+05D6 U+05F3: "ז׳" HEBREW LETTER ZAYIN + HEBREW PUNCTUATION GERESH
                     key("\u05D6", moreKey("\u05D6\u05F3")),
                     // U+05E1: "ס" HEBREW LETTER SAMEKH
-                    key("\u05E1"),
                     // U+05D1: "ב" HEBREW LETTER BET
-                    key("\u05D1"),
                     // U+05D4: "ה" HEBREW LETTER HE
-                    key("\u05D4"),
                     // U+05E0: "נ" HEBREW LETTER NUN
-                    key("\u05E0"),
                     // U+05DE: "מ" HEBREW LETTER MEM
-                    key("\u05DE"),
+                    "\u05E1", "\u05D1", "\u05D4", "\u05E0", "\u05DE",
                     // U+05E6: "צ" HEBREW LETTER TSADI
                     // U+05E6 U+05F3: "צ׳" HEBREW LETTER TSADI + HEBREW PUNCTUATION GERESH
                     key("\u05E6", moreKey("\u05E6\u05F3")),
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Hindi.java b/tests/src/com/android/inputmethod/keyboard/layout/Hindi.java
index c1d1616..7ff2dcb 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/Hindi.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Hindi.java
@@ -155,7 +155,7 @@
                     // U+0947/U+0902: "ें" DEVANAGARI VOWEL SIGN E/DEVANAGARI SIGN ANUSVARA
                     key("\u0947", moreKey("\u0947\u0902")),
                     // U+094D: "्" DEVANAGARI SIGN VIRAMA
-                    key("\u094D"),
+                    "\u094D",
                     // U+093F: "ि" DEVANAGARI VOWEL SIGN I
                     // U+093F/U+0902: "िं" DEVANAGARI VOWEL SIGN I/DEVANAGARI SIGN ANUSVARA
                     key("\u093F", moreKey("\u093F\u0902")),
@@ -164,7 +164,7 @@
                     // U+0941/U+0901: "ुँ" DEVANAGARI VOWEL SIGN U/DEVANAGARI SIGN CANDRABINDU
                     key("\u0941", joinMoreKeys("\u0941\u0902", "\u0941\u0901")),
                     // U+092A: "प" DEVANAGARI LETTER PA
-                    key("\u092A"),
+                    "\u092A",
                     // U+0930: "र" DEVANAGARI LETTER RA
                     // U+090B: "ऋ" DEVANAGARI LETTER VOCALIC R
                     // U+0930/U+093C: "ऱ" DEVANAGARI LETTER RA/DEVANAGARI SIGN NUKTA
@@ -178,14 +178,12 @@
                     //     "त्र" DEVANAGARI LETTER TA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER RA
                     key("\u0924", moreKey("\u0924\u094D\u0930")),
                     // U+091A: "च" DEVANAGARI LETTER CA
-                    key("\u091A"),
                     // U+091F: "ट" DEVANAGARI LETTER TTA
-                    key("\u091F"))
+                    "\u091A","\u091F")
             .setKeysOfRow(3,
                     // U+0949: "ॉ" DEVANAGARI VOWEL SIGN CANDRA O
-                    key("\u0949"),
                     // U+0902: "ं" DEVANAGARI SIGN ANUSVARA
-                    key("\u0902"),
+                    "\u0949", "\u0902",
                     // U+092E: "म" DEVANAGARI LETTER MA
                     // U+0950: "ॐ" DEVANAGARI OM
                     key("\u092E", moreKey("\u0950")),
@@ -195,13 +193,13 @@
                     // U+0928/U+093C: "ऩ" DEVANAGARI LETTER NA/DEVANAGARI SIGN NUKTA
                     key("\u0928", joinMoreKeys("\u091E", "\u0919", "\u0928\u093C")),
                     // U+0935: "व" DEVANAGARI LETTER VA
-                    key("\u0935"),
+                    "\u0935",
                     // U+0932: "ल" DEVANAGARI LETTER LA
                     // U+090C: "ऌ" DEVANAGARI LETTER VOCALIC L
                     // U+0961: "ॡ" DEVANAGARI LETTER VOCALIC LL
                     key("\u0932", joinMoreKeys("\u090C", "\u0961")),
                     // U+0938: "स" DEVANAGARI LETTER SA
-                    key("\u0938"),
+                    "\u0938",
                     // U+092F: "य" DEVANAGARI LETTER YA
                     // U+095F: "य़" DEVANAGARI LETTER YYA
                     key("\u092F", moreKey("\u095F")),
@@ -232,11 +230,9 @@
                     // U+090A/U+0901: "ऊँ" DEVANAGARI LETTER UU/DEVANAGARI SIGN CANDRABINDU
                     key("\u090A", joinMoreKeys("\u090A\u0902", "\u090A\u0901")),
                     // U+092D: "भ" DEVANAGARI LETTER BHA
-                    key("\u092D"),
                     // U+0903: "ः" DEVANAGARI SIGN VISARGA
-                    key("\u0903"),
                     // U+0918: "घ" DEVANAGARI LETTER GHA
-                    key("\u0918"),
+                    "\u092D", "\u0903", "\u0918",
                     // U+0927: "ध" DEVANAGARI LETTER DHA
                     // U+0915/U+094D/U+0937:
                     //     "क्ष" DEVANAGARI LETTER KA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER SSA
@@ -244,9 +240,8 @@
                     //     "श्र" DEVANAGARI LETTER SHA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER RA
                     key("\u0927", joinMoreKeys("\u0915\u094D\u0937", "\u0936\u094D\u0930")),
                     // U+091D: "झ" DEVANAGARI LETTER JHA
-                    key("\u091D"),
                     // U+0922: "ढ" DEVANAGARI LETTER DDHA
-                    key("\u0922"))
+                    "\u091D", "\u0922")
             .setKeysOfRow(2,
                     // U+0913: "ओ" DEVANAGARI LETTER O
                     // U+0913/U+0902: "ओं" DEVANAGARI LETTER O/DEVANAGARI SIGN ANUSVARA
@@ -282,33 +277,29 @@
                     // U+0916/U+093C: "ख़" DEVANAGARI LETTER KHA/DEVANAGARI SIGN NUKTA
                     key("\u0916", moreKey("\u0916\u093C")),
                     // U+0925: "थ" DEVANAGARI LETTER THA
-                    key("\u0925"),
                     // U+091B: "छ" DEVANAGARI LETTER CHA
-                    key("\u091B"),
                     // U+0920: "ठ" DEVANAGARI LETTER TTHA
-                    key("\u0920"))
+                    "\u0925", "\u091B", "\u0920")
             .setKeysOfRow(3,
                     // U+0911: "ऑ" DEVANAGARI LETTER CANDRA O
-                    key("\u0911"),
+                    "\u0911",
                     // U+0901: "ँ" DEVANAGARI SIGN CANDRABINDU
                     // U+0945: "ॅ" DEVANAGARI VOWEL SIGN CANDRA E
                     key("\u0901", moreKey("\u0945")),
                     // U+0923: "ण" DEVANAGARI LETTER NNA
-                    key("\u0923"),
                     // U+0929: "ऩ" DEVANAGARI LETTER NNNA
-                    key("\u0929"),
+                    "\u0923", "\u0929",
                     // U+0933: "ळ" DEVANAGARI LETTER LLA
                     // U+0934: "ऴ" DEVANAGARI LETTER LLLA
                     key("\u0933", moreKey("\u0934")),
                     // U+0936: "श" DEVANAGARI LETTER SHA
-                    key("\u0936"),
                     // U+0937: "ष" DEVANAGARI LETTER SSA
-                    key("\u0937"),
+                    "\u0936", "\u0937",
                     // U+0943: "ृ" DEVANAGARI VOWEL SIGN VOCALIC R
                     // U+0944: "ॄ" DEVANAGARI VOWEL SIGN VOCALIC RR
                     key("\u0943", moreKey("\u0944")),
                     // U+091E: "ञ" DEVANAGARI LETTER NYA
-                    key("\u091E"))
+                    "\u091E")
             .build();
 
     static class HindiSymbols extends Symbols {
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Khmer.java b/tests/src/com/android/inputmethod/keyboard/layout/Khmer.java
index 61ade8b..e7f6a65 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/Khmer.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Khmer.java
@@ -66,7 +66,7 @@
             return ALPHABET_COMMON;
         }
         final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(ALPHABET_COMMON);
-        builder.addKeysOnTheRightOfRow(4, EXCLAMATION_AND_QUESTION_MARKS);
+        builder.addKeysOnTheRightOfRow(4, (Object[])EXCLAMATION_AND_QUESTION_MARKS);
         return builder.build();
     }
 
@@ -84,11 +84,9 @@
     ExpectedKeyboardBuilder convertCommonLayoutToKeyboard(final ExpectedKeyboardBuilder builder,
             final boolean isPhone) {
         final LayoutCustomizer customizer = getCustomizer();
-        final ExpectedKey[] spacebar = joinKeys(
-                customizer.getKeysLeftToSpacebar(isPhone),
-                customizer.getSpaceKeys(isPhone),
-                customizer.getKeysRightToSpacebar(isPhone));
-        builder.setKeysOfRow(5, spacebar);
+        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())
@@ -99,8 +97,8 @@
                     .addKeysOnTheLeftOfRow(5, customizer.getSymbolsKey(), SETTINGS_KEY)
                     .addKeysOnTheRightOfRow(5, EMOJI_KEY);
         }
-        builder.addKeysOnTheLeftOfRow(4, customizer.getLeftShiftKeys(isPhone))
-                .addKeysOnTheRightOfRow(4, customizer.getRightShiftKeys(isPhone));
+        builder.addKeysOnTheLeftOfRow(4, (Object[])customizer.getLeftShiftKeys(isPhone))
+                .addKeysOnTheRightOfRow(4, (Object[])customizer.getRightShiftKeys(isPhone));
         return builder;
     }
 
@@ -144,27 +142,18 @@
                     key("\u17B2", moreKey("\u17B1")))
             .setKeysOfRow(2,
                     // U+1786: "ឆ" KHMER LETTER CHA
-                    key("\u1786"),
                     // U+17B9: "ឹ" KHMER VOWEL SIGN Y
-                    key("\u17B9"),
                     // U+17C1: "េ" KHMER VOWEL SIGN E
-                    key("\u17C1"),
                     // U+179A: "រ" KHMER LETTER RO
-                    key("\u179A"),
                     // U+178F: "ត" KHMER LETTER TA
-                    key("\u178F"),
                     // U+1799: "យ" KHMER LETTER YO
-                    key("\u1799"),
                     // U+17BB: "ុ" KHMER VOWEL SIGN U
-                    key("\u17BB"),
                     // U+17B7: "ិ" KHMER VOWEL SIGN I
-                    key("\u17B7"),
                     // U+17C4: "ោ" KHMER VOWEL SIGN OO
-                    key("\u17C4"),
                     // U+1795: "ផ" KHMER LETTER PHA
-                    key("\u1795"),
                     // U+17C0: "ៀ" KHMER VOWEL SIGN IE
-                    key("\u17C0"),
+                    "\u1786", "\u17B9", "\u17C1", "\u179A", "\u178F", "\u1799", "\u17BB", "\u17B7",
+                    "\u17C4", "\u1795", "\u17C0",
                     // U+17AA: "ឪ" KHMER INDEPENDENT VOWEL QUUV
                     // U+17A7: "ឧ" KHMER INDEPENDENT VOWEL QU
                     // U+17B1: "ឱ" KHMER INDEPENDENT VOWEL QOO TYPE ONE
@@ -174,32 +163,23 @@
                     key("\u17AA", joinMoreKeys("\u17A7", "\u17B1", "\u17B3", "\u17A9", "\u17A8")))
             .setKeysOfRow(3,
                     // U+17B6: "ា" KHMER VOWEL SIGN AA
-                    key("\u17B6"),
                     // U+179F: "ស" KHMER LETTER SA
-                    key("\u179F"),
                     // U+178A: "ដ" KHMER LETTER DA
-                    key("\u178A"),
                     // U+1790: "ថ" KHMER LETTER THA
-                    key("\u1790"),
                     // U+1784: "ង" KHMER LETTER NGO
-                    key("\u1784"),
                     // U+17A0: "ហ" KHMER LETTER HA
-                    key("\u17A0"),
                     // U+17D2: "្" KHMER SIGN COENG
-                    key("\u17D2"),
                     // U+1780: "ក" KHMER LETTER KA
-                    key("\u1780"),
                     // U+179B: "ល" KHMER LETTER LO
-                    key("\u179B"),
                     // U+17BE: "ើ" KHMER VOWEL SIGN OE
-                    key("\u17BE"),
                     // U+17CB: "់" KHMER SIGN BANTOC
-                    key("\u17CB"),
+                    "\u17B6", "\u179F", "\u178A", "\u1790", "\u1784", "\u17A0", "\u17D2", "\u1780",
+                    "\u179B", "\u17BE", "\u17CB",
                     // U+17AE: "ឮ" KHMER INDEPENDENT VOWEL LYY
                     // U+17AD: "ឭ" KHMER INDEPENDENT VOWEL LY
                     // U+17B0: "ឰ" KHMER INDEPENDENT VOWEL QAI
                     key("\u17AE", joinMoreKeys("\u17AD", "\u17B0")))
-            .setLabelsOfRow(4,
+            .setKeysOfRow(4,
                     // U+178B: "ឋ" KHMER LETTER TTHA
                     // U+1781: "ខ" KHMER LETTER KHA
                     // U+1785: "ច" KHMER LETTER CA
@@ -241,7 +221,7 @@
                     // U+00D7: "×" MULTIPLICATION SIGN
                     key("\u17CC", moreKey("\u00D7")),
                     // U+17CE: "៎" KHMER SIGN KAKABAT
-                    key("\u17CE"))
+                    "\u17CE")
             .setKeysOfRow(2,
                     // U+1788: "ឈ" KHMER LETTER CHO
                     // U+17DC: "ៜ" KHMER SIGN AVAKRAHASANYA
@@ -250,73 +230,52 @@
                     // U+17DD: "៝" KHMER SIGN ATTHACAN
                     key("\u17BA", moreKey("\u17DD")),
                     // U+17C2: "ែ" KHMER VOWEL SIGN AE
-                    key("\u17C2"),
+                    "\u17C2",
                     // U+17AC: "ឬ" KHMER INDEPENDENT VOWEL RYY
                     // U+17AB: "ឫ" KHMER INDEPENDENT VOWEL RY
                     key("\u17AC", moreKey("\u17AB")),
                     // U+1791: "ទ" KHMER LETTER TO
-                    key("\u1791"),
                     // U+17BD: "ួ" KHMER VOWEL SIGN UA
-                    key("\u17BD"),
                     // U+17BC: "ូ" KHMER VOWEL SIGN UU
-                    key("\u17BC"),
                     // U+17B8: "ី" KHMER VOWEL SIGN II
-                    key("\u17B8"),
                     // U+17C5: "ៅ" KHMER VOWEL SIGN AU
-                    key("\u17C5"),
                     // U+1797: "ភ" KHMER LETTER PHO
-                    key("\u1797"),
                     // U+17BF: "ឿ" KHMER VOWEL SIGN YA
-                    key("\u17BF"),
                     // U+17B0: "ឰ" KHMER INDEPENDENT VOWEL QAI
-                    key("\u17B0"))
+                    "\u1791", "\u17BD", "\u17BC", "\u17B8", "\u17C5", "\u1797", "\u17BF", "\u17B0")
             .setKeysOfRow(3,
                     // U+17B6/U+17C6: "ាំ" KHMER VOWEL SIGN AA/KHMER SIGN NIKAHIT
-                    key("\u17B6\u17C6"),
                     // U+17C3: "ៃ" KHMER VOWEL SIGN AI
-                    key("\u17C3"),
                     // U+178C: "ឌ" KHMER LETTER DO
-                    key("\u178C"),
                     // U+1792: "ធ" KHMER LETTER THO
-                    key("\u1792"),
                     // U+17A2: "អ" KHMER LETTER QAE
-                    key("\u17A2"),
+                    "\u17B6\u17C6", "\u17C3", "\u178C", "\u1792", "\u17A2",
                     // U+17C7: "ះ" KHMER SIGN REAHMUK
                     // U+17C8: "ៈ" KHMER SIGN YUUKALEAPINTU
                     key("\u17C7", moreKey("\u17C8")),
                     // U+1789: "ញ" KHMER LETTER NYO
-                    key("\u1789"),
+                    "\u1789",
                     // U+1782: "គ" KHMER LETTER KO
                     // U+179D: "ឝ" KHMER LETTER SHA
                     key("\u1782", moreKey("\u179D")),
                     // U+17A1: "ឡ" KHMER LETTER LA
-                    key("\u17A1"),
                     // U+17C4/U+17C7: "ោះ" KHMER VOWEL SIGN OO/KHMER SIGN REAHMUK
-                    key("\u17C4\u17C7"),
                     // U+17C9: "៉" KHMER SIGN MUUSIKATOAN
-                    key("\u17C9"),
                     // U+17AF: "ឯ" KHMER INDEPENDENT VOWEL QE
-                    key("\u17AF"))
+                    "\u17A1", "\u17C4\u17C7", "\u17C9", "\u17AF")
             .setKeysOfRow(4,
                     // U+178D: "ឍ" KHMER LETTER TTHO
-                    key("\u178D"),
                     // U+1783: "ឃ" KHMER LETTER KHO
-                    key("\u1783"),
                     // U+1787: "ជ" KHMER LETTER CO
-                    key("\u1787"),
                     // U+17C1/U+17C7: "េះ" KHMER VOWEL SIGN E/KHMER SIGN REAHMUK
-                    key("\u17C1\u17C7"),
+                    "\u178D", "\u1783", "\u1787", "\u17C1\u17C7",
                     // U+1796: "ព" KHMER LETTER PO
                     // U+179E: "ឞ" KHMER LETTER SSO
                     key("\u1796", moreKey("\u179E")),
                     // U+178E: "ណ" KHMER LETTER NNO
-                    key("\u178E"),
                     // U+17C6: "ំ" KHMER SIGN NIKAHIT
-                    key("\u17C6"),
                     // U+17BB/U+17C7: "ុះ" KHMER VOWEL SIGN U/KHMER SIGN REAHMUK
-                    key("\u17BB\u17C7"),
                     // U+17D5: "៕" KHMER SIGN BARIYOOSAN
-                    key("\u17D5"),
-                    key("?"))
+                    "\u178E", "\u17C6", "\u17BB\u17C7", "\u17D5", "?")
             .build();
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Lao.java b/tests/src/com/android/inputmethod/keyboard/layout/Lao.java
index 4889055..6f2ef21 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/Lao.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Lao.java
@@ -70,7 +70,7 @@
             return ALPHABET_COMMON;
         }
         final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(ALPHABET_COMMON);
-        builder.addKeysOnTheRightOfRow(4, EXCLAMATION_AND_QUESTION_MARKS);
+        builder.addKeysOnTheRightOfRow(4, (Object[])EXCLAMATION_AND_QUESTION_MARKS);
         return builder.build();
     }
 
@@ -88,11 +88,9 @@
     ExpectedKeyboardBuilder convertCommonLayoutToKeyboard(final ExpectedKeyboardBuilder builder,
             final boolean isPhone) {
         final LayoutCustomizer customizer = getCustomizer();
-        final ExpectedKey[] spacebar = joinKeys(
-                customizer.getKeysLeftToSpacebar(isPhone),
-                customizer.getSpaceKeys(isPhone),
-                customizer.getKeysRightToSpacebar(isPhone));
-        builder.setKeysOfRow(5, spacebar);
+        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())
@@ -103,8 +101,8 @@
                     .addKeysOnTheLeftOfRow(5, customizer.getSymbolsKey(), SETTINGS_KEY)
                     .addKeysOnTheRightOfRow(5, EMOJI_KEY);
         }
-        builder.addKeysOnTheLeftOfRow(4, customizer.getLeftShiftKeys(isPhone))
-                .addKeysOnTheRightOfRow(4, customizer.getRightShiftKeys(isPhone));
+        builder.addKeysOnTheLeftOfRow(4, (Object[])customizer.getLeftShiftKeys(isPhone))
+                .addKeysOnTheRightOfRow(4, (Object[])customizer.getRightShiftKeys(isPhone));
         return builder;
     }
 
@@ -123,9 +121,8 @@
                     // U+0ED4: "໔" LAO DIGIT FOUR
                     key("\u0E96", joinMoreKeys("4", "\u0ED4")),
                     // U+0EB8: "ຸ" LAO VOWEL SIGN U
-                    key("\u0EB8"),
                     // U+0EB9: "ູ" LAO VOWEL SIGN UU
-                    key("\u0EB9"),
+                    "\u0EB8", "\u0EB9",
                     // U+0E84: "ຄ" LAO LETTER KHO TAM
                     // U+0ED5: "໕" LAO DIGIT FIVE
                     key("\u0E84", joinMoreKeys("5", "\u0ED5")),
@@ -142,34 +139,26 @@
                     // U+0ED9: "໙" LAO DIGIT NINE
                     key("\u0E8A", joinMoreKeys("9", "\u0ED9")),
                     // U+0ECD: "ໍ" LAO NIGGAHITA
-                    key("\u0ECD"))
+                    "\u0ECD")
             .setKeysOfRow(2,
                     // U+0EBB: "ົ" LAO VOWEL SIGN MAI KON
-                    key("\u0EBB"),
+                    "\u0EBB",
                     // U+0EC4: "ໄ" LAO VOWEL SIGN AI
                     // U+0ED0: "໐" LAO DIGIT ZERO
                     key("\u0EC4", joinMoreKeys("0", "\u0ED0")),
                     // U+0EB3: "ຳ" LAO VOWEL SIGN AM
-                    key("\u0EB3"),
                     // U+0E9E: "ພ" LAO LETTER PHO TAM
-                    key("\u0E9E"),
                     // U+0EB0: "ະ" LAO VOWEL SIGN A
-                    key("\u0EB0"),
                     // U+0EB4: "ິ" LAO VOWEL SIGN I
-                    key("\u0EB4"),
                     // U+0EB5: "ີ" LAO VOWEL SIGN II
-                    key("\u0EB5"),
                     // U+0EAE: "ຮ" LAO LETTER HO TAM
-                    key("\u0EAE"),
                     // U+0E99: "ນ" LAO LETTER NO
-                    key("\u0E99"),
                     // U+0E8D: "ຍ" LAO LETTER NYO
-                    key("\u0E8D"),
                     // U+0E9A: "ບ" LAO LETTER BO
-                    key("\u0E9A"),
                     // U+0EA5: "ລ" LAO LETTER LO LOOT
-                    key("\u0EA5"))
-            .setLabelsOfRow(3,
+                    "\u0EB3", "\u0E9E", "\u0EB0", "\u0EB4", "\u0EB5", "\u0EAE", "\u0E99", "\u0E8D",
+                    "\u0E9A", "\u0EA5")
+            .setKeysOfRow(3,
                     // U+0EB1: "ັ" LAO VOWEL SIGN MAI KAN
                     // U+0EAB: "ຫ" LAO LETTER HO SUNG
                     // U+0E81: "ກ" LAO LETTER KO
@@ -184,7 +173,7 @@
                     // U+201C: "“" LEFT DOUBLE QUOTATION MARK
                     "\u0EB1", "\u0EAB", "\u0E81", "\u0E94", "\u0EC0", "\u0EC9", "\u0EC8", "\u0EB2",
                     "\u0EAA", "\u0EA7", "\u0E87", "\u201C")
-            .setLabelsOfRow(4,
+            .setKeysOfRow(4,
                     // U+0E9C: "ຜ" LAO LETTER PHO SUNG
                     // U+0E9B: "ປ" LAO LETTER PO
                     // U+0EC1: "ແ" LAO VOWEL SIGN EI
@@ -200,7 +189,7 @@
             .build();
 
     private static final ExpectedKey[][] ALPHABET_SHIFTED_COMMON = new ExpectedKeyboardBuilder()
-            .setLabelsOfRow(1,
+            .setKeysOfRow(1,
                     // U+0ED1: "໑" LAO DIGIT ONE
                     // U+0ED2: "໒" LAO DIGIT TWO
                     // U+0ED3: "໓" LAO DIGIT THREE
@@ -215,7 +204,7 @@
                     // U+0ECD/U+0EC8: "ໍ່" LAO NIGGAHITA/LAO TONE MAI EK
                     "\u0ED1", "\u0ED2", "\u0ED3", "\u0ED4", "\u0ECC", "\u0EBC", "\u0ED5", "\u0ED6",
                     "\u0ED7", "\u0ED8", "\u0ED9", "\u0ECD\u0EC8")
-            .setLabelsOfRow(2,
+            .setKeysOfRow(2,
                     // U+0EBB/U+0EC9: "" LAO VOWEL SIGN MAI KON/LAO TONE MAI THO
                     // U+0ED0: "໐" LAO DIGIT ZERO
                     // U+0EB3/U+0EC9: "ຳ້" LAO VOWEL SIGN AM/LAO TONE MAI THO
@@ -228,14 +217,14 @@
                     // U+201D: "”" RIGHT DOUBLE QUOTATION MARK
                     "\u0EBB\u0EC9", "\u0ED0", "\u0EB3\u0EC9", "_", "+", "\u0EB4\u0EC9",
                     "\u0EB5\u0EC9", "\u0EA3", "\u0EDC", "\u0EBD", "\u0EAB\u0EBC", "\u201D")
-            .setLabelsOfRow(3,
+            .setKeysOfRow(3,
                     // U+0EB1/U+0EC9: "ັ້" LAO VOWEL SIGN MAI KAN/LAO TONE MAI THO
                     // U+0ECA: "໊" LAO TONE MAI TI
                     // U+0ECB: "໋" LAO TONE MAI CATAWA
                     // U+201C: "“" LEFT DOUBLE QUOTATION MARK
                     "\u0EB1\u0EC9", ";", ".", ",", ":", "\u0ECA", "\u0ECB", "!", "?", "%", "=",
                     "\u201C")
-            .setLabelsOfRow(4,
+            .setKeysOfRow(4,
                     // U+20AD: "₭" KIP SIGN
                     // U+0EAF: "ຯ" LAO ELLIPSIS
                     // U+0EB6/U+0EC9: "ຶ້" LAO VOWEL SIGN Y/LAO TONE MAI THO
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/LayoutBase.java b/tests/src/com/android/inputmethod/keyboard/layout/LayoutBase.java
index 982777b..09cc8f9 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/LayoutBase.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/LayoutBase.java
@@ -161,7 +161,7 @@
          * @return the array of {@link ExpectedKey} that should be placed at left of the spacebar.
          */
         public ExpectedKey[] getKeysLeftToSpacebar(final boolean isPhone) {
-            return isPhone ? joinKeys(key(",", SETTINGS_KEY)) : joinKeys(key("/"));
+            return isPhone ? joinKeys(key(",", SETTINGS_KEY)) : joinKeys("/");
         }
 
         /**
@@ -171,7 +171,7 @@
          */
         public ExpectedKey[] getKeysRightToSpacebar(final boolean isPhone) {
             final ExpectedKey periodKey = key(".", getPunctuationMoreKeys(isPhone));
-            return isPhone ? joinKeys(periodKey) : joinKeys(key(","), periodKey);
+            return isPhone ? joinKeys(periodKey) : joinKeys(",", periodKey);
         }
 
         /**
@@ -188,8 +188,8 @@
     /**
      * The layout customize class for countries that use Euro.
      */
-    public static class EuroLayoutCustomizer extends LayoutCustomizer {
-        public EuroLayoutCustomizer(final Locale locale) {
+    public static class EuroCustomizer extends LayoutCustomizer {
+        public EuroCustomizer(final Locale locale) {
             super(locale);
         }
 
@@ -270,13 +270,12 @@
 
     // Punctuation more keys for phone form factor.
     public static final ExpectedKey[] PHONE_PUNCTUATION_MORE_KEYS = joinKeys(
-            ";", "/", "(", ")", "#", "!", ",", "?",
-            "&", "%", "+", "\"", "-", ":", "'", "@");
-
+            ",", "?", "!", "#", ")", "(", "/", ";",
+            "'", "@", ":", "-", "\"", "+", "%", "&");
     // Punctuation more keys for tablet form factor.
     public static final ExpectedKey[] TABLET_PUNCTUATION_MORE_KEYS = joinKeys(
-            ";", "/", "(", ")", "#", "'", ",",
-            "&", "%", "+", "\"", "-", ":", "@");
+            ",", "'", "#", ")", "(", "/", ";",
+            "@", ":", "-", "\"", "+", "%", "&");
 
    /**
      * Helper method to create alphabet layout adding special function keys.
@@ -288,11 +287,9 @@
     ExpectedKeyboardBuilder convertCommonLayoutToKeyboard(final ExpectedKeyboardBuilder builder,
             final boolean isPhone) {
         final LayoutCustomizer customizer = getCustomizer();
-        final ExpectedKey[] spacebar = joinKeys(
-                customizer.getKeysLeftToSpacebar(isPhone),
-                customizer.getSpaceKeys(isPhone),
-                customizer.getKeysRightToSpacebar(isPhone));
-        builder.setKeysOfRow(4, spacebar);
+        builder.setKeysOfRow(4, (Object[])customizer.getSpaceKeys(isPhone));
+        builder.addKeysOnTheLeftOfRow(4, (Object[])customizer.getKeysLeftToSpacebar(isPhone));
+        builder.addKeysOnTheRightOfRow(4, (Object[])customizer.getKeysRightToSpacebar(isPhone));
         if (isPhone) {
             builder.addKeysOnTheRightOfRow(3, DELETE_KEY)
                     .addKeysOnTheLeftOfRow(4, customizer.getSymbolsKey())
@@ -302,10 +299,9 @@
                     .addKeysOnTheRightOfRow(2, ENTER_KEY)
                     .addKeysOnTheLeftOfRow(4, customizer.getSymbolsKey(), SETTINGS_KEY)
                     .addKeysOnTheRightOfRow(4, EMOJI_KEY);
-
         }
-        builder.addKeysOnTheLeftOfRow(3, customizer.getLeftShiftKeys(isPhone))
-            .addKeysOnTheRightOfRow(3, customizer.getRightShiftKeys(isPhone));
+        builder.addKeysOnTheLeftOfRow(3, (Object[])customizer.getLeftShiftKeys(isPhone))
+                .addKeysOnTheRightOfRow(3, (Object[])customizer.getRightShiftKeys(isPhone));
         return builder;
     }
 
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Mongolian.java b/tests/src/com/android/inputmethod/keyboard/layout/Mongolian.java
index 3c9f4a0..3c6c058 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/Mongolian.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Mongolian.java
@@ -77,37 +77,33 @@
                     // U+0437: "з" CYRILLIC SMALL LETTER ZE
                     key("\u0437", moreKey("0")),
                     // U+043A: "к" CYRILLIC SMALL LETTER KA
-                    key("\u043A"))
-            // U+0439: "й" CYRILLIC SMALL LETTER SHORT I
-            // U+044B: "ы" CYRILLIC SMALL LETTER YERU
-            // U+0431: "б" CYRILLIC SMALL LETTER BE
-            // U+04E9: "ө" CYRILLIC SMALL LETTER BARRED O
-            // U+0430: "а" CYRILLIC SMALL LETTER A
-            // U+0445: "х" CYRILLIC SMALL LETTER HA
-            // U+0440: "р" CYRILLIC SMALL LETTER ER
-            // U+043E: "о" CYRILLIC SMALL LETTER O
-            // U+043B: "л" CYRILLIC SMALL LETTER EL
-            // U+0434: "д" CYRILLIC SMALL LETTER DE
-            // U+043F: "п" CYRILLIC SMALL LETTER PE
-            .setLabelsOfRow(2,
+                    "\u043A")
+            .setKeysOfRow(2,
+                    // U+0439: "й" CYRILLIC SMALL LETTER SHORT I
+                    // U+044B: "ы" CYRILLIC SMALL LETTER YERU
+                    // U+0431: "б" CYRILLIC SMALL LETTER BE
+                    // U+04E9: "ө" CYRILLIC SMALL LETTER BARRED O
+                    // U+0430: "а" CYRILLIC SMALL LETTER A
+                    // U+0445: "х" CYRILLIC SMALL LETTER HA
+                    // U+0440: "р" CYRILLIC SMALL LETTER ER
+                    // U+043E: "о" CYRILLIC SMALL LETTER O
+                    // U+043B: "л" CYRILLIC SMALL LETTER EL
+                    // U+0434: "д" CYRILLIC SMALL LETTER DE
+                    // U+043F: "п" CYRILLIC SMALL LETTER PE
                     "\u0439", "\u044B", "\u0431", "\u04E9", "\u0430", "\u0445", "\u0440", "\u043E",
                     "\u043B", "\u0434", "\u043F")
             .setKeysOfRow(3,
                     // U+044F: "я" CYRILLIC SMALL LETTER YA
-                    key("\u044F"),
                     // U+0447: "ч" CYRILLIC SMALL LETTER CHE
-                    key("\u0447"),
+                    "\u044F", "\u0447",
                     // U+0451: "ё" CYRILLIC SMALL LETTER IO
                     // U+0435: "е" CYRILLIC SMALL LETTER IE
                     key("\u0451", moreKey("\u0435")),
                     // U+0441: "с" CYRILLIC SMALL LETTER ES
-                    key("\u0441"),
                     // U+043C: "м" CYRILLIC SMALL LETTER EM
-                    key("\u043C"),
                     // U+0438: "и" CYRILLIC SMALL LETTER I
-                    key("\u0438"),
                     // U+0442: "т" CYRILLIC SMALL LETTER TE
-                    key("\u0442"),
+                    "\u0441", "\u043C", "\u0438", "\u0442",
                     // U+044C: "ь" CYRILLIC SMALL LETTER SOFT SIGN
                     // U+044A: "ъ" CYRILLIC SMALL LETTER HARD SIGN
                     key("\u044C", moreKey("\u044A")),
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/NepaliRomanized.java b/tests/src/com/android/inputmethod/keyboard/layout/NepaliRomanized.java
index c0bc29f..7cfe344 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/NepaliRomanized.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/NepaliRomanized.java
@@ -99,77 +99,76 @@
                     // U+0966: "०" DEVANAGARI DIGIT ZERO
                     key("\u092A", joinMoreKeys("\u0966", "0")),
                     // U+0907: "इ" DEVANAGARI LETTER I
-                    key("\u0907"))
-            // U+093E: "ा" DEVANAGARI VOWEL SIGN AA
-            // U+0938: "स" DEVANAGARI LETTER SA
-            // U+0926: "द" DEVANAGARI LETTER DA
-            // U+0909: "उ" DEVANAGARI LETTER U
-            // U+0917: "ग" DEVANAGARI LETTER GA
-            // U+0939: "ह" DEVANAGARI LETTER HA
-            // U+091C: "ज" DEVANAGARI LETTER JA
-            // U+0915: "क" DEVANAGARI LETTER KA
-            // U+0932: "ल" DEVANAGARI LETTER LA
-            // U+090F: "ए" DEVANAGARI LETTER E
-            // U+0950: "ॐ" DEVANAGARI OM
-            .setLabelsOfRow(2,
+                    "\u0907")
+            .setKeysOfRow(2,
+                    // U+093E: "ा" DEVANAGARI VOWEL SIGN AA
+                    // U+0938: "स" DEVANAGARI LETTER SA
+                    // U+0926: "द" DEVANAGARI LETTER DA
+                    // U+0909: "उ" DEVANAGARI LETTER U
+                    // U+0917: "ग" DEVANAGARI LETTER GA
+                    // U+0939: "ह" DEVANAGARI LETTER HA
+                    // U+091C: "ज" DEVANAGARI LETTER JA
+                    // U+0915: "क" DEVANAGARI LETTER KA
+                    // U+0932: "ल" DEVANAGARI LETTER LA
+                    // U+090F: "ए" DEVANAGARI LETTER E
+                    // U+0950: "ॐ" DEVANAGARI OM
                     "\u093E", "\u0938", "\u0926", "\u0909", "\u0917", "\u0939", "\u091C", "\u0915",
                     "\u0932", "\u090F", "\u0950")
-            // U+0937: "ष" DEVANAGARI LETTER SSA
-            // U+0921: "ड" DEVANAGARI LETTER DDA
-            // U+091A: "च" DEVANAGARI LETTER CA
-            // U+0935: "व" DEVANAGARI LETTER VA
-            // U+092C: "ब" DEVANAGARI LETTER BHA
-            // U+0928: "न" DEVANAGARI LETTER NA
-            // U+092E: "म" DEVANAGARI LETTER MA
-            // U+0964: "।" DEVANAGARI DANDA
-            // U+094D: "्" DEVANAGARI SIGN VIRAMA
-            .setLabelsOfRow(3,
-                    "\u0937", "\u0921", "\u091A", "\u0935", "\u092C", "\u0928", "\u092E", "\u0964",
+            .setKeysOfRow(3,
+                    // U+0937: "ष" DEVANAGARI LETTER SSA
+                    // U+0921: "ड" DEVANAGARI LETTER DDA
+                    // U+091A: "च" DEVANAGARI LETTER CA
+                    // U+0935: "व" DEVANAGARI LETTER VA
+                    // U+092C: "ब" DEVANAGARI LETTER BHA
+                    // U+0928: "न" DEVANAGARI LETTER NA
+                    // U+092E: "म" DEVANAGARI LETTER MA
+                    "\u0937", "\u0921", "\u091A", "\u0935", "\u092C", "\u0928", "\u092E",
+                    // U+0964: "।" DEVANAGARI DANDA
+                    // U+093D: "ऽ" DEVANAGARI SIGN AVAGRAHA
+                    key("\u0964", moreKey("\u093D")),
+                    // U+094D: "्" DEVANAGARI SIGN VIRAMA
                     "\u094D")
-            // U+0964: "।" DEVANAGARI DANDA
-            // U+093D: "ऽ" DEVANAGARI SIGN AVAGRAHA
-            .setMoreKeysOf("\u0964", "\u093D")
             .build();
 
     private static final ExpectedKey[][] ALPHABET_SHIFTED_COMMON = new ExpectedKeyboardBuilder()
-            // U+0920: "ठ" DEVANAGARI LETTER TTHA
-            // U+0914: "औ" DEVANAGARI LETTER AU
-            // U+0948: "ै" DEVANAGARI VOWEL SIGN AI
-            // U+0943: "ृ" DEVANAGARI VOWEL SIGN VOCALIC R
-            // U+0925: "थ" DEVANAGARI LETTER THA
-            // U+091E: "ञ" DEVANAGARI LETTER NYA
-            // U+0942: "ू" DEVANAGARI VOWEL SIGN UU
-            // U+0940: "ी" DEVANAGARI VOWEL SIGN II
-            // U+0913: "ओ" DEVANAGARI LETTER O
-            // U+092B: "फ" DEVANAGARI LETTER PHA
-            // U+0908: "ई" DEVANAGARI LETTER II
-            .setLabelsOfRow(1,
+            .setKeysOfRow(1,
+                    // U+0920: "ठ" DEVANAGARI LETTER TTHA
+                    // U+0914: "औ" DEVANAGARI LETTER AU
+                    // U+0948: "ै" DEVANAGARI VOWEL SIGN AI
+                    // U+0943: "ृ" DEVANAGARI VOWEL SIGN VOCALIC R
+                    // U+0925: "थ" DEVANAGARI LETTER THA
+                    // U+091E: "ञ" DEVANAGARI LETTER NYA
+                    // U+0942: "ू" DEVANAGARI VOWEL SIGN UU
+                    // U+0940: "ी" DEVANAGARI VOWEL SIGN II
+                    // U+0913: "ओ" DEVANAGARI LETTER O
+                    // U+092B: "फ" DEVANAGARI LETTER PHA
+                    // U+0908: "ई" DEVANAGARI LETTER II
                     "\u0920", "\u0914", "\u0948", "\u0943", "\u0925", "\u091E", "\u0942", "\u0940",
                     "\u0913", "\u092B", "\u0908")
-            // U+0906: "आ" DEVANAGARI LETTER AA
-            // U+0936: "श" DEVANAGARI LETTER SHA
-            // U+0927: "ध" DEVANAGARI LETTER DHA
-            // U+090A: "ऊ" DEVANAGARI LETTER UU
-            // U+0918: "घ" DEVANAGARI LETTER GHA
-            // U+0905: "अ" DEVANAGARI LETTER A
-            // U+091D: "झ" DEVANAGARI LETTER JHA
-            // U+0916: "ख" DEVANAGARI LETTER KHA
-            // U+0965: "॥" DEVANAGARI DOUBLE DANDA
-            // U+0910: "ऐ" DEVANAGARI LETTER AI
-            // U+0903: "ः" DEVANAGARI SIGN VISARGA
-            .setLabelsOfRow(2,
+            .setKeysOfRow(2,
+                    // U+0906: "आ" DEVANAGARI LETTER AA
+                    // U+0936: "श" DEVANAGARI LETTER SHA
+                    // U+0927: "ध" DEVANAGARI LETTER DHA
+                    // U+090A: "ऊ" DEVANAGARI LETTER UU
+                    // U+0918: "घ" DEVANAGARI LETTER GHA
+                    // U+0905: "अ" DEVANAGARI LETTER A
+                    // U+091D: "झ" DEVANAGARI LETTER JHA
+                    // U+0916: "ख" DEVANAGARI LETTER KHA
+                    // U+0965: "॥" DEVANAGARI DOUBLE DANDA
+                    // U+0910: "ऐ" DEVANAGARI LETTER AI
+                    // U+0903: "ः" DEVANAGARI SIGN VISARGA
                     "\u0906", "\u0936", "\u0927", "\u090A", "\u0918", "\u0905", "\u091D", "\u0916",
                     "\u0965", "\u0910", "\u0903")
-            // U+090B: "ऋ" DEVANAGARI LETTER VOCALIC R
-            // U+0922: "ढ" DEVANAGARI LETTER DDHA
-            // U+091B: "छ" DEVANAGARI LETTER CHA
-            // U+0901: "ँ" DEVANAGARI SIGN CANDRABINDU
-            // U+092D: "भ" DEVANAGARI LETTER BHA
-            // U+0923: "ण" DEVANAGARI LETTER NNA
-            // U+0902: "ं" DEVANAGARI SIGN ANUSVARA
-            // U+0919: "ङ" DEVANAGARI LETTER NGA
-            // U+094D: "्" DEVANAGARI SIGN VIRAMA
-            .setLabelsOfRow(3,
+            .setKeysOfRow(3,
+                    // U+090B: "ऋ" DEVANAGARI LETTER VOCALIC R
+                    // U+0922: "ढ" DEVANAGARI LETTER DDHA
+                    // U+091B: "छ" DEVANAGARI LETTER CHA
+                    // U+0901: "ँ" DEVANAGARI SIGN CANDRABINDU
+                    // U+092D: "भ" DEVANAGARI LETTER BHA
+                    // U+0923: "ण" DEVANAGARI LETTER NNA
+                    // U+0902: "ं" DEVANAGARI SIGN ANUSVARA
+                    // U+0919: "ङ" DEVANAGARI LETTER NGA
+                    // U+094D: "्" DEVANAGARI SIGN VIRAMA
                     "\u090B", "\u0922", "\u091B", "\u0901", "\u092D", "\u0923", "\u0902", "\u0919",
                     "\u094D")
             .build();
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/NepaliTraditional.java b/tests/src/com/android/inputmethod/keyboard/layout/NepaliTraditional.java
index 658dec0..1599fd7 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/NepaliTraditional.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/NepaliTraditional.java
@@ -63,7 +63,7 @@
                     // U+093D: "ऽ" DEVANAGARI SIGN AVAGRAHA
                     key("\u0947", joinMoreKeys("\u0903", "\u093D")),
                     // U+0964: "।" DEVANAGARI DANDA
-                    key("\u0964"),
+                    "\u0964",
                     // U+0930: "र" DEVANAGARI LETTER RA
                     // U+0930/U+0941: "रु" DEVANAGARI LETTER RA/DEVANAGARI VOWEL SIGN U
                     key("\u0930", moreKey("\u0930\u0941")));
@@ -73,9 +73,8 @@
                     // U+093D: "ऽ" DEVANAGARI SIGN AVAGRAHA
                     key("\u0903", moreKey("\u093D")),
                     // U+0947: "े" DEVANAGARI VOWEL SIGN E
-                    key("\u0947"),
                     // U+0964: "।" DEVANAGARI DANDA
-                    key("\u0964"),
+                    "\u0947", "\u0964",
                     // U+0930: "र" DEVANAGARI LETTER RA
                     key("\u0930", moreKey("!")),
                     // U+094D: "्" DEVANAGARI SIGN VIRAMA
@@ -94,9 +93,8 @@
         if (isPhone) {
             builder.addKeysOnTheRightOfRow(3,
                     // U+0902: "ं" DEVANAGARI SIGN ANUSVARA
-                    key("\u0902"),
                     // U+0919: "ङ" DEVANAGARI LETTER NGA
-                    key("\u0919"),
+                    "\u0902", "\u0919",
                     // U+0948: "ै" DEVANAGARI VOWEL SIGN AI
                     // U+0936/U+094D/U+0930:
                     //     "श्र" DEVANAGARI LETTER SHA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER RA
@@ -104,16 +102,15 @@
         } else {
             builder.addKeysOnTheRightOfRow(3,
                     // U+0902: "ं" DEVANAGARI SIGN ANUSVARA
-                    key("\u0902"),
                     // U+0919: "ङ" DEVANAGARI LETTER NGA
-                    key("\u0919"),
+                    "\u0902", "\u0919",
                     // U+0948: "ै" DEVANAGARI VOWEL SIGN AI
                     // U+0936/U+094D/U+0930:
                     //     "श्र" DEVANAGARI LETTER SHA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER RA
                     key("\u0948", moreKey("\u0936\u094D\u0930")),
                     // U+0930/U+0941: "रु" DEVANAGARI LETTER RA/DEVANAGARI VOWEL SIGN U
                     key("\u0930\u0941", moreKey("!")),
-                    key("?"));
+                    "?");
         }
         return builder.build();
     }
@@ -153,27 +150,28 @@
                     // U+0907: "इ" DEVANAGARI LETTER I
                     // U+0914: "औ" DEVANAGARI LETTER AU
                     key("\u0907", moreKey("\u0914")))
-            // U+092C: "ब" DEVANAGARI LETTER BA
-            // U+0915: "क" DEVANAGARI LETTER KA
-            // U+092E: "म" DEVANAGARI LETTER MA
-            // U+093E: "ा" DEVANAGARI VOWEL SIGN AA
-            // U+0928: "न" DEVANAGARI LETTER NA
-            // U+091C: "ज" DEVANAGARI LETTER JA
-            // U+0935: "व" DEVANAGARI LETTER VA
-            // U+092A: "प" DEVANAGARI LETTER PA
-            // U+093F: "ि" DEVANAGARI VOWEL SIGN I
-            // U+0938: "स" DEVANAGARI LETTER SA
-            // U+0941: "ु" DEVANAGARI VOWEL SIGN U
-            .setLabelsOfRow(2,
+            .setKeysOfRow(2,
+                    // U+092C: "ब" DEVANAGARI LETTER BA
+                    // U+0915: "क" DEVANAGARI LETTER KA
+                    // U+092E: "म" DEVANAGARI LETTER MA
+                    // U+093E: "ा" DEVANAGARI VOWEL SIGN AA
+                    // U+0928: "न" DEVANAGARI LETTER NA
+                    // U+091C: "ज" DEVANAGARI LETTER JA
+                    // U+0935: "व" DEVANAGARI LETTER VA
+                    // U+092A: "प" DEVANAGARI LETTER PA
+                    // U+093F: "ि" DEVANAGARI VOWEL SIGN I
+                    // U+0938: "स" DEVANAGARI LETTER SA
+                    // U+0941: "ु" DEVANAGARI VOWEL SIGN U
                     "\u092C", "\u0915", "\u092E", "\u093E", "\u0928", "\u091C", "\u0935", "\u092A",
                     "\u093F", "\u0938", "\u0941")
-            // U+0936: "श" DEVANAGARI LETTER SHA
-            // U+0939: "ह" DEVANAGARI LETTER HA
-            // U+0905: "अ" DEVANAGARI LETTER A
-            // U+0916: "ख" DEVANAGARI LETTER KHA
-            // U+0926: "द" DEVANAGARI LETTER DA
-            // U+0932: "ल" DEVANAGARI LETTER LA
-            .setLabelsOfRow(3, "\u0936", "\u0939", "\u0905", "\u0916", "\u0926", "\u0932")
+            .setKeysOfRow(3,
+                    // U+0936: "श" DEVANAGARI LETTER SHA
+                    // U+0939: "ह" DEVANAGARI LETTER HA
+                    // U+0905: "अ" DEVANAGARI LETTER A
+                    // U+0916: "ख" DEVANAGARI LETTER KHA
+                    // U+0926: "द" DEVANAGARI LETTER DA
+                    // U+0932: "ल" DEVANAGARI LETTER LA
+                    "\u0936", "\u0939", "\u0905", "\u0916", "\u0926", "\u0932")
             .build();
 
     private static final ExpectedKey[][] ALPHABET_SHIFTED_COMMON = new ExpectedKeyboardBuilder()
@@ -222,32 +220,32 @@
                     // U+0943: "ृ" DEVANAGARI VOWEL SIGN VOCALIC R
                     // U+0913: "ओ" DEVANAGARI LETTER O
                     key("\u0943", moreKey("\u0913")))
-            // U+0906: "आ" DEVANAGARI LETTER AA
-            // U+0919/U+094D: "ङ्" DEVANAGARI LETTER NGA/DEVANAGARI SIGN VIRAMA
-            // U+0921/U+094D/U+0921:
-            //     "ड्ड" DEVANAGARI LETTER DDA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER DDA
-            // U+0901: "ँ" DEVANAGARI SIGN CANDRABINDU
-            // U+0926/U+094D/U+0926:
-            //     "द्द" DEVANAGARI LETTER DA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER DA
-            // U+091D: "झ" DEVANAGARI LETTER JHA
-            // U+094B: "ो" DEVANAGARI VOWEL SIGN O
-            // U+092B: "फ" DEVANAGARI LETTER PHA
-            // U+0940: "ी" DEVANAGARI VOWEL SIGN II
-            // U+091F/U+094D/U+0920:
-            //     "ट्ठ" DEVANAGARI LETTER TTA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER TTHA
-            // U+0942: "ू" DEVANAGARI VOWEL SIGN UU
-            .setLabelsOfRow(2,
+            .setKeysOfRow(2,
+                    // U+0906: "आ" DEVANAGARI LETTER AA
+                    // U+0919/U+094D: "ङ्" DEVANAGARI LETTER NGA/DEVANAGARI SIGN VIRAMA
+                    // U+0921/U+094D/U+0921:
+                    //     "ड्ड" DEVANAGARI LETTER DDA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER DDA
+                    // U+0901: "ँ" DEVANAGARI SIGN CANDRABINDU
+                    // U+0926/U+094D/U+0926:
+                    //     "द्द" DEVANAGARI LETTER DA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER DA
+                    // U+091D: "झ" DEVANAGARI LETTER JHA
+                    // U+094B: "ो" DEVANAGARI VOWEL SIGN O
+                    // U+092B: "फ" DEVANAGARI LETTER PHA
+                    // U+0940: "ी" DEVANAGARI VOWEL SIGN II
+                    // U+091F/U+094D/U+0920:
+                    //     "ट्ठ" DEVANAGARI LETTER TTA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER TTHA
+                    // U+0942: "ू" DEVANAGARI VOWEL SIGN UU
                     "\u0906", "\u0919\u094D", "\u0921\u094D\u0921", "\u0901", "\u0926\u094D\u0926",
                     "\u091D", "\u094B", "\u092B", "\u0940", "\u091F\u094D\u0920", "\u0942")
-            // U+0915/U+094D: "क्" DEVANAGARI LETTER KA/DEVANAGARI SIGN VIRAMA
-            // U+0939/U+094D/U+092E:
-            //     "ह्म" DEVANAGARI LETTER HA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER MA
-            // U+090B: "ऋ" DEVANAGARI LETTER VOCALIC R
-            // U+0950: "ॐ" DEVANAGARI OM
-            // U+094C: "ौ" DEVANAGARI VOWEL SIGN AU
-            // U+0926/U+094D/U+092F:
-            //     "द्य" DEVANAGARI LETTER DA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER YA
-            .setLabelsOfRow(3,
+            .setKeysOfRow(3,
+                    // U+0915/U+094D: "क्" DEVANAGARI LETTER KA/DEVANAGARI SIGN VIRAMA
+                    // U+0939/U+094D/U+092E:
+                    //     "ह्म" DEVANAGARI LETTER HA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER MA
+                    // U+090B: "ऋ" DEVANAGARI LETTER VOCALIC R
+                    // U+0950: "ॐ" DEVANAGARI OM
+                    // U+094C: "ौ" DEVANAGARI VOWEL SIGN AU
+                    // U+0926/U+094D/U+092F:
+                    //     "द्य" DEVANAGARI LETTER DA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER YA
                     "\u0915\u094D", "\u0939\u094D\u092E", "\u090B", "\u0950", "\u094C",
                     "\u0926\u094D\u092F")
             .build();
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Nordic.java b/tests/src/com/android/inputmethod/keyboard/layout/Nordic.java
index a535ad2..c791c40 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/Nordic.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Nordic.java
@@ -41,18 +41,18 @@
 
     private static final ExpectedKey[][] ALPHABET_COMMON = new ExpectedKeyboardBuilder()
             .setKeysOfRow(1,
-                    key("q", moreKey("1")),
-                    key("w", moreKey("2")),
-                    key("e", moreKey("3")),
-                    key("r", moreKey("4")),
-                    key("t", moreKey("5")),
-                    key("y", moreKey("6")),
-                    key("u", moreKey("7")),
-                    key("i", moreKey("8")),
-                    key("o", moreKey("9")),
-                    key("p", moreKey("0")),
-                    key(ROW1_11))
-            .setLabelsOfRow(2, "a", "s", "d", "f", "g", "h", "j", "k", "l", ROW2_10, ROW2_11)
-            .setLabelsOfRow(3, "z", "x", "c", "v", "b", "n", "m")
+                    key("q", additionalMoreKey("1")),
+                    key("w", additionalMoreKey("2")),
+                    key("e", additionalMoreKey("3")),
+                    key("r", additionalMoreKey("4")),
+                    key("t", additionalMoreKey("5")),
+                    key("y", additionalMoreKey("6")),
+                    key("u", additionalMoreKey("7")),
+                    key("i", additionalMoreKey("8")),
+                    key("o", additionalMoreKey("9")),
+                    key("p", additionalMoreKey("0")),
+                    ROW1_11)
+            .setKeysOfRow(2, "a", "s", "d", "f", "g", "h", "j", "k", "l", ROW2_10, ROW2_11)
+            .setKeysOfRow(3, "z", "x", "c", "v", "b", "n", "m")
             .build();
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/PcQwerty.java b/tests/src/com/android/inputmethod/keyboard/layout/PcQwerty.java
new file mode 100644
index 0000000..9da6dcc
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/PcQwerty.java
@@ -0,0 +1,227 @@
+/*
+ * 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 java.util.Locale;
+
+/**
+ * The PC QWERTY alphabet keyboard.
+ */
+public final class PcQwerty extends LayoutBase {
+    private static final String LAYOUT_NAME = "pcqwerty";
+
+    public PcQwerty(final LayoutCustomizer customizer) {
+        super(customizer, Symbols.class, SymbolsShifted.class);
+    }
+
+    @Override
+    public String getName() { return LAYOUT_NAME; }
+
+    public static class PcQwertyCustomizer extends LayoutCustomizer {
+        public PcQwertyCustomizer(final Locale locale) { super(locale); }
+
+        @Override
+        public ExpectedKey[] getLeftShiftKeys(final boolean isPhone) {
+            return joinKeys(SHIFT_KEY);
+        }
+
+        @Override
+        public ExpectedKey[] getRightShiftKeys(final boolean isPhone) {
+            return joinKeys(SHIFT_KEY);
+        }
+
+        @Override
+        public ExpectedKey[] getKeysLeftToSpacebar(final boolean isPhone) {
+            return joinKeys(SETTINGS_KEY);
+        }
+
+        @Override
+        public ExpectedKey[] getKeysRightToSpacebar(final boolean isPhone) {
+            return isPhone ? joinKeys(key(ENTER_KEY, EMOJI_KEY)) : joinKeys(EMOJI_KEY);
+        }
+    }
+
+    @Override
+    ExpectedKey[][] getCommonAlphabetLayout(final boolean isPhone) {
+        final LayoutCustomizer customizer = getCustomizer();
+        final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(ALPHABET_COMMON);
+        customizer.setAccentedLetters(builder);
+        builder.replaceKeyOfLabel(ROW1_1, key("`", moreKey("~")))
+                .replaceKeyOfLabel(ROW2_11, key("[", moreKey("{")))
+                .replaceKeyOfLabel(ROW2_12, key("]", moreKey("}")))
+                .replaceKeyOfLabel(ROW2_13, key("\\", moreKey("|")))
+                .replaceKeyOfLabel(ROW3_10, key(";", moreKey(":")))
+                .replaceKeyOfLabel(ROW3_11, key("'", joinMoreKeys(additionalMoreKey("\""),
+                        customizer.getDoubleQuoteMoreKeys(),
+                        customizer.getSingleQuoteMoreKeys())))
+                .setAdditionalMoreKeysPositionOf("'", 4)
+                .replaceKeyOfLabel(ROW4_8, key(",", moreKey("<")))
+                .replaceKeyOfLabel(ROW4_9, key(".", moreKey(">")))
+                // U+00BF: "¿" INVERTED QUESTION MARK
+                .replaceKeyOfLabel(ROW4_10, key("/", joinMoreKeys("?", "\u00BF")));
+        if (isPhone) {
+            // U+221E: "∞" INFINITY
+            // U+2260: "≠" NOT EQUAL TO
+            // U+2248: "≈" ALMOST EQUAL TO
+            builder.replaceKeyOfLabel(ROW1_13, key("=",
+                    joinMoreKeys("\u221E", "\u2260", "\u2248", "+")));
+        } else {
+            // U+221E: "∞" INFINITY
+            // U+2260: "≠" NOT EQUAL TO
+            // U+2248: "≈" ALMOST EQUAL TO
+            builder.replaceKeyOfLabel(ROW1_13, key("=",
+                    joinMoreKeys("+", "\u221E", "\u2260", "\u2248")));
+        }
+        return builder.build();
+    }
+
+    @Override
+    ExpectedKey[][] getCommonAlphabetShiftLayout(final boolean isPhone, final int elementId) {
+        final ExpectedKeyboardBuilder builder;
+        if (elementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED
+                || elementId == KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED) {
+            builder = new ExpectedKeyboardBuilder(getCommonAlphabetLayout(isPhone));
+        } else {
+            builder = new ExpectedKeyboardBuilder(ALPHABET_COMMON);
+            final LayoutCustomizer customizer = getCustomizer();
+            customizer.setAccentedLetters(builder);
+            builder.setKeysOfRow(1,
+                    "~",
+                    // U+00A1: "¡" INVERTED EXCLAMATION MARK
+                    key("!", moreKey("\u00A1")),
+                    "@", "#",
+                    customizer.getCurrencyKey(),
+                    // U+2030: "‰" PER MILLE SIGN
+                    key("%", moreKey("\u2030")),
+                    "^", "&",
+                    // U+2020: "†" DAGGER
+                    // U+2021: "‡" DOUBLE DAGGER
+                    // U+2605: "★" BLACK STAR
+                    key("*", joinMoreKeys("\u2020", "\u2021", "\u2605")),
+                    "(", ")", "_",
+                    // U+00B1: "±" PLUS-MINUS SIGN
+                    // U+00D7: "×" MULTIPLICATION SIGN
+                    // U+00F7: "÷" DIVISION SIGN
+                    // U+221A: "√" SQUARE ROOT
+                    key("+", joinMoreKeys("\u00B1", "\u00D7", "\u00F7", "\u221A")))
+                    .replaceKeyOfLabel(ROW2_11, key("{"))
+                    .replaceKeyOfLabel(ROW2_12, key("}"))
+                    .replaceKeyOfLabel(ROW2_13, key("|"))
+                    .replaceKeyOfLabel(ROW3_10, key(":"))
+                    .replaceKeyOfLabel(ROW3_11, key("\"", joinMoreKeys(
+                            customizer.getDoubleQuoteMoreKeys(),
+                            customizer.getSingleQuoteMoreKeys())))
+                    // U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+                    // U+2264: "≤" LESS-THAN OR EQUAL TO
+                    // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+                    .replaceKeyOfLabel(ROW4_8, key("<", joinMoreKeys("\u2039", "\u2264", "\u00AB")))
+                    // U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+                    // U+2265: "≥" GREATER-THAN EQUAL TO
+                    // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+                    .replaceKeyOfLabel(ROW4_9, key(">", joinMoreKeys("\u203A", "\u2265", "\u00BB")))
+                    // U+00BF: "¿" INVERTED QUESTION MARK
+                    .replaceKeyOfLabel(ROW4_10, key("?", moreKey("\u00BF")));
+        }
+        builder.toUpperCase(getLocale());
+        return builder.build();
+    }
+
+    // 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(3, DELETE_KEY);
+        } else {
+            builder.addKeysOnTheRightOfRow(1, DELETE_KEY)
+                    .addKeysOnTheLeftOfRow(2, TAB_KEY)
+                    .addKeysOnTheRightOfRow(3, ENTER_KEY);
+        }
+        builder.addKeysOnTheLeftOfRow(4, (Object[])customizer.getLeftShiftKeys(isPhone))
+                .addKeysOnTheRightOfRow(4, (Object[])customizer.getRightShiftKeys(isPhone));
+        return builder;
+    }
+
+    @Override
+    public ExpectedKey[][] getLayout(final boolean isPhone, final int elementId) {
+        if (elementId == KeyboardId.ELEMENT_SYMBOLS
+                || elementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED) {
+            return null;
+        }
+        return super.getLayout(isPhone, elementId);
+    }
+
+    private static final String ROW1_1 = "ROW1_1";
+    private static final String ROW1_13 = "ROW1_13";
+    private static final String ROW2_11 = "ROW2_11";
+    private static final String ROW2_12 = "ROW2_12";
+    private static final String ROW2_13 = "ROW2_13";
+    private static final String ROW3_10 = "ROW3_10";
+    private static final String ROW3_11 = "ROW3_11";
+    private static final String ROW4_8 = "ROW4_8";
+    private static final String ROW4_9 = "ROW4_9";
+    private static final String ROW4_10 = "ROW4_10";
+
+    private static final ExpectedKey[][] ALPHABET_COMMON = new ExpectedKeyboardBuilder()
+            .setKeysOfRow(1,
+                    ROW1_1,
+                    // U+00A1: "¡" INVERTED EXCLAMATION MARK
+                    // U+00B9: "¹" SUPERSCRIPT ONE
+                    // U+00BD: "½" VULGAR FRACTION ONE HALF
+                    // U+2153: "⅓" VULGAR FRACTION ONE THIRD
+                    // U+00BC: "¼" VULGAR FRACTION ONE QUARTER
+                    // U+215B: "⅛" VULGAR FRACTION ONE EIGHTH
+                    key("1", joinMoreKeys(
+                            "!", "\u00A1", "\u00B9", "\u00BD", "\u2153", "\u00BC", "\u215B")),
+                    // U+00B2: "²" SUPERSCRIPT TWO
+                    // U+2154: "⅔" VULGAR FRACTION TWO THIRDS
+                    key("2", joinMoreKeys("@", "\u00B2", "\u2154")),
+                    // U+00B3: "³" SUPERSCRIPT THREE
+                    // U+00BE: "¾" VULGAR FRACTION THREE QUARTERS
+                    // U+215C: "⅜" VULGAR FRACTION THREE EIGHTHS
+                    key("3", joinMoreKeys("#", "\u00B3", "\u00BE", "\u215C")),
+                    // U+2074: "⁴" SUPERSCRIPT FOUR
+                    key("4", joinMoreKeys("$", "\u2074")),
+                    // U+215D: "⅝" VULGAR FRACTION FIVE EIGHTHS
+                    key("5", joinMoreKeys("%", "\u215D")),
+                    key("6", moreKey("^")),
+                    // U+215E: "⅞" VULGAR FRACTION SEVEN EIGHTHS
+                    key("7", joinMoreKeys("&", "\u215E")),
+                    key("8", moreKey("*")),
+                    key("9", moreKey("(")),
+                    // U+207F: "ⁿ" SUPERSCRIPT LATIN SMALL LETTER N
+                    // U+2205: "∅" EMPTY SET
+                    key("0", joinMoreKeys(")", "\u207F", "\u2205")),
+                    // U+2013: "–" EN DASH
+                    // U+2014: "—" EM DASH
+                    // U+00B7: "·" MIDDLE DOT
+                    key("-", joinMoreKeys("_", "\u2013", "\u2014", "\u00B7")),
+                    ROW1_13)
+            .setKeysOfRow(2, "q", "w", "e", "r", "t", "y", "u", "i", "o", "p",
+                    ROW2_11, ROW2_12, ROW2_13)
+            .setKeysOfRow(3, "a", "s", "d", "f", "g", "h", "j", "k", "l", ROW3_10, ROW3_11)
+            .setKeysOfRow(4, "z", "x", "c", "v", "b", "n", "m", ROW4_8, ROW4_9, ROW4_10)
+            .build();
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Qwerty.java b/tests/src/com/android/inputmethod/keyboard/layout/Qwerty.java
index a0da7e3..d790a1e 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/Qwerty.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Qwerty.java
@@ -37,17 +37,17 @@
 
     private static final ExpectedKey[][] ALPHABET_COMMON = new ExpectedKeyboardBuilder()
             .setKeysOfRow(1,
-                    key("q", moreKey("1")),
-                    key("w", moreKey("2")),
-                    key("e", moreKey("3")),
-                    key("r", moreKey("4")),
-                    key("t", moreKey("5")),
-                    key("y", moreKey("6")),
-                    key("u", moreKey("7")),
-                    key("i", moreKey("8")),
-                    key("o", moreKey("9")),
-                    key("p", moreKey("0")))
-            .setLabelsOfRow(2, "a", "s", "d", "f", "g", "h", "j", "k", "l")
-            .setLabelsOfRow(3, "z", "x", "c", "v", "b", "n", "m")
+                    key("q", additionalMoreKey("1")),
+                    key("w", additionalMoreKey("2")),
+                    key("e", additionalMoreKey("3")),
+                    key("r", additionalMoreKey("4")),
+                    key("t", additionalMoreKey("5")),
+                    key("y", additionalMoreKey("6")),
+                    key("u", additionalMoreKey("7")),
+                    key("i", additionalMoreKey("8")),
+                    key("o", additionalMoreKey("9")),
+                    key("p", additionalMoreKey("0")))
+            .setKeysOfRow(2, "a", "s", "d", "f", "g", "h", "j", "k", "l")
+            .setKeysOfRow(3, "z", "x", "c", "v", "b", "n", "m")
             .build();
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Qwertz.java b/tests/src/com/android/inputmethod/keyboard/layout/Qwertz.java
index 25f4734..26ba6cf 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/Qwertz.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Qwertz.java
@@ -34,17 +34,17 @@
 
     private static final ExpectedKey[][] ALPHABET_COMMON = new ExpectedKeyboardBuilder()
             .setKeysOfRow(1,
-                    key("q", moreKey("1")),
-                    key("w", moreKey("2")),
-                    key("e", moreKey("3")),
-                    key("r", moreKey("4")),
-                    key("t", moreKey("5")),
-                    key("z", moreKey("6")),
-                    key("u", moreKey("7")),
-                    key("i", moreKey("8")),
-                    key("o", moreKey("9")),
-                    key("p", moreKey("0")))
-            .setLabelsOfRow(2, "a", "s", "d", "f", "g", "h", "j", "k", "l")
-            .setLabelsOfRow(3, "y", "x", "c", "v", "b", "n", "m")
+                    key("q", additionalMoreKey("1")),
+                    key("w", additionalMoreKey("2")),
+                    key("e", additionalMoreKey("3")),
+                    key("r", additionalMoreKey("4")),
+                    key("t", additionalMoreKey("5")),
+                    key("z", additionalMoreKey("6")),
+                    key("u", additionalMoreKey("7")),
+                    key("i", additionalMoreKey("8")),
+                    key("o", additionalMoreKey("9")),
+                    key("p", additionalMoreKey("0")))
+            .setKeysOfRow(2, "a", "s", "d", "f", "g", "h", "j", "k", "l")
+            .setKeysOfRow(3, "y", "x", "c", "v", "b", "n", "m")
             .build();
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/SouthSlavic.java b/tests/src/com/android/inputmethod/keyboard/layout/SouthSlavic.java
index ad226dd..be8b435 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/SouthSlavic.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/SouthSlavic.java
@@ -63,47 +63,47 @@
     private static final ExpectedKey[][] ALPHABET_COMMON = new ExpectedKeyboardBuilder()
             .setKeysOfRow(1,
                     // U+0459: "љ" CYRILLIC SMALL LETTER LJE
-                    key("\u0459", moreKey("1")),
+                    key("\u0459", additionalMoreKey("1")),
                     // U+045A: "њ" CYRILLIC SMALL LETTER NJE
-                    key("\u045A", moreKey("2")),
+                    key("\u045A", additionalMoreKey("2")),
                     // U+0435: "е" CYRILLIC SMALL LETTER IE
-                    key("\u0435", moreKey("3")),
+                    key("\u0435", additionalMoreKey("3")),
                     // U+0440: "р" CYRILLIC SMALL LETTER ER
-                    key("\u0440", moreKey("4")),
+                    key("\u0440", additionalMoreKey("4")),
                     // U+0442: "т" CYRILLIC SMALL LETTER TE
-                    key("\u0442", moreKey("5")),
-                    key(ROW1_6, moreKey("6")),
+                    key("\u0442", additionalMoreKey("5")),
+                    key(ROW1_6, additionalMoreKey("6")),
                     // U+0443: "у" CYRILLIC SMALL LETTER U
-                    key("\u0443", moreKey("7")),
+                    key("\u0443", additionalMoreKey("7")),
                     // U+0438: "и" CYRILLIC SMALL LETTER I
-                    key("\u0438", moreKey("8")),
+                    key("\u0438", additionalMoreKey("8")),
                     // U+043E: "о" CYRILLIC SMALL LETTER O
-                    key("\u043E", moreKey("9")),
+                    key("\u043E", additionalMoreKey("9")),
                     // U+043F: "п" CYRILLIC SMALL LETTER PE
-                    key("\u043F", moreKey("0")),
+                    key("\u043F", additionalMoreKey("0")),
                     // U+0448: "ш" CYRILLIC SMALL LETTER SHA
-                    key("\u0448"))
-            // U+0430: "а" CYRILLIC SMALL LETTER A
-            // U+0441: "с" CYRILLIC SMALL LETTER ES
-            // U+0434: "д" CYRILLIC SMALL LETTER DE
-            // U+0444: "ф" CYRILLIC SMALL LETTER EF
-            // U+0433: "г" CYRILLIC SMALL LETTER GHE
-            // U+0445: "х" CYRILLIC SMALL LETTER HA
-            // U+0458: "ј" CYRILLIC SMALL LETTER JE
-            // U+043A: "к" CYRILLIC SMALL LETTER KA
-            // U+043B: "л" CYRILLIC SMALL LETTER EL
-            // U+0447: "ч" CYRILLIC SMALL LETTER CHE
-            .setLabelsOfRow(2,
+                    "\u0448")
+            .setKeysOfRow(2,
+                    // U+0430: "а" CYRILLIC SMALL LETTER A
+                    // U+0441: "с" CYRILLIC SMALL LETTER ES
+                    // U+0434: "д" CYRILLIC SMALL LETTER DE
+                    // U+0444: "ф" CYRILLIC SMALL LETTER EF
+                    // U+0433: "г" CYRILLIC SMALL LETTER GHE
+                    // U+0445: "х" CYRILLIC SMALL LETTER HA
+                    // U+0458: "ј" CYRILLIC SMALL LETTER JE
+                    // U+043A: "к" CYRILLIC SMALL LETTER KA
+                    // U+043B: "л" CYRILLIC SMALL LETTER EL
+                    // U+0447: "ч" CYRILLIC SMALL LETTER CHE
                     "\u0430", "\u0441", "\u0434", "\u0444", "\u0433", "\u0445", "\u0458", "\u043A",
                     "\u043B", "\u0447", ROW2_11)
-            // U+045F: "џ" CYRILLIC SMALL LETTER DZHE
-            // U+0446: "ц" CYRILLIC SMALL LETTER TSE
-            // U+0432: "в" CYRILLIC SMALL LETTER VE
-            // U+0431: "б" CYRILLIC SMALL LETTER BE
-            // U+043D: "н" CYRILLIC SMALL LETTER EN
-            // U+043C: "м" CYRILLIC SMALL LETTER EM
-            // U+0436: "ж" CYRILLIC SMALL LETTER ZHE
-            .setLabelsOfRow(3,
+            .setKeysOfRow(3,
+                    // U+045F: "џ" CYRILLIC SMALL LETTER DZHE
+                    // U+0446: "ц" CYRILLIC SMALL LETTER TSE
+                    // U+0432: "в" CYRILLIC SMALL LETTER VE
+                    // U+0431: "б" CYRILLIC SMALL LETTER BE
+                    // U+043D: "н" CYRILLIC SMALL LETTER EN
+                    // U+043C: "м" CYRILLIC SMALL LETTER EM
+                    // U+0436: "ж" CYRILLIC SMALL LETTER ZHE
                     ROW3_1, "\u045F", "\u0446", "\u0432", "\u0431", "\u043D", "\u043C", ROW3_8,
                     "\u0436")
             .build();
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Spanish.java b/tests/src/com/android/inputmethod/keyboard/layout/Spanish.java
index 5ccc364..225b9f6 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/Spanish.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Spanish.java
@@ -36,17 +36,17 @@
 
     private static final ExpectedKey[][] ALPHABET_COMMON = new ExpectedKeyboardBuilder()
             .setKeysOfRow(1,
-                    key("q", moreKey("1")),
-                    key("w", moreKey("2")),
-                    key("e", moreKey("3")),
-                    key("r", moreKey("4")),
-                    key("t", moreKey("5")),
-                    key("y", moreKey("6")),
-                    key("u", moreKey("7")),
-                    key("i", moreKey("8")),
-                    key("o", moreKey("9")),
-                    key("p", moreKey("0")))
-            .setLabelsOfRow(2, "a", "s", "d", "f", "g", "h", "j", "k", "l", ROW2_10)
-            .setLabelsOfRow(3, "z", "x", "c", "v", "b", "n", "m")
+                    key("q", additionalMoreKey("1")),
+                    key("w", additionalMoreKey("2")),
+                    key("e", additionalMoreKey("3")),
+                    key("r", additionalMoreKey("4")),
+                    key("t", additionalMoreKey("5")),
+                    key("y", additionalMoreKey("6")),
+                    key("u", additionalMoreKey("7")),
+                    key("i", additionalMoreKey("8")),
+                    key("o", additionalMoreKey("9")),
+                    key("p", additionalMoreKey("0")))
+            .setKeysOfRow(2, "a", "s", "d", "f", "g", "h", "j", "k", "l", ROW2_10)
+            .setKeysOfRow(3, "z", "x", "c", "v", "b", "n", "m")
             .build();
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Swiss.java b/tests/src/com/android/inputmethod/keyboard/layout/Swiss.java
index 5bc45d4..01a6020 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/Swiss.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Swiss.java
@@ -38,18 +38,18 @@
 
     private static final ExpectedKey[][] ALPHABET_COMMON = new ExpectedKeyboardBuilder()
             .setKeysOfRow(1,
-                    key("q", moreKey("1")),
-                    key("w", moreKey("2")),
-                    key("e", moreKey("3")),
-                    key("r", moreKey("4")),
-                    key("t", moreKey("5")),
-                    key("z", moreKey("6")),
-                    key("u", moreKey("7")),
-                    key("i", moreKey("8")),
-                    key("o", moreKey("9")),
-                    key("p", moreKey("0")),
-                    key(ROW1_11))
-            .setLabelsOfRow(2, "a", "s", "d", "f", "g", "h", "j", "k", "l", ROW2_10, ROW2_11)
-            .setLabelsOfRow(3, "y", "x", "c", "v", "b", "n", "m")
+                    key("q", additionalMoreKey("1")),
+                    key("w", additionalMoreKey("2")),
+                    key("e", additionalMoreKey("3")),
+                    key("r", additionalMoreKey("4")),
+                    key("t", additionalMoreKey("5")),
+                    key("z", additionalMoreKey("6")),
+                    key("u", additionalMoreKey("7")),
+                    key("i", additionalMoreKey("8")),
+                    key("o", additionalMoreKey("9")),
+                    key("p", additionalMoreKey("0")),
+                    ROW1_11)
+            .setKeysOfRow(2, "a", "s", "d", "f", "g", "h", "j", "k", "l", ROW2_10, ROW2_11)
+            .setKeysOfRow(3, "y", "x", "c", "v", "b", "n", "m")
             .build();
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Symbols.java b/tests/src/com/android/inputmethod/keyboard/layout/Symbols.java
index 9ce4187..726fefc 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/Symbols.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Symbols.java
@@ -46,7 +46,7 @@
                     .addKeysOnTheRightOfRow(4, key(ENTER_KEY, EMOJI_KEY));
         } else {
             // Tablet symbols keyboard has extra two keys at the left edge of the 3rd row.
-            builder.addKeysOnTheLeftOfRow(3, joinKeys("\\", "="));
+            builder.addKeysOnTheLeftOfRow(3, (Object[])joinKeys("\\", "="));
             builder.addKeysOnTheRightOfRow(1, DELETE_KEY)
                     .addKeysOnTheRightOfRow(2, ENTER_KEY)
                     .addKeysOnTheLeftOfRow(3, customizer.getSymbolsShiftKey(isPhone))
@@ -136,11 +136,10 @@
                     key("4", moreKey("\u2074")),
                     // U+215D: "⅝" VULGAR FRACTION FIVE EIGHTHS
                     key("5", moreKey("\u215D")),
-                    key("6"),
+                    "6",
                     // U+215E: "⅞" VULGAR FRACTION SEVEN EIGHTHS
                     key("7", moreKey("\u215E")),
-                    key("8"),
-                    key("9"),
+                    "8", "9",
                     // U+207F: "ⁿ" SUPERSCRIPT LATIN SMALL LETTER N
                     // U+2205: "∅" EMPTY SET
                     key("0", joinMoreKeys("\u207F", "\u2205")))
@@ -148,7 +147,7 @@
                     key("@"), key("#"), key(CURRENCY),
                     // U+2030: "‰" PER MILLE SIGN
                     key("%", moreKey("\u2030")),
-                    key("&"),
+                    "&",
                     // U+2013: "–" EN DASH
                     // U+2014: "—" EM DASH
                     // U+00B7: "·" MIDDLE DOT
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/SymbolsShifted.java b/tests/src/com/android/inputmethod/keyboard/layout/SymbolsShifted.java
index 7cbd2fb..f611310 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/SymbolsShifted.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/SymbolsShifted.java
@@ -34,7 +34,7 @@
     public ExpectedKey[][] getLayout(final boolean isPhone) {
         final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(SYMBOLS_SHIFTED_COMMON);
         final LayoutCustomizer customizer = mCustomizer;
-        builder.replaceKeyOfLabel(OTHER_CURRENCIES, customizer.getOtherCurrencyKeys());
+        builder.replaceKeyOfLabel(OTHER_CURRENCIES, (Object[])customizer.getOtherCurrencyKeys());
         if (isPhone) {
             builder.addKeysOnTheLeftOfRow(3, customizer.getBackToSymbolsKey())
                     .addKeysOnTheRightOfRow(3, DELETE_KEY)
@@ -44,7 +44,7 @@
             // Tablet symbols shifted keyboard has extra two keys at the right edge of the 3rd row.
             // U+00BF: "¿" INVERTED QUESTION MARK
             // U+00A1: "¡" INVERTED EXCLAMATION MARK
-            builder.addKeysOnTheRightOfRow(3, joinKeys("\u00A1", "\u00BF"));
+            builder.addKeysOnTheRightOfRow(3, (Object[])joinKeys("\u00A1", "\u00BF"));
             builder.addKeysOnTheRightOfRow(1, DELETE_KEY)
                     .addKeysOnTheRightOfRow(2, ENTER_KEY)
                     .addKeysOnTheLeftOfRow(3, customizer.getBackToSymbolsKey())
@@ -72,10 +72,8 @@
     // Common symbols shifted keyboard layout.
     private static final ExpectedKey[][] SYMBOLS_SHIFTED_COMMON = new ExpectedKeyboardBuilder()
             .setKeysOfRow(1,
-                    key("~"),
                     // U+0060: "`" GRAVE ACCENT
-                    key("\u0060"),
-                    key("|"),
+                    "~", "\u0060", "|",
                     // U+2022: "•" BULLET
                     // U+266A: "♪" EIGHTH NOTE
                     // U+2665: "♥" BLACK HEART SUIT
@@ -84,21 +82,20 @@
                     // U+2663: "♣" BLACK CLUB SUIT
                     key("\u2022", joinMoreKeys("\u266A", "\u2665", "\u2660", "\u2666", "\u2663")),
                     // U+221A: "√" SQUARE ROOT
-                    key("\u221A"),
+                    "\u221A",
                     // U+03C0: "π" GREEK SMALL LETTER PI
                     // U+03A0: "Π" GREEK CAPITAL LETTER PI
                     key("\u03C0", moreKey("\u03A0")),
                     // U+00F7: "÷" DIVISION SIGN
-                    key("\u00F7"),
                     // U+00D7: "×" MULTIPLICATION SIGN
-                    key("\u00D7"),
+                    "\u00F7", "\u00D7",
                     // U+00B6: "¶" PILCROW SIGN
                     // U+00A7: "§" SECTION SIGN
                     key("\u00B6", moreKey("\u00A7")),
                     // U+2206: "∆" INCREMENT
-                    key("\u2206"))
+                    "\u2206")
             .setKeysOfRow(2,
-                    key(OTHER_CURRENCIES),
+                    OTHER_CURRENCIES,
                     // U+2191: "↑" UPWARDS ARROW
                     // U+2193: "↓" DOWNWARDS ARROW
                     // U+2190: "←" LEFTWARDS ARROW
@@ -112,9 +109,8 @@
                     // U+2248: "≈" ALMOST EQUAL TO
                     // U+221E: "∞" INFINITY
                     key("=", joinMoreKeys("\u2260", "\u2248", "\u221E")),
-                    key("{"),
-                    key("}"))
-            .setLabelsOfRow(3,
+                    "{", "}")
+            .setKeysOfRow(3,
                     // U+00A9: "©" COPYRIGHT SIGN
                     // U+00AE: "®" REGISTERED SIGN
                     // U+2122: "™" TRADE MARK SIGN
@@ -129,7 +125,7 @@
                     // U+2265: "≥" GREATER-THAN EQUAL TO
                     // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
                     key(">", joinMoreKeys("\u203A", "\u2265", "\u00BB")),
-                    SPACE_KEY, key(","),
+                    SPACE_KEY, ",",
                     // U+2026: "…" HORIZONTAL ELLIPSIS
                     key(".", moreKey("\u2026")))
             .build();
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Thai.java b/tests/src/com/android/inputmethod/keyboard/layout/Thai.java
index 64081a1..253c93b 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/Thai.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Thai.java
@@ -69,11 +69,11 @@
         final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(ALPHABET_COMMON);
         if (isPhone) {
             // U+0E03: "ฃ" THAI CHARACTER KHO KHUAT
-            builder.addKeysOnTheRightOfRow(3, key("\u0E03"));
+            builder.addKeysOnTheRightOfRow(3, "\u0E03");
         } else {
             // U+0E03: "ฃ" THAI CHARACTER KHO KHUAT
-            builder.addKeysOnTheRightOfRow(2, key("\u0E03"))
-                    .addKeysOnTheRightOfRow(4, EXCLAMATION_AND_QUESTION_MARKS);
+            builder.addKeysOnTheRightOfRow(2, "\u0E03")
+                    .addKeysOnTheRightOfRow(4, (Object[])EXCLAMATION_AND_QUESTION_MARKS);
         }
         return builder.build();
     }
@@ -88,10 +88,10 @@
                 ALPHABET_SHIFTED_COMMON);
         if (isPhone) {
             // U+0E05: "ฅ" THAI CHARACTER KHO KHON
-            builder.addKeysOnTheRightOfRow(3, key("\u0E05"));
+            builder.addKeysOnTheRightOfRow(3, "\u0E05");
         } else {
             // U+0E05: "ฅ" THAI CHARACTER KHO KHON
-            builder.addKeysOnTheRightOfRow(2, key("\u0E05"));
+            builder.addKeysOnTheRightOfRow(2, "\u0E05");
         }
         return builder.build();
     }
@@ -101,11 +101,9 @@
     ExpectedKeyboardBuilder convertCommonLayoutToKeyboard(final ExpectedKeyboardBuilder builder,
             final boolean isPhone) {
         final LayoutCustomizer customizer = getCustomizer();
-        final ExpectedKey[] spacebar = joinKeys(
-                customizer.getKeysLeftToSpacebar(isPhone),
-                customizer.getSpaceKeys(isPhone),
-                customizer.getKeysRightToSpacebar(isPhone));
-        builder.setKeysOfRow(5, spacebar);
+        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())
@@ -116,15 +114,15 @@
                     .addKeysOnTheLeftOfRow(5, customizer.getSymbolsKey(), SETTINGS_KEY)
                     .addKeysOnTheRightOfRow(5, EMOJI_KEY);
         }
-        builder.addKeysOnTheLeftOfRow(4, customizer.getLeftShiftKeys(isPhone))
-                .addKeysOnTheRightOfRow(4, customizer.getRightShiftKeys(isPhone));
+        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+0E45: "ๅ" THAI CHARACTER LAKKHANGYAO
-                    key("\u0E45"),
+                    "\u0E45",
                     // U+0E51: "๑" THAI DIGIT ONE
                     key("/", joinMoreKeys("1", "\u0E51")),
                     // U+0E52: "๒" THAI DIGIT TWO
@@ -159,160 +157,110 @@
                     // U+0E50: "๐" THAI DIGIT ZERO
                     key("\u0E46", joinMoreKeys("0", "\u0E50")),
                     // U+0E44: "ไ" THAI CHARACTER SARA AI MAIMALAI
-                    key("\u0E44"),
                     // U+0E33: "ำ" THAI CHARACTER SARA AM
-                    key("\u0E33"),
                     // U+0E1E: "พ" THAI CHARACTER PHO PHAN
-                    key("\u0E1E"),
                     // U+0E30: "ะ" THAI CHARACTER SARA A
-                    key("\u0E30"),
+                    "\u0E44", "\u0E33", "\u0E1E", "\u0E30",
                     // U+0E31: " ั" THAI CHARACTER MAI HAN-AKAT
                     key(" \u0E31", "\u0E31"),
                     // U+0E35: " ี" HAI CHARACTER SARA II
                     key(" \u0E35", "\u0E35"),
                     // U+0E23: "ร" THAI CHARACTER RO RUA
-                    key("\u0E23"),
                     // U+0E19: "น" THAI CHARACTER NO NU
-                    key("\u0E19"),
                     // U+0E22: "ย" THAI CHARACTER YO YAK
-                    key("\u0E22"),
                     // U+0E1A: "บ" THAI CHARACTER BO BAIMAI
-                    key("\u0E1A"),
                     // U+0E25: "ล" THAI CHARACTER LO LING
-                    key("\u0E25"))
+                    "\u0E23", "\u0E19", "\u0E22", "\u0E1A", "\u0E25")
             .setKeysOfRow(3,
                     // U+0E1F: "ฟ" THAI CHARACTER FO FAN
-                    key("\u0E1F"),
                     // U+0E2B: "ห" THAI CHARACTER HO HIP
-                    key("\u0E2B"),
                     // U+0E01: "ก" THAI CHARACTER KO KAI
-                    key("\u0E01"),
                     // U+0E14: "ด" THAI CHARACTER DO DEK
-                    key("\u0E14"),
                     // U+0E40: "เ" THAI CHARACTER SARA E
-                    key("\u0E40"),
+                    "\u0E1F", "\u0E2B", "\u0E01", "\u0E14", "\u0E40",
                     // U+0E49: " ้" THAI CHARACTER MAI THO
                     key(" \u0E49", "\u0E49"),
                     // U+0E48: " ่" THAI CHARACTER MAI EK
                     key(" \u0E48", "\u0E48"),
                     // U+0E32: "า" THAI CHARACTER SARA AA
-                    key("\u0E32"),
                     // U+0E2A: "ส" THAI CHARACTER SO SUA
-                    key("\u0E2A"),
                     // U+0E27: "ว" THAI CHARACTER WO WAEN
-                    key("\u0E27"),
                     // U+0E07: "ง" THAI CHARACTER NGO NGU
-                    key("\u0E07"))
+                    "\u0E32", "\u0E2A", "\u0E27", "\u0E07")
             .setKeysOfRow(4,
                     // U+0E1C: "ผ" THAI CHARACTER PHO PHUNG
-                    key("\u0E1C"),
                     // U+0E1B: "ป" THAI CHARACTER PO PLA
-                    key("\u0E1B"),
                     // U+0E41: "แ" THAI CHARACTER SARA AE
-                    key("\u0E41"),
                     // U+0E2D: "อ" THAI CHARACTER O ANG
-                    key("\u0E2D"),
+                    "\u0E1C", "\u0E1B", "\u0E41", "\u0E2D",
                     // U+0E34: " ิ" THAI CHARACTER SARA I
                     key(" \u0E34", "\u0E34"),
                     // U+0E37: " ื" THAI CHARACTER SARA UEE
                     key(" \u0E37", "\u0E37"),
                     // U+0E17: "ท" THAI CHARACTER THO THAHAN
-                    key("\u0E17"),
                     // U+0E21: "ม" THAI CHARACTER MO MA
-                    key("\u0E21"),
                     // U+0E43: "ใ" THAI CHARACTER SARA AI MAIMUAN
-                    key("\u0E43"),
                     // U+0E1D: "ฝ" THAI CHARACTER FO FA
-                    key("\u0E1D"))
+                    "\u0E17", "\u0E21", "\u0E43", "\u0E1D")
             .build();
 
     private static final ExpectedKey[][] ALPHABET_SHIFTED_COMMON = new ExpectedKeyboardBuilder()
             .setKeysOfRow(1,
-                    key("+"),
                     // U+0E51: "๑" THAI DIGIT ONE
-                    key("\u0E51"),
                     // U+0E52: "๒" THAI DIGIT TWO
-                    key("\u0E52"),
                     // U+0E53: "๓" THAI DIGIT THREE
-                    key("\u0E53"),
                     // U+0E54: "๔" THAI DIGIT FOUR
-                    key("\u0E54"),
                     // U+0E39: " ู" THAI CHARACTER SARA UU
+                    "+", "\u0E51", "\u0E52", "\u0E53", "\u0E54",
                     key(" \u0E39", "\u0E39"),
                     // U+0E3F: "฿" THAI CURRENCY SYMBOL BAHT
-                    key("\u0E3F"),
                     // U+0E55: "๕" THAI DIGIT FIVE
-                    key("\u0E55"),
                     // U+0E56: "๖" THAI DIGIT SIX
-                    key("\u0E56"),
                     // U+0E57: "๗" THAI DIGIT SEVEN
-                    key("\u0E57"),
                     // U+0E58: "๘" THAI DIGIT EIGHT
-                    key("\u0E58"),
                     // U+0E59: "๙" THAI DIGIT NINE
-                    key("\u0E59"))
+                    "\u0E3F", "\u0E55", "\u0E56", "\u0E57", "\u0E58", "\u0E59")
             .setKeysOfRow(2,
                     // U+0E50: "๐" THAI DIGIT ZERO
-                    key("\u0E50"),
-                    key("\""),
                     // U+0E0E: "ฎ" THAI CHARACTER DO CHADA
-                    key("\u0E0E"),
                     // U+0E11: "ฑ" THAI CHARACTER THO NANGMONTHO
-                    key("\u0E11"),
                     // U+0E18: "ธ" THAI CHARACTER THO THONG
-                    key("\u0E18"),
+                    "\u0E50", "\"", "\u0E0E", "\u0E11", "\u0E18",
                     // U+0E4D: " ํ" THAI CHARACTER THANTHAKHAT
                     key(" \u0E4D", "\u0E4D"),
                     // U+0E4A: " ๊" THAI CHARACTER MAI TRI
                     key(" \u0E4A", "\u0E4A"),
                     // U+0E13: "ณ" THAI CHARACTER NO NEN
-                    key("\u0E13"),
                     // U+0E2F: "ฯ" THAI CHARACTER PAIYANNOI
-                    key("\u0E2F"),
                     // U+0E0D: "ญ" THAI CHARACTER YO YING
-                    key("\u0E0D"),
                     // U+0E10: "ฐ" THAI CHARACTER THO THAN
-                    key("\u0E10"),
-                    key(","))
+                    "\u0E13", "\u0E2F", "\u0E0D", "\u0E10", ",")
             .setKeysOfRow(3,
                     // U+0E24: "ฤ" THAI CHARACTER RU
-                    key("\u0E24"),
                     // U+0E06: "ฆ" THAI CHARACTER KHO RAKHANG
-                    key("\u0E06"),
                     // U+0E0F: "ฏ" THAI CHARACTER TO PATAK
-                    key("\u0E0F"),
                     // U+0E42: "โ" THAI CHARACTER SARA O
-                    key("\u0E42"),
                     // U+0E0C: "ฌ" THAI CHARACTER CHO CHOE
-                    key("\u0E0C"),
+                    "\u0E24", "\u0E06", "\u0E0F", "\u0E42", "\u0E0C",
                     // U+0E47: " ็" THAI CHARACTER MAITAIKHU
                     key(" \u0E47", "\u0E47"),
                     // U+0E4B: " ๋" THAI CHARACTER MAI CHATTAWA
                     key(" \u0E4B", "\u0E4B"),
                     // U+0E29: "ษ" THAI CHARACTER SO RUSI
-                    key("\u0E29"),
                     // U+0E28: "ศ" THAI CHARACTER SO SALA
-                    key("\u0E28"),
                     // U+0E0B: "ซ" THAI CHARACTER SO SO
-                    key("\u0E0B"),
-                    key("."))
+                    "\u0E29", "\u0E28", "\u0E0B", ".")
             .setKeysOfRow(4,
-                    key("("),
-                    key(")"),
                     // U+0E09: "ฉ" THAI CHARACTER CHO CHING
-                    key("\u0E09"),
                     // U+0E2E: "ฮ" THAI CHARACTER HO NOKHUK
-                    key("\u0E2E"),
+                    "(", ")", "\u0E09", "\u0E2E",
                     // U+0E3A: " ฺ" THAI CHARACTER PHINTHU
                     key(" \u0E3A", "\u0E3A"),
                     // U+0E4C: " ์" THAI CHARACTER THANTHAKHAT
                     key(" \u0E4C", "\u0E4C"),
-                    key("?"),
                     // U+0E12: "ฒ" THAI CHARACTER THO PHUTHAO
-                    key("\u0E12"),
                     // U+0E2C: "ฬ" THAI CHARACTER LO CHULA
-                    key("\u0E2C"),
                     // U+0E26: "ฦ" THAI CHARACTER LU
-                    key("\u0E26"))
+                    "?", "\u0E12", "\u0E2C", "\u0E26")
             .build();
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/expected/AbstractLayoutBase.java b/tests/src/com/android/inputmethod/keyboard/layout/expected/AbstractLayoutBase.java
index 61cadfc..6176f6a 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/expected/AbstractLayoutBase.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/expected/AbstractLayoutBase.java
@@ -17,13 +17,10 @@
 package com.android.inputmethod.keyboard.layout.expected;
 
 import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKey.ExpectedAdditionalMoreKey;
 import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.utils.CollectionUtils;
 import com.android.inputmethod.latin.utils.StringUtils;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-
 /**
  * Base class to create an expected keyboard for unit test.
  */
@@ -65,6 +62,15 @@
         return ExpectedKey.newInstance(key.getVisual(), key.getOutput(), moreKeys);
     }
 
+    // Helper method to create an {@link ExpectedAdditionalMoreKey} object for an
+    // "additional more key" that has the label.
+    // The additional more keys can be defined independently from other more keys. The position of
+    // the additional more keys in the long press popup keyboard can be controlled by specifying
+    // special marker "%" in the usual more keys definitions.
+    public static ExpectedAdditionalMoreKey additionalMoreKey(final String label) {
+        return ExpectedAdditionalMoreKey.newInstance(label);
+    }
+
     // Helper method to create an {@link ExpectedKey} object for a "more key" that has the label.
     public static ExpectedKey moreKey(final String label) {
         return ExpectedKey.newInstance(label);
@@ -97,26 +103,20 @@
     // Helper method to create {@link ExpectedKey} array by joining {@link ExpectedKey},
     // {@link ExpectedKey} array, and {@link String}.
     public static ExpectedKey[] joinKeys(final Object ... keys) {
-        final ArrayList<ExpectedKey> list = CollectionUtils.newArrayList();
-        for (final Object key : keys) {
-            if (key instanceof ExpectedKey) {
-                list.add((ExpectedKey)key);
-            } else if (key instanceof ExpectedKey[]) {
-                list.addAll(Arrays.asList((ExpectedKey[])key));
-            } else if (key instanceof String) {
-                list.add(key((String)key));
-            } else {
-                throw new RuntimeException("Unknown expected key type: " + key);
-            }
-        }
-        return list.toArray(new ExpectedKey[list.size()]);
+        return ExpectedKeyboardBuilder.joinKeys(keys);
     }
 
     // Icon ids.
     private static final int ICON_DELETE = KeyboardIconsSet.getIconId(
             KeyboardIconsSet.NAME_DELETE_KEY);
+    private static final int ICON_TAB = KeyboardIconsSet.getIconId(
+            KeyboardIconsSet.NAME_TAB_KEY);
+    private static final int ICON_SHORTCUT = KeyboardIconsSet.getIconId(
+            KeyboardIconsSet.NAME_SHORTCUT_KEY);
     private static final int ICON_SETTINGS = KeyboardIconsSet.getIconId(
             KeyboardIconsSet.NAME_SETTINGS_KEY);
+    private static final int ICON_LANGUAGE_SWITCH = KeyboardIconsSet.getIconId(
+            KeyboardIconsSet.NAME_LANGUAGE_SWITCH_KEY);
     private static final int ICON_ENTER = KeyboardIconsSet.getIconId(
             KeyboardIconsSet.NAME_ENTER_KEY);
     private static final int ICON_EMOJI = KeyboardIconsSet.getIconId(
@@ -124,7 +124,11 @@
 
     // Functional keys.
     public static final ExpectedKey DELETE_KEY = key(ICON_DELETE, Constants.CODE_DELETE);
+    public static final ExpectedKey TAB_KEY = key(ICON_TAB, Constants.CODE_TAB);
+    public static final ExpectedKey SHORTCUT_KEY = key(ICON_SHORTCUT, Constants.CODE_SHORTCUT);
     public static final ExpectedKey SETTINGS_KEY = key(ICON_SETTINGS, Constants.CODE_SETTINGS);
+    public static final ExpectedKey LANGUAGE_SWITCH_KEY = key(
+            ICON_LANGUAGE_SWITCH, Constants.CODE_LANGUAGE_SWITCH);
     public static final ExpectedKey ENTER_KEY = key(ICON_ENTER, Constants.CODE_ENTER);
     public static final ExpectedKey EMOJI_KEY = key(ICON_EMOJI, Constants.CODE_EMOJI);
     public static final ExpectedKey SPACE_KEY = key(
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKey.java b/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKey.java
index 98c08ad..ad08ba5 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKey.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKey.java
@@ -18,7 +18,9 @@
 
 import com.android.inputmethod.keyboard.Key;
 import com.android.inputmethod.keyboard.internal.MoreKeySpec;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Locale;
 
@@ -29,44 +31,73 @@
     static ExpectedKey EMPTY_KEY = newInstance("");
 
     // A key that has a string label and may have "more keys".
-    static ExpectedKey newInstance(final String label, final ExpectedKey ... moreKeys) {
+    static ExpectedKey newInstance(final String label, final ExpectedKey... moreKeys) {
         return newInstance(label, label, moreKeys);
     }
 
     // A key that has a string label and a different output text and may have "more keys".
     static ExpectedKey newInstance(final String label, final String outputText,
-            final ExpectedKey ... moreKeys) {
+            final ExpectedKey... moreKeys) {
         return newInstance(ExpectedKeyVisual.newInstance(label),
                 ExpectedKeyOutput.newInstance(outputText), moreKeys);
     }
 
     // A key that has a string label and a code point output and may have "more keys".
     static ExpectedKey newInstance(final String label, final int code,
-            final ExpectedKey ... moreKeys) {
+            final ExpectedKey... moreKeys) {
         return newInstance(ExpectedKeyVisual.newInstance(label),
                 ExpectedKeyOutput.newInstance(code), moreKeys);
     }
 
     // A key that has an icon and an output text and may have "more keys".
     static ExpectedKey newInstance(final int iconId, final String outputText,
-            final ExpectedKey ... moreKeys) {
+            final ExpectedKey... moreKeys) {
         return newInstance(ExpectedKeyVisual.newInstance(iconId),
                 ExpectedKeyOutput.newInstance(outputText), moreKeys);
     }
 
     // A key that has an icon and a code point output and may have "more keys".
     static ExpectedKey newInstance(final int iconId, final int code,
-            final ExpectedKey ... moreKeys) {
+            final ExpectedKey... moreKeys) {
         return newInstance(ExpectedKeyVisual.newInstance(iconId),
                 ExpectedKeyOutput.newInstance(code), moreKeys);
     }
 
     static ExpectedKey newInstance(final ExpectedKeyVisual visual, final ExpectedKeyOutput output,
-            final ExpectedKey ... moreKeys) {
+            final ExpectedKey... moreKeys) {
         if (moreKeys.length == 0) {
             return new ExpectedKey(visual, output);
         }
-        return new ExpectedKeyWithMoreKeys(visual, output, moreKeys);
+        // The more keys are the extra keys that the main keyboard key may have in its long press
+        // popup keyboard.
+        // The additional more keys can be defined independently from other more keys.
+        // The position of the additional more keys in the long press popup keyboard can be
+        // controlled by specifying special marker "%" in the usual more keys definitions.
+        final ArrayList<ExpectedKey> moreKeysList = CollectionUtils.newArrayList();
+        final ArrayList<ExpectedAdditionalMoreKey> additionalMoreKeys =
+                CollectionUtils.newArrayList();
+        int firstAdditionalMoreKeyIndex = -1;
+        for (int index = 0; index < moreKeys.length; index++) {
+            final ExpectedKey moreKey = moreKeys[index];
+            if (moreKey instanceof ExpectedAdditionalMoreKey) {
+                additionalMoreKeys.add((ExpectedAdditionalMoreKey) moreKey);
+                if (firstAdditionalMoreKeyIndex < 0) {
+                    firstAdditionalMoreKeyIndex = index;
+                }
+            } else {
+                moreKeysList.add(moreKey);
+            }
+        }
+        if (additionalMoreKeys.isEmpty()) {
+            return new ExpectedKeyWithMoreKeys(visual, output, moreKeys);
+        }
+        final ExpectedKey[] moreKeysArray = moreKeysList.toArray(
+                new ExpectedKey[moreKeysList.size()]);
+        final ExpectedAdditionalMoreKey[] additionalMoreKeysArray = additionalMoreKeys.toArray(
+                new ExpectedAdditionalMoreKey[additionalMoreKeys.size()]);
+        return new ExpectedKeyWithMoreKeysAndAdditionalMoreKeys(
+                visual, output, moreKeysArray, firstAdditionalMoreKeyIndex,
+                additionalMoreKeysArray);
     }
 
     private static final ExpectedKey[] EMPTY_KEYS = new ExpectedKey[0];
@@ -89,6 +120,27 @@
         return EMPTY_KEYS;
     }
 
+    public ExpectedKey setMoreKeys(final ExpectedKey... moreKeys) {
+        return newInstance(mVisual, mOutput, moreKeys);
+    }
+
+    public ExpectedKey setAdditionalMoreKeys(
+            final ExpectedAdditionalMoreKey... additionalMoreKeys) {
+        if (additionalMoreKeys.length == 0) {
+            return this;
+        }
+        return new ExpectedKeyWithMoreKeysAndAdditionalMoreKeys(
+                mVisual, mOutput, EMPTY_KEYS, 0 /* additionalMoreKeysIndex */, additionalMoreKeys);
+    }
+
+    public ExpectedKey setAdditionalMoreKeysIndex(final int additionalMoreKeysIndex) {
+        if (additionalMoreKeysIndex == 0) {
+            return this;
+        }
+        return new ExpectedKeyWithMoreKeysAndAdditionalMoreKeys(
+                mVisual, mOutput, EMPTY_KEYS, additionalMoreKeysIndex);
+    }
+
     protected ExpectedKey(final ExpectedKeyVisual visual, final ExpectedKeyOutput output) {
         mVisual = visual;
         mOutput = output;
@@ -110,14 +162,14 @@
     @Override
     public boolean equals(final Object object) {
         if (object instanceof ExpectedKey) {
-            final ExpectedKey key = (ExpectedKey)object;
+            final ExpectedKey key = (ExpectedKey) object;
             return mVisual.equalsTo(key.mVisual) && mOutput.equalsTo(key.mOutput)
                     && Arrays.equals(getMoreKeys(), key.getMoreKeys());
         }
         return false;
     }
 
-    private static int hashCode(final Object ... objects) {
+    private static int hashCode(final Object... objects) {
         return Arrays.hashCode(objects);
     }
 
@@ -135,13 +187,42 @@
     }
 
     /**
+     * This class represents an expected "additional more key".
+     *
+     * The additional more keys can be defined independently from other more keys. The position of
+     * the additional more keys in the long press popup keyboard can be controlled by specifying
+     * special marker "%" in the usual more keys definitions.
+     */
+    public static class ExpectedAdditionalMoreKey extends ExpectedKey {
+        public static ExpectedAdditionalMoreKey newInstance(final String label) {
+            return new ExpectedAdditionalMoreKey(ExpectedKeyVisual.newInstance(label),
+                    ExpectedKeyOutput.newInstance(label));
+        }
+
+        public static ExpectedAdditionalMoreKey newInstance(final ExpectedKey key) {
+            return new ExpectedAdditionalMoreKey(key.getVisual(), key.getOutput());
+        }
+
+        ExpectedAdditionalMoreKey(final ExpectedKeyVisual visual, final ExpectedKeyOutput output) {
+            super(visual, output);
+        }
+
+        @Override
+        public ExpectedAdditionalMoreKey toUpperCase(final Locale locale) {
+            final ExpectedKey upperCaseKey = super.toUpperCase(locale);
+            return new ExpectedAdditionalMoreKey(
+                    upperCaseKey.getVisual(), upperCaseKey.getOutput());
+        }
+    }
+
+    /**
      * This class represents an expected key that has "more keys".
      */
-    private static final class ExpectedKeyWithMoreKeys extends ExpectedKey {
+    private static class ExpectedKeyWithMoreKeys extends ExpectedKey {
         private final ExpectedKey[] mMoreKeys;
 
-        ExpectedKeyWithMoreKeys(final ExpectedKeyVisual visual,
-                final ExpectedKeyOutput output, final ExpectedKey ... moreKeys) {
+        ExpectedKeyWithMoreKeys(final ExpectedKeyVisual visual, final ExpectedKeyOutput output,
+                final ExpectedKey... moreKeys) {
             super(visual, output);
             mMoreKeys = moreKeys;
         }
@@ -162,15 +243,36 @@
         }
 
         @Override
+        public ExpectedKey setAdditionalMoreKeys(
+                final ExpectedAdditionalMoreKey... additionalMoreKeys) {
+            if (additionalMoreKeys.length == 0) {
+                return this;
+            }
+            return new ExpectedKeyWithMoreKeysAndAdditionalMoreKeys(
+                    getVisual(), getOutput(), mMoreKeys, 0 /* additionalMoreKeysIndex */,
+                    additionalMoreKeys);
+        }
+
+        @Override
+        public ExpectedKey setAdditionalMoreKeysIndex(final int additionalMoreKeysIndex) {
+            if (additionalMoreKeysIndex == 0) {
+                return this;
+            }
+            return new ExpectedKeyWithMoreKeysAndAdditionalMoreKeys(
+                    getVisual(), getOutput(), mMoreKeys, additionalMoreKeysIndex);
+        }
+
+        @Override
         public boolean equalsTo(final Key key) {
             if (getVisual().equalsTo(key) && getOutput().equalsTo(key)) {
-                final MoreKeySpec[] moreKeys = key.getMoreKeys();
+                final MoreKeySpec[] moreKeySpecs = key.getMoreKeys();
+                final ExpectedKey[] moreKeys = getMoreKeys();
                 // This key should have at least one "more key".
-                if (moreKeys == null || moreKeys.length != mMoreKeys.length) {
+                if (moreKeySpecs == null || moreKeySpecs.length != moreKeys.length) {
                     return false;
                 }
-                for (int index = 0; index < moreKeys.length; index++) {
-                    if (!mMoreKeys[index].equalsTo(moreKeys[index])) {
+                for (int index = 0; index < moreKeySpecs.length; index++) {
+                    if (!moreKeys[index].equalsTo(moreKeySpecs[index])) {
                         return false;
                     }
                 }
@@ -187,7 +289,77 @@
 
         @Override
         public String toString() {
-            return super.toString() + "^" + Arrays.toString(mMoreKeys);
+            return super.toString() + "^" + Arrays.toString(getMoreKeys());
+        }
+    }
+
+    /**
+     * This class represents an expected key that has "more keys" and "additional more keys".
+     */
+    private static final class ExpectedKeyWithMoreKeysAndAdditionalMoreKeys
+            extends ExpectedKeyWithMoreKeys {
+        private final ExpectedAdditionalMoreKey[] mAdditionalMoreKeys;
+        private final int mAdditionalMoreKeysIndex;
+
+        ExpectedKeyWithMoreKeysAndAdditionalMoreKeys(final ExpectedKeyVisual visual,
+                final ExpectedKeyOutput output, final ExpectedKey[] moreKeys,
+                final int additionalMoreKeysIndex,
+                final ExpectedAdditionalMoreKey... additionalMoreKeys) {
+            super(visual, output, moreKeys);
+            mAdditionalMoreKeysIndex = additionalMoreKeysIndex;
+            mAdditionalMoreKeys = additionalMoreKeys;
+        }
+
+        @Override
+        public ExpectedKey setMoreKeys(final ExpectedKey... moreKeys) {
+            return new ExpectedKeyWithMoreKeysAndAdditionalMoreKeys(
+                    getVisual(), getOutput(), moreKeys, mAdditionalMoreKeysIndex,
+                    mAdditionalMoreKeys);
+        }
+
+        @Override
+        public ExpectedKey setAdditionalMoreKeys(
+                final ExpectedAdditionalMoreKey... additionalMoreKeys) {
+            return new ExpectedKeyWithMoreKeysAndAdditionalMoreKeys(
+                    getVisual(), getOutput(), super.getMoreKeys(), mAdditionalMoreKeysIndex,
+                    additionalMoreKeys);
+        }
+
+        @Override
+        public ExpectedKey setAdditionalMoreKeysIndex(final int additionalMoreKeysIndex) {
+            return new ExpectedKeyWithMoreKeysAndAdditionalMoreKeys(
+                    getVisual(), getOutput(), super.getMoreKeys(), additionalMoreKeysIndex,
+                    mAdditionalMoreKeys);
+        }
+
+        @Override
+        public ExpectedKey toUpperCase(final Locale locale) {
+            final ExpectedKey[] moreKeys = super.getMoreKeys();
+            final ExpectedKey[] upperCaseMoreKeys = new ExpectedKey[moreKeys.length];
+            for (int i = 0; i < moreKeys.length; i++) {
+                upperCaseMoreKeys[i] = moreKeys[i].toUpperCase(locale);
+            }
+            final ExpectedAdditionalMoreKey[] upperCaseAdditionalMoreKeys =
+                    new ExpectedAdditionalMoreKey[mAdditionalMoreKeys.length];
+            for (int i = 0; i < mAdditionalMoreKeys.length; i++) {
+                upperCaseAdditionalMoreKeys[i] = mAdditionalMoreKeys[i].toUpperCase(locale);
+            }
+            return new ExpectedKeyWithMoreKeysAndAdditionalMoreKeys(
+                    getVisual().toUpperCase(locale), getOutput().toUpperCase(locale),
+                    upperCaseMoreKeys, mAdditionalMoreKeysIndex, upperCaseAdditionalMoreKeys);
+        }
+
+        @Override
+        public ExpectedKey[] getMoreKeys() {
+            final ExpectedKey[] moreKeys = super.getMoreKeys();
+            final ExpectedKey[] edittedMoreKeys = Arrays.copyOf(
+                    moreKeys, moreKeys.length + mAdditionalMoreKeys.length);
+            System.arraycopy(edittedMoreKeys, mAdditionalMoreKeysIndex,
+                    edittedMoreKeys, mAdditionalMoreKeysIndex + mAdditionalMoreKeys.length,
+                    moreKeys.length - mAdditionalMoreKeysIndex);
+            System.arraycopy(mAdditionalMoreKeys, 0, edittedMoreKeys, mAdditionalMoreKeysIndex,
+                    mAdditionalMoreKeys.length);
+            return edittedMoreKeys;
         }
     }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyboardBuilder.java b/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyboardBuilder.java
index 176e0eb..f068ad1 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyboardBuilder.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyboardBuilder.java
@@ -16,6 +16,9 @@
 
 package com.android.inputmethod.keyboard.layout.expected;
 
+import com.android.inputmethod.latin.utils.CollectionUtils;
+
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Locale;
 
@@ -105,67 +108,57 @@
         }
     }
 
-    /**
-     * Set the row with specified keys that have specified labels.
-     * @param row the row number to set keys.
-     * @param labels the label texts of the keys.
-     * @return this builder.
-     */
-    public ExpectedKeyboardBuilder setLabelsOfRow(final int row, final String ... labels) {
-        final ExpectedKey[] keys = new ExpectedKey[labels.length];
-        for (int columnIndex = 0; columnIndex < labels.length; columnIndex++) {
-            keys[columnIndex] = ExpectedKey.newInstance(labels[columnIndex]);
+    // Helper method to create {@link ExpectedKey} array by joining {@link ExpectedKey},
+    // {@link ExpectedKey} array, and {@link String}.
+    static ExpectedKey[] joinKeys(final Object ... keys) {
+        final ArrayList<ExpectedKey> list = CollectionUtils.newArrayList();
+        for (final Object key : keys) {
+            if (key instanceof ExpectedKey) {
+                list.add((ExpectedKey)key);
+            } else if (key instanceof ExpectedKey[]) {
+                list.addAll(Arrays.asList((ExpectedKey[])key));
+            } else if (key instanceof String) {
+                list.add(ExpectedKey.newInstance((String)key));
+            } else {
+                throw new RuntimeException("Unknown expected key type: " + key);
+            }
         }
-        setRowAt(row, keys);
-        return this;
+        return list.toArray(new ExpectedKey[list.size()]);
     }
 
     /**
      * Set the row with specified keys.
      * @param row the row number to set keys.
-     * @param keys the keys to be set at <code>row</code>.
+     * @param keys the keys to be set at <code>row</code>. Each key can be {@link ExpectedKey},
+     *        {@link ExpectedKey} array, and {@link String}.
      * @return this builder.
      */
-    public ExpectedKeyboardBuilder setKeysOfRow(final int row, final ExpectedKey ... keys) {
-        setRowAt(row, keys);
+    public ExpectedKeyboardBuilder setKeysOfRow(final int row, final Object ... keys) {
+        setRowAt(row, joinKeys(keys));
         return this;
     }
 
     /**
      * Set the "more keys" of the key that has the specified label.
      * @param label the label of the key to set the "more keys".
-     * @param moreKeys the array of labels of the "more keys" to be set.
+     * @param moreKeys the array of "more key" to be set. Each "more key" can be
+     *        {@link ExpectedKey}, {@link ExpectedKey} array, and {@link String}.
      * @return this builder.
      */
-    public ExpectedKeyboardBuilder setMoreKeysOf(final String label, final String ... moreKeys) {
-        final ExpectedKey[] expectedMoreKeys = new ExpectedKey[moreKeys.length];
-        for (int index = 0; index < moreKeys.length; index++) {
-            expectedMoreKeys[index] = ExpectedKey.newInstance(moreKeys[index]);
-        }
-        setMoreKeysOf(label, expectedMoreKeys);
-        return this;
-    }
-
-    /**
-     * Set the "more keys" of the key that has the specified label.
-     * @param label the label of the key to set the "more keys".
-     * @param moreKeys the array of "more key" to be set.
-     * @return this builder.
-     */
-    public ExpectedKeyboardBuilder setMoreKeysOf(final String label,
-            final ExpectedKey ... moreKeys) {
-        setMoreKeysOf(ExpectedKeyVisual.newInstance(label), moreKeys);
+    public ExpectedKeyboardBuilder setMoreKeysOf(final String label, final Object ... moreKeys) {
+        setMoreKeysOf(ExpectedKeyVisual.newInstance(label), joinKeys(moreKeys));
         return this;
     }
 
     /**
      * Set the "more keys" of the key that has the specified icon.
      * @param iconId the icon id of the key to set the "more keys".
-     * @param moreKeys the array of "more key" to be set.
+     * @param moreKeys the array of "more key" to be set. Each "more key" can be
+     *        {@link ExpectedKey}, {@link ExpectedKey} array, and {@link String}.
      * @return this builder.
      */
-    public ExpectedKeyboardBuilder setMoreKeysOf(final int iconId, final ExpectedKey ... moreKeys) {
-        setMoreKeysOf(ExpectedKeyVisual.newInstance(iconId), moreKeys);
+    public ExpectedKeyboardBuilder setMoreKeysOf(final int iconId, final Object ... moreKeys) {
+        setMoreKeysOf(ExpectedKeyVisual.newInstance(iconId), joinKeys(moreKeys));
         return this;
     }
 
@@ -173,9 +166,7 @@
         replaceKeyOf(visual, new ReplaceJob() {
             @Override
             public ExpectedKey[] replacingKeys(final ExpectedKey oldKey) {
-                return new ExpectedKey[] {
-                    ExpectedKey.newInstance(oldKey.getVisual(), oldKey.getOutput(), moreKeys)
-                };
+                return new ExpectedKey[] { oldKey.setMoreKeys(moreKeys) };
             }
             @Override
             public boolean stopAtFirstOccurrence() {
@@ -185,17 +176,49 @@
     }
 
     /**
+     * Set the "additional more keys position" of the key that has the specified label.
+     * @param label the label of the key to set the "additional more keys".
+     * @param additionalMoreKeysPosition the position in the "more keys" where
+     *        "additional more keys" will be merged. The position starts from 1.
+     * @return this builder.
+     */
+    public ExpectedKeyboardBuilder setAdditionalMoreKeysPositionOf(final String label,
+            final int additionalMoreKeysPosition) {
+        final int additionalMoreKeysIndex = additionalMoreKeysPosition - 1;
+        if (additionalMoreKeysIndex < 0) {
+            throw new RuntimeException("Illegal additional more keys position: "
+                    + additionalMoreKeysPosition);
+        }
+        final ExpectedKeyVisual visual = ExpectedKeyVisual.newInstance(label);
+        replaceKeyOf(visual, new ReplaceJob() {
+            @Override
+            public ExpectedKey[] replacingKeys(final ExpectedKey oldKey) {
+                return new ExpectedKey[] {
+                        oldKey.setAdditionalMoreKeysIndex(additionalMoreKeysIndex)
+                };
+            }
+            @Override
+            public boolean stopAtFirstOccurrence() {
+                return true;
+            }
+        });
+        return this;
+    }
+
+    /**
      * Insert the keys at specified position.
      * @param row the row number to insert the <code>keys</code>.
      * @param column the column number to insert the <code>keys</code>.
-     * @param keys the array of keys to insert at <code>row,column</code>.
+     * @param keys the array of keys to insert at <code>row,column</code>. Each key can be
+     *        {@link ExpectedKey}, {@link ExpectedKey} array, and {@link String}.
      * @return this builder.
      * @throws {@link RuntimeException} if <code>row</code> or <code>column</code> is illegal.
      */
     public ExpectedKeyboardBuilder insertKeysAtRow(final int row, final int column,
-            final ExpectedKey ... keys) {
+            final Object ... keys) {
+        final ExpectedKey[] expectedKeys = joinKeys(keys);
         for (int index = 0; index < keys.length; index++) {
-            setElementAt(row, column + index, keys[index], true /* insert */);
+            setElementAt(row, column + index, expectedKeys[index], true /* insert */);
         }
         return this;
     }
@@ -203,15 +226,17 @@
     /**
      * Add the keys on the left most of the row.
      * @param row the row number to add the <code>keys</code>.
-     * @param keys the array of keys to add on the left most of the row.
+     * @param keys the array of keys to add on the left most of the row. Each key can be
+     *        {@link ExpectedKey}, {@link ExpectedKey} array, and {@link String}.
      * @return this builder.
      * @throws {@link RuntimeException} if <code>row</code> is illegal.
      */
     public ExpectedKeyboardBuilder addKeysOnTheLeftOfRow(final int row,
-            final ExpectedKey ... keys) {
+            final Object ... keys) {
+        final ExpectedKey[] expectedKeys = joinKeys(keys);
         // Keys should be inserted from the last to preserve the order.
         for (int index = keys.length - 1; index >= 0; index--) {
-            setElementAt(row, 1, keys[index], true /* insert */);
+            setElementAt(row, 1, expectedKeys[index], true /* insert */);
         }
         return this;
     }
@@ -219,12 +244,13 @@
     /**
      * Add the keys on the right most of the row.
      * @param row the row number to add the <code>keys</code>.
-     * @param keys the array of keys to add on the right most of the row.
+     * @param keys the array of keys to add on the right most of the row. Each key can be
+     *        {@link ExpectedKey}, {@link ExpectedKey} array, and {@link String}.
      * @return this builder.
      * @throws {@link RuntimeException} if <code>row</code> is illegal.
      */
     public ExpectedKeyboardBuilder addKeysOnTheRightOfRow(final int row,
-            final ExpectedKey ... keys) {
+            final Object ... keys) {
         final int rightEnd = getRowAt(row).length + 1;
         insertKeysAtRow(row, rightEnd, keys);
         return this;
@@ -233,16 +259,17 @@
     /**
      * Replace the most top-left key that has the specified label with the new keys.
      * @param label the label of the key to set <code>newKeys</code>.
-     * @param newKeys the keys to be set.
+     * @param newKeys the keys to be set. Each key can be {@link ExpectedKey}, {@link ExpectedKey}
+     *        array, and {@link String}.
      * @return this builder.
      */
     public ExpectedKeyboardBuilder replaceKeyOfLabel(final String label,
-            final ExpectedKey ... newKeys) {
+            final Object ... newKeys) {
         final ExpectedKeyVisual visual = ExpectedKeyVisual.newInstance(label);
         replaceKeyOf(visual, new ReplaceJob() {
             @Override
             public ExpectedKey[] replacingKeys(final ExpectedKey oldKey) {
-                return newKeys;
+                return joinKeys(newKeys);
             }
             @Override
             public boolean stopAtFirstOccurrence() {
@@ -255,15 +282,16 @@
     /**
      * Replace the all specified keys with the new keys.
      * @param key the key to be replaced by <code>newKeys</code>.
-     * @param newKeys the keys to be set.
+     * @param newKeys the keys to be set. Each key can be {@link ExpectedKey}, {@link ExpectedKey}
+     *        array, and {@link String}.
      * @return this builder.
      */
     public ExpectedKeyboardBuilder replaceKeysOfAll(final ExpectedKey key,
-            final ExpectedKey ... newKeys) {
+            final Object ... newKeys) {
         replaceKeyOf(key.getVisual(), new ReplaceJob() {
             @Override
             public ExpectedKey[] replacingKeys(final ExpectedKey oldKey) {
-                return newKeys;
+                return joinKeys(newKeys);
             }
             @Override
             public boolean stopAtFirstOccurrence() {
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/EnglishCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/EnglishCustomizer.java
new file mode 100644
index 0000000..29264ff
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/EnglishCustomizer.java
@@ -0,0 +1,76 @@
+/*
+ * 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 EnglishCustomizer extends LayoutCustomizer {
+    EnglishCustomizer(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+0113: "ē" LATIN SMALL LETTER E WITH MACRON
+                .setMoreKeysOf("e", "\u00E8", "\u00E9", "\u00EA", "\u00EB", "\u0113")
+                // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
+                // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
+                // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
+                // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
+                // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
+                .setMoreKeysOf("u", "\u00FB", "\u00FC", "\u00F9", "\u00FA", "\u016B")
+                // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
+                // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
+                // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
+                // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
+                // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
+                .setMoreKeysOf("i", "\u00EE", "\u00EF", "\u00ED", "\u012B", "\u00EC")
+                // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
+                // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
+                // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
+                // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
+                // U+0153: "œ" LATIN SMALL LIGATURE OE
+                // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
+                // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
+                // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
+                .setMoreKeysOf("o",
+                        "\u00F4", "\u00F6", "\u00F2", "\u00F3", "\u0153", "\u00F8", "\u014D",
+                        "\u00F5")
+                // 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
+                .setMoreKeysOf("a",
+                        "\u00E0", "\u00E1", "\u00E2", "\u00E4", "\u00E6", "\u00E3", "\u00E5",
+                        "\u0101")
+                // U+00DF: "ß" LATIN SMALL LETTER SHARP S
+                .setMoreKeysOf("s", "\u00DF")
+                // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
+                .setMoreKeysOf("c", "\u00E7")
+                // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
+                .setMoreKeysOf("n", "\u00F1");
+    }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/FrenchCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/FrenchCustomizer.java
new file mode 100644
index 0000000..ab90267
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/FrenchCustomizer.java
@@ -0,0 +1,89 @@
+/*
+ * 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 FrenchCustomizer extends LayoutCustomizer {
+    FrenchCustomizer(final Locale locale) { super(locale); }
+
+    @Override
+    public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
+        return builder
+                // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
+                // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
+                // U+00E6: "æ" LATIN SMALL LETTER AE
+                // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
+                // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
+                // 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
+                .setAdditionalMoreKeysPositionOf("a", 3)
+                .setMoreKeysOf("a",
+                        "\u00E0", "\u00E2", "\u00E6", "\u00E1", "\u00E4", "\u00E3", "\u00E5",
+                        "\u0101", "\u00AA")
+                // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
+                // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
+                // 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
+                .setAdditionalMoreKeysPositionOf("e", 5)
+                .setMoreKeysOf("e",
+                        "\u00E9", "\u00E8", "\u00EA", "\u00EB", "\u0119", "\u0117", "\u0113")
+                // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
+                .setMoreKeysOf("y", "\u00FF")
+                // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
+                // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
+                // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
+                // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
+                // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
+                .setAdditionalMoreKeysPositionOf("u", 3)
+                .setMoreKeysOf("u", "\u00F9", "\u00FB", "\u00FC", "\u00FA", "\u016B")
+                // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
+                // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
+                // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
+                // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
+                // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
+                // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
+                .setAdditionalMoreKeysPositionOf("i", 2)
+                .setMoreKeysOf("i", "\u00EE", "\u00EF", "\u00EC", "\u00ED", "\u012F", "\u012B")
+                // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
+                // U+0153: "œ" LATIN SMALL LIGATURE OE
+                // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
+                // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
+                // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
+                // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
+                // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
+                // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
+                // U+00BA: "º" MASCULINE ORDINAL INDICATOR
+                .setAdditionalMoreKeysPositionOf("o", 3)
+                .setMoreKeysOf("o",
+                        "\u00F4", "\u0153", "\u00F6", "\u00F2", "\u00F3", "\u00F5", "\u00F8",
+                        "\u014D", "\u00BA")
+                // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
+                // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
+                // U+010D: "č" LATIN SMALL LETTER C WITH CARON
+                .setMoreKeysOf("c", "\u00E7", "\u0107", "\u010D")
+                .setAdditionalMoreKeysPositionOf("c", 2);
+    }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/GermanCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/GermanCustomizer.java
new file mode 100644
index 0000000..cd88140
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/GermanCustomizer.java
@@ -0,0 +1,86 @@
+/*
+ * 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.Symbols;
+import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+
+import java.util.Locale;
+
+class GermanCustomizer extends LayoutCustomizer {
+    public GermanCustomizer(final Locale locale) { super(locale); }
+
+    @Override
+    public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_R9L; }
+
+    @Override
+    public ExpectedKey[] getSingleQuoteMoreKeys() { return Symbols.SINGLE_QUOTES_R9L; }
+
+    @Override
+    public ExpectedKey[] getDoubleAngleQuoteKeys() { return Symbols.DOUBLE_ANGLE_QUOTES_RL; }
+
+    @Override
+    public ExpectedKey[] getSingleAngleQuoteKeys() { return Symbols.SINGLE_ANGLE_QUOTES_RL; }
+
+    @Override
+    public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
+        return builder
+                // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
+                // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
+                // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
+                // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
+                // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
+                .setMoreKeysOf("e", "\u00E9", "\u00E8", "\u00EA", "\u00EB", "\u0117")
+                // 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
+                .setMoreKeysOf("u", "\u00FC", "\u00FB", "\u00F9", "\u00FA", "\u016B")
+                // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
+                // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
+                // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
+                // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
+                // 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
+                .setMoreKeysOf("o",
+                        "\u00F6", "\u00F4", "\u00F2", "\u00F3", "\u00F5", "\u0153", "\u00F8",
+                        "\u014D")
+                // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
+                // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
+                // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
+                // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
+                // 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
+                .setMoreKeysOf("a",
+                        "\u00E4", "\u00E2", "\u00E0", "\u00E1", "\u00E6", "\u00E3", "\u00E5",
+                        "\u0101")
+                // U+00DF: "ß" LATIN SMALL LETTER SHARP S
+                // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
+                // U+0161: "š" LATIN SMALL LETTER S WITH CARON
+                .setMoreKeysOf("s", "\u00DF", "\u015B", "\u0161")
+                // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
+                // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
+                .setMoreKeysOf("n", "\u00F1", "\u0144");
+    }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/LayoutTestsBase.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/LayoutTestsBase.java
index c51abc0..555ec89 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/LayoutTestsBase.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/LayoutTestsBase.java
@@ -28,6 +28,7 @@
 import com.android.inputmethod.keyboard.layout.expected.AbstractLayoutBase;
 import com.android.inputmethod.keyboard.layout.expected.ActualKeyboardBuilder;
 import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKey.ExpectedAdditionalMoreKey;
 import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
 import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
 
@@ -72,6 +73,12 @@
         return AbstractLayoutBase.key(key, moreKeys);
     }
 
+    // Helper method to create an {@link ExpectedAdditionalMoreKey} object for an
+    // "additional more key" that has the label.
+    public static ExpectedAdditionalMoreKey additionalMoreKey(final String label) {
+        return AbstractLayoutBase.additionalMoreKey(label);
+    }
+
     // Helper method to create an {@link ExpectedKey} object for a "more key" that has the label.
     static ExpectedKey moreKey(final String label) {
         return AbstractLayoutBase.moreKey(label);
@@ -150,7 +157,7 @@
         Log.d(tag, "actual  =\n" + ActualKeyboardBuilder.toString(actualKeyboard));
         // Test both keyboards have the same number of rows.
         assertEquals(tag + " labels"
-                + "\nexpected=" + Arrays.deepToString(expectedKeyboard)
+                + "\nexpected=" + ExpectedKeyboardBuilder.toString(expectedKeyboard)
                 + "\nactual  =" + ActualKeyboardBuilder.toString(actualKeyboard),
                 expectedKeyboard.length, actualKeyboard.length);
         for (int r = 0; r < actualKeyboard.length; r++) {
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/NoLanguageCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/NoLanguageCustomizer.java
new file mode 100644
index 0000000..9edbcab
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/NoLanguageCustomizer.java
@@ -0,0 +1,159 @@
+/*
+ * 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 NoLanguageCustomizer extends LayoutCustomizer {
+    NoLanguageCustomizer(final Locale locale) { super(locale); }
+
+    @Override
+    public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
+        return builder
+                // U+0175: "ŵ" LATIN SMALL LETTER W WITH CIRCUMFLEX
+                .setMoreKeysOf("w", "\u0175")
+                // 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+0113: "ē" LATIN SMALL LETTER E WITH MACRON
+                // U+0115: "ĕ" LATIN SMALL LETTER E WITH BREVE
+                // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
+                // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK
+                // U+011B: "ě" LATIN SMALL LETTER E WITH CARON
+                .setMoreKeysOf("e",
+                        "\u00E8", "\u00E9", "\u00EA", "\u00EB", "\u0113", "\u0115", "\u0117",
+                        "\u0119", "\u011B")
+                // U+0155: "ŕ" LATIN SMALL LETTER R WITH ACUTE
+                // U+0157: "ŗ" LATIN SMALL LETTER R WITH CEDILLA
+                // U+0159: "ř" LATIN SMALL LETTER R WITH CARON
+                .setMoreKeysOf("r", "\u0155", "\u0157", "\u0159")
+                // U+00FE: "þ" LATIN SMALL LETTER THORN
+                // U+0163: "ţ" LATIN SMALL LETTER T WITH CEDILLA
+                // U+0165: "ť" LATIN SMALL LETTER T WITH CARON
+                // U+0167: "ŧ" LATIN SMALL LETTER T WITH STROKE
+                .setMoreKeysOf("t", "\u00FE", "\u0163", "\u0165", "\u0167")
+                // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
+                // U+0177: "ŷ" LATIN SMALL LETTER Y WITH CIRCUMFLEX
+                // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
+                // U+0133: "ij" LATIN SMALL LIGATURE IJ
+                .setMoreKeysOf("y", "\u00FD", "\u0177", "\u00FF", "\u0133")
+                // 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+0169: "ũ" LATIN SMALL LETTER U WITH TILDE
+                // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
+                // U+016D: "ŭ" LATIN SMALL LETTER U WITH BREVE
+                // U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE
+                // U+0171: "ű" LATIN SMALL LETTER U WITH DOUBLE ACUTE
+                // U+0173: "ų" LATIN SMALL LETTER U WITH OGONEK
+                .setMoreKeysOf("u",
+                        "\u00F9", "\u00FA", "\u00FB", "\u00FC", "\u0169", "\u016B", "\u016D",
+                        "\u016F", "\u0171", "\u0173")
+                // 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+0129: "ĩ" LATIN SMALL LETTER I WITH TILDE
+                // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
+                // U+012D: "ĭ" LATIN SMALL LETTER I WITH BREVE
+                // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
+                // U+0131: "ı" LATIN SMALL LETTER DOTLESS I
+                // U+0133: "ij" LATIN SMALL LIGATURE IJ
+                .setMoreKeysOf("i",
+                        "\u00EC", "\u00ED", "\u00EE", "\u00EF", "\u0129", "\u012B", "\u012D",
+                        "\u012F", "\u0131", "\u0133")
+                // 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+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
+                // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
+                // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
+                // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
+                // U+014F: "ŏ" LATIN SMALL LETTER O WITH BREVE
+                // U+0151: "ő" LATIN SMALL LETTER O WITH DOUBLE ACUTE
+                // U+0153: "œ" LATIN SMALL LIGATURE OE
+                // U+00BA: "º" MASCULINE ORDINAL INDICATOR
+                .setMoreKeysOf("o",
+                        "\u00F2", "\u00F3", "\u00F4", "\u00F5", "\u00F6", "\u00F8", "\u014D",
+                        "\u014F", "\u0151", "\u0153", "\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+00E3: "ã" LATIN SMALL LETTER A WITH TILDE
+                // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
+                // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
+                // U+00E6: "æ" LATIN SMALL LETTER AE
+                // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON
+                // U+0103: "ă" LATIN SMALL LETTER A WITH BREVE
+                // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK
+                // U+00AA: "ª" FEMININE ORDINAL INDICATOR
+                .setMoreKeysOf("a",
+                        "\u00E0", "\u00E1", "\u00E2", "\u00E3", "\u00E4", "\u00E5", "\u00E6",
+                        "\u0101", "\u0103", "\u0105", "\u00AA")
+                // U+00DF: "ß" LATIN SMALL LETTER SHARP S
+                // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
+                // U+015D: "ŝ" LATIN SMALL LETTER S WITH CIRCUMFLEX
+                // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA
+                // U+0161: "š" LATIN SMALL LETTER S WITH CARON
+                // U+017F: "ſ" LATIN SMALL LETTER LONG S
+                .setMoreKeysOf("s", "\u00DF", "\u015B", "\u015D", "\u015F", "\u0161", "\u017F")
+                // U+010F: "ď" LATIN SMALL LETTER D WITH CARON
+                // U+0111: "đ" LATIN SMALL LETTER D WITH STROKE
+                // U+00F0: "ð" LATIN SMALL LETTER ETH
+                .setMoreKeysOf("d", "\u010F", "\u0111", "\u00F0")
+                // U+011D: "ĝ" LATIN SMALL LETTER G WITH CIRCUMFLEX
+                // U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE
+                // U+0121: "ġ" LATIN SMALL LETTER G WITH DOT ABOVE
+                // U+0123: "ģ" LATIN SMALL LETTER G WITH CEDILLA
+                .setMoreKeysOf("g", "\u011D", "\u011F", "\u0121", "\u0123")
+                // U+0125: "ĥ" LATIN SMALL LETTER H WITH CIRCUMFLEX
+                .setMoreKeysOf("h", "\u0125")
+                // U+0135: "ĵ" LATIN SMALL LETTER J WITH CIRCUMFLEX
+                .setMoreKeysOf("j", "\u0135")
+                // U+0137: "ķ" LATIN SMALL LETTER K WITH CEDILLA
+                // U+0138: "ĸ" LATIN SMALL LETTER KRA
+                .setMoreKeysOf("k", "\u0137", "\u0138")
+                // U+013A: "ĺ" LATIN SMALL LETTER L WITH ACUTE
+                // U+013C: "ļ" LATIN SMALL LETTER L WITH CEDILLA
+                // U+013E: "ľ" LATIN SMALL LETTER L WITH CARON
+                // U+0140: "ŀ" LATIN SMALL LETTER L WITH MIDDLE DOT
+                // U+0142: "ł" LATIN SMALL LETTER L WITH STROKE
+                .setMoreKeysOf("l", "\u013A", "\u013C", "\u013E", "\u0140", "\u0142")
+                // U+017A: "ź" LATIN SMALL LETTER Z WITH ACUTE
+                // U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE
+                // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON
+                .setMoreKeysOf("z", "\u017A", "\u017C", "\u017E")
+                // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
+                // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
+                // U+0109: "ĉ" LATIN SMALL LETTER C WITH CIRCUMFLEX
+                // U+010B: "ċ" LATIN SMALL LETTER C WITH DOT ABOVE
+                // U+010D: "č" LATIN SMALL LETTER C WITH CARON
+                .setMoreKeysOf("c", "\u00E7", "\u0107", "\u0109", "\u010B", "\u010D")
+                // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
+                // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
+                // U+0146: "ņ" LATIN SMALL LETTER N WITH CEDILLA
+                // U+0148: "ň" LATIN SMALL LETTER N WITH CARON
+                // U+0149: "ʼn" LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
+                // U+014B: "ŋ" LATIN SMALL LETTER ENG
+                .setMoreKeysOf("n", "\u00F1", "\u0144", "\u0146", "\u0148", "\u0149", "\u014B");
+    }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/PortugueseCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/PortugueseCustomizer.java
new file mode 100644
index 0000000..629e8cb
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/PortugueseCustomizer.java
@@ -0,0 +1,80 @@
+/*
+ * 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 PortugueseCustomizer extends LayoutCustomizer {
+    PortugueseCustomizer(final Locale locale) { super(locale); }
+
+    @Override
+    public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
+        return builder
+                // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
+                // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
+                // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
+                // 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
+                // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
+                .setMoreKeysOf("e",
+                        "\u00E9", "\u00EA", "\u00E8", "\u0119", "\u0117", "\u0113", "\u00EB")
+                // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
+                // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
+                // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
+                // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
+                // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
+                .setMoreKeysOf("u", "\u00FA", "\u00FC", "\u00F9", "\u00FB", "\u016B")
+                // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
+                // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
+                // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
+                // 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", "\u00ED", "\u00EE", "\u00EC", "\u00EF", "\u012F", "\u012B")
+                // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
+                // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
+                // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
+                // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
+                // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
+                // 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",
+                        "\u00F3", "\u00F5", "\u00F4", "\u00F2", "\u00F6", "\u0153", "\u00F8",
+                        "\u014D", "\u00BA")
+                // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
+                // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE
+                // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
+                // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
+                // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
+                // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
+                // U+00E6: "æ" LATIN SMALL LETTER AE
+                // U+00AA: "ª" FEMININE ORDINAL INDICATOR
+                .setMoreKeysOf("a",
+                        "\u00E1", "\u00E3", "\u00E0", "\u00E2", "\u00E4", "\u00E5", "\u00E6",
+                        "\u00AA")
+                // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
+                // U+010D: "č" LATIN SMALL LETTER C WITH CARON
+                // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
+                .setMoreKeysOf("c", "\u00E7", "\u010D", "\u0107");
+    }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/SpanishCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/SpanishCustomizer.java
new file mode 100644
index 0000000..8974ad6
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/SpanishCustomizer.java
@@ -0,0 +1,104 @@
+/*
+ * 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;
+import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer;
+import com.android.inputmethod.keyboard.layout.Spanish;
+import com.android.inputmethod.keyboard.layout.expected.AbstractLayoutBase;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+
+import java.util.Locale;
+
+class SpanishCustomizer extends LayoutCustomizer {
+    SpanishCustomizer(final Locale locale) { super(locale); }
+
+    @Override
+    public ExpectedKey[] getPunctuationMoreKeys(final boolean isPhone) {
+        return isPhone ? PHONE_PUNCTUATION_MORE_KEYS
+                : LayoutBase.TABLET_PUNCTUATION_MORE_KEYS;
+    }
+
+    // Punctuation more keys for phone form factor.
+    private static final ExpectedKey[] PHONE_PUNCTUATION_MORE_KEYS = AbstractLayoutBase.joinKeys(
+            // U+00A1: "¡" INVERTED EXCLAMATION MARK
+            // U+00BF: "¿" INVERTED QUESTION MARK
+            ",", "?", "!", "#", ")", "(", "/", ";", "\u00A1",
+            "'", "@", ":", "-", "\"", "+", "%", "&", "\u00BF");
+
+    @Override
+    public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
+        return builder
+                // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
+                // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
+                // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
+                // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
+                // 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",
+                        "\u00E9", "\u00E8", "\u00EB", "\u00EA", "\u0119", "\u0117", "\u0113")
+                // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
+                // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
+                // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
+                // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
+                // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
+                .setMoreKeysOf("u", "\u00FA", "\u00FC", "\u00F9", "\u00FB", "\u016B")
+                // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
+                // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
+                // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
+                // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
+                // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
+                // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
+                .setMoreKeysOf("i", "\u00ED", "\u00EF", "\u00EC", "\u00EE", "\u012F", "\u012B")
+                // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
+                // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
+                // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
+                // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
+                // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
+                // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
+                // U+0153: "œ" LATIN SMALL LIGATURE OE
+                // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
+                // U+00BA: "º" MASCULINE ORDINAL INDICATOR
+                .setMoreKeysOf("o",
+                        "\u00F3", "\u00F2", "\u00F6", "\u00F4", "\u00F5", "\u00F8", "\u0153",
+                        "\u014D", "\u00BA")
+                // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
+                // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
+                // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
+                // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
+                // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE
+                // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
+                // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK
+                // U+00E6: "æ" LATIN SMALL LETTER AE
+                // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON
+                // U+00AA: "ª" FEMININE ORDINAL INDICATOR
+                .setMoreKeysOf("a",
+                        "\u00E1", "\u00E0", "\u00E4", "\u00E2", "\u00E3", "\u00E5", "\u0105",
+                        "\u00E6", "\u0101", "\u00AA")
+                // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
+                .replaceKeyOfLabel(Spanish.ROW2_10, "\u00F1")
+                // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
+                // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
+                // U+010D: "č" LATIN SMALL LETTER C WITH CARON
+                .setMoreKeysOf("c", "\u00E7", "\u0107", "\u010D")
+                // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
+                // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
+                .setMoreKeysOf("n", "\u00F1", "\u0144");
+    }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsAfrikaans.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsAfrikaans.java
index c98b4a5..cd22598 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsAfrikaans.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsAfrikaans.java
@@ -50,17 +50,16 @@
                     // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
                     // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
                     .setMoreKeysOf("e",
-                            "3", "\u00E9", "\u00E8", "\u00EA", "\u00EB", "\u0119", "\u0117",
-                            "\u0113")
+                            "\u00E9", "\u00E8", "\u00EA", "\u00EB", "\u0119", "\u0117", "\u0113")
                     // 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+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
                     // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
-                    .setMoreKeysOf("u", "7", "\u00FA", "\u00FB", "\u00FC", "\u00F9", "\u016B")
+                    .setMoreKeysOf("u", "\u00FA", "\u00FB", "\u00FC", "\u00F9", "\u016B")
                     // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
                     // U+0133: "ij" LATIN SMALL LIGATURE IJ
-                    .setMoreKeysOf("y", "6", "\u00FD", "\u0133")
+                    .setMoreKeysOf("y", "\u00FD", "\u0133")
                     // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
                     // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
                     // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
@@ -69,8 +68,7 @@
                     // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
                     // U+0133: "ij" LATIN SMALL LIGATURE IJ
                     .setMoreKeysOf("i",
-                            "8", "\u00ED", "\u00EC", "\u00EF", "\u00EE", "\u012F", "\u012B",
-                            "\u0133")
+                            "\u00ED", "\u00EC", "\u00EF", "\u00EE", "\u012F", "\u012B", "\u0133")
                     // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
                     // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
                     // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
@@ -80,8 +78,8 @@
                     // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
                     // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
                     .setMoreKeysOf("o",
-                            "9", "\u00F3", "\u00F4", "\u00F6", "\u00F2", "\u00F5", "\u0153",
-                            "\u00F8", "\u014D")
+                            "\u00F3", "\u00F4", "\u00F6", "\u00F2", "\u00F5", "\u0153", "\u00F8",
+                            "\u014D")
                     // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
                     // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
                     // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsArmenianAMPhonetic.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsArmenianAMPhonetic.java
new file mode 100644
index 0000000..327e943
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsArmenianAMPhonetic.java
@@ -0,0 +1,38 @@
+/*
+ * 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.ArmenianPhonetic;
+import com.android.inputmethod.keyboard.layout.ArmenianPhonetic.ArmenianPhoneticCustomizer;
+import com.android.inputmethod.keyboard.layout.LayoutBase;
+
+import java.util.Locale;
+
+/**
+ * hy_AM: Armenian (Armenia) Phonetic/armenian_phonetic
+ */
+@SmallTest
+public final class TestsArmenianAMPhonetic extends LayoutTestsBase {
+    private static final Locale LOCALE = new Locale("hy", "AM");
+    private static final LayoutBase LAYOUT = new ArmenianPhonetic(
+            new ArmenianPhoneticCustomizer(LOCALE));
+
+    @Override
+    LayoutBase getLayout() { return LAYOUT; }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsAzerbaijaniAZ.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsAzerbaijaniAZ.java
index 84d5a36..f5317e2 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsAzerbaijaniAZ.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsAzerbaijaniAZ.java
@@ -43,13 +43,13 @@
         public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
             return builder
                     // U+0259: "ə" LATIN SMALL LETTER SCHWA
-                    .setMoreKeysOf("e", "3", "\u0259")
+                    .setMoreKeysOf("e", "\u0259")
                     // 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
-                    .setMoreKeysOf("u", "7", "\u00FC", "\u00FB", "\u00F9", "\u00FA", "\u016B")
+                    .setMoreKeysOf("u", "\u00FC", "\u00FB", "\u00F9", "\u00FA", "\u016B")
                     // U+0131: "ı" LATIN SMALL LETTER DOTLESS I
                     // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
                     // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
@@ -58,8 +58,7 @@
                     // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
                     // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
                     .setMoreKeysOf("i",
-                            "8", "\u0131", "\u00EE", "\u00EF", "\u00EC", "\u00ED", "\u012F",
-                            "\u012B")
+                            "\u0131", "\u00EE", "\u00EF", "\u00EC", "\u00ED", "\u012F", "\u012B")
                     // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
                     // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
                     // U+0153: "œ" LATIN SMALL LIGATURE OE
@@ -69,8 +68,8 @@
                     // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
                     // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
                     .setMoreKeysOf("o",
-                            "9", "\u00F6", "\u00F4", "\u0153", "\u00F2", "\u00F3", "\u00F5",
-                            "\u00F8", "\u014D")
+                            "\u00F6", "\u00F4", "\u0153", "\u00F2", "\u00F3", "\u00F5", "\u00F8",
+                            "\u014D")
                     // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
                     .setMoreKeysOf("a", "\u00E2")
                     // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBasqueES.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBasqueES.java
new file mode 100644
index 0000000..bef18c5
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBasqueES.java
@@ -0,0 +1,52 @@
+/*
+ * 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.LayoutBase.EuroCustomizer;
+import com.android.inputmethod.keyboard.layout.Spanish;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+
+import java.util.Locale;
+
+/**
+ * eu_ES: Basque (Spain)/spanish
+ */
+@SmallTest
+public class TestsBasqueES extends LayoutTestsBase {
+    private static final Locale LOCALE = new Locale("eu", "ES");
+    private static final LayoutBase LAYOUT = new Spanish(new BasqueESCustomizer(LOCALE));
+
+    @Override
+    LayoutBase getLayout() { return LAYOUT; }
+
+    private static class BasqueESCustomizer extends EuroCustomizer {
+        private final SpanishCustomizer mSpanishCustomizer;
+
+        public BasqueESCustomizer(final Locale locale) {
+            super(locale);
+            mSpanishCustomizer = new SpanishCustomizer(locale);
+        }
+
+        @Override
+        public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
+            return mSpanishCustomizer.setAccentedLetters(builder);
+        }
+    }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBelarusianBY.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBelarusianBY.java
index 476841c..c5238d5 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBelarusianBY.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBelarusianBY.java
@@ -56,15 +56,15 @@
             return builder
                     // U+0435: "е" CYRILLIC SMALL LETTER IE
                     // U+0451: "ё" CYRILLIC SMALL LETTER IO
-                    .setMoreKeysOf("\u0435", "5", "\u0451")
+                    .setMoreKeysOf("\u0435", "\u0451")
                     // U+045E: "ў" CYRILLIC SMALL LETTER SHORT U
-                    .replaceKeyOfLabel(EastSlavic.ROW1_9, key("\u045E", moreKey("9")))
+                    .replaceKeyOfLabel(EastSlavic.ROW1_9, key("\u045E", additionalMoreKey("9")))
                     // U+044B: "ы" CYRILLIC SMALL LETTER YERU
-                    .replaceKeyOfLabel(EastSlavic.ROW2_2, key("\u044B"))
+                    .replaceKeyOfLabel(EastSlavic.ROW2_2, "\u044B")
                     // U+044D: "э" CYRILLIC SMALL LETTER E
-                    .replaceKeyOfLabel(EastSlavic.ROW2_11, key("\u044D"))
+                    .replaceKeyOfLabel(EastSlavic.ROW2_11, "\u044D")
                     // U+0456: "і" CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
-                    .replaceKeyOfLabel(EastSlavic.ROW3_5, key("\u0456"))
+                    .replaceKeyOfLabel(EastSlavic.ROW3_5, "\u0456")
                     // U+044C: "ь" CYRILLIC SMALL LETTER SOFT SIGN
                     // U+044A: "ъ" CYRILLIC SMALL LETTER HARD SIGN
                     .setMoreKeysOf("\u044C", "\u044A");
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCatalan.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCatalan.java
index ec03f0d..151a0a6 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCatalan.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCatalan.java
@@ -19,7 +19,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.EuroLayoutCustomizer;
+import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer;
 import com.android.inputmethod.keyboard.layout.Spanish;
 import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
 import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
@@ -37,7 +37,7 @@
     @Override
     LayoutBase getLayout() { return LAYOUT; }
 
-    private static class CatalanCustomizer extends EuroLayoutCustomizer {
+    private static class CatalanCustomizer extends EuroCustomizer {
         public CatalanCustomizer(final Locale locale) { super(locale); }
 
         @Override
@@ -48,12 +48,12 @@
 
         // U+00B7: "·" MIDDLE DOT
         private static final ExpectedKey[] PHONE_PUNCTUATION_MORE_KEYS = joinKeys(
-                ";", "/", "(", ")", "#", "\u00B7", "!", ",", "?",
-                "&", "%", "+", "\"", "-", ":", "'", "@");
+                ",", "?", "!", "\u00B7", "#", ")", "(", "/", ";",
+                "'", "@", ":", "-", "\"", "+", "%", "&");
 
         private static final ExpectedKey[] TABLET_PUNCTUATION_MORE_KEYS = joinKeys(
-                ";", "/", "(", ")", "#", "\u00B7", "'", ",",
-                "&", "%", "+", "\"", "-", ":", "@");
+                ",", "'", "\u00B7", "#", ")", "(", "/", ";",
+                "@", ":", "-", "\"", "+", "%", "&");
 
         @Override
         public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
@@ -66,22 +66,20 @@
                     // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
                     // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
                     .setMoreKeysOf("e",
-                            "3", "\u00E8", "\u00E9", "\u00EB", "\u00EA", "\u0119", "\u0117",
-                            "\u0113")
+                            "\u00E8", "\u00E9", "\u00EB", "\u00EA", "\u0119", "\u0117", "\u0113")
                     // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
                     // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
                     // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
                     // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
                     // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
-                    .setMoreKeysOf("u", "7", "\u00FA", "\u00FC", "\u00F9", "\u00FB", "\u016B")
+                    .setMoreKeysOf("u", "\u00FA", "\u00FC", "\u00F9", "\u00FB", "\u016B")
                     // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
                     // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
                     // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
                     // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
                     // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
                     // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
-                    .setMoreKeysOf("i",
-                            "8", "\u00ED", "\u00EF", "\u00EC", "\u00EE", "\u012F", "\u012B")
+                    .setMoreKeysOf("i", "\u00ED", "\u00EF", "\u00EC", "\u00EE", "\u012F", "\u012B")
                     // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
                     // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
                     // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
@@ -92,8 +90,8 @@
                     // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
                     // U+00BA: "º" MASCULINE ORDINAL INDICATOR
                     .setMoreKeysOf("o",
-                            "9", "\u00F2", "\u00F3", "\u00F6", "\u00F4", "\u00F5", "\u00F8",
-                            "\u0153", "\u014D", "\u00BA")
+                            "\u00F2", "\u00F3", "\u00F6", "\u00F4", "\u00F5", "\u00F8", "\u0153",
+                            "\u014D", "\u00BA")
                     // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
                     // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
                     // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
@@ -111,7 +109,7 @@
                     // U+0142: "ł" LATIN SMALL LETTER L WITH STROKE
                     .setMoreKeysOf("l", "l\u00B7l", "\u0142")
                     // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
-                    .replaceKeyOfLabel(Spanish.ROW2_10, key("\u00E7"))
+                    .replaceKeyOfLabel(Spanish.ROW2_10, "\u00E7")
                     // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
                     // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
                     // U+010D: "č" LATIN SMALL LETTER C WITH CARON
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCroatian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCroatian.java
index cf76de5..8575ef2 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCroatian.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCroatian.java
@@ -59,7 +59,7 @@
                     // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON
                     // U+017A: "ź" LATIN SMALL LETTER Z WITH ACUTE
                     // U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE
-                    .setMoreKeysOf("z", "6", "\u017E", "\u017A", "\u017C")
+                    .setMoreKeysOf("z", "\u017E", "\u017A", "\u017C")
                     // U+0161: "š" LATIN SMALL LETTER S WITH CARON
                     // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
                     // U+00DF: "ß" LATIN SMALL LETTER SHARP S
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCzech.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCzech.java
index 5cf4740..f479470 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCzech.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCzech.java
@@ -65,32 +65,30 @@
                     // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
                     // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
                     .setMoreKeysOf("e",
-                            "3", "\u00E9", "\u011B", "\u00E8", "\u00EA", "\u00EB", "\u0119",
-                            "\u0117", "\u0113")
+                            "\u00E9", "\u011B", "\u00E8", "\u00EA", "\u00EB", "\u0119", "\u0117",
+                            "\u0113")
                     // U+0159: "ř" LATIN SMALL LETTER R WITH CARON
-                    .setMoreKeysOf("r", "4", "\u0159")
+                    .setMoreKeysOf("r", "\u0159")
                     // U+0165: "ť" LATIN SMALL LETTER T WITH CARON
-                    .setMoreKeysOf("t", "5", "\u0165")
+                    .setMoreKeysOf("t", "\u0165")
                     // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON
                     // U+017A: "ź" LATIN SMALL LETTER Z WITH ACUTE
                     // U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE
-                    .setMoreKeysOf("z", "6", "\u017E", "\u017A", "\u017C")
+                    .setMoreKeysOf("z", "\u017E", "\u017A", "\u017C")
                     // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
                     // U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE
                     // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
                     // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
                     // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
                     // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
-                    .setMoreKeysOf("u",
-                            "7", "\u00FA", "\u016F", "\u00FB", "\u00FC", "\u00F9", "\u016B")
+                    .setMoreKeysOf("u", "\u00FA", "\u016F", "\u00FB", "\u00FC", "\u00F9", "\u016B")
                     // 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+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
                     // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
                     // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
-                    .setMoreKeysOf("i",
-                            "8", "\u00ED", "\u00EE", "\u00EF", "\u00EC", "\u012F", "\u012B")
+                    .setMoreKeysOf("i", "\u00ED", "\u00EE", "\u00EF", "\u00EC", "\u012F", "\u012B")
                     // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
                     // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
                     // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
@@ -100,8 +98,8 @@
                     // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
                     // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
                     .setMoreKeysOf("o",
-                            "9", "\u00F3", "\u00F6", "\u00F4", "\u00F2", "\u00F5", "\u0153",
-                            "\u00F8", "\u014D")
+                            "\u00F3", "\u00F6", "\u00F4", "\u00F2", "\u00F5", "\u0153", "\u00F8",
+                            "\u014D")
                     // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
                     // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
                     // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDanish.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDanish.java
index 050a0c4..85c63a1 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDanish.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDanish.java
@@ -19,7 +19,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.EuroLayoutCustomizer;
+import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer;
 import com.android.inputmethod.keyboard.layout.Nordic;
 import com.android.inputmethod.keyboard.layout.Symbols;
 import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
@@ -38,7 +38,7 @@
     @Override
     LayoutBase getLayout() { return LAYOUT; }
 
-    private static class DanishCustomizer extends EuroLayoutCustomizer {
+    private static class DanishCustomizer extends EuroCustomizer {
         public DanishCustomizer(final Locale locale) { super(locale); }
 
         @Override
@@ -58,29 +58,28 @@
             return builder
                     // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
                     // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
-                    .setMoreKeysOf("e", "3", "\u00E9", "\u00EB")
+                    .setMoreKeysOf("e", "\u00E9", "\u00EB")
                     // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
                     // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
-                    .setMoreKeysOf("y", "6", "\u00FD", "\u00FF")
+                    .setMoreKeysOf("y", "\u00FD", "\u00FF")
                     // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
                     // 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+016B: "ū" LATIN SMALL LETTER U WITH MACRON
-                    .setMoreKeysOf("u", "7", "\u00FA", "\u00FC", "\u00FB", "\u00F9", "\u016B")
+                    .setMoreKeysOf("u", "\u00FA", "\u00FC", "\u00FB", "\u00F9", "\u016B")
                     // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
                     // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
-                    .setMoreKeysOf("i", "8", "\u00ED", "\u00EF")
+                    .setMoreKeysOf("i", "\u00ED", "\u00EF")
                     // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
                     // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
                     // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
                     // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
                     // U+0153: "œ" LATIN SMALL LIGATURE OE
                     // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
-                    .setMoreKeysOf("o",
-                            "9", "\u00F3", "\u00F4", "\u00F2", "\u00F5", "\u0153", "\u014D")
+                    .setMoreKeysOf("o", "\u00F3", "\u00F4", "\u00F2", "\u00F5", "\u0153", "\u014D")
                     // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
-                    .replaceKeyOfLabel(Nordic.ROW1_11, key("\u00E5"))
+                    .replaceKeyOfLabel(Nordic.ROW1_11, "\u00E5")
                     // U+00E6: "æ" LATIN SMALL LETTER AE
                     // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
                     .replaceKeyOfLabel(Nordic.ROW2_10, key("\u00E6", moreKey("\u00E4")))
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDutch.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDutch.java
index e6e3378..1730f66 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDutch.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDutch.java
@@ -19,7 +19,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.EuroLayoutCustomizer;
+import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer;
 import com.android.inputmethod.keyboard.layout.Qwerty;
 import com.android.inputmethod.keyboard.layout.Symbols;
 import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
@@ -38,7 +38,7 @@
     @Override
     LayoutBase getLayout() { return LAYOUT; }
 
-    private static class DutchCustomizer extends EuroLayoutCustomizer {
+    static class DutchCustomizer extends EuroCustomizer {
         public DutchCustomizer(final Locale locale) { super(locale); }
 
         @Override
@@ -50,45 +50,6 @@
         @Override
         public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
             return builder
-                    // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
-                    // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
-                    // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
-                    // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
-                    // 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",
-                            "3", "\u00E9", "\u00EB", "\u00EA", "\u00E8", "\u0119", "\u0117",
-                            "\u0113")
-                    // U+0133: "ij" LATIN SMALL LIGATURE IJ
-                    .setMoreKeysOf("y", "6", "\u0133")
-                    // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
-                    // 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+016B: "ū" LATIN SMALL LETTER U WITH MACRON
-                    .setMoreKeysOf("u", "7", "\u00FA", "\u00FC", "\u00FB", "\u00F9", "\u016B")
-                    // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
-                    // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
-                    // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
-                    // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
-                    // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
-                    // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
-                    // U+0133: "ij" LATIN SMALL LIGATURE IJ
-                    .setMoreKeysOf("i",
-                            "8", "\u00ED", "\u00EF", "\u00EC", "\u00EE", "\u012F", "\u012B",
-                            "\u0133")
-                    // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
-                    // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
-                    // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
-                    // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
-                    // 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
-                    .setMoreKeysOf("o",
-                            "9", "\u00F3", "\u00F6", "\u00F4", "\u00F2", "\u00F5", "\u0153",
-                            "\u00F8", "\u014D")
                     // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
                     // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
                     // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
@@ -100,6 +61,43 @@
                     .setMoreKeysOf("a",
                             "\u00E1", "\u00E4", "\u00E2", "\u00E0", "\u00E6", "\u00E3", "\u00E5",
                             "\u0101")
+                    // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
+                    // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
+                    // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
+                    // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
+                    // 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",
+                            "\u00E9", "\u00EB", "\u00EA", "\u00E8", "\u0119", "\u0117", "\u0113")
+                    // U+0133: "ij" LATIN SMALL LIGATURE IJ
+                    .setMoreKeysOf("y", "\u0133")
+                    // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
+                    // 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+016B: "ū" LATIN SMALL LETTER U WITH MACRON
+                    .setMoreKeysOf("u", "\u00FA", "\u00FC", "\u00FB", "\u00F9", "\u016B")
+                    // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
+                    // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
+                    // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
+                    // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
+                    // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
+                    // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
+                    // U+0133: "ij" LATIN SMALL LIGATURE IJ
+                    .setMoreKeysOf("i",
+                            "\u00ED", "\u00EF", "\u00EC", "\u00EE", "\u012F", "\u012B", "\u0133")
+                    // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
+                    // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
+                    // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
+                    // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
+                    // 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
+                    .setMoreKeysOf("o",
+                            "\u00F3", "\u00F6", "\u00F4", "\u00F2", "\u00F5", "\u0153", "\u00F8",
+                            "\u014D")
                     // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
                     // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
                     .setMoreKeysOf("n", "\u00F1", "\u0144");
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDutchBE.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDutchBE.java
index aa706f6..31adf7a 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDutchBE.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDutchBE.java
@@ -20,10 +20,7 @@
 
 import com.android.inputmethod.keyboard.layout.Azerty;
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.EuroLayoutCustomizer;
-import com.android.inputmethod.keyboard.layout.Symbols;
-import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
-import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+import com.android.inputmethod.keyboard.layout.tests.TestsDutch.DutchCustomizer;
 
 import java.util.Locale;
 
@@ -33,76 +30,8 @@
 @SmallTest
 public final class TestsDutchBE extends LayoutTestsBase {
     private static final Locale LOCALE = new Locale("nl", "BE");
-    private static final LayoutBase LAYOUT = new Azerty(new DutchBECustomizer(LOCALE));
+    private static final LayoutBase LAYOUT = new Azerty(new DutchCustomizer(LOCALE));
 
     @Override
     LayoutBase getLayout() { return LAYOUT; }
-
-    private static class DutchBECustomizer extends EuroLayoutCustomizer {
-        public DutchBECustomizer(final Locale locale) { super(locale); }
-
-        @Override
-        public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_L9R; }
-
-        @Override
-        public ExpectedKey[] getSingleQuoteMoreKeys() { return Symbols.SINGLE_QUOTES_L9R; }
-
-        @Override
-        public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
-            return builder
-                    // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
-                    // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
-                    // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
-                    // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
-                    // 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
-                    .setMoreKeysOf("a",
-                            "1", "\u00E1", "\u00E4", "\u00E2", "\u00E0", "\u00E6", "\u00E3",
-                            "\u00E5", "\u0101")
-                    // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
-                    // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
-                    // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
-                    // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
-                    // 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",
-                            "3", "\u00E9", "\u00EB", "\u00EA", "\u00E8", "\u0119", "\u0117",
-                            "\u0113")
-                    // U+0133: "ij" LATIN SMALL LIGATURE IJ
-                    .setMoreKeysOf("y", "6", "\u0133")
-                    // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
-                    // 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+016B: "ū" LATIN SMALL LETTER U WITH MACRON
-                    .setMoreKeysOf("u", "7", "\u00FA", "\u00FC", "\u00FB", "\u00F9", "\u016B")
-                    // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
-                    // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
-                    // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
-                    // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
-                    // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
-                    // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
-                    // U+0133: "ij" LATIN SMALL LIGATURE IJ
-                    .setMoreKeysOf("i",
-                            "8", "\u00ED", "\u00EF", "\u00EC", "\u00EE", "\u012F", "\u012B",
-                            "\u0133")
-                    // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
-                    // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
-                    // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
-                    // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
-                    // 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
-                    .setMoreKeysOf("o",
-                            "9", "\u00F3", "\u00F6", "\u00F4", "\u00F2", "\u00F5", "\u0153",
-                            "\u00F8", "\u014D")
-                    // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
-                    // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
-                    .setMoreKeysOf("n", "\u00F1", "\u0144");
-        }
-    }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishDvorak.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishDvorak.java
new file mode 100644
index 0000000..a052693
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishDvorak.java
@@ -0,0 +1,52 @@
+/*
+ * 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.Dvorak;
+import com.android.inputmethod.keyboard.layout.Dvorak.DvorakCustomizer;
+import com.android.inputmethod.keyboard.layout.LayoutBase;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+
+import java.util.Locale;
+
+/**
+ * en_US: English (United States)/dvorak
+ */
+@SmallTest
+public class TestsEnglishDvorak extends LayoutTestsBase {
+    private static final Locale LOCALE = new Locale("en", "US");
+    private static final LayoutBase LAYOUT = new Dvorak(new EnglishDvorakCustomizer(LOCALE));
+
+    @Override
+    LayoutBase getLayout() { return LAYOUT; }
+
+    private static class EnglishDvorakCustomizer extends DvorakCustomizer {
+        private final EnglishCustomizer mEnglishCustomizer;
+
+        EnglishDvorakCustomizer(final Locale locale) {
+            super(locale);
+            mEnglishCustomizer = new EnglishCustomizer(locale);
+        }
+
+        @Override
+        public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
+            return mEnglishCustomizer.setAccentedLetters(builder);
+        }
+    }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishUK.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishUK.java
index 4789507..c0dcbdc 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishUK.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishUK.java
@@ -36,7 +36,7 @@
     @Override
     LayoutBase getLayout() { return LAYOUT; }
 
-    private static class EnglishUKCustomizer extends EnglishUSCustomizer {
+    private static class EnglishUKCustomizer extends EnglishCustomizer {
         public EnglishUKCustomizer(final Locale locale) { super(locale); }
 
         @Override
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishUS.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishUS.java
index 991187a..6ea8f60 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishUS.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishUS.java
@@ -19,9 +19,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer;
 import com.android.inputmethod.keyboard.layout.Qwerty;
-import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
 
 import java.util.Locale;
 
@@ -31,63 +29,8 @@
 @SmallTest
 public class TestsEnglishUS extends LayoutTestsBase {
     private static final Locale LOCALE = new Locale("en", "US");
-    private static final LayoutBase LAYOUT = new Qwerty(new EnglishUSCustomizer(LOCALE));
+    private static final LayoutBase LAYOUT = new Qwerty(new EnglishCustomizer(LOCALE));
 
     @Override
     LayoutBase getLayout() { return LAYOUT; }
-
-    // TODO: Make this as generic English customizer.
-    static class EnglishUSCustomizer extends LayoutCustomizer {
-        public EnglishUSCustomizer(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+0113: "ē" LATIN SMALL LETTER E WITH MACRON
-                    .setMoreKeysOf("e", "3", "\u00E8", "\u00E9", "\u00EA", "\u00EB", "\u0113")
-                    // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
-                    // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
-                    // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
-                    // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
-                    // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
-                    .setMoreKeysOf("u", "7", "\u00FB", "\u00FC", "\u00F9", "\u00FA", "\u016B")
-                    // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
-                    // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
-                    // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
-                    // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
-                    // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
-                    .setMoreKeysOf("i", "8", "\u00EE", "\u00EF", "\u00ED", "\u012B", "\u00EC")
-                    // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
-                    // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
-                    // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
-                    // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
-                    // U+0153: "œ" LATIN SMALL LIGATURE OE
-                    // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
-                    // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
-                    // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
-                    .setMoreKeysOf("o",
-                            "9", "\u00F4", "\u00F6", "\u00F2", "\u00F3", "\u0153", "\u00F8",
-                            "\u014D", "\u00F5")
-                    // 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
-                    .setMoreKeysOf("a",
-                            "\u00E0", "\u00E1", "\u00E2", "\u00E4", "\u00E6", "\u00E3", "\u00E5",
-                            "\u0101")
-                    // U+00DF: "ß" LATIN SMALL LETTER SHARP S
-                    .setMoreKeysOf("s", "\u00DF")
-                    // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
-                    .setMoreKeysOf("c", "\u00E7")
-                    // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
-                    .setMoreKeysOf("n", "\u00F1");
-        }
-    }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEsperanto.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEsperanto.java
index a54601b..6a44187 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEsperanto.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEsperanto.java
@@ -43,11 +43,12 @@
         public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
             return builder
                     // U+015D: "ŝ" LATIN SMALL LETTER S WITH CIRCUMFLEX
-                    .replaceKeyOfLabel("q", key("\u015D", moreKey("1"), moreKey("q")))
+                    .replaceKeyOfLabel("q", key("\u015D", joinMoreKeys(
+                            additionalMoreKey("1"), "q")))
                     // U+011D: "ĝ" LATIN SMALL LETTER G WITH CIRCUMFLEX
                     // U+0175: "ŵ" LATIN SMALL LETTER W WITH CIRCUMFLEX
-                    .replaceKeyOfLabel("w", key("\u011D",
-                            moreKey("2"), moreKey("w"), moreKey("\u0175")))
+                    .replaceKeyOfLabel("w", key("\u011D", joinMoreKeys(
+                            additionalMoreKey("2"), "w", "\u0175")))
                     // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
                     // U+011B: "ě" LATIN SMALL LETTER E WITH CARON
                     // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
@@ -57,25 +58,24 @@
                     // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
                     // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
                     .setMoreKeysOf("e",
-                            "3", "\u00E9", "\u011B", "\u00E8", "\u00EA", "\u00EB", "\u0119",
-                            "\u0117", "\u0113")
+                            "\u00E9", "\u011B", "\u00E8", "\u00EA", "\u00EB", "\u0119", "\u0117",
+                            "\u0113")
                     // U+0159: "ř" LATIN SMALL LETTER R WITH CARON
                     // U+0155: "ŕ" LATIN SMALL LETTER R WITH ACUTE
                     // U+0157: "ŗ" LATIN SMALL LETTER R WITH CEDILLA
-                    .setMoreKeysOf("r", "4", "\u0159", "\u0155", "\u0157")
+                    .setMoreKeysOf("r", "\u0159", "\u0155", "\u0157")
                     // U+0165: "ť" LATIN SMALL LETTER T WITH CARON
                     // U+021B: "ț" LATIN SMALL LETTER T WITH COMMA BELOW
                     // U+0163: "ţ" LATIN SMALL LETTER T WITH CEDILLA
                     // U+0167: "ŧ" LATIN SMALL LETTER T WITH STROKE
-                    .setMoreKeysOf("t", "5", "\u0165", "\u021B", "\u0163", "\u0167")
+                    .setMoreKeysOf("t", "\u0165", "\u021B", "\u0163", "\u0167")
                     // U+016D: "ŭ" LATIN SMALL LETTER U WITH BREVE
                     // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
                     // U+0177: "ŷ" LATIN SMALL LETTER Y WITH CIRCUMFLEX
                     // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
                     // U+00FE: "þ" LATIN SMALL LETTER THORN
-                    .replaceKeyOfLabel("y", key("\u016D",
-                            moreKey("6"), moreKey("y"), moreKey("\u00FD"), moreKey("\u0177"),
-                            moreKey("\u00FF"), moreKey("\u00FE")))
+                    .replaceKeyOfLabel("y", key("\u016D", joinMoreKeys(
+                            additionalMoreKey("6"), "y", "\u00FD", "\u0177", "\u00FF", "\u00FE")))
                     // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
                     // U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE
                     // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
@@ -87,8 +87,8 @@
                     // U+0173: "ų" LATIN SMALL LETTER U WITH OGONEK
                     // U+00B5: "µ" MICRO SIGN
                     .setMoreKeysOf("u",
-                            "7", "\u00FA", "\u016F", "\u00FB", "\u00FC", "\u00F9", "\u016B",
-                            "\u0169", "\u0171", "\u0173", "\u00B5")
+                            "\u00FA", "\u016F", "\u00FB", "\u00FC", "\u00F9", "\u016B", "\u0169",
+                            "\u0171", "\u0173", "\u00B5")
                     // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
                     // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
                     // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
@@ -99,8 +99,8 @@
                     // U+0131: "ı" LATIN SMALL LETTER DOTLESS I
                     // U+0133: "ij" LATIN SMALL LIGATURE IJ
                     .setMoreKeysOf("i",
-                            "8", "\u00ED", "\u00EE", "\u00EF", "\u0129", "\u00EC", "\u012F",
-                            "\u012B", "\u0131", "\u0133")
+                            "\u00ED", "\u00EE", "\u00EF", "\u0129", "\u00EC", "\u012F", "\u012B",
+                            "\u0131", "\u0133")
                     // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
                     // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
                     // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
@@ -112,8 +112,8 @@
                     // U+0151: "ő" LATIN SMALL LETTER O WITH DOUBLE ACUTE
                     // U+00BA: "º" MASCULINE ORDINAL INDICATOR
                     .setMoreKeysOf("o",
-                            "9", "\u00F3", "\u00F6", "\u00F4", "\u00F2", "\u00F5", "\u0153",
-                            "\u00F8", "\u014D", "\u0151", "\u00BA")
+                            "\u00F3", "\u00F6", "\u00F4", "\u00F2", "\u00F5", "\u0153", "\u00F8",
+                            "\u014D", "\u0151", "\u00BA")
                     // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
                     // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
                     // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
@@ -162,7 +162,7 @@
                     // U+0142: "ł" LATIN SMALL LETTER L WITH STROKE
                     .setMoreKeysOf("l", "\u013A", "\u013C", "\u013E", "\u0140", "\u0142")
                     // U+0135: "ĵ" LATIN SMALL LETTER J WITH CIRCUMFLEX
-                    .replaceKeyOfLabel(Spanish.ROW2_10, key("\u0135"))
+                    .replaceKeyOfLabel(Spanish.ROW2_10, "\u0135")
                     // U+017A: "ź" LATIN SMALL LETTER Z WITH ACUTE
                     // U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE
                     // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEstonianEE.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEstonianEE.java
index be3786a..865e9ea 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEstonianEE.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEstonianEE.java
@@ -19,7 +19,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.EuroLayoutCustomizer;
+import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer;
 import com.android.inputmethod.keyboard.layout.Nordic;
 import com.android.inputmethod.keyboard.layout.Symbols;
 import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
@@ -38,7 +38,7 @@
     @Override
     LayoutBase getLayout() { return LAYOUT; }
 
-    private static class EstonianEECustomizer extends EuroLayoutCustomizer {
+    private static class EstonianEECustomizer extends EuroCustomizer {
         public EstonianEECustomizer(final Locale locale) {
             super(locale);
         }
@@ -61,18 +61,18 @@
                     // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK
                     // U+011B: "ě" LATIN SMALL LETTER E WITH CARON
                     .setMoreKeysOf("e",
-                            "3", "\u0113", "\u00E8", "\u0117", "\u00E9", "\u00EA", "\u00EB",
-                            "\u0119", "\u011B")
+                            "\u0113", "\u00E8", "\u0117", "\u00E9", "\u00EA", "\u00EB", "\u0119",
+                            "\u011B")
                     // U+0157: "ŗ" LATIN SMALL LETTER R WITH CEDILLA
                     // U+0159: "ř" LATIN SMALL LETTER R WITH CARON
                     // U+0155: "ŕ" LATIN SMALL LETTER R WITH ACUTE
-                    .setMoreKeysOf("r", "4", "\u0157", "\u0159", "\u0155")
+                    .setMoreKeysOf("r", "\u0157", "\u0159", "\u0155")
                     // U+0163: "ţ" LATIN SMALL LETTER T WITH CEDILLA
                     // U+0165: "ť" LATIN SMALL LETTER T WITH CARON
-                    .setMoreKeysOf("t", "5", "\u0163", "\u0165")
+                    .setMoreKeysOf("t", "\u0163", "\u0165")
                     // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
                     // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
-                    .setMoreKeysOf("y", "6", "\u00FD", "\u00FF")
+                    .setMoreKeysOf("y", "\u00FD", "\u00FF")
                     // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
                     // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
                     // U+0173: "ų" LATIN SMALL LETTER U WITH OGONEK
@@ -82,8 +82,8 @@
                     // U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE
                     // U+0171: "ű" LATIN SMALL LETTER U WITH DOUBLE ACUTE
                     .setMoreKeysOf("u",
-                            "7", "\u00FC", "\u016B", "\u0173", "\u00F9", "\u00FA", "\u00FB",
-                            "\u016F", "\u0171")
+                            "\u00FC", "\u016B", "\u0173", "\u00F9", "\u00FA", "\u00FB", "\u016F",
+                            "\u0171")
                     // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
                     // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
                     // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
@@ -92,8 +92,7 @@
                     // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
                     // U+0131: "ı" LATIN SMALL LETTER DOTLESS I
                     .setMoreKeysOf("i",
-                            "8", "\u012B", "\u00EC", "\u012F", "\u00ED", "\u00EE", "\u00EF",
-                            "\u0131")
+                            "\u012B", "\u00EC", "\u012F", "\u00ED", "\u00EE", "\u00EF", "\u0131")
                     // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
                     // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
                     // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
@@ -103,15 +102,15 @@
                     // U+0151: "ő" LATIN SMALL LETTER O WITH DOUBLE ACUTE
                     // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
                     .setMoreKeysOf("o",
-                            "9", "\u00F6", "\u00F5", "\u00F2", "\u00F3", "\u00F4", "\u0153",
-                            "\u0151", "\u00F8")
+                            "\u00F6", "\u00F5", "\u00F2", "\u00F3", "\u00F4", "\u0153", "\u0151",
+                            "\u00F8")
                     // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
-                    .replaceKeyOfLabel(Nordic.ROW1_11, key("\u00FC"))
+                    .replaceKeyOfLabel(Nordic.ROW1_11, "\u00FC")
                     // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
                     // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
                     .replaceKeyOfLabel(Nordic.ROW2_10, key("\u00F6", moreKey("\u00F5")))
                     // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
-                    .replaceKeyOfLabel(Nordic.ROW2_11, key("\u00E4"))
+                    .replaceKeyOfLabel(Nordic.ROW2_11, "\u00E4")
                     // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
                     // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON
                     // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFinnish.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFinnish.java
index 20ecd51..ff32da1 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFinnish.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFinnish.java
@@ -19,7 +19,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.EuroLayoutCustomizer;
+import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer;
 import com.android.inputmethod.keyboard.layout.Nordic;
 import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
 
@@ -36,14 +36,14 @@
     @Override
     LayoutBase getLayout() { return LAYOUT; }
 
-    private static class FinnishCustomizer extends EuroLayoutCustomizer {
+    private static class FinnishCustomizer extends EuroCustomizer {
         public FinnishCustomizer(final Locale locale) { super(locale); }
 
         @Override
         public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
             return builder
                     // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
-                    .setMoreKeysOf("u", "7", "\u00FC")
+                    .setMoreKeysOf("u", "\u00FC")
                     // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
                     // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
                     // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
@@ -52,10 +52,9 @@
                     // U+0153: "œ" LATIN SMALL LIGATURE OE
                     // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
                     .setMoreKeysOf("o",
-                            "9", "\u00F8", "\u00F4", "\u00F2", "\u00F3", "\u00F5", "\u0153",
-                            "\u014D")
+                            "\u00F8", "\u00F4", "\u00F2", "\u00F3", "\u00F5", "\u0153", "\u014D")
                     // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
-                    .replaceKeyOfLabel(Nordic.ROW1_11, key("\u00E5"))
+                    .replaceKeyOfLabel(Nordic.ROW1_11, "\u00E5")
                     // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
                     // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
                     .replaceKeyOfLabel(Nordic.ROW2_10, key("\u00F6", moreKey("\u00F8")))
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrench.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrench.java
index 5f8ecd6..7ced1fb 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrench.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrench.java
@@ -20,8 +20,8 @@
 
 import com.android.inputmethod.keyboard.layout.Azerty;
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.EuroLayoutCustomizer;
-import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
 
 import java.util.Locale;
 
@@ -31,71 +31,25 @@
 @SmallTest
 public final class TestsFrench extends LayoutTestsBase {
     private static final Locale LOCALE = new Locale("fr");
-    private static final LayoutBase LAYOUT = new Azerty(new FrenchCustomizer(LOCALE));
+    private static final LayoutBase LAYOUT = new Azerty(new FrenchEuroCustomizer(LOCALE));
 
     @Override
     LayoutBase getLayout() { return LAYOUT; }
 
-    private static class FrenchCustomizer extends EuroLayoutCustomizer {
-        public FrenchCustomizer(final Locale locale) { super(locale); }
+    static final class FrenchEuroCustomizer extends FrenchCustomizer {
+        private final EuroCustomizer mEuroCustomizer;
+
+        public FrenchEuroCustomizer(final Locale locale) {
+            super(locale);
+            mEuroCustomizer = new EuroCustomizer(locale);
+        }
 
         @Override
-        public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
-            return builder
-                    // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
-                    // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
-                    // U+00E6: "æ" LATIN SMALL LETTER AE
-                    // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
-                    // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
-                    // 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", "\u00E2", "1", "\u00E6", "\u00E1", "\u00E4", "\u00E3",
-                            "\u00E5", "\u0101", "\u00AA")
-                    // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
-                    // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
-                    // 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",
-                            "\u00E9", "\u00E8", "\u00EA", "\u00EB", "3", "\u0119", "\u0117",
-                            "\u0113")
-                    // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
-                    .setMoreKeysOf("y", "6", "\u00FF")
-                    // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
-                    // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
-                    // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
-                    // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
-                    // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
-                    .setMoreKeysOf("u", "\u00F9", "\u00FB", "7", "\u00FC", "\u00FA", "\u016B")
-                    // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
-                    // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
-                    // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
-                    // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
-                    // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
-                    // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
-                    .setMoreKeysOf("i", "\u00EE", "8", "\u00EF", "\u00EC", "\u00ED", "\u012F",
-                            "\u012B")
-                    // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
-                    // U+0153: "œ" LATIN SMALL LIGATURE OE
-                    // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
-                    // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
-                    // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
-                    // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
-                    // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
-                    // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
-                    // U+00BA: "º" MASCULINE ORDINAL INDICATOR
-                    .setMoreKeysOf("o",
-                            "\u00F4", "\u0153", "9", "\u00F6", "\u00F2", "\u00F3", "\u00F5",
-                            "\u00F8", "\u014D", "\u00BA")
-                    // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
-                    // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
-                    // U+010D: "č" LATIN SMALL LETTER C WITH CARON
-                    .setMoreKeysOf("c", "\u00E7", "\u0107", "\u010D");
+        public final ExpectedKey getCurrencyKey() { return mEuroCustomizer.getCurrencyKey(); }
+
+        @Override
+        public final ExpectedKey[] getOtherCurrencyKeys() {
+            return mEuroCustomizer.getOtherCurrencyKeys();
         }
     }
 }
\ No newline at end of file
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchCA.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchCA.java
index d6babc8..9b3cd1e 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchCA.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchCA.java
@@ -19,9 +19,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer;
 import com.android.inputmethod.keyboard.layout.Qwerty;
-import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
 
 import java.util.Locale;
 
@@ -31,71 +29,8 @@
 @SmallTest
 public final class TestsFrenchCA extends LayoutTestsBase {
     private static final Locale LOCALE = new Locale("fr", "CA");
-    private static final LayoutBase LAYOUT = new Qwerty(new FrenchCACustomizer(LOCALE));
+    private static final LayoutBase LAYOUT = new Qwerty(new FrenchCustomizer(LOCALE));
 
     @Override
     LayoutBase getLayout() { return LAYOUT; }
-
-    private static class FrenchCACustomizer extends LayoutCustomizer {
-        public FrenchCACustomizer(final Locale locale) { super(locale); }
-
-        @Override
-        public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
-            return builder
-                    // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
-                    // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
-                    // 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",
-                            "\u00E9", "\u00E8", "\u00EA", "\u00EB", "3", "\u0119", "\u0117",
-                            "\u0113")
-                    // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
-                    .setMoreKeysOf("y", "6", "\u00FF")
-                    // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
-                    // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
-                    // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
-                    // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
-                    // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
-                    .setMoreKeysOf("u", "\u00F9", "\u00FB", "7", "\u00FC", "\u00FA", "\u016B")
-                    // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
-                    // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
-                    // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
-                    // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
-                    // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
-                    // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
-                    .setMoreKeysOf("i", "\u00EE", "8", "\u00EF", "\u00EC", "\u00ED", "\u012F",
-                            "\u012B")
-                    // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
-                    // U+0153: "œ" LATIN SMALL LIGATURE OE
-                    // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
-                    // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
-                    // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
-                    // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
-                    // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
-                    // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
-                    // U+00BA: "º" MASCULINE ORDINAL INDICATOR
-                    .setMoreKeysOf("o",
-                            "\u00F4", "\u0153", "9", "\u00F6", "\u00F2", "\u00F3", "\u00F5",
-                            "\u00F8", "\u014D", "\u00BA")
-                    // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
-                    // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
-                    // U+00E6: "æ" LATIN SMALL LETTER AE
-                    // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
-                    // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
-                    // 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", "\u00E2", "\u00E6", "\u00E1", "\u00E4", "\u00E3", "\u00E5",
-                            "\u0101", "\u00AA")
-                    // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
-                    // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
-                    // U+010D: "č" LATIN SMALL LETTER C WITH CARON
-                    .setMoreKeysOf("c", "\u00E7", "\u0107", "\u010D");
-        }
-    }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchCH.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchCH.java
index 5a56ad1..2598aa3 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchCH.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchCH.java
@@ -19,7 +19,6 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer;
 import com.android.inputmethod.keyboard.layout.Swiss;
 import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
 
@@ -36,75 +35,22 @@
     @Override
     LayoutBase getLayout() { return LAYOUT; }
 
-    private static class FrenchCHCustomizer extends LayoutCustomizer {
+    private static class FrenchCHCustomizer extends FrenchCustomizer {
         public FrenchCHCustomizer(final Locale locale) { super(locale); }
 
         @Override
         public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
+            super.setAccentedLetters(builder);
             return builder
-                    // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
-                    // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
-                    // 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",
-                            "\u00E9", "\u00E8", "\u00EA", "\u00EB", "3", "\u0119", "\u0117",
-                            "\u0113")
-                    // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
-                    // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
-                    // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
-                    // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
-                    // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
-                    .setMoreKeysOf("u", "\u00F9", "\u00FB", "7", "\u00FC", "\u00FA", "\u016B")
-                    // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
-                    // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
-                    // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
-                    // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
-                    // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
-                    // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
-                    .setMoreKeysOf("i", "\u00EE", "8", "\u00EF", "\u00EC", "\u00ED", "\u012F",
-                            "\u012B")
-                    // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
-                    // U+0153: "œ" LATIN SMALL LIGATURE OE
-                    // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
-                    // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
-                    // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
-                    // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
-                    // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
-                    // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
-                    // U+00BA: "º" MASCULINE ORDINAL INDICATOR
-                    .setMoreKeysOf("o",
-                            "\u00F4", "\u0153", "9", "\u00F6", "\u00F2", "\u00F3", "\u00F5",
-                            "\u00F8", "\u014D", "\u00BA")
                     // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
                     // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
                     .replaceKeyOfLabel(Swiss.ROW1_11, key("\u00E8", moreKey("\u00FC")))
-                    // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
-                    // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
-                    // U+00E6: "æ" LATIN SMALL LETTER AE
-                    // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
-                    // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
-                    // 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", "\u00E2", "\u00E6", "\u00E1", "\u00E4", "\u00E3", "\u00E5",
-                            "\u0101", "\u00AA")
                     // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
                     // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
                     .replaceKeyOfLabel(Swiss.ROW2_10, key("\u00E9", moreKey("\u00F6")))
                     // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
                     // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
-                    .replaceKeyOfLabel(Swiss.ROW2_11, key("\u00E0", moreKey("\u00E4")))
-                    // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
-                    .setMoreKeysOf("y", "\u00FF")
-                    // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
-                    // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
-                    // U+010D: "č" LATIN SMALL LETTER C WITH CARON
-                    .setMoreKeysOf("c", "\u00E7", "\u0107", "\u010D");
+                    .replaceKeyOfLabel(Swiss.ROW2_11, key("\u00E0", moreKey("\u00E4")));
         }
     }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchDvorak.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchDvorak.java
new file mode 100644
index 0000000..33d1445
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchDvorak.java
@@ -0,0 +1,62 @@
+/*
+ * 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.Dvorak;
+import com.android.inputmethod.keyboard.layout.Dvorak.DvorakCustomizer;
+import com.android.inputmethod.keyboard.layout.LayoutBase;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+import com.android.inputmethod.keyboard.layout.tests.TestsFrench.FrenchEuroCustomizer;
+
+import java.util.Locale;
+
+/**
+ * fr: French/dvorak
+ */
+@SmallTest
+public final class TestsFrenchDvorak extends LayoutTestsBase {
+    private static final Locale LOCALE = new Locale("fr");
+    private static final LayoutBase LAYOUT = new Dvorak(new FrenchDvorakCustomizer(LOCALE));
+
+    @Override
+    LayoutBase getLayout() { return LAYOUT; }
+
+    private static class FrenchDvorakCustomizer extends DvorakCustomizer {
+        private final FrenchEuroCustomizer mFrenchEuroCustomizer;
+
+        public FrenchDvorakCustomizer(final Locale locale) {
+            super(locale);
+            mFrenchEuroCustomizer = new FrenchEuroCustomizer(locale);
+        }
+
+        @Override
+        public ExpectedKey getCurrencyKey() { return mFrenchEuroCustomizer.getCurrencyKey(); }
+
+        @Override
+        public ExpectedKey[] getOtherCurrencyKeys() {
+            return mFrenchEuroCustomizer.getOtherCurrencyKeys();
+        }
+
+        @Override
+        public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
+            return mFrenchEuroCustomizer.setAccentedLetters(builder);
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchQwertz.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchQwertz.java
index 0582b0c..6ab2870 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchQwertz.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchQwertz.java
@@ -19,9 +19,8 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.EuroLayoutCustomizer;
 import com.android.inputmethod.keyboard.layout.Qwertz;
-import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+import com.android.inputmethod.keyboard.layout.tests.TestsFrench.FrenchEuroCustomizer;
 
 import java.util.Locale;
 
@@ -31,71 +30,8 @@
 @SmallTest
 public final class TestsFrenchQwertz extends LayoutTestsBase {
     private static final Locale LOCALE = new Locale("fr");
-    private static final LayoutBase LAYOUT = new Qwertz(new FrenchQwertzCustomizer(LOCALE));
+    private static final LayoutBase LAYOUT = new Qwertz(new FrenchEuroCustomizer(LOCALE));
 
     @Override
     LayoutBase getLayout() { return LAYOUT; }
-
-    private static class FrenchQwertzCustomizer extends EuroLayoutCustomizer {
-        public FrenchQwertzCustomizer(final Locale locale) { super(locale); }
-
-        @Override
-        public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
-            return builder
-                    // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
-                    // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
-                    // 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",
-                            "\u00E9", "\u00E8", "\u00EA", "\u00EB", "3", "\u0119", "\u0117",
-                            "\u0113")
-                    // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
-                    // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
-                    // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
-                    // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
-                    // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
-                    .setMoreKeysOf("u", "\u00F9", "\u00FB", "7", "\u00FC", "\u00FA", "\u016B")
-                    // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
-                    // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
-                    // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
-                    // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
-                    // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
-                    // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
-                    .setMoreKeysOf("i", "\u00EE", "8", "\u00EF", "\u00EC", "\u00ED", "\u012F",
-                            "\u012B")
-                    // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
-                    // U+0153: "œ" LATIN SMALL LIGATURE OE
-                    // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
-                    // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
-                    // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
-                    // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
-                    // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
-                    // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
-                    // U+00BA: "º" MASCULINE ORDINAL INDICATOR
-                    .setMoreKeysOf("o",
-                            "\u00F4", "\u0153", "9", "\u00F6", "\u00F2", "\u00F3", "\u00F5",
-                            "\u00F8", "\u014D", "\u00BA")
-                    // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
-                    // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
-                    // U+00E6: "æ" LATIN SMALL LETTER AE
-                    // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
-                    // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
-                    // 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", "\u00E2", "\u00E6", "\u00E1", "\u00E4", "\u00E3", "\u00E5",
-                            "\u0101", "\u00AA")
-                    // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
-                    .setMoreKeysOf("y", "\u00FF")
-                    // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
-                    // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
-                    // U+010D: "č" LATIN SMALL LETTER C WITH CARON
-                    .setMoreKeysOf("c", "\u00E7", "\u0107", "\u010D");
-        }
-    }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGalicianES.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGalicianES.java
new file mode 100644
index 0000000..1472828
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGalicianES.java
@@ -0,0 +1,52 @@
+/*
+ * 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.LayoutBase.EuroCustomizer;
+import com.android.inputmethod.keyboard.layout.Spanish;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+
+import java.util.Locale;
+
+/**
+ * gl_ES: Galician (Spain)/spanish
+ */
+@SmallTest
+public class TestsGalicianES extends LayoutTestsBase {
+    private static final Locale LOCALE = new Locale("gl", "ES");
+    private static final LayoutBase LAYOUT = new Spanish(new GalicianESCustomizer(LOCALE));
+
+    @Override
+    LayoutBase getLayout() { return LAYOUT; }
+
+    private static class GalicianESCustomizer extends EuroCustomizer {
+        private final SpanishCustomizer mSpanishCustomizer;
+
+        public GalicianESCustomizer(final Locale locale) {
+            super(locale);
+            mSpanishCustomizer = new SpanishCustomizer(locale);
+        }
+
+        @Override
+        public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
+            return mSpanishCustomizer.setAccentedLetters(builder);
+        }
+    }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGerman.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGerman.java
index 7c12b37..6f75711 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGerman.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGerman.java
@@ -19,11 +19,9 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.EuroLayoutCustomizer;
+import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer;
 import com.android.inputmethod.keyboard.layout.Qwertz;
-import com.android.inputmethod.keyboard.layout.Symbols;
 import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
-import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
 
 import java.util.Locale;
 
@@ -33,70 +31,25 @@
 @SmallTest
 public final class TestsGerman extends LayoutTestsBase {
     private static final Locale LOCALE = new Locale("de");
-    private static final LayoutBase LAYOUT = new Qwertz(new GermanCustomizer(LOCALE));
+    private static final LayoutBase LAYOUT = new Qwertz(new GermanEuroCustomizer(LOCALE));
 
     @Override
     LayoutBase getLayout() { return LAYOUT; }
 
-    private static class GermanCustomizer extends EuroLayoutCustomizer {
-        public GermanCustomizer(final Locale locale) { super(locale); }
+    static class GermanEuroCustomizer extends GermanCustomizer {
+        final EuroCustomizer mEuroCustomizer;
+
+        public GermanEuroCustomizer(final Locale locale) {
+            super(locale);
+            mEuroCustomizer = new EuroCustomizer(locale);
+        }
 
         @Override
-        public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_R9L; }
+        public ExpectedKey getCurrencyKey() { return mEuroCustomizer.getCurrencyKey(); }
 
         @Override
-        public ExpectedKey[] getSingleQuoteMoreKeys() { return Symbols.SINGLE_QUOTES_R9L; }
-
-        @Override
-        public ExpectedKey[] getDoubleAngleQuoteKeys() { return Symbols.DOUBLE_ANGLE_QUOTES_RL; }
-
-        @Override
-        public ExpectedKey[] getSingleAngleQuoteKeys() { return Symbols.SINGLE_ANGLE_QUOTES_RL; }
-
-        @Override
-        public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
-            return builder
-                    // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
-                    // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
-                    // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
-                    // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
-                    // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
-                    .setMoreKeysOf("e", "3", "\u00E9", "\u00E8", "\u00EA", "\u00EB", "\u0117")
-                    // 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
-                    .setMoreKeysOf("u", "7", "\u00FC", "\u00FB", "\u00F9", "\u00FA", "\u016B")
-                    // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
-                    // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
-                    // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
-                    // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
-                    // 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
-                    .setMoreKeysOf("o",
-                            "9", "\u00F6", "\u00F4", "\u00F2", "\u00F3", "\u00F5", "\u0153",
-                            "\u00F8", "\u014D")
-                    // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
-                    // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
-                    // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
-                    // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
-                    // 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
-                    .setMoreKeysOf("a",
-                            "\u00E4", "\u00E2", "\u00E0", "\u00E1", "\u00E6", "\u00E3", "\u00E5",
-                            "\u0101")
-                    // U+00DF: "ß" LATIN SMALL LETTER SHARP S
-                    // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
-                    // U+0161: "š" LATIN SMALL LETTER S WITH CARON
-                    .setMoreKeysOf("s", "\u00DF", "\u015B", "\u0161")
-                    // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
-                    // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
-                    .setMoreKeysOf("n", "\u00F1", "\u0144");
+        public ExpectedKey[] getOtherCurrencyKeys() {
+            return mEuroCustomizer.getOtherCurrencyKeys();
         }
     }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGermanCH.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGermanCH.java
index 001c3c4..7deb00b 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGermanCH.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGermanCH.java
@@ -19,10 +19,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer;
 import com.android.inputmethod.keyboard.layout.Swiss;
-import com.android.inputmethod.keyboard.layout.Symbols;
-import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
 import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
 
 import java.util.Locale;
@@ -38,74 +35,22 @@
     @Override
     LayoutBase getLayout() { return LAYOUT; }
 
-    private static class GermanCHCustomizer extends LayoutCustomizer {
+    private static class GermanCHCustomizer extends GermanCustomizer {
         public GermanCHCustomizer(final Locale locale) { super(locale); }
 
         @Override
-        public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_R9L; }
-
-        @Override
-        public ExpectedKey[] getSingleQuoteMoreKeys() { return Symbols.SINGLE_QUOTES_R9L; }
-
-        @Override
-        public ExpectedKey[] getDoubleAngleQuoteKeys() { return Symbols.DOUBLE_ANGLE_QUOTES_RL; }
-
-        @Override
-        public ExpectedKey[] getSingleAngleQuoteKeys() { return Symbols.SINGLE_ANGLE_QUOTES_RL; }
-
-        @Override
         public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
+            super.setAccentedLetters(builder);
             return builder
-                    // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
-                    // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
-                    // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
-                    // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
-                    // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
-                    .setMoreKeysOf("e", "3", "\u00E9", "\u00E8", "\u00EA", "\u00EB", "\u0117")
-                    // 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
-                    .setMoreKeysOf("u", "7", "\u00FC", "\u00FB", "\u00F9", "\u00FA", "\u016B")
-                    // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
-                    // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
-                    // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
-                    // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
-                    // 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
-                    .setMoreKeysOf("o",
-                            "9", "\u00F6", "\u00F4", "\u00F2", "\u00F3", "\u00F5", "\u0153",
-                            "\u00F8", "\u014D")
                     // 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+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
-                    // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
-                    // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
-                    // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
-                    // 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
-                    .setMoreKeysOf("a",
-                            "\u00E4", "\u00E2", "\u00E0", "\u00E1", "\u00E6", "\u00E3", "\u00E5",
-                            "\u0101")
                     // 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")))
-                    // U+00DF: "ß" LATIN SMALL LETTER SHARP S
-                    // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
-                    // U+0161: "š" LATIN SMALL LETTER S WITH CARON
-                    .setMoreKeysOf("s", "\u00DF", "\u015B", "\u0161")
-                    // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
-                    // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
-                    .setMoreKeysOf("n", "\u00F1", "\u0144");
+                    .replaceKeyOfLabel(Swiss.ROW2_11, key("\u00E4", moreKey("\u00E0")));
         }
     }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGermanDvorak.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGermanDvorak.java
new file mode 100644
index 0000000..b28d5cf
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGermanDvorak.java
@@ -0,0 +1,75 @@
+/*
+ * 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.Dvorak;
+import com.android.inputmethod.keyboard.layout.Dvorak.DvorakCustomizer;
+import com.android.inputmethod.keyboard.layout.LayoutBase;
+import com.android.inputmethod.keyboard.layout.Symbols;
+import com.android.inputmethod.keyboard.layout.SymbolsShifted;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+
+import java.util.Locale;
+
+/**
+ * de: German/dvorak
+ */
+@SmallTest
+public final class TestsGermanDvorak extends LayoutTestsBase {
+    private static final Locale LOCALE = new Locale("de");
+    private static final LayoutBase LAYOUT = new Dvorak(new GermanDvorakCustomizer(LOCALE));
+
+    @Override
+    LayoutBase getLayout() { return LAYOUT; }
+
+    static class GermanDvorakCustomizer extends DvorakCustomizer {
+        final GermanCustomizer mGermanCustomizer;
+
+        public GermanDvorakCustomizer(final Locale locale) {
+            super(locale);
+            mGermanCustomizer = new GermanCustomizer(locale);
+        }
+
+        @Override
+        public ExpectedKey getCurrencyKey() { return Symbols.CURRENCY_EURO; }
+
+        @Override
+        public ExpectedKey[] getOtherCurrencyKeys() {
+            return SymbolsShifted.CURRENCIES_OTHER_THAN_EURO;
+        }
+
+        @Override
+        public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_R9L; }
+
+        @Override
+        public ExpectedKey[] getSingleQuoteMoreKeys() { return Symbols.SINGLE_QUOTES_R9L; }
+
+        @Override
+        public ExpectedKey[] getDoubleAngleQuoteKeys() { return Symbols.DOUBLE_ANGLE_QUOTES_RL; }
+
+        @Override
+        public ExpectedKey[] getSingleAngleQuoteKeys() { return Symbols.SINGLE_ANGLE_QUOTES_RL; }
+
+        @Override
+        public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
+            return mGermanCustomizer.setAccentedLetters(builder);
+        }
+    }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGermanQwerty.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGermanQwerty.java
index 618485d..19ae5a3 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGermanQwerty.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGermanQwerty.java
@@ -19,11 +19,8 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.EuroLayoutCustomizer;
 import com.android.inputmethod.keyboard.layout.Qwerty;
-import com.android.inputmethod.keyboard.layout.Symbols;
-import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
-import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+import com.android.inputmethod.keyboard.layout.tests.TestsGerman.GermanEuroCustomizer;
 
 import java.util.Locale;
 
@@ -33,70 +30,8 @@
 @SmallTest
 public final class TestsGermanQwerty extends LayoutTestsBase {
     private static final Locale LOCALE = new Locale("de");
-    private static final LayoutBase LAYOUT = new Qwerty(new GermanQwertyCustomizer(LOCALE));
+    private static final LayoutBase LAYOUT = new Qwerty(new GermanEuroCustomizer(LOCALE));
 
     @Override
     LayoutBase getLayout() { return LAYOUT; }
-
-    private static class GermanQwertyCustomizer extends EuroLayoutCustomizer {
-        public GermanQwertyCustomizer(final Locale locale) { super(locale); }
-
-        @Override
-        public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_R9L; }
-
-        @Override
-        public ExpectedKey[] getSingleQuoteMoreKeys() { return Symbols.SINGLE_QUOTES_R9L; }
-
-        @Override
-        public ExpectedKey[] getDoubleAngleQuoteKeys() { return Symbols.DOUBLE_ANGLE_QUOTES_RL; }
-
-        @Override
-        public ExpectedKey[] getSingleAngleQuoteKeys() { return Symbols.SINGLE_ANGLE_QUOTES_RL; }
-
-        @Override
-        public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
-            return builder
-                    // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
-                    // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
-                    // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
-                    // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
-                    // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
-                    .setMoreKeysOf("e", "3", "\u00E9", "\u00E8", "\u00EA", "\u00EB", "\u0117")
-                    // 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
-                    .setMoreKeysOf("u", "7", "\u00FC", "\u00FB", "\u00F9", "\u00FA", "\u016B")
-                    // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
-                    // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
-                    // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
-                    // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
-                    // 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
-                    .setMoreKeysOf("o",
-                            "9", "\u00F6", "\u00F4", "\u00F2", "\u00F3", "\u00F5", "\u0153",
-                            "\u00F8", "\u014D")
-                    // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
-                    // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
-                    // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
-                    // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
-                    // 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
-                    .setMoreKeysOf("a",
-                            "\u00E4", "\u00E2", "\u00E0", "\u00E1", "\u00E6", "\u00E3", "\u00E5",
-                            "\u0101")
-                    // U+00DF: "ß" LATIN SMALL LETTER SHARP S
-                    // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
-                    // U+0161: "š" LATIN SMALL LETTER S WITH CARON
-                    .setMoreKeysOf("s", "\u00DF", "\u015B", "\u0161")
-                    // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
-                    // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
-                    .setMoreKeysOf("n", "\u00F1", "\u0144");
-        }
-    }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHungarian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHungarian.java
index 942c07a..efc95dc 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHungarian.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHungarian.java
@@ -64,24 +64,21 @@
                     // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
                     // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
                     .setMoreKeysOf("e",
-                            "3", "\u00E9", "\u00E8", "\u00EA", "\u00EB", "\u0119", "\u0117",
-                            "\u0113")
+                            "\u00E9", "\u00E8", "\u00EA", "\u00EB", "\u0119", "\u0117", "\u0113")
                     // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
                     // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
                     // U+0171: "ű" LATIN SMALL LETTER U WITH DOUBLE ACUTE
                     // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
                     // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
                     // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
-                    .setMoreKeysOf("u", "7", "\u00FA", "\u00FC", "\u0171", "\u00FB", "\u00F9",
-                            "\u016B")
+                    .setMoreKeysOf("u", "\u00FA", "\u00FC", "\u0171", "\u00FB", "\u00F9", "\u016B")
                     // 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+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
                     // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
                     // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
-                    .setMoreKeysOf("i", "8", "\u00ED", "\u00EE", "\u00EF", "\u00EC", "\u012F",
-                            "\u012B")
+                    .setMoreKeysOf("i", "\u00ED", "\u00EE", "\u00EF", "\u00EC", "\u012F", "\u012B")
                     // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
                     // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
                     // U+0151: "ő" LATIN SMALL LETTER O WITH DOUBLE ACUTE
@@ -92,8 +89,8 @@
                     // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
                     // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
                     .setMoreKeysOf("o",
-                            "9", "\u00F3", "\u00F6", "\u0151", "\u00F4", "\u00F2", "\u00F5",
-                            "\u0153", "\u00F8", "\u014D")
+                            "\u00F3", "\u00F6", "\u0151", "\u00F4", "\u00F2", "\u00F5", "\u0153",
+                            "\u00F8", "\u014D")
                     // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
                     // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
                     // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsIcelandic.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsIcelandic.java
index c10c1a9..62b111e 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsIcelandic.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsIcelandic.java
@@ -58,27 +58,25 @@
                     // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
                     // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
                     .setMoreKeysOf("e",
-                            "3", "\u00E9", "\u00EB", "\u00E8", "\u00EA", "\u0119", "\u0117",
-                            "\u0113")
+                            "\u00E9", "\u00EB", "\u00E8", "\u00EA", "\u0119", "\u0117", "\u0113")
                     // U+00FE: "þ" LATIN SMALL LETTER THORN
-                    .setMoreKeysOf("t", "5", "\u00FE")
+                    .setMoreKeysOf("t", "\u00FE")
                     // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
                     // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
-                    .setMoreKeysOf("y", "6", "\u00FD", "\u00FF")
+                    .setMoreKeysOf("y", "\u00FD", "\u00FF")
                     // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
                     // 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+016B: "ū" LATIN SMALL LETTER U WITH MACRON
-                    .setMoreKeysOf("u", "7", "\u00FA", "\u00FC", "\u00FB", "\u00F9", "\u016B")
+                    .setMoreKeysOf("u", "\u00FA", "\u00FC", "\u00FB", "\u00F9", "\u016B")
                     // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
                     // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
                     // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
                     // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
                     // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
                     // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
-                    .setMoreKeysOf("i", "8", "\u00ED", "\u00EF", "\u00EE", "\u00EC", "\u012F",
-                            "\u012B")
+                    .setMoreKeysOf("i", "\u00ED", "\u00EF", "\u00EE", "\u00EC", "\u012F", "\u012B")
                     // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
                     // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
                     // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
@@ -88,8 +86,8 @@
                     // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
                     // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
                     .setMoreKeysOf("o",
-                            "9", "\u00F3", "\u00F6", "\u00F4", "\u00F2", "\u00F5", "\u0153",
-                            "\u00F8", "\u014D")
+                            "\u00F3", "\u00F6", "\u00F4", "\u00F2", "\u00F5", "\u0153", "\u00F8",
+                            "\u014D")
                     // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
                     // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
                     // U+00E6: "æ" LATIN SMALL LETTER AE
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 1ba54b1..4a22003 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsItalian.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsItalian.java
@@ -19,7 +19,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.EuroLayoutCustomizer;
+import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer;
 import com.android.inputmethod.keyboard.layout.Qwerty;
 import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
 
@@ -36,7 +36,7 @@
     @Override
     LayoutBase getLayout() { return LAYOUT; }
 
-    private static class ItalianCustomizer extends EuroLayoutCustomizer {
+    private static class ItalianCustomizer extends EuroCustomizer {
         public ItalianCustomizer(final Locale locale) { super(locale); }
 
         @Override
@@ -50,22 +50,20 @@
                     // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
                     // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
                     .setMoreKeysOf("e",
-                            "3", "\u00E8", "\u00E9", "\u00EA", "\u00EB", "\u0119", "\u0117",
-                            "\u0113")
+                            "\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", "7", "\u00F9", "\u00FA", "\u00FB", "\u00FC", "\u016B")
+                    .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", "8", "\u00EC", "\u00ED", "\u00EE", "\u00EF", "\u012F",
-                            "\u012B")
+                    .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
@@ -76,8 +74,8 @@
                     // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
                     // U+00BA: "º" MASCULINE ORDINAL INDICATOR
                     .setMoreKeysOf("o",
-                            "9", "\u00F2", "\u00F3", "\u00F4", "\u00F6", "\u00F5", "\u0153",
-                            "\u00F8", "\u014D", "\u00BA")
+                            "\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
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKazakh.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKazakh.java
index ec08a5a..d255a0f 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKazakh.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKazakh.java
@@ -45,21 +45,21 @@
                     // U+0443: "у" CYRILLIC SMALL LETTER U
                     // U+04AF: "ү" CYRILLIC SMALL LETTER STRAIGHT U
                     // U+04B1: "ұ" CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE
-                    .setMoreKeysOf("\u0443", "3", "\u04AF", "\u04B1")
+                    .setMoreKeysOf("\u0443", "\u04AF", "\u04B1")
                     // U+043A: "к" CYRILLIC SMALL LETTER KA
                     // U+049B: "қ" CYRILLIC SMALL LETTER KA WITH DESCENDER
-                    .setMoreKeysOf("\u043A", "4", "\u049B")
+                    .setMoreKeysOf("\u043A", "\u049B")
                     // U+0435: "е" CYRILLIC SMALL LETTER IE
                     // U+0451: "ё" CYRILLIC SMALL LETTER IO
-                    .setMoreKeysOf("\u0435", "5", "\u0451")
+                    .setMoreKeysOf("\u0435", "\u0451")
                     // U+043D: "н" CYRILLIC SMALL LETTER EN
                     // U+04A3: "ң" CYRILLIC SMALL LETTER EN WITH DESCENDER
-                    .setMoreKeysOf("\u043D", "6", "\u04A3")
+                    .setMoreKeysOf("\u043D", "\u04A3")
                     // U+0433: "г" CYRILLIC SMALL LETTER GHE
                     // U+0493: "ғ" CYRILLIC SMALL LETTER GHE WITH STROKE
-                    .setMoreKeysOf("\u0433", "7", "\u0493")
+                    .setMoreKeysOf("\u0433", "\u0493")
                     // U+0449: "щ" CYRILLIC SMALL LETTER SHCHA
-                    .replaceKeyOfLabel(EastSlavic.ROW1_9, key("\u0449", moreKey("9")))
+                    .replaceKeyOfLabel(EastSlavic.ROW1_9, key("\u0449", additionalMoreKey("9")))
                     // U+044B: "ы" CYRILLIC SMALL LETTER YERU
                     // U+0456: "і" CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
                     .replaceKeyOfLabel(EastSlavic.ROW2_2, key("\u044B", moreKey("\u0456")))
@@ -73,7 +73,7 @@
                     // U+04BB: "һ" CYRILLIC SMALL LETTER SHHA
                     .replaceKeyOfLabel(EastSlavic.ROW2_11, key("\u044D", moreKey("\u04BB")))
                     // U+0438: "и" CYRILLIC SMALL LETTER I
-                    .replaceKeyOfLabel(EastSlavic.ROW3_5, key("\u0438"))
+                    .replaceKeyOfLabel(EastSlavic.ROW3_5, "\u0438")
                     // U+044C: "ь" CYRILLIC SMALL LETTER SOFT SIGN
                     // U+044A: "ъ" CYRILLIC SMALL LETTER HARD SIGN
                     .setMoreKeysOf("\u044C", "\u044A");
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKyrgyz.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKyrgyz.java
index ccacf3f..9797b4b 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKyrgyz.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKyrgyz.java
@@ -44,24 +44,24 @@
             return builder
                     // U+0443: "у" CYRILLIC SMALL LETTER U
                     // U+04AF: "ү" CYRILLIC SMALL LETTER STRAIGHT U
-                    .setMoreKeysOf("\u0443", "3", "\u04AF")
+                    .setMoreKeysOf("\u0443", "\u04AF")
                     // U+0435: "е" CYRILLIC SMALL LETTER IE
                     // U+0451: "ё" CYRILLIC SMALL LETTER IO
-                    .setMoreKeysOf("\u0435", "5", "\u0451")
+                    .setMoreKeysOf("\u0435", "\u0451")
                     // U+043D: "н" CYRILLIC SMALL LETTER EN
                     // U+04A3: "ң" CYRILLIC SMALL LETTER EN WITH DESCENDER
-                    .setMoreKeysOf("\u043D", "6", "\u04A3")
+                    .setMoreKeysOf("\u043D", "\u04A3")
                     // U+0449: "щ" CYRILLIC SMALL LETTER SHCHA
-                    .replaceKeyOfLabel(EastSlavic.ROW1_9, key("\u0449", moreKey("9")))
+                    .replaceKeyOfLabel(EastSlavic.ROW1_9, key("\u0449", additionalMoreKey("9")))
                     // U+044B: "ы" CYRILLIC SMALL LETTER YERU
-                    .replaceKeyOfLabel(EastSlavic.ROW2_2, key("\u044B"))
+                    .replaceKeyOfLabel(EastSlavic.ROW2_2, "\u044B")
                     // U+043E: "о" CYRILLIC SMALL LETTER O
                     // U+04E9: "ө" CYRILLIC SMALL LETTER BARRED O
                     .setMoreKeysOf("\u043E", "\u04E9")
                     // U+044D: "э" CYRILLIC SMALL LETTER E
-                    .replaceKeyOfLabel(EastSlavic.ROW2_11, key("\u044D"))
+                    .replaceKeyOfLabel(EastSlavic.ROW2_11, "\u044D")
                     // U+0438: "и" CYRILLIC SMALL LETTER I
-                    .replaceKeyOfLabel(EastSlavic.ROW3_5, key("\u0438"))
+                    .replaceKeyOfLabel(EastSlavic.ROW3_5, "\u0438")
                     // U+044C: "ь" CYRILLIC SMALL LETTER SOFT SIGN
                     // U+044A: "ъ" CYRILLIC SMALL LETTER HARD SIGN
                     .setMoreKeysOf("\u044C", "\u044A");
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsLatvian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsLatvian.java
index 0f07854..dc1736c 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsLatvian.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsLatvian.java
@@ -59,18 +59,18 @@
                     // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK
                     // U+011B: "ě" LATIN SMALL LETTER E WITH CARON
                     .setMoreKeysOf("e",
-                            "3", "\u0113", "\u0117", "\u00E8", "\u00E9", "\u00EA", "\u00EB",
-                            "\u0119", "\u011B")
+                            "\u0113", "\u0117", "\u00E8", "\u00E9", "\u00EA", "\u00EB", "\u0119",
+                            "\u011B")
                     // U+0157: "ŗ" LATIN SMALL LETTER R WITH CEDILLA
                     // U+0159: "ř" LATIN SMALL LETTER R WITH CARON
                     // U+0155: "ŕ" LATIN SMALL LETTER R WITH ACUTE
-                    .setMoreKeysOf("r", "4", "\u0157", "\u0159", "\u0155")
+                    .setMoreKeysOf("r", "\u0157", "\u0159", "\u0155")
                     // U+0163: "ţ" LATIN SMALL LETTER T WITH CEDILLA
                     // U+0165: "ť" LATIN SMALL LETTER T WITH CARON
-                    .setMoreKeysOf("t", "5", "\u0163", "\u0165")
+                    .setMoreKeysOf("t", "\u0163", "\u0165")
                     // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
                     // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
-                    .setMoreKeysOf("y", "6", "\u00FD", "\u00FF")
+                    .setMoreKeysOf("y", "\u00FD", "\u00FF")
                     // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
                     // U+0173: "ų" LATIN SMALL LETTER U WITH OGONEK
                     // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
@@ -80,8 +80,8 @@
                     // U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE
                     // U+0171: "ű" LATIN SMALL LETTER U WITH DOUBLE ACUTE
                     .setMoreKeysOf("u",
-                            "7", "\u016B", "\u0173", "\u00F9", "\u00FA", "\u00FB", "\u00FC",
-                            "\u016F", "\u0171")
+                            "\u016B", "\u0173", "\u00F9", "\u00FA", "\u00FB", "\u00FC", "\u016F",
+                            "\u0171")
                     // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
                     // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
                     // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
@@ -90,8 +90,7 @@
                     // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
                     // U+0131: "ı" LATIN SMALL LETTER DOTLESS I
                     .setMoreKeysOf("i",
-                            "8", "\u012B", "\u012F", "\u00EC", "\u00ED", "\u00EE", "\u00EF",
-                            "\u0131")
+                            "\u012B", "\u012F", "\u00EC", "\u00ED", "\u00EE", "\u00EF", "\u0131")
                     // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
                     // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
                     // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
@@ -101,8 +100,8 @@
                     // U+0151: "ő" LATIN SMALL LETTER O WITH DOUBLE ACUTE
                     // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
                     .setMoreKeysOf("o",
-                            "9", "\u00F2", "\u00F3", "\u00F4", "\u00F5", "\u00F6", "\u0153",
-                            "\u0151", "\u00F8")
+                            "\u00F2", "\u00F3", "\u00F4", "\u00F5", "\u00F6", "\u0153", "\u0151",
+                            "\u00F8")
                     // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON
                     // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
                     // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsLithuanian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsLithuanian.java
index 9094db9..55ac37a 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsLithuanian.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsLithuanian.java
@@ -59,18 +59,18 @@
                     // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
                     // U+011B: "ě" LATIN SMALL LETTER E WITH CARON
                     .setMoreKeysOf("e",
-                            "3", "\u0117", "\u0119", "\u0113", "\u00E8", "\u00E9", "\u00EA",
-                            "\u00EB", "\u011B")
+                            "\u0117", "\u0119", "\u0113", "\u00E8", "\u00E9", "\u00EA", "\u00EB",
+                            "\u011B")
                     // U+0157: "ŗ" LATIN SMALL LETTER R WITH CEDILLA
                     // U+0159: "ř" LATIN SMALL LETTER R WITH CARON
                     // U+0155: "ŕ" LATIN SMALL LETTER R WITH ACUTE
-                    .setMoreKeysOf("r", "4", "\u0157", "\u0159", "\u0155")
+                    .setMoreKeysOf("r", "\u0157", "\u0159", "\u0155")
                     // U+0163: "ţ" LATIN SMALL LETTER T WITH CEDILLA
                     // U+0165: "ť" LATIN SMALL LETTER T WITH CARON
-                    .setMoreKeysOf("t", "5", "\u0163", "\u0165")
+                    .setMoreKeysOf("t", "\u0163", "\u0165")
                     // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
                     // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
-                    .setMoreKeysOf("y", "6", "\u00FD", "\u00FF")
+                    .setMoreKeysOf("y", "\u00FD", "\u00FF")
                     // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
                     // U+0173: "ų" LATIN SMALL LETTER U WITH OGONEK
                     // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
@@ -81,8 +81,8 @@
                     // U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE
                     // U+0171: "ű" LATIN SMALL LETTER U WITH DOUBLE ACUTE
                     .setMoreKeysOf("u",
-                            "7", "\u016B", "\u0173", "\u00FC", "\u016B", "\u00F9", "\u00FA",
-                            "\u00FB", "\u016F", "\u0171")
+                            "\u016B", "\u0173", "\u00FC", "\u016B", "\u00F9", "\u00FA", "\u00FB",
+                            "\u016F", "\u0171")
                     // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
                     // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
                     // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
@@ -91,8 +91,7 @@
                     // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
                     // U+0131: "ı" LATIN SMALL LETTER DOTLESS I
                     .setMoreKeysOf("i",
-                            "8", "\u012F", "\u012B", "\u00EC", "\u00ED", "\u00EE", "\u00EF",
-                            "\u0131")
+                            "\u012F", "\u012B", "\u00EC", "\u00ED", "\u00EE", "\u00EF", "\u0131")
                     // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
                     // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
                     // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
@@ -102,8 +101,8 @@
                     // U+0151: "ő" LATIN SMALL LETTER O WITH DOUBLE ACUTE
                     // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
                     .setMoreKeysOf("o",
-                            "9", "\u00F6", "\u00F5", "\u00F2", "\u00F3", "\u00F4", "\u0153",
-                            "\u0151", "\u00F8")
+                            "\u00F6", "\u00F5", "\u00F2", "\u00F3", "\u00F4", "\u0153", "\u0151",
+                            "\u00F8")
                     // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK
                     // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
                     // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMacedonian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMacedonian.java
index 5202698..1d7d856 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMacedonian.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMacedonian.java
@@ -52,18 +52,18 @@
             return builder
                     // U+0435: "е" CYRILLIC SMALL LETTER IE
                     // U+0450: "ѐ" CYRILLIC SMALL LETTER IE WITH GRAVE
-                    .setMoreKeysOf("\u0435", "3", "\u0450")
+                    .setMoreKeysOf("\u0435", "\u0450")
                     // U+0455: "ѕ" CYRILLIC SMALL LETTER DZE
-                    .replaceKeyOfLabel(SouthSlavic.ROW1_6, key("\u0455", moreKey("6")))
+                    .replaceKeyOfLabel(SouthSlavic.ROW1_6, key("\u0455", additionalMoreKey("6")))
                     // U+0438: "и" CYRILLIC SMALL LETTER I
                     // U+045D: "ѝ" CYRILLIC SMALL LETTER I WITH GRAVE
-                    .setMoreKeysOf("\u0438", "8", "\u045D")
+                    .setMoreKeysOf("\u0438", "\u045D")
                     // U+045C: "ќ" CYRILLIC SMALL LETTER KJE
-                    .replaceKeyOfLabel(SouthSlavic.ROW2_11, key("\u045C"))
+                    .replaceKeyOfLabel(SouthSlavic.ROW2_11, "\u045C")
                     // U+0437: "з" CYRILLIC SMALL LETTER ZE
-                    .replaceKeyOfLabel(SouthSlavic.ROW3_1, key("\u0437"))
+                    .replaceKeyOfLabel(SouthSlavic.ROW3_1, "\u0437")
                     // U+0453: "ѓ" CYRILLIC SMALL LETTER GJE
-                    .replaceKeyOfLabel(SouthSlavic.ROW3_8, key("\u0453"));
+                    .replaceKeyOfLabel(SouthSlavic.ROW3_8, "\u0453");
         }
     }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguage.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguage.java
index 76a3d4d..3ed6315 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguage.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguage.java
@@ -19,14 +19,12 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer;
 import com.android.inputmethod.keyboard.layout.Qwerty;
-import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
 
 import java.util.Locale;
 
 /**
- * zz: QWERTY/qwerty
+ * zz: Alphabet/qwerty
  */
 @SmallTest
 public final class TestsNoLanguage extends LayoutTestsBase {
@@ -35,141 +33,4 @@
 
     @Override
     LayoutBase getLayout() { return LAYOUT; }
-
-    private static class NoLanguageCustomizer extends LayoutCustomizer {
-        public NoLanguageCustomizer(final Locale locale) { super(locale); }
-
-        @Override
-        public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
-            return builder
-                    // U+0175: "ŵ" LATIN SMALL LETTER W WITH CIRCUMFLEX
-                    .setMoreKeysOf("w", "2", "\u0175")
-                    // 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+0113: "ē" LATIN SMALL LETTER E WITH MACRON
-                    // U+0115: "ĕ" LATIN SMALL LETTER E WITH BREVE
-                    // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
-                    // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK
-                    // U+011B: "ě" LATIN SMALL LETTER E WITH CARON
-                    .setMoreKeysOf("e",
-                            "3", "\u00E8", "\u00E9", "\u00EA", "\u00EB", "\u0113", "\u0115",
-                            "\u0117", "\u0119", "\u011B")
-                    // U+0155: "ŕ" LATIN SMALL LETTER R WITH ACUTE
-                    // U+0157: "ŗ" LATIN SMALL LETTER R WITH CEDILLA
-                    // U+0159: "ř" LATIN SMALL LETTER R WITH CARON
-                    .setMoreKeysOf("r", "4", "\u0155", "\u0157", "\u0159")
-                    // U+00FE: "þ" LATIN SMALL LETTER THORN
-                    // U+0163: "ţ" LATIN SMALL LETTER T WITH CEDILLA
-                    // U+0165: "ť" LATIN SMALL LETTER T WITH CARON
-                    // U+0167: "ŧ" LATIN SMALL LETTER T WITH STROKE
-                    .setMoreKeysOf("t", "5", "\u00FE", "\u0163", "\u0165", "\u0167")
-                    // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
-                    // U+0177: "ŷ" LATIN SMALL LETTER Y WITH CIRCUMFLEX
-                    // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
-                    // U+0133: "ij" LATIN SMALL LIGATURE IJ
-                    .setMoreKeysOf("y", "6", "\u00FD", "\u0177", "\u00FF", "\u0133")
-                    // 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+0169: "ũ" LATIN SMALL LETTER U WITH TILDE
-                    // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
-                    // U+016D: "ŭ" LATIN SMALL LETTER U WITH BREVE
-                    // U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE
-                    // U+0171: "ű" LATIN SMALL LETTER U WITH DOUBLE ACUTE
-                    // U+0173: "ų" LATIN SMALL LETTER U WITH OGONEK
-                    .setMoreKeysOf("u",
-                            "7", "\u00F9", "\u00FA", "\u00FB", "\u00FC", "\u0169", "\u016B",
-                            "\u016D", "\u016F", "\u0171", "\u0173")
-                    // 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+0129: "ĩ" LATIN SMALL LETTER I WITH TILDE
-                    // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
-                    // U+012D: "ĭ" LATIN SMALL LETTER I WITH BREVE
-                    // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
-                    // U+0131: "ı" LATIN SMALL LETTER DOTLESS I
-                    // U+0133: "ij" LATIN SMALL LIGATURE IJ
-                    .setMoreKeysOf("i",
-                            "8", "\u00EC", "\u00ED", "\u00EE", "\u00EF", "\u0129", "\u012B",
-                            "\u012D", "\u012F", "\u0131", "\u0133")
-                    // 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+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
-                    // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
-                    // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
-                    // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
-                    // U+014F: "ŏ" LATIN SMALL LETTER O WITH BREVE
-                    // U+0151: "ő" LATIN SMALL LETTER O WITH DOUBLE ACUTE
-                    // U+0153: "œ" LATIN SMALL LIGATURE OE
-                    // U+00BA: "º" MASCULINE ORDINAL INDICATOR
-                    .setMoreKeysOf("o",
-                            "9", "\u00F2", "\u00F3", "\u00F4", "\u00F5", "\u00F6", "\u00F8",
-                            "\u014D", "\u014F", "\u0151", "\u0153", "\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+00E3: "ã" LATIN SMALL LETTER A WITH TILDE
-                    // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
-                    // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
-                    // U+00E6: "æ" LATIN SMALL LETTER AE
-                    // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON
-                    // U+0103: "ă" LATIN SMALL LETTER A WITH BREVE
-                    // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK
-                    // U+00AA: "ª" FEMININE ORDINAL INDICATOR
-                    .setMoreKeysOf("a",
-                            "\u00E0", "\u00E1", "\u00E2", "\u00E3", "\u00E4", "\u00E5", "\u00E6",
-                            "\u0101", "\u0103", "\u0105", "\u00AA")
-                    // U+00DF: "ß" LATIN SMALL LETTER SHARP S
-                    // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
-                    // U+015D: "ŝ" LATIN SMALL LETTER S WITH CIRCUMFLEX
-                    // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA
-                    // U+0161: "š" LATIN SMALL LETTER S WITH CARON
-                    // U+017F: "ſ" LATIN SMALL LETTER LONG S
-                    .setMoreKeysOf("s", "\u00DF", "\u015B", "\u015D", "\u015F", "\u0161", "\u017F")
-                    // U+010F: "ď" LATIN SMALL LETTER D WITH CARON
-                    // U+0111: "đ" LATIN SMALL LETTER D WITH STROKE
-                    // U+00F0: "ð" LATIN SMALL LETTER ETH
-                    .setMoreKeysOf("d", "\u010F", "\u0111", "\u00F0")
-                    // U+011D: "ĝ" LATIN SMALL LETTER G WITH CIRCUMFLEX
-                    // U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE
-                    // U+0121: "ġ" LATIN SMALL LETTER G WITH DOT ABOVE
-                    // U+0123: "ģ" LATIN SMALL LETTER G WITH CEDILLA
-                    .setMoreKeysOf("g", "\u011D", "\u011F", "\u0121", "\u0123")
-                    // U+0125: "ĥ" LATIN SMALL LETTER H WITH CIRCUMFLEX
-                    .setMoreKeysOf("h", "\u0125")
-                    // U+0135: "ĵ" LATIN SMALL LETTER J WITH CIRCUMFLEX
-                    .setMoreKeysOf("j", "\u0135")
-                    // U+0137: "ķ" LATIN SMALL LETTER K WITH CEDILLA
-                    // U+0138: "ĸ" LATIN SMALL LETTER KRA
-                    .setMoreKeysOf("k", "\u0137", "\u0138")
-                    // U+013A: "ĺ" LATIN SMALL LETTER L WITH ACUTE
-                    // U+013C: "ļ" LATIN SMALL LETTER L WITH CEDILLA
-                    // U+013E: "ľ" LATIN SMALL LETTER L WITH CARON
-                    // U+0140: "ŀ" LATIN SMALL LETTER L WITH MIDDLE DOT
-                    // U+0142: "ł" LATIN SMALL LETTER L WITH STROKE
-                    .setMoreKeysOf("l", "\u013A", "\u013C", "\u013E", "\u0140", "\u0142")
-                    // U+017A: "ź" LATIN SMALL LETTER Z WITH ACUTE
-                    // U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE
-                    // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON
-                    .setMoreKeysOf("z", "\u017A", "\u017C", "\u017E")
-                    // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
-                    // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
-                    // U+0109: "ĉ" LATIN SMALL LETTER C WITH CIRCUMFLEX
-                    // U+010B: "ċ" LATIN SMALL LETTER C WITH DOT ABOVE
-                    // U+010D: "č" LATIN SMALL LETTER C WITH CARON
-                    .setMoreKeysOf("c", "\u00E7", "\u0107", "\u0109", "\u010B", "\u010D")
-                    // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
-                    // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
-                    // U+0146: "ņ" LATIN SMALL LETTER N WITH CEDILLA
-                    // U+0148: "ň" LATIN SMALL LETTER N WITH CARON
-                    // U+0149: "ʼn" LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
-                    // U+014B: "ŋ" LATIN SMALL LETTER ENG
-                    .setMoreKeysOf("n", "\u00F1", "\u0144", "\u0146", "\u0148", "\u0149", "\u014B");
-        }
-    }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguageColemak.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguageColemak.java
new file mode 100644
index 0000000..8d627e3
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguageColemak.java
@@ -0,0 +1,52 @@
+/*
+ * 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.Colemak;
+import com.android.inputmethod.keyboard.layout.LayoutBase;
+import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+
+import java.util.Locale;
+
+/**
+ * zz: Alphabet/colemak
+ */
+@SmallTest
+public final class TestsNoLanguageColemak extends LayoutTestsBase {
+    private static final Locale LOCALE = new Locale("zz");
+    private static final LayoutBase LAYOUT = new Colemak(new NoLanguageColemakCustomizer(LOCALE));
+
+    @Override
+    LayoutBase getLayout() { return LAYOUT; }
+
+    private static class NoLanguageColemakCustomizer extends LayoutCustomizer {
+        private final NoLanguageCustomizer mNoLanguageCustomizer;
+
+        public NoLanguageColemakCustomizer(final Locale locale) {
+            super(locale);
+            mNoLanguageCustomizer = new NoLanguageCustomizer(locale);
+        }
+
+        @Override
+        public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
+            return mNoLanguageCustomizer.setAccentedLetters(builder);
+        }
+    }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguageDvorak.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguageDvorak.java
new file mode 100644
index 0000000..9bf47ed
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguageDvorak.java
@@ -0,0 +1,52 @@
+/*
+ * 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.Dvorak;
+import com.android.inputmethod.keyboard.layout.Dvorak.DvorakCustomizer;
+import com.android.inputmethod.keyboard.layout.LayoutBase;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+
+import java.util.Locale;
+
+/**
+ * zz: Alphabet/dvorak
+ */
+@SmallTest
+public final class TestsNoLanguageDvorak extends LayoutTestsBase {
+    private static final Locale LOCALE = new Locale("zz");
+    private static final LayoutBase LAYOUT = new Dvorak(new NoLanguageDvorakCustomizer(LOCALE));
+
+    @Override
+    LayoutBase getLayout() { return LAYOUT; }
+
+    private static class NoLanguageDvorakCustomizer extends DvorakCustomizer {
+        private final NoLanguageCustomizer mNoLanguageCustomizer;
+
+        public NoLanguageDvorakCustomizer(final Locale locale) {
+            super(locale);
+            mNoLanguageCustomizer = new NoLanguageCustomizer(locale);
+        }
+
+        @Override
+        public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
+            return mNoLanguageCustomizer.setAccentedLetters(builder);
+        }
+    }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguagePcQwerty.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguagePcQwerty.java
new file mode 100644
index 0000000..cd8d43c
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguagePcQwerty.java
@@ -0,0 +1,52 @@
+/*
+ * 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.PcQwerty;
+import com.android.inputmethod.keyboard.layout.PcQwerty.PcQwertyCustomizer;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+
+import java.util.Locale;
+
+/**
+ * zz: Alphabet/pcqwerty
+ */
+@SmallTest
+public final class TestsNoLanguagePcQwerty extends LayoutTestsBase {
+    private static final Locale LOCALE = new Locale("zz");
+    private static final LayoutBase LAYOUT = new PcQwerty(new NoLanguagePcQwertyCustomizer(LOCALE));
+
+    @Override
+    LayoutBase getLayout() { return LAYOUT; }
+
+    private static class NoLanguagePcQwertyCustomizer extends PcQwertyCustomizer {
+        private final NoLanguageCustomizer mNoLanguageCustomizer;
+
+        public NoLanguagePcQwertyCustomizer(final Locale locale) {
+            super(locale);
+            mNoLanguageCustomizer = new NoLanguageCustomizer(locale);
+        }
+
+        @Override
+        public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
+            return mNoLanguageCustomizer.setAccentedLetters(builder);
+        }
+    }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNorwegian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNorwegian.java
index d5b904c..5d220df 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNorwegian.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNorwegian.java
@@ -58,14 +58,13 @@
                     // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
                     // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
                     .setMoreKeysOf("e",
-                            "3", "\u00E9", "\u00E8", "\u00EA", "\u00EB", "\u0119", "\u0117",
-                            "\u0113")
+                            "\u00E9", "\u00E8", "\u00EA", "\u00EB", "\u0119", "\u0117", "\u0113")
                     // 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
-                    .setMoreKeysOf("u", "7", "\u00FC", "\u00FB", "\u00F9", "\u00FA", "\u016B")
+                    .setMoreKeysOf("u", "\u00FC", "\u00FB", "\u00F9", "\u00FA", "\u016B")
                     // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
                     // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
                     // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
@@ -74,10 +73,9 @@
                     // U+0153: "œ" LATIN SMALL LIGATURE OE
                     // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
                     .setMoreKeysOf("o",
-                            "9", "\u00F4", "\u00F2", "\u00F3", "\u00F6", "\u00F5", "\u0153",
-                            "\u014D")
+                            "\u00F4", "\u00F2", "\u00F3", "\u00F6", "\u00F5", "\u0153", "\u014D")
                     // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
-                    .replaceKeyOfLabel(Nordic.ROW1_11, key("\u00E5"))
+                    .replaceKeyOfLabel(Nordic.ROW1_11, "\u00E5")
                     // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
                     // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
                     .replaceKeyOfLabel(Nordic.ROW2_10, key("\u00F8", moreKey("\u00F6")))
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPolish.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPolish.java
index 7d8f629..04f88c3 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPolish.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPolish.java
@@ -58,8 +58,7 @@
                     // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
                     // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
                     .setMoreKeysOf("e",
-                            "3", "\u0119", "\u00E8", "\u00E9", "\u00EA", "\u00EB", "\u0117",
-                            "\u0113")
+                            "\u0119", "\u00E8", "\u00E9", "\u00EA", "\u00EB", "\u0117", "\u0113")
                     // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
                     // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
                     // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
@@ -69,8 +68,8 @@
                     // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
                     // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
                     .setMoreKeysOf("o",
-                            "9", "\u00F3", "\u00F6", "\u00F4", "\u00F2", "\u00F5", "\u0153",
-                            "\u00F8", "\u014D")
+                            "\u00F3", "\u00F6", "\u00F4", "\u00F2", "\u00F5", "\u0153", "\u00F8",
+                            "\u014D")
                     // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK
                     // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
                     // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPortugueseBR.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPortugueseBR.java
index 00ee698..8a984a7 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPortugueseBR.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPortugueseBR.java
@@ -19,9 +19,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer;
 import com.android.inputmethod.keyboard.layout.Qwerty;
-import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
 
 import java.util.Locale;
 
@@ -31,69 +29,8 @@
 @SmallTest
 public class TestsPortugueseBR extends LayoutTestsBase {
     private static final Locale LOCALE = new Locale("pt", "BR");
-    private static final LayoutBase LAYOUT = new Qwerty(new PortugueseBRCustomizer(LOCALE));
+    private static final LayoutBase LAYOUT = new Qwerty(new PortugueseCustomizer(LOCALE));
 
     @Override
     LayoutBase getLayout() { return LAYOUT; }
-
-    // TODO: Make this as generic Portuguese customizer.
-    static class PortugueseBRCustomizer extends LayoutCustomizer {
-        public PortugueseBRCustomizer(final Locale locale) { super(locale); }
-
-        @Override
-        public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
-            return builder
-                    // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
-                    // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
-                    // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
-                    // 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
-                    // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
-                    .setMoreKeysOf("e",
-                            "3", "\u00E9", "\u00EA", "\u00E8", "\u0119", "\u0117", "\u0113",
-                            "\u00EB")
-                    // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
-                    // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
-                    // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
-                    // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
-                    // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
-                    .setMoreKeysOf("u", "7", "\u00FA", "\u00FC", "\u00F9", "\u00FB", "\u016B")
-                    // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
-                    // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
-                    // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
-                    // 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", "8", "\u00ED", "\u00EE", "\u00EC", "\u00EF", "\u012F",
-                            "\u012B")
-                    // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
-                    // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
-                    // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
-                    // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
-                    // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
-                    // 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",
-                            "9", "\u00F3", "\u00F5", "\u00F4", "\u00F2", "\u00F6", "\u0153",
-                            "\u00F8", "\u014D", "\u00BA")
-                    // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
-                    // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE
-                    // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
-                    // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
-                    // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
-                    // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
-                    // U+00E6: "æ" LATIN SMALL LETTER AE
-                    // U+00AA: "ª" FEMININE ORDINAL INDICATOR
-                    .setMoreKeysOf("a",
-                            "\u00E1", "\u00E3", "\u00E0", "\u00E2", "\u00E4", "\u00E5", "\u00E6",
-                            "\u00AA")
-                    // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
-                    // U+010D: "č" LATIN SMALL LETTER C WITH CARON
-                    // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
-                    .setMoreKeysOf("c", "\u00E7", "\u010D", "\u0107");
-        }
-    }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPortuguesePT.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPortuguesePT.java
index 836542e..e15e811 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPortuguesePT.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPortuguesePT.java
@@ -19,9 +19,9 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.EuroLayoutCustomizer;
+import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer;
 import com.android.inputmethod.keyboard.layout.Qwerty;
-import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
 
 import java.util.Locale;
 
@@ -36,17 +36,20 @@
     @Override
     LayoutBase getLayout() { return LAYOUT; }
 
-    private static class PortuguesePTCustomizer extends EuroLayoutCustomizer {
-        private final PortugueseBRCustomizer mPortugueseCustomizer;
+    private static class PortuguesePTCustomizer extends PortugueseCustomizer {
+        private final EuroCustomizer mEuroCustomizer;
 
         public PortuguesePTCustomizer(final Locale locale) {
             super(locale);
-            mPortugueseCustomizer = new PortugueseBRCustomizer(locale);
+            mEuroCustomizer = new EuroCustomizer(locale);
         }
 
         @Override
-        public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
-            return mPortugueseCustomizer.setAccentedLetters(builder);
+        public ExpectedKey getCurrencyKey() { return mEuroCustomizer.getCurrencyKey(); }
+
+        @Override
+        public ExpectedKey[] getOtherCurrencyKeys() {
+            return mEuroCustomizer.getOtherCurrencyKeys();
         }
     }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsRomanian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsRomanian.java
index 59b328d..0207f1c 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsRomanian.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsRomanian.java
@@ -51,15 +51,14 @@
         public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
             return builder
                     // U+021B: "ț" LATIN SMALL LETTER T WITH COMMA BELOW
-                    .setMoreKeysOf("t", "5", "\u021B")
+                    .setMoreKeysOf("t", "\u021B")
                     // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
                     // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
                     // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
                     // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
                     // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
                     // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
-                    .setMoreKeysOf("i", "8", "\u00EE", "\u00EF", "\u00EC", "\u00ED", "\u012F",
-                            "\u012B")
+                    .setMoreKeysOf("i", "\u00EE", "\u00EF", "\u00EC", "\u00ED", "\u012F", "\u012B")
                     // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
                     // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE
                     // U+0103: "ă" LATIN SMALL LETTER A WITH BREVE
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsRussian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsRussian.java
index 14f9501..9919207 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsRussian.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsRussian.java
@@ -52,15 +52,15 @@
             return builder
                     // U+0435: "е" CYRILLIC SMALL LETTER IE
                     // U+0451: "ё" CYRILLIC SMALL LETTER IO
-                    .setMoreKeysOf("\u0435", "5", "\u0451")
+                    .setMoreKeysOf("\u0435", "\u0451")
                     // U+0449: "щ" CYRILLIC SMALL LETTER SHCHA
-                    .replaceKeyOfLabel(EastSlavic.ROW1_9, key("\u0449", moreKey("9")))
+                    .replaceKeyOfLabel(EastSlavic.ROW1_9, key("\u0449", additionalMoreKey("9")))
                     // U+044B: "ы" CYRILLIC SMALL LETTER YERU
-                    .replaceKeyOfLabel(EastSlavic.ROW2_2, key("\u044B"))
+                    .replaceKeyOfLabel(EastSlavic.ROW2_2, "\u044B")
                     // U+044D: "э" CYRILLIC SMALL LETTER E
-                    .replaceKeyOfLabel(EastSlavic.ROW2_11, key("\u044D"))
+                    .replaceKeyOfLabel(EastSlavic.ROW2_11, "\u044D")
                     // U+0438: "и" CYRILLIC SMALL LETTER I
-                    .replaceKeyOfLabel(EastSlavic.ROW3_5, key("\u0438"))
+                    .replaceKeyOfLabel(EastSlavic.ROW3_5, "\u0438")
                     // U+044C: "ь" CYRILLIC SMALL LETTER SOFT SIGN
                     // U+044A: "ъ" CYRILLIC SMALL LETTER HARD SIGN
                     .setMoreKeysOf("\u044C", "\u044A");
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbian.java
index 119ea14..41f1690 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbian.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbian.java
@@ -58,18 +58,18 @@
             return builder
                     // U+0435: "е" CYRILLIC SMALL LETTER IE
                     // U+0450: "ѐ" CYRILLIC SMALL LETTER IE WITH GRAVE
-                    .setMoreKeysOf("\u0435", "3", "\u0450")
+                    .setMoreKeysOf("\u0435", "\u0450")
                     // U+0437: "з" CYRILLIC SMALL LETTER ZE
-                    .replaceKeyOfLabel(SouthSlavic.ROW1_6, key("\u0437", moreKey("6")))
+                    .replaceKeyOfLabel(SouthSlavic.ROW1_6, key("\u0437", additionalMoreKey("6")))
                     // U+0438: "и" CYRILLIC SMALL LETTER I
                     // U+045D: "ѝ" CYRILLIC SMALL LETTER I WITH GRAVE
-                    .setMoreKeysOf("\u0438", "8", "\u045D")
+                    .setMoreKeysOf("\u0438", "\u045D")
                     // U+045B: "ћ" CYRILLIC SMALL LETTER TSHE
-                    .replaceKeyOfLabel(SouthSlavic.ROW2_11, key("\u045B"))
+                    .replaceKeyOfLabel(SouthSlavic.ROW2_11, "\u045B")
                     // U+0455: "ѕ" CYRILLIC SMALL LETTER DZE
-                    .replaceKeyOfLabel(SouthSlavic.ROW3_1, key("\u0455"))
+                    .replaceKeyOfLabel(SouthSlavic.ROW3_1, "\u0455")
                     // U+0452: "ђ" CYRILLIC SMALL LETTER DJE
-                    .replaceKeyOfLabel(SouthSlavic.ROW3_8, key("\u0452"));
+                    .replaceKeyOfLabel(SouthSlavic.ROW3_8, "\u0452");
         }
     }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSlovak.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSlovak.java
index 3d7825b..bdaf0ca 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSlovak.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSlovak.java
@@ -19,7 +19,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.EuroLayoutCustomizer;
+import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer;
 import com.android.inputmethod.keyboard.layout.Qwerty;
 import com.android.inputmethod.keyboard.layout.Symbols;
 import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
@@ -38,7 +38,7 @@
     @Override
     LayoutBase getLayout() { return LAYOUT; }
 
-    private static class SlovakCustomizer extends EuroLayoutCustomizer {
+    private static class SlovakCustomizer extends EuroCustomizer {
         public SlovakCustomizer(final Locale locale) { super(locale); }
 
         @Override
@@ -65,18 +65,18 @@
                     // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
                     // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK
                     .setMoreKeysOf("e",
-                            "3", "\u00E9", "\u011B", "\u0113", "\u0117", "\u00E8", "\u00EA",
-                            "\u00EB", "\u0119")
+                            "\u00E9", "\u011B", "\u0113", "\u0117", "\u00E8", "\u00EA", "\u00EB",
+                            "\u0119")
                     // U+0155: "ŕ" LATIN SMALL LETTER R WITH ACUTE
                     // U+0159: "ř" LATIN SMALL LETTER R WITH CARON
                     // U+0157: "ŗ" LATIN SMALL LETTER R WITH CEDILLA
-                    .setMoreKeysOf("r", "4", "\u0155", "\u0159", "\u0157")
+                    .setMoreKeysOf("r", "\u0155", "\u0159", "\u0157")
                     // U+0165: "ť" LATIN SMALL LETTER T WITH CARON
                     // U+0163: "ţ" LATIN SMALL LETTER T WITH CEDILLA
-                    .setMoreKeysOf("t", "5", "\u0165", "\u0163")
+                    .setMoreKeysOf("t", "\u0165", "\u0163")
                     // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
                     // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
-                    .setMoreKeysOf("y", "6", "\u00FD", "\u00FF")
+                    .setMoreKeysOf("y", "\u00FD", "\u00FF")
                     // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
                     // U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE
                     // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
@@ -86,8 +86,8 @@
                     // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
                     // U+0171: "ű" LATIN SMALL LETTER U WITH DOUBLE ACUTE
                     .setMoreKeysOf("u",
-                            "7", "\u00FA", "\u016F", "\u00FC", "\u016B", "\u0173", "\u00F9",
-                            "\u00FB", "\u0171")
+                            "\u00FA", "\u016F", "\u00FC", "\u016B", "\u0173", "\u00F9", "\u00FB",
+                            "\u0171")
                     // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
                     // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
                     // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
@@ -96,8 +96,7 @@
                     // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
                     // U+0131: "ı" LATIN SMALL LETTER DOTLESS I
                     .setMoreKeysOf("i",
-                            "8", "\u00ED", "\u012B", "\u012F", "\u00EC", "\u00EE", "\u00EF",
-                            "\u0131")
+                            "\u00ED", "\u012B", "\u012F", "\u00EC", "\u00EE", "\u00EF", "\u0131")
                     // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
                     // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
                     // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
@@ -107,8 +106,8 @@
                     // U+0151: "ő" LATIN SMALL LETTER O WITH DOUBLE ACUTE
                     // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
                     .setMoreKeysOf("o",
-                            "9", "\u00F4", "\u00F3", "\u00F6", "\u00F2", "\u00F5", "\u0153",
-                            "\u0151", "\u00F8")
+                            "\u00F4", "\u00F3", "\u00F6", "\u00F2", "\u00F5", "\u0153", "\u0151",
+                            "\u00F8")
                     // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
                     // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
                     // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSlovenian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSlovenian.java
index 88a23ba..cdb1bee 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSlovenian.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSlovenian.java
@@ -19,7 +19,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.EuroLayoutCustomizer;
+import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer;
 import com.android.inputmethod.keyboard.layout.Qwerty;
 import com.android.inputmethod.keyboard.layout.Symbols;
 import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
@@ -38,7 +38,7 @@
     @Override
     LayoutBase getLayout() { return LAYOUT; }
 
-    private static class SlovenianCustomizer extends EuroLayoutCustomizer {
+    private static class SlovenianCustomizer extends EuroCustomizer {
         public SlovenianCustomizer(final Locale locale) { super(locale); }
 
         @Override
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSpanish.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSpanish.java
index cc5a64c..12e8676 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSpanish.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSpanish.java
@@ -19,11 +19,9 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.EuroLayoutCustomizer;
+import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer;
 import com.android.inputmethod.keyboard.layout.Spanish;
 import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
-import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
-import com.android.inputmethod.keyboard.layout.tests.TestsSpanishUS.SpanishUSCustomizer;
 
 import java.util.Locale;
 
@@ -38,22 +36,20 @@
     @Override
     LayoutBase getLayout() { return LAYOUT; }
 
-    private static class SpanishESCustomizer extends EuroLayoutCustomizer {
-        private final SpanishUSCustomizer mSpanishUSCustomizer;
+    private static class SpanishESCustomizer extends SpanishCustomizer {
+        private final EuroCustomizer mEuroCustomizer;
 
         public SpanishESCustomizer(final Locale locale) {
             super(locale);
-            mSpanishUSCustomizer = new SpanishUSCustomizer(locale);
+            mEuroCustomizer = new EuroCustomizer(locale);
         }
 
         @Override
-        public ExpectedKey[] getPunctuationMoreKeys(final boolean isPhone) {
-            return mSpanishUSCustomizer.getPunctuationMoreKeys(isPhone);
-        }
+        public ExpectedKey getCurrencyKey() { return mEuroCustomizer.getCurrencyKey(); }
 
         @Override
-        public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
-            return mSpanishUSCustomizer.setAccentedLetters(builder);
+        public ExpectedKey[] getOtherCurrencyKeys() {
+            return mEuroCustomizer.getOtherCurrencyKeys();
         }
     }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSpanishUS.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSpanishUS.java
index 517db9d..c3ac0a0 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSpanishUS.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSpanishUS.java
@@ -19,10 +19,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer;
 import com.android.inputmethod.keyboard.layout.Spanish;
-import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
-import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
 
 import java.util.Locale;
 
@@ -32,89 +29,8 @@
 @SmallTest
 public class TestsSpanishUS extends TestsSpanish {
     private static final Locale LOCALE = new Locale("es", "US");
-    private static final LayoutBase LAYOUT = new Spanish(new SpanishUSCustomizer(LOCALE));
+    private static final LayoutBase LAYOUT = new Spanish(new SpanishCustomizer(LOCALE));
 
     @Override
     LayoutBase getLayout() { return LAYOUT; }
-
-    // Make this as generic Spanish customizer.
-    static class SpanishUSCustomizer extends LayoutCustomizer {
-        public SpanishUSCustomizer(final Locale locale) { super(locale); }
-
-        @Override
-        public ExpectedKey[] getPunctuationMoreKeys(final boolean isPhone) {
-            return isPhone ? PHONE_PUNCTUATION_MORE_KEYS
-                    : LayoutBase.TABLET_PUNCTUATION_MORE_KEYS;
-        }
-
-        // Punctuation more keys for phone form factor.
-        private static final ExpectedKey[] PHONE_PUNCTUATION_MORE_KEYS = joinKeys(
-                // U+00A1: "¡" INVERTED EXCLAMATION MARK
-                // U+00BF: "¿" INVERTED QUESTION MARK
-                "\u00A1", ";", "/", "(", ")", "#", "!", ",", "?",
-                "\u00BF", "&", "%", "+", "\"", "-", ":", "'", "@");
-
-        @Override
-        public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
-            return builder
-                    // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
-                    // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
-                    // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
-                    // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
-                    // 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",
-                            "3", "\u00E9", "\u00E8", "\u00EB", "\u00EA", "\u0119", "\u0117",
-                            "\u0113")
-                    // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
-                    // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
-                    // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
-                    // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
-                    // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
-                    .setMoreKeysOf("u", "7", "\u00FA", "\u00FC", "\u00F9", "\u00FB", "\u016B")
-                    // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
-                    // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
-                    // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
-                    // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
-                    // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
-                    // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
-                    .setMoreKeysOf("i", "8", "\u00ED", "\u00EF", "\u00EC", "\u00EE", "\u012F",
-                            "\u012B")
-                    // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
-                    // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
-                    // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
-                    // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
-                    // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
-                    // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
-                    // U+0153: "œ" LATIN SMALL LIGATURE OE
-                    // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
-                    // U+00BA: "º" MASCULINE ORDINAL INDICATOR
-                    .setMoreKeysOf("o",
-                            "9", "\u00F3", "\u00F2", "\u00F6", "\u00F4", "\u00F5", "\u00F8",
-                            "\u0153", "\u014D", "\u00BA")
-                    // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
-                    // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
-                    // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
-                    // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
-                    // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE
-                    // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
-                    // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK
-                    // U+00E6: "æ" LATIN SMALL LETTER AE
-                    // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON
-                    // U+00AA: "ª" FEMININE ORDINAL INDICATOR
-                    .setMoreKeysOf("a",
-                            "\u00E1", "\u00E0", "\u00E4", "\u00E2", "\u00E3", "\u00E5", "\u0105",
-                            "\u00E6", "\u0101", "\u00AA")
-                    // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
-                    .replaceKeyOfLabel(Spanish.ROW2_10, key("\u00F1"))
-                    // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
-                    // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
-                    // U+010D: "č" LATIN SMALL LETTER C WITH CARON
-                    .setMoreKeysOf("c", "\u00E7", "\u0107", "\u010D")
-                    // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
-                    // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
-                    .setMoreKeysOf("n", "\u00F1", "\u0144");
-        }
-    }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSwahili.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSwahili.java
index 49e1912..13b9741 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSwahili.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSwahili.java
@@ -47,19 +47,19 @@
                     // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
                     // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
                     // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
-                    .setMoreKeysOf("e", "3", "\u00E8", "\u00E9", "\u00EA", "\u00EB", "\u0113")
+                    .setMoreKeysOf("e", "\u00E8", "\u00E9", "\u00EA", "\u00EB", "\u0113")
                     // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
                     // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
                     // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
                     // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
                     // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
-                    .setMoreKeysOf("u", "7", "\u00FB", "\u00FC", "\u00F9", "\u00FA", "\u016B")
+                    .setMoreKeysOf("u", "\u00FB", "\u00FC", "\u00F9", "\u00FA", "\u016B")
                     // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
                     // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
                     // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
                     // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
                     // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
-                    .setMoreKeysOf("i", "8", "\u00EE", "\u00EF", "\u00ED", "\u012B", "\u00EC")
+                    .setMoreKeysOf("i", "\u00EE", "\u00EF", "\u00ED", "\u012B", "\u00EC")
                     // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
                     // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
                     // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
@@ -69,8 +69,8 @@
                     // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
                     // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
                     .setMoreKeysOf("o",
-                            "9", "\u00F4", "\u00F6", "\u00F2", "\u00F3", "\u0153", "\u00F8",
-                            "\u014D", "\u00F5")
+                            "\u00F4", "\u00F6", "\u00F2", "\u00F3", "\u0153", "\u00F8", "\u014D",
+                            "\u00F5")
                     // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
                     // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
                     // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSwedish.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSwedish.java
index 14155cb..9b58914 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSwedish.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSwedish.java
@@ -19,7 +19,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.EuroLayoutCustomizer;
+import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer;
 import com.android.inputmethod.keyboard.layout.Nordic;
 import com.android.inputmethod.keyboard.layout.Symbols;
 import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
@@ -38,7 +38,7 @@
     @Override
     LayoutBase getLayout() { return LAYOUT; }
 
-    private static class SwedishCustomizer extends EuroLayoutCustomizer {
+    private static class SwedishCustomizer extends EuroCustomizer {
         public SwedishCustomizer(final Locale locale) { super(locale); }
 
         @Override
@@ -55,39 +55,39 @@
                     // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
                     // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
                     // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK
-                    .setMoreKeysOf("e", "3", "\u00E9", "\u00E8", "\u00EA", "\u00EB", "\u0119")
+                    .setMoreKeysOf("e", "\u00E9", "\u00E8", "\u00EA", "\u00EB", "\u0119")
                     // U+0159: "ř" LATIN SMALL LETTER R WITH CARON
-                    .setMoreKeysOf("r", "4", "\u0159")
+                    .setMoreKeysOf("r", "\u0159")
                     // U+0165: "ť" LATIN SMALL LETTER T WITH CARON
                     // U+00FE: "þ" LATIN SMALL LETTER THORN
-                    .setMoreKeysOf("t", "5", "\u0165", "\u00FE")
+                    .setMoreKeysOf("t", "\u0165", "\u00FE")
                     // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
                     // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
-                    .setMoreKeysOf("y", "6", "\u00FD", "\u00FF")
+                    .setMoreKeysOf("y", "\u00FD", "\u00FF")
                     // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
                     // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
                     // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
                     // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
                     // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
-                    .setMoreKeysOf("u", "7", "\u00FC", "\u00FA", "\u00F9", "\u00FB", "\u016B")
+                    .setMoreKeysOf("u", "\u00FC", "\u00FA", "\u00F9", "\u00FB", "\u016B")
                     // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
                     // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
                     // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
                     // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
-                    .setMoreKeysOf("i", "8", "\u00ED", "\u00EC", "\u00EE", "\u00EF")
+                    .setMoreKeysOf("i", "\u00ED", "\u00EC", "\u00EE", "\u00EF")
                     // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
                     // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
                     // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
                     // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
                     // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
-                    .setMoreKeysOf("o", "9", "\u00F3", "\u00F2", "\u00F4", "\u00F5", "\u014D")
+                    .setMoreKeysOf("o", "\u00F3", "\u00F2", "\u00F4", "\u00F5", "\u014D")
                     // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
-                    .replaceKeyOfLabel(Nordic.ROW1_11, key("\u00E5"))
+                    .replaceKeyOfLabel(Nordic.ROW1_11, "\u00E5")
                     // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
                     // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
                     // U+0153: "œ" LATIN SMALL LIGATURE OE
-                    .replaceKeyOfLabel(Nordic.ROW2_10, key("\u00F6",
-                            moreKey("\u00F8"), moreKey("\u0153")))
+                    .replaceKeyOfLabel(Nordic.ROW2_10,
+                            key("\u00F6", joinMoreKeys("\u00F8", "\u0153")))
                     // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
                     // U+00E6: "æ" LATIN SMALL LETTER AE
                     .replaceKeyOfLabel(Nordic.ROW2_11, key("\u00E4", moreKey("\u00E6")))
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTagalog.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTagalog.java
index 72e435a..38d5364 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTagalog.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTagalog.java
@@ -19,10 +19,8 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer;
 import com.android.inputmethod.keyboard.layout.Spanish;
-import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
-import com.android.inputmethod.keyboard.layout.tests.TestsSpanishUS.SpanishUSCustomizer;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
 
 import java.util.Locale;
 
@@ -37,17 +35,16 @@
     @Override
     LayoutBase getLayout() { return LAYOUT; }
 
-    private static class TagalogCustomizer extends LayoutCustomizer {
-        private final SpanishUSCustomizer mSpanishUSCustomizer;
+    private static class TagalogCustomizer extends SpanishCustomizer {
 
         public TagalogCustomizer(final Locale locale) {
             super(locale);
-            mSpanishUSCustomizer = new SpanishUSCustomizer(locale);
         }
 
         @Override
-        public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
-            return mSpanishUSCustomizer.setAccentedLetters(builder);
+        public ExpectedKey[] getPunctuationMoreKeys(final boolean isPhone) {
+            return isPhone ? LayoutBase.PHONE_PUNCTUATION_MORE_KEYS
+                    : LayoutBase.TABLET_PUNCTUATION_MORE_KEYS;
         }
     }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTurkish.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTurkish.java
index ab67ae9..b35f885 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTurkish.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTurkish.java
@@ -19,7 +19,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.LayoutBase;
-import com.android.inputmethod.keyboard.layout.LayoutBase.EuroLayoutCustomizer;
+import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer;
 import com.android.inputmethod.keyboard.layout.Qwerty;
 import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
 
@@ -36,7 +36,7 @@
     @Override
     LayoutBase getLayout() { return LAYOUT; }
 
-    private static class TurkishCustomizer extends EuroLayoutCustomizer {
+    private static class TurkishCustomizer extends EuroCustomizer {
         public TurkishCustomizer(final Locale locale) { super(locale); }
 
         @Override
@@ -47,7 +47,7 @@
                     // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
                     // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
                     // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
-                    .setMoreKeysOf("u", "7", "\u00FC", "\u00FB", "\u00F9", "\u00FA", "\u016B")
+                    .setMoreKeysOf("u", "\u00FC", "\u00FB", "\u00F9", "\u00FA", "\u016B")
                     // U+0131: "ı" LATIN SMALL LETTER DOTLESS I
                     // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
                     // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
@@ -55,7 +55,7 @@
                     // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
                     // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
                     // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
-                    .setMoreKeysOf("i", "8",
+                    .setMoreKeysOf("i",
                             "\u0131", "\u00EE", "\u00EF", "\u00EC", "\u00ED", "\u012F", "\u012B")
                     // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
                     // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
@@ -66,8 +66,8 @@
                     // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
                     // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
                     .setMoreKeysOf("o",
-                            "9", "\u00F6", "\u00F4", "\u0153", "\u00F2", "\u00F3", "\u00F5",
-                            "\u00F8", "\u014D")
+                            "\u00F6", "\u00F4", "\u0153", "\u00F2", "\u00F3", "\u00F5", "\u00F8",
+                            "\u014D")
                     // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
                     .setMoreKeysOf("a", "\u00E2")
                     // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsUkrainian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsUkrainian.java
index 27893fe..a6bcacc 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsUkrainian.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsUkrainian.java
@@ -65,16 +65,16 @@
             return builder
                     // U+0433: "г" CYRILLIC SMALL LETTER GHE
                     // U+0491: "ґ" CYRILLIC SMALL LETTER GHE WITH UPTURN
-                    .setMoreKeysOf("\u0433", "7", "\u0491")
+                    .setMoreKeysOf("\u0433", "\u0491")
                     // U+0449: "щ" CYRILLIC SMALL LETTER SHCHA
-                    .replaceKeyOfLabel(EastSlavic.ROW1_9, key("\u0449", moreKey("9")))
+                    .replaceKeyOfLabel(EastSlavic.ROW1_9, key("\u0449", additionalMoreKey("9")))
                     // U+0456: "і" CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
                     // U+0457: "ї" CYRILLIC SMALL LETTER YI
                     .replaceKeyOfLabel(EastSlavic.ROW2_2, key("\u0456", moreKey("\u0457")))
                     // U+0454: "є" CYRILLIC SMALL LETTER UKRAINIAN IE
-                    .replaceKeyOfLabel(EastSlavic.ROW2_11, key("\u0454"))
+                    .replaceKeyOfLabel(EastSlavic.ROW2_11, "\u0454")
                     // U+0438: "и" CYRILLIC SMALL LETTER I
-                    .replaceKeyOfLabel(EastSlavic.ROW3_5, key("\u0438"))
+                    .replaceKeyOfLabel(EastSlavic.ROW3_5, "\u0438")
                     // U+044C: "ь" CYRILLIC SMALL LETTER SOFT SIGN
                     // U+044A: "ъ" CYRILLIC SMALL LETTER HARD SIGN
                     .setMoreKeysOf("\u044C", "\u044A");
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsVietnamese.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsVietnamese.java
index 96ae38a..83d86ac 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsVietnamese.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsVietnamese.java
@@ -71,14 +71,14 @@
                     // U+1EC5: "ễ" LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE
                     // U+1EC7: "ệ" LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW
                     .setMoreKeysOf("e",
-                            "3", "\u00E8", "\u00E9", "\u1EBB", "\u1EBD", "\u1EB9", "\u00EA",
-                            "\u1EC1", "\u1EBF", "\u1EC3", "\u1EC5", "\u1EC7")
+                            "\u00E8", "\u00E9", "\u1EBB", "\u1EBD", "\u1EB9", "\u00EA", "\u1EC1",
+                            "\u1EBF", "\u1EC3", "\u1EC5", "\u1EC7")
                     // U+1EF3: "ỳ" LATIN SMALL LETTER Y WITH GRAVE
                     // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
                     // U+1EF7: "ỷ" LATIN SMALL LETTER Y WITH HOOK ABOVE
                     // U+1EF9: "ỹ" LATIN SMALL LETTER Y WITH TILDE
                     // U+1EF5: "ỵ" LATIN SMALL LETTER Y WITH DOT BELOW
-                    .setMoreKeysOf("y", "6", "\u1EF3", "\u00FD", "\u1EF7", "\u1EF9", "\u1EF5")
+                    .setMoreKeysOf("y", "\u1EF3", "\u00FD", "\u1EF7", "\u1EF9", "\u1EF5")
                     // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
                     // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
                     // U+1EE7: "ủ" LATIN SMALL LETTER U WITH HOOK ABOVE
@@ -91,14 +91,14 @@
                     // U+1EEF: "ữ" LATIN SMALL LETTER U WITH HORN AND TILDE
                     // U+1EF1: "ự" LATIN SMALL LETTER U WITH HORN AND DOT BELOW
                     .setMoreKeysOf("u",
-                            "7", "\u00F9", "\u00FA", "\u1EE7", "\u0169", "\u1EE5", "\u01B0",
-                            "\u1EEB", "\u1EE9", "\u1EED", "\u1EEF", "\u1EF1")
+                            "\u00F9", "\u00FA", "\u1EE7", "\u0169", "\u1EE5", "\u01B0", "\u1EEB",
+                            "\u1EE9", "\u1EED", "\u1EEF", "\u1EF1")
                     // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
                     // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
                     // U+1EC9: "ỉ" LATIN SMALL LETTER I WITH HOOK ABOVE
                     // U+0129: "ĩ" LATIN SMALL LETTER I WITH TILDE
                     // U+1ECB: "ị" LATIN SMALL LETTER I WITH DOT BELOW
-                    .setMoreKeysOf("i", "8", "\u00EC", "\u00ED", "\u1EC9", "\u0129", "\u1ECB")
+                    .setMoreKeysOf("i", "\u00EC", "\u00ED", "\u1EC9", "\u0129", "\u1ECB")
                     // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
                     // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
                     // U+1ECF: "ỏ" LATIN SMALL LETTER O WITH HOOK ABOVE
@@ -117,9 +117,9 @@
                     // U+1EE1: "ỡ" LATIN SMALL LETTER O WITH HORN AND TILDE
                     // U+1EE3: "ợ" LATIN SMALL LETTER O WITH HORN AND DOT BELOW
                     .setMoreKeysOf("o",
-                            "9", "\u00F2", "\u00F3", "\u1ECF", "\u00F5", "\u1ECD", "\u00F4",
-                            "\u1ED3", "\u1ED1", "\u1ED5", "\u1ED7", "\u1ED9", "\u01A1", "\u1EDD",
-                            "\u1EDB", "\u1EDF", "\u1EE1", "\u1EE3")
+                            "\u00F2", "\u00F3", "\u1ECF", "\u00F5", "\u1ECD", "\u00F4", "\u1ED3",
+                            "\u1ED1", "\u1ED5", "\u1ED7", "\u1ED9", "\u01A1", "\u1EDD", "\u1EDB",
+                            "\u1EDF", "\u1EE1", "\u1EE3")
                     // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
                     // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
                     // U+1EA3: "ả" LATIN SMALL LETTER A WITH HOOK ABOVE
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsZulu.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsZulu.java
index 04e89be..e048e92 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsZulu.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsZulu.java
@@ -29,7 +29,7 @@
 @SmallTest
 public final class TestsZulu extends TestsEnglishUS {
     private static final Locale LOCALE = new Locale("zu");
-    private static final LayoutBase LAYOUT = new Qwerty(new EnglishUSCustomizer(LOCALE));
+    private static final LayoutBase LAYOUT = new Qwerty(new EnglishCustomizer(LOCALE));
 
     @Override
     LayoutBase getLayout() { return LAYOUT; }
diff --git a/tools/dicttool/Android.mk b/tools/dicttool/Android.mk
index 948c03b..0e9c14e 100644
--- a/tools/dicttool/Android.mk
+++ b/tools/dicttool/Android.mk
@@ -35,6 +35,7 @@
 # a significant part of the dependencies are mocked in the compat/ directory, with empty or
 # nearly-empty implementations, for parts that we don't use in Dicttool.
 LATINIME_SRCS_FOR_DICTTOOL := \
+        event/Combiner.java \
         event/Event.java \
         latin/BinaryDictionary.java \
         latin/DicTraverseSession.java \
diff --git a/java/src/com/android/inputmethod/event/EventDecoderSpec.java b/tools/dicttool/compat/com/android/inputmethod/event/CombinerChain.java
similarity index 64%
rename from java/src/com/android/inputmethod/event/EventDecoderSpec.java
rename to tools/dicttool/compat/com/android/inputmethod/event/CombinerChain.java
index 303b4b4..66ad60c 100644
--- a/java/src/com/android/inputmethod/event/EventDecoderSpec.java
+++ b/tools/dicttool/compat/com/android/inputmethod/event/CombinerChain.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 The Android Open Source Project
+ * 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.
@@ -16,11 +16,11 @@
 
 package com.android.inputmethod.event;
 
-/**
- * Class describing a decoder chain. This will depend on the language and the input medium (soft
- * or hard keyboard for example).
- */
-public class EventDecoderSpec {
-    public EventDecoderSpec() {
-    }
+import com.android.inputmethod.latin.utils.CollectionUtils;
+
+import java.util.ArrayList;
+
+public class CombinerChain {
+    public CombinerChain(final Combiner... combinerList) {}
+    public void processEvent(final ArrayList<Event> previousEvents, final Event newEvent) {}
 }
diff --git a/tools/make-keyboard-text/res/values-ar/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-ar/donottranslate-more-keys.xml
index 4bbe343..dcff29a 100644
--- a/tools/make-keyboard-text/res/values-ar/donottranslate-more-keys.xml
+++ b/tools/make-keyboard-text/res/values-ar/donottranslate-more-keys.xml
@@ -64,7 +64,6 @@
     <string name="additional_more_keys_for_symbols_0">0,&#x066B;,&#x066C;</string>
     <!-- U+060C: "،" ARABIC COMMA -->
     <string name="keylabel_for_comma">&#x060C;</string>
-    <string name="more_keys_for_comma">"\\,"</string>
     <!-- U+0651: "ّ" ARABIC SHADDA -->
     <string name="keyhintlabel_for_period">&#x0651;</string>
     <string name="more_keys_for_period">!text/more_keys_for_arabic_diacritics</string>
@@ -85,7 +84,6 @@
     <string name="keylabel_for_tablet_comma">"&#x060C;"</string>
     <string name="keyhintlabel_for_tablet_comma">"&#x061F;"</string>
     <string name="more_keys_for_tablet_comma">"!fixedColumnOrder!4,:,!,&#x061F;,&#x061B;,-,/,\",\'"</string>
-    <string name="more_keys_for_punctuation">"!fixedColumnOrder!8,\",\',#,-,:,!,&#x060C;,&#x061F;,@,&amp;,\\%,+,&#x061B;,/,(|),)|("</string>
     <!-- U+266A: "♪" EIGHTH NOTE -->
     <string name="more_keys_for_bullet">&#x266A;</string>
     <!-- U+2605: "★" BLACK STAR
diff --git a/tools/make-keyboard-text/res/values-ca/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-ca/donottranslate-more-keys.xml
index 8865a60..574be24 100644
--- a/tools/make-keyboard-text/res/values-ca/donottranslate-more-keys.xml
+++ b/tools/make-keyboard-text/res/values-ca/donottranslate-more-keys.xml
@@ -71,8 +71,8 @@
          U+0142: "ł" LATIN SMALL LETTER L WITH STROKE -->
     <string name="more_keys_for_l">l&#x00B7;l,&#x0142;</string>
     <!-- U+00B7: "·" MIDDLE DOT -->
-    <string name="more_keys_for_punctuation">"!fixedColumnOrder!9,;,/,(,),#,&#x00B7;,!,\\,,?,&amp;,\\%,+,\",-,:,',@"</string>
-    <string name="more_keys_for_tablet_punctuation">"!fixedColumnOrder!8,;,/,(,),#,&#x00B7;,',\\,,&amp;,\\%,+,\",-,:,@"</string>
+    <string name="more_keys_for_punctuation">"!autoColumnOrder!9,\\,,?,!,&#x00B7;,#,),(,/,;,',@,:,-,\",+,\\%,&amp;"</string>
+    <string name="more_keys_for_tablet_punctuation">"!autoColumnOrder!8,\\,,',&#x00B7;,#,),(,/,;,@,:,-,\",+,\\%,&amp;"</string>
     <!-- U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA -->
     <string name="keylabel_for_spanish_row2_10">&#x00E7;</string>
 </resources>
diff --git a/tools/make-keyboard-text/res/values-es/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-es/donottranslate-more-keys.xml
index 453d5c1..1737502 100644
--- a/tools/make-keyboard-text/res/values-es/donottranslate-more-keys.xml
+++ b/tools/make-keyboard-text/res/values-es/donottranslate-more-keys.xml
@@ -69,5 +69,5 @@
     <string name="more_keys_for_c">&#x00E7;,&#x0107;,&#x010D;</string>
     <!-- U+00A1: "¡" INVERTED EXCLAMATION MARK
          U+00BF: "¿" INVERTED QUESTION MARK -->
-    <string name="more_keys_for_punctuation">"!fixedColumnOrder!9,&#x00A1;,;,/,(,),#,!,\\,,?,&#x00BF;,&amp;,\\%,+,\",-,:,',@"</string>
-</resources>
+    <string name="more_keys_for_punctuation">"!autoColumnOrder!9,\\,,?,!,#,),(,/,;,&#x00A1;,',@,:,-,\",+,\\%,&amp;,&#x00BF;"</string>
+ </resources>
diff --git a/tools/make-keyboard-text/res/values-eu-rES/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-eu-rES/donottranslate-more-keys.xml
new file mode 100644
index 0000000..83dbe0e
--- /dev/null
+++ b/tools/make-keyboard-text/res/values-eu-rES/donottranslate-more-keys.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** 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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
+         U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
+         U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
+         U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
+         U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE
+         U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
+         U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK
+         U+00E6: "æ" LATIN SMALL LETTER AE
+         U+0101: "ā" LATIN SMALL LETTER A WITH MACRON
+         U+00AA: "ª" FEMININE ORDINAL INDICATOR -->
+    <string name="more_keys_for_a">&#x00E1;,&#x00E0;,&#x00E4;,&#x00E2;,&#x00E3;,&#x00E5;,&#x0105;,&#x00E6;,&#x0101;,&#x00AA;</string>
+    <!-- U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
+         U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
+         U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
+         U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
+         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 -->
+    <string name="more_keys_for_e">&#x00E9;,&#x00E8;,&#x00EB;,&#x00EA;,&#x0119;,&#x0117;,&#x0113;</string>
+    <!-- U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
+         U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
+         U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
+         U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
+         U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
+         U+012B: "ī" LATIN SMALL LETTER I WITH MACRON -->
+    <string name="more_keys_for_i">&#x00ED;,&#x00EF;,&#x00EC;,&#x00EE;,&#x012F;,&#x012B;</string>
+    <!-- U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
+         U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
+         U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
+         U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
+         U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
+         U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
+         U+0153: "œ" LATIN SMALL LIGATURE OE
+         U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
+         U+00BA: "º" MASCULINE ORDINAL INDICATOR -->
+    <string name="more_keys_for_o">&#x00F3;,&#x00F2;,&#x00F6;,&#x00F4;,&#x00F5;,&#x00F8;,&#x0153;,&#x014D;,&#x00BA;</string>
+    <!-- U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
+         U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
+         U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
+         U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
+         U+016B: "ū" LATIN SMALL LETTER U WITH MACRON -->
+    <string name="more_keys_for_u">&#x00FA;,&#x00FC;,&#x00F9;,&#x00FB;,&#x016B;</string>
+    <!-- U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
+         U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE -->
+    <string name="more_keys_for_n">&#x00F1;,&#x0144;</string>
+    <!-- U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
+         U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
+         U+010D: "č" LATIN SMALL LETTER C WITH CARON -->
+    <string name="more_keys_for_c">&#x00E7;,&#x0107;,&#x010D;</string>
+</resources>
diff --git a/tools/make-keyboard-text/res/values-fa/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-fa/donottranslate-more-keys.xml
index 56993be..b886195 100644
--- a/tools/make-keyboard-text/res/values-fa/donottranslate-more-keys.xml
+++ b/tools/make-keyboard-text/res/values-fa/donottranslate-more-keys.xml
@@ -64,7 +64,6 @@
     <string name="additional_more_keys_for_symbols_0">0,&#x066B;,&#x066C;</string>
     <!-- U+060C: "،" ARABIC COMMA -->
     <string name="keylabel_for_comma">&#x060C;</string>
-    <string name="more_keys_for_comma">"\\,"</string>
     <!-- U+064B: "ً" ARABIC FATHATAN -->
     <string name="keyhintlabel_for_period">&#x064B;</string>
     <string name="more_keys_for_period">!text/more_keys_for_arabic_diacritics</string>
@@ -89,10 +88,6 @@
     <string name="more_keys_for_tablet_comma">"!fixedColumnOrder!4,:,!,&#x061F;,&#x061B;,-,/,!text/keyspec_left_double_angle_quote,!text/keyspec_right_double_angle_quote"</string>
     <!-- U+FDFC: "﷼" RIAL SIGN -->
     <string name="keylabel_for_currency">&#xFDFC;</string>
-    <!-- U+061F: "؟" ARABIC QUESTION MARK
-         U+060C: "،" ARABIC COMMA
-         U+061B: "؛" ARABIC SEMICOLON -->
-    <string name="more_keys_for_punctuation">"!fixedColumnOrder!8,\",\',#,-,:,!,&#x060C;,&#x061F;,@,&amp;,\\%,+,&#x061B;,/,!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis"</string>
     <!-- U+266A: "♪" EIGHTH NOTE -->
     <string name="more_keys_for_bullet">&#x266A;</string>
     <!-- U+2605: "★" BLACK STAR
diff --git a/tools/make-keyboard-text/res/values-fr/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-fr/donottranslate-more-keys.xml
index 6656776..47b1c9e 100644
--- a/tools/make-keyboard-text/res/values-fr/donottranslate-more-keys.xml
+++ b/tools/make-keyboard-text/res/values-fr/donottranslate-more-keys.xml
@@ -62,7 +62,7 @@
     <!-- U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
          U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
          U+010D: "č" LATIN SMALL LETTER C WITH CARON -->
-    <string name="more_keys_for_c">&#x00E7;,&#x0107;,&#x010D;</string>
+    <string name="more_keys_for_c">&#x00E7;,%,&#x0107;,&#x010D;</string>
     <!-- U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS -->
     <string name="more_keys_for_y">%,&#x00FF;</string>
     <!-- U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE -->
diff --git a/tools/make-keyboard-text/res/values-gl-rES/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-gl-rES/donottranslate-more-keys.xml
new file mode 100644
index 0000000..83dbe0e
--- /dev/null
+++ b/tools/make-keyboard-text/res/values-gl-rES/donottranslate-more-keys.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** 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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
+         U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE
+         U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
+         U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
+         U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE
+         U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
+         U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK
+         U+00E6: "æ" LATIN SMALL LETTER AE
+         U+0101: "ā" LATIN SMALL LETTER A WITH MACRON
+         U+00AA: "ª" FEMININE ORDINAL INDICATOR -->
+    <string name="more_keys_for_a">&#x00E1;,&#x00E0;,&#x00E4;,&#x00E2;,&#x00E3;,&#x00E5;,&#x0105;,&#x00E6;,&#x0101;,&#x00AA;</string>
+    <!-- U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
+         U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
+         U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
+         U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
+         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 -->
+    <string name="more_keys_for_e">&#x00E9;,&#x00E8;,&#x00EB;,&#x00EA;,&#x0119;,&#x0117;,&#x0113;</string>
+    <!-- U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
+         U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
+         U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
+         U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
+         U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
+         U+012B: "ī" LATIN SMALL LETTER I WITH MACRON -->
+    <string name="more_keys_for_i">&#x00ED;,&#x00EF;,&#x00EC;,&#x00EE;,&#x012F;,&#x012B;</string>
+    <!-- U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
+         U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
+         U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
+         U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
+         U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
+         U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
+         U+0153: "œ" LATIN SMALL LIGATURE OE
+         U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
+         U+00BA: "º" MASCULINE ORDINAL INDICATOR -->
+    <string name="more_keys_for_o">&#x00F3;,&#x00F2;,&#x00F6;,&#x00F4;,&#x00F5;,&#x00F8;,&#x0153;,&#x014D;,&#x00BA;</string>
+    <!-- U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
+         U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
+         U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
+         U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
+         U+016B: "ū" LATIN SMALL LETTER U WITH MACRON -->
+    <string name="more_keys_for_u">&#x00FA;,&#x00FC;,&#x00F9;,&#x00FB;,&#x016B;</string>
+    <!-- U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
+         U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE -->
+    <string name="more_keys_for_n">&#x00F1;,&#x0144;</string>
+    <!-- U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
+         U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE
+         U+010D: "č" LATIN SMALL LETTER C WITH CARON -->
+    <string name="more_keys_for_c">&#x00E7;,&#x0107;,&#x010D;</string>
+</resources>
diff --git a/tools/make-keyboard-text/res/values-hy-rAM/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-hy-rAM/donottranslate-more-keys.xml
index a17dc10..8ab78d0 100644
--- a/tools/make-keyboard-text/res/values-hy-rAM/donottranslate-more-keys.xml
+++ b/tools/make-keyboard-text/res/values-hy-rAM/donottranslate-more-keys.xml
@@ -23,20 +23,22 @@
          U+0532: "Բ" ARMENIAN CAPITAL LETTER BEN
          U+0533: "Գ" ARMENIAN CAPITAL LETTER GIM -->
     <string name="label_to_alpha_key">&#x0531;&#x0532;&#x0533;</string>
-    <!-- U+058A: "֊" ARMENIAN HYPHEN -->
-    <!-- U+055C: "՜" ARMENIAN EXCLAMATION MARK -->
-    <!-- U+055D: "՝" ARMENIAN COMMA -->
-    <!-- U+055E: "՞" ARMENIAN QUESTION MARK -->
-    <!-- U+0559: "ՙ" ARMENIAN MODIFIER LETTER LEFT HALF RING -->
-    <!-- U+055A: "՚" ARMENIAN APOSTROPHE -->
-    <!-- U+055B: "՛" ARMENIAN EMPHASIS MARK -->
-    <!-- U+055F: "՟" ARMENIAN ABBREVIATION MARK -->
-    <string name="more_keys_for_punctuation">"!fixedColumnOrder!8,!,?,&#x0559;,&#x055A;,.,&#x055C;,\\,,&#x055E;,:,;,&#x055F;,&#x00AB;,&#x00BB;,&#x058A;,&#x055D;,&#x055B;"</string>
-    <!-- U+055E: "՞" ARMENIAN QUESTION MARK -->
-    <!-- U+00BF: "¿" INVERTED QUESTION MARK -->
+    <!-- U+055E: "՞" ARMENIAN QUESTION MARK
+         U+055C: "՜" ARMENIAN EXCLAMATION MARK
+         U+055A: "՚" ARMENIAN APOSTROPHE
+         U+0559: "ՙ" ARMENIAN MODIFIER LETTER LEFT HALF RING
+         U+055D: "՝" ARMENIAN COMMA
+         U+055B: "՛" ARMENIAN EMPHASIS MARK
+         U+058A: "֊" ARMENIAN HYPHEN
+         U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+         U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+         U+055F: "՟" ARMENIAN ABBREVIATION MARK -->
+    <string name="more_keys_for_punctuation">"!autoColumnOrder!8,\\,,&#x055E;,&#x055C;,.,&#x055A;,&#x0559;,?,!,&#x055D;,&#x055B;,&#x058A;,&#x00BB;,&#x00AB;,&#x055F;,;,:"</string>
+    <!-- U+055E: "՞" ARMENIAN QUESTION MARK
+         U+00BF: "¿" INVERTED QUESTION MARK -->
     <string name="more_keys_for_question">&#x055E;,&#x00BF;</string>
-    <!-- U+055C: "՜" ARMENIAN EXCLAMATION MARK -->
-    <!-- U+00A1: "¡" INVERTED EXCLAMATION MARK -->
+    <!-- U+055C: "՜" ARMENIAN EXCLAMATION MARK
+         U+00A1: "¡" INVERTED EXCLAMATION MARK -->
     <string name="more_keys_for_exclamation">&#x055C;,&#x00A1;</string>
     <!-- U+058F: "֏" ARMENIAN DRAM SIGN -->
     <!-- TODO: Enable this when we have glyph for the following letter
diff --git a/java/res/xml-sw600dp/key_colemak_colon.xml b/tools/make-keyboard-text/res/values-my-rMM/donottranslate-more-keys.xml
similarity index 61%
rename from java/res/xml-sw600dp/key_colemak_colon.xml
rename to tools/make-keyboard-text/res/values-my-rMM/donottranslate-more-keys.xml
index 25b0e52..16a0bc4 100644
--- a/java/res/xml-sw600dp/key_colemak_colon.xml
+++ b/tools/make-keyboard-text/res/values-my-rMM/donottranslate-more-keys.xml
@@ -2,7 +2,7 @@
 <!--
 /*
 **
-** Copyright 2012, The Android Open Source Project
+** Copyright 2014, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
@@ -17,13 +17,10 @@
 ** limitations under the License.
 */
 -->
-
-<merge
-    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
-    <Key
-        latin:keySpec=":"
-        latin:keyHintLabel=";"
-        latin:moreKeys=";"
-        latin:keyStyle="hasShiftedLetterHintStyle" />
-</merge>
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Label for "switch to alphabetic" key.
+         U+1000: "က" MYANMAR LETTER KA
+         U+1001: "ခ" MYANMAR LETTER KHA
+         U+1002: "ဂ" MYANMAR LETTER GA -->
+    <string name="label_to_alpha_key">&#x1000;&#x1001;&#x1002;</string>
+</resources>
diff --git a/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml
index 1ea3018..79f2c65 100644
--- a/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml
+++ b/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml
@@ -82,8 +82,8 @@
     <string name="more_keys_for_currency_dollar">&#x00A2;,&#x00A3;,&#x20AC;,&#x00A5;,&#x20B1;</string>
     <string name="keylabel_for_currency">$</string>
     <string name="more_keys_for_currency">$,&#x00A2;,&#x20AC;,&#x00A3;,&#x00A5;,&#x20B1;</string>
-    <string name="more_keys_for_punctuation">"!fixedColumnOrder!8,;,/,!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis,#,!,\\,,?,&amp;,\\%,+,\",-,:,',@"</string>
-    <string name="more_keys_for_tablet_punctuation">"!fixedColumnOrder!7,;,/,!text/keyspec_left_parenthesis,!text/keyspec_right_parenthesis,#,',\\,,&amp;,\\%,+,\",-,:,@"</string>
+    <string name="more_keys_for_punctuation">"!autoColumnOrder!8,\\,,?,!,#,!text/keyspec_right_parenthesis,!text/keyspec_left_parenthesis,/,;,',@,:,-,\",+,\\%,&amp;"</string>
+    <string name="more_keys_for_tablet_punctuation">"!autoColumnOrder!7,\\,,',#,!text/keyspec_right_parenthesis,!text/keyspec_left_parenthesis,/,;,@,:,-,\",+,\\%,&amp;"</string>
     <!-- U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE -->
     <string name="keylabel_for_spanish_row2_10">&#x00F1;</string>
     <!-- U+2020: "†" DAGGER
@@ -177,7 +177,6 @@
     <string name="keyspec_right_single_angle_quote">&#x203A;</string>
     <!-- Comma key -->
     <string name="keylabel_for_comma">,</string>
-    <string name="more_keys_for_comma"></string>
     <string name="keylabel_for_tablet_comma">,</string>
     <string name="keyhintlabel_for_tablet_comma"></string>
     <string name="more_keys_for_tablet_comma"></string>