Merge "[IL127] Move the double space countdown to InputLogic"
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/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/rows_pcqwerty.xml b/java/res/xml-sw600dp/rows_pcqwerty.xml
index 8714815..b503d83 100644
--- a/java/res/xml-sw600dp/rows_pcqwerty.xml
+++ b/java/res/xml-sw600dp/rows_pcqwerty.xml
@@ -56,7 +56,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/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/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/method.xml b/java/res/xml/method.xml
index 49b0df1..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
@@ -256,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"
@@ -296,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"
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/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/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/internal/KeyboardTextsTable.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
index e9ecd1e..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:21 */ "label_to_alpha_key",
-        /*   9:20 */ "more_keys_for_s",
-        /*  10:20 */ "more_keys_for_n",
+        /*   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,24 +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,
         // Label for "switch to alphabetic" key.
         /* label_to_alpha_key */ "ABC",
         /* more_keys_for_s ~ */
-        EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
+        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",
@@ -292,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
@@ -339,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,
@@ -359,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",
@@ -505,12 +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, 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",
+        /* 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",
@@ -519,8 +519,8 @@
     /* Language ar: Arabic */
     private static final String[] LANGUAGE_ar = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null, null, null, null,
-        /* ~ more_keys_for_c */
+        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
@@ -530,9 +530,7 @@
         /* 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,
-        /* ~ more_keys_for_cyrillic_soft_sign */
-        /* more_keys_for_punctuation */ "!fixedColumnOrder!8,\",\',#,-,:,!,\u060C,\u061F,@,&,\\%,+,\u061B,/,(|),)|(",
-        /* more_keys_for_nordic_row2_11 */ null,
+        /* ~ more_keys_for_nordic_row2_11 */
         // U+0661: "١" ARABIC-INDIC DIGIT ONE
         /* keylabel_for_symbols_1 */ "\u0661",
         // U+0662: "٢" ARABIC-INDIC DIGIT TWO
@@ -571,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",
@@ -632,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
@@ -677,20 +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",
-        /* label_to_alpha_key */ null,
+        /* 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,
+        /* 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",
@@ -699,18 +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,
         // 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_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,
         /* ~ more_keys_for_k */
         // U+0451: "ё" CYRILLIC SMALL LETTER IO
         /* more_keys_for_cyrillic_ie */ "\u0451",
@@ -732,12 +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",
+        /* more_keys_for_n */ null,
         /* single_quotes */ null,
-        /* more_keys_for_c */ null,
         // Label for "switch to alphabetic" key.
         // U+0410: "А" CYRILLIC CAPITAL LETTER A
         // U+0411: "Б" CYRILLIC CAPITAL LETTER BE
@@ -789,42 +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",
-        /* label_to_alpha_key */ null,
-        /* 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",
-        /* more_keys_for_y ~ */
-        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 */
@@ -870,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",
+        /* 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+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",
         // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
         // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
         /* more_keys_for_y */ "\u00FD,\u00FF",
@@ -933,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",
         // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
         // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
         /* more_keys_for_y */ "\u00FD,\u00FF",
@@ -968,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",
     };
@@ -1007,17 +1002,17 @@
         // 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",
         /* more_keys_for_y ~ */
         null, null, null, null, null, null,
         /* ~ more_keys_for_g */
@@ -1047,8 +1042,8 @@
     /* Language el: Greek */
     private static final String[] LANGUAGE_el = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null, null, null, null,
-        /* ~ more_keys_for_c */
+        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
@@ -1094,15 +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",
+        /* 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",
-        // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
-        /* more_keys_for_n */ "\u00F1",
     };
 
     /* Language eo: Esperanto */
@@ -1160,20 +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",
-        /* 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",
+        /* 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
@@ -1181,6 +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
@@ -1238,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",
@@ -1301,24 +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",
-        /* label_to_alpha_key */ null,
-        /* 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",
-        /* more_keys_for_y ~ */
+        /* single_quotes ~ */
         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) */
@@ -1368,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",
         // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
         // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
         /* more_keys_for_y */ "\u00FD,\u00FF",
@@ -1424,11 +1417,65 @@
         /* 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,
-        /* ~ more_keys_for_c */
+        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
@@ -1436,18 +1483,13 @@
         // U+067E: "پ" ARABIC LETTER PEH
         /* label_to_alpha_key */ "\u0627\u200C\u0628\u200C\u067E",
         /* more_keys_for_s ~ */
-        null, null, null, null, null, null, null, null, null, null,
+        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
@@ -1486,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",
@@ -1543,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
@@ -1590,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, null,
+        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,
-        /* ~ 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
@@ -1615,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",
     };
@@ -1664,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",
-        /* label_to_alpha_key ~ */
-        null, null, null,
-        /* ~ more_keys_for_n */
+        /* 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 ~ */
@@ -1696,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,
-        /* ~ more_keys_for_c */
+        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_s ~ */
-        null, null, null, null, null, null, null, null, null, null,
+        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",
@@ -1756,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",
         /* more_keys_for_y */ null,
         // U+0111: "đ" LATIN SMALL LETTER D WITH STROKE
         /* more_keys_for_d */ "\u0111",
@@ -1827,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",
@@ -1839,8 +1934,8 @@
     /* Language hy_AM: Armenian (Armenia) */
     private static final String[] LANGUAGE_hy_AM = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null, null, null, null,
-        /* ~ more_keys_for_c */
+        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
@@ -1848,21 +1943,22 @@
         /* label_to_alpha_key */ "\u0531\u0532\u0533",
         /* 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,
-        /* ~ 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
@@ -1877,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",
@@ -1928,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,
-        /* ~ more_keys_for_n */
+        /* 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",
@@ -1991,18 +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,
         // 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_s ~ */
-        null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null,
         /* ~ double_angle_quotes */
         // U+20AA: "₪" NEW SHEQEL SIGN
         /* keylabel_for_currency */ "\u20AA",
@@ -2010,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
@@ -2038,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
@@ -2048,11 +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,
         // Label for "switch to alphabetic" key.
         // U+10D0: "ა" GEORGIAN LETTER AN
         // U+10D1: "ბ" GEORGIAN LETTER BAN
@@ -2063,15 +2160,15 @@
     /* Language kk: Kazakh */
     private static final String[] LANGUAGE_kk = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null, null, null, null,
-        /* ~ more_keys_for_c */
+        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_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,
         /* ~ more_keys_for_k */
         // U+0451: "ё" CYRILLIC SMALL LETTER IO
         /* more_keys_for_cyrillic_ie */ "\u0451",
@@ -2088,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,
@@ -2106,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",
@@ -2119,8 +2216,8 @@
     /* Language km_KH: Khmer (Cambodia) */
     private static final String[] LANGUAGE_km_KH = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null, null, null, null,
-        /* ~ more_keys_for_c */
+        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
@@ -2133,7 +2230,7 @@
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null,
         /* ~ more_keys_for_east_slavic_row2_11 */
         // U+17DB: "៛" KHMER CURRENCY SYMBOL RIEL
         /* more_keys_for_currency_dollar */ "\u17DB,\u00A2,\u00A3,\u20AC,\u00A5,\u20B1",
@@ -2142,15 +2239,15 @@
     /* Language ky: Kirghiz */
     private static final String[] LANGUAGE_ky = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null, null, null, null,
-        /* ~ more_keys_for_c */
+        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_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,
         /* ~ more_keys_for_k */
         // U+0451: "ё" CYRILLIC SMALL LETTER IO
         /* more_keys_for_cyrillic_ie */ "\u0451",
@@ -2167,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,
@@ -2185,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,
-        /* ~ more_keys_for_c */
+        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_s ~ */
-        null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null,
         /* ~ double_angle_quotes */
         // U+20AD: "₭" KIP SIGN
         /* keylabel_for_currency */ "\u20AD",
@@ -2247,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",
         // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
         // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
         /* more_keys_for_y */ "\u00FD,\u00FF",
@@ -2341,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",
         // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
         // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
         /* more_keys_for_y */ "\u00FD,\u00FF",
@@ -2391,18 +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,
         // 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_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,
         /* ~ more_keys_for_k */
         // U+0450: "ѐ" CYRILLIC SMALL LETTER IE WITH GRAVE
         /* more_keys_for_cyrillic_ie */ "\u0450",
@@ -2427,15 +2524,15 @@
     /* Language mn_MN: Mongolian (Mongolia) */
     private static final String[] LANGUAGE_mn_MN = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null, null, null, null,
-        /* ~ more_keys_for_c */
+        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_s ~ */
-        null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null,
         /* ~ double_angle_quotes */
         // U+20AE: "₮" TUGRIK SIGN
         /* keylabel_for_currency */ "\u20AE",
@@ -2444,8 +2541,8 @@
     /* Language my_MM: Burmese (Myanmar) */
     private static final String[] LANGUAGE_my_MM = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null, null, null, null,
-        /* ~ more_keys_for_c */
+        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
@@ -2485,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",
@@ -2500,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",
     };
@@ -2509,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,
-        /* ~ more_keys_for_c */
+        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_s ~ */
-        null, null, null, null, null, null, null, null, null, null,
+        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",
@@ -2603,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",
+        /* more_keys_for_c */ null,
         /* double_quotes */ "!text/double_9qm_rqm",
-        /* single_quotes */ "!text/single_9qm_rqm",
-        /* more_keys_for_c ~ */
-        null, null, null,
-        /* ~ more_keys_for_s */
         // 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",
     };
@@ -2646,20 +2744,20 @@
         // 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",
         /* more_keys_for_y */ null,
         /* more_keys_for_d */ null,
         // U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE
@@ -2713,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
@@ -2756,17 +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,
+        /* 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",
@@ -2775,18 +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,
         // 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_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,
         /* ~ more_keys_for_k */
         // U+0451: "ё" CYRILLIC SMALL LETTER IO
         /* more_keys_for_cyrillic_ie */ "\u0451",
@@ -2852,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",
+        /* 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+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",
         // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
         // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
         /* more_keys_for_y */ "\u00FD,\u00FF",
@@ -2905,15 +3002,15 @@
         /* 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,
         /* more_keys_for_y */ null,
         // U+0111: "đ" LATIN SMALL LETTER D WITH STROKE
         /* more_keys_for_d */ "\u0111",
@@ -2929,11 +3026,11 @@
     /* 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,
         // END: More keys definitions for Serbian (Cyrillic)
         // Label for "switch to alphabetic" key.
         // U+0410: "А" CYRILLIC CAPITAL LETTER A
@@ -2941,7 +3038,7 @@
         // U+0412: "В" CYRILLIC CAPITAL LETTER VE
         /* label_to_alpha_key */ "\u0410\u0411\u0412",
         /* more_keys_for_s ~ */
-        null, null, null, null, null, null, null, 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",
@@ -3017,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",
         // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
         // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
         /* more_keys_for_y */ "\u00FD,\u00FF",
@@ -3066,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",
     };
@@ -3111,15 +3208,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",
+        /* 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",
-        // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
-        /* more_keys_for_n */ "\u00F1",
         /* more_keys_for_y ~ */
         null, null, null, null, null,
         /* ~ more_keys_for_l */
@@ -3129,15 +3226,15 @@
     /* Language th: Thai */
     private static final String[] LANGUAGE_th = {
         /* more_keys_for_a ~ */
-        null, null, null, null, null, null, null, null,
-        /* ~ more_keys_for_c */
+        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_s ~ */
-        null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null,
         /* ~ double_angle_quotes */
         // U+0E3F: "฿" THAI CURRENCY SYMBOL BAHT
         /* keylabel_for_currency */ "\u0E3F",
@@ -3187,14 +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",
-        /* label_to_alpha_key */ null,
-        /* 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",
@@ -3228,20 +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",
-        /* label_to_alpha_key */ null,
+        /* 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,
+        /* 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",
@@ -3250,18 +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,
         // 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_s ~ */
-        null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null,
         /* ~ double_angle_quotes */
         // U+20B4: "₴" HRYVNIA SIGN
         /* keylabel_for_currency */ "\u20B4",
@@ -3278,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,
@@ -3358,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,
-        /* ~ more_keys_for_n */
+        /* ~ 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
@@ -3415,15 +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",
+        /* 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",
-        // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
-        /* more_keys_for_n */ "\u00F1",
     };
 
     /* Language zz: Alphabet */
@@ -3484,14 +3578,21 @@
         // 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",
+        /* 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
+        // U+0148: "ň" LATIN SMALL LETTER N WITH CARON
+        // 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
@@ -3500,13 +3601,6 @@
         // 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+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
-        /* more_keys_for_n */ "\u00F1,\u0144,\u0146,\u0148,\u0149,\u014B",
         // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
         // U+0177: "ŷ" LATIN SMALL LETTER Y WITH CIRCUMFLEX
         // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
@@ -3559,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",
@@ -3569,61 +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/  9 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/  9 Greek */
+        "el", LANGUAGE_el,    /*   1/ 10 Greek */
         "en", LANGUAGE_en,    /*   8/ 11 English */
-        "eo", LANGUAGE_eo,    /*  26/128 Esperanto */
-        "es", LANGUAGE_es,    /*   8/ 33 Spanish */
+        "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/  9 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) */
-        "my", LANGUAGE_my_MM, /*   1/  9 Burmese (Myanmar) */
-        "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/ 11 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/ 11 Zulu */
-        "zz", LANGUAGE_zz,    /*  19/111 Alphabet */
+        "zz", LANGUAGE_zz,    /*  19/110 Alphabet */
     };
 
     static {
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 ee66a9b..8faf175 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;
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/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/layout/Arabic.java b/tests/src/com/android/inputmethod/keyboard/layout/Arabic.java
index 838f987..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);
         }
@@ -312,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("(", ")",
@@ -342,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/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/Farsi.java b/tests/src/com/android/inputmethod/keyboard/layout/Farsi.java
index 6da817f..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);
         }
@@ -315,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("(", ")",
@@ -345,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/Hebrew.java b/tests/src/com/android/inputmethod/keyboard/layout/Hebrew.java
index 83446de..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
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/LayoutBase.java b/tests/src/com/android/inputmethod/keyboard/layout/LayoutBase.java
index d870931..09cc8f9 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/LayoutBase.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/LayoutBase.java
@@ -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.
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 cce9d5f..a13ec75 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/expected/AbstractLayoutBase.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/expected/AbstractLayoutBase.java
@@ -109,6 +109,8 @@
     // Icon ids.
     private static final int ICON_DELETE = KeyboardIconsSet.getIconId(
             KeyboardIconsSet.NAME_DELETE_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_ENTER = KeyboardIconsSet.getIconId(
@@ -118,6 +120,7 @@
 
     // Functional keys.
     public static final ExpectedKey DELETE_KEY = key(ICON_DELETE, Constants.CODE_DELETE);
+    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 ENTER_KEY = key(ICON_ENTER, Constants.CODE_ENTER);
     public static final ExpectedKey EMOJI_KEY = key(ICON_EMOJI, Constants.CODE_EMOJI);
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/FrenchCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/FrenchCustomizer.java
index b10b368..ab90267 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/FrenchCustomizer.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/FrenchCustomizer.java
@@ -83,6 +83,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
-                .setMoreKeysOf("c", "\u00E7", "\u0107", "\u010D");
+                .setMoreKeysOf("c", "\u00E7", "\u0107", "\u010D")
+                .setAdditionalMoreKeysPositionOf("c", 2);
     }
 }
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/SpanishCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/SpanishCustomizer.java
index da4a83c..8974ad6 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/SpanishCustomizer.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/SpanishCustomizer.java
@@ -38,8 +38,8 @@
     private static final ExpectedKey[] PHONE_PUNCTUATION_MORE_KEYS = AbstractLayoutBase.joinKeys(
             // U+00A1: "¡" INVERTED EXCLAMATION MARK
             // U+00BF: "¿" INVERTED QUESTION MARK
-            "\u00A1", ";", "/", "(", ")", "#", "!", ",", "?",
-            "\u00BF", "&", "%", "+", "\"", "-", ":", "'", "@");
+            ",", "?", "!", "#", ")", "(", "/", ";", "\u00A1",
+            "'", "@", ":", "-", "\"", "+", "%", "&", "\u00BF");
 
     @Override
     public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
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/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/TestsCatalan.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCatalan.java
index 988eb81..151a0a6 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCatalan.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCatalan.java
@@ -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) {
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/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/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/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/TestsNoLanguage.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguage.java
index 480f5f2..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", "\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/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/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/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>