Merge "Don't assume a word has been added to the user dict"
diff --git a/java/res/values-am/strings.xml b/java/res/values-am/strings.xml
index 6cf4203..b57a9e8 100644
--- a/java/res/values-am/strings.xml
+++ b/java/res/values-am/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"ፅሁፍ አስተካክል"</string>
     <string name="misc_category" msgid="6894192814868233453">"ሌሎች አማራጮች"</string>
     <string name="advanced_settings" msgid="362895144495591463">"የላቁ ቅንብሮች"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"ለብቁ ተጠቃሚዎች አማራጮች"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"የቁልፍ ብቅ ባይ መዘግየትን ያስወገዳል"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"የዘገየ የለም"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"ነባሪ"</string>
diff --git a/java/res/values-ar/donottranslate-more-keys.xml b/java/res/values-ar/donottranslate-more-keys.xml
index bb36af2..ecad0bb 100644
--- a/java/res/values-ar/donottranslate-more-keys.xml
+++ b/java/res/values-ar/donottranslate-more-keys.xml
@@ -18,27 +18,25 @@
 */
 -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- U+060C: "،" ARABIC COMMA
-         U+061B: "؛" ARABIC SEMICOLON
-         U+061F: "؟" ARABIC QUESTION MARK -->
+    <!-- U+061F: "؟" ARABIC QUESTION MARK
+         U+060C: "،" ARABIC COMMA
+         U+061B: "؛" ARABIC SEMICOLON -->
     <!-- U+0650: "ِ" ARABIC KASRA
          U+064E: "َ" ARABIC FATHA
-         U+064B: "ً" ARABIC FATHATAN
-         U+0640: "ـ" ARABIC TATWEEL
          U+064D: "ٍ" ARABIC KASRATAN
-         U+0670: "ٰ" ARABIC LETTER SUPERSCRIPT ALEF
+         U+064B: "ً" ARABIC FATHATAN
          U+0656: "ٖ" ARABIC SUBSCRIPT ALEF
-         U+0654: "ٔ" ARABIC HAMZA ABOVE
-         U+0655: "ٕ" ARABIC HAMZA BELOW -->
-    <!-- U+0651: "ّ" ARABIC SHADDA
-         U+0652: "ْ" ARABIC SUKUN
+         U+0670: "ٰ" ARABIC LETTER SUPERSCRIPT ALEF
+         U+0655: "ٕ" ARABIC HAMZA BELOW
+         U+0654: "ٔ" ARABIC HAMZA ABOVE -->
+    <!-- U+064F: "ُ" ARABIC DAMMA
          U+064C: "ٌ" ARABIC DAMMATAN
+         U+0651: "ّ" ARABIC SHADDA
+         U+0652: "ْ" ARABIC SUKUN
          U+0653: "ٓ" ARABIC MADDAH ABOVE
-         U+064F: "ُ" ARABIC DAMMA -->
+         U+0640: "ـ" ARABIC TATWEEL -->
     <!-- In order to make Tatweel easily distinguishable from other punctuations, we use consecutive Tatweels only for its displayed label. -->
-    <!-- TODO: Will introduce "grouping marks" to the more characters specification. -->
-    <string name="more_keys_for_punctuation">"&#x060C;,&#x061B;,&#x061F;,!,:,-,/,\',\",&#x0640;&#x0640;&#x0640;|&#x0640;,&#x064E;,&#x0650;,&#x064B;,&#x064D;,&#x0670;,&#x0656;,&#x0655;,&#x0654;,&#x0653;,&#x0652;,&#x0651;,&#x064C;,&#x064F;"</string>
-    <integer name="more_keys_keyboard_column_for_punctuation">9</integer>
+    <string name="more_keys_for_punctuation">"!fixedColumnOrder!8,\",\',-,:,!,&#x061F;,&#x060C;,&#x061B;,&#x0650;,&#x064E;,&#x064D;,&#x064B;,&#x0656;,&#x0670;,&#x0655;,&#x0654;,&#x064F;,&#x064C;,&#x0651;,&#x0652;,&#x0653;,&#x0640;&#x0640;&#x0640;|&#x0640;,/"</string>
     <string name="keyhintlabel_for_punctuation">&#x064B;</string>
     <!-- U+0661: "١" ARABIC-INDIC DIGIT ONE -->
     <string name="keylabel_for_symbols_1">&#x0661;</string>
@@ -72,16 +70,13 @@
     <!-- U+066B: "٫" ARABIC DECIMAL SEPARATOR
          U+066C: "٬" ARABIC THOUSANDS SEPARATOR -->
     <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="keylabel_for_f1">&#x060C;</string>
+    <string name="more_keys_for_comma">"\\,"</string>
     <string name="keylabel_for_symbols_question">&#x061F;</string>
     <string name="keylabel_for_symbols_semicolon">&#x061B;</string>
     <!-- U+066A: "٪" ARABIC PERCENT SIGN -->
     <string name="keylabel_for_symbols_percent">&#x066A;</string>
-    <string name="more_keys_for_comma">,</string>
-    <string name="more_keys_for_f1">,</string>
-    <string name="more_keys_for_f1_settings">\\,,\@icon/settingsKey|\@integer/key_settings</string>
-    <string name="more_keys_for_f1_navigate">\\,,\@icon/tabKey|\@integer/key_tab</string>
     <string name="more_keys_for_symbols_question">\?</string>
     <string name="more_keys_for_symbols_semicolon">;</string>
     <!-- U+2030: "‰" PER MILLE SIGN -->
@@ -125,8 +120,8 @@
          U+FD3F: "﴿" ORNATE RIGHT PARENTHESIS -->
     <!-- TODO: DroidSansArabic lacks the glyph of U+FD3E ORNATE LEFT PARENTHESIS -->
     <!-- TODO: DroidSansArabic lacks the glyph of U+FD3F ORNATE RIGHT PARENTHESIS -->
-    <string name="more_keys_for_left_parenthesis">[|],{|},&lt;|&gt;,&#xFD3E;|&#xFD3F;</string>
-    <string name="more_keys_for_right_parenthesis">]|[,}|{,&gt;|&lt;,&#xFD3F;|&#xFD3E;</string>
+    <string name="more_keys_for_left_parenthesis">!fixedColumnOrder!4,&#xFD3E;|&#xFD3F;,&lt;|&gt;,{|},[|]</string>
+    <string name="more_keys_for_right_parenthesis">!fixedColumnOrder!4,&#xFD3F;|&#xFD3E;,&gt;|&lt;,}|{,]|[</string>
     <!-- U+003E: ">" GREATER-THAN SIGN -->
     <integer name="keycode_for_less_than">0x003E</integer>
     <!-- U+003C: "<" LESS-THAN SIGN -->
@@ -146,8 +141,8 @@
          U+201D: "”" RIGHT DOUBLE QUOTATION MARK
          U+201E: "„" DOUBLE LOW-9 QUOTATION MARK
          U+201F: "‟" DOUBLE HIGH-REVERSED-9 QUOTATION MARK -->
-    <string name="more_keys_for_less_than">&#x2264;|&#x2265;,&#x00AB;|&#x00BB;,&#x2039;|&#x203A;</string>
-    <string name="more_keys_for_greater_than">&#x2265;|&#x2264;,&#x00BB;|&#x00AB;,&#x203A;|&#x2039;</string>
+    <string name="more_keys_for_less_than">!fixedColumnOrder!3,&#x2039;|&#x203A;,&#x2264;|&#x2265;,&#x00AB;|&#x00BB;</string>
+    <string name="more_keys_for_greater_than">!fixedColumnOrder!3,&#x203A;|&#x2039;,&#x2265;|&#x2264;,&#x00BB;|&#x00AB;</string>
     <!-- U+005D: "]" RIGHT SQUARE BRACKET -->
     <integer name="keycode_for_left_square_bracket">0x005D</integer>
     <!-- U+005B: "[" LEFT SQUARE BRACKET -->
@@ -157,11 +152,9 @@
     <!-- U+007B: "{" LEFT CURLY BRACKET -->
     <integer name="keycode_for_right_curly_bracket">0x007B</integer>
     <!-- TODO: Neither DroidSans nor Roboto have the glyph for U+201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK -->
-    <!-- <string name="more_keys_for_double_quote">&#x201C;,&#x201D;,&#x201E;,&#x201F;,&#x00AB;,&#x00BB;</string> -->
-    <!-- The 4-more keys will be displayed in order of "3,1,2,4". -->
-    <string name="more_keys_for_double_quote">&#x201D;,&#x00AB;|&#x00BB;,&#x201C;,&#x00BB;|&#x00AB;</string>
+    <!-- <string name="more_keys_for_double_quote">&#x201C;,&#x201D;,&#x201E;,&#x201F;,&#x00AB;|&#x00BB;,&#x00BB;|&#x00AB;</string> -->
+    <string name="more_keys_for_double_quote">!fixedColumnOrder!4,&#x201C;,&#x201D;,&#x00AB;|&#x00BB;,&#x00BB;|&#x00AB;</string>
     <!-- TODO: Neither DroidSans nor Roboto have the glyph for U+201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK -->
-    <!-- <string name="more_keys_for_tablet_double_quote">&#x201C;,&#x201D;,&#x201E;,&#x201F;,&#x00AB;,&#x00BB;,&#x2018;,&#x2019;,&#x201A;,&#x201B;</string> -->
-    <!-- The 8-more keys with maxMoreKeysColumn=4 will be displayed in order of "3,1,2,4|7,5,6,8". -->
-    <string name="more_keys_for_tablet_double_quote">&#x201D;,&#x00AB;|&#x00BB;,&#x201C;,&#x00BB;|&#x00AB;,&#x2019;,&#x201A;,&#x2018;,&#x201B;</string>
+    <!-- <string name="more_keys_for_tablet_double_quote">!fixedColumnOrder!6,&#x201C;,&#x201D;,&#x201E;,&#x201F;,&#x00AB;|&#x00BB;,&#x00BB|&#x00AB;;,&#x2018;,&#x2019;,&#x201A;,&#x201B;</string> -->
+    <string name="more_keys_for_tablet_double_quote">!fixedColumnOrder!4,&#x201C;,&#x201D;,&#x00AB;|&#x00BB;,&#x00BB;|&#x00AB;,&#x2018;,&#x2019;,&#x201A;,&#x201B;</string>
 </resources>
diff --git a/java/res/values-ar/strings.xml b/java/res/values-ar/strings.xml
index 9f570ab..e182f1c 100644
--- a/java/res/values-ar/strings.xml
+++ b/java/res/values-ar/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"تصحيح النص"</string>
     <string name="misc_category" msgid="6894192814868233453">"خيارات أخرى"</string>
     <string name="advanced_settings" msgid="362895144495591463">"الإعدادات المتقدمة"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"خيارات للخبراء"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"تأخير إزالة النافذة المنبثقة الأساسية"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"بلا تأخير"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"افتراضي"</string>
diff --git a/java/res/values-be/strings.xml b/java/res/values-be/strings.xml
index 53507e7..415ea3d 100644
--- a/java/res/values-be/strings.xml
+++ b/java/res/values-be/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Выпраўленне тэксту"</string>
     <string name="misc_category" msgid="6894192814868233453">"Іншыя параметры"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Адмысловыя налады"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Функцыi для спецыялістаў"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Затрым. скр. падк. клав."</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Няма затрымкі"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Па змаўчанні"</string>
diff --git a/java/res/values-bg/strings.xml b/java/res/values-bg/strings.xml
index 6f80a80..18977e4 100644
--- a/java/res/values-bg/strings.xml
+++ b/java/res/values-bg/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Корекция на текста"</string>
     <string name="misc_category" msgid="6894192814868233453">"Други опции"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Разширени настройки"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Опции за експерти"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Отхвърляне на подсказката"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Без задържане"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"По подразбиране"</string>
diff --git a/java/res/values-cs/strings.xml b/java/res/values-cs/strings.xml
index 1faac53..679ced4 100644
--- a/java/res/values-cs/strings.xml
+++ b/java/res/values-cs/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Oprava textu"</string>
     <string name="misc_category" msgid="6894192814868233453">"Další možnosti"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Pokročilá nastavení"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Možnosti pro odborníky"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Prodleva vysk. okna kláv."</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Bez prodlevy"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Výchozí"</string>
diff --git a/java/res/values-el/strings.xml b/java/res/values-el/strings.xml
index ee2d63c..d3b3e03 100644
--- a/java/res/values-el/strings.xml
+++ b/java/res/values-el/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Διόρθωση κειμένου"</string>
     <string name="misc_category" msgid="6894192814868233453">"Άλλες επιλογές"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Σύνθετες ρυθμίσεις"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Επιλογές για έμπειρους χρήστες"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Χρόνος εξαφ. αναδ. παραθ."</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Χωρίς καθυστέρ."</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Προεπιλογή"</string>
@@ -79,10 +78,8 @@
     <string name="spoken_no_text_entered" msgid="7479685225597344496">"Δεν υπάρχει κείμενο"</string>
     <string name="spoken_description_unknown" msgid="3197434010402179157">"Κωδικός πλήκτρου %d"</string>
     <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
-    <!-- no translation found for spoken_description_shift_shifted (1681877323344195035) -->
-    <skip />
-    <!-- no translation found for spoken_description_caps_lock (3276478269526304432) -->
-    <skip />
+    <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"Το Shift είναι ενεργοποιημένο (πατήστε για απενεργοποίηση)"</string>
+    <string name="spoken_description_caps_lock" msgid="3276478269526304432">"Το Caps lock είναι ενεργοποιημένο (πατήστε για απενεργοποίηση)"</string>
     <string name="spoken_description_delete" msgid="8740376944276199801">"Πλήκτρο Delete"</string>
     <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Σύμβολα"</string>
     <string name="spoken_description_to_alpha" msgid="23129338819771807">"Γράμματα:"</string>
@@ -94,20 +91,13 @@
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Smiley"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Πλήκτρο Return"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"Κουκκίδα"</string>
-    <!-- no translation found for spoken_description_shiftmode_on (5700440798609574589) -->
-    <skip />
-    <!-- no translation found for spoken_description_shiftmode_locked (593175803181701830) -->
-    <skip />
-    <!-- no translation found for spoken_description_shiftmode_off (657219998449174808) -->
-    <skip />
-    <!-- no translation found for spoken_description_mode_symbol (7183343879909747642) -->
-    <skip />
-    <!-- no translation found for spoken_description_mode_alpha (3528307674390156956) -->
-    <skip />
-    <!-- no translation found for spoken_description_mode_phone (6520207943132026264) -->
-    <skip />
-    <!-- no translation found for spoken_description_mode_phone_shift (5499629753962641227) -->
-    <skip />
+    <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Το Shift ενεργοποιημένο"</string>
+    <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Το Caps lock είναι ενεργοποιημένο"</string>
+    <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Το Shift είναι απενεργοποιημένο"</string>
+    <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"Λειτουργία συμβόλων"</string>
+    <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"Λειτουργία γραμμάτων"</string>
+    <string name="spoken_description_mode_phone" msgid="6520207943132026264">"Λειτουργία τηλεφώνου"</string>
+    <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"Λειτουργία συμβόλων τηλεφώνου"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Φωνητική είσοδος"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Η φωνητική είσοδος δεν υποστηρίζεται αυτή τη στιγμή για τη γλώσσα σας, ωστόσο λειτουργεί στα Αγγλικά."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Οι φωνητικές εντολές χρησιμοποιούν την τεχνολογία αναγνώρισης φωνής της Google. Ισχύει "<a href="http://m.google.com/privacy">"η Πολιτική Απορρήτου για κινητά"</a>"."</string>
diff --git a/java/res/values-es-rUS/strings.xml b/java/res/values-es-rUS/strings.xml
index 1d01a1f..ce0040f 100644
--- a/java/res/values-es-rUS/strings.xml
+++ b/java/res/values-es-rUS/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Corrección de texto"</string>
     <string name="misc_category" msgid="6894192814868233453">"Otras opciones"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Configuración avanzada"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Opciones para expertos"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Retraso en rechazo de alerta de tecla"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Sin demora"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Predeterminada"</string>
@@ -79,8 +78,8 @@
     <string name="spoken_no_text_entered" msgid="7479685225597344496">"No se ingresó texto."</string>
     <string name="spoken_description_unknown" msgid="3197434010402179157">"Clave de código %d"</string>
     <string name="spoken_description_shift" msgid="244197883292549308">"Mayús"</string>
-    <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"Se activó el modo Alternancia (toca para inhabilitarlo)."</string>
-    <string name="spoken_description_caps_lock" msgid="3276478269526304432">"Se activó el bloqueo de mayúsculas (toca para inhabilitarlo)."</string>
+    <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"Se activó el modo Mayúscula (toca para desactivarlo)."</string>
+    <string name="spoken_description_caps_lock" msgid="3276478269526304432">"Se activó el bloqueo de mayúsculas (toca para desactivarlo)."</string>
     <string name="spoken_description_delete" msgid="8740376944276199801">"Borrar"</string>
     <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Símbolos"</string>
     <string name="spoken_description_to_alpha" msgid="23129338819771807">"Letras"</string>
@@ -92,9 +91,9 @@
     <string name="spoken_description_smiley" msgid="2256309826200113918">"Carita sonriente"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"Volver"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"Punto"</string>
-    <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Se habilitó el modo Alternancia."</string>
-    <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Se habilitó el bloqueo de mayúsculas."</string>
-    <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Se inhabilitó el modo Alternancia."</string>
+    <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Se activó el modo Mayúscula."</string>
+    <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Se activó el bloqueo de mayúsculas."</string>
+    <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Se desactivó el modo Mayúscula"</string>
     <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"Modo Símbolos"</string>
     <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"Modo Letras"</string>
     <string name="spoken_description_mode_phone" msgid="6520207943132026264">"Modo Teléfono"</string>
diff --git a/java/res/values-es/donottranslate-more-keys.xml b/java/res/values-es/donottranslate-more-keys.xml
index ec8b6e4..4833d69 100644
--- a/java/res/values-es/donottranslate-more-keys.xml
+++ b/java/res/values-es/donottranslate-more-keys.xml
@@ -67,7 +67,7 @@
          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>
-    <!-- U+00BF: "¿" INVERTED QUESTION MARK
-         U+00A1: "¡" INVERTED EXCLAMATION MARK -->
-    <string name="more_keys_for_punctuation">"\\,,\?,!,&#x00BF;,&#x00A1;,:,-,\',\",),(,/,;,+,&amp;,\@"</string>
+    <!-- U+00A1: "¡" INVERTED EXCLAMATION MARK
+         U+00BF: "¿" INVERTED QUESTION MARK -->
+    <string name="more_keys_for_punctuation">"!fixedColumnOrder!8,\",\',-,&#x00A1;,!,&#x00BF;,\\,,\?,\@,&amp;,+,;,:,/,(,)"</string>
 </resources>
diff --git a/java/res/values-et/strings.xml b/java/res/values-et/strings.xml
index ce7935c..08bfb83 100644
--- a/java/res/values-et/strings.xml
+++ b/java/res/values-et/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Teksti parandamine"</string>
     <string name="misc_category" msgid="6894192814868233453">"Muud valikud"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Täpsemad seaded"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Valikud ekspertidele"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Hüpiku loobumisviivitus"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Viivituseta"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Vaikeseade"</string>
diff --git a/java/res/values-fa/strings.xml b/java/res/values-fa/strings.xml
index 954fe99..61abde7 100644
--- a/java/res/values-fa/strings.xml
+++ b/java/res/values-fa/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"تصحیح متن"</string>
     <string name="misc_category" msgid="6894192814868233453">"سایر گزینه ها"</string>
     <string name="advanced_settings" msgid="362895144495591463">"تنظیمات پیشرفته"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"گزینه‌هایی برای حرفه‌ای‌ها"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"تأخیر در رد کردن کلید نمایشی"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"بدون تأخیر"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"پیش فرض"</string>
diff --git a/java/res/values-fi/strings.xml b/java/res/values-fi/strings.xml
index 39110dd..8f2add5 100644
--- a/java/res/values-fi/strings.xml
+++ b/java/res/values-fi/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Tekstin korjaus"</string>
     <string name="misc_category" msgid="6894192814868233453">"Muut vaihtoehdot"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Lisäasetukset"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Valinnat asiantuntijoille"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Näppäimen hylkäysviive"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Ei viivettä"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Oletus"</string>
diff --git a/java/res/values-hi/strings.xml b/java/res/values-hi/strings.xml
index fc3e9fd..37fce39 100644
--- a/java/res/values-hi/strings.xml
+++ b/java/res/values-hi/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"पाठ सुधार"</string>
     <string name="misc_category" msgid="6894192814868233453">"अन्य विकल्प"</string>
     <string name="advanced_settings" msgid="362895144495591463">"उन्नत सेटिंग"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"विशेषज्ञों के लिए विकल्‍प"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"कुंजी पॉपअप खारिज़ विलंब"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"कोई विलंब नहीं"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"डिफ़ॉल्ट"</string>
@@ -92,9 +91,9 @@
     <string name="spoken_description_smiley" msgid="2256309826200113918">"मुस्कुराता चेहरा"</string>
     <string name="spoken_description_return" msgid="8178083177238315647">"रिटर्न"</string>
     <string name="spoken_description_dot" msgid="40711082435231673">"बिंदु"</string>
-    <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift सक्षम किया गया है"</string>
-    <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock सक्षम किया गया है"</string>
-    <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift अक्षम किया गया है"</string>
+    <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift सक्षम किया गया"</string>
+    <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock सक्षम किया गया"</string>
+    <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift अक्षम किया गया"</string>
     <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"प्रतीक मोड"</string>
     <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"अक्षर मोड"</string>
     <string name="spoken_description_mode_phone" msgid="6520207943132026264">"फ़ोन मोड"</string>
diff --git a/java/res/values-hr/strings.xml b/java/res/values-hr/strings.xml
index b537caf..0c6e32c 100644
--- a/java/res/values-hr/strings.xml
+++ b/java/res/values-hr/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Ispravak teksta"</string>
     <string name="misc_category" msgid="6894192814868233453">"Ostale opcije"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Napredne postavke"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Opcije za stručnjake"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Odgoda prikaza tipki"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Bez odgode"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Zadano"</string>
diff --git a/java/res/values-hu/strings.xml b/java/res/values-hu/strings.xml
index dc094cb..2a31321 100644
--- a/java/res/values-hu/strings.xml
+++ b/java/res/values-hu/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Szövegjavítás"</string>
     <string name="misc_category" msgid="6894192814868233453">"Egyéb beállítások"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Speciális beállítások"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Beállítások gyakorlott felhasználóknak"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Gombeltüntetés késése"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Nincs késés"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Alapbeállítás"</string>
diff --git a/java/res/values-in/strings.xml b/java/res/values-in/strings.xml
index 364e360..5ebf834 100644
--- a/java/res/values-in/strings.xml
+++ b/java/res/values-in/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Koreksi teks"</string>
     <string name="misc_category" msgid="6894192814868233453">"Opsi lain"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Setelan lanjutan"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Opsi untuk ahli"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Tundaan singkir munculan kunci"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Tanpa penundaan"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Bawaan"</string>
@@ -97,8 +96,8 @@
     <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift dinonaktifkan"</string>
     <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"Mode simbol"</string>
     <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"Mode huruf"</string>
-    <string name="spoken_description_mode_phone" msgid="6520207943132026264">"Mode ponsel"</string>
-    <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"Mode simbol ponsel"</string>
+    <string name="spoken_description_mode_phone" msgid="6520207943132026264">"Mode telepon"</string>
+    <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"Mode simbol telepon"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Masukan suara"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Masukan suara saat ini tidak didukung untuk bahasa Anda, tetapi bekerja dalam Bahasa Inggris."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Masukan suara menggunakan pengenalan ucapan Google. "<a href="http://m.google.com/privacy">"Kebijakan Privasi Seluler"</a>" berlaku."</string>
diff --git a/java/res/values-it/strings.xml b/java/res/values-it/strings.xml
index dae8944..6fb0119 100644
--- a/java/res/values-it/strings.xml
+++ b/java/res/values-it/strings.xml
@@ -65,7 +65,7 @@
     <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : parola salvata"</string>
     <string name="label_go_key" msgid="1635148082137219148">"Vai"</string>
     <string name="label_next_key" msgid="362972844525672568">"Avanti"</string>
-    <string name="label_previous_key" msgid="1211868118071386787">"Prec."</string>
+    <string name="label_previous_key" msgid="1211868118071386787">"Indietro"</string>
     <string name="label_done_key" msgid="2441578748772529288">"Fine"</string>
     <string name="label_send_key" msgid="2815056534433717444">"Invia"</string>
     <string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
diff --git a/java/res/values-iw/donottranslate-more-keys.xml b/java/res/values-iw/donottranslate-more-keys.xml
index 865aac6..c5431b6 100644
--- a/java/res/values-iw/donottranslate-more-keys.xml
+++ b/java/res/values-iw/donottranslate-more-keys.xml
@@ -29,8 +29,8 @@
     <integer name="keycode_for_left_parenthesis">0x0029</integer>
     <!-- U+0028: "(" LEFT PARENTHESIS -->
     <integer name="keycode_for_right_parenthesis">0x0028</integer>
-    <string name="more_keys_for_left_parenthesis">[|],{|},&lt;|&gt;</string>
-    <string name="more_keys_for_right_parenthesis">]|[,}|{,&gt;|&lt;</string>
+    <string name="more_keys_for_left_parenthesis">!fixedColumnOrder!3,&lt;|&gt;,{|},[|]</string>
+    <string name="more_keys_for_right_parenthesis">!fixedColumnOrder!3,&gt;|&lt;,}|{,]|[</string>
     <!-- U+003E: ">" GREATER-THAN SIGN -->
     <integer name="keycode_for_less_than">0x003E</integer>
     <!-- U+003C: "<" LESS-THAN SIGN -->
@@ -50,8 +50,8 @@
          U+201D: "”" RIGHT DOUBLE QUOTATION MARK
          U+201E: "„" DOUBLE LOW-9 QUOTATION MARK
          U+201F: "‟" DOUBLE HIGH-REVERSED-9 QUOTATION MARK -->
-    <string name="more_keys_for_less_than">&#x2264;|&#x2265;,&#x00AB;|&#x00BB;,&#x2039;|&#x203A;</string>
-    <string name="more_keys_for_greater_than">&#x2265;|&#x2264;,&#x00BB;|&#x00AB;,&#x203A;|&#x2039;</string>
+    <string name="more_keys_for_less_than">!fixedColumnOrder!3,&#x2039;|&#x203A;,&#x2264;|&#x2265;,&#x00AB;|&#x00BB;</string>
+    <string name="more_keys_for_greater_than">!fixedColumnOrder!3,&#x203A;|&#x2039;,&#x2265;|&#x2264;,&#x00BB;|&#x00AB;</string>
     <!-- U+005D: "]" RIGHT SQUARE BRACKET -->
     <integer name="keycode_for_left_square_bracket">0x005D</integer>
     <!-- U+005B: "[" LEFT SQUARE BRACKET -->
@@ -60,12 +60,10 @@
     <integer name="keycode_for_left_curly_bracket">0x007D</integer>
     <!-- U+007B: "{" LEFT CURLY BRACKET -->
     <integer name="keycode_for_right_curly_bracket">0x007B</integer>
-    <!-- TODO: Neither DroidSans nor Roboto have the glyph for U+201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK. -->
-    <!-- <string name="more_keys_for_double_quote">&#x201C;,&#x201D;,&#x201E;,&#x201F;,&#x00AB;,&#x00BB;</string> -->
-    <!-- The 4-more keys will be displayed in order of "3,1,2,4". -->
-    <string name="more_keys_for_double_quote">&#x201D;,&#x00AB;|&#x00BB;,&#x201C;,&#x00BB;|&#x00AB;</string>
-    <!-- TODO: Neither DroidSans nor Roboto have the glyph for U+201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK. -->
-    <!-- <string name="more_keys_for_tablet_double_quote">&#x201C;,&#x201D;,&#x201E;,&#x201F;,&#x00AB;,&#x00BB;,&#x2018;,&#x2019;,&#x201A;,&#x201B;</string> -->
-    <!-- The 8-more keys with maxMoreKeysColumn=4 will be displayed in order of "3,1,2,4|7,5,6,8". -->
-    <string name="more_keys_for_tablet_double_quote">&#x201D;,&#x00AB;|&#x00BB;,&#x201C;,&#x00BB;|&#x00AB;,&#x2019;,&#x201A;,&#x2018;,&#x201B;</string>
+    <!-- TODO: Neither DroidSans nor Roboto have the glyph for U+201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK -->
+    <!-- <string name="more_keys_for_double_quote">&#x201C;,&#x201D;,&#x201E;,&#x201F;,&#x00AB;|&#x00BB;,&#x00BB;|&#x00AB;</string> -->
+    <string name="more_keys_for_double_quote">!fixedColumnOrder!4,&#x201C;,&#x201D;,&#x00AB;|&#x00BB;,&#x00BB;|&#x00AB;</string>
+    <!-- TODO: Neither DroidSans nor Roboto have the glyph for U+201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK -->
+    <!-- <string name="more_keys_for_tablet_double_quote">!fixedColumnOrder!6,&#x201C;,&#x201D;,&#x201E;,&#x201F;,&#x00AB;|&#x00BB;,&#x00BB|&#x00AB;;,&#x2018;,&#x2019;,&#x201A;,&#x201B;</string> -->
+    <string name="more_keys_for_tablet_double_quote">!fixedColumnOrder!4,&#x201C;,&#x201D;,&#x00AB;|&#x00BB;,&#x00BB;|&#x00AB;,&#x2018;,&#x2019;,&#x201A;,&#x201B;</string>
 </resources>
diff --git a/java/res/values-iw/strings.xml b/java/res/values-iw/strings.xml
index baca298..bd0e17d 100644
--- a/java/res/values-iw/strings.xml
+++ b/java/res/values-iw/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"תיקון טקסט"</string>
     <string name="misc_category" msgid="6894192814868233453">"אפשרויות אחרות"</string>
     <string name="advanced_settings" msgid="362895144495591463">"הגדרות מתקדמות"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"אפשרויות למומחים"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"עיכוב סגירת חלון קופץ של מקש"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"ללא עיכוב"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"ברירת מחדל"</string>
diff --git a/java/res/values-ja/strings.xml b/java/res/values-ja/strings.xml
index ea4718a..491d272 100644
--- a/java/res/values-ja/strings.xml
+++ b/java/res/values-ja/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"テキストの修正"</string>
     <string name="misc_category" msgid="6894192814868233453">"他のオプション"</string>
     <string name="advanced_settings" msgid="362895144495591463">"詳細設定"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"上級者向けオプション"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"キーのポップアップ時間"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"すぐに消去"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"デフォルト"</string>
diff --git a/java/res/values-ko/strings.xml b/java/res/values-ko/strings.xml
index 40bb4df..b8fa29d 100644
--- a/java/res/values-ko/strings.xml
+++ b/java/res/values-ko/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"텍스트 수정"</string>
     <string name="misc_category" msgid="6894192814868233453">"기타 옵션"</string>
     <string name="advanced_settings" msgid="362895144495591463">"고급 설정"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"전문가용 옵션"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"키 팝업 해제 지연"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"지연 없음"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"기본값"</string>
@@ -97,7 +96,7 @@
     <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift 사용중지"</string>
     <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"기호 모드"</string>
     <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"문자 모드"</string>
-    <string name="spoken_description_mode_phone" msgid="6520207943132026264">"전화 모드"</string>
+    <string name="spoken_description_mode_phone" msgid="6520207943132026264">"다이얼 모드"</string>
     <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"전화 기호 모드"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"음성 입력"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"음성 입력은 현재 자국어로 지원되지 않으며 영어로 작동됩니다."</string>
diff --git a/java/res/values-lt/strings.xml b/java/res/values-lt/strings.xml
index 9ab6967..2008045 100644
--- a/java/res/values-lt/strings.xml
+++ b/java/res/values-lt/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Teksto taisymas"</string>
     <string name="misc_category" msgid="6894192814868233453">"Kitos parinktys"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Išplėstiniai nustatymai"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Parinktys ekspertams"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Pagr. išš. l. atsis. d."</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Be delsos"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Numatytasis"</string>
diff --git a/java/res/values-lv/strings.xml b/java/res/values-lv/strings.xml
index d380b5e..b41dd90 100644
--- a/java/res/values-lv/strings.xml
+++ b/java/res/values-lv/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Teksta korekcija"</string>
     <string name="misc_category" msgid="6894192814868233453">"Citas opcijas"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Papildu iestatījumi"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Opcijas ekspertiem"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Taust. uzn. loga noraid. aizk."</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Bez aizkaves"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Noklusējums"</string>
diff --git a/java/res/values-ms/strings.xml b/java/res/values-ms/strings.xml
index de9a215..2dfb627 100644
--- a/java/res/values-ms/strings.xml
+++ b/java/res/values-ms/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Pembetulan teks"</string>
     <string name="misc_category" msgid="6894192814868233453">"Pilihan lain"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Tetapan terperinci"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Pilihan untuk pakar"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Pop tmbl knci ketpkn lengah"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Tiada lengah"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Lalai"</string>
diff --git a/java/res/values-nb/strings.xml b/java/res/values-nb/strings.xml
index 19cc230..47cafda 100644
--- a/java/res/values-nb/strings.xml
+++ b/java/res/values-nb/strings.xml
@@ -79,8 +79,8 @@
     <string name="spoken_no_text_entered" msgid="7479685225597344496">"Ingen tekst er skrevet inn"</string>
     <string name="spoken_description_unknown" msgid="3197434010402179157">"Tastaturkode %d"</string>
     <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
-    <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"Shift er slått på (trykk for å deaktivere)"</string>
-    <string name="spoken_description_caps_lock" msgid="3276478269526304432">"Caps Lock er slått på (trykk for å deaktivere)"</string>
+    <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"Shift er på (trykk for å deaktivere)"</string>
+    <string name="spoken_description_caps_lock" msgid="3276478269526304432">"Caps Lock er på (trykk for å deaktivere)"</string>
     <string name="spoken_description_delete" msgid="8740376944276199801">"Slett"</string>
     <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Symboler"</string>
     <string name="spoken_description_to_alpha" msgid="23129338819771807">"Bokstaver"</string>
diff --git a/java/res/values-nl/strings.xml b/java/res/values-nl/strings.xml
index 4e7cd53..5e93e04 100644
--- a/java/res/values-nl/strings.xml
+++ b/java/res/values-nl/strings.xml
@@ -94,10 +94,10 @@
     <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift ingeschakeld"</string>
     <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps Lock ingeschakeld"</string>
     <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift uitgeschakeld"</string>
-    <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"Symbolenmodus"</string>
-    <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"Brievenmodus"</string>
-    <string name="spoken_description_mode_phone" msgid="6520207943132026264">"Telefoonmodus"</string>
-    <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"Telefoonsymbolenmodus"</string>
+    <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"Symbolen"</string>
+    <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"Alfanumeriek toetsenbord"</string>
+    <string name="spoken_description_mode_phone" msgid="6520207943132026264">"Toetsenbord telefoon"</string>
+    <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"Telefoonsymbolen"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Spraakinvoer"</string>
     <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Spraakinvoer wordt momenteel niet ondersteund in uw taal, maar is wel beschikbaar in het Engels."</string>
     <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Spraakinvoer maakt gebruik van de spraakherkenning van Google. Het "<a href="http://m.google.com/privacy">"Privacybeleid van Google Mobile"</a>" is van toepassing."</string>
diff --git a/java/res/values-pl/strings.xml b/java/res/values-pl/strings.xml
index c0e3132..4fc54d8 100644
--- a/java/res/values-pl/strings.xml
+++ b/java/res/values-pl/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Poprawianie tekstu"</string>
     <string name="misc_category" msgid="6894192814868233453">"Inne opcje"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Ustawienia zaawansowane"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Opcje dla ekspertów"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Opóźnienie znikania klawiszy"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Bez opóźnienia"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Wartość domyślna"</string>
@@ -66,7 +65,7 @@
     <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Zapisano"</string>
     <string name="label_go_key" msgid="1635148082137219148">"OK"</string>
     <string name="label_next_key" msgid="362972844525672568">"Dalej"</string>
-    <string name="label_previous_key" msgid="1211868118071386787">"Poprz"</string>
+    <string name="label_previous_key" msgid="1211868118071386787">"Wstecz"</string>
     <string name="label_done_key" msgid="2441578748772529288">"OK"</string>
     <string name="label_send_key" msgid="2815056534433717444">"Wyślij"</string>
     <string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
diff --git a/java/res/values-pt-rPT/strings.xml b/java/res/values-pt-rPT/strings.xml
index be6544b..a77190f 100644
--- a/java/res/values-pt-rPT/strings.xml
+++ b/java/res/values-pt-rPT/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Correção de texto"</string>
     <string name="misc_category" msgid="6894192814868233453">"Outras opções"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Definições avançadas"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Opções para especialistas"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Atraso p/ ignorar pop-up"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Sem atraso"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Predefinido"</string>
diff --git a/java/res/values-ro/strings.xml b/java/res/values-ro/strings.xml
index 4ed4956..6eae664 100644
--- a/java/res/values-ro/strings.xml
+++ b/java/res/values-ro/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Corectare text"</string>
     <string name="misc_category" msgid="6894192814868233453">"Alte opţiuni"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Setări avansate"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Opţiuni pentru experţi"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Înt. înch. pop-up esenţ."</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Fără întârziere"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Prestabilit"</string>
@@ -79,8 +78,8 @@
     <string name="spoken_no_text_entered" msgid="7479685225597344496">"Nu a fost introdus text"</string>
     <string name="spoken_description_unknown" msgid="3197434010402179157">"Tasta cu codul %d"</string>
     <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
-    <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"Tasta Shift este activată (apăsaţi pentru a dezactiva)"</string>
-    <string name="spoken_description_caps_lock" msgid="3276478269526304432">"Tasta Caps Lock este activată (apăsaţi pentru a dezactiva)"</string>
+    <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"Tasta Shift este activată (apăsaţi pentru a o dezactiva)"</string>
+    <string name="spoken_description_caps_lock" msgid="3276478269526304432">"Tasta Caps Lock este activată (apăsaţi pentru a o dezactiva)"</string>
     <string name="spoken_description_delete" msgid="8740376944276199801">"Delete"</string>
     <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Simboluri"</string>
     <string name="spoken_description_to_alpha" msgid="23129338819771807">"Litere"</string>
diff --git a/java/res/values-ru/strings.xml b/java/res/values-ru/strings.xml
index 0571073..3632062 100644
--- a/java/res/values-ru/strings.xml
+++ b/java/res/values-ru/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Исправление текста"</string>
     <string name="misc_category" msgid="6894192814868233453">"Другие варианты"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Расширенные настройки"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Для опытных пользователей"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Задержка закрытия"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Без задержки"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"По умолчанию"</string>
@@ -95,8 +94,8 @@
     <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Верхний регистр включен"</string>
     <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps Lock включен"</string>
     <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Верхний регистр отключен"</string>
-    <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"Режим символов"</string>
-    <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"Режим ввода букв"</string>
+    <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"Режим добавления символов"</string>
+    <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"Режим ввода текста"</string>
     <string name="spoken_description_mode_phone" msgid="6520207943132026264">"Режим набора номера"</string>
     <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"Режим телефонных символов"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Голосовой ввод"</string>
diff --git a/java/res/values-sk/strings.xml b/java/res/values-sk/strings.xml
index 34cf278..16c30b5 100644
--- a/java/res/values-sk/strings.xml
+++ b/java/res/values-sk/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Oprava textu"</string>
     <string name="misc_category" msgid="6894192814868233453">"Ďalšie možnosti"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Rozšírené nastavenia"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Možnosti pre odborníkov"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Onesk. zrušenia kľúč. kon. okna"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Bez oneskorenia"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Predvolená"</string>
diff --git a/java/res/values-sl/strings.xml b/java/res/values-sl/strings.xml
index e29107b..586b0e2 100644
--- a/java/res/values-sl/strings.xml
+++ b/java/res/values-sl/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Popravljanje besedila"</string>
     <string name="misc_category" msgid="6894192814868233453">"Druge možnosti"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Dodatne nastavitve"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Možnosti za strokovnjake"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Trajanje povečanja tipke"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Brez zakasnitve"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Privzeto"</string>
diff --git a/java/res/values-sr/strings.xml b/java/res/values-sr/strings.xml
index 6e04ebf..54b64dc 100644
--- a/java/res/values-sr/strings.xml
+++ b/java/res/values-sr/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Исправљање текста"</string>
     <string name="misc_category" msgid="6894192814868233453">"Друге опције"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Напредна подешавања"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Опције за стручњаке"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Одложи одбац. иск. прозора тастера"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Без одлагања"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Подразумевано"</string>
diff --git a/java/res/values-sv/strings.xml b/java/res/values-sv/strings.xml
index 17cb5ab..33964d0 100644
--- a/java/res/values-sv/strings.xml
+++ b/java/res/values-sv/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Textkorrigering"</string>
     <string name="misc_category" msgid="6894192814868233453">"Andra alternativ"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Avancerade inställningar"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Alternativ för experter"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Ta bort popup-fördröjning"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Fördröj inte"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Standard"</string>
diff --git a/java/res/values-sw600dp/config.xml b/java/res/values-sw600dp/config.xml
index ecc5b71..689b209 100644
--- a/java/res/values-sw600dp/config.xml
+++ b/java/res/values-sw600dp/config.xml
@@ -19,8 +19,6 @@
 -->
 
 <resources>
-    <bool name="config_enable_show_settings_key_option">true</bool>
-    <bool name="config_default_show_settings_key">false</bool>
     <bool name="config_enable_show_voice_key_option">false</bool>
     <bool name="config_enable_show_popup_on_keypress_option">false</bool>
     <bool name="config_enable_bigram_suggestions_option">false</bool>
diff --git a/java/res/values-sw768dp/config.xml b/java/res/values-sw768dp/config.xml
index c1f9179..d46e5f1 100644
--- a/java/res/values-sw768dp/config.xml
+++ b/java/res/values-sw768dp/config.xml
@@ -19,8 +19,6 @@
 -->
 
 <resources>
-    <bool name="config_enable_show_settings_key_option">false</bool>
-    <bool name="config_default_show_settings_key">true</bool>
     <bool name="config_enable_show_voice_key_option">false</bool>
     <bool name="config_enable_show_popup_on_keypress_option">false</bool>
     <bool name="config_enable_bigram_suggestions_option">false</bool>
diff --git a/java/res/values-th/strings.xml b/java/res/values-th/strings.xml
index 815273b..42b8643 100644
--- a/java/res/values-th/strings.xml
+++ b/java/res/values-th/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"การแก้ไขข้อความ"</string>
     <string name="misc_category" msgid="6894192814868233453">"ตัวเลือกอื่นๆ"</string>
     <string name="advanced_settings" msgid="362895144495591463">"การตั้งค่าขั้นสูง"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"ตัวเลือกสำหรับผู้เชี่ยวชาญ"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"หน่วงเวลาก่อนปิดป๊อปอัพหลัก"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"ไม่มีการหน่วงเวลา"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"ค่าเริ่มต้น"</string>
diff --git a/java/res/values-tl/strings.xml b/java/res/values-tl/strings.xml
index f83d8b3..8828af9 100644
--- a/java/res/values-tl/strings.xml
+++ b/java/res/values-tl/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Pagwawasto ng teksto"</string>
     <string name="misc_category" msgid="6894192814868233453">"Iba pang mga pagpipilian"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Mga advanced na setting"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Mga pagpipilian para sa mga dalubhasa"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Balewala antala key popup"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Walang antala"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Default"</string>
diff --git a/java/res/values-tr/strings.xml b/java/res/values-tr/strings.xml
index 56424b0..8e9dafa 100644
--- a/java/res/values-tr/strings.xml
+++ b/java/res/values-tr/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Metin düzeltme"</string>
     <string name="misc_category" msgid="6894192814868233453">"Diğer seçenekler"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Gelişmiş ayarlar"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Uzmanlar için seçenekler"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Tuş popup içn kaptm ertlm"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Gecikme yok"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Varsayılan"</string>
diff --git a/java/res/values-uk/strings.xml b/java/res/values-uk/strings.xml
index 8d4fbe0..e5e2ca4 100644
--- a/java/res/values-uk/strings.xml
+++ b/java/res/values-uk/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Виправлення тексту"</string>
     <string name="misc_category" msgid="6894192814868233453">"Інші опції"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Розширені налаштування"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Налаштування для досвідчених користувачів"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Затримка клавіши закриття"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Без затримки"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"За умовчанням"</string>
diff --git a/java/res/values-vi/strings.xml b/java/res/values-vi/strings.xml
index ab3d1b1..cf9f25d 100644
--- a/java/res/values-vi/strings.xml
+++ b/java/res/values-vi/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"Sửa văn bản"</string>
     <string name="misc_category" msgid="6894192814868233453">"Tùy chọn khác"</string>
     <string name="advanced_settings" msgid="362895144495591463">"Cài đặt nâng cao"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"Tùy chọn dành cho chuyên gia"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Loại bỏ hiển thị phím trễ"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Không có tgian trễ"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Mặc định"</string>
diff --git a/java/res/values-zh-rCN/strings.xml b/java/res/values-zh-rCN/strings.xml
index a3edc5a..0d54a2e 100644
--- a/java/res/values-zh-rCN/strings.xml
+++ b/java/res/values-zh-rCN/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"文本更正"</string>
     <string name="misc_category" msgid="6894192814868233453">"其他选项"</string>
     <string name="advanced_settings" msgid="362895144495591463">"高级设置"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"高级选项"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"关闭弹出键时的延迟"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"无延迟"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"默认"</string>
diff --git a/java/res/values-zh-rTW/strings.xml b/java/res/values-zh-rTW/strings.xml
index 302aa83..24c3de6 100644
--- a/java/res/values-zh-rTW/strings.xml
+++ b/java/res/values-zh-rTW/strings.xml
@@ -35,8 +35,7 @@
     <string name="correction_category" msgid="2236750915056607613">"文字修正"</string>
     <string name="misc_category" msgid="6894192814868233453">"其他選項"</string>
     <string name="advanced_settings" msgid="362895144495591463">"進階設定"</string>
-    <!-- no translation found for advanced_settings_summary (4487980456152830271) -->
-    <skip />
+    <string name="advanced_settings_summary" msgid="4487980456152830271">"專家選項"</string>
     <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"關閉彈出式鍵盤的延遲時間"</string>
     <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"不延遲"</string>
     <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"預設"</string>
diff --git a/java/res/values-zu/strings.xml b/java/res/values-zu/strings.xml
index 5129dfd..6fbb1a9 100644
--- a/java/res/values-zu/strings.xml
+++ b/java/res/values-zu/strings.xml
@@ -80,7 +80,7 @@
     <string name="spoken_description_unknown" msgid="3197434010402179157">"Ikhodi yokhiye %d"</string>
     <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
     <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"U-Shift uvuliwe (thepha ukuwuvimbela)"</string>
-    <string name="spoken_description_caps_lock" msgid="3276478269526304432">"Ofeleba Bavuliwe (thepha ukubavimbela)"</string>
+    <string name="spoken_description_caps_lock" msgid="3276478269526304432">"Ofeleba bavuliwe (thepha ukubavimbela)"</string>
     <string name="spoken_description_delete" msgid="8740376944276199801">"Susa"</string>
     <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Amasimbuli"</string>
     <string name="spoken_description_to_alpha" msgid="23129338819771807">"Imbhalo"</string>
@@ -96,7 +96,7 @@
     <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Ofeleba bavunyelwe"</string>
     <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"U-Shift uvimbelwe"</string>
     <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"Imodi yezimpawu"</string>
-    <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"Imodi yamagama"</string>
+    <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"Imodi yezinhlamvu"</string>
     <string name="spoken_description_mode_phone" msgid="6520207943132026264">"Imodi yefoni"</string>
     <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"Imodi yezimpawu zefoni"</string>
     <string name="voice_warning_title" msgid="4419354150908395008">"Okufakwa ngezwi"</string>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index 2dea8fb..f91b0a3 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -357,14 +357,6 @@
         </attr>
         <attr name="navigateAction" format="boolean" />
         <attr name="passwordInput" format="boolean" />
-        <attr name="hasSettingsKey" format="boolean" />
-        <!-- This should be aligned with KeyboardID.F2KEY_MODE_* -->
-        <attr name="f2KeyMode" format="enum">
-            <enum name="none" value="0" />
-            <enum name="settings" value="1" />
-            <enum name="shortcutIme" value="2" />
-            <enum name="shortcutImeOrSettings" value="3" />
-        </attr>
         <attr name="clobberSettingsKey" format="boolean" />
         <attr name="shortcutKeyEnabled" format="boolean" />
         <attr name="hasShortcutKey" format="boolean" />
diff --git a/java/res/values/config.xml b/java/res/values/config.xml
index cb13ba3..9e962ee 100644
--- a/java/res/values/config.xml
+++ b/java/res/values/config.xml
@@ -20,8 +20,6 @@
 
 <resources>
     <bool name="config_use_fullscreen_mode">false</bool>
-    <bool name="config_enable_show_settings_key_option">true</bool>
-    <bool name="config_default_show_settings_key">false</bool>
     <bool name="config_enable_show_voice_key_option">true</bool>
     <bool name="config_enable_show_popup_on_keypress_option">true</bool>
     <bool name="config_enable_bigram_suggestions_option">true</bool>
diff --git a/java/res/values/donottranslate-more-keys.xml b/java/res/values/donottranslate-more-keys.xml
index c04e6d0..f1c2d2b 100644
--- a/java/res/values/donottranslate-more-keys.xml
+++ b/java/res/values/donottranslate-more-keys.xml
@@ -64,9 +64,8 @@
     <string name="more_keys_for_currency_euro">&#x00A2;,&#x00A3;,$,&#x00A5;,&#x20B1;</string>
     <string name="more_keys_for_currency_pound">&#x00A2;,$,&#x20AC;,&#x00A5;,&#x20B1;</string>
     <string name="more_keys_for_currency_general">&#x00A2;,$,&#x20AC;,&#x00A3;,&#x00A5;,&#x20B1;</string>
-    <string name="more_keys_for_smiley">":-)|:-) ,:-(|:-( ,;-)|;-) ,:-P|:-P ,=-O|=-O ,:-*|:-* ,:O|:O ,B-)|B-) ,:-$|:-$ ,:-!|:-! ,:-[|:-[ ,O:-)|O:-) ,:-\\\\|:-\\\\ ,:\'(|:\'( ,:-D|:-D "</string>
-    <string name="more_keys_for_punctuation">"\\,,\?,!,:,-,\',\",(,),/,;,+,&amp;,\@"</string>
-    <integer name="more_keys_keyboard_column_for_punctuation">7</integer>
+    <string name="more_keys_for_smiley">"!fixedColumnOrder!5,=-O|=-O ,:-P|:-P ,;-)|;-) ,:-(|:-( ,:-)|:-) ,:-!|:-! ,:-$|:-$ ,B-)|B-) ,:O|:O ,:-*|:-* ,:-D|:-D ,:\'(|:\'( ,:-\\\\|:-\\\\ ,O:-)|O:-) ,:-[|:-[ "</string>
+    <string name="more_keys_for_punctuation">"!fixedColumnOrder!7,\",\',-,:,!,\\,,\?,\@,&amp;,+,;,/,(,)"</string>
     <string name="keyhintlabel_for_punctuation"></string>
     <string name="keylabel_for_popular_domain">".com"</string>
     <!-- popular web domains for the locale - most popular, displayed on the keyboard -->
@@ -116,15 +115,12 @@
     <!-- U+207F: "ⁿ" SUPERSCRIPT LATIN SMALL LETTER N
          U+2205: "∅" EMPTY SET -->
     <string name="more_keys_for_symbols_0">&#x207F;,&#x2205;</string>
+    <string name="settings_as_more_key">\@icon/settingsKey|\@integer/key_settings</string>
     <string name="keylabel_for_comma">,</string>
-    <string name="keylabel_for_f1">,</string>
+    <string name="more_keys_for_comma"></string>
     <string name="keylabel_for_symbols_question">\?</string>
     <string name="keylabel_for_symbols_semicolon">;</string>
     <string name="keylabel_for_symbols_percent">%</string>
-    <string name="more_keys_for_comma"></string>
-    <string name="more_keys_for_f1"></string>
-    <string name="more_keys_for_f1_settings">\@icon/settingsKey|\@integer/key_settings</string>
-    <string name="more_keys_for_f1_navigate">\@icon/tabKey|\@integer/key_tab</string>
     <!-- U+00BF: "¿" INVERTED QUESTION MARK -->
     <string name="more_keys_for_symbols_question">&#x00BF;</string>
     <string name="more_keys_for_symbols_semicolon"></string>
@@ -154,18 +150,18 @@
     <integer name="keycode_for_left_parenthesis">0x0028</integer>
     <!-- U+0029: ")" RIGHT PARENTHESIS -->
     <integer name="keycode_for_right_parenthesis">0x0029</integer>
-    <string name="more_keys_for_left_parenthesis">[,{,&lt;</string>
-    <string name="more_keys_for_right_parenthesis">],},&gt;</string>
+    <string name="more_keys_for_left_parenthesis">!fixedColumnOrder!3,&lt;,{,[</string>
+    <string name="more_keys_for_right_parenthesis">!fixedColumnOrder!3,&gt;,},]</string>
     <!-- U+003C: "<" LESS-THAN SIGN -->
     <integer name="keycode_for_less_than">0x003C</integer>
     <!-- U+003E: ">" GREATER-THAN SIGN -->
     <integer name="keycode_for_greater_than">0x003E</integer>
-    <!-- U+2264: "≤" LESS-THAN OR EQUAL TO
+    <!-- U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+         U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+         U+2264: "≤" LESS-THAN OR EQUAL TO
          U+2265: "≥" GREATER-THAN EQUAL TO
          U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
          U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
-         U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
-         U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
          The following characters don't need BIDI mirroring.
          U+2018: "‘" LEFT SINGLE QUOTATION MARK
          U+2019: "’" RIGHT SINGLE QUOTATION MARK
@@ -175,8 +171,8 @@
          U+201D: "”" RIGHT DOUBLE QUOTATION MARK
          U+201E: "„" DOUBLE LOW-9 QUOTATION MARK
          U+201F: "‟" DOUBLE HIGH-REVERSED-9 QUOTATION MARK -->
-    <string name="more_keys_for_less_than">&#x2264;,&#x00AB;,&#x2039;</string>
-    <string name="more_keys_for_greater_than">&#x2265;,&#x00BB;,&#x203A;</string>
+    <string name="more_keys_for_less_than">!fixedColumnOrder!3,&#x2039;,&#x2264;,&#x00AB;</string>
+    <string name="more_keys_for_greater_than">!fixedColumnOrder!3,&#x203A;,&#x2265;,&#x00BB;</string>
     <!-- U+005B: "[" LEFT SQUARE BRACKET -->
     <integer name="keycode_for_left_square_bracket">0x005B</integer>
     <!-- U+005D: "]" RIGHT SQUARE BRACKET -->
@@ -185,14 +181,11 @@
     <integer name="keycode_for_left_curly_bracket">0x007B</integer>
     <!-- U+007D: "}" RIGHT CURLY BRACKET -->
     <integer name="keycode_for_right_curly_bracket">0x007D</integer>
-    <!-- The 4-more keys will be displayed in order of "3,1,2,4". -->
-    <string name="more_keys_for_single_quote">&#x2019;,&#x201A;,&#x2018;,&#x201B;</string>
+    <string name="more_keys_for_single_quote">!fixedColumnOrder!4,&#x2018;,&#x2019;,&#x201A;,&#x201B;</string>
     <!-- TODO: Neither DroidSans nor Roboto have the glyph for U+201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK. -->
-    <!-- <string name="more_keys_for_double_quote">&#x201C;,&#x201D;,&#x201E;,&#x201F;,&#x00AB;,&#x00BB;</string> -->
-    <!-- The 4-more keys will be displayed in order of "3,1,2,4". -->
-    <string name="more_keys_for_double_quote">&#x201D;,&#x00AB;,&#x201C;,&#x00BB;</string>
+    <!-- <string name="more_keys_for_double_quote">!fixedColumnOrder!6,&#x201C;,&#x201D;,&#x201E;,&#x201F;,&#x00AB;,&#x00BB;</string> -->
+    <string name="more_keys_for_double_quote">!fixedColumnOrder!4,&#x201C;,&#x201D;,&#x00AB;,&#x00BB;</string>
     <!-- TODO: Neither DroidSans nor Roboto have the glyph for U+201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK. -->
-    <!-- <string name="more_keys_for_tablet_double_quote">&#x201C;,&#x201D;,&#x201E;,&#x201F;,&#x00AB;,&#x00BB;,&#x2018;,&#x2019;,&#x201A;,&#x201B;</string> -->
-    <!-- The 8-more keys with maxMoreKeysColumn=4 will be displayed in order of "3,1,2,4|7,5,6,8". -->
-    <string name="more_keys_for_tablet_double_quote">&#x201D;,&#x00AB;,&#x201C;,&#x00BB;,&#x2019;,&#x201A;,&#x2018;,&#x201B;</string>
+    <!-- <string name="more_keys_for_tablet_double_quote">!fixedColumnOrder!6,&#x201C;,&#x201D;,&#x201E;,&#x201F;,&#x00AB;,&#x00BB;,&#x2018;,&#x2019;,&#x201A;,&#x201B;</string> -->
+    <string name="more_keys_for_tablet_double_quote">!fixedColumnOrder!4,&#x201C;,&#x201D;,&#x00AB;,&#x00BB;,&#x2018;,&#x2019;,&#x201A;,&#x201B;</string>
 </resources>
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index c8b6421..516c607 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -95,9 +95,6 @@
     <string name="prefs_suggestion_visibility_show_only_portrait_name">Show on portrait mode</string>
     <string name="prefs_suggestion_visibility_hide_name">Always hide</string>
 
-    <!-- Option to show/hide the settings key -->
-    <string name="prefs_settings_key">Show settings key</string>
-
     <!-- Option to decide the auto correction threshold score -->
     <!-- Option to enable auto correction [CHAR LIMIT=20]-->
     <string name="auto_correction">Auto correction</string>
diff --git a/java/res/xml-sw600dp/key_f2.xml b/java/res/xml-sw600dp/key_f2.xml
deleted file mode 100644
index b25afc1..0000000
--- a/java/res/xml-sw600dp/key_f2.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
-    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
-    <switch>
-        <case
-            latin:f2KeyMode="settings"
-        >
-            <Key
-                latin:keyStyle="settingsKeyStyle"
-                latin:keyWidth="fillBoth" />
-        </case>
-        <case
-            latin:f2KeyMode="shortcutIme"
-        >
-            <switch>
-                <case
-                    latin:shortcutKeyEnabled="true"
-                >
-                    <Key
-                        latin:keyStyle="shortcutKeyStyle"
-                        latin:keyWidth="fillBoth" />
-                </case>
-                <!-- shortcutKeyEnabled="false" -->
-                <default>
-                    <Spacer />
-                </default>
-            </switch>
-        </case>
-        <case
-            latin:f2KeyMode="shortcutImeOrSettings"
-        >
-            <switch>
-                <case
-                    latin:shortcutKeyEnabled="true"
-                >
-                    <Key
-                        latin:keyStyle="shortcutKeyStyle"
-                        latin:keyWidth="fillBoth" />
-                </case>
-                <!-- shortcutKeyEnabled="false" -->
-                <default>
-                    <Key
-                        latin:keyStyle="settingsKeyStyle"
-                        latin:keyWidth="fillBoth" />
-                </default>
-            </switch>
-        </case>
-        <!-- f2KeyMode="none" -->
-        <default>
-            <Spacer />
-        </default>
-    </switch>
-</merge>
diff --git a/java/res/xml-sw600dp/key_shortcut.xml b/java/res/xml-sw600dp/key_shortcut.xml
new file mode 100644
index 0000000..8869ab9
--- /dev/null
+++ b/java/res/xml-sw600dp/key_shortcut.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <switch>
+        <case
+            latin:shortcutKeyEnabled="true"
+            latin:clobberSettingsKey="false"
+        >
+            <Key
+                latin:keyStyle="shortcutKeyStyle"
+                latin:keyLabelFlags="hasPopupHint"
+                latin:moreKeys="@string/settings_as_more_key"
+                latin:keyWidth="fillBoth" />
+        </case>
+        <case
+            latin:shortcutKeyEnabled="true"
+            latin:clobberSettingsKey="true"
+        >
+            <Key
+                latin:keyStyle="shortcutKeyStyle"
+                latin:keyWidth="fillBoth" />
+        </case>
+        <case
+            latin:shortcutKeyEnabled="false"
+            latin:clobberSettingsKey="false"
+        >
+            <Key
+                latin:keyStyle="settingsKeyStyle"
+                latin:keyWidth="fillBoth" />
+        </case>
+        <!-- shortcutKeyEnabled="false" clobberSettingsKey="true" -->
+        <default>
+            <Spacer />
+        </default>
+    </switch>
+</merge>
diff --git a/java/res/xml-sw600dp/key_styles_common.xml b/java/res/xml-sw600dp/key_styles_common.xml
index e524aa3..bb75b1c 100644
--- a/java/res/xml-sw600dp/key_styles_common.xml
+++ b/java/res/xml-sw600dp/key_styles_common.xml
@@ -21,23 +21,6 @@
 <merge
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
 >
-    <!-- Base key style for the key which may have settings key as popup key -->
-    <switch>
-        <case
-            latin:clobberSettingsKey="true"
-        >
-            <key-style
-                latin:styleName="f2PopupStyle"
-                latin:backgroundType="functional" />
-        </case>
-        <default>
-            <key-style
-                latin:styleName="f2PopupStyle"
-                latin:keyLabelFlags="hasPopupHint"
-                latin:moreKeys="\@icon/settingsKey|\@integer/key_settings"
-                latin:backgroundType="functional" />
-        </default>
-    </switch>
     <switch>
         <case
             latin:keyboardSetElement="alphabetManualShifted|alphabetShiftLockShifted"
@@ -104,8 +87,7 @@
         latin:keyLabel=":-)"
         latin:keyOutputText=":-) "
         latin:keyLabelFlags="hasPopupHint|preserveCase"
-        latin:moreKeys="@string/more_keys_for_smiley"
-        latin:maxMoreKeysColumn="5" />
+        latin:moreKeys="@string/more_keys_for_smiley" />
     <key-style
         latin:styleName="shortcutKeyStyle"
         latin:code="@integer/key_shortcut"
@@ -113,7 +95,7 @@
         latin:keyIconDisabled="iconDisabledShortcutKey"
         latin:keyLabelFlags="preserveCase"
         latin:keyActionFlags="noKeyPreview|altCodeWhileTyping"
-        latin:parentStyle="f2PopupStyle" />
+        latin:backgroundType="functional" />
     <key-style
         latin:styleName="settingsKeyStyle"
         latin:code="@integer/key_settings"
diff --git a/java/res/xml-sw600dp/row_qwerty4.xml b/java/res/xml-sw600dp/row_qwerty4.xml
index b06508e..3c2f06d 100644
--- a/java/res/xml-sw600dp/row_qwerty4.xml
+++ b/java/res/xml-sw600dp/row_qwerty4.xml
@@ -71,6 +71,6 @@
             latin:keyXPos="-10.00%p"
             latin:keyWidth="0%p" />
         <include
-            latin:keyboardLayout="@xml/key_f2" />
+            latin:keyboardLayout="@xml/key_shortcut" />
     </Row>
 </merge>
diff --git a/java/res/xml-sw600dp/rows_number_normal.xml b/java/res/xml-sw600dp/rows_number_normal.xml
index 3141bbd..1c38a62 100644
--- a/java/res/xml-sw600dp/rows_number_normal.xml
+++ b/java/res/xml-sw600dp/rows_number_normal.xml
@@ -133,6 +133,6 @@
             latin:keyXPos="-11.00%p"
             latin:keyWidth="0%p" />
         <include
-            latin:keyboardLayout="@xml/key_f2" />
+            latin:keyboardLayout="@xml/key_shortcut" />
     </Row>
 </merge>
diff --git a/java/res/xml-sw600dp/rows_number_password.xml b/java/res/xml-sw600dp/rows_number_password.xml
index 0a71f74..59279fb 100644
--- a/java/res/xml-sw600dp/rows_number_password.xml
+++ b/java/res/xml-sw600dp/rows_number_password.xml
@@ -76,6 +76,6 @@
             latin:keyXPos="-11.00%p"
             latin:keyWidth="0%p" />
         <include
-            latin:keyboardLayout="@xml/key_f2" />
+            latin:keyboardLayout="@xml/key_shortcut" />
     </Row>
 </merge>
diff --git a/java/res/xml-sw600dp/rows_phone.xml b/java/res/xml-sw600dp/rows_phone.xml
index d61b4b2..4c896e9 100644
--- a/java/res/xml-sw600dp/rows_phone.xml
+++ b/java/res/xml-sw600dp/rows_phone.xml
@@ -127,6 +127,6 @@
             latin:keyXPos="-11.00%p"
             latin:keyWidth="0%p" />
         <include
-            latin:keyboardLayout="@xml/key_f2" />
+            latin:keyboardLayout="@xml/key_shortcut" />
     </Row>
 </merge>
diff --git a/java/res/xml-sw600dp/rows_symbols.xml b/java/res/xml-sw600dp/rows_symbols.xml
index 448e3bb..96695e8 100644
--- a/java/res/xml-sw600dp/rows_symbols.xml
+++ b/java/res/xml-sw600dp/rows_symbols.xml
@@ -160,14 +160,13 @@
             latin:keyWidth="39.750%p" />
         <Key
             latin:keyLabel="&quot;"
-            latin:moreKeys="@string/more_keys_for_tablet_double_quote"
-            latin:maxMoreKeysColumn="4" />
+            latin:moreKeys="@string/more_keys_for_tablet_double_quote" />
         <Key
             latin:keyLabel="_" />
         <Spacer
             latin:keyXPos="-10.00%p"
             latin:keyWidth="0%p" />
         <include
-            latin:keyboardLayout="@xml/key_f2" />
+            latin:keyboardLayout="@xml/key_shortcut" />
     </Row>
 </merge>
diff --git a/java/res/xml-sw600dp/rows_symbols_shift.xml b/java/res/xml-sw600dp/rows_symbols_shift.xml
index 05824b9..c5eee62 100644
--- a/java/res/xml-sw600dp/rows_symbols_shift.xml
+++ b/java/res/xml-sw600dp/rows_symbols_shift.xml
@@ -148,6 +148,6 @@
             latin:keyXPos="-10.00%p"
             latin:keyWidth="0%p" />
         <include
-            latin:keyboardLayout="@xml/key_f2" />
+            latin:keyboardLayout="@xml/key_shortcut" />
     </Row>
 </merge>
diff --git a/java/res/xml-sw768dp/key_settings.xml b/java/res/xml-sw768dp/key_settings.xml
new file mode 100644
index 0000000..0359a99
--- /dev/null
+++ b/java/res/xml-sw768dp/key_settings.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <switch>
+        <case
+            latin:clobberSettingsKey="false"
+        >
+            <Key
+                latin:keyStyle="settingsKeyStyle" />
+        </case>
+        <default>
+            <Spacer />
+        </default>
+    </switch>
+ </merge>
diff --git a/java/res/xml-sw768dp/key_styles_common.xml b/java/res/xml-sw768dp/key_styles_common.xml
index 07bdd7b..9da0d1f 100644
--- a/java/res/xml-sw768dp/key_styles_common.xml
+++ b/java/res/xml-sw768dp/key_styles_common.xml
@@ -86,8 +86,7 @@
         latin:keyLabel=":-)"
         latin:keyOutputText=":-) "
         latin:keyLabelFlags="hasPopupHint|preserveCase"
-        latin:moreKeys="@string/more_keys_for_smiley"
-        latin:maxMoreKeysColumn="5" />
+        latin:moreKeys="@string/more_keys_for_smiley" />
     <key-style
         latin:styleName="shortcutKeyStyle"
         latin:code="@integer/key_shortcut"
diff --git a/java/res/xml-sw768dp/row_qwerty4.xml b/java/res/xml-sw768dp/row_qwerty4.xml
index 84c4a37..24c081e 100644
--- a/java/res/xml-sw768dp/row_qwerty4.xml
+++ b/java/res/xml-sw768dp/row_qwerty4.xml
@@ -24,15 +24,8 @@
     <Row
         latin:keyWidth="8.047%p"
     >
-        <switch>
-            <case
-                latin:hasSettingsKey="true"
-            >
-                <Key
-                    latin:keyStyle="settingsKeyStyle"
-                    latin:keyWidth="8.047%p" />
-            </case>
-        </switch>
+        <include
+            latin:keyboardLayout="@xml/key_settings" />
         <Spacer
             latin:keyXPos="15.157%p"
             latin:keyWidth="0%p" />
diff --git a/java/res/xml-sw768dp/rows_number_normal.xml b/java/res/xml-sw768dp/rows_number_normal.xml
index cf947ab..60674cd 100644
--- a/java/res/xml-sw768dp/rows_number_normal.xml
+++ b/java/res/xml-sw768dp/rows_number_normal.xml
@@ -115,18 +115,9 @@
             latin:keyWidth="0%p" />
     </Row>
     <Row>
-        <switch>
-            <case latin:hasSettingsKey="true">
-                <Key
-                    latin:keyStyle="settingsKeyStyle"
-                    latin:keyWidth="8.047%p" />
-            </case>
-            <default>
-                <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
-                <Spacer
-                    latin:keyWidth="8.047%p" />
-            </default>
-        </switch>
+        <include
+            latin:keyboardLayout="@xml/key_settings"
+            latin:keyWidth="8.047%p" />
         <Key
             latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
             latin:keyXPos="13.829%p"
diff --git a/java/res/xml-sw768dp/rows_phone.xml b/java/res/xml-sw768dp/rows_phone.xml
index 0404bb1..69c9e86 100644
--- a/java/res/xml-sw768dp/rows_phone.xml
+++ b/java/res/xml-sw768dp/rows_phone.xml
@@ -110,18 +110,9 @@
             latin:keyWidth="0%p" />
     </Row>
     <Row>
-        <switch>
-            <case latin:hasSettingsKey="true">
-                <Key
-                    latin:keyStyle="settingsKeyStyle"
-                    latin:keyWidth="8.047%p" />
-            </case>
-            <default>
-                <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
-                <Spacer
-                    latin:keyWidth="8.047%p" />
-            </default>
-        </switch>
+        <include
+            latin:keyboardLayout="@xml/key_settings"
+            latin:keyWidth="8.047%p" />
         <Key
             latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
             latin:keyXPos="13.829%p"
diff --git a/java/res/xml-sw768dp/rows_symbols.xml b/java/res/xml-sw768dp/rows_symbols.xml
index d82f20b..96a86ec 100644
--- a/java/res/xml-sw768dp/rows_symbols.xml
+++ b/java/res/xml-sw768dp/rows_symbols.xml
@@ -155,15 +155,8 @@
     <Row
         latin:keyWidth="8.047%p"
     >
-        <switch>
-            <case
-                latin:hasSettingsKey="true"
-            >
-                <Key
-                    latin:keyStyle="settingsKeyStyle"
-                    latin:keyWidth="8.047%p" />
-            </case>
-        </switch>
+        <include
+            latin:keyboardLayout="@xml/key_settings" />
         <Key
             latin:keyLabel="/"
             latin:keyXPos="15.157%p" />
@@ -175,8 +168,7 @@
             latin:keyWidth="37.500%p" />
         <Key
             latin:keyLabel="&quot;"
-            latin:moreKeys="@string/more_keys_for_tablet_double_quote"
-            latin:maxMoreKeysColumn="4" />
+            latin:moreKeys="@string/more_keys_for_tablet_double_quote" />
         <Key
             latin:keyLabel="_" />
         <switch>
diff --git a/java/res/xml-sw768dp/rows_symbols_shift.xml b/java/res/xml-sw768dp/rows_symbols_shift.xml
index 4c80771..8c1bef4 100644
--- a/java/res/xml-sw768dp/rows_symbols_shift.xml
+++ b/java/res/xml-sw768dp/rows_symbols_shift.xml
@@ -145,13 +145,8 @@
     <Row
         latin:keyWidth="8.047%p"
     >
-        <switch>
-            <case latin:hasSettingsKey="true">
-                <Key
-                    latin:keyStyle="settingsKeyStyle"
-                    latin:keyWidth="8.047%p" />
-            </case>
-        </switch>
+        <include
+            latin:keyboardLayout="@xml/key_settings" />
         <Key
             latin:keyStyle="spaceKeyStyle"
             latin:keyXPos="31.250%p"
diff --git a/java/res/xml/key_f1.xml b/java/res/xml/key_f1.xml
index 83b6ecc..6068d25 100644
--- a/java/res/xml/key_f1.xml
+++ b/java/res/xml/key_f1.xml
@@ -23,7 +23,6 @@
 >
     <switch>
         <case
-            latin:hasSettingsKey="false"
             latin:navigateAction="false"
         >
             <switch>
@@ -51,11 +50,14 @@
                 <default>
                     <Key
                         latin:keyLabel="@string/keylabel_for_comma"
+                        latin:keyLabelFlags="hasPopupHint"
+                        latin:additionalMoreKeys="@string/more_keys_for_comma"
                         latin:keyStyle="f1PopupStyle" />
                 </default>
             </switch>
         </case>
-        <!-- hasSettingsKey="true" or navigateAction="true" -->
+        <!-- TODO: Remove dedicated navigation tab key. -->
+        <!-- navigateAction="true" -->
         <default>
             <switch>
                 <case
@@ -85,9 +87,10 @@
                 <default>
                     <Key
                         latin:keyLabel="@string/keylabel_for_comma"
-                        latin:keyWidth="9.2%p"
-                        latin:keyStyle="f1PopupStyle" />
-                </default>
+                        latin:additionalMoreKeys="@string/more_keys_for_comma"
+                        latin:keyStyle="f1PopupStyle"
+                        latin:keyWidth="9.2%p" />
+                    </default>
             </switch>
         </default>
     </switch>
diff --git a/java/res/xml/key_settings_or_tab.xml b/java/res/xml/key_navigation_tab.xml
similarity index 70%
rename from java/res/xml/key_settings_or_tab.xml
rename to java/res/xml/key_navigation_tab.xml
index 2d35e3b..c77189f 100644
--- a/java/res/xml/key_settings_or_tab.xml
+++ b/java/res/xml/key_navigation_tab.xml
@@ -23,17 +23,6 @@
 >
     <switch>
         <case
-            latin:hasSettingsKey="true"
-        >
-            <!-- Because this settings key is not adjacent to the space key, this key should be
-                 just ignored while typing (altCode=CODE_UNSPECIFIED). -->
-            <Key
-                latin:keyStyle="settingsKeyStyle"
-                latin:altCode="@integer/key_unspecified"
-                latin:keyWidth="9.2%p" />
-        </case>
-        <!-- hasSettingsKey="false" -->
-        <case
             latin:navigateAction="true"
         >
             <Key
diff --git a/java/res/xml/key_styles_common.xml b/java/res/xml/key_styles_common.xml
index 0e31bcb..eabbdb3 100644
--- a/java/res/xml/key_styles_common.xml
+++ b/java/res/xml/key_styles_common.xml
@@ -28,36 +28,14 @@
         >
             <key-style
                 latin:styleName="f1PopupStyle"
-                latin:keyLabelFlags="hasPopupHint"
-                latin:moreKeys="@string/more_keys_for_f1"
                 latin:backgroundType="functional" />
         </case>
-        <!-- clobberSettingsKey="false -->
-        <case
-            latin:hasSettingsKey="false"
-        >
-            <key-style
-                latin:styleName="f1PopupStyle"
-                latin:keyLabelFlags="hasPopupHint"
-                latin:moreKeys="@string/more_keys_for_f1_settings"
-                latin:backgroundType="functional" />
-        </case>
-        <!-- clobberSettingsKey="false" hasSettingsKey="true" -->
-        <case
-            latin:navigateAction="true"
-        >
-            <key-style
-                latin:styleName="f1PopupStyle"
-                latin:keyLabelFlags="hasPopupHint"
-                latin:moreKeys="@string/more_keys_for_f1_navigate"
-                latin:backgroundType="functional" />
-        </case>
-        <!-- clobberSettingsKey="false" and hasSettingsKey="true" navigateAction="false" -->
+        <!-- clobberSettingsKey="false" -->
         <default>
             <key-style
                 latin:styleName="f1PopupStyle"
                 latin:keyLabelFlags="hasPopupHint"
-                latin:moreKeys="@string/more_keys_for_f1"
+                latin:moreKeys="@string/settings_as_more_key"
                 latin:backgroundType="functional" />
         </default>
     </switch>
@@ -188,6 +166,5 @@
         latin:keyHintLabel="@string/keyhintlabel_for_punctuation"
         latin:keyLabelFlags="hasPopupHint|preserveCase"
         latin:moreKeys="@string/more_keys_for_punctuation"
-        latin:maxMoreKeysColumn="@integer/more_keys_keyboard_column_for_punctuation"
         latin:backgroundType="functional" />
 </merge>
diff --git a/java/res/xml/key_styles_enter_phone.xml b/java/res/xml/key_styles_enter_phone.xml
index 6af81fb..af34cb8 100644
--- a/java/res/xml/key_styles_enter_phone.xml
+++ b/java/res/xml/key_styles_enter_phone.xml
@@ -55,7 +55,6 @@
                 latin:keyOutputText=":-) "
                 latin:keyLabelFlags="hasPopupHint"
                 latin:moreKeys="@string/more_keys_for_smiley"
-                latin:maxMoreKeysColumn="5"
                 latin:backgroundType="functional" />
         </case>
         <case
diff --git a/java/res/xml/key_symbols_f1.xml b/java/res/xml/key_symbols_f1.xml
index 0dd3d91..ac4031f 100644
--- a/java/res/xml/key_symbols_f1.xml
+++ b/java/res/xml/key_symbols_f1.xml
@@ -23,7 +23,6 @@
 >
     <switch>
         <case
-            latin:hasSettingsKey="false"
             latin:navigateAction="false"
         >
             <switch>
@@ -36,12 +35,14 @@
                 <!-- latin:hasShortcutKey="false" -->
                 <default>
                     <Key
-                        latin:keyLabel="@string/keylabel_for_f1"
+                        latin:keyLabel="@string/keylabel_for_comma"
+                        latin:keyLabelFlags="hasPopupHint"
+                        latin:additionalMoreKeys="@string/more_keys_for_comma"
                         latin:keyStyle="f1PopupStyle" />
                 </default>
             </switch>
         </case>
-        <!-- hasSettingsKey="true" or navigateAction="true" -->
+        <!-- navigateAction="true" -->
         <default>
             <switch>
                 <case
@@ -54,10 +55,12 @@
                 <!-- latin:hasShortcutKey="false" -->
                 <default>
                     <Key
-                        latin:keyLabel="@string/keylabel_for_f1"
-                        latin:keyWidth="9.2%p"
-                        latin:keyStyle="f1PopupStyle" />
-                </default>
+                        latin:keyLabel="@string/keylabel_for_comma"
+                        latin:keyLabelFlags="hasPopupHint"
+                        latin:additionalMoreKeys="@string/more_keys_for_comma"
+                        latin:keyStyle="f1PopupStyle"
+                        latin:keyWidth="9.2%p" />
+                    </default>
             </switch>
         </default>
     </switch>
diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index 77f4650..f826ef0 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -44,11 +44,6 @@
             android:title="@string/popup_on_keypress"
             android:persistent="true"
             android:defaultValue="@bool/config_default_popup_preview" />
-        <CheckBoxPreference
-            android:key="show_settings_key"
-            android:title="@string/prefs_settings_key"
-            android:persistent="true"
-            android:defaultValue="@bool/config_default_show_settings_key" />
         <ListPreference
             android:key="voice_mode"
             android:title="@string/voice_input"
diff --git a/java/res/xml/row_qwerty4.xml b/java/res/xml/row_qwerty4.xml
index 8c20a72..2f8b82c 100644
--- a/java/res/xml/row_qwerty4.xml
+++ b/java/res/xml/row_qwerty4.xml
@@ -26,7 +26,6 @@
     >
         <switch>
             <case
-                latin:hasSettingsKey="false"
                 latin:navigateAction="false"
             >
                 <Key
@@ -43,13 +42,14 @@
                     latin:keyStyle="enterKeyStyle"
                     latin:keyWidth="fillRight" />
             </case>
-            <!-- hasSettingsKey="true" or navigateAction="true" -->
+            <!-- TODO: Remove dedicated navigation tab key. -->
+            <!-- navigateAction="true" -->
             <default>
                 <Key
                     latin:keyStyle="toSymbolKeyStyle"
                     latin:keyWidth="13.75%p" />
                 <include
-                    latin:keyboardLayout="@xml/key_settings_or_tab" />
+                    latin:keyboardLayout="@xml/key_navigation_tab" />
                 <include
                     latin:keyboardLayout="@xml/key_f1" />
                 <Key
diff --git a/java/res/xml/row_symbols4.xml b/java/res/xml/row_symbols4.xml
index be0c94f..ef77bc3 100644
--- a/java/res/xml/row_symbols4.xml
+++ b/java/res/xml/row_symbols4.xml
@@ -26,7 +26,6 @@
     >
         <switch>
             <case
-                latin:hasSettingsKey="false"
                 latin:navigateAction="false"
             >
                 <Key
@@ -43,13 +42,14 @@
                     latin:keyStyle="enterKeyStyle"
                     latin:keyWidth="fillRight" />
             </case>
-            <!-- hasSettingsKey="true" or navigateAction="true" -->
+            <!-- TODO: Remove dedicated navigation tab key. -->
+            <!-- navigateAction="true" -->
             <default>
                 <Key
                     latin:keyStyle="toAlphaKeyStyle"
                     latin:keyWidth="13.75%p" />
                 <include
-                    latin:keyboardLayout="@xml/key_settings_or_tab" />
+                    latin:keyboardLayout="@xml/key_navigation_tab" />
                 <include
                     latin:keyboardLayout="@xml/key_f1" />
                 <Key
diff --git a/java/res/xml/row_symbols_shift4.xml b/java/res/xml/row_symbols_shift4.xml
index 5cb6512..632aafc 100644
--- a/java/res/xml/row_symbols_shift4.xml
+++ b/java/res/xml/row_symbols_shift4.xml
@@ -26,7 +26,6 @@
     >
         <switch>
             <case
-                latin:hasSettingsKey="false"
                 latin:navigateAction="false"
             >
                 <Key
@@ -51,13 +50,14 @@
                     latin:keyStyle="enterKeyStyle"
                     latin:keyWidth="fillRight" />
             </case>
-            <!-- hasSettingsKey="true" or navigateAction="true" -->
+            <!-- TODO: Remove dedicated navigation tab key. -->
+            <!-- navigateAction="true" -->
             <default>
                 <Key
                     latin:keyStyle="toAlphaKeyStyle"
                     latin:keyWidth="13.75%p" />
                 <include
-                    latin:keyboardLayout="@xml/key_settings_or_tab" />
+                    latin:keyboardLayout="@xml/key_navigation_tab" />
                 <!-- U+201F: "‟" DOUBLE HIGH-REVERSED-9 QUOTATION MARK -->
                 <!-- TODO: Neither DroidSans nor Roboto have the glyph for U+201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK. -->
                     <!-- latin:keyLabelFlags="hasPopupHint" -->
diff --git a/java/res/xml/rows_azerty.xml b/java/res/xml/rows_azerty.xml
index 6f607cb..bd3ff6f 100644
--- a/java/res/xml/rows_azerty.xml
+++ b/java/res/xml/rows_azerty.xml
@@ -130,13 +130,9 @@
         <Key
             latin:keyLabel="n"
             latin:moreKeys="@string/more_keys_for_n" />
-        <!-- TODO: Introduce a flag, such as strinctMoreKeysOrder, to control moreKeys display
-             order more precisely. -->
-        <!-- This key is close enough to right edge, so that the 4-more keys will be displayed in
-             order of "4,3,1,2". See @string/more_keys_for_single_quote -->
         <Key
             latin:keyLabel="\'"
-            latin:moreKeys="&#x2018;,&#x2019;,&#x201B;,&#x201A;" />
+            latin:moreKeys="@string/more_keys_for_single_quote" />
         <Key
             latin:keyStyle="deleteKeyStyle"
             latin:keyWidth="fillRight"
diff --git a/java/res/xml/rows_symbols.xml b/java/res/xml/rows_symbols.xml
index 05699e0..27f75b5 100644
--- a/java/res/xml/rows_symbols.xml
+++ b/java/res/xml/rows_symbols.xml
@@ -109,8 +109,7 @@
             latin:moreKeys="&#x00A1;" />
         <Key
             latin:keyLabel="&quot;"
-            latin:moreKeys="@string/more_keys_for_double_quote"
-            latin:maxMoreKeysColumn="4" />
+            latin:moreKeys="@string/more_keys_for_double_quote" />
         <Key
             latin:keyLabel="\'"
             latin:moreKeys="@string/more_keys_for_single_quote" />
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index cf3a437..f839376 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -105,6 +105,9 @@
     public final String[] mMoreKeys;
     /** More keys maximum column number */
     public final int mMaxMoreKeysColumn;
+    public static final int MORE_KEYS_FIXED_COLUMN_ORDER = 0x80000000;
+    private static final String AUTO_COLUMN_ORDER = "!autoColumnOrder!";
+    private static final String FIXED_COLUMN_ORDER = "!fixedColumnOrder!";
 
     /** Background type that represents different key background visual than normal one. */
     public final int mBackgroundType;
@@ -232,10 +235,19 @@
         mLabelFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags);
         final boolean preserveCase = (mLabelFlags & LABEL_FLAGS_PRESERVE_CASE) != 0;
         int actionFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyActionFlags);
+        String[] moreKeys = style.getStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys);
+        int column;
+        if ((column = parseMoreKeysColumnOrder(moreKeys, AUTO_COLUMN_ORDER)) > 0) {
+            mMaxMoreKeysColumn = column;
+        } else if ((column = parseMoreKeysColumnOrder(moreKeys, FIXED_COLUMN_ORDER)) > 0) {
+            mMaxMoreKeysColumn = column | MORE_KEYS_FIXED_COLUMN_ORDER;
+        } else {
+            mMaxMoreKeysColumn = style.getInt(keyAttr,
+                    R.styleable.Keyboard_Key_maxMoreKeysColumn, params.mMaxMoreKeysKeyboardColumn);
+        }
         final String[] additionalMoreKeys = style.getStringArray(
                 keyAttr, R.styleable.Keyboard_Key_additionalMoreKeys);
-        final String[] moreKeys = KeySpecParser.insertAddtionalMoreKeys(style.getStringArray(
-                keyAttr, R.styleable.Keyboard_Key_moreKeys), additionalMoreKeys);
+        moreKeys = KeySpecParser.insertAddtionalMoreKeys(moreKeys, additionalMoreKeys);
         if (moreKeys != null) {
             actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS;
             for (int i = 0; i < moreKeys.length; i++) {
@@ -245,8 +257,6 @@
         }
         mActionFlags = actionFlags;
         mMoreKeys = moreKeys;
-        mMaxMoreKeysColumn = style.getInt(keyAttr,
-                R.styleable.Keyboard_Key_maxMoreKeysColumn, params.mMaxMoreKeysKeyboardColumn);
 
         if ((mLabelFlags & LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL) != 0) {
             mLabel = params.mId.mCustomActionLabel;
@@ -301,6 +311,21 @@
         }
     }
 
+    private static int parseMoreKeysColumnOrder(String[] moreKeys, String key) {
+        if (moreKeys == null || moreKeys.length == 0 || moreKeys[0] == null
+                || !moreKeys[0].startsWith(key)) {
+            return -1;
+        }
+        try {
+            final int column = Integer.parseInt(moreKeys[0].substring(key.length()));
+            moreKeys[0] = null;
+            return column;
+        } catch (NumberFormatException e) {
+            Log.w(TAG, "column number should follow after " + key);
+            return 0;
+        }
+    }
+
     private static int adjustCaseOfCodeForKeyboardId(int code, boolean preserveCase,
             KeyboardId id) {
         if (!Keyboard.isLetterCode(code) || preserveCase) return code;
diff --git a/java/src/com/android/inputmethod/keyboard/KeyDetector.java b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
index bff491f..0ce98d2 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
@@ -180,32 +180,34 @@
         if (maxCodesSize <= numCodes) {
             return;
         }
-        if (primaryCode != NOT_A_CODE) {
-            final List<Integer> additionalChars =
-                    mKeyboard.getAdditionalProximityChars().get(primaryCode);
-            if (additionalChars == null || additionalChars.size() == 0) {
-                return;
-            }
-            int currentCodesSize = numCodes;
-            allCodes[numCodes++] = ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE;
-            if (maxCodesSize <= numCodes) {
-                return;
-            }
-            // TODO: This is O(N^2). Assuming additionalChars.size() is up to 4 or 5.
-            for (int i = 0; i < additionalChars.size(); ++i) {
-                final int additionalChar = additionalChars.get(i);
-                boolean contains = false;
-                for (int j = 0; j < currentCodesSize; ++j) {
-                    if (additionalChar == allCodes[j]) {
-                        contains = true;
-                        break;
-                    }
+
+        final int code = (primaryCode == NOT_A_CODE) ? allCodes[0] : primaryCode;
+        if (code == NOT_A_CODE) {
+            return;
+        }
+        final List<Integer> additionalChars = mKeyboard.getAdditionalProximityChars().get(code);
+        if (additionalChars == null || additionalChars.size() == 0) {
+            return;
+        }
+        int currentCodesSize = numCodes;
+        allCodes[numCodes++] = ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE;
+        if (maxCodesSize <= numCodes) {
+            return;
+        }
+        // TODO: This is O(N^2). Assuming additionalChars.size() is up to 4 or 5.
+        for (int i = 0; i < additionalChars.size(); ++i) {
+            final int additionalChar = additionalChars.get(i);
+            boolean contains = false;
+            for (int j = 0; j < currentCodesSize; ++j) {
+                if (additionalChar == allCodes[j]) {
+                    contains = true;
+                    break;
                 }
-                if (!contains) {
-                    allCodes[numCodes++] = additionalChar;
-                    if (maxCodesSize <= numCodes) {
-                        return;
-                    }
+            }
+            if (!contains) {
+                allCodes[numCodes++] = additionalChar;
+                if (maxCodesSize <= numCodes) {
+                    return;
                 }
             }
         }
@@ -257,10 +259,17 @@
 
     public static String printableCodes(int[] codes) {
         final StringBuilder sb = new StringBuilder();
+        boolean addDelimiter = false;
         for (final int code : codes) {
             if (code == NOT_A_CODE) break;
-            if (sb.length() > 0) sb.append(", ");
-            sb.append(code);
+            if (code == ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE) {
+                sb.append(" | ");
+                addDelimiter = false;
+            } else {
+                if (addDelimiter) sb.append(", ");
+                sb.append(code);
+                addDelimiter = true;
+            }
         }
         return "[" + sb + "]";
     }
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 28f71f4..60e5069 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -1073,10 +1073,6 @@
                         R.styleable.Keyboard_Case_navigateAction, id.navigateAction());
                 final boolean passwordInputMatched = matchBoolean(a,
                         R.styleable.Keyboard_Case_passwordInput, id.passwordInput());
-                final boolean hasSettingsKeyMatched = matchBoolean(a,
-                        R.styleable.Keyboard_Case_hasSettingsKey, id.hasSettingsKey());
-                final boolean f2KeyModeMatched = matchInteger(a,
-                        R.styleable.Keyboard_Case_f2KeyMode, id.f2KeyMode());
                 final boolean clobberSettingsKeyMatched = matchBoolean(a,
                         R.styleable.Keyboard_Case_clobberSettingsKey, id.mClobberSettingsKey);
                 final boolean shortcutKeyEnabledMatched = matchBoolean(a,
@@ -1094,14 +1090,13 @@
                 final boolean countryCodeMatched = matchString(a,
                         R.styleable.Keyboard_Case_countryCode, id.mLocale.getCountry());
                 final boolean selected = keyboardSetElementMatched && modeMatched
-                        && navigateActionMatched && passwordInputMatched && hasSettingsKeyMatched
-                        && f2KeyModeMatched && clobberSettingsKeyMatched
-                        && shortcutKeyEnabledMatched && hasShortcutKeyMatched && isMultiLineMatched
-                        && imeActionMatched && localeCodeMatched && languageCodeMatched
-                        && countryCodeMatched;
+                        && navigateActionMatched && passwordInputMatched
+                        && clobberSettingsKeyMatched && shortcutKeyEnabledMatched
+                        && hasShortcutKeyMatched && isMultiLineMatched && imeActionMatched
+                        && localeCodeMatched && languageCodeMatched && countryCodeMatched;
 
                 if (DEBUG) {
-                    startTag("<%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s>%s", TAG_CASE,
+                    startTag("<%s%s%s%s%s%s%s%s%s%s%s%s%s>%s", TAG_CASE,
                             textAttr(a.getString(R.styleable.Keyboard_Case_keyboardSetElement),
                                     "keyboardSetElement"),
                             textAttr(a.getString(R.styleable.Keyboard_Case_mode), "mode"),
@@ -1109,11 +1104,6 @@
                                     "navigateAction"),
                             booleanAttr(a, R.styleable.Keyboard_Case_passwordInput,
                                     "passwordInput"),
-                            booleanAttr(a, R.styleable.Keyboard_Case_hasSettingsKey,
-                                    "hasSettingsKey"),
-                            textAttr(KeyboardId.f2KeyModeName(
-                                    a.getInt(R.styleable.Keyboard_Case_f2KeyMode, -1)),
-                                    "f2KeyMode"),
                             booleanAttr(a, R.styleable.Keyboard_Case_clobberSettingsKey,
                                     "clobberSettingsKey"),
                             booleanAttr(a, R.styleable.Keyboard_Case_shortcutKeyEnabled,
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index 3ab2493..a75caf2 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -48,11 +48,6 @@
     public static final int ELEMENT_PHONE_SYMBOLS = 8;
     public static final int ELEMENT_NUMBER = 9;
 
-    private static final int F2KEY_MODE_NONE = 0;
-    private static final int F2KEY_MODE_SETTINGS = 1;
-    private static final int F2KEY_MODE_SHORTCUT_IME = 2;
-    private static final int F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS = 3;
-
     private static final int IME_ACTION_CUSTOM_LABEL = EditorInfo.IME_MASK_ACTION + 1;
 
     public final Locale mLocale;
@@ -61,7 +56,6 @@
     public final int mMode;
     public final int mElementId;
     private final EditorInfo mEditorInfo;
-    private final boolean mSettingsKeyEnabled;
     public final boolean mClobberSettingsKey;
     public final boolean mShortcutKeyEnabled;
     public final boolean mHasShortcutKey;
@@ -70,15 +64,14 @@
     private final int mHashCode;
 
     public KeyboardId(int elementId, Locale locale, int orientation, int width, int mode,
-            EditorInfo editorInfo, boolean settingsKeyEnabled, boolean clobberSettingsKey,
-            boolean shortcutKeyEnabled, boolean hasShortcutKey) {
+            EditorInfo editorInfo, boolean clobberSettingsKey, boolean shortcutKeyEnabled,
+            boolean hasShortcutKey) {
         this.mLocale = locale;
         this.mOrientation = orientation;
         this.mWidth = width;
         this.mMode = mode;
         this.mElementId = elementId;
         this.mEditorInfo = editorInfo;
-        this.mSettingsKeyEnabled = settingsKeyEnabled;
         this.mClobberSettingsKey = clobberSettingsKey;
         this.mShortcutKeyEnabled = shortcutKeyEnabled;
         this.mHasShortcutKey = hasShortcutKey;
@@ -96,7 +89,6 @@
                 id.mWidth,
                 id.navigateAction(),
                 id.passwordInput(),
-                id.mSettingsKeyEnabled,
                 id.mClobberSettingsKey,
                 id.mShortcutKeyEnabled,
                 id.mHasShortcutKey,
@@ -116,7 +108,6 @@
                 && other.mWidth == this.mWidth
                 && other.navigateAction() == this.navigateAction()
                 && other.passwordInput() == this.passwordInput()
-                && other.mSettingsKeyEnabled == this.mSettingsKeyEnabled
                 && other.mClobberSettingsKey == this.mClobberSettingsKey
                 && other.mShortcutKeyEnabled == this.mShortcutKeyEnabled
                 && other.mHasShortcutKey == this.mHasShortcutKey
@@ -183,25 +174,6 @@
         }
     }
 
-    public boolean hasSettingsKey() {
-        return mSettingsKeyEnabled && !mClobberSettingsKey;
-    }
-
-    public int f2KeyMode() {
-        if (mClobberSettingsKey) {
-            // Never shows the Settings key
-            return KeyboardId.F2KEY_MODE_SHORTCUT_IME;
-        }
-
-        if (mSettingsKeyEnabled) {
-            return KeyboardId.F2KEY_MODE_SETTINGS;
-        } else {
-            // It should be alright to fall back to the Settings key on 7-inch layouts
-            // even when the Settings key is not explicitly enabled.
-            return KeyboardId.F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS;
-        }
-    }
-
     @Override
     public boolean equals(Object other) {
         return other instanceof KeyboardId && equals((KeyboardId) other);
@@ -214,17 +186,15 @@
 
     @Override
     public String toString() {
-        return String.format("[%s %s %s%d %s %s %s%s%s%s%s%s%s]",
+        return String.format("[%s %s %s%d %s %s %s%s%s%s%s]",
                 elementIdToName(mElementId),
                 mLocale,
                 (mOrientation == 1 ? "port" : "land"), mWidth,
                 modeName(mMode),
                 imeAction(),
-                f2KeyModeName(f2KeyMode()),
                 (mClobberSettingsKey ? " clobberSettingsKey" : ""),
                 (navigateAction() ? " navigateAction" : ""),
                 (passwordInput() ? " passwordInput" : ""),
-                (hasSettingsKey() ? " hasSettingsKey" : ""),
                 (mShortcutKeyEnabled ? " shortcutKeyEnabled" : ""),
                 (mHasShortcutKey ? " hasShortcutKey" : "")
         );
@@ -270,14 +240,4 @@
         return (actionId == IME_ACTION_CUSTOM_LABEL) ? "actionCustomLabel"
                 : EditorInfoCompatUtils.imeActionName(actionId);
     }
-
-    public static String f2KeyModeName(int f2KeyMode) {
-        switch (f2KeyMode) {
-        case F2KEY_MODE_NONE: return "none";
-        case F2KEY_MODE_SETTINGS: return "settings";
-        case F2KEY_MODE_SHORTCUT_IME: return "shortcutIme";
-        case F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS: return "shortcutImeOrSettings";
-        default: return null;
-        }
-    }
 }
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
index f27170a..6e62f74 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
@@ -98,7 +98,6 @@
         int mMode;
         EditorInfo mEditorInfo;
         boolean mTouchPositionCorrectionEnabled;
-        boolean mSettingsKeyEnabled;
         boolean mVoiceKeyEnabled;
         boolean mVoiceKeyOnMain;
         boolean mNoSettingsKey;
@@ -193,8 +192,8 @@
         final boolean hasShortcutKey = params.mVoiceKeyEnabled
                 && (isSymbols != params.mVoiceKeyOnMain);
         return new KeyboardId(keyboardSetElementId, params.mLocale, params.mOrientation,
-                params.mWidth, params.mMode, params.mEditorInfo, params.mSettingsKeyEnabled,
-                params.mNoSettingsKey, params.mVoiceKeyEnabled, hasShortcutKey);
+                params.mWidth, params.mMode, params.mEditorInfo, params.mNoSettingsKey,
+                params.mVoiceKeyEnabled, hasShortcutKey);
     }
 
     public static class Builder {
@@ -237,9 +236,7 @@
             return this;
         }
 
-        public Builder setOptions(boolean settingsKeyEnabled, boolean voiceKeyEnabled,
-                boolean voiceKeyOnMain) {
-            mParams.mSettingsKeyEnabled = settingsKeyEnabled;
+        public Builder setOptions(boolean voiceKeyEnabled, boolean voiceKeyOnMain) {
             @SuppressWarnings("deprecation")
             final boolean deprecatedNoMicrophone = Utils.inPrivateImeOptions(
                     null, LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, mEditorInfo);
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 5ba560d..622e583 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -35,7 +35,6 @@
 import com.android.inputmethod.latin.LatinIME;
 import com.android.inputmethod.latin.LatinImeLogger;
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.Settings;
 import com.android.inputmethod.latin.SettingsValues;
 import com.android.inputmethod.latin.SubtypeSwitcher;
 import com.android.inputmethod.latin.Utils;
@@ -133,7 +132,6 @@
                 mSubtypeSwitcher.currentSubtypeContainsExtraValueKey(
                         LatinIME.SUBTYPE_EXTRA_VALUE_SUPPORT_TOUCH_POSITION_CORRECTION));
         builder.setOptions(
-                settingsValues.isSettingsKeyEnabled(),
                 settingsValues.isVoiceKeyEnabled(editorInfo),
                 settingsValues.isVoiceKeyOnMain());
         mKeyboardSet = builder.build();
@@ -268,6 +266,16 @@
 
     // Implements {@link KeyboardState.SwitchActions}.
     @Override
+    public void cancelDoubleTapTimer() {
+        final LatinKeyboardView keyboardView = getKeyboardView();
+        if (keyboardView != null) {
+            final TimerProxy timer = keyboardView.getTimerProxy();
+            timer.cancelDoubleTapTimer();
+        }
+    }
+
+    // Implements {@link KeyboardState.SwitchActions}.
+    @Override
     public boolean isInDoubleTapTimeout() {
         final LatinKeyboardView keyboardView = getKeyboardView();
         return (keyboardView != null)
@@ -286,6 +294,16 @@
 
     // Implements {@link KeyboardState.SwitchActions}.
     @Override
+    public void cancelLongPressTimer() {
+        final LatinKeyboardView keyboardView = getKeyboardView();
+        if (keyboardView != null) {
+            final TimerProxy timer = keyboardView.getTimerProxy();
+            timer.cancelLongPressTimer();
+        }
+    }
+
+    // Implements {@link KeyboardState.SwitchActions}.
+    @Override
     public void hapticAndAudioFeedback(int code) {
         mInputMethodService.hapticAndAudioFeedback(code);
     }
@@ -384,8 +402,6 @@
         if (PREF_KEYBOARD_LAYOUT.equals(key)) {
             final int themeIndex = getKeyboardThemeIndex(mInputMethodService, sharedPreferences);
             postSetInputView(createInputView(themeIndex, false));
-        } else if (Settings.PREF_SHOW_SETTINGS_KEY.equals(key)) {
-            postSetInputView(createInputView(mThemeIndex, true));
         }
     }
 
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index 88a4157..9a0fe1e 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -233,6 +233,11 @@
         }
 
         @Override
+        public void cancelDoubleTapTimer() {
+            removeMessages(MSG_DOUBLE_TAP);
+        }
+
+        @Override
         public boolean isInDoubleTapTimeout() {
             return hasMessages(MSG_DOUBLE_TAP);
         }
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
index 1597b1e..7d8181d 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
@@ -37,9 +37,11 @@
         private final String[] mMoreKeys;
 
         public static class MoreKeysKeyboardParams extends Keyboard.Params {
+            public boolean mIsFixedOrder;
             /* package */int mTopRowAdjustment;
             public int mNumRows;
             public int mNumColumns;
+            public int mTopKeys;
             public int mLeftKeys;
             public int mRightKeys; // includes default key.
 
@@ -58,14 +60,17 @@
              * Set keyboard parameters of more keys keyboard.
              *
              * @param numKeys number of keys in this more keys keyboard.
-             * @param maxColumns number of maximum columns of this more keys keyboard.
+             * @param maxColumnsAndFlags number of maximum columns of this more keys keyboard.
+             * This might have {@link Key#MORE_KEYS_FIXED_COLUMN_ORDER} flag.
              * @param keyWidth more keys keyboard key width in pixel, including horizontal gap.
              * @param rowHeight more keys keyboard row height in pixel, including vertical gap.
              * @param coordXInParent coordinate x of the key preview in parent keyboard.
              * @param parentKeyboardWidth parent keyboard width in pixel.
              */
-            public void setParameters(int numKeys, int maxColumns, int keyWidth, int rowHeight,
-                    int coordXInParent, int parentKeyboardWidth) {
+            public void setParameters(int numKeys, int maxColumnsAndFlags, int keyWidth,
+                    int rowHeight, int coordXInParent, int parentKeyboardWidth) {
+                mIsFixedOrder = (maxColumnsAndFlags & Key.MORE_KEYS_FIXED_COLUMN_ORDER) != 0;
+                final int maxColumns = maxColumnsAndFlags & ~Key.MORE_KEYS_FIXED_COLUMN_ORDER;
                 if (parentKeyboardWidth / keyWidth < maxColumns) {
                     throw new IllegalArgumentException(
                             "Keyboard is too small to hold more keys keyboard: "
@@ -76,8 +81,11 @@
 
                 final int numRows = (numKeys + maxColumns - 1) / maxColumns;
                 mNumRows = numRows;
-                final int numColumns = getOptimizedColumns(numKeys, maxColumns);
+                final int numColumns = mIsFixedOrder ? Math.min(numKeys, maxColumns)
+                        : getOptimizedColumns(numKeys, maxColumns);
                 mNumColumns = numColumns;
+                final int topKeys = numKeys % numColumns;
+                mTopKeys = topKeys == 0 ? numColumns : topKeys;
 
                 final int numLeftKeys = (numColumns - 1) / 2;
                 final int numRightKeys = numColumns - numLeftKeys; // including default key.
@@ -110,28 +118,68 @@
                 mLeftKeys = leftKeys;
                 mRightKeys = rightKeys;
 
-                // Centering of the top row.
-                if (numRows < 2 || getTopRowEmptySlots(numKeys, numColumns) % 2 == 0) {
-                    mTopRowAdjustment = 0;
-                } else if (mLeftKeys < mRightKeys - 1) {
-                    mTopRowAdjustment = 1;
-                } else {
-                    mTopRowAdjustment = -1;
-                }
-
+                // Adjustment of the top row.
+                mTopRowAdjustment = mIsFixedOrder ? getFixedOrderTopRowAdjustment()
+                        : getAutoOrderTopRowAdjustment();
                 mBaseWidth = mOccupiedWidth = mNumColumns * mDefaultKeyWidth;
                 // Need to subtract the bottom row's gutter only.
                 mBaseHeight = mOccupiedHeight = mNumRows * mDefaultRowHeight - mVerticalGap
                         + mTopPadding + mBottomPadding;
             }
 
+            private int getFixedOrderTopRowAdjustment() {
+                if (mNumRows == 1 || mTopKeys % 2 == 1 || mTopKeys == mNumColumns
+                        || mLeftKeys == 0  || mRightKeys == 1) {
+                    return 0;
+                }
+                return -1;
+            }
+
+            private int getAutoOrderTopRowAdjustment() {
+                if (mNumRows == 1 || mTopKeys == 1 || mNumColumns % 2 == mTopKeys % 2
+                        || mLeftKeys == 0 || mRightKeys == 1) {
+                    return 0;
+                }
+                return -1;
+            }
+
             // Return key position according to column count (0 is default).
             /* package */int getColumnPos(int n) {
+                return mIsFixedOrder ? getFixedOrderColumnPos(n) : getAutomaticColumnPos(n);
+            }
+
+            private int getFixedOrderColumnPos(int n) {
                 final int col = n % mNumColumns;
+                final int row = n / mNumColumns;
+                if (!isTopRow(row)) {
+                    return col - mLeftKeys;
+                }
+                final int rightSideKeys = mTopKeys / 2;
+                final int leftSideKeys = mTopKeys - (rightSideKeys + 1);
+                final int pos = col - leftSideKeys;
+                final int numLeftKeys = mLeftKeys + mTopRowAdjustment;
+                final int numRightKeys = mRightKeys - 1;
+                if (numRightKeys >= rightSideKeys && numLeftKeys >= leftSideKeys) {
+                    return pos;
+                } else if (numRightKeys < rightSideKeys) {
+                    return pos - (rightSideKeys - numRightKeys);
+                } else { // numLeftKeys < leftSideKeys
+                    return pos + (leftSideKeys - numLeftKeys);
+                }
+            }
+
+            private int getAutomaticColumnPos(int n) {
+                final int col = n % mNumColumns;
+                final int row = n / mNumColumns;
+                int leftKeys = mLeftKeys;
+                if (isTopRow(row)) {
+                    leftKeys += mTopRowAdjustment;
+                }
                 if (col == 0) {
                     // default position.
                     return 0;
                 }
+
                 int pos = 0;
                 int right = 1; // include default position key.
                 int left = 0;
@@ -146,7 +194,7 @@
                     if (i >= col)
                         break;
                     // Assign left key if available.
-                    if (left < mLeftKeys) {
+                    if (left < leftKeys) {
                         left++;
                         pos = -left;
                         i++;
@@ -158,12 +206,8 @@
             }
 
             private static int getTopRowEmptySlots(int numKeys, int numColumns) {
-                final int remainingKeys = numKeys % numColumns;
-                if (remainingKeys == 0) {
-                    return 0;
-                } else {
-                    return numColumns - remainingKeys;
-                }
+                final int remainings = numKeys % numColumns;
+                return remainings == 0 ? 0 : numColumns - remainings;
             }
 
             private int getOptimizedColumns(int numKeys, int maxColumns) {
@@ -198,7 +242,7 @@
             }
 
             private boolean isTopRow(int rowCount) {
-                return rowCount == mNumRows - 1;
+                return mNumRows > 1 && rowCount == mNumRows - 1;
             }
         }
 
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 110f7f6..c453084 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -77,6 +77,7 @@
         public void startLongPressTimer(int code);
         public void cancelLongPressTimer();
         public void startDoubleTapTimer();
+        public void cancelDoubleTapTimer();
         public boolean isInDoubleTapTimeout();
         public void cancelKeyTimers();
 
@@ -96,6 +97,8 @@
             @Override
             public void startDoubleTapTimer() {}
             @Override
+            public void cancelDoubleTapTimer() {}
+            @Override
             public boolean isInDoubleTapTimeout() { return false; }
             @Override
             public void cancelKeyTimers() {}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
index 1626a14..f61eefd 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
@@ -206,9 +206,51 @@
         return KeyboardIconsSet.ICON_UNDEFINED;
     }
 
-    public static String[] insertAddtionalMoreKeys(String[] moreKeys, String[] additionalMoreKeys) {
-        final int moreKeysCount = (moreKeys != null) ? moreKeys.length : 0;
-        final int additionalCount = (additionalMoreKeys != null) ? additionalMoreKeys.length : 0;
+    private static <T> ArrayList<T> arrayAsList(T[] array, int start, int end) {
+        if (array == null) {
+            throw new NullPointerException();
+        }
+        if (start < 0 || start > end || end > array.length) {
+            throw new IllegalArgumentException();
+        }
+
+        final ArrayList<T> list = new ArrayList<T>(end - start);
+        for (int i = start; i < end; i++) {
+            list.add(array[i]);
+        }
+        return list;
+    }
+
+    private static final String[] EMPTY_STRING_ARRAY = new String[0];
+
+    private static String[] filterOutEmptyString(String[] array) {
+        if (array == null) {
+            return EMPTY_STRING_ARRAY;
+        }
+        ArrayList<String> out = null;
+        for (int i = 0; i < array.length; i++) {
+            final String entry = array[i];
+            if (TextUtils.isEmpty(entry)) {
+                if (out == null) {
+                    out = arrayAsList(array, 0, i);
+                }
+            } else if (out != null) {
+                out.add(entry);
+            }
+        }
+        if (out == null) {
+            return array;
+        } else {
+            return out.toArray(new String[out.size()]);
+        }
+    }
+
+    public static String[] insertAddtionalMoreKeys(String[] moreKeySpecs,
+            String[] additionalMoreKeySpecs) {
+        final String[] moreKeys = filterOutEmptyString(moreKeySpecs);
+        final String[] additionalMoreKeys = filterOutEmptyString(additionalMoreKeySpecs);
+        final int moreKeysCount = moreKeys.length;
+        final int additionalCount = additionalMoreKeys.length;
         ArrayList<String> out = null;
         int additionalIndex = 0;
         for (int moreKeyIndex = 0; moreKeyIndex < moreKeysCount; moreKeyIndex++) {
@@ -226,10 +268,7 @@
                 } else {
                     // Filter out excessive '%' marker.
                     if (out == null) {
-                        out = new ArrayList<String>(moreKeyIndex);
-                        for (int i = 0; i < moreKeyIndex; i++) {
-                            out.add(moreKeys[i]);
-                        }
+                        out = arrayAsList(moreKeys, 0, moreKeyIndex);
                     }
                 }
             } else {
@@ -246,10 +285,7 @@
                         + " moreKeys=" + Arrays.toString(moreKeys)
                         + " additionalMoreKeys=" + Arrays.toString(additionalMoreKeys));
             }
-            out = new ArrayList<String>(additionalCount + moreKeysCount);
-            for (int i = additionalIndex; i < additionalCount; i++) {
-                out.add(additionalMoreKeys[i]);
-            }
+            out = arrayAsList(additionalMoreKeys, additionalIndex, additionalCount);
             for (int i = 0; i < moreKeysCount; i++) {
                 out.add(moreKeys[i]);
             }
@@ -261,18 +297,17 @@
                         + " moreKeys=" + Arrays.toString(moreKeys)
                         + " additionalMoreKeys=" + Arrays.toString(additionalMoreKeys));
             }
-            out = new ArrayList<String>(moreKeysCount);
-            for (int i = 0; i < moreKeysCount; i++) {
-                out.add(moreKeys[i]);
-            }
+            out = arrayAsList(moreKeys, 0, moreKeysCount);
             for (int i = additionalIndex; i < additionalCount; i++) {
                 out.add(additionalMoreKeys[additionalIndex]);
             }
         }
-        if (out != null) {
-            return out.size() > 0 ? out.toArray(new String[out.size()]) : null;
-        } else {
+        if (out == null && moreKeysCount > 0) {
             return moreKeys;
+        } else if (out != null && out.size() > 0) {
+            return out.toArray(new String[out.size()]);
+        } else {
+            return null;
         }
     }
 
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
index cb8b4f0..6a8a036 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
@@ -54,7 +54,9 @@
 
         public void startDoubleTapTimer();
         public boolean isInDoubleTapTimeout();
+        public void cancelDoubleTapTimer();
         public void startLongPressTimer(int code);
+        public void cancelLongPressTimer();
         public void hapticAndAudioFeedback(int code);
     }
 
@@ -300,6 +302,8 @@
         } else if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
             onPressSymbol();
         } else {
+            mSwitchActions.cancelDoubleTapTimer();
+            mSwitchActions.cancelLongPressTimer();
             mShiftKeyState.onOtherKeyPressed();
             mSymbolKeyState.onOtherKeyPressed();
         }
@@ -348,7 +352,7 @@
                 // state. And mark as if shift key is released.
                 mShiftKeyState.onRelease();
             } else {
-                // Shift key is long pressed while shift unloked state.
+                // Shift key is long pressed while shift unlocked state.
                 setShiftLocked(true);
             }
             mSwitchActions.hapticAndAudioFeedback(code);
@@ -364,6 +368,11 @@
 
     private void updateAlphabetShiftState(boolean autoCaps) {
         if (!mIsAlphabetMode) return;
+        if (!mShiftKeyState.isReleasing()) {
+            // Ignore update shift state event while the shift key is being pressed (including
+            // chording).
+            return;
+        }
         if (!mAlphabetShiftState.isShiftLocked() && !mShiftKeyState.isIgnoring()) {
             if (mShiftKeyState.isReleasing() && autoCaps) {
                 // Only when shift key is releasing, automatic temporary upper case will be set.
diff --git a/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java
index d9181f7..5db65c6 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java
@@ -16,12 +16,18 @@
 
 package com.android.inputmethod.keyboard.internal;
 
+import android.util.Log;
+
+import com.android.inputmethod.keyboard.Keyboard;
 import com.android.inputmethod.keyboard.PointerTracker;
 
 import java.util.Iterator;
 import java.util.LinkedList;
 
 public class PointerTrackerQueue {
+    private static final String TAG = PointerTrackerQueue.class.getSimpleName();
+    private static final boolean DEBUG = false;
+
     private final LinkedList<PointerTracker> mQueue = new LinkedList<PointerTracker>();
 
     public synchronized void add(PointerTracker tracker) {
@@ -32,7 +38,11 @@
         mQueue.remove(tracker);
     }
 
-    public synchronized void releaseAllPointersOlderThan(PointerTracker tracker, long eventTime) {
+    public synchronized void releaseAllPointersOlderThan(PointerTracker tracker,
+            long eventTime) {
+        if (DEBUG) {
+            Log.d(TAG, "releaseAllPoniterOlderThan: [" + tracker.mPointerId + "] " + this);
+        }
         if (!mQueue.contains(tracker)) {
             return;
         }
@@ -54,6 +64,13 @@
     }
 
     public synchronized void releaseAllPointersExcept(PointerTracker tracker, long eventTime) {
+        if (DEBUG) {
+            if (tracker == null) {
+                Log.d(TAG, "releaseAllPoniters: " + this);
+            } else {
+                Log.d(TAG, "releaseAllPoniterExcept: [" + tracker.mPointerId + "] " + this);
+            }
+        }
         final Iterator<PointerTracker> it = mQueue.iterator();
         while (it.hasNext()) {
             final PointerTracker t = it.next();
@@ -79,8 +96,9 @@
         for (final PointerTracker tracker : mQueue) {
             if (sb.length() > 0)
                 sb.append(" ");
-            sb.append(tracker.mPointerId);
+            sb.append("[" + tracker.mPointerId + " "
+                + Keyboard.printableCode(tracker.getKey().mCode) + "]");
         }
-        return "[" + sb + "]";
+        return sb.toString();
     }
 }
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 1cb79e7..730992b 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -325,7 +325,7 @@
             return hasMessages(MSG_UPDATE_SUGGESTIONS);
         }
 
-        public void postUpdateShiftKeyState() {
+        public void postUpdateShiftState() {
             removeMessages(MSG_UPDATE_SHIFT_STATE);
             sendMessageDelayed(obtainMessage(MSG_UPDATE_SHIFT_STATE), mDelayUpdateShiftState);
         }
@@ -898,9 +898,10 @@
                 resetComposingState(true /* alsoResetLastComposedWord */);
                 updateSuggestions();
             }
+
+            mHandler.postUpdateShiftState();
         }
         mExpectingUpdateSelection = false;
-        mHandler.postUpdateShiftKeyState();
         // TODO: Decide to call restartSuggestionsOnWordBeforeCursorIfAtEndOfWord() or not
         // here. It would probably be too expensive to call directly here but we may want to post a
         // message to delay it. The point would be to unify behavior between backspace to the
@@ -1391,7 +1392,7 @@
         mVoiceProxy.handleBackspace();
 
         // In many cases, we may have to put the keyboard in auto-shift state again.
-        mHandler.postUpdateShiftKeyState();
+        mHandler.postUpdateShiftState();
 
         if (mEnteredText != null && sameAsTextBeforeCursor(ic, mEnteredText)) {
             // Cancel multi-character input: remove the text we just entered.
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index d323100..dfcb645 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -65,7 +65,6 @@
     public static final String PREF_VIBRATE_ON = "vibrate_on";
     public static final String PREF_SOUND_ON = "sound_on";
     public static final String PREF_POPUP_ON = "popup_on";
-    public static final String PREF_SHOW_SETTINGS_KEY = "show_settings_key";
     public static final String PREF_VOICE_MODE = "voice_mode";
     public static final String PREF_CORRECTION_SETTINGS = "correction_settings";
     public static final String PREF_CONFIGURE_DICTIONARIES_KEY = "configure_dictionaries_key";
@@ -96,7 +95,6 @@
     private PreferenceScreen mKeypressVibrationDurationSettingsPref;
     private PreferenceScreen mKeypressSoundVolumeSettingsPref;
     private ListPreference mVoicePreference;
-    private CheckBoxPreference mShowSettingsKeyPreference;
     private ListPreference mShowCorrectionSuggestionsPreference;
     private ListPreference mAutoCorrectionThresholdPreference;
     private ListPreference mKeyPreviewPopupDismissDelay;
@@ -147,7 +145,6 @@
         mInputLanguageSelection = (PreferenceScreen) findPreference(PREF_SUBTYPES_SETTINGS);
         mInputLanguageSelection.setOnPreferenceClickListener(this);
         mVoicePreference = (ListPreference) findPreference(PREF_VOICE_MODE);
-        mShowSettingsKeyPreference = (CheckBoxPreference) findPreference(PREF_SHOW_SETTINGS_KEY);
         mShowCorrectionSuggestionsPreference =
                 (ListPreference) findPreference(PREF_SHOW_SUGGESTIONS_SETTING);
         SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
@@ -178,10 +175,6 @@
         final PreferenceGroup miscSettings =
                 (PreferenceGroup) findPreference(PREF_MISC_SETTINGS);
 
-        if (!SettingsValues.isShowSettingsKeyOptionEnabled(res)) {
-            generalSettings.removePreference(mShowSettingsKeyPreference);
-        }
-
         final boolean showVoiceKeyOption = res.getBoolean(
                 R.bool.config_enable_show_voice_key_option);
         if (!showVoiceKeyOption) {
diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java
index 6b65231..7a43cb8 100644
--- a/java/src/com/android/inputmethod/latin/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/SettingsValues.java
@@ -49,7 +49,6 @@
     public final boolean mVibrateOn;
     public final boolean mSoundOn;
     public final boolean mKeyPreviewPopupOn;
-    private final boolean mShowSettingsKey;
     private final String mVoiceMode;
     private final String mAutoCorrectionThresholdRawValue;
     public final String mShowSuggestionsSetting;
@@ -118,7 +117,6 @@
         mSoundOn = prefs.getBoolean(Settings.PREF_SOUND_ON,
                 res.getBoolean(R.bool.config_default_sound_enabled));
         mKeyPreviewPopupOn = isKeyPreviewPopupEnabled(prefs, res);
-        mShowSettingsKey = isSettingsKeyShown(prefs, res);
         final String voiceModeMain = res.getString(R.string.voice_mode_main);
         final String voiceModeOff = res.getString(R.string.voice_mode_off);
         mVoiceMode = prefs.getString(Settings.PREF_VOICE_MODE, voiceModeMain);
@@ -202,19 +200,6 @@
         return wordSeparators;
     }
 
-    private static boolean isSettingsKeyShown(final SharedPreferences prefs, final Resources res) {
-        final boolean defaultShowSettingsKey = res.getBoolean(
-                R.bool.config_default_show_settings_key);
-        return isShowSettingsKeyOptionEnabled(res)
-                ? prefs.getBoolean(Settings.PREF_SHOW_SETTINGS_KEY, defaultShowSettingsKey)
-                : defaultShowSettingsKey;
-    }
-
-    public static boolean isShowSettingsKeyOptionEnabled(final Resources resources) {
-        // TODO: Read this once and for all into a public final member
-        return resources.getBoolean(R.bool.config_enable_show_settings_key_option);
-    }
-
     private static boolean isVibrateOn(final Context context, final SharedPreferences prefs,
             final Resources res) {
         final boolean hasVibrator = VibratorCompatWrapper.getInstance(context).hasVibrator();
@@ -306,10 +291,6 @@
         return autoCorrectionThreshold;
     }
 
-    public boolean isSettingsKeyEnabled() {
-        return mShowSettingsKey;
-    }
-
     public boolean isVoiceKeyEnabled(final EditorInfo editorInfo) {
         final boolean shortcutImeEnabled = SubtypeSwitcher.getInstance().isShortcutImeEnabled();
         final int inputType = (editorInfo != null) ? editorInfo.inputType : 0;
diff --git a/tests/src/com/android/inputmethod/keyboard/MoreKeysKeyboardBuilderFixedOrderTests.java b/tests/src/com/android/inputmethod/keyboard/MoreKeysKeyboardBuilderFixedOrderTests.java
new file mode 100644
index 0000000..c0b3445
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/MoreKeysKeyboardBuilderFixedOrderTests.java
@@ -0,0 +1,2629 @@
+/*
+ * 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.keyboard;
+
+import android.test.AndroidTestCase;
+
+import com.android.inputmethod.keyboard.MoreKeysKeyboard.Builder.MoreKeysKeyboardParams;
+
+public class MoreKeysKeyboardBuilderFixedOrderTests extends AndroidTestCase {
+    private static final int WIDTH = 10;
+    private static final int HEIGHT = 10;
+
+    private static final int KEYBOARD_WIDTH = WIDTH * 10;
+    private static final int XPOS_L0 = WIDTH * 0 + WIDTH / 2;
+    private static final int XPOS_L1 = WIDTH * 1 + WIDTH / 2;
+    private static final int XPOS_L2 = WIDTH * 2 + WIDTH / 2;
+    private static final int XPOS_L3 = WIDTH * 3 + WIDTH / 2;
+    private static final int XPOS_M0 = WIDTH * 4 + WIDTH / 2;
+    private static final int XPOS_M1 = WIDTH * 5 + WIDTH / 2;
+    private static final int XPOS_R3 = WIDTH * 6 + WIDTH / 2;
+    private static final int XPOS_R2 = WIDTH * 7 + WIDTH / 2;
+    private static final int XPOS_R1 = WIDTH * 8 + WIDTH / 2;
+    private static final int XPOS_R0 = WIDTH * 9 + WIDTH / 2;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    private static MoreKeysKeyboardParams createParams(int numKeys, int fixColumns,
+            int coordXInParnet) {
+        return new MoreKeysKeyboardParams(numKeys, fixColumns | Key.MORE_KEYS_FIXED_COLUMN_ORDER,
+                WIDTH, HEIGHT, coordXInParnet, KEYBOARD_WIDTH);
+    }
+
+    public void testLayoutError() {
+        MoreKeysKeyboardParams params = null;
+        try {
+            final int fixColumns = KEYBOARD_WIDTH / WIDTH;
+            params = createParams(10, fixColumns + 1, HEIGHT);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Too small keyboard to hold more keys keyboard.
+        }
+        assertNull("Too small keyboard to hold more keys keyboard", params);
+    }
+
+    // More keys keyboard layout test.
+    // "[n]" represents n-th key position in more keys keyboard.
+    // "<m>" is the default key.
+
+    // <1>
+    public void testLayout1KeyFix5M0() {
+        MoreKeysKeyboardParams params = createParams(1, 5, XPOS_M0);
+        assertEquals("1 key fix 5 M0 columns", 1, params.mNumColumns);
+        assertEquals("1 key fix 5 M0 rows", 1, params.mNumRows);
+        assertEquals("1 key fix 5 M0 left", 0, params.mLeftKeys);
+        assertEquals("1 key fix 5 M0 right", 1, params.mRightKeys);
+        assertEquals("1 key fix 5 M0 <1>", 0, params.getColumnPos(0));
+        assertEquals("1 key fix 5 M0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("1 key fix 5 M0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |<1>
+    public void testLayout1KeyFix5L0() {
+        MoreKeysKeyboardParams params = createParams(1, 5, XPOS_L0);
+        assertEquals("1 key fix 5 L0 columns", 1, params.mNumColumns);
+        assertEquals("1 key fix 5 L0 rows", 1, params.mNumRows);
+        assertEquals("1 key fix 5 L0 left", 0, params.mLeftKeys);
+        assertEquals("1 key fix 5 L0 right", 1, params.mRightKeys);
+        assertEquals("1 key fix 5 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("1 key fix 5 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("1 key fix 5 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ <1>
+    public void testLayout1KeyFix5L1() {
+        MoreKeysKeyboardParams params = createParams(1, 5, XPOS_L1);
+        assertEquals("1 key fix 5 L1 columns", 1, params.mNumColumns);
+        assertEquals("1 key fix 5 L1 rows", 1, params.mNumRows);
+        assertEquals("1 key fix 5 L1 left", 0, params.mLeftKeys);
+        assertEquals("1 key fix 5 L1 right", 1, params.mRightKeys);
+        assertEquals("1 key fix 5 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("1 key fix 5 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("1 key fix 5 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ ___ <1>
+    public void testLayout1KeyFix5L2() {
+        MoreKeysKeyboardParams params = createParams(1, 5, XPOS_L2);
+        assertEquals("1 key fix 5 L2 columns", 1, params.mNumColumns);
+        assertEquals("1 key fix 5 L2 rows", 1, params.mNumRows);
+        assertEquals("1 key fix 5 L2 left", 0, params.mLeftKeys);
+        assertEquals("1 key fix 5 L2 right", 1, params.mRightKeys);
+        assertEquals("1 key fix 5 L2 <1>", 0, params.getColumnPos(0));
+        assertEquals("1 key fix 5 L2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("1 key fix 5 L2 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // <1>|
+    public void testLayout1KeyFix5R0() {
+        MoreKeysKeyboardParams params = createParams(1, 5, XPOS_R0);
+        assertEquals("1 key fix 5 R0 columns", 1, params.mNumColumns);
+        assertEquals("1 key fix 5 R0 rows", 1, params.mNumRows);
+        assertEquals("1 key fix 5 R0 left", 0, params.mLeftKeys);
+        assertEquals("1 key fix 5 R0 right", 1, params.mRightKeys);
+        assertEquals("1 key fix 5 R0 <1>", 0, params.getColumnPos(0));
+        assertEquals("1 key fix 5 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("1 key fix 5 R0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // <1> ___|
+    public void testLayout1KeyFix5R1() {
+        MoreKeysKeyboardParams params = createParams(1, 5, XPOS_R1);
+        assertEquals("1 key fix 5 R1 columns", 1, params.mNumColumns);
+        assertEquals("1 key fix 5 R1 rows", 1, params.mNumRows);
+        assertEquals("1 key fix 5 R1 left", 0, params.mLeftKeys);
+        assertEquals("1 key fix 5 R1 right", 1, params.mRightKeys);
+        assertEquals("1 key fix 5 R1 <1>", 0, params.getColumnPos(0));
+        assertEquals("1 key fix 5 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("1 key fix 5 R1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // <1> ___ ___|
+    public void testLayout1KeyFix5R2() {
+        MoreKeysKeyboardParams params = createParams(1, 5, XPOS_R2);
+        assertEquals("1 key fix 5 R2 columns", 1, params.mNumColumns);
+        assertEquals("1 key fix 5 R2 rows", 1, params.mNumRows);
+        assertEquals("1 key fix 5 R2 left", 0, params.mLeftKeys);
+        assertEquals("1 key fix 5 R2 right", 1, params.mRightKeys);
+        assertEquals("1 key fix 5 R2 <1>", 0, params.getColumnPos(0));
+        assertEquals("1 key fix 5 R2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("1 key fix 5 R2 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // <1> [2]
+    public void testLayout2KeyFix5M0() {
+        MoreKeysKeyboardParams params = createParams(2, 5, XPOS_M0);
+        assertEquals("2 key fix 5 M0 columns", 2, params.mNumColumns);
+        assertEquals("2 key fix 5 M0 rows", 1, params.mNumRows);
+        assertEquals("2 key fix 5 M0 left", 0, params.mLeftKeys);
+        assertEquals("2 key fix 5 M0 right", 2, params.mRightKeys);
+        assertEquals("2 key fix 5 M0 <1>", 0, params.getColumnPos(0));
+        assertEquals("2 key fix 5 M0 [2]", 1, params.getColumnPos(1));
+        assertEquals("2 key fix 5 M0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("2 key fix 5 M0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |<1> [2]
+    public void testLayout2KeyFix5L0() {
+        MoreKeysKeyboardParams params = createParams(2, 5, XPOS_L0);
+        assertEquals("2 key fix 5 L0 columns", 2, params.mNumColumns);
+        assertEquals("2 key fix 5 L0 rows", 1, params.mNumRows);
+        assertEquals("2 key fix 5 L0 left", 0, params.mLeftKeys);
+        assertEquals("2 key fix 5 L0 right", 2, params.mRightKeys);
+        assertEquals("2 key fix 5 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("2 key fix 5 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("2 key fix 5 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("2 key fix 5 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ <1> [2]
+    public void testLayout2KeyFix5L1() {
+        MoreKeysKeyboardParams params = createParams(2, 5, XPOS_L1);
+        assertEquals("2 key fix 5 L1 columns", 2, params.mNumColumns);
+        assertEquals("2 key fix 5 L1 rows", 1, params.mNumRows);
+        assertEquals("2 key fix 5 L1 left", 0, params.mLeftKeys);
+        assertEquals("2 key fix 5 L1 right", 2, params.mRightKeys);
+        assertEquals("2 key fix 5 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("2 key fix 5 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("2 key fix 5 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("2 key fix 5 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ ___ <1> [2]
+    public void testLayout2KeyFix5L2() {
+        MoreKeysKeyboardParams params = createParams(2, 5, XPOS_L2);
+        assertEquals("2 key fix 5 L2 columns", 2, params.mNumColumns);
+        assertEquals("2 key fix 5 L2 rows", 1, params.mNumRows);
+        assertEquals("2 key fix 5 L2 left", 0, params.mLeftKeys);
+        assertEquals("2 key fix 5 L2 right", 2, params.mRightKeys);
+        assertEquals("2 key fix 5 L2 <1>", 0, params.getColumnPos(0));
+        assertEquals("2 key fix 5 L2 [2]", 1, params.getColumnPos(1));
+        assertEquals("2 key fix 5 L2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("2 key fix 5 L2 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // [1] <2>|
+    public void testLayout2KeyFix5R0() {
+        MoreKeysKeyboardParams params = createParams(2, 5, XPOS_R0);
+        assertEquals("2 key fix 5 R0 columns", 2, params.mNumColumns);
+        assertEquals("2 key fix 5 R0 rows", 1, params.mNumRows);
+        assertEquals("2 key fix 5 R0 left", 1, params.mLeftKeys);
+        assertEquals("2 key fix 5 R0 right", 1, params.mRightKeys);
+        assertEquals("2 key fix 5 R0 [1]", -1, params.getColumnPos(0));
+        assertEquals("2 key fix 5 R0 <2>", 0, params.getColumnPos(1));
+        assertEquals("2 key fix 5 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("2 key fix 5 R0 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // [1] <2> ___|
+    public void testLayout2KeyFix5R1() {
+        MoreKeysKeyboardParams params = createParams(2, 5, XPOS_R1);
+        assertEquals("2 key fix 5 R1 columns", 2, params.mNumColumns);
+        assertEquals("2 key fix 5 R1 rows", 1, params.mNumRows);
+        assertEquals("2 key fix 5 R1 left", 1, params.mLeftKeys);
+        assertEquals("2 key fix 5 R1 right", 1, params.mRightKeys);
+        assertEquals("2 key fix 5 R1 [1]", -1, params.getColumnPos(0));
+        assertEquals("2 key fix 5 R1 <2>", 0, params.getColumnPos(1));
+        assertEquals("2 key fix 5 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("2 key fix 5 R1 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // <1> [2] ___|
+    public void testLayout2KeyFix5R2() {
+        MoreKeysKeyboardParams params = createParams(2, 5, XPOS_R2);
+        assertEquals("2 key fix 5 R2 columns", 2, params.mNumColumns);
+        assertEquals("2 key fix 5 R2 rows", 1, params.mNumRows);
+        assertEquals("2 key fix 5 R2 left", 0, params.mLeftKeys);
+        assertEquals("2 key fix 5 R2 right", 2, params.mRightKeys);
+        assertEquals("2 key fix 5 R2 <1>", 0, params.getColumnPos(0));
+        assertEquals("2 key fix 5 R2 [2]", 1, params.getColumnPos(1));
+        assertEquals("2 key fix 5 R2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("2 key fix 5 R2 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // [3]
+    // <1> [2]
+    public void testLayout3KeyFix2M0() {
+        MoreKeysKeyboardParams params = createParams(3, 2, XPOS_M0);
+        assertEquals("3 key fix 2 M0 columns", 2, params.mNumColumns);
+        assertEquals("3 key fix 2 M0 rows", 2, params.mNumRows);
+        assertEquals("3 key fix 2 M0 left", 0, params.mLeftKeys);
+        assertEquals("3 key fix 2 M0 right", 2, params.mRightKeys);
+        assertEquals("3 key fix 2 M0 <1>", 0, params.getColumnPos(0));
+        assertEquals("3 key fix 2 M0 [2]", 1, params.getColumnPos(1));
+        assertEquals("3 key fix 2 M0 [3]", 0, params.getColumnPos(2));
+        assertEquals("3 key fix 2 M0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("3 key fix 2 M0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |[3]
+    // |<1> [2]
+    public void testLayout3KeyFix2L0() {
+        MoreKeysKeyboardParams params = createParams(3, 2, XPOS_L0);
+        assertEquals("3 key fix 2 L0 columns", 2, params.mNumColumns);
+        assertEquals("3 key fix 2 L0 rows", 2, params.mNumRows);
+        assertEquals("3 key fix 2 L0 left", 0, params.mLeftKeys);
+        assertEquals("3 key fix 2 L0 right", 2, params.mRightKeys);
+        assertEquals("3 key fix 2 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("3 key fix 2 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("3 key fix 2 L0 [3]", 0, params.getColumnPos(2));
+        assertEquals("3 key fix 2 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("3 key fix 2 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [3]
+    // |___ <1> [2]
+    public void testLayout3KeyFix2L1() {
+        MoreKeysKeyboardParams params = createParams(3, 2, XPOS_L1);
+        assertEquals("3 key fix 2 L1 columns", 2, params.mNumColumns);
+        assertEquals("3 key fix 2 L1 rows", 2, params.mNumRows);
+        assertEquals("3 key fix 2 L1 left", 0, params.mLeftKeys);
+        assertEquals("3 key fix 2 L1 right", 2, params.mRightKeys);
+        assertEquals("3 key fix 2 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("3 key fix 2 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("3 key fix 2 L1 [3]", 0, params.getColumnPos(2));
+        assertEquals("3 key fix 2 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("3 key fix 2 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |        [3]
+    // |___ ___ <1> [2]
+    public void testLayout3KeyFix2L2() {
+        MoreKeysKeyboardParams params = createParams(3, 2, XPOS_L2);
+        assertEquals("3 key fix 2 L2 columns", 2, params.mNumColumns);
+        assertEquals("3 key fix 2 L2 rows", 2, params.mNumRows);
+        assertEquals("3 key fix 2 L2 left", 0, params.mLeftKeys);
+        assertEquals("3 key fix 2 L2 right", 2, params.mRightKeys);
+        assertEquals("3 key fix 2 L2 <1>", 0, params.getColumnPos(0));
+        assertEquals("3 key fix 2 L2 [2]", 1, params.getColumnPos(1));
+        assertEquals("3 key fix 2 L2 [3]", 0, params.getColumnPos(2));
+        assertEquals("3 key fix 2 L2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("3 key fix 2 L2 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    //     [3]|
+    // [1] <2>|
+    public void testLayout3KeyFix2R0() {
+        MoreKeysKeyboardParams params = createParams(3, 2, XPOS_R0);
+        assertEquals("3 key fix 2 R0 columns", 2, params.mNumColumns);
+        assertEquals("3 key fix 2 R0 rows", 2, params.mNumRows);
+        assertEquals("3 key fix 2 R0 left", 1, params.mLeftKeys);
+        assertEquals("3 key fix 2 R0 right", 1, params.mRightKeys);
+        assertEquals("3 key fix 2 R0 [1]", -1, params.getColumnPos(0));
+        assertEquals("3 key fix 2 R0 <2>", 0, params.getColumnPos(1));
+        assertEquals("3 key fix 2 R0 [3]", 0, params.getColumnPos(2));
+        assertEquals("3 key fix 2 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("3 key fix 2 R0 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    //     [3] ___|
+    // [1] <2> ___|
+    public void testLayout3KeyFix2R1() {
+        MoreKeysKeyboardParams params = createParams(3, 2, XPOS_R1);
+        assertEquals("3 key fix 2 R1 columns", 2, params.mNumColumns);
+        assertEquals("3 key fix 2 R1 rows", 2, params.mNumRows);
+        assertEquals("3 key fix 2 R1 left", 1, params.mLeftKeys);
+        assertEquals("3 key fix 2 R1 right", 1, params.mRightKeys);
+        assertEquals("3 key fix 2 R1 [1]", -1, params.getColumnPos(0));
+        assertEquals("3 key fix 2 R1 <2>", 0, params.getColumnPos(1));
+        assertEquals("3 key fix 2 R1 [3]", 0, params.getColumnPos(2));
+        assertEquals("3 key fix 2 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("3 key fix 2 R1 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // [3]     ___|
+    // <1> [2] ___|
+    public void testLayout3KeyFix2R2() {
+        MoreKeysKeyboardParams params = createParams(3, 2, XPOS_R2);
+        assertEquals("3 key fix 2 R2 columns", 2, params.mNumColumns);
+        assertEquals("3 key fix 2 R2 rows", 2, params.mNumRows);
+        assertEquals("3 key fix 2 R2 left", 0, params.mLeftKeys);
+        assertEquals("3 key fix 2 R2 right", 2, params.mRightKeys);
+        assertEquals("3 key fix 2 R2 <1>", 0, params.getColumnPos(0));
+        assertEquals("3 key fix 2 R2 [2]", 1, params.getColumnPos(1));
+        assertEquals("3 key fix 2 R2 [3]", 0, params.getColumnPos(2));
+        assertEquals("3 key fix 2 R2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("3 key fix 2 R2 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // [3] [4]
+    // <1> [2]
+    public void testLayout4KeyFix2M0() {
+        MoreKeysKeyboardParams params = createParams(4, 2, XPOS_M0);
+        assertEquals("3 key fix 2 M0 columns", 2, params.mNumColumns);
+        assertEquals("3 key fix 2 M0 rows", 2, params.mNumRows);
+        assertEquals("3 key fix 2 M0 left", 0, params.mLeftKeys);
+        assertEquals("3 key fix 2 M0 right", 2, params.mRightKeys);
+        assertEquals("3 key fix 2 M0 <1>", 0, params.getColumnPos(0));
+        assertEquals("3 key fix 2 M0 [2]", 1, params.getColumnPos(1));
+        assertEquals("3 key fix 2 M0 [3]", 0, params.getColumnPos(2));
+        assertEquals("3 key fix 2 M0 [4]", 1, params.getColumnPos(3));
+        assertEquals("3 key fix 2 M0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("3 key fix 2 M0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |[3] [4]
+    // |<1> [2]
+    public void testLayout4KeyFix2L0() {
+        MoreKeysKeyboardParams params = createParams(4, 2, XPOS_L0);
+        assertEquals("3 key fix 2 L0 columns", 2, params.mNumColumns);
+        assertEquals("3 key fix 2 L0 rows", 2, params.mNumRows);
+        assertEquals("3 key fix 2 L0 left", 0, params.mLeftKeys);
+        assertEquals("3 key fix 2 L0 right", 2, params.mRightKeys);
+        assertEquals("3 key fix 2 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("3 key fix 2 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("3 key fix 2 L0 [3]", 0, params.getColumnPos(2));
+        assertEquals("3 key fix 2 L0 [4]", 1, params.getColumnPos(3));
+        assertEquals("3 key fix 2 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("3 key fix 2 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [3] [4]
+    // |___ <1> [2]
+    public void testLayout4KeyFix2L1() {
+        MoreKeysKeyboardParams params = createParams(4, 2, XPOS_L1);
+        assertEquals("3 key fix 2 L1 columns", 2, params.mNumColumns);
+        assertEquals("3 key fix 2 L1 rows", 2, params.mNumRows);
+        assertEquals("3 key fix 2 L1 left", 0, params.mLeftKeys);
+        assertEquals("3 key fix 2 L1 right", 2, params.mRightKeys);
+        assertEquals("3 key fix 2 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("3 key fix 2 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("3 key fix 2 L1 [3]", 0, params.getColumnPos(2));
+        assertEquals("3 key fix 2 L1 [4]", 1, params.getColumnPos(3));
+        assertEquals("3 key fix 2 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("3 key fix 2 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |        [3] [4]
+    // |___ ___ <1> [2]
+    public void testLayout4KeyFix2L2() {
+        MoreKeysKeyboardParams params = createParams(4, 2, XPOS_L2);
+        assertEquals("3 key fix 2 L2 columns", 2, params.mNumColumns);
+        assertEquals("3 key fix 2 L2 rows", 2, params.mNumRows);
+        assertEquals("3 key fix 2 L2 left", 0, params.mLeftKeys);
+        assertEquals("3 key fix 2 L2 right", 2, params.mRightKeys);
+        assertEquals("3 key fix 2 L2 <1>", 0, params.getColumnPos(0));
+        assertEquals("3 key fix 2 L2 [2]", 1, params.getColumnPos(1));
+        assertEquals("3 key fix 2 L2 [3]", 0, params.getColumnPos(2));
+        assertEquals("3 key fix 2 L2 [4]", 1, params.getColumnPos(3));
+        assertEquals("3 key fix 2 L2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("3 key fix 2 L2 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // [3] [4]|
+    // [1] <2>|
+    public void testLayout4KeyFix2R0() {
+        MoreKeysKeyboardParams params = createParams(4, 2, XPOS_R0);
+        assertEquals("3 key fix 2 R0 columns", 2, params.mNumColumns);
+        assertEquals("3 key fix 2 R0 rows", 2, params.mNumRows);
+        assertEquals("3 key fix 2 R0 left", 1, params.mLeftKeys);
+        assertEquals("3 key fix 2 R0 right", 1, params.mRightKeys);
+        assertEquals("3 key fix 2 R0 [1]", -1, params.getColumnPos(0));
+        assertEquals("3 key fix 2 R0 <2>", 0, params.getColumnPos(1));
+        assertEquals("3 key fix 2 R0 [3]", -1, params.getColumnPos(2));
+        assertEquals("3 key fix 2 R0 [4]", 0, params.getColumnPos(3));
+        assertEquals("3 key fix 2 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("3 key fix 2 R0 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // [3] [4] ___|
+    // [1] <2> ___|
+    public void testLayout4KeyFix2R1() {
+        MoreKeysKeyboardParams params = createParams(4, 2, XPOS_R1);
+        assertEquals("3 key fix 2 R1 columns", 2, params.mNumColumns);
+        assertEquals("3 key fix 2 R1 rows", 2, params.mNumRows);
+        assertEquals("3 key fix 2 R1 left", 1, params.mLeftKeys);
+        assertEquals("3 key fix 2 R1 right", 1, params.mRightKeys);
+        assertEquals("3 key fix 2 R1 [1]", -1, params.getColumnPos(0));
+        assertEquals("3 key fix 2 R1 <2>", 0, params.getColumnPos(1));
+        assertEquals("3 key fix 2 R1 [3]", -1, params.getColumnPos(2));
+        assertEquals("3 key fix 2 R1 [4]", 0, params.getColumnPos(3));
+        assertEquals("3 key fix 2 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("3 key fix 2 R1 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // [3] [4] ___|
+    // <1> [2] ___|
+    public void testLayout4KeyFix2R2() {
+        MoreKeysKeyboardParams params = createParams(4, 2, XPOS_R2);
+        assertEquals("3 key fix 2 R2 columns", 2, params.mNumColumns);
+        assertEquals("3 key fix 2 R2 rows", 2, params.mNumRows);
+        assertEquals("3 key fix 2 R2 left", 0, params.mLeftKeys);
+        assertEquals("3 key fix 2 R2 right", 2, params.mRightKeys);
+        assertEquals("3 key fix 2 R2 <1>", 0, params.getColumnPos(0));
+        assertEquals("3 key fix 2 R2 [2]", 1, params.getColumnPos(1));
+        assertEquals("3 key fix 2 R2 [3]", 0, params.getColumnPos(2));
+        assertEquals("3 key fix 2 R2 [4]", 1, params.getColumnPos(3));
+        assertEquals("3 key fix 2 R2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("3 key fix 2 R2 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // [1] <2> [3]
+    public void testLayout3KeyFix5M0() {
+        MoreKeysKeyboardParams params = createParams(3, 5, XPOS_M0);
+        assertEquals("3 key fix 5 columns", 3, params.mNumColumns);
+        assertEquals("3 key fix 5 rows", 1, params.mNumRows);
+        assertEquals("3 key fix 5 left", 1, params.mLeftKeys);
+        assertEquals("3 key fix 5 right", 2, params.mRightKeys);
+        assertEquals("3 key fix 5 [1]", -1, params.getColumnPos(0));
+        assertEquals("3 key fix 5 <2>", 0, params.getColumnPos(1));
+        assertEquals("3 key fix 5 [3]", 1, params.getColumnPos(2));
+        assertEquals("3 key fix 5 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("3 key fix 5 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // |<1> [2] [3]
+    public void testLayout3KeyFix5L0() {
+        MoreKeysKeyboardParams params = createParams(3, 5, XPOS_L0);
+        assertEquals("3 key fix 5 L0 columns", 3, params.mNumColumns);
+        assertEquals("3 key fix 5 L0 rows", 1, params.mNumRows);
+        assertEquals("3 key fix 5 L0 left", 0, params.mLeftKeys);
+        assertEquals("3 key fix 5 L0 right", 3, params.mRightKeys);
+        assertEquals("3 key fix 5 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("3 key fix 5 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("3 key fix 5 L0 [3]", 2, params.getColumnPos(2));
+        assertEquals("3 key fix 5 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("3 key fix 5 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ <1> [2] [3]
+    public void testLayout3KeyFix5L1() {
+        MoreKeysKeyboardParams params = createParams(3, 5, XPOS_L1);
+        assertEquals("3 key fix 5 L1 columns", 3, params.mNumColumns);
+        assertEquals("3 key fix 5 L1 rows", 1, params.mNumRows);
+        assertEquals("3 key fix 5 L1 left", 0, params.mLeftKeys);
+        assertEquals("3 key fix 5 L1 right", 3, params.mRightKeys);
+        assertEquals("3 key fix 5 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("3 key fix 5 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("3 key fix 5 L1 [3]", 2, params.getColumnPos(2));
+        assertEquals("3 key fix 5 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("3 key fix 5 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [1] <2> [3]
+    public void testLayout3KeyFix5L2() {
+        MoreKeysKeyboardParams params = createParams(3, 5, XPOS_L2);
+        assertEquals("3 key fix 5 L2 columns", 3, params.mNumColumns);
+        assertEquals("3 key fix 5 L2 rows", 1, params.mNumRows);
+        assertEquals("3 key fix 5 L2 left", 1, params.mLeftKeys);
+        assertEquals("3 key fix 5 L2 right", 2, params.mRightKeys);
+        assertEquals("3 key fix 5 L2 [1]", -1, params.getColumnPos(0));
+        assertEquals("3 key fix 5 L2 <2>", 0, params.getColumnPos(1));
+        assertEquals("3 key fix 5 L2 [3]", 1, params.getColumnPos(2));
+        assertEquals("3 key fix 5 L2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("3 key fix 5 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // [1] [2] <3>|
+    public void testLayout3KeyFix5R0() {
+        MoreKeysKeyboardParams params = createParams(3, 5, XPOS_R0);
+        assertEquals("3 key fix 5 R0 columns", 3, params.mNumColumns);
+        assertEquals("3 key fix 5 R0 rows", 1, params.mNumRows);
+        assertEquals("3 key fix 5 R0 left", 2, params.mLeftKeys);
+        assertEquals("3 key fix 5 R0 right", 1, params.mRightKeys);
+        assertEquals("3 key fix 5 R0 [1]", -2, params.getColumnPos(0));
+        assertEquals("3 key fix 5 R0 [2]", -1, params.getColumnPos(1));
+        assertEquals("3 key fix 5 R0 <3>", 0, params.getColumnPos(2));
+        assertEquals("3 key fix 5 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("3 key fix 5 R0 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    // [1] [2] <3> ___|
+    public void testLayout3KeyFix5R1() {
+        MoreKeysKeyboardParams params = createParams(3, 5, XPOS_R1);
+        assertEquals("3 key fix 5 R1 columns", 3, params.mNumColumns);
+        assertEquals("3 key fix 5 R1 rows", 1, params.mNumRows);
+        assertEquals("3 key fix 5 R1 left", 2, params.mLeftKeys);
+        assertEquals("3 key fix 5 R1 right", 1, params.mRightKeys);
+        assertEquals("3 key fix 5 R1 [1]", -2, params.getColumnPos(0));
+        assertEquals("3 key fix 5 R1 [2]", -1, params.getColumnPos(1));
+        assertEquals("3 key fix 5 R1 <3>", 0, params.getColumnPos(2));
+        assertEquals("3 key fix 5 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("3 key fix 5 R1 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    // [1] <2> [3] ___|
+    public void testLayout3KeyFix5R2() {
+        MoreKeysKeyboardParams params = createParams(3, 5, XPOS_R2);
+        assertEquals("3 key fix 5 R2 columns", 3, params.mNumColumns);
+        assertEquals("3 key fix 5 R2 rows", 1, params.mNumRows);
+        assertEquals("3 key fix 5 R2 left", 1, params.mLeftKeys);
+        assertEquals("3 key fix 5 R2 right", 2, params.mRightKeys);
+        assertEquals("3 key fix 5 R2 [1]", -1, params.getColumnPos(0));
+        assertEquals("3 key fix 5 R2 <2>", 0, params.getColumnPos(1));
+        assertEquals("3 key fix 5 R2 [3]", 1, params.getColumnPos(2));
+        assertEquals("3 key fix 5 R2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("3 key fix 5 R2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    //     [4]
+    // [1] <2> [3]
+    public void testLayout4KeyFix3M0() {
+        MoreKeysKeyboardParams params = createParams(4, 3, XPOS_M0);
+        assertEquals("4 key fix 3 M0 columns", 3, params.mNumColumns);
+        assertEquals("4 key fix 3 M0 rows", 2, params.mNumRows);
+        assertEquals("4 key fix 3 M0 left", 1, params.mLeftKeys);
+        assertEquals("4 key fix 3 M0 right", 2, params.mRightKeys);
+        assertEquals("4 key fix 3 M0 [1]", -1, params.getColumnPos(0));
+        assertEquals("4 key fix 3 M0 <2>", 0, params.getColumnPos(1));
+        assertEquals("4 key fix 3 M0 [3]", 1, params.getColumnPos(2));
+        assertEquals("4 key fix 3 M0 [4]", 0, params.getColumnPos(3));
+        assertEquals("4 key fix 3 M0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key fix 3 M0 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // |[4]
+    // |<1> [2] [3]
+    public void testLayout4KeyFix3L0() {
+        MoreKeysKeyboardParams params = createParams(4, 3, XPOS_L0);
+        assertEquals("4 key fix 3 L0 columns", 3, params.mNumColumns);
+        assertEquals("4 key fix 3 L0 rows", 2, params.mNumRows);
+        assertEquals("4 key fix 3 L0 left", 0, params.mLeftKeys);
+        assertEquals("4 key fix 3 L0 right", 3, params.mRightKeys);
+        assertEquals("4 key fix 3 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("4 key fix 3 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("4 key fix 3 L0 [3]", 2, params.getColumnPos(2));
+        assertEquals("4 key fix 3 L0 [4]", 0, params.getColumnPos(3));
+        assertEquals("4 key fix 3 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key fix 3 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [4]
+    // |___ <1> [2] [3]
+    public void testLayout4KeyFix3L1() {
+        MoreKeysKeyboardParams params = createParams(4, 3, XPOS_L1);
+        assertEquals("4 key fix 3 L1 columns", 3, params.mNumColumns);
+        assertEquals("4 key fix 3 L1 rows", 2, params.mNumRows);
+        assertEquals("4 key fix 3 L1 left", 0, params.mLeftKeys);
+        assertEquals("4 key fix 3 L1 right", 3, params.mRightKeys);
+        assertEquals("4 key fix 3 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("4 key fix 3 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("4 key fix 3 L1 [3]", 2, params.getColumnPos(2));
+        assertEquals("4 key fix 3 L1 [4]", 0, params.getColumnPos(3));
+        assertEquals("4 key fix 3 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key fix 3 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ ___     [4]
+    // |___ ___ [1] <2> [3]
+    public void testLayout4KeyFix3L2() {
+        MoreKeysKeyboardParams params = createParams(4, 3, XPOS_L2);
+        assertEquals("4 key fix 3 L2 columns", 3, params.mNumColumns);
+        assertEquals("4 key fix 3 L2 rows", 2, params.mNumRows);
+        assertEquals("4 key fix 3 L2 left", 1, params.mLeftKeys);
+        assertEquals("4 key fix 3 L2 right", 2, params.mRightKeys);
+        assertEquals("4 key fix 3 L2 [1]", -1, params.getColumnPos(0));
+        assertEquals("4 key fix 3 L2 <2>", 0, params.getColumnPos(1));
+        assertEquals("4 key fix 3 L2 [3]", 1, params.getColumnPos(2));
+        assertEquals("4 key fix 3 L2 [4]", 0, params.getColumnPos(3));
+        assertEquals("4 key fix 3 L2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key fix 3 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    //         [4]|
+    // [1] [2] <3>|
+    public void testLayout4KeyFix3R0() {
+        MoreKeysKeyboardParams params = createParams(4, 3, XPOS_R0);
+        assertEquals("4 key fix 3 R0 columns", 3, params.mNumColumns);
+        assertEquals("4 key fix 3 R0 rows", 2, params.mNumRows);
+        assertEquals("4 key fix 3 R0 left", 2, params.mLeftKeys);
+        assertEquals("4 key fix 3 R0 right", 1, params.mRightKeys);
+        assertEquals("4 key fix 3 R0 [1]", -2, params.getColumnPos(0));
+        assertEquals("4 key fix 3 R0 [2]", -1, params.getColumnPos(1));
+        assertEquals("4 key fix 3 R0 <3>", 0, params.getColumnPos(2));
+        assertEquals("4 key fix 3 R0 [4]", 0, params.getColumnPos(3));
+        assertEquals("4 key fix 3 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key fix 3 R0 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    //         [4] ___|
+    // [1] [2] <3> ___|
+    public void testLayout4KeyFix3R1() {
+        MoreKeysKeyboardParams params = createParams(4, 3, XPOS_R1);
+        assertEquals("4 key fix 3 R1 columns", 3, params.mNumColumns);
+        assertEquals("4 key fix 3 R1 rows", 2, params.mNumRows);
+        assertEquals("4 key fix 3 R1 left", 2, params.mLeftKeys);
+        assertEquals("4 key fix 3 R1 right", 1, params.mRightKeys);
+        assertEquals("4 key fix 3 R1 [1]", -2, params.getColumnPos(0));
+        assertEquals("4 key fix 3 R1 [2]", -1, params.getColumnPos(1));
+        assertEquals("4 key fix 3 R1 <3>", 0, params.getColumnPos(2));
+        assertEquals("4 key fix 3 R1 [4]", 0, params.getColumnPos(3));
+        assertEquals("4 key fix 3 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key fix 3 R1 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    //     [4]     ___|
+    // [1] <2> [3] ___|
+    public void testLayout4KeyFix3R2() {
+        MoreKeysKeyboardParams params = createParams(4, 3, XPOS_R2);
+        assertEquals("4 key fix 3 R2 columns", 3, params.mNumColumns);
+        assertEquals("4 key fix 3 R2 rows", 2, params.mNumRows);
+        assertEquals("4 key fix 3 R2 left", 1, params.mLeftKeys);
+        assertEquals("4 key fix 3 R2 right", 2, params.mRightKeys);
+        assertEquals("4 key fix 3 R2 [1]", -1, params.getColumnPos(0));
+        assertEquals("4 key fix 3 R2 <2>", 0, params.getColumnPos(1));
+        assertEquals("4 key fix 3 R2 [3]", 1, params.getColumnPos(2));
+        assertEquals("4 key fix 3 R2 [4]", 0, params.getColumnPos(3));
+        assertEquals("4 key fix 3 R2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key fix 3 R2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    //   [4] [5]
+    // [1] <2> [3]
+    public void testLayout5KeyFix3M0() {
+        MoreKeysKeyboardParams params = createParams(5, 3, XPOS_M0);
+        assertEquals("5 key fix 3 M0 columns", 3, params.mNumColumns);
+        assertEquals("5 key fix 3 M0 rows", 2, params.mNumRows);
+        assertEquals("5 key fix 3 M0 left", 1, params.mLeftKeys);
+        assertEquals("5 key fix 3 M0 right", 2, params.mRightKeys);
+        assertEquals("5 key fix 3 M0 [1]", -1, params.getColumnPos(0));
+        assertEquals("5 key fix 3 M0 <2>", 0, params.getColumnPos(1));
+        assertEquals("5 key fix 3 M0 [3]", 1, params.getColumnPos(2));
+        assertEquals("5 key fix 3 M0 [4]", 0, params.getColumnPos(3));
+        assertEquals("5 key fix 3 M0 [5]", 1, params.getColumnPos(4));
+        assertEquals("5 key fix 3 M0 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("5 key fix 3 M0 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // |[4] [5]
+    // |<1> [2] [3]
+    public void testLayout5KeyFix3L0() {
+        MoreKeysKeyboardParams params = createParams(5, 3, XPOS_L0);
+        assertEquals("5 key fix 3 L0 columns", 3, params.mNumColumns);
+        assertEquals("5 key fix 3 L0 rows", 2, params.mNumRows);
+        assertEquals("5 key fix 3 L0 left", 0, params.mLeftKeys);
+        assertEquals("5 key fix 3 L0 right", 3, params.mRightKeys);
+        assertEquals("5 key fix 3 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("5 key fix 3 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("5 key fix 3 L0 [3]", 2, params.getColumnPos(2));
+        assertEquals("5 key fix 3 L0 [4]", 0, params.getColumnPos(3));
+        assertEquals("5 key fix 3 L0 [5]", 1, params.getColumnPos(4));
+        assertEquals("5 key fix 3 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key fix 3 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [4] [5]
+    // |___ <1> [2] [3]
+    public void testLayout5KeyFix3L1() {
+        MoreKeysKeyboardParams params = createParams(5, 3, XPOS_L1);
+        assertEquals("5 key fix 3 L1 columns", 3, params.mNumColumns);
+        assertEquals("5 key fix 3 L1 rows", 2, params.mNumRows);
+        assertEquals("5 key fix 3 L1 left", 0, params.mLeftKeys);
+        assertEquals("5 key fix 3 L1 right", 3, params.mRightKeys);
+        assertEquals("5 key fix 3 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("5 key fix 3 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("5 key fix 3 L1 [3]", 2, params.getColumnPos(2));
+        assertEquals("5 key fix 3 L1 [4]", 0, params.getColumnPos(3));
+        assertEquals("5 key fix 3 L1 [5]", 1, params.getColumnPos(4));
+        assertEquals("5 key fix 3 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key fix 3 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___   [4] [5]
+    // |___ [1] <2> [3]
+    public void testLayout5KeyFix3L2() {
+        MoreKeysKeyboardParams params = createParams(5, 3, XPOS_L2);
+        assertEquals("5 key fix 3 L2 columns", 3, params.mNumColumns);
+        assertEquals("5 key fix 3 L2 rows", 2, params.mNumRows);
+        assertEquals("5 key fix 3 L2 left", 1, params.mLeftKeys);
+        assertEquals("5 key fix 3 L2 right", 2, params.mRightKeys);
+        assertEquals("5 key fix 3 L2 [1]", -1, params.getColumnPos(0));
+        assertEquals("5 key fix 3 L2 <2>", 0, params.getColumnPos(1));
+        assertEquals("5 key fix 3 L2 [3]", 1, params.getColumnPos(2));
+        assertEquals("5 key fix 3 L2 [4]", 0, params.getColumnPos(3));
+        assertEquals("5 key fix 3 L2 [5]", 1, params.getColumnPos(4));
+        assertEquals("5 key fix 3 L2 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("5 key fix 3 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    //     [4] [5]|
+    // [1] [2] <3>|
+    public void testLayout5KeyFix3R0() {
+        MoreKeysKeyboardParams params = createParams(5, 3, XPOS_R0);
+        assertEquals("5 key fix 3 R0 columns", 3, params.mNumColumns);
+        assertEquals("5 key fix 3 R0 rows", 2, params.mNumRows);
+        assertEquals("5 key fix 3 R0 left", 2, params.mLeftKeys);
+        assertEquals("5 key fix 3 R0 right", 1, params.mRightKeys);
+        assertEquals("5 key fix 3 R0 [1]", -2, params.getColumnPos(0));
+        assertEquals("5 key fix 3 R0 [2]", -1, params.getColumnPos(1));
+        assertEquals("5 key fix 3 R0 <3>", 0, params.getColumnPos(2));
+        assertEquals("5 key fix 3 R0 [4]", -1, params.getColumnPos(3));
+        assertEquals("5 key fix 3 R0 [5]", 0, params.getColumnPos(4));
+        assertEquals("5 key fix 3 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key fix 3 R0 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    //     [4] [5] ___|
+    // [1] [2] <3> ___|
+    public void testLayout5KeyFix3R1() {
+        MoreKeysKeyboardParams params = createParams(5, 3, XPOS_R1);
+        assertEquals("5 key fix 3 R1 columns", 3, params.mNumColumns);
+        assertEquals("5 key fix 3 R1 rows", 2, params.mNumRows);
+        assertEquals("5 key fix 3 R1 left", 2, params.mLeftKeys);
+        assertEquals("5 key fix 3 R1 right", 1, params.mRightKeys);
+        assertEquals("5 key fix 3 R1 [1]", -2, params.getColumnPos(0));
+        assertEquals("5 key fix 3 R1 [2]", -1, params.getColumnPos(1));
+        assertEquals("5 key fix 3 R1 <3>", 0, params.getColumnPos(2));
+        assertEquals("5 key fix 3 R1 [4]", -1, params.getColumnPos(3));
+        assertEquals("5 key fix 3 R1 [5]", 0, params.getColumnPos(4));
+        assertEquals("5 key fix 3 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key fix 3 R1 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    //   [4] [5]   ___|
+    // [1] <2> [3] ___|
+    public void testLayout5KeyFix3R2() {
+        MoreKeysKeyboardParams params = createParams(5, 3, XPOS_R2);
+        assertEquals("5 key fix 3 R2 columns", 3, params.mNumColumns);
+        assertEquals("5 key fix 3 R2 rows", 2, params.mNumRows);
+        assertEquals("5 key fix 3 R2 left", 1, params.mLeftKeys);
+        assertEquals("5 key fix 3 R2 right", 2, params.mRightKeys);
+        assertEquals("5 key fix 3 R2 [1]", -1, params.getColumnPos(0));
+        assertEquals("5 key fix 3 R2 <2>", 0, params.getColumnPos(1));
+        assertEquals("5 key fix 3 R2 [3]", 1, params.getColumnPos(2));
+        assertEquals("5 key fix 3 R2 [4]", 0, params.getColumnPos(3));
+        assertEquals("5 key fix 3 R2 [5]", 1, params.getColumnPos(4));
+        assertEquals("5 key fix 3 R2 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("5 key fix 3 R2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // [4] [5] [6]
+    // [1] <2> [3]
+    public void testLayout6KeyFix3M0() {
+        MoreKeysKeyboardParams params = createParams(6, 3, XPOS_M0);
+        assertEquals("6 key fix 3 M0 columns", 3, params.mNumColumns);
+        assertEquals("6 key fix 3 M0 rows", 2, params.mNumRows);
+        assertEquals("6 key fix 3 M0 left", 1, params.mLeftKeys);
+        assertEquals("6 key fix 3 M0 right", 2, params.mRightKeys);
+        assertEquals("6 key fix 3 M0 [1]", -1, params.getColumnPos(0));
+        assertEquals("6 key fix 3 M0 <2>", 0, params.getColumnPos(1));
+        assertEquals("6 key fix 3 M0 [3]", 1, params.getColumnPos(2));
+        assertEquals("6 key fix 3 M0 [4]", -1, params.getColumnPos(3));
+        assertEquals("6 key fix 3 M0 [5]", 0, params.getColumnPos(4));
+        assertEquals("6 key fix 3 M0 [6]", 1, params.getColumnPos(5));
+        assertEquals("6 key fix 3 M0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key fix 3 M0 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // |[4] [5] [6]
+    // |<1> [2] [3]
+    public void testLayout6KeyFix3L0() {
+        MoreKeysKeyboardParams params = createParams(6, 3, XPOS_L0);
+        assertEquals("6 key fix 3 L0 columns", 3, params.mNumColumns);
+        assertEquals("6 key fix 3 L0 rows", 2, params.mNumRows);
+        assertEquals("6 key fix 3 L0 left", 0, params.mLeftKeys);
+        assertEquals("6 key fix 3 L0 right", 3, params.mRightKeys);
+        assertEquals("6 key fix 3 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("6 key fix 3 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("6 key fix 3 L0 [3]", 2, params.getColumnPos(2));
+        assertEquals("6 key fix 3 L0 [4]", 0, params.getColumnPos(3));
+        assertEquals("6 key fix 3 L0 [5]", 1, params.getColumnPos(4));
+        assertEquals("6 key fix 3 L0 [6]", 2, params.getColumnPos(5));
+        assertEquals("6 key fix 3 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key fix 3 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [4] [5] [6]
+    // |___ <1> [2] [3]
+    public void testLayout6KeyFix3L1() {
+        MoreKeysKeyboardParams params = createParams(6, 3, XPOS_L1);
+        assertEquals("6 key fix 3 L1 columns", 3, params.mNumColumns);
+        assertEquals("6 key fix 3 L1 rows", 2, params.mNumRows);
+        assertEquals("6 key fix 3 L1 left", 0, params.mLeftKeys);
+        assertEquals("6 key fix 3 L1 right", 3, params.mRightKeys);
+        assertEquals("6 key fix 3 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("6 key fix 3 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("6 key fix 3 L1 [3]", 2, params.getColumnPos(2));
+        assertEquals("6 key fix 3 L1 [4]", 0, params.getColumnPos(3));
+        assertEquals("6 key fix 3 L1 [5]", 1, params.getColumnPos(4));
+        assertEquals("6 key fix 3 L1 [6]", 2, params.getColumnPos(5));
+        assertEquals("6 key fix 3 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key fix 3 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [4] [5] [6]
+    // |___ [1] <2> [3]
+    public void testLayout6KeyFix3L2() {
+        MoreKeysKeyboardParams params = createParams(6, 3, XPOS_L2);
+        assertEquals("6 key fix 3 L2 columns", 3, params.mNumColumns);
+        assertEquals("6 key fix 3 L2 rows", 2, params.mNumRows);
+        assertEquals("6 key fix 3 L2 left", 1, params.mLeftKeys);
+        assertEquals("6 key fix 3 L2 right", 2, params.mRightKeys);
+        assertEquals("6 key fix 3 L2 [1]", -1, params.getColumnPos(0));
+        assertEquals("6 key fix 3 L2 <2>", 0, params.getColumnPos(1));
+        assertEquals("6 key fix 3 L2 [3]", 1, params.getColumnPos(2));
+        assertEquals("6 key fix 3 L2 [4]", -1, params.getColumnPos(3));
+        assertEquals("6 key fix 3 L2 [5]", 0, params.getColumnPos(4));
+        assertEquals("6 key fix 3 L2 [6]", 1, params.getColumnPos(5));
+        assertEquals("6 key fix 3 L2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key fix 3 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // [4] [5] [6]|
+    // [1] [2] <3>|
+    public void testLayout6KeyFix3R0() {
+        MoreKeysKeyboardParams params = createParams(6, 3, XPOS_R0);
+        assertEquals("6 key fix 3 R0 columns", 3, params.mNumColumns);
+        assertEquals("6 key fix 3 R0 rows", 2, params.mNumRows);
+        assertEquals("6 key fix 3 R0 left", 2, params.mLeftKeys);
+        assertEquals("6 key fix 3 R0 right", 1, params.mRightKeys);
+        assertEquals("6 key fix 3 R0 [1]", -2, params.getColumnPos(0));
+        assertEquals("6 key fix 3 R0 [2]", -1, params.getColumnPos(1));
+        assertEquals("6 key fix 3 R0 <3>", 0, params.getColumnPos(2));
+        assertEquals("6 key fix 3 R0 [4]", -2, params.getColumnPos(3));
+        assertEquals("6 key fix 3 R0 [5]", -1, params.getColumnPos(4));
+        assertEquals("6 key fix 3 R0 [6]", 0, params.getColumnPos(5));
+        assertEquals("6 key fix 3 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key fix 3 R0 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    // [4] [5] [6] ___|
+    // [1] [2] <3> ___|
+    public void testLayout6KeyFix3R1() {
+        MoreKeysKeyboardParams params = createParams(6, 3, XPOS_R1);
+        assertEquals("6 key fix 3 R1 columns", 3, params.mNumColumns);
+        assertEquals("6 key fix 3 R1 rows", 2, params.mNumRows);
+        assertEquals("6 key fix 3 R1 left", 2, params.mLeftKeys);
+        assertEquals("6 key fix 3 R1 right", 1, params.mRightKeys);
+        assertEquals("6 key fix 3 R1 [1]", -2, params.getColumnPos(0));
+        assertEquals("6 key fix 3 R1 [2]", -1, params.getColumnPos(1));
+        assertEquals("6 key fix 3 R1 <3>", 0, params.getColumnPos(2));
+        assertEquals("6 key fix 3 R1 [4]", -2, params.getColumnPos(3));
+        assertEquals("6 key fix 3 R1 [5]", -1, params.getColumnPos(4));
+        assertEquals("6 key fix 3 R1 [6]", 0, params.getColumnPos(5));
+        assertEquals("6 key fix 3 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key fix 3 R1 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    // [4] [5] [6] ___|
+    // [1] <2> [3] ___|
+    public void testLayout6KeyFix3R2() {
+        MoreKeysKeyboardParams params = createParams(6, 3, XPOS_R2);
+        assertEquals("6 key fix 3 R2 columns", 3, params.mNumColumns);
+        assertEquals("6 key fix 3 R2 rows", 2, params.mNumRows);
+        assertEquals("6 key fix 3 R2 left", 1, params.mLeftKeys);
+        assertEquals("6 key fix 3 R2 right", 2, params.mRightKeys);
+        assertEquals("6 key fix 3 R2 [1]", -1, params.getColumnPos(0));
+        assertEquals("6 key fix 3 R2 <2>", 0, params.getColumnPos(1));
+        assertEquals("6 key fix 3 R2 [1]", 1, params.getColumnPos(2));
+        assertEquals("6 key fix 3 R2 [4]", -1, params.getColumnPos(3));
+        assertEquals("6 key fix 3 R2 [5]", 0, params.getColumnPos(4));
+        assertEquals("6 key fix 3 R2 [6]", 1, params.getColumnPos(5));
+        assertEquals("6 key fix 3 R2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key fix 3 R2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // <1> [2] [3] [4]
+    public void testLayout4KeyFix5M0() {
+        MoreKeysKeyboardParams params = createParams(4, 5, XPOS_M0);
+        assertEquals("4 key fix 5 columns", 4, params.mNumColumns);
+        assertEquals("4 key fix 5 rows", 1, params.mNumRows);
+        assertEquals("4 key fix 5 left", 1, params.mLeftKeys);
+        assertEquals("4 key fix 5 right", 3, params.mRightKeys);
+        assertEquals("4 key fix 5 <1>", -1, params.getColumnPos(0));
+        assertEquals("4 key fix 5 [2]", 0, params.getColumnPos(1));
+        assertEquals("4 key fix 5 [3]", 1, params.getColumnPos(2));
+        assertEquals("4 key fix 5 [4]", 2, params.getColumnPos(3));
+        assertEquals("4 key fix 5 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key fix 5 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // |<1> [2] [3] [4]
+    public void testLayout4KeyFix5L0() {
+        MoreKeysKeyboardParams params = createParams(4, 5, XPOS_L0);
+        assertEquals("4 key fix 5 L0 columns", 4, params.mNumColumns);
+        assertEquals("4 key fix 5 L0 rows", 1, params.mNumRows);
+        assertEquals("4 key fix 5 L0 left", 0, params.mLeftKeys);
+        assertEquals("4 key fix 5 L0 right", 4, params.mRightKeys);
+        assertEquals("4 key fix 5 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("4 key fix 5 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("4 key fix 5 L0 [3]", 2, params.getColumnPos(2));
+        assertEquals("4 key fix 5 L0 [4]", 3, params.getColumnPos(3));
+        assertEquals("4 key fix 5 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key fix 5 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ <1> [2] [3] [4]
+    public void testLayout4KeyFix5L1() {
+        MoreKeysKeyboardParams params = createParams(4, 5, XPOS_L1);
+        assertEquals("4 key fix 5 L1 columns", 4, params.mNumColumns);
+        assertEquals("4 key fix 5 L1 rows", 1, params.mNumRows);
+        assertEquals("4 key fix 5 L1 left", 0, params.mLeftKeys);
+        assertEquals("4 key fix 5 L1 right", 4, params.mRightKeys);
+        assertEquals("4 key fix 5 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("4 key fix 5 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("4 key fix 5 L1 [3]", 2, params.getColumnPos(2));
+        assertEquals("4 key fix 5 L1 [4]", 3, params.getColumnPos(3));
+        assertEquals("4 key fix 5 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key fix 5 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [1] <2> [3] [4]
+    public void testLayout4KeyFix5L2() {
+        MoreKeysKeyboardParams params = createParams(4, 5, XPOS_L2);
+        assertEquals("4 key fix 5 L2 columns", 4, params.mNumColumns);
+        assertEquals("4 key fix 5 L2 rows", 1, params.mNumRows);
+        assertEquals("4 key fix 5 L2 left", 1, params.mLeftKeys);
+        assertEquals("4 key fix 5 L2 right", 3, params.mRightKeys);
+        assertEquals("4 key fix 5 L2 [1]", -1, params.getColumnPos(0));
+        assertEquals("4 key fix 5 L2 <2>", 0, params.getColumnPos(1));
+        assertEquals("4 key fix 5 L2 [3]", 1, params.getColumnPos(2));
+        assertEquals("4 key fix 5 L2 [4]", 2, params.getColumnPos(3));
+        assertEquals("4 key fix 5 L2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key fix 5 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // [1] [2] [3] <4>|
+    public void testLayout4KeyFix5R0() {
+        MoreKeysKeyboardParams params = createParams(4, 5, XPOS_R0);
+        assertEquals("4 key fix 5 R0 columns", 4, params.mNumColumns);
+        assertEquals("4 key fix 5 R0 rows", 1, params.mNumRows);
+        assertEquals("4 key fix 5 R0 left", 3, params.mLeftKeys);
+        assertEquals("4 key fix 5 R0 right", 1, params.mRightKeys);
+        assertEquals("4 key fix 5 R0 [1]", -3, params.getColumnPos(0));
+        assertEquals("4 key fix 5 R0 [2]", -2, params.getColumnPos(1));
+        assertEquals("4 key fix 5 R0 [3]", -1, params.getColumnPos(2));
+        assertEquals("4 key fix 5 R0 <4>", 0, params.getColumnPos(3));
+        assertEquals("4 key fix 5 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key fix 5 R0 default", WIDTH * 3, params.getDefaultKeyCoordX());
+    }
+
+    // [1] [2] [3] <4> ___|
+    public void testLayout4KeyFix5R1() {
+        MoreKeysKeyboardParams params = createParams(4, 5, XPOS_R1);
+        assertEquals("4 key fix 5 R1 columns", 4, params.mNumColumns);
+        assertEquals("4 key fix 5 R1 rows", 1, params.mNumRows);
+        assertEquals("4 key fix 5 R1 left", 3, params.mLeftKeys);
+        assertEquals("4 key fix 5 R1 right", 1, params.mRightKeys);
+        assertEquals("4 key fix 5 R1 [1]", -3, params.getColumnPos(0));
+        assertEquals("4 key fix 5 R1 [2]", -2, params.getColumnPos(1));
+        assertEquals("4 key fix 5 R1 [3]", -1, params.getColumnPos(2));
+        assertEquals("4 key fix 5 R1 <4>", 0, params.getColumnPos(3));
+        assertEquals("4 key fix 5 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key fix 5 R1 default", WIDTH * 3, params.getDefaultKeyCoordX());
+    }
+
+    // [1] [2] <3> [4] ___|
+    public void testLayout4KeyFix5R2() {
+        MoreKeysKeyboardParams params = createParams(4, 5, XPOS_R2);
+        assertEquals("4 key fix 5 R2 columns", 4, params.mNumColumns);
+        assertEquals("4 key fix 5 R2 rows", 1, params.mNumRows);
+        assertEquals("4 key fix 5 R2 left", 2, params.mLeftKeys);
+        assertEquals("4 key fix 5 R2 right", 2, params.mRightKeys);
+        assertEquals("4 key fix 5 R2 [1]", -2, params.getColumnPos(0));
+        assertEquals("4 key fix 5 R2 [2]", -1, params.getColumnPos(1));
+        assertEquals("4 key fix 5 R2 <3>", 0, params.getColumnPos(2));
+        assertEquals("4 key fix 5 R2 [4]", 1, params.getColumnPos(3));
+        assertEquals("4 key fix 5 R2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key fix 5 R2 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    //     [5]
+    // [1] <2> [3] [4]
+    public void testLayout5KeyFix4M0() {
+        MoreKeysKeyboardParams params = createParams(5, 4, XPOS_M0);
+        assertEquals("5 key fix 4 M0 columns", 4, params.mNumColumns);
+        assertEquals("5 key fix 4 M0 rows", 2, params.mNumRows);
+        assertEquals("5 key fix 4 M0 left", 1, params.mLeftKeys);
+        assertEquals("5 key fix 4 M0 right", 3, params.mRightKeys);
+        assertEquals("5 key fix 4 M0 [1]", -1, params.getColumnPos(0));
+        assertEquals("5 key fix 4 M0 <2>", 0, params.getColumnPos(1));
+        assertEquals("5 key fix 4 M0 [3]", 1, params.getColumnPos(2));
+        assertEquals("5 key fix 4 M0 [4]", 2, params.getColumnPos(3));
+        assertEquals("5 key fix 4 M0 [5]", 0, params.getColumnPos(4));
+        assertEquals("5 key fix 4 M0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key fix 4 M0 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // |[5]
+    // |<1> [2] [3] [4]
+    public void testLayout5KeyFix4L0() {
+        MoreKeysKeyboardParams params = createParams(5, 4, XPOS_L0);
+        assertEquals("5 key fix 4 L0 columns", 4, params.mNumColumns);
+        assertEquals("5 key fix 4 L0 rows", 2, params.mNumRows);
+        assertEquals("5 key fix 4 L0 left", 0, params.mLeftKeys);
+        assertEquals("5 key fix 4 L0 right", 4, params.mRightKeys);
+        assertEquals("5 key fix 4 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("5 key fix 4 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("5 key fix 4 L0 [3]", 2, params.getColumnPos(2));
+        assertEquals("5 key fix 4 L0 [4]", 3, params.getColumnPos(3));
+        assertEquals("5 key fix 4 L0 [5]", 0, params.getColumnPos(4));
+        assertEquals("5 key fix 4 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key fix 4 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [5]
+    // |___ <1> [2] [3] [4]
+    public void testLayout5KeyFix4L1() {
+        MoreKeysKeyboardParams params = createParams(5, 4, XPOS_L1);
+        assertEquals("5 key fix 4 L1 columns", 4, params.mNumColumns);
+        assertEquals("5 key fix 4 L1 rows", 2, params.mNumRows);
+        assertEquals("5 key fix 4 L1 left", 0, params.mLeftKeys);
+        assertEquals("5 key fix 4 L1 right", 4, params.mRightKeys);
+        assertEquals("5 key fix 4 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("5 key fix 4 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("5 key fix 4 L1 [3]", 2, params.getColumnPos(2));
+        assertEquals("5 key fix 4 L1 [4]", 3, params.getColumnPos(3));
+        assertEquals("5 key fix 4 L1 [5]", 0, params.getColumnPos(4));
+        assertEquals("5 key fix 4 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key fix 4 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___     [5]
+    // |___ [1] <2> [3] [4]
+    public void testLayout5KeyFix4L2() {
+        MoreKeysKeyboardParams params = createParams(5, 4, XPOS_L2);
+        assertEquals("5 key fix 4 L2 columns", 4, params.mNumColumns);
+        assertEquals("5 key fix 4 L2 rows", 2, params.mNumRows);
+        assertEquals("5 key fix 4 L2 left", 1, params.mLeftKeys);
+        assertEquals("5 key fix 4 L2 right", 3, params.mRightKeys);
+        assertEquals("5 key fix 4 L2 [1]", -1, params.getColumnPos(0));
+        assertEquals("5 key fix 4 L2 <2>", 0, params.getColumnPos(1));
+        assertEquals("5 key fix 4 L2 [3]", 1, params.getColumnPos(2));
+        assertEquals("5 key fix 4 L2 [4]", 2, params.getColumnPos(3));
+        assertEquals("5 key fix 4 L2 [5]", 0, params.getColumnPos(4));
+        assertEquals("5 key fix 4 L2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key fix 4 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    //             [5]|
+    // [1] [2] [3] <4>|
+    public void testLayout5KeyFix4R0() {
+        MoreKeysKeyboardParams params = createParams(5, 4, XPOS_R0);
+        assertEquals("5 key fix 4 R0 columns", 4, params.mNumColumns);
+        assertEquals("5 key fix 4 R0 rows", 2, params.mNumRows);
+        assertEquals("5 key fix 4 R0 left", 3, params.mLeftKeys);
+        assertEquals("5 key fix 4 R0 right", 1, params.mRightKeys);
+        assertEquals("5 key fix 4 R0 [1]", -3, params.getColumnPos(0));
+        assertEquals("5 key fix 4 R0 [2]", -2, params.getColumnPos(1));
+        assertEquals("5 key fix 4 R0 [3]", -1, params.getColumnPos(2));
+        assertEquals("5 key fix 4 R0 <4>", 0, params.getColumnPos(3));
+        assertEquals("5 key fix 4 R0 [5]", 0, params.getColumnPos(4));
+        assertEquals("5 key fix 4 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key fix 4 R0 default", WIDTH * 3, params.getDefaultKeyCoordX());
+    }
+
+    //             [5] ___|
+    // [1] [2] [3] <4> ___|
+    public void testLayout5KeyFix4R1() {
+        MoreKeysKeyboardParams params = createParams(5, 4, XPOS_R1);
+        assertEquals("5 key fix 4 R1 columns", 4, params.mNumColumns);
+        assertEquals("5 key fix 4 R1 rows", 2, params.mNumRows);
+        assertEquals("5 key fix 4 R1 left", 3, params.mLeftKeys);
+        assertEquals("5 key fix 4 R1 right", 1, params.mRightKeys);
+        assertEquals("5 key fix 4 R1 [1]", -3, params.getColumnPos(0));
+        assertEquals("5 key fix 4 R1 [2]", -2, params.getColumnPos(1));
+        assertEquals("5 key fix 4 R1 [3]", -1, params.getColumnPos(2));
+        assertEquals("5 key fix 4 R1 [4]", 0, params.getColumnPos(3));
+        assertEquals("5 key fix 4 R1 [5]", 0, params.getColumnPos(4));
+        assertEquals("5 key fix 4 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key fix 4 R1 default", WIDTH * 3, params.getDefaultKeyCoordX());
+    }
+
+    //         [5]     ___|
+    // [1] [2] <3> [4] ___|
+    public void testLayout5KeyFix4R2() {
+        MoreKeysKeyboardParams params = createParams(5, 4, XPOS_R2);
+        assertEquals("5 key fix 4 R2 columns", 4, params.mNumColumns);
+        assertEquals("5 key fix 4 R2 rows", 2, params.mNumRows);
+        assertEquals("5 key fix 4 R2 left", 2, params.mLeftKeys);
+        assertEquals("5 key fix 4 R2 right", 2, params.mRightKeys);
+        assertEquals("5 key fix 4 R2 [1]", -2, params.getColumnPos(0));
+        assertEquals("5 key fix 4 R2 [2]", -1, params.getColumnPos(1));
+        assertEquals("5 key fix 4 R2 <3>", 0, params.getColumnPos(2));
+        assertEquals("5 key fix 4 R2 [4]", 1, params.getColumnPos(3));
+        assertEquals("5 key fix 4 R2 [5]", 0, params.getColumnPos(4));
+        assertEquals("5 key fix 4 R2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key fix 4 R2 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    //   [5] [6]
+    // [1] <2> [3] [4]
+    public void testLayout6KeyFix4M0() {
+        MoreKeysKeyboardParams params = createParams(6, 4, XPOS_M0);
+        assertEquals("6 key fix 4 M0 columns", 4, params.mNumColumns);
+        assertEquals("6 key fix 4 M0 rows", 2, params.mNumRows);
+        assertEquals("6 key fix 4 M0 left", 1, params.mLeftKeys);
+        assertEquals("6 key fix 4 M0 right", 3, params.mRightKeys);
+        assertEquals("6 key fix 4 M0 [1]", -1, params.getColumnPos(0));
+        assertEquals("6 key fix 4 M0 <2>", 0, params.getColumnPos(1));
+        assertEquals("6 key fix 4 M0 [3]", 1, params.getColumnPos(2));
+        assertEquals("6 key fix 4 M0 [4]", 2, params.getColumnPos(3));
+        assertEquals("6 key fix 4 M0 [5]", 0, params.getColumnPos(4));
+        assertEquals("6 key fix 4 M0 [6]", 1, params.getColumnPos(5));
+        assertEquals("6 key fix 4 M0 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("6 key fix 4 M0 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // |[5] [6]
+    // |<1> [2] [3] [4]
+    public void testLayout6KeyFix4L0() {
+        MoreKeysKeyboardParams params = createParams(6, 4, XPOS_L0);
+        assertEquals("6 key fix 4 L0 columns", 4, params.mNumColumns);
+        assertEquals("6 key fix 4 L0 rows", 2, params.mNumRows);
+        assertEquals("6 key fix 4 L0 left", 0, params.mLeftKeys);
+        assertEquals("6 key fix 4 L0 right", 4, params.mRightKeys);
+        assertEquals("6 key fix 4 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("6 key fix 4 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("6 key fix 4 L0 [3]", 2, params.getColumnPos(2));
+        assertEquals("6 key fix 4 L0 [4]", 3, params.getColumnPos(3));
+        assertEquals("6 key fix 4 L0 [5]", 0, params.getColumnPos(4));
+        assertEquals("6 key fix 4 L0 [6]", 1, params.getColumnPos(5));
+        assertEquals("6 key fix 4 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key fix 4 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [5] [6]
+    // |___ <1> [2] [3] [4]
+    public void testLayout6KeyFix4L1() {
+        MoreKeysKeyboardParams params = createParams(6, 4, XPOS_L1);
+        assertEquals("6 key fix 4 L1 columns", 4, params.mNumColumns);
+        assertEquals("6 key fix 4 L1 rows", 2, params.mNumRows);
+        assertEquals("6 key fix 4 L1 left", 0, params.mLeftKeys);
+        assertEquals("6 key fix 4 L1 right", 4, params.mRightKeys);
+        assertEquals("6 key fix 4 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("6 key fix 4 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("6 key fix 4 L1 [3]", 2, params.getColumnPos(2));
+        assertEquals("6 key fix 4 L1 [4]", 3, params.getColumnPos(3));
+        assertEquals("6 key fix 4 L1 [5]", 0, params.getColumnPos(4));
+        assertEquals("6 key fix 4 L1 [6]", 1, params.getColumnPos(5));
+        assertEquals("6 key fix 4 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key fix 4 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___   [5] [6]
+    // |___ [1] <2> [3] [4]
+    public void testLayout6KeyFix4L2() {
+        MoreKeysKeyboardParams params = createParams(6, 4, XPOS_L2);
+        assertEquals("6 key fix 4 L2 columns", 4, params.mNumColumns);
+        assertEquals("6 key fix 4 L2 rows", 2, params.mNumRows);
+        assertEquals("6 key fix 4 L2 left", 1, params.mLeftKeys);
+        assertEquals("6 key fix 4 L2 right", 3, params.mRightKeys);
+        assertEquals("6 key fix 4 L2 [1]", -1, params.getColumnPos(0));
+        assertEquals("6 key fix 4 L2 <2>", 0, params.getColumnPos(1));
+        assertEquals("6 key fix 4 L2 [3]", 1, params.getColumnPos(2));
+        assertEquals("6 key fix 4 L2 [4]", 2, params.getColumnPos(3));
+        assertEquals("6 key fix 4 L2 [5]", 0, params.getColumnPos(4));
+        assertEquals("6 key fix 4 L2 [6]", 1, params.getColumnPos(5));
+        assertEquals("6 key fix 4 L2 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("6 key fix 4 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    //         [5] [6]|
+    // [1] [2] [3] <4>|
+    public void testLayout6KeyFix4R0() {
+        MoreKeysKeyboardParams params = createParams(6, 4, XPOS_R0);
+        assertEquals("6 key fix 4 R0 columns", 4, params.mNumColumns);
+        assertEquals("6 key fix 4 R0 rows", 2, params.mNumRows);
+        assertEquals("6 key fix 4 R0 left", 3, params.mLeftKeys);
+        assertEquals("6 key fix 4 R0 right", 1, params.mRightKeys);
+        assertEquals("6 key fix 4 R0 [1]", -3, params.getColumnPos(0));
+        assertEquals("6 key fix 4 R0 [2]", -2, params.getColumnPos(1));
+        assertEquals("6 key fix 4 R0 [3]", -1, params.getColumnPos(2));
+        assertEquals("6 key fix 4 R0 <4>", 0, params.getColumnPos(3));
+        assertEquals("6 key fix 4 R0 [5]", -1, params.getColumnPos(4));
+        assertEquals("6 key fix 4 R0 [6]", 0, params.getColumnPos(5));
+        assertEquals("6 key fix 4 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key fix 4 R0 default", WIDTH * 3, params.getDefaultKeyCoordX());
+    }
+
+    //         [5] [6] ___|
+    // [1] [2] [3] <4> ___|
+    public void testLayout6KeyFix4R1() {
+        MoreKeysKeyboardParams params = createParams(6, 4, XPOS_R1);
+        assertEquals("6 key fix 4 R1 columns", 4, params.mNumColumns);
+        assertEquals("6 key fix 4 R1 rows", 2, params.mNumRows);
+        assertEquals("6 key fix 4 R1 left", 3, params.mLeftKeys);
+        assertEquals("6 key fix 4 R1 right", 1, params.mRightKeys);
+        assertEquals("6 key fix 4 R1 [1]", -3, params.getColumnPos(0));
+        assertEquals("6 key fix 4 R1 [2]", -2, params.getColumnPos(1));
+        assertEquals("6 key fix 4 R1 [3]", -1, params.getColumnPos(2));
+        assertEquals("6 key fix 4 R1 [4]", 0, params.getColumnPos(3));
+        assertEquals("6 key fix 4 R1 [5]", -1, params.getColumnPos(4));
+        assertEquals("6 key fix 4 R1 [6]", 0, params.getColumnPos(5));
+        assertEquals("6 key fix 4 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key fix 4 R1 default", WIDTH * 3, params.getDefaultKeyCoordX());
+    }
+
+    //       [5] [6]   ___|
+    // [1] [2] <3> [4] ___|
+    public void testLayout6KeyFix4R2() {
+        MoreKeysKeyboardParams params = createParams(6, 4, XPOS_R2);
+        assertEquals("6 key fix 4 R2 columns", 4, params.mNumColumns);
+        assertEquals("6 key fix 4 R2 rows", 2, params.mNumRows);
+        assertEquals("6 key fix 4 R2 left", 2, params.mLeftKeys);
+        assertEquals("6 key fix 4 R2 right", 2, params.mRightKeys);
+        assertEquals("6 key fix 4 R2 [1]", -2, params.getColumnPos(0));
+        assertEquals("6 key fix 4 R2 [2]", -1, params.getColumnPos(1));
+        assertEquals("6 key fix 4 R2 <3>", 0, params.getColumnPos(2));
+        assertEquals("6 key fix 4 R2 [4]", 1, params.getColumnPos(3));
+        assertEquals("6 key fix 4 R2 [5]", 0, params.getColumnPos(4));
+        assertEquals("6 key fix 4 R2 [6]", 1, params.getColumnPos(5));
+        assertEquals("6 key fix 4 R2 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("6 key fix 4 R2 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    // [5] [6] [7]
+    // [1] <2> [3] [4]
+    public void testLayout7KeyFix4M0() {
+        MoreKeysKeyboardParams params = createParams(7, 4, XPOS_M0);
+        assertEquals("7 key fix 4 M0 columns", 4, params.mNumColumns);
+        assertEquals("7 key fix 4 M0 rows", 2, params.mNumRows);
+        assertEquals("7 key fix 4 M0 left", 1, params.mLeftKeys);
+        assertEquals("7 key fix 4 M0 right", 3, params.mRightKeys);
+        assertEquals("7 key fix 4 M0 [1]", -1, params.getColumnPos(0));
+        assertEquals("7 key fix 4 M0 <2>", 0, params.getColumnPos(1));
+        assertEquals("7 key fix 4 M0 [3]", 1, params.getColumnPos(2));
+        assertEquals("7 key fix 4 M0 [4]", 2, params.getColumnPos(3));
+        assertEquals("7 key fix 4 M0 [5]", -1, params.getColumnPos(4));
+        assertEquals("7 key fix 4 M0 [6]", 0, params.getColumnPos(5));
+        assertEquals("7 key fix 4 M0 [7]", 1, params.getColumnPos(6));
+        assertEquals("7 key fix 4 M0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key fix 4 M0 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // |[5] [6] [7]
+    // |<1> [2] [3] [4]
+    public void testLayout7KeyFix4L0() {
+        MoreKeysKeyboardParams params = createParams(7, 4, XPOS_L0);
+        assertEquals("7 key fix 4 L0 columns", 4, params.mNumColumns);
+        assertEquals("7 key fix 4 L0 rows", 2, params.mNumRows);
+        assertEquals("7 key fix 4 L0 left", 0, params.mLeftKeys);
+        assertEquals("7 key fix 4 L0 right", 4, params.mRightKeys);
+        assertEquals("7 key fix 4 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("7 key fix 4 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("7 key fix 4 L0 [3]", 2, params.getColumnPos(2));
+        assertEquals("7 key fix 4 L0 [4]", 3, params.getColumnPos(3));
+        assertEquals("7 key fix 4 L0 [5]", 0, params.getColumnPos(4));
+        assertEquals("7 key fix 4 L0 [6]", 1, params.getColumnPos(5));
+        assertEquals("7 key fix 4 L0 [7]", 2, params.getColumnPos(6));
+        assertEquals("7 key fix 4 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key fix 4 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [5] [6] [7]
+    // |___ <1> [2] [3] [4]
+    public void testLayout7KeyFix4L1() {
+        MoreKeysKeyboardParams params = createParams(7, 4, XPOS_L1);
+        assertEquals("7 key fix 4 L1 columns", 4, params.mNumColumns);
+        assertEquals("7 key fix 4 L1 rows", 2, params.mNumRows);
+        assertEquals("7 key fix 4 L1 left", 0, params.mLeftKeys);
+        assertEquals("7 key fix 4 L1 right", 4, params.mRightKeys);
+        assertEquals("7 key fix 4 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("7 key fix 4 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("7 key fix 4 L1 [3]", 2, params.getColumnPos(2));
+        assertEquals("7 key fix 4 L1 [4]", 3, params.getColumnPos(3));
+        assertEquals("7 key fix 4 L1 [5]", 0, params.getColumnPos(4));
+        assertEquals("7 key fix 4 L1 [6]", 1, params.getColumnPos(5));
+        assertEquals("7 key fix 4 l1 [7]", 2, params.getColumnPos(6));
+        assertEquals("7 key fix 4 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key fix 4 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [5] [6] [7]
+    // |___ [1] <2> [3] [4]
+    public void testLayout7KeyFix4L2() {
+        MoreKeysKeyboardParams params = createParams(7, 4, XPOS_L2);
+        assertEquals("7 key fix 4 L2 columns", 4, params.mNumColumns);
+        assertEquals("7 key fix 4 L2 rows", 2, params.mNumRows);
+        assertEquals("7 key fix 4 L2 left", 1, params.mLeftKeys);
+        assertEquals("7 key fix 4 L2 right", 3, params.mRightKeys);
+        assertEquals("7 key fix 4 L2 [1]", -1, params.getColumnPos(0));
+        assertEquals("7 key fix 4 L2 <2>", 0, params.getColumnPos(1));
+        assertEquals("7 key fix 4 L2 [3]", 1, params.getColumnPos(2));
+        assertEquals("7 key fix 4 L2 [4]", 2, params.getColumnPos(3));
+        assertEquals("7 key fix 4 L2 [5]", -1, params.getColumnPos(4));
+        assertEquals("7 key fix 4 L2 [6]", 0, params.getColumnPos(5));
+        assertEquals("7 key fix 4 L2 [7]", 1, params.getColumnPos(6));
+        assertEquals("7 key fix 4 L2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key fix 4 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    //     [5] [6] [7]|
+    // [1] [2] [3] <4>|
+    public void testLayout7KeyFix4R0() {
+        MoreKeysKeyboardParams params = createParams(7, 4, XPOS_R0);
+        assertEquals("7 key fix 4 R0 columns", 4, params.mNumColumns);
+        assertEquals("7 key fix 4 R0 rows", 2, params.mNumRows);
+        assertEquals("7 key fix 4 R0 left", 3, params.mLeftKeys);
+        assertEquals("7 key fix 4 R0 right", 1, params.mRightKeys);
+        assertEquals("7 key fix 4 R0 [1]", -3, params.getColumnPos(0));
+        assertEquals("7 key fix 4 R0 [2]", -2, params.getColumnPos(1));
+        assertEquals("7 key fix 4 R0 [3]", -1, params.getColumnPos(2));
+        assertEquals("7 key fix 4 R0 <4>", 0, params.getColumnPos(3));
+        assertEquals("7 key fix 4 R0 [5]", -2, params.getColumnPos(4));
+        assertEquals("7 key fix 4 R0 [6]", -1, params.getColumnPos(5));
+        assertEquals("7 key fix 4 R0 [7]", 0, params.getColumnPos(6));
+        assertEquals("7 key fix 4 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key fix 4 R0 default", WIDTH * 3, params.getDefaultKeyCoordX());
+    }
+
+    //     [5] [6] [7] ___|
+    // [1] [2] [3] <4> ___|
+    public void testLayout7KeyFix4R1() {
+        MoreKeysKeyboardParams params = createParams(7, 4, XPOS_R1);
+        assertEquals("7 key fix 4 R1 columns", 4, params.mNumColumns);
+        assertEquals("7 key fix 4 R1 rows", 2, params.mNumRows);
+        assertEquals("7 key fix 4 R1 left", 3, params.mLeftKeys);
+        assertEquals("7 key fix 4 R1 right", 1, params.mRightKeys);
+        assertEquals("7 key fix 4 R1 [1]", -3, params.getColumnPos(0));
+        assertEquals("7 key fix 4 R1 [2]", -2, params.getColumnPos(1));
+        assertEquals("7 key fix 4 R1 [3]", -1, params.getColumnPos(2));
+        assertEquals("7 key fix 4 R1 <4>", 0, params.getColumnPos(3));
+        assertEquals("7 key fix 4 R1 [5]", -2, params.getColumnPos(4));
+        assertEquals("7 key fix 4 R1 [6]", -1, params.getColumnPos(5));
+        assertEquals("7 key fix 4 R1 [7]", 0, params.getColumnPos(6));
+        assertEquals("7 key fix 4 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key fix 4 R1 default", WIDTH * 3, params.getDefaultKeyCoordX());
+    }
+
+    //     [5] [6] [7] ___|
+    // [1] [2] <3> [4] ___|
+    public void testLayout7KeyFix4R2() {
+        MoreKeysKeyboardParams params = createParams(7, 4, XPOS_R2);
+        assertEquals("7 key fix 4 R2 columns", 4, params.mNumColumns);
+        assertEquals("7 key fix 4 R2 rows", 2, params.mNumRows);
+        assertEquals("7 key fix 4 R2 left", 2, params.mLeftKeys);
+        assertEquals("7 key fix 4 R2 right", 2, params.mRightKeys);
+        assertEquals("7 key fix 4 R2 [1]", -2, params.getColumnPos(0));
+        assertEquals("7 key fix 4 R2 [2]", -1, params.getColumnPos(1));
+        assertEquals("7 key fix 4 R2 <3>", 0, params.getColumnPos(2));
+        assertEquals("7 key fix 4 R2 [4]", 1, params.getColumnPos(3));
+        assertEquals("7 key fix 4 R2 [5]", -1, params.getColumnPos(4));
+        assertEquals("7 key fix 4 R2 [6]", 0, params.getColumnPos(5));
+        assertEquals("7 key fix 4 R2 [7]", 1, params.getColumnPos(6));
+        assertEquals("7 key fix 4 R2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key fix 4 R2 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    // [5] [6] [7] [8]
+    // [1] <2> [3] [4]
+    public void testLayout8KeyFix4M0() {
+        MoreKeysKeyboardParams params = createParams(8, 4, XPOS_M0);
+        assertEquals("8 key fix 4 M0 columns", 4, params.mNumColumns);
+        assertEquals("8 key fix 4 M0 rows", 2, params.mNumRows);
+        assertEquals("8 key fix 4 M0 left", 1, params.mLeftKeys);
+        assertEquals("8 key fix 4 M0 right", 3, params.mRightKeys);
+        assertEquals("8 key fix 4 M0 [1]", -1, params.getColumnPos(0));
+        assertEquals("8 key fix 4 M0 <2>", 0, params.getColumnPos(1));
+        assertEquals("8 key fix 4 M0 [3]", 1, params.getColumnPos(2));
+        assertEquals("8 key fix 4 M0 [4]", 2, params.getColumnPos(3));
+        assertEquals("8 key fix 4 M0 [5]", -1, params.getColumnPos(4));
+        assertEquals("8 key fix 4 M0 [6]", 0, params.getColumnPos(5));
+        assertEquals("8 key fix 4 M0 [7]", 1, params.getColumnPos(6));
+        assertEquals("8 key fix 4 M0 [8]", 2, params.getColumnPos(7));
+        assertEquals("8 key fix 4 M0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("8 key fix 4 M0 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // |[5] [6] [7] [8]
+    // |<1> [2] [3] [4]
+    public void testLayout8KeyFix4L0() {
+        MoreKeysKeyboardParams params = createParams(8, 4, XPOS_L0);
+        assertEquals("8 key fix 4 L0 columns", 4, params.mNumColumns);
+        assertEquals("8 key fix 4 L0 rows", 2, params.mNumRows);
+        assertEquals("8 key fix 4 L0 left", 0, params.mLeftKeys);
+        assertEquals("8 key fix 4 L0 right", 4, params.mRightKeys);
+        assertEquals("8 key fix 4 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("8 key fix 4 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("8 key fix 4 L0 [3]", 2, params.getColumnPos(2));
+        assertEquals("8 key fix 4 L0 [4]", 3, params.getColumnPos(3));
+        assertEquals("8 key fix 4 L0 [5]", 0, params.getColumnPos(4));
+        assertEquals("8 key fix 4 L0 [6]", 1, params.getColumnPos(5));
+        assertEquals("8 key fix 4 L0 [7]", 2, params.getColumnPos(6));
+        assertEquals("8 key fix 4 L0 [8]", 3, params.getColumnPos(7));
+        assertEquals("8 key fix 4 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("8 key fix 4 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [5] [6] [7] [8]
+    // |___ <1> [2] [3] [4]
+    public void testLayout8KeyFix4L1() {
+        MoreKeysKeyboardParams params = createParams(8, 4, XPOS_L1);
+        assertEquals("8 key fix 4 L1 columns", 4, params.mNumColumns);
+        assertEquals("8 key fix 4 L1 rows", 2, params.mNumRows);
+        assertEquals("8 key fix 4 L1 left", 0, params.mLeftKeys);
+        assertEquals("8 key fix 4 L1 right", 4, params.mRightKeys);
+        assertEquals("8 key fix 4 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("8 key fix 4 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("8 key fix 4 L1 [3]", 2, params.getColumnPos(2));
+        assertEquals("8 key fix 4 L1 [4]", 3, params.getColumnPos(3));
+        assertEquals("8 key fix 4 L1 [5]", 0, params.getColumnPos(4));
+        assertEquals("8 key fix 4 L1 [6]", 1, params.getColumnPos(5));
+        assertEquals("8 key fix 4 L1 [7]", 2, params.getColumnPos(6));
+        assertEquals("8 key fix 4 L1 [8]", 3, params.getColumnPos(7));
+        assertEquals("8 key fix 4 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("8 key fix 4 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [5] [6] [7] [8]
+    // |___ [1] <2> [3] [4]
+    public void testLayout8KeyFix4L2() {
+        MoreKeysKeyboardParams params = createParams(8, 4, XPOS_L2);
+        assertEquals("8 key fix 4 L2 columns", 4, params.mNumColumns);
+        assertEquals("8 key fix 4 L2 rows", 2, params.mNumRows);
+        assertEquals("8 key fix 4 L2 left", 1, params.mLeftKeys);
+        assertEquals("8 key fix 4 L2 right", 3, params.mRightKeys);
+        assertEquals("8 key fix 4 L2 [1]", -1, params.getColumnPos(0));
+        assertEquals("8 key fix 4 L2 <2>", 0, params.getColumnPos(1));
+        assertEquals("8 key fix 4 L2 [3]", 1, params.getColumnPos(2));
+        assertEquals("8 key fix 4 L2 [4]", 2, params.getColumnPos(3));
+        assertEquals("8 key fix 4 L2 [5]", -1, params.getColumnPos(4));
+        assertEquals("8 key fix 4 L2 [6]", 0, params.getColumnPos(5));
+        assertEquals("8 key fix 4 L2 [7]", 1, params.getColumnPos(6));
+        assertEquals("8 key fix 4 L2 [8]", 2, params.getColumnPos(7));
+        assertEquals("8 key fix 4 L2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("8 key fix 4 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // [5] [6] [7] [8]|
+    // [1] [2] [3] <4>|
+    public void testLayout8KeyFix4R0() {
+        MoreKeysKeyboardParams params = createParams(8, 4, XPOS_R0);
+        assertEquals("8 key fix 4 R0 columns", 4, params.mNumColumns);
+        assertEquals("8 key fix 4 R0 rows", 2, params.mNumRows);
+        assertEquals("8 key fix 4 R0 left", 3, params.mLeftKeys);
+        assertEquals("8 key fix 4 R0 right", 1, params.mRightKeys);
+        assertEquals("8 key fix 4 R0 [1]", -3, params.getColumnPos(0));
+        assertEquals("8 key fix 4 R0 [2]", -2, params.getColumnPos(1));
+        assertEquals("8 key fix 4 R0 [3]", -1, params.getColumnPos(2));
+        assertEquals("8 key fix 4 R0 <4>", 0, params.getColumnPos(3));
+        assertEquals("8 key fix 4 R0 [5]", -3, params.getColumnPos(4));
+        assertEquals("8 key fix 4 R0 [6]", -2, params.getColumnPos(5));
+        assertEquals("8 key fix 4 R0 [7]", -1, params.getColumnPos(6));
+        assertEquals("8 key fix 4 R0 [8]", 0, params.getColumnPos(7));
+        assertEquals("8 key fix 4 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("8 key fix 4 R0 default", WIDTH * 3, params.getDefaultKeyCoordX());
+    }
+
+    // [5] [6] [7] [8] ___|
+    // [1] [2] [3] <4> ___|
+    public void testLayout8KeyFix4R1() {
+        MoreKeysKeyboardParams params = createParams(8, 4, XPOS_R1);
+        assertEquals("8 key fix 4 R1 columns", 4, params.mNumColumns);
+        assertEquals("8 key fix 4 R1 rows", 2, params.mNumRows);
+        assertEquals("8 key fix 4 R1 left", 3, params.mLeftKeys);
+        assertEquals("8 key fix 4 R1 right", 1, params.mRightKeys);
+        assertEquals("8 key fix 4 R1 [1]", -3, params.getColumnPos(0));
+        assertEquals("8 key fix 4 R1 [2]", -2, params.getColumnPos(1));
+        assertEquals("8 key fix 4 R1 [3]", -1, params.getColumnPos(2));
+        assertEquals("8 key fix 4 R1 <4>", 0, params.getColumnPos(3));
+        assertEquals("8 key fix 4 R1 [5]", -3, params.getColumnPos(4));
+        assertEquals("8 key fix 4 R1 [6]", -2, params.getColumnPos(5));
+        assertEquals("8 key fix 4 R1 [7]", -1, params.getColumnPos(6));
+        assertEquals("8 key fix 4 R1 [8]", 0, params.getColumnPos(7));
+        assertEquals("8 key fix 4 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("8 key fix 4 R1 default", WIDTH * 3, params.getDefaultKeyCoordX());
+    }
+
+    // [5] [6] [7] [8] ___|
+    // [1] [2] <3> [4] ___|
+    public void testLayout8KeyFix4R2() {
+        MoreKeysKeyboardParams params = createParams(8, 4, XPOS_R2);
+        assertEquals("8 key fix 4 R2 columns", 4, params.mNumColumns);
+        assertEquals("8 key fix 4 R2 rows", 2, params.mNumRows);
+        assertEquals("8 key fix 4 R2 left", 2, params.mLeftKeys);
+        assertEquals("8 key fix 4 R2 right", 2, params.mRightKeys);
+        assertEquals("8 key fix 4 R2 [1]", -2, params.getColumnPos(0));
+        assertEquals("8 key fix 4 R2 [2]", -1, params.getColumnPos(1));
+        assertEquals("8 key fix 4 R2 <3>", 0, params.getColumnPos(2));
+        assertEquals("8 key fix 4 R2 [4]", 1, params.getColumnPos(3));
+        assertEquals("8 key fix 4 R2 [5]", -2, params.getColumnPos(4));
+        assertEquals("8 key fix 4 R2 [6]", -1, params.getColumnPos(5));
+        assertEquals("8 key fix 4 R2 [7]", 0, params.getColumnPos(6));
+        assertEquals("8 key fix 4 R2 [8]", 1, params.getColumnPos(7));
+        assertEquals("8 key fix 4 R2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("8 key fix 4 R2 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+     // [1] [2] <3> [4] [5]
+    public void testLayout5KeyFix5M0() {
+        MoreKeysKeyboardParams params = createParams(5, 5, XPOS_M0);
+        assertEquals("5 key fix 5 columns", 5, params.mNumColumns);
+        assertEquals("5 key fix 5 rows", 1, params.mNumRows);
+        assertEquals("5 key fix 5 left", 2, params.mLeftKeys);
+        assertEquals("5 key fix 5 right", 3, params.mRightKeys);
+        assertEquals("5 key fix 5 [1]", -2, params.getColumnPos(0));
+        assertEquals("5 key fix 5 [2]", -1, params.getColumnPos(1));
+        assertEquals("5 key fix 5 <3>", 0, params.getColumnPos(2));
+        assertEquals("5 key fix 5 [4]", 1, params.getColumnPos(3));
+        assertEquals("5 key fix 5 [5]", 2, params.getColumnPos(4));
+        assertEquals("5 key fix 5 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key fix 5 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    // |<1> [2] [3] [4] [5]
+    public void testLayout5KeyFix5L0() {
+        MoreKeysKeyboardParams params = createParams(5, 5, XPOS_L0);
+        assertEquals("5 key fix 5 L0 columns", 5, params.mNumColumns);
+        assertEquals("5 key fix 5 L0 rows", 1, params.mNumRows);
+        assertEquals("5 key fix 5 L0 left", 0, params.mLeftKeys);
+        assertEquals("5 key fix 5 L0 right", 5, params.mRightKeys);
+        assertEquals("5 key fix 5 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("5 key fix 5 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("5 key fix 5 L0 [3]", 2, params.getColumnPos(2));
+        assertEquals("5 key fix 5 L0 [4]", 3, params.getColumnPos(3));
+        assertEquals("5 key fix 5 L0 [5]", 4, params.getColumnPos(4));
+        assertEquals("5 key fix 5 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key fix 5 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ <1> [2] [3] [4] [5]
+    public void testLayout5KeyFix5L1() {
+        MoreKeysKeyboardParams params = createParams(5, 5, XPOS_L1);
+        assertEquals("5 key fix 5 L1 columns", 5, params.mNumColumns);
+        assertEquals("5 key fix 5 L1 rows", 1, params.mNumRows);
+        assertEquals("5 key fix 5 L1 left", 0, params.mLeftKeys);
+        assertEquals("5 key fix 5 L1 right", 5, params.mRightKeys);
+        assertEquals("5 key fix 5 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("5 key fix 5 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("5 key fix 5 L1 [3]", 2, params.getColumnPos(2));
+        assertEquals("5 key fix 5 L1 [4]", 3, params.getColumnPos(3));
+        assertEquals("5 key fix 5 L1 [5]", 4, params.getColumnPos(4));
+        assertEquals("5 key fix 5 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key fix 5 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [1] <2> [3] [4] [5]
+    public void testLayout5KeyFix5L2() {
+        MoreKeysKeyboardParams params = createParams(5, 5, XPOS_L2);
+        assertEquals("5 key fix 5 L2 columns", 5, params.mNumColumns);
+        assertEquals("5 key fix 5 L2 rows", 1, params.mNumRows);
+        assertEquals("5 key fix 5 L2 left", 1, params.mLeftKeys);
+        assertEquals("5 key fix 5 L2 right", 4, params.mRightKeys);
+        assertEquals("5 key fix 5 L2 [1]", -1, params.getColumnPos(0));
+        assertEquals("5 key fix 5 L2 <2>", 0, params.getColumnPos(1));
+        assertEquals("5 key fix 5 L2 [3]", 1, params.getColumnPos(2));
+        assertEquals("5 key fix 5 L2 [4]", 2, params.getColumnPos(3));
+        assertEquals("5 key fix 5 L2 [5]", 3, params.getColumnPos(4));
+        assertEquals("5 key fix 5 L2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key fix 5 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // [1] [2] [3] [4] <5>|
+    public void testLayout5KeyFix5R0() {
+        MoreKeysKeyboardParams params = createParams(5, 5, XPOS_R0);
+        assertEquals("5 key fix 5 R0 columns", 5, params.mNumColumns);
+        assertEquals("5 key fix 5 R0 rows", 1, params.mNumRows);
+        assertEquals("5 key fix 5 R0 left", 4, params.mLeftKeys);
+        assertEquals("5 key fix 5 R0 right", 1, params.mRightKeys);
+        assertEquals("5 key fix 5 R0 [1]", -4, params.getColumnPos(0));
+        assertEquals("5 key fix 5 R0 [2]", -3, params.getColumnPos(1));
+        assertEquals("5 key fix 5 R0 [3]", -2, params.getColumnPos(2));
+        assertEquals("5 key fix 5 R0 [4]", -1, params.getColumnPos(3));
+        assertEquals("5 key fix 5 R0 <5>", 0, params.getColumnPos(4));
+        assertEquals("5 key fix 5 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key fix 5 R0 default", WIDTH * 4, params.getDefaultKeyCoordX());
+    }
+
+    // [1] [2] [3] [4] <5> ___|
+    public void testLayout5KeyFix5R1() {
+        MoreKeysKeyboardParams params = createParams(5, 5, XPOS_R1);
+        assertEquals("5 key fix 5 R1 columns", 5, params.mNumColumns);
+        assertEquals("5 key fix 5 R1 rows", 1, params.mNumRows);
+        assertEquals("5 key fix 5 R1 left", 4, params.mLeftKeys);
+        assertEquals("5 key fix 5 R1 right", 1, params.mRightKeys);
+        assertEquals("5 key fix 5 R1 [1]", -4, params.getColumnPos(0));
+        assertEquals("5 key fix 5 R1 [2]", -3, params.getColumnPos(1));
+        assertEquals("5 key fix 5 R1 [3]", -2, params.getColumnPos(2));
+        assertEquals("5 key fix 5 R1 [4]", -1, params.getColumnPos(3));
+        assertEquals("5 key fix 5 R1 <5>", 0, params.getColumnPos(4));
+        assertEquals("5 key fix 5 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key fix 5 R1 default", WIDTH * 4, params.getDefaultKeyCoordX());
+    }
+
+    // [1] [2] [3] <4> [5] ___|
+    public void testLayout5KeyFix5R2() {
+        MoreKeysKeyboardParams params = createParams(5, 5, XPOS_R2);
+        assertEquals("5 key fix 5 R2 columns", 5, params.mNumColumns);
+        assertEquals("5 key fix 5 R2 rows", 1, params.mNumRows);
+        assertEquals("5 key fix 5 R2 left", 3, params.mLeftKeys);
+        assertEquals("5 key fix 5 R2 right", 2, params.mRightKeys);
+        assertEquals("5 key fix 5 R2 [1]", -3, params.getColumnPos(0));
+        assertEquals("5 key fix 5 R2 [2]", -2, params.getColumnPos(1));
+        assertEquals("5 key fix 5 R2 [3]", -1, params.getColumnPos(2));
+        assertEquals("5 key fix 5 R2 <4>", 0, params.getColumnPos(3));
+        assertEquals("5 key fix 5 R2 [5]", 1, params.getColumnPos(4));
+        assertEquals("5 key fix 5 R2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key fix 5 R2 default", WIDTH * 3, params.getDefaultKeyCoordX());
+    }
+
+    //         [6]
+    // [1] [2] <3> [4] [5]
+    public void testLayout6KeyFix5M0() {
+        MoreKeysKeyboardParams params = createParams(6, 5, XPOS_M0);
+        assertEquals("6 key fix 5 columns", 5, params.mNumColumns);
+        assertEquals("6 key fix 5 rows", 2, params.mNumRows);
+        assertEquals("6 key fix 5 left", 2, params.mLeftKeys);
+        assertEquals("6 key fix 5 right", 3, params.mRightKeys);
+        assertEquals("6 key fix 5 [1]", -2, params.getColumnPos(0));
+        assertEquals("6 key fix 5 [2]", -1, params.getColumnPos(1));
+        assertEquals("6 key fix 5 <3>", 0, params.getColumnPos(2));
+        assertEquals("6 key fix 5 [4]", 1, params.getColumnPos(3));
+        assertEquals("6 key fix 5 [5]", 2, params.getColumnPos(4));
+        assertEquals("6 key fix 5 [6]", 0, params.getColumnPos(5));
+        assertEquals("6 key fix 5 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key fix 5 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    // |[6]
+    // |<1> [2] [3] [4] [5]
+    public void testLayout6KeyFix5L0() {
+        MoreKeysKeyboardParams params = createParams(6, 5, XPOS_L0);
+        assertEquals("6 key fix 5 L0 columns", 5, params.mNumColumns);
+        assertEquals("6 key fix 5 L0 rows", 2, params.mNumRows);
+        assertEquals("6 key fix 5 L0 left", 0, params.mLeftKeys);
+        assertEquals("6 key fix 5 L0 right", 5, params.mRightKeys);
+        assertEquals("6 key fix 5 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("6 key fix 5 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("6 key fix 5 L0 [3]", 2, params.getColumnPos(2));
+        assertEquals("6 key fix 5 L0 [4]", 3, params.getColumnPos(3));
+        assertEquals("6 key fix 5 L0 [5]", 4, params.getColumnPos(4));
+        assertEquals("6 key fix 5 L0 [6]", 0, params.getColumnPos(5));
+        assertEquals("6 key fix 5 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key fix 5 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [6]
+    // |___ <1> [2] [3] [4] [5]
+    public void testLayout6KeyFix5L1() {
+        MoreKeysKeyboardParams params = createParams(6, 5, XPOS_L1);
+        assertEquals("6 key fix 5 L1 columns", 5, params.mNumColumns);
+        assertEquals("6 key fix 5 L1 rows", 2, params.mNumRows);
+        assertEquals("6 key fix 5 L1 left", 0, params.mLeftKeys);
+        assertEquals("6 key fix 5 L1 right", 5, params.mRightKeys);
+        assertEquals("6 key fix 5 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("6 key fix 5 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("6 key fix 5 L1 [3]", 2, params.getColumnPos(2));
+        assertEquals("6 key fix 5 L1 [4]", 3, params.getColumnPos(3));
+        assertEquals("6 key fix 5 L1 [5]", 4, params.getColumnPos(4));
+        assertEquals("6 key fix 5 L1 [6]", 0, params.getColumnPos(5));
+        assertEquals("6 key fix 5 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key fix 5 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___     [6]
+    // |___ [1] <2> [3] [4] [5]
+    public void testLayout6KeyFix5L2() {
+        MoreKeysKeyboardParams params = createParams(6, 5, XPOS_L2);
+        assertEquals("6 key fix 5 L2 columns", 5, params.mNumColumns);
+        assertEquals("6 key fix 5 L2 rows", 2, params.mNumRows);
+        assertEquals("6 key fix 5 L2 left", 1, params.mLeftKeys);
+        assertEquals("6 key fix 5 L2 right", 4, params.mRightKeys);
+        assertEquals("6 key fix 5 L2 [1]", -1, params.getColumnPos(0));
+        assertEquals("6 key fix 5 L2 <2>", 0, params.getColumnPos(1));
+        assertEquals("6 key fix 5 L2 [3]", 1, params.getColumnPos(2));
+        assertEquals("6 key fix 5 L2 [4]", 2, params.getColumnPos(3));
+        assertEquals("6 key fix 5 L2 [5]", 3, params.getColumnPos(4));
+        assertEquals("6 key fix 5 L2 [6]", 0, params.getColumnPos(5));
+        assertEquals("6 key fix 5 L2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key fix 5 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    //                 [6]|
+    // [1] [2] [3] [4] <5>|
+    public void testLayout6KeyFix5R0() {
+        MoreKeysKeyboardParams params = createParams(6, 5, XPOS_R0);
+        assertEquals("6 key fix 5 R0 columns", 5, params.mNumColumns);
+        assertEquals("6 key fix 5 R0 rows", 2, params.mNumRows);
+        assertEquals("6 key fix 5 R0 left", 4, params.mLeftKeys);
+        assertEquals("6 key fix 5 R0 right", 1, params.mRightKeys);
+        assertEquals("6 key fix 5 R0 [1]", -4, params.getColumnPos(0));
+        assertEquals("6 key fix 5 R0 [2]", -3, params.getColumnPos(1));
+        assertEquals("6 key fix 5 R0 [3]", -2, params.getColumnPos(2));
+        assertEquals("6 key fix 5 R0 [4]", -1, params.getColumnPos(3));
+        assertEquals("6 key fix 5 R0 <5>", 0, params.getColumnPos(4));
+        assertEquals("6 key fix 5 R0 [6]", 0, params.getColumnPos(5));
+        assertEquals("6 key fix 5 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key fix 5 R0 default", WIDTH * 4, params.getDefaultKeyCoordX());
+    }
+
+    //                 [6] ___|
+    // [1] [2] [3] [4] <5> ___|
+    public void testLayout6KeyFix5R1() {
+        MoreKeysKeyboardParams params = createParams(6, 5, XPOS_R1);
+        assertEquals("6 key fix 5 R1 columns", 5, params.mNumColumns);
+        assertEquals("6 key fix 5 R1 rows", 2, params.mNumRows);
+        assertEquals("6 key fix 5 R1 left", 4, params.mLeftKeys);
+        assertEquals("6 key fix 5 R1 right", 1, params.mRightKeys);
+        assertEquals("6 key fix 5 R1 [1]", -4, params.getColumnPos(0));
+        assertEquals("6 key fix 5 R1 [2]", -3, params.getColumnPos(1));
+        assertEquals("6 key fix 5 R1 [3]", -2, params.getColumnPos(2));
+        assertEquals("6 key fix 5 R1 [4]", -1, params.getColumnPos(3));
+        assertEquals("6 key fix 5 R1 <5>", 0, params.getColumnPos(4));
+        assertEquals("6 key fix 5 R1 [6]", 0, params.getColumnPos(5));
+        assertEquals("6 key fix 5 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key fix 5 R1 default", WIDTH * 4, params.getDefaultKeyCoordX());
+    }
+
+    //             [6]     ___|
+    // [1] [2] [3] <4> [5] ___|
+    public void testLayout6KeyFix5R2() {
+        MoreKeysKeyboardParams params = createParams(6, 5, XPOS_R2);
+        assertEquals("6 key fix 5 R2 columns", 5, params.mNumColumns);
+        assertEquals("6 key fix 5 R2 rows", 2, params.mNumRows);
+        assertEquals("6 key fix 5 R2 left", 3, params.mLeftKeys);
+        assertEquals("6 key fix 5 R2 right", 2, params.mRightKeys);
+        assertEquals("6 key fix 5 R2 [1]", -3, params.getColumnPos(0));
+        assertEquals("6 key fix 5 R2 [2]", -2, params.getColumnPos(1));
+        assertEquals("6 key fix 5 R2 [3]", -1, params.getColumnPos(2));
+        assertEquals("6 key fix 5 R2 <4>", 0, params.getColumnPos(3));
+        assertEquals("6 key fix 5 R2 [5]", 1, params.getColumnPos(4));
+        assertEquals("6 key fix 5 R2 [6]", 0, params.getColumnPos(5));
+        assertEquals("6 key fix 5 R2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key fix 5 R2 default", WIDTH * 3, params.getDefaultKeyCoordX());
+    }
+
+    //       [6] [7]
+    // [1] [2] <3> [4] [5]
+    public void testLayout7KeyFix5M0() {
+        MoreKeysKeyboardParams params = createParams(7, 5, XPOS_M0);
+        assertEquals("7 key fix 5 columns", 5, params.mNumColumns);
+        assertEquals("7 key fix 5 rows", 2, params.mNumRows);
+        assertEquals("7 key fix 5 left", 2, params.mLeftKeys);
+        assertEquals("7 key fix 5 right", 3, params.mRightKeys);
+        assertEquals("7 key fix 5 [1]", -2, params.getColumnPos(0));
+        assertEquals("7 key fix 5 [2]", -1, params.getColumnPos(1));
+        assertEquals("7 key fix 5 <3>", 0, params.getColumnPos(2));
+        assertEquals("7 key fix 5 [4]", 1, params.getColumnPos(3));
+        assertEquals("7 key fix 5 [5]", 2, params.getColumnPos(4));
+        assertEquals("7 key fix 5 [6]", 0, params.getColumnPos(5));
+        assertEquals("7 key fix 5 [7]", 1, params.getColumnPos(6));
+        assertEquals("7 key fix 5 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("7 key fix 5 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    // |[6] [7]
+    // |<1> [2] [3] [4] [5]
+    public void testLayout7KeyFix5L0() {
+        MoreKeysKeyboardParams params = createParams(7, 5, XPOS_L0);
+        assertEquals("7 key fix 5 L0 columns", 5, params.mNumColumns);
+        assertEquals("7 key fix 5 L0 rows", 2, params.mNumRows);
+        assertEquals("7 key fix 5 L0 left", 0, params.mLeftKeys);
+        assertEquals("7 key fix 5 L0 right", 5, params.mRightKeys);
+        assertEquals("7 key fix 5 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("7 key fix 5 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("7 key fix 5 L0 [3]", 2, params.getColumnPos(2));
+        assertEquals("7 key fix 5 L0 [4]", 3, params.getColumnPos(3));
+        assertEquals("7 key fix 5 L0 [5]", 4, params.getColumnPos(4));
+        assertEquals("7 key fix 5 L0 [6]", 0, params.getColumnPos(5));
+        assertEquals("7 key fix 5 L0 [7]", 1, params.getColumnPos(6));
+        assertEquals("7 key fix 5 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key fix 5 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [6] [7]
+    // |___ <1> [2] [3] [4] [5]
+    public void testLayout7KeyFix5L1() {
+        MoreKeysKeyboardParams params = createParams(7, 5, XPOS_L1);
+        assertEquals("7 key fix 5 L1 columns", 5, params.mNumColumns);
+        assertEquals("7 key fix 5 L1 rows", 2, params.mNumRows);
+        assertEquals("7 key fix 5 L1 left", 0, params.mLeftKeys);
+        assertEquals("7 key fix 5 L1 right", 5, params.mRightKeys);
+        assertEquals("7 key fix 5 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("7 key fix 5 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("7 key fix 5 L1 [3]", 2, params.getColumnPos(2));
+        assertEquals("7 key fix 5 L1 [4]", 3, params.getColumnPos(3));
+        assertEquals("7 key fix 5 L1 [5]", 4, params.getColumnPos(4));
+        assertEquals("7 key fix 5 L1 [6]", 0, params.getColumnPos(5));
+        assertEquals("7 key fix 5 L1 [7]", 1, params.getColumnPos(6));
+        assertEquals("7 key fix 5 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key fix 5 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___   [6] [7]
+    // |___ [1] <2> [3] [4] [5]
+    public void testLayout7KeyFix5L2() {
+        MoreKeysKeyboardParams params = createParams(7, 5, XPOS_L2);
+        assertEquals("7 key fix 5 L2 columns", 5, params.mNumColumns);
+        assertEquals("7 key fix 5 L2 rows", 2, params.mNumRows);
+        assertEquals("7 key fix 5 L2 left", 1, params.mLeftKeys);
+        assertEquals("7 key fix 5 L2 right", 4, params.mRightKeys);
+        assertEquals("7 key fix 5 L2 [1]", -1, params.getColumnPos(0));
+        assertEquals("7 key fix 5 L2 <2>", 0, params.getColumnPos(1));
+        assertEquals("7 key fix 5 L2 [3]", 1, params.getColumnPos(2));
+        assertEquals("7 key fix 5 L2 [4]", 2, params.getColumnPos(3));
+        assertEquals("7 key fix 5 L2 [5]", 3, params.getColumnPos(4));
+        assertEquals("7 key fix 5 L2 [6]", 0, params.getColumnPos(5));
+        assertEquals("7 key fix 5 L2 [7]", 1, params.getColumnPos(6));
+        assertEquals("7 key fix 5 L2 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("7 key fix 5 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    //             [6] [7]|
+    // [1] [2] [3] [4] <5>|
+    public void testLayout7KeyFix5R0() {
+        MoreKeysKeyboardParams params = createParams(7, 5, XPOS_R0);
+        assertEquals("7 key fix 5 R0 columns", 5, params.mNumColumns);
+        assertEquals("7 key fix 5 R0 rows", 2, params.mNumRows);
+        assertEquals("7 key fix 5 R0 left", 4, params.mLeftKeys);
+        assertEquals("7 key fix 5 R0 right", 1, params.mRightKeys);
+        assertEquals("7 key fix 5 R0 [1]", -4, params.getColumnPos(0));
+        assertEquals("7 key fix 5 R0 [2]", -3, params.getColumnPos(1));
+        assertEquals("7 key fix 5 R0 [3]", -2, params.getColumnPos(2));
+        assertEquals("7 key fix 5 R0 [4]", -1, params.getColumnPos(3));
+        assertEquals("7 key fix 5 R0 <5>", 0, params.getColumnPos(4));
+        assertEquals("7 key fix 5 R0 [6]", -1, params.getColumnPos(5));
+        assertEquals("7 key fix 5 R0 [7]", 0, params.getColumnPos(6));
+        assertEquals("7 key fix 5 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key fix 5 R0 default", WIDTH * 4, params.getDefaultKeyCoordX());
+    }
+
+    //             [6] [7] ___|
+    // [1] [2] [3] [4] <5> ___|
+    public void testLayout7KeyFix5R1() {
+        MoreKeysKeyboardParams params = createParams(7, 5, XPOS_R1);
+        assertEquals("7 key fix 5 R1 columns", 5, params.mNumColumns);
+        assertEquals("7 key fix 5 R1 rows", 2, params.mNumRows);
+        assertEquals("7 key fix 5 R1 left", 4, params.mLeftKeys);
+        assertEquals("7 key fix 5 R1 right", 1, params.mRightKeys);
+        assertEquals("7 key fix 5 R1 [1]", -4, params.getColumnPos(0));
+        assertEquals("7 key fix 5 R1 [2]", -3, params.getColumnPos(1));
+        assertEquals("7 key fix 5 R1 [3]", -2, params.getColumnPos(2));
+        assertEquals("7 key fix 5 R1 [4]", -1, params.getColumnPos(3));
+        assertEquals("7 key fix 5 R1 <5>", 0, params.getColumnPos(4));
+        assertEquals("7 key fix 5 R1 [6]", -1, params.getColumnPos(5));
+        assertEquals("7 key fix 5 R1 [7]", 0, params.getColumnPos(6));
+        assertEquals("7 key fix 5 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key fix 5 R1 default", WIDTH * 4, params.getDefaultKeyCoordX());
+    }
+
+    //           [6] [7]   ___|
+    // [1] [2] [3] <4> [5] ___|
+    public void testLayout7KeyFix5R2() {
+        MoreKeysKeyboardParams params = createParams(7, 5, XPOS_R2);
+        assertEquals("7 key fix 5 R2 columns",5, params.mNumColumns);
+        assertEquals("7 key fix 5 R2 rows", 2, params.mNumRows);
+        assertEquals("7 key fix 5 R2 left", 3, params.mLeftKeys);
+        assertEquals("7 key fix 5 R2 right", 2, params.mRightKeys);
+        assertEquals("7 key fix 5 R2 [1]", -3, params.getColumnPos(0));
+        assertEquals("7 key fix 5 R2 [2]", -2, params.getColumnPos(1));
+        assertEquals("7 key fix 5 R2 [3]", -1, params.getColumnPos(2));
+        assertEquals("7 key fix 5 R2 <4>", 0, params.getColumnPos(3));
+        assertEquals("7 key fix 5 R2 [5]", 1, params.getColumnPos(4));
+        assertEquals("7 key fix 5 R2 [6]", 0, params.getColumnPos(5));
+        assertEquals("7 key fix 5 R2 [7]", 1, params.getColumnPos(6));
+        assertEquals("7 key fix 5 R2 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("7 key fix 5 R2 default", WIDTH * 3, params.getDefaultKeyCoordX());
+    }
+
+    //     [6] [7] [8]
+    // [1] [2] <3> [4] [5]
+    public void testLayout8KeyFix5M0() {
+        MoreKeysKeyboardParams params = createParams(8, 5, XPOS_M0);
+        assertEquals("8 key fix 5 M0 columns", 5, params.mNumColumns);
+        assertEquals("8 key fix 5 M0 rows", 2, params.mNumRows);
+        assertEquals("8 key fix 5 M0 left", 2, params.mLeftKeys);
+        assertEquals("8 key fix 5 M0 right", 3, params.mRightKeys);
+        assertEquals("8 key fix 5 M0 [1]", -2, params.getColumnPos(0));
+        assertEquals("8 key fix 5 M0 [2]", -1, params.getColumnPos(1));
+        assertEquals("8 key fix 5 M0 <3>", 0, params.getColumnPos(2));
+        assertEquals("8 key fix 5 M0 [4]", 1, params.getColumnPos(3));
+        assertEquals("8 key fix 5 M0 [5]", 2, params.getColumnPos(4));
+        assertEquals("8 key fix 5 M0 [6]", -1, params.getColumnPos(5));
+        assertEquals("8 key fix 5 M0 [7]", 0, params.getColumnPos(6));
+        assertEquals("8 key fix 5 M0 [8]", 1, params.getColumnPos(7));
+        assertEquals("8 key fix 5 M0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("8 key fix 5 M0 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    // |[6] [7] [8]
+    // |<1> [2] [3] [4] [5]
+    public void testLayout8KeyFix5L0() {
+        MoreKeysKeyboardParams params = createParams(8, 5, XPOS_L0);
+        assertEquals("8 key fix 5 L0 columns", 5, params.mNumColumns);
+        assertEquals("8 key fix 5 L0 rows", 2, params.mNumRows);
+        assertEquals("8 key fix 5 L0 left", 0, params.mLeftKeys);
+        assertEquals("8 key fix 5 L0 right", 5, params.mRightKeys);
+        assertEquals("8 key fix 5 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("8 key fix 5 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("8 key fix 5 L0 [3]", 2, params.getColumnPos(2));
+        assertEquals("8 key fix 5 L0 [4]", 3, params.getColumnPos(3));
+        assertEquals("8 key fix 5 L0 [5]", 4, params.getColumnPos(4));
+        assertEquals("8 key fix 5 L0 [6]", 0, params.getColumnPos(5));
+        assertEquals("8 key fix 5 L0 [7]", 1, params.getColumnPos(6));
+        assertEquals("8 key fix 5 L0 [8]", 2, params.getColumnPos(7));
+        assertEquals("8 key fix 5 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("8 key fix 5 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [6] [7] [8]
+    // |___ <1> [2] [3] [4] [5]
+    public void testLayout8KeyFix5L1() {
+        MoreKeysKeyboardParams params = createParams(8, 5, XPOS_L1);
+        assertEquals("8 key fix 5 L1 columns", 5, params.mNumColumns);
+        assertEquals("8 key fix 5 L1 rows", 2, params.mNumRows);
+        assertEquals("8 key fix 5 L1 left", 0, params.mLeftKeys);
+        assertEquals("8 key fix 5 L1 right", 5, params.mRightKeys);
+        assertEquals("8 key fix 5 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("8 key fix 5 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("8 key fix 5 L1 [3]", 2, params.getColumnPos(2));
+        assertEquals("8 key fix 5 L1 [4]", 3, params.getColumnPos(3));
+        assertEquals("8 key fix 5 L1 [5]", 4, params.getColumnPos(4));
+        assertEquals("8 key fix 5 L1 [6]", 0, params.getColumnPos(5));
+        assertEquals("8 key fix 5 L1 [7]", 1, params.getColumnPos(6));
+        assertEquals("8 key fix 5 L1 [8]", 2, params.getColumnPos(7));
+        assertEquals("8 key fix 5 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("8 key fix 5 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [6] [7] [8]
+    // |___ [1] <2> [3] [4] [5]
+    public void testLayout8KeyFix5L2() {
+        MoreKeysKeyboardParams params = createParams(8, 5, XPOS_L2);
+        assertEquals("8 key fix 5 L2 columns", 5, params.mNumColumns);
+        assertEquals("8 key fix 5 L2 rows", 2, params.mNumRows);
+        assertEquals("8 key fix 5 L2 left", 1, params.mLeftKeys);
+        assertEquals("8 key fix 5 L2 right", 4, params.mRightKeys);
+        assertEquals("8 key fix 5 L2 [1]", -1, params.getColumnPos(0));
+        assertEquals("8 key fix 5 L2 <2>", 0, params.getColumnPos(1));
+        assertEquals("8 key fix 5 L2 [3]", 1, params.getColumnPos(2));
+        assertEquals("8 key fix 5 L2 [4]", 2, params.getColumnPos(3));
+        assertEquals("8 key fix 5 L2 [5]", 3, params.getColumnPos(4));
+        assertEquals("8 key fix 5 L2 [6]", -1, params.getColumnPos(5));
+        assertEquals("8 key fix 5 L2 [7]", 0, params.getColumnPos(6));
+        assertEquals("8 key fix 5 L2 [8]", 1, params.getColumnPos(7));
+        assertEquals("8 key fix 5 L2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("8 key fix 5 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    //         [6] [7] [8]|
+    // [1] [2] [3] [4] <5>|
+    public void testLayout8KeyFix5R0() {
+        MoreKeysKeyboardParams params = createParams(8, 5, XPOS_R0);
+        assertEquals("8 key fix 5 R0 columns", 5, params.mNumColumns);
+        assertEquals("8 key fix 5 R0 rows", 2, params.mNumRows);
+        assertEquals("8 key fix 5 R0 left", 4, params.mLeftKeys);
+        assertEquals("8 key fix 5 R0 right", 1, params.mRightKeys);
+        assertEquals("8 key fix 5 R0 [1]", -4, params.getColumnPos(0));
+        assertEquals("8 key fix 5 R0 [2]", -3, params.getColumnPos(1));
+        assertEquals("8 key fix 5 R0 [3]", -2, params.getColumnPos(2));
+        assertEquals("8 key fix 5 R0 [4]", -1, params.getColumnPos(3));
+        assertEquals("8 key fix 5 R0 <5>", 0, params.getColumnPos(4));
+        assertEquals("8 key fix 5 R0 [6]", -2, params.getColumnPos(5));
+        assertEquals("8 key fix 5 R0 [7]", -1, params.getColumnPos(6));
+        assertEquals("8 key fix 5 R0 [8]", 0, params.getColumnPos(7));
+        assertEquals("8 key fix 5 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("8 key fix 5 R0 default", WIDTH * 4, params.getDefaultKeyCoordX());
+    }
+
+    //         [6] [7] [8] ___|
+    // [1] [2] [3] [4] <5> ___|
+    public void testLayout8KeyFix5R1() {
+        MoreKeysKeyboardParams params = createParams(8, 5, XPOS_R1);
+        assertEquals("8 key fix 5 R1 columns", 5, params.mNumColumns);
+        assertEquals("8 key fix 5 R1 rows", 2, params.mNumRows);
+        assertEquals("8 key fix 5 R1 left", 4, params.mLeftKeys);
+        assertEquals("8 key fix 5 R1 right", 1, params.mRightKeys);
+        assertEquals("8 key fix 5 R1 [1]", -4, params.getColumnPos(0));
+        assertEquals("8 key fix 5 R1 [2]", -3, params.getColumnPos(1));
+        assertEquals("8 key fix 5 R1 [3]", -2, params.getColumnPos(2));
+        assertEquals("8 key fix 5 R1 [4]", -1, params.getColumnPos(3));
+        assertEquals("8 key fix 5 R1 <5>", 0, params.getColumnPos(4));
+        assertEquals("8 key fix 5 R1 [6]", -2, params.getColumnPos(5));
+        assertEquals("8 key fix 5 R1 [7]", -1, params.getColumnPos(6));
+        assertEquals("8 key fix 5 R1 [8]", 0, params.getColumnPos(7));
+        assertEquals("8 key fix 5 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("8 key fix 5 R1 default", WIDTH * 4, params.getDefaultKeyCoordX());
+    }
+
+    //         [6] [7] [8] ___|
+    // [1] [2] [3] <4> [5] ___|
+    public void testLayout8KeyFix5R2() {
+        MoreKeysKeyboardParams params = createParams(8, 5, XPOS_R2);
+        assertEquals("8 key fix 5 R2 columns", 5, params.mNumColumns);
+        assertEquals("8 key fix 5 R2 rows", 2, params.mNumRows);
+        assertEquals("8 key fix 5 R2 left", 3, params.mLeftKeys);
+        assertEquals("8 key fix 5 R2 right", 2, params.mRightKeys);
+        assertEquals("8 key fix 5 R2 [1]", -3, params.getColumnPos(0));
+        assertEquals("8 key fix 5 R2 [2]", -2, params.getColumnPos(1));
+        assertEquals("8 key fix 5 R2 [3]", -1, params.getColumnPos(2));
+        assertEquals("8 key fix 5 R2 <4>", 0, params.getColumnPos(3));
+        assertEquals("8 key fix 5 R2 [5]", 1, params.getColumnPos(4));
+        assertEquals("8 key fix 5 R2 [6]", -1, params.getColumnPos(5));
+        assertEquals("8 key fix 5 R2 [7]", 0, params.getColumnPos(6));
+        assertEquals("8 key fix 5 R2 [8]", 1, params.getColumnPos(7));
+        assertEquals("8 key fix 5 R2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("8 key fix 5 R2 default", WIDTH * 3, params.getDefaultKeyCoordX());
+    }
+
+    //   [6] [7] [8] [9]
+    // [1] [2] <3> [4] [5]
+    public void testLayout9KeyFix5M0() {
+        MoreKeysKeyboardParams params = createParams(9, 5, XPOS_M0);
+        assertEquals("9 key fix 5 M0 columns", 5, params.mNumColumns);
+        assertEquals("9 key fix 5 M0 rows", 2, params.mNumRows);
+        assertEquals("9 key fix 5 M0 left", 2, params.mLeftKeys);
+        assertEquals("9 key fix 5 M0 right", 3, params.mRightKeys);
+        assertEquals("9 key fix 5 M0 [1]", -2, params.getColumnPos(0));
+        assertEquals("9 key fix 5 M0 [2]", -1, params.getColumnPos(1));
+        assertEquals("9 key fix 5 M0 <3>", 0, params.getColumnPos(2));
+        assertEquals("9 key fix 5 M0 [4]", 1, params.getColumnPos(3));
+        assertEquals("9 key fix 5 M0 [5]", 2, params.getColumnPos(4));
+        assertEquals("9 key fix 5 M0 [6]", -1, params.getColumnPos(5));
+        assertEquals("9 key fix 5 M0 [7]", 0, params.getColumnPos(6));
+        assertEquals("9 key fix 5 M0 [8]", 1, params.getColumnPos(7));
+        assertEquals("9 key fix 5 M0 [9]", 2, params.getColumnPos(8));
+        assertEquals("9 key fix 5 M0 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("9 key fix 5 M0 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    // |[6] [7] [8] [9]
+    // |<1> [2] [3] [4] [5]
+    public void testLayout9KeyFix5L0() {
+        MoreKeysKeyboardParams params = createParams(9, 5, XPOS_L0);
+        assertEquals("9 key fix 5 L0 columns", 5, params.mNumColumns);
+        assertEquals("9 key fix 5 L0 rows", 2, params.mNumRows);
+        assertEquals("9 key fix 5 L0 left", 0, params.mLeftKeys);
+        assertEquals("9 key fix 5 L0 right", 5, params.mRightKeys);
+        assertEquals("9 key fix 5 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("9 key fix 5 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("9 key fix 5 L0 [3]", 2, params.getColumnPos(2));
+        assertEquals("9 key fix 5 L0 [4]", 3, params.getColumnPos(3));
+        assertEquals("9 key fix 5 L0 [5]", 4, params.getColumnPos(4));
+        assertEquals("9 key fix 5 L0 [6]", 0, params.getColumnPos(5));
+        assertEquals("9 key fix 5 L0 [7]", 1, params.getColumnPos(6));
+        assertEquals("9 key fix 5 L0 [8]", 2, params.getColumnPos(7));
+        assertEquals("9 key fix 5 L0 [9]", 3, params.getColumnPos(8));
+        assertEquals("9 key fix 5 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("9 key fix 5 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [6] [7] [8] [9]
+    // |___ <1> [2] [3] [4] [5]
+    public void testLayout9KeyFix5L1() {
+        MoreKeysKeyboardParams params = createParams(9, 5, XPOS_L1);
+        assertEquals("9 key fix 5 L1 columns", 5, params.mNumColumns);
+        assertEquals("9 key fix 5 L1 rows", 2, params.mNumRows);
+        assertEquals("9 key fix 5 L1 left", 0, params.mLeftKeys);
+        assertEquals("9 key fix 5 L1 right", 5, params.mRightKeys);
+        assertEquals("9 key fix 5 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("9 key fix 5 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("9 key fix 5 L1 [3]", 2, params.getColumnPos(2));
+        assertEquals("9 key fix 5 L1 [4]", 3, params.getColumnPos(3));
+        assertEquals("9 key fix 5 L1 [5]", 4, params.getColumnPos(4));
+        assertEquals("9 key fix 5 L1 [6]", 0, params.getColumnPos(5));
+        assertEquals("9 key fix 5 L1 [7]", 1, params.getColumnPos(6));
+        assertEquals("9 key fix 5 L1 [8]", 2, params.getColumnPos(7));
+        assertEquals("9 key fix 5 L1 [9]", 3, params.getColumnPos(8));
+        assertEquals("9 key fix 5 L1 adjust",0, params.mTopRowAdjustment);
+        assertEquals("9 key fix 5 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___   [6] [7] [8] [9]
+    // |___ [1] <2> [3] [4] [5]
+    public void testLayout9KeyFix5L2() {
+        MoreKeysKeyboardParams params = createParams(9, 5, XPOS_L2);
+        assertEquals("9 key fix 5 L2 columns", 5, params.mNumColumns);
+        assertEquals("9 key fix 5 L2 rows", 2, params.mNumRows);
+        assertEquals("9 key fix 5 L2 left", 1, params.mLeftKeys);
+        assertEquals("9 key fix 5 L2 right", 4, params.mRightKeys);
+        assertEquals("9 key fix 5 L2 [1]", -1, params.getColumnPos(0));
+        assertEquals("9 key fix 5 L2 <2>", 0, params.getColumnPos(1));
+        assertEquals("9 key fix 5 L2 [3]", 1, params.getColumnPos(2));
+        assertEquals("9 key fix 5 L2 [4]", 2, params.getColumnPos(3));
+        assertEquals("9 key fix 5 L2 [5]", 3, params.getColumnPos(4));
+        assertEquals("9 key fix 5 L2 [6]", 0, params.getColumnPos(5));
+        assertEquals("9 key fix 5 L2 [7]", 1, params.getColumnPos(6));
+        assertEquals("9 key fix 5 L2 [8]", 2, params.getColumnPos(7));
+        assertEquals("9 key fix 5 L2 [9]", 3, params.getColumnPos(8));
+        assertEquals("9 key fix 5 L2 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("9 key fix 5 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    //     [6] [7] [8] [9]|
+    // [1] [2] [3] [4] <5>|
+    public void testLayout9KeyFix5R0() {
+        MoreKeysKeyboardParams params = createParams(9, 5, XPOS_R0);
+        assertEquals("9 key fix 5 R0 columns", 5, params.mNumColumns);
+        assertEquals("9 key fix 5 R0 rows", 2, params.mNumRows);
+        assertEquals("9 key fix 5 R0 left", 4, params.mLeftKeys);
+        assertEquals("9 key fix 5 R0 right", 1, params.mRightKeys);
+        assertEquals("9 key fix 5 R0 [1]", -4, params.getColumnPos(0));
+        assertEquals("9 key fix 5 R0 [2]", -3, params.getColumnPos(1));
+        assertEquals("9 key fix 5 R0 [3]", -2, params.getColumnPos(2));
+        assertEquals("9 key fix 5 R0 [4]", -1, params.getColumnPos(3));
+        assertEquals("9 key fix 5 R0 <5>", 0, params.getColumnPos(4));
+        assertEquals("9 key fix 5 R0 [6]", -3, params.getColumnPos(5));
+        assertEquals("9 key fix 5 R0 [7]", -2, params.getColumnPos(6));
+        assertEquals("9 key fix 5 R0 [8]", -1, params.getColumnPos(7));
+        assertEquals("9 key fix 5 R0 [9]", 0, params.getColumnPos(8));
+        assertEquals("9 key fix 5 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("9 key fix 5 R0 default", WIDTH * 4, params.getDefaultKeyCoordX());
+    }
+
+    //     [6] [7] [8] [9] ___|
+    // [1] [2] [3] [4] <5> ___|
+    public void testLayout9KeyFix5R1() {
+        MoreKeysKeyboardParams params = createParams(9, 5, XPOS_R1);
+        assertEquals("9 key fix 5 R1 columns", 5, params.mNumColumns);
+        assertEquals("9 key fix 5 R1 rows", 2, params.mNumRows);
+        assertEquals("9 key fix 5 R1 left", 4, params.mLeftKeys);
+        assertEquals("9 key fix 5 R1 right", 1, params.mRightKeys);
+        assertEquals("9 key fix 5 R1 [1]", -4, params.getColumnPos(0));
+        assertEquals("9 key fix 5 R1 [2]", -3, params.getColumnPos(1));
+        assertEquals("9 key fix 5 R1 [3]", -2, params.getColumnPos(2));
+        assertEquals("9 key fix 5 R1 [4]", -1, params.getColumnPos(3));
+        assertEquals("9 key fix 5 R1 <5>", 0, params.getColumnPos(4));
+        assertEquals("9 key fix 5 R1 [6]", -3, params.getColumnPos(5));
+        assertEquals("9 key fix 5 R1 [7]", -2, params.getColumnPos(6));
+        assertEquals("9 key fix 5 R1 [8]", -1, params.getColumnPos(7));
+        assertEquals("9 key fix 5 R1 [9]", 0, params.getColumnPos(8));
+        assertEquals("9 key fix 5 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("9 key fix 5 R1 default", WIDTH * 4, params.getDefaultKeyCoordX());
+    }
+
+    //   [6] [7] [8] [9]  ___|
+    // [1] [2] [3] <4> [5] ___|
+    public void testLayout9KeyFix5R2() {
+        MoreKeysKeyboardParams params = createParams(9, 5, XPOS_R2);
+        assertEquals("9 key fix 5 R2 columns", 5, params.mNumColumns);
+        assertEquals("9 key fix 5 R2 rows", 2, params.mNumRows);
+        assertEquals("9 key fix 5 R2 left", 3, params.mLeftKeys);
+        assertEquals("9 key fix 5 R2 right", 2, params.mRightKeys);
+        assertEquals("9 key fix 5 R2 [1]", -3, params.getColumnPos(0));
+        assertEquals("9 key fix 5 R2 [2]", -2, params.getColumnPos(1));
+        assertEquals("9 key fix 5 R2 [3]", -1, params.getColumnPos(2));
+        assertEquals("9 key fix 5 R2 <4>", 0, params.getColumnPos(3));
+        assertEquals("9 key fix 5 R2 [5]", 1, params.getColumnPos(4));
+        assertEquals("9 key fix 5 R2 [6]", -2, params.getColumnPos(5));
+        assertEquals("9 key fix 5 R2 [7]", -1, params.getColumnPos(6));
+        assertEquals("9 key fix 5 R2 [8]", 0, params.getColumnPos(7));
+        assertEquals("9 key fix 5 R2 [9]", 1, params.getColumnPos(8));
+        assertEquals("9 key fix 5 R2 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("9 key fix 5 R2 default", WIDTH * 3, params.getDefaultKeyCoordX());
+    }
+
+    // [6] [7] [8] [9] [A]
+    // [1] [2] <3> [4] [5]
+    public void testLayout10KeyFix5M0() {
+        MoreKeysKeyboardParams params = createParams(10, 5, XPOS_M0);
+        assertEquals("10 key fix 5 M0 columns", 5, params.mNumColumns);
+        assertEquals("10 key fix 5 M0 rows", 2, params.mNumRows);
+        assertEquals("10 key fix 5 M0 left", 2, params.mLeftKeys);
+        assertEquals("10 key fix 5 M0 right", 3, params.mRightKeys);
+        assertEquals("10 key fix 5 M0 [1]", -2, params.getColumnPos(0));
+        assertEquals("10 key fix 5 M0 [2]", -1, params.getColumnPos(1));
+        assertEquals("10 key fix 5 M0 <3>", 0, params.getColumnPos(2));
+        assertEquals("10 key fix 5 M0 [4]", 1, params.getColumnPos(3));
+        assertEquals("10 key fix 5 M0 [5]", 2, params.getColumnPos(4));
+        assertEquals("10 key fix 5 M0 [6]", -2, params.getColumnPos(5));
+        assertEquals("10 key fix 5 M0 [7]", -1, params.getColumnPos(6));
+        assertEquals("10 key fix 5 M0 [8]", 0, params.getColumnPos(7));
+        assertEquals("10 key fix 5 M0 [9]", 1, params.getColumnPos(8));
+        assertEquals("10 key fix 5 M0 [A]", 2, params.getColumnPos(9));
+        assertEquals("10 key fix 5 M0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("10 key fix 5 M0 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    // |[6] [7] [8] [9] [A]
+    // |<1> [2] [3] [4] [5]
+    public void testLayout10KeyFix5L0() {
+        MoreKeysKeyboardParams params = createParams(10, 5, XPOS_L0);
+        assertEquals("10 key fix 5 L0 columns", 5, params.mNumColumns);
+        assertEquals("10 key fix 5 L0 rows", 2, params.mNumRows);
+        assertEquals("10 key fix 5 L0 left", 0, params.mLeftKeys);
+        assertEquals("10 key fix 5 L0 right", 5, params.mRightKeys);
+        assertEquals("10 key fix 5 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("10 key fix 5 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("10 key fix 5 L0 [3]", 2, params.getColumnPos(2));
+        assertEquals("10 key fix 5 L0 [4]", 3, params.getColumnPos(3));
+        assertEquals("10 key fix 5 L0 [5]", 4, params.getColumnPos(4));
+        assertEquals("10 key fix 5 L0 [6]", 0, params.getColumnPos(5));
+        assertEquals("10 key fix 5 L0 [7]", 1, params.getColumnPos(6));
+        assertEquals("10 key fix 5 L0 [8]", 2, params.getColumnPos(7));
+        assertEquals("10 key fix 5 L0 [9]", 3, params.getColumnPos(8));
+        assertEquals("10 key fix 5 L0 [A]", 4, params.getColumnPos(9));
+        assertEquals("10 key fix 5 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("10 key fix 5 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [6] [7] [8] [9] [A]
+    // |___ <1> [2] [3] [4] [5]
+    public void testLayout10KeyFix5L1() {
+        MoreKeysKeyboardParams params = createParams(10, 5, XPOS_L1);
+        assertEquals("10 key fix 5 L1 columns", 5, params.mNumColumns);
+        assertEquals("10 key fix 5 L1 rows", 2, params.mNumRows);
+        assertEquals("10 key fix 5 L1 left", 0, params.mLeftKeys);
+        assertEquals("10 key fix 5 L1 right", 5, params.mRightKeys);
+        assertEquals("10 key fix 5 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("10 key fix 5 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("10 key fix 5 L1 [3]", 2, params.getColumnPos(2));
+        assertEquals("10 key fix 5 L1 [4]", 3, params.getColumnPos(3));
+        assertEquals("10 key fix 5 L1 [5]", 4, params.getColumnPos(4));
+        assertEquals("10 key fix 5 L1 [6]", 0, params.getColumnPos(5));
+        assertEquals("10 key fix 5 L1 [7]", 1, params.getColumnPos(6));
+        assertEquals("10 key fix 5 L1 [8]", 2, params.getColumnPos(7));
+        assertEquals("10 key fix 5 L1 [9]", 3, params.getColumnPos(8));
+        assertEquals("10 key fix 5 L1 [A]", 4, params.getColumnPos(9));
+        assertEquals("10 key fix 5 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("10 key fix 5 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [6] [7] [8] [9] [A]
+    // |___ [1] <2> [3] [4] [5]
+    public void testLayout10KeyFix5L2() {
+        MoreKeysKeyboardParams params = createParams(10, 5, XPOS_L2);
+        assertEquals("10 key fix 5 L2 columns", 5, params.mNumColumns);
+        assertEquals("10 key fix 5 L2 rows", 2, params.mNumRows);
+        assertEquals("10 key fix 5 L2 left", 1, params.mLeftKeys);
+        assertEquals("10 key fix 5 L2 right", 4, params.mRightKeys);
+        assertEquals("10 key fix 5 L2 [1]", -1, params.getColumnPos(0));
+        assertEquals("10 key fix 5 L2 <2>", 0, params.getColumnPos(1));
+        assertEquals("10 key fix 5 L2 [3]", 1, params.getColumnPos(2));
+        assertEquals("10 key fix 5 L2 [4]", 2, params.getColumnPos(3));
+        assertEquals("10 key fix 5 L2 [5]", 3, params.getColumnPos(4));
+        assertEquals("10 key fix 5 L2 [6]", -1, params.getColumnPos(5));
+        assertEquals("10 key fix 5 L2 [7]", 0, params.getColumnPos(6));
+        assertEquals("10 key fix 5 L2 [8]", 1, params.getColumnPos(7));
+        assertEquals("10 key fix 5 L2 [9]", 2, params.getColumnPos(8));
+        assertEquals("10 key fix 5 L2 [A]", 3, params.getColumnPos(9));
+        assertEquals("10 key fix 5 L2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("10 key fix 5 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // [6] [7] [8] [9] [A]|
+    // [1] [2] [3] [4] <5>|
+    public void testLayout10KeyFix5R0() {
+        MoreKeysKeyboardParams params = createParams(10, 5, XPOS_R0);
+        assertEquals("10 key fix 5 R0 columns", 5, params.mNumColumns);
+        assertEquals("10 key fix 5 R0 rows", 2, params.mNumRows);
+        assertEquals("10 key fix 5 R0 left", 4, params.mLeftKeys);
+        assertEquals("10 key fix 5 R0 right", 1, params.mRightKeys);
+        assertEquals("10 key fix 5 R0 [1]", -4, params.getColumnPos(0));
+        assertEquals("10 key fix 5 R0 [2]", -3, params.getColumnPos(1));
+        assertEquals("10 key fix 5 R0 [3]", -2, params.getColumnPos(2));
+        assertEquals("10 key fix 5 R0 [4]", -1, params.getColumnPos(3));
+        assertEquals("10 key fix 5 R0 <5>", 0, params.getColumnPos(4));
+        assertEquals("10 key fix 5 R0 [6]", -4, params.getColumnPos(5));
+        assertEquals("10 key fix 5 R0 [7]", -3, params.getColumnPos(6));
+        assertEquals("10 key fix 5 R0 [8]", -2, params.getColumnPos(7));
+        assertEquals("10 key fix 5 R0 [9]", -1, params.getColumnPos(8));
+        assertEquals("10 key fix 5 R0 [A]", 0, params.getColumnPos(9));
+        assertEquals("10 key fix 5 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("10 key fix 5 R0 default", WIDTH * 4, params.getDefaultKeyCoordX());
+    }
+
+    // [6] [7] [8] [9] [A] ___|
+    // [1] [2] [3] [4] <5> ___|
+    public void testLayout10KeyFix5R1() {
+        MoreKeysKeyboardParams params = createParams(10, 5, XPOS_R1);
+        assertEquals("10 key fix 5 R1 columns", 5, params.mNumColumns);
+        assertEquals("10 key fix 5 R1 rows", 2, params.mNumRows);
+        assertEquals("10 key fix 5 R1 left", 4, params.mLeftKeys);
+        assertEquals("10 key fix 5 R1 right", 1, params.mRightKeys);
+        assertEquals("10 key fix 5 R1 [1]", -4, params.getColumnPos(0));
+        assertEquals("10 key fix 5 R1 [2]", -3, params.getColumnPos(1));
+        assertEquals("10 key fix 5 R1 [3]", -2, params.getColumnPos(2));
+        assertEquals("10 key fix 5 R1 [4]", -1, params.getColumnPos(3));
+        assertEquals("10 key fix 5 R1 <5>", 0, params.getColumnPos(4));
+        assertEquals("10 key fix 5 R1 [6]", -4, params.getColumnPos(5));
+        assertEquals("10 key fix 5 R1 [7]", -3, params.getColumnPos(6));
+        assertEquals("10 key fix 5 R1 [8]", -2, params.getColumnPos(7));
+        assertEquals("10 key fix 5 R1 [9]", -1, params.getColumnPos(8));
+        assertEquals("10 key fix 5 R1 [A]", 0, params.getColumnPos(9));
+        assertEquals("10 key fix 5 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("10 key fix 5 R1 default", WIDTH * 4, params.getDefaultKeyCoordX());
+    }
+
+    // [6] [7] [8] [9] [A] ___|
+    // [1] [2] [3] <4> [5] ___|
+    public void testLayout10KeyFix5R2() {
+        MoreKeysKeyboardParams params = createParams(10, 5, XPOS_R2);
+        assertEquals("10 key fix 5 R2 columns", 5, params.mNumColumns);
+        assertEquals("10 key fix 5 R2 rows", 2, params.mNumRows);
+        assertEquals("10 key fix 5 R2 left", 3, params.mLeftKeys);
+        assertEquals("10 key fix 5 R2 right", 2, params.mRightKeys);
+        assertEquals("10 key fix 5 R2 [1]", -3, params.getColumnPos(0));
+        assertEquals("10 key fix 5 R2 [2]", -2, params.getColumnPos(1));
+        assertEquals("10 key fix 5 R2 [3]", -1, params.getColumnPos(2));
+        assertEquals("10 key fix 5 R2 <4>", 0, params.getColumnPos(3));
+        assertEquals("10 key fix 5 R2 [5]", 1, params.getColumnPos(4));
+        assertEquals("10 key fix 5 R2 [6]", -3, params.getColumnPos(5));
+        assertEquals("10 key fix 5 R2 [7]", -2, params.getColumnPos(6));
+        assertEquals("10 key fix 5 R2 [8]", -1, params.getColumnPos(7));
+        assertEquals("10 key fix 5 R2 [9]", 0, params.getColumnPos(8));
+        assertEquals("10 key fix 5 R2 [A]", 1, params.getColumnPos(9));
+        assertEquals("10 key fix 5 R2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("10 key fix 5 R2 default", WIDTH * 3, params.getDefaultKeyCoordX());
+    }
+
+    //         [B]
+    // [6] [7] [8] [9] [A]
+    // [1] [2] <3> [4] [5]
+    public void testLayout11KeyFix5M0() {
+        MoreKeysKeyboardParams params = createParams(11, 5, XPOS_M0);
+        assertEquals("11 key fix 5 M0 columns", 5, params.mNumColumns);
+        assertEquals("11 key fix 5 M0 rows", 3, params.mNumRows);
+        assertEquals("11 key fix 5 M0 left", 2, params.mLeftKeys);
+        assertEquals("11 key fix 5 M0 right", 3, params.mRightKeys);
+        assertEquals("11 key fix 5 M0 [1]", -2, params.getColumnPos(0));
+        assertEquals("11 key fix 5 M0 [2]", -1, params.getColumnPos(1));
+        assertEquals("11 key fix 5 M0 <3>", 0, params.getColumnPos(2));
+        assertEquals("11 key fix 5 M0 [4]", 1, params.getColumnPos(3));
+        assertEquals("11 key fix 5 M0 [5]", 2, params.getColumnPos(4));
+        assertEquals("11 key fix 5 M0 [6]", -2, params.getColumnPos(5));
+        assertEquals("11 key fix 5 M0 [7]", -1, params.getColumnPos(6));
+        assertEquals("11 key fix 5 M0 [8]", 0, params.getColumnPos(7));
+        assertEquals("11 key fix 5 M0 [9]", 1, params.getColumnPos(8));
+        assertEquals("11 key fix 5 M0 [A]", 2, params.getColumnPos(9));
+        assertEquals("11 key fix 5 M0 [B]", 0, params.getColumnPos(10));
+        assertEquals("11 key fix 5 M0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("11 key fix 5 M0 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    //       [B] [C]
+    // [6] [7] [8] [9] [A]
+    // [1] [2] <3> [4] [5]
+    public void testLayout12KeyFix5M0() {
+        MoreKeysKeyboardParams params = createParams(12, 5, XPOS_M0);
+        assertEquals("12 key fix 5 M0 columns", 5, params.mNumColumns);
+        assertEquals("12 key fix 5 M0 rows", 3, params.mNumRows);
+        assertEquals("12 key fix 5 M0 left", 2, params.mLeftKeys);
+        assertEquals("12 key fix 5 M0 right", 3, params.mRightKeys);
+        assertEquals("12 key fix 5 M0 [1]", -2, params.getColumnPos(0));
+        assertEquals("12 key fix 5 M0 [2]", -1, params.getColumnPos(1));
+        assertEquals("12 key fix 5 M0 <3>", 0, params.getColumnPos(2));
+        assertEquals("12 key fix 5 M0 [4]", 1, params.getColumnPos(3));
+        assertEquals("12 key fix 5 M0 [5]", 2, params.getColumnPos(4));
+        assertEquals("12 key fix 5 M0 [6]", -2, params.getColumnPos(5));
+        assertEquals("12 key fix 5 M0 [7]", -1, params.getColumnPos(6));
+        assertEquals("12 key fix 5 M0 [8]", 0, params.getColumnPos(7));
+        assertEquals("12 key fix 5 M0 [9]", 1, params.getColumnPos(8));
+        assertEquals("12 key fix 5 M0 [A]", 2, params.getColumnPos(9));
+        assertEquals("12 key fix 5 M0 [B]", 0, params.getColumnPos(10));
+        assertEquals("12 key fix 5 M0 [C]", 1, params.getColumnPos(11));
+        assertEquals("12 key fix 5 M0 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("12 key fix 5 M0 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    //     [B] [C] [D]
+    // [6] [7] [8] [9] [A]
+    // [1] [2] <3> [4] [5]
+    public void testLayout13KeyFix5M0() {
+        MoreKeysKeyboardParams params = createParams(13, 5, XPOS_M0);
+        assertEquals("13 key fix 5 M0 columns", 5, params.mNumColumns);
+        assertEquals("13 key fix 5 M0 rows", 3, params.mNumRows);
+        assertEquals("13 key fix 5 M0 left", 2, params.mLeftKeys);
+        assertEquals("13 key fix 5 M0 right", 3, params.mRightKeys);
+        assertEquals("13 key fix 5 M0 [1]", -2, params.getColumnPos(0));
+        assertEquals("13 key fix 5 M0 [2]", -1, params.getColumnPos(1));
+        assertEquals("13 key fix 5 M0 <3>", 0, params.getColumnPos(2));
+        assertEquals("13 key fix 5 M0 [4]", 1, params.getColumnPos(3));
+        assertEquals("13 key fix 5 M0 [5]", 2, params.getColumnPos(4));
+        assertEquals("13 key fix 5 M0 [6]", -2, params.getColumnPos(5));
+        assertEquals("13 key fix 5 M0 [7]", -1, params.getColumnPos(6));
+        assertEquals("13 key fix 5 M0 [8]", 0, params.getColumnPos(7));
+        assertEquals("13 key fix 5 M0 [9]", 1, params.getColumnPos(8));
+        assertEquals("13 key fix 5 M0 [A]", 2, params.getColumnPos(9));
+        assertEquals("13 key fix 5 M0 [B]", -1, params.getColumnPos(10));
+        assertEquals("13 key fix 5 M0 [C]", 0, params.getColumnPos(11));
+        assertEquals("13 key fix 5 M0 [D]", 1, params.getColumnPos(12));
+        assertEquals("13 key fix 5 M0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("13 key fix 5 M0 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    //   [B] [C] [D] [E]
+    // [6] [7] [8] [9] [A]
+    // [1] [2] <3> [4] [5]
+    public void testLayout14KeyFix5M0() {
+        MoreKeysKeyboardParams params = createParams(14, 5, XPOS_M0);
+        assertEquals("14 key fix 5 M0 columns", 5, params.mNumColumns);
+        assertEquals("14 key fix 5 M0 rows", 3, params.mNumRows);
+        assertEquals("14 key fix 5 M0 left", 2, params.mLeftKeys);
+        assertEquals("14 key fix 5 M0 right", 3, params.mRightKeys);
+        assertEquals("14 key fix 5 M0 [1]", -2, params.getColumnPos(0));
+        assertEquals("14 key fix 5 M0 [2]", -1, params.getColumnPos(1));
+        assertEquals("14 key fix 5 M0 <3>", 0, params.getColumnPos(2));
+        assertEquals("14 key fix 5 M0 [4]", 1, params.getColumnPos(3));
+        assertEquals("14 key fix 5 M0 [5]", 2, params.getColumnPos(4));
+        assertEquals("14 key fix 5 M0 [6]", -2, params.getColumnPos(5));
+        assertEquals("14 key fix 5 M0 [7]", -1, params.getColumnPos(6));
+        assertEquals("14 key fix 5 M0 [8]", 0, params.getColumnPos(7));
+        assertEquals("14 key fix 5 M0 [9]", 1, params.getColumnPos(8));
+        assertEquals("14 key fix 5 M0 [A]", 2, params.getColumnPos(9));
+        assertEquals("14 key fix 5 M0 [B]", -1, params.getColumnPos(10));
+        assertEquals("14 key fix 5 M0 [C]", 0, params.getColumnPos(11));
+        assertEquals("14 key fix 5 M0 [D]", 1, params.getColumnPos(12));
+        assertEquals("14 key fix 5 M0 [E]", 2, params.getColumnPos(13));
+        assertEquals("14 key fix 5 M0 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("14 key fix 5 M0 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    // |<1> [2] [3] [4] [5] [6] [7]
+    public void testLayout7KeyFix7L0() {
+        MoreKeysKeyboardParams params = createParams(7, 7, XPOS_L0);
+        assertEquals("7 key fix 7 L0 columns", 7, params.mNumColumns);
+        assertEquals("7 key fix 7 L0 rows", 1, params.mNumRows);
+        assertEquals("7 key fix 7 L0 left", 0, params.mLeftKeys);
+        assertEquals("7 key fix 7 L0 right", 7, params.mRightKeys);
+        assertEquals("7 key fix 7 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("7 key fix 7 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("7 key fix 7 L0 [3]", 2, params.getColumnPos(2));
+        assertEquals("7 key fix 7 L0 [4]", 3, params.getColumnPos(3));
+        assertEquals("7 key fix 7 L0 [5]", 4, params.getColumnPos(4));
+        assertEquals("7 key fix 7 L0 [6]", 5, params.getColumnPos(5));
+        assertEquals("7 key fix 7 L0 [7]", 6, params.getColumnPos(6));
+        assertEquals("7 key fix 7 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key fix 7 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ <1> [2] [3] [4] [5] [6] [7]
+    public void testLayout7KeyFix7L1() {
+        MoreKeysKeyboardParams params = createParams(7, 7, XPOS_L1);
+        assertEquals("7 key fix 7 L1 columns", 7, params.mNumColumns);
+        assertEquals("7 key fix 7 L1 rows", 1, params.mNumRows);
+        assertEquals("7 key fix 7 L1 left", 0, params.mLeftKeys);
+        assertEquals("7 key fix 7 L1 right", 7, params.mRightKeys);
+        assertEquals("7 key fix 7 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("7 key fix 7 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("7 key fix 7 L1 [3]", 2, params.getColumnPos(2));
+        assertEquals("7 key fix 7 L1 [4]", 3, params.getColumnPos(3));
+        assertEquals("7 key fix 7 L1 [5]", 4, params.getColumnPos(4));
+        assertEquals("7 key fix 7 L1 [6]", 5, params.getColumnPos(5));
+        assertEquals("7 key fix 7 L1 [7]", 6, params.getColumnPos(6));
+        assertEquals("7 key fix 7 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key fix 7 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [1] <2> [3] [4] [5] [6] [7]
+    public void testLayout7KeyFix7L2() {
+        MoreKeysKeyboardParams params = createParams(7, 7, XPOS_L2);
+        assertEquals("7 key fix 7 L2 columns", 7, params.mNumColumns);
+        assertEquals("7 key fix 7 L2 rows", 1, params.mNumRows);
+        assertEquals("7 key fix 7 L2 left", 1, params.mLeftKeys);
+        assertEquals("7 key fix 7 L2 right", 6, params.mRightKeys);
+        assertEquals("7 key fix 7 L2 [1]", -1, params.getColumnPos(0));
+        assertEquals("7 key fix 7 L2 <2>", 0, params.getColumnPos(1));
+        assertEquals("7 key fix 7 L2 [3]", 1, params.getColumnPos(2));
+        assertEquals("7 key fix 7 L2 [4]", 2, params.getColumnPos(3));
+        assertEquals("7 key fix 7 L2 [5]", 3, params.getColumnPos(4));
+        assertEquals("7 key fix 7 L2 [6]", 4, params.getColumnPos(5));
+        assertEquals("7 key fix 7 L2 [7]", 5, params.getColumnPos(6));
+        assertEquals("7 key fix 7 L2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key fix 7 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [1] [2] <3> [4] [5] [6] [7]
+    public void testLayout7KeyFix7L3() {
+        MoreKeysKeyboardParams params = createParams(7, 7, XPOS_L3);
+        assertEquals("7 key fix 7 L3 columns", 7, params.mNumColumns);
+        assertEquals("7 key fix 7 L3 rows", 1, params.mNumRows);
+        assertEquals("7 key fix 7 L3 left", 2, params.mLeftKeys);
+        assertEquals("7 key fix 7 L3 right", 5, params.mRightKeys);
+        assertEquals("7 key fix 7 L3 [1]", -2, params.getColumnPos(0));
+        assertEquals("7 key fix 7 L3 [2]", -1, params.getColumnPos(1));
+        assertEquals("7 key fix 7 L3 <3>", 0, params.getColumnPos(2));
+        assertEquals("7 key fix 7 L3 [4]", 1, params.getColumnPos(3));
+        assertEquals("7 key fix 7 L3 [5]", 2, params.getColumnPos(4));
+        assertEquals("7 key fix 7 L3 [6]", 3, params.getColumnPos(5));
+        assertEquals("7 key fix 7 L3 [7]", 4, params.getColumnPos(6));
+        assertEquals("7 key fix 7 L3 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key fix 7 L3 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [1] [2] [3] <4> [5] [6] [7] ___ ___|
+    public void testLayout7KeyFix7M0() {
+        MoreKeysKeyboardParams params = createParams(7, 7, XPOS_M0);
+        assertEquals("7 key fix 7 M0 columns", 7, params.mNumColumns);
+        assertEquals("7 key fix 7 M0 rows", 1, params.mNumRows);
+        assertEquals("7 key fix 7 M0 left", 3, params.mLeftKeys);
+        assertEquals("7 key fix 7 M0 right", 4, params.mRightKeys);
+        assertEquals("7 key fix 7 M0 [1]", -3, params.getColumnPos(0));
+        assertEquals("7 key fix 7 M0 [2]", -2, params.getColumnPos(1));
+        assertEquals("7 key fix 7 M0 [3]", -1, params.getColumnPos(2));
+        assertEquals("7 key fix 7 M0 <4>", 0, params.getColumnPos(3));
+        assertEquals("7 key fix 7 M0 [5]", 1, params.getColumnPos(4));
+        assertEquals("7 key fix 7 M0 [6]", 2, params.getColumnPos(5));
+        assertEquals("7 key fix 7 M0 [7]", 3, params.getColumnPos(6));
+        assertEquals("7 key fix 7 M0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key fix 7 M0 default", WIDTH * 3, params.getDefaultKeyCoordX());
+    }
+
+    // |___ ___ [1] [2] [3] <4> [5] [6] [7] ___|
+    public void testLayout7KeyFix7M1() {
+        MoreKeysKeyboardParams params = createParams(7, 7, XPOS_M1);
+        assertEquals("7 key fix 7 M1 columns", 7, params.mNumColumns);
+        assertEquals("7 key fix 7 M1 rows", 1, params.mNumRows);
+        assertEquals("7 key fix 7 M1 left", 3, params.mLeftKeys);
+        assertEquals("7 key fix 7 M1 right", 4, params.mRightKeys);
+        assertEquals("7 key fix 7 M1 [1]", -3, params.getColumnPos(0));
+        assertEquals("7 key fix 7 M1 [2]", -2, params.getColumnPos(1));
+        assertEquals("7 key fix 7 M1 [3]", -1, params.getColumnPos(2));
+        assertEquals("7 key fix 7 M1 <4>", 0, params.getColumnPos(3));
+        assertEquals("7 key fix 7 M1 [5]", 1, params.getColumnPos(4));
+        assertEquals("7 key fix 7 M1 [6]", 2, params.getColumnPos(5));
+        assertEquals("7 key fix 7 M1 [7]", 3, params.getColumnPos(6));
+        assertEquals("7 key fix 7 M1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key fix 7 M1 default", WIDTH * 3, params.getDefaultKeyCoordX());
+    }
+
+    // [1] [2] [3] [4] <5> [6] [7] ___|
+    public void testLayout7KeyFix7R3() {
+        MoreKeysKeyboardParams params = createParams(7, 7, XPOS_R3);
+        assertEquals("7 key fix 7 R3 columns", 7, params.mNumColumns);
+        assertEquals("7 key fix 7 R3 rows", 1, params.mNumRows);
+        assertEquals("7 key fix 7 R3 left", 4, params.mLeftKeys);
+        assertEquals("7 key fix 7 R3 right", 3, params.mRightKeys);
+        assertEquals("7 key fix 7 R3 [1]", -4, params.getColumnPos(0));
+        assertEquals("7 key fix 7 R3 [2]", -3, params.getColumnPos(1));
+        assertEquals("7 key fix 7 R3 [3]", -2, params.getColumnPos(2));
+        assertEquals("7 key fix 7 R3 [4]", -1, params.getColumnPos(3));
+        assertEquals("7 key fix 7 R3 <5>", 0, params.getColumnPos(4));
+        assertEquals("7 key fix 7 R3 [6]", 1, params.getColumnPos(5));
+        assertEquals("7 key fix 7 R3 [7]", 2, params.getColumnPos(6));
+        assertEquals("7 key fix 7 R3 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key fix 7 R3 default", WIDTH * 4, params.getDefaultKeyCoordX());
+    }
+
+    // [1] [2] [3] [4] [5] <6> [7] ___|
+    public void testLayout7KeyFix7R2() {
+        MoreKeysKeyboardParams params = createParams(7, 7, XPOS_R2);
+        assertEquals("7 key fix 7 R2 columns", 7, params.mNumColumns);
+        assertEquals("7 key fix 7 R2 rows", 1, params.mNumRows);
+        assertEquals("7 key fix 7 R2 left", 5, params.mLeftKeys);
+        assertEquals("7 key fix 7 R2 right", 2, params.mRightKeys);
+        assertEquals("7 key fix 7 R2 [1]", -5, params.getColumnPos(0));
+        assertEquals("7 key fix 7 R2 [2]", -4, params.getColumnPos(1));
+        assertEquals("7 key fix 7 R2 [3]", -3, params.getColumnPos(2));
+        assertEquals("7 key fix 7 R2 [4]", -2, params.getColumnPos(3));
+        assertEquals("7 key fix 7 R2 [5]", -1, params.getColumnPos(4));
+        assertEquals("7 key fix 7 R2 <6>", 0, params.getColumnPos(5));
+        assertEquals("7 key fix 7 R2 [7]", 1, params.getColumnPos(6));
+        assertEquals("7 key fix 7 R2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key fix 7 R2 default", WIDTH * 5, params.getDefaultKeyCoordX());
+    }
+
+    // [1] [2] [3] [4] [5] [6] <7> ___|
+    public void testLayout7KeyFix7R1() {
+        MoreKeysKeyboardParams params = createParams(7, 7, XPOS_R1);
+        assertEquals("7 key fix 7 R1 columns", 7, params.mNumColumns);
+        assertEquals("7 key fix 7 R1 rows", 1, params.mNumRows);
+        assertEquals("7 key fix 7 R1 left", 6, params.mLeftKeys);
+        assertEquals("7 key fix 7 R1 right", 1, params.mRightKeys);
+        assertEquals("7 key fix 7 R1 [1]", -6, params.getColumnPos(0));
+        assertEquals("7 key fix 7 R1 [2]", -5, params.getColumnPos(1));
+        assertEquals("7 key fix 7 R1 [3]", -4, params.getColumnPos(2));
+        assertEquals("7 key fix 7 R1 [4]", -3, params.getColumnPos(3));
+        assertEquals("7 key fix 7 R1 [5]", -2, params.getColumnPos(4));
+        assertEquals("7 key fix 7 R1 [6]", -1, params.getColumnPos(5));
+        assertEquals("7 key fix 7 R1 <7>", 0, params.getColumnPos(6));
+        assertEquals("7 key fix 7 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key fix 7 R1 default", WIDTH * 6, params.getDefaultKeyCoordX());
+    }
+
+    // [1] [2] [3] [4] [5] [6] <7>|
+    public void testLayout7KeyFix7R0() {
+        MoreKeysKeyboardParams params = createParams(7, 7, XPOS_R0);
+        assertEquals("7 key fix 7 R0 columns", 7, params.mNumColumns);
+        assertEquals("7 key fix 7 R0 rows", 1, params.mNumRows);
+        assertEquals("7 key fix 7 R0 left", 6, params.mLeftKeys);
+        assertEquals("7 key fix 7 R0 right", 1, params.mRightKeys);
+        assertEquals("7 key fix 7 R0 [1]", -6, params.getColumnPos(0));
+        assertEquals("7 key fix 7 R0 [2]", -5, params.getColumnPos(1));
+        assertEquals("7 key fix 7 R0 [3]", -4, params.getColumnPos(2));
+        assertEquals("7 key fix 7 R0 [4]", -3, params.getColumnPos(3));
+        assertEquals("7 key fix 7 R0 [5]", -2, params.getColumnPos(4));
+        assertEquals("7 key fix 7 R0 [6]", -1, params.getColumnPos(5));
+        assertEquals("7 key fix 7 R0 <7>", 0, params.getColumnPos(6));
+        assertEquals("7 key fix 7 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key fix 7 R0 default", WIDTH * 6, params.getDefaultKeyCoordX());
+    }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/MoreKeysKeyboardBuilderTests.java b/tests/src/com/android/inputmethod/keyboard/MoreKeysKeyboardBuilderTests.java
index 1a1d643..90bbf7e 100644
--- a/tests/src/com/android/inputmethod/keyboard/MoreKeysKeyboardBuilderTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/MoreKeysKeyboardBuilderTests.java
@@ -61,409 +61,626 @@
 
     // More keys keyboard layout test.
     // "[n]" represents n-th key position in more keys keyboard.
-    // "[1]" is the default key.
+    // "<1>" is the default key.
 
-    // [1]
+    // <1>
     public void testLayout1KeyMax5M0() {
         MoreKeysKeyboardParams params = createParams(1, 5, XPOS_M0);
         assertEquals("1 key max 5 M0 columns", 1, params.mNumColumns);
         assertEquals("1 key max 5 M0 rows", 1, params.mNumRows);
         assertEquals("1 key max 5 M0 left", 0, params.mLeftKeys);
         assertEquals("1 key max 5 M0 right", 1, params.mRightKeys);
-        assertEquals("1 key max 5 M0 [1]", 0, params.getColumnPos(0));
+        assertEquals("1 key max 5 M0 <1>", 0, params.getColumnPos(0));
         assertEquals("1 key max 5 M0 adjust", 0, params.mTopRowAdjustment);
         assertEquals("1 key max 5 M0 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // |[1]
+    // |<1>
     public void testLayout1KeyMax5L0() {
         MoreKeysKeyboardParams params = createParams(1, 5, XPOS_L0);
         assertEquals("1 key max 5 L0 columns", 1, params.mNumColumns);
         assertEquals("1 key max 5 L0 rows", 1, params.mNumRows);
         assertEquals("1 key max 5 L0 left", 0, params.mLeftKeys);
         assertEquals("1 key max 5 L0 right", 1, params.mRightKeys);
-        assertEquals("1 key max 5 L0 [1]", 0, params.getColumnPos(0));
+        assertEquals("1 key max 5 L0 <1>", 0, params.getColumnPos(0));
         assertEquals("1 key max 5 L0 adjust", 0, params.mTopRowAdjustment);
         assertEquals("1 key max 5 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // |___ [1]
+    // |___ <1>
     public void testLayout1KeyMax5L1() {
         MoreKeysKeyboardParams params = createParams(1, 5, XPOS_L1);
         assertEquals("1 key max 5 L1 columns", 1, params.mNumColumns);
         assertEquals("1 key max 5 L1 rows", 1, params.mNumRows);
         assertEquals("1 key max 5 L1 left", 0, params.mLeftKeys);
         assertEquals("1 key max 5 L1 right", 1, params.mRightKeys);
-        assertEquals("1 key max 5 L1 [1]", 0, params.getColumnPos(0));
+        assertEquals("1 key max 5 L1 <1>", 0, params.getColumnPos(0));
         assertEquals("1 key max 5 L1 adjust", 0, params.mTopRowAdjustment);
         assertEquals("1 key max 5 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // |___ ___ [1]
+    // |___ ___ <1>
     public void testLayout1KeyMax5L2() {
         MoreKeysKeyboardParams params = createParams(1, 5, XPOS_L2);
         assertEquals("1 key max 5 L2 columns", 1, params.mNumColumns);
         assertEquals("1 key max 5 L2 rows", 1, params.mNumRows);
         assertEquals("1 key max 5 L2 left", 0, params.mLeftKeys);
         assertEquals("1 key max 5 L2 right", 1, params.mRightKeys);
-        assertEquals("1 key max 5 L2 [1]", 0, params.getColumnPos(0));
+        assertEquals("1 key max 5 L2 <1>", 0, params.getColumnPos(0));
         assertEquals("1 key max 5 L2 adjust", 0, params.mTopRowAdjustment);
         assertEquals("1 key max 5 L2 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // [1]|
+    // <1>|
     public void testLayout1KeyMax5R0() {
         MoreKeysKeyboardParams params = createParams(1, 5, XPOS_R0);
         assertEquals("1 key max 5 R0 columns", 1, params.mNumColumns);
         assertEquals("1 key max 5 R0 rows", 1, params.mNumRows);
         assertEquals("1 key max 5 R0 left", 0, params.mLeftKeys);
         assertEquals("1 key max 5 R0 right", 1, params.mRightKeys);
-        assertEquals("1 key max 5 R0 [1]", 0, params.getColumnPos(0));
+        assertEquals("1 key max 5 R0 <1>", 0, params.getColumnPos(0));
         assertEquals("1 key max 5 R0 adjust", 0, params.mTopRowAdjustment);
         assertEquals("1 key max 5 R0 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // [1] ___|
+    // <1> ___|
     public void testLayout1KeyMax5R1() {
         MoreKeysKeyboardParams params = createParams(1, 5, XPOS_R1);
         assertEquals("1 key max 5 R1 columns", 1, params.mNumColumns);
         assertEquals("1 key max 5 R1 rows", 1, params.mNumRows);
         assertEquals("1 key max 5 R1 left", 0, params.mLeftKeys);
         assertEquals("1 key max 5 R1 right", 1, params.mRightKeys);
-        assertEquals("1 key max 5 R1 [1]", 0, params.getColumnPos(0));
+        assertEquals("1 key max 5 R1 <1>", 0, params.getColumnPos(0));
         assertEquals("1 key max 5 R1 adjust", 0, params.mTopRowAdjustment);
         assertEquals("1 key max 5 R1 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // [1] ___ ___|
+    // <1> ___ ___|
     public void testLayout1KeyMax5R2() {
         MoreKeysKeyboardParams params = createParams(1, 5, XPOS_R2);
         assertEquals("1 key max 5 R2 columns", 1, params.mNumColumns);
         assertEquals("1 key max 5 R2 rows", 1, params.mNumRows);
         assertEquals("1 key max 5 R2 left", 0, params.mLeftKeys);
         assertEquals("1 key max 5 R2 right", 1, params.mRightKeys);
-        assertEquals("1 key max 5 R2 [1]", 0, params.getColumnPos(0));
+        assertEquals("1 key max 5 R2 <1>", 0, params.getColumnPos(0));
         assertEquals("1 key max 5 R2 adjust", 0, params.mTopRowAdjustment);
         assertEquals("1 key max 5 R2 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // [1] [2]
+    // <1> [2]
     public void testLayout2KeyMax5M0() {
         MoreKeysKeyboardParams params = createParams(2, 5, XPOS_M0);
         assertEquals("2 key max 5 M0 columns", 2, params.mNumColumns);
         assertEquals("2 key max 5 M0 rows", 1, params.mNumRows);
         assertEquals("2 key max 5 M0 left", 0, params.mLeftKeys);
         assertEquals("2 key max 5 M0 right", 2, params.mRightKeys);
-        assertEquals("2 key max 5 M0 [1]", 0, params.getColumnPos(0));
+        assertEquals("2 key max 5 M0 <1>", 0, params.getColumnPos(0));
         assertEquals("2 key max 5 M0 [2]", 1, params.getColumnPos(1));
         assertEquals("2 key max 5 M0 adjust", 0, params.mTopRowAdjustment);
         assertEquals("2 key max 5 M0 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // |[1] [2]
+    // |<1> [2]
     public void testLayout2KeyMax5L0() {
         MoreKeysKeyboardParams params = createParams(2, 5, XPOS_L0);
         assertEquals("2 key max 5 L0 columns", 2, params.mNumColumns);
         assertEquals("2 key max 5 L0 rows", 1, params.mNumRows);
         assertEquals("2 key max 5 L0 left", 0, params.mLeftKeys);
         assertEquals("2 key max 5 L0 right", 2, params.mRightKeys);
-        assertEquals("2 key max 5 L0 [1]", 0, params.getColumnPos(0));
+        assertEquals("2 key max 5 L0 <1>", 0, params.getColumnPos(0));
         assertEquals("2 key max 5 L0 [2]", 1, params.getColumnPos(1));
         assertEquals("2 key max 5 L0 adjust", 0, params.mTopRowAdjustment);
         assertEquals("2 key max 5 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // |___ [1] [2]
+    // |___ <1> [2]
     public void testLayout2KeyMax5L1() {
         MoreKeysKeyboardParams params = createParams(2, 5, XPOS_L1);
         assertEquals("2 key max 5 L1 columns", 2, params.mNumColumns);
         assertEquals("2 key max 5 L1 rows", 1, params.mNumRows);
         assertEquals("2 key max 5 L1 left", 0, params.mLeftKeys);
         assertEquals("2 key max 5 L1 right", 2, params.mRightKeys);
-        assertEquals("2 key max 5 L1 [1]", 0, params.getColumnPos(0));
+        assertEquals("2 key max 5 L1 <1>", 0, params.getColumnPos(0));
         assertEquals("2 key max 5 L1 [2]", 1, params.getColumnPos(1));
         assertEquals("2 key max 5 L1 adjust", 0, params.mTopRowAdjustment);
         assertEquals("2 key max 5 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // |___ ___ [1] [2]
+    // |___ ___ <1> [2]
     public void testLayout2KeyMax5L2() {
         MoreKeysKeyboardParams params = createParams(2, 5, XPOS_L2);
         assertEquals("2 key max 5 L2 columns", 2, params.mNumColumns);
         assertEquals("2 key max 5 L2 rows", 1, params.mNumRows);
         assertEquals("2 key max 5 L2 left", 0, params.mLeftKeys);
         assertEquals("2 key max 5 L2 right", 2, params.mRightKeys);
-        assertEquals("2 key max 5 L2 [1]", 0, params.getColumnPos(0));
+        assertEquals("2 key max 5 L2 <1>", 0, params.getColumnPos(0));
         assertEquals("2 key max 5 L2 [2]", 1, params.getColumnPos(1));
         assertEquals("2 key max 5 L2 adjust", 0, params.mTopRowAdjustment);
         assertEquals("2 key max 5 L2 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // [2] [1]|
+    // [2] <1>|
     public void testLayout2KeyMax5R0() {
         MoreKeysKeyboardParams params = createParams(2, 5, XPOS_R0);
         assertEquals("2 key max 5 R0 columns", 2, params.mNumColumns);
         assertEquals("2 key max 5 R0 rows", 1, params.mNumRows);
         assertEquals("2 key max 5 R0 left", 1, params.mLeftKeys);
         assertEquals("2 key max 5 R0 right", 1, params.mRightKeys);
-        assertEquals("2 key max 5 R0 [1]", 0, params.getColumnPos(0));
+        assertEquals("2 key max 5 R0 <1>", 0, params.getColumnPos(0));
         assertEquals("2 key max 5 R0 [2]", -1, params.getColumnPos(1));
         assertEquals("2 key max 5 R0 adjust", 0, params.mTopRowAdjustment);
         assertEquals("2 key max 5 R0 default", WIDTH * 1, params.getDefaultKeyCoordX());
     }
 
-    // [2] [1] ___|
+    // [2] <1> ___|
     public void testLayout2KeyMax5R1() {
         MoreKeysKeyboardParams params = createParams(2, 5, XPOS_R1);
         assertEquals("2 key max 5 R1 columns", 2, params.mNumColumns);
         assertEquals("2 key max 5 R1 rows", 1, params.mNumRows);
         assertEquals("2 key max 5 R1 left", 1, params.mLeftKeys);
         assertEquals("2 key max 5 R1 right", 1, params.mRightKeys);
-        assertEquals("2 key max 5 R1 [1]", 0, params.getColumnPos(0));
+        assertEquals("2 key max 5 R1 <1>", 0, params.getColumnPos(0));
         assertEquals("2 key max 5 R1 [2]", -1, params.getColumnPos(1));
         assertEquals("2 key max 5 R1 adjust", 0, params.mTopRowAdjustment);
         assertEquals("2 key max 5 R1 default", WIDTH * 1, params.getDefaultKeyCoordX());
     }
 
-    // [1] [2] ___|
+    // <1> [2] ___|
     public void testLayout2KeyMax5R2() {
         MoreKeysKeyboardParams params = createParams(2, 5, XPOS_R2);
         assertEquals("2 key max 5 R2 columns", 2, params.mNumColumns);
         assertEquals("2 key max 5 R2 rows", 1, params.mNumRows);
         assertEquals("2 key max 5 R2 left", 0, params.mLeftKeys);
         assertEquals("2 key max 5 R2 right", 2, params.mRightKeys);
-        assertEquals("2 key max 5 R2 [1]", 0, params.getColumnPos(0));
+        assertEquals("2 key max 5 R2 <1>", 0, params.getColumnPos(0));
         assertEquals("2 key max 5 R2 [2]", 1, params.getColumnPos(1));
         assertEquals("2 key max 5 R2 adjust", 0, params.mTopRowAdjustment);
         assertEquals("2 key max 5 R2 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // [3] [1] [2]
+    // [3] <1> [2]
     public void testLayout3KeyMax5M0() {
         MoreKeysKeyboardParams params = createParams(3, 5, XPOS_M0);
-        assertEquals("3 key columns", 3, params.mNumColumns);
-        assertEquals("3 key rows", 1, params.mNumRows);
-        assertEquals("3 key left", 1, params.mLeftKeys);
-        assertEquals("3 key right", 2, params.mRightKeys);
-        assertEquals("3 key [1]", 0, params.getColumnPos(0));
-        assertEquals("3 key [2]", 1, params.getColumnPos(1));
-        assertEquals("3 key [3]", -1, params.getColumnPos(2));
-        assertEquals("3 key adjust", 0, params.mTopRowAdjustment);
-        assertEquals("3 key default", WIDTH * 1, params.getDefaultKeyCoordX());
+        assertEquals("3 key max 5 M0 columns", 3, params.mNumColumns);
+        assertEquals("3 key max 5 M0 rows", 1, params.mNumRows);
+        assertEquals("3 key max 5 M0 left", 1, params.mLeftKeys);
+        assertEquals("3 key max 5 M0 right", 2, params.mRightKeys);
+        assertEquals("3 key max 5 M0 <1>", 0, params.getColumnPos(0));
+        assertEquals("3 key max 5 M0 [2]", 1, params.getColumnPos(1));
+        assertEquals("3 key max 5 M0 [3]", -1, params.getColumnPos(2));
+        assertEquals("3 key max 5 M0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("3 key max 5 M0 default", WIDTH * 1, params.getDefaultKeyCoordX());
     }
 
-    // |[1] [2] [3]
+    // |<1> [2] [3]
     public void testLayout3KeyMax5L0() {
         MoreKeysKeyboardParams params = createParams(3, 5, XPOS_L0);
         assertEquals("3 key max 5 L0 columns", 3, params.mNumColumns);
         assertEquals("3 key max 5 L0 rows", 1, params.mNumRows);
         assertEquals("3 key max 5 L0 left", 0, params.mLeftKeys);
         assertEquals("3 key max 5 L0 right", 3, params.mRightKeys);
-        assertEquals("3 key max 5 L0 [1]", 0, params.getColumnPos(0));
+        assertEquals("3 key max 5 L0 <1>", 0, params.getColumnPos(0));
         assertEquals("3 key max 5 L0 [2]", 1, params.getColumnPos(1));
         assertEquals("3 key max 5 L0 [3]", 2, params.getColumnPos(2));
         assertEquals("3 key max 5 L0 adjust", 0, params.mTopRowAdjustment);
         assertEquals("3 key max 5 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // |___ [1] [2] [3]
+    // |___ <1> [2] [3]
     public void testLayout3KeyMax5L1() {
         MoreKeysKeyboardParams params = createParams(3, 5, XPOS_L1);
         assertEquals("3 key max 5 L1 columns", 3, params.mNumColumns);
         assertEquals("3 key max 5 L1 rows", 1, params.mNumRows);
         assertEquals("3 key max 5 L1 left", 0, params.mLeftKeys);
         assertEquals("3 key max 5 L1 right", 3, params.mRightKeys);
-        assertEquals("3 key max 5 L1 [1]", 0, params.getColumnPos(0));
+        assertEquals("3 key max 5 L1 <1>", 0, params.getColumnPos(0));
         assertEquals("3 key max 5 L1 [2]", 1, params.getColumnPos(1));
         assertEquals("3 key max 5 L1 [3]", 2, params.getColumnPos(2));
         assertEquals("3 key max 5 L1 adjust", 0, params.mTopRowAdjustment);
         assertEquals("3 key max 5 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // |___ [3] [1] [2]
+    // |___ [3] <1> [2]
     public void testLayout3KeyMax5L2() {
         MoreKeysKeyboardParams params = createParams(3, 5, XPOS_L2);
         assertEquals("3 key max 5 L2 columns", 3, params.mNumColumns);
         assertEquals("3 key max 5 L2 rows", 1, params.mNumRows);
         assertEquals("3 key max 5 L2 left", 1, params.mLeftKeys);
         assertEquals("3 key max 5 L2 right", 2, params.mRightKeys);
-        assertEquals("3 key max 5 L2 [1]", 0, params.getColumnPos(0));
+        assertEquals("3 key max 5 L2 <1>", 0, params.getColumnPos(0));
         assertEquals("3 key max 5 L2 [2]", 1, params.getColumnPos(1));
         assertEquals("3 key max 5 L2 [3]", -1, params.getColumnPos(2));
         assertEquals("3 key max 5 L2 adjust", 0, params.mTopRowAdjustment);
         assertEquals("3 key max 5 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
     }
 
-    // [3] [2] [1]|
+    // [3] [2] <1>|
     public void testLayout3KeyMax5R0() {
         MoreKeysKeyboardParams params = createParams(3, 5, XPOS_R0);
         assertEquals("3 key max 5 R0 columns", 3, params.mNumColumns);
         assertEquals("3 key max 5 R0 rows", 1, params.mNumRows);
         assertEquals("3 key max 5 R0 left", 2, params.mLeftKeys);
         assertEquals("3 key max 5 R0 right", 1, params.mRightKeys);
-        assertEquals("3 key max 5 R0 [1]", 0, params.getColumnPos(0));
+        assertEquals("3 key max 5 R0 <1>", 0, params.getColumnPos(0));
         assertEquals("3 key max 5 R0 [2]", -1, params.getColumnPos(1));
         assertEquals("3 key max 5 R0 [3]", -2, params.getColumnPos(2));
         assertEquals("3 key max 5 R0 adjust", 0, params.mTopRowAdjustment);
         assertEquals("3 key max 5 R0 default", WIDTH * 2, params.getDefaultKeyCoordX());
     }
 
-    // [3] [2] [1] ___|
+    // [3] [2] <1> ___|
     public void testLayout3KeyMax5R1() {
         MoreKeysKeyboardParams params = createParams(3, 5, XPOS_R1);
         assertEquals("3 key max 5 R1 columns", 3, params.mNumColumns);
         assertEquals("3 key max 5 R1 rows", 1, params.mNumRows);
         assertEquals("3 key max 5 R1 left", 2, params.mLeftKeys);
         assertEquals("3 key max 5 R1 right", 1, params.mRightKeys);
-        assertEquals("3 key max 5 R1 [1]", 0, params.getColumnPos(0));
+        assertEquals("3 key max 5 R1 <1>", 0, params.getColumnPos(0));
         assertEquals("3 key max 5 R1 [2]", -1, params.getColumnPos(1));
         assertEquals("3 key max 5 R1 [3]", -2, params.getColumnPos(2));
         assertEquals("3 key max 5 R1 adjust", 0, params.mTopRowAdjustment);
         assertEquals("3 key max 5 R1 default", WIDTH * 2, params.getDefaultKeyCoordX());
     }
 
-    // [3] [1] [2] ___|
+    // [3] <1> [2] ___|
     public void testLayout3KeyMax5R2() {
         MoreKeysKeyboardParams params = createParams(3, 5, XPOS_R2);
         assertEquals("3 key max 5 R2 columns", 3, params.mNumColumns);
         assertEquals("3 key max 5 R2 rows", 1, params.mNumRows);
         assertEquals("3 key max 5 R2 left", 1, params.mLeftKeys);
         assertEquals("3 key max 5 R2 right", 2, params.mRightKeys);
-        assertEquals("3 key max 5 R2 [1]", 0, params.getColumnPos(0));
+        assertEquals("3 key max 5 R2 <1>", 0, params.getColumnPos(0));
         assertEquals("3 key max 5 R2 [2]", 1, params.getColumnPos(1));
         assertEquals("3 key max 5 R2 [3]", -1, params.getColumnPos(2));
         assertEquals("3 key max 5 R2 adjust", 0, params.mTopRowAdjustment);
         assertEquals("3 key max 5 R2 default", WIDTH * 1, params.getDefaultKeyCoordX());
     }
 
-    //   [3]
-    // [1] [2]
+    // [3]
+    // <1> [2]
     public void testLayout3KeyMax2M0() {
         MoreKeysKeyboardParams params = createParams(3, 2, XPOS_M0);
-        assertEquals("3 key max 2 columns", 2, params.mNumColumns);
-        assertEquals("3 key max 2 rows", 2, params.mNumRows);
-        assertEquals("3 key max 2 left", 0, params.mLeftKeys);
-        assertEquals("3 key max 2 right", 2, params.mRightKeys);
-        assertEquals("3 key max 2 [1]", 0, params.getColumnPos(0));
-        assertEquals("3 key max 2 [2]", 1, params.getColumnPos(1));
-        assertEquals("3 key max 2 [3]", 0, params.getColumnPos(2));
-        assertEquals("3 key max 2 adjust", 1, params.mTopRowAdjustment);
-        assertEquals("3 key max 2 default", WIDTH * 0, params.getDefaultKeyCoordX());
+        assertEquals("3 key max 2 M0 columns", 2, params.mNumColumns);
+        assertEquals("3 key max 2 M0 rows", 2, params.mNumRows);
+        assertEquals("3 key max 2 M0 left", 0, params.mLeftKeys);
+        assertEquals("3 key max 2 M0 right", 2, params.mRightKeys);
+        assertEquals("3 key max 2 M0 <1>", 0, params.getColumnPos(0));
+        assertEquals("3 key max 2 M0 [2]", 1, params.getColumnPos(1));
+        assertEquals("3 key max 2 M0 [3]", 0, params.getColumnPos(2));
+        assertEquals("3 key max 2 M0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("3 key max 2 M0 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // |  [3]
-    // |[1] [2]
+    // |[3]
+    // |<1> [2]
     public void testLayout3KeyMax2L0() {
         MoreKeysKeyboardParams params = createParams(3, 2, XPOS_L0);
         assertEquals("3 key max 2 L0 columns", 2, params.mNumColumns);
         assertEquals("3 key max 2 L0 rows", 2, params.mNumRows);
         assertEquals("3 key max 2 L0 left", 0, params.mLeftKeys);
         assertEquals("3 key max 2 L0 right", 2, params.mRightKeys);
-        assertEquals("3 key max 2 L0 [1]", 0, params.getColumnPos(0));
+        assertEquals("3 key max 2 L0 <1>", 0, params.getColumnPos(0));
         assertEquals("3 key max 2 L0 [2]", 1, params.getColumnPos(1));
         assertEquals("3 key max 2 L0 [3]", 0, params.getColumnPos(2));
-        assertEquals("3 key max 2 L0 adjust", 1, params.mTopRowAdjustment);
+        assertEquals("3 key max 2 L0 adjust", 0, params.mTopRowAdjustment);
         assertEquals("3 key max 2 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // |___   [3]
-    // |___ [1] [2]
+    // |___ [3]
+    // |___ <1> [2]
     public void testLayout3KeyMax2L1() {
         MoreKeysKeyboardParams params = createParams(3, 2, XPOS_L1);
         assertEquals("3 key max 2 L1 columns", 2, params.mNumColumns);
         assertEquals("3 key max 2 L1 rows", 2, params.mNumRows);
         assertEquals("3 key max 2 L1 left", 0, params.mLeftKeys);
         assertEquals("3 key max 2 L1 right", 2, params.mRightKeys);
-        assertEquals("3 key max 2 L1 [1]", 0, params.getColumnPos(0));
+        assertEquals("3 key max 2 L1 <1>", 0, params.getColumnPos(0));
         assertEquals("3 key max 2 L1 [2]", 1, params.getColumnPos(1));
         assertEquals("3 key max 2 L1 [3]", 0, params.getColumnPos(2));
-        assertEquals("3 key max 2 L1 adjust", 1, params.mTopRowAdjustment);
+        assertEquals("3 key max 2 L1 adjust", 0, params.mTopRowAdjustment);
         assertEquals("3 key max 2 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // |          [3]
-    // |___ ___ [1] [2]
+    // |        [3]
+    // |___ ___ <1> [2]
     public void testLayout3KeyMax2L2() {
         MoreKeysKeyboardParams params = createParams(3, 2, XPOS_L2);
         assertEquals("3 key max 2 L2 columns", 2, params.mNumColumns);
         assertEquals("3 key max 2 L2 rows", 2, params.mNumRows);
         assertEquals("3 key max 2 L2 left", 0, params.mLeftKeys);
         assertEquals("3 key max 2 L2 right", 2, params.mRightKeys);
-        assertEquals("3 key max 2 L2 [1]", 0, params.getColumnPos(0));
+        assertEquals("3 key max 2 L2 <1>", 0, params.getColumnPos(0));
         assertEquals("3 key max 2 L2 [2]", 1, params.getColumnPos(1));
         assertEquals("3 key max 2 L2 [3]", 0, params.getColumnPos(2));
-        assertEquals("3 key max 2 L2 adjust", 1, params.mTopRowAdjustment);
+        assertEquals("3 key max 2 L2 adjust", 0, params.mTopRowAdjustment);
         assertEquals("3 key max 2 L2 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    //   [3]  |
-    // [2] [1]|
+    //     [3]|
+    // [2] <1>|
     public void testLayout3KeyMax2R0() {
         MoreKeysKeyboardParams params = createParams(3, 2, XPOS_R0);
         assertEquals("3 key max 2 R0 columns", 2, params.mNumColumns);
         assertEquals("3 key max 2 R0 rows", 2, params.mNumRows);
         assertEquals("3 key max 2 R0 left", 1, params.mLeftKeys);
         assertEquals("3 key max 2 R0 right", 1, params.mRightKeys);
-        assertEquals("3 key max 2 R0 [1]", 0, params.getColumnPos(0));
+        assertEquals("3 key max 2 R0 <1>", 0, params.getColumnPos(0));
         assertEquals("3 key max 2 R0 [2]", -1, params.getColumnPos(1));
         assertEquals("3 key max 2 R0 [3]", 0, params.getColumnPos(2));
-        assertEquals("3 key max 2 R0 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("3 key max 2 R0 adjust", 0, params.mTopRowAdjustment);
         assertEquals("3 key max 2 R0 default", WIDTH * 1, params.getDefaultKeyCoordX());
     }
 
-    //   [3]      |
-    // [2] [1] ___|
+    //     [3]    |
+    // [2] <1> ___|
     public void testLayout3KeyMax2R1() {
         MoreKeysKeyboardParams params = createParams(3, 2, XPOS_R1);
         assertEquals("3 key max 2 R1 columns", 2, params.mNumColumns);
         assertEquals("3 key max 2 R1 rows", 2, params.mNumRows);
         assertEquals("3 key max 2 R1 left", 1, params.mLeftKeys);
         assertEquals("3 key max 2 R1 right", 1, params.mRightKeys);
-        assertEquals("3 key max 2 R1 [1]", 0, params.getColumnPos(0));
+        assertEquals("3 key max 2 R1 <1>", 0, params.getColumnPos(0));
         assertEquals("3 key max 2 R1 [2]", -1, params.getColumnPos(1));
         assertEquals("3 key max 2 R1 [3]", 0, params.getColumnPos(2));
-        assertEquals("3 key max 2 R1 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("3 key max 2 R1 adjust", 0, params.mTopRowAdjustment);
         assertEquals("3 key max 2 R1 default", WIDTH * 1, params.getDefaultKeyCoordX());
     }
 
-    //   [3]      |
-    // [1] [2] ___|
+    // [3]        |
+    // <1> [2] ___|
     public void testLayout3KeyMax2R2() {
         MoreKeysKeyboardParams params = createParams(3, 2, XPOS_R2);
         assertEquals("3 key max 2 R2 columns", 2, params.mNumColumns);
         assertEquals("3 key max 2 R2 rows", 2, params.mNumRows);
         assertEquals("3 key max 2 R2 left", 0, params.mLeftKeys);
         assertEquals("3 key max 2 R2 right", 2, params.mRightKeys);
-        assertEquals("3 key max 2 R2 [1]", 0, params.getColumnPos(0));
+        assertEquals("3 key max 2 R2 <1>", 0, params.getColumnPos(0));
         assertEquals("3 key max 2 R2 [2]", 1, params.getColumnPos(1));
         assertEquals("3 key max 2 R2 [3]", 0, params.getColumnPos(2));
-        assertEquals("3 key max 2 R2 adjust", 1, params.mTopRowAdjustment);
+        assertEquals("3 key max 2 R2 adjust", 0, params.mTopRowAdjustment);
         assertEquals("3 key max 2 R2 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // [3] [1] [2] [4]
-    public void testLayout4KeyMax5M0() {
-        MoreKeysKeyboardParams params = createParams(4, 5, XPOS_M0);
-        assertEquals("4 key columns", 4, params.mNumColumns);
-        assertEquals("4 key rows", 1, params.mNumRows);
-        assertEquals("4 key left", 1, params.mLeftKeys);
-        assertEquals("4 key right", 3, params.mRightKeys);
-        assertEquals("4 key [1]", 0, params.getColumnPos(0));
-        assertEquals("4 key [2]", 1, params.getColumnPos(1));
-        assertEquals("4 key [3]", -1, params.getColumnPos(2));
-        assertEquals("4 key [4]", 2, params.getColumnPos(3));
-        assertEquals("4 key adjust", 0, params.mTopRowAdjustment);
-        assertEquals("4 key default", WIDTH * 1, params.getDefaultKeyCoordX());
+    // [3] [4]
+    // <1> [2]
+    public void testLayout4KeyMax3M0() {
+        MoreKeysKeyboardParams params = createParams(4, 3, XPOS_M0);
+        assertEquals("4 key max 3 M0 columns", 2, params.mNumColumns);
+        assertEquals("4 key max 3 M0 rows", 2, params.mNumRows);
+        assertEquals("4 key max 3 M0 left", 0, params.mLeftKeys);
+        assertEquals("4 key max 3 M0 right", 2, params.mRightKeys);
+        assertEquals("4 key max 3 M0 <1>", 0, params.getColumnPos(0));
+        assertEquals("4 key max 3 M0 [2]", 1, params.getColumnPos(1));
+        assertEquals("4 key max 3 M0 [3]", 0, params.getColumnPos(2));
+        assertEquals("4 key max 3 M0 [4]", 1, params.getColumnPos(3));
+        assertEquals("4 key max 3 M0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key max 3 M0 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // |[1] [2] [3] [4]
+    // |[3] [4]
+    // |<1> [2]
+    public void testLayout4KeyMax3L0() {
+        MoreKeysKeyboardParams params = createParams(4, 3, XPOS_L0);
+        assertEquals("4 key max 3 L0 columns", 2, params.mNumColumns);
+        assertEquals("4 key max 3 L0 rows", 2, params.mNumRows);
+        assertEquals("4 key max 3 L0 left", 0, params.mLeftKeys);
+        assertEquals("4 key max 3 L0 right", 2, params.mRightKeys);
+        assertEquals("4 key max 3 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("4 key max 3 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("4 key max 3 L0 [3]", 0, params.getColumnPos(2));
+        assertEquals("4 key max 3 L0 [4]", 1, params.getColumnPos(3));
+        assertEquals("4 key max 3 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key max 3 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [3] [4]
+    // |___ <1> [2]
+    public void testLayout4KeyMax3L1() {
+        MoreKeysKeyboardParams params = createParams(4, 3, XPOS_L1);
+        assertEquals("4 key max 3 L1 columns", 2, params.mNumColumns);
+        assertEquals("4 key max 3 L1 rows", 2, params.mNumRows);
+        assertEquals("4 key max 3 L1 left", 0, params.mLeftKeys);
+        assertEquals("4 key max 3 L1 right", 2, params.mRightKeys);
+        assertEquals("4 key max 3 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("4 key max 3 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("4 key max 3 L1 [3]", 0, params.getColumnPos(2));
+        assertEquals("4 key max 3 L1 [4]", 1, params.getColumnPos(3));
+        assertEquals("4 key max 3 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key max 3 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ ___ [3] [4]
+    // |___ ___ <1> [2]
+    public void testLayout4KeyMax3L2() {
+        MoreKeysKeyboardParams params = createParams(4, 3, XPOS_L2);
+        assertEquals("4 key max 3 L2 columns", 2, params.mNumColumns);
+        assertEquals("4 key max 3 L2 rows", 2, params.mNumRows);
+        assertEquals("4 key max 3 L2 left", 0, params.mLeftKeys);
+        assertEquals("4 key max 3 L2 right", 2, params.mRightKeys);
+        assertEquals("4 key max 3 L2 <1>", 0, params.getColumnPos(0));
+        assertEquals("4 key max 3 L2 [2]", 1, params.getColumnPos(1));
+        assertEquals("4 key max 3 L2 [3]", 0, params.getColumnPos(2));
+        assertEquals("4 key max 3 L2 [4]", 1, params.getColumnPos(3));
+        assertEquals("4 key max 3 L2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key max 3 L2 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // [4] [3]|
+    // [2] <1>|
+    public void testLayout4KeyMax3R0() {
+        MoreKeysKeyboardParams params = createParams(4, 3, XPOS_R0);
+        assertEquals("4 key max 3 R0 columns", 2, params.mNumColumns);
+        assertEquals("4 key max 3 R0 rows", 2, params.mNumRows);
+        assertEquals("4 key max 3 R0 left", 1, params.mLeftKeys);
+        assertEquals("4 key max 3 R0 right", 1, params.mRightKeys);
+        assertEquals("4 key max 3 R0 <1>", 0, params.getColumnPos(0));
+        assertEquals("4 key max 3 R0 [2]", -1, params.getColumnPos(1));
+        assertEquals("4 key max 3 R0 [3]", 0, params.getColumnPos(2));
+        assertEquals("4 key max 3 R0 [4]", -1, params.getColumnPos(3));
+        assertEquals("4 key max 3 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key max 3 R0 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // [4] [3] ___|
+    // [2] <1> ___|
+    public void testLayout4KeyMax3R1() {
+        MoreKeysKeyboardParams params = createParams(4, 3, XPOS_R1);
+        assertEquals("4 key max 3 R1 columns", 2, params.mNumColumns);
+        assertEquals("4 key max 3 R1 rows", 2, params.mNumRows);
+        assertEquals("4 key max 3 R1 left", 1, params.mLeftKeys);
+        assertEquals("4 key max 3 R1 right", 1, params.mRightKeys);
+        assertEquals("4 key max 3 R1 <1>", 0, params.getColumnPos(0));
+        assertEquals("4 key max 3 R1 [2]", -1, params.getColumnPos(1));
+        assertEquals("4 key max 3 R1 [3]", 0, params.getColumnPos(2));
+        assertEquals("4 key max 3 R1 [4]", -1, params.getColumnPos(3));
+        assertEquals("4 key max 3 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key max 3 R1 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // [3] [4] ___|
+    // <1> [2] ___|
+    public void testLayout4KeyMax3R2() {
+        MoreKeysKeyboardParams params = createParams(4, 3, XPOS_R2);
+        assertEquals("4 key max 3 R2 columns", 2, params.mNumColumns);
+        assertEquals("4 key max 3 R2 rows", 2, params.mNumRows);
+        assertEquals("4 key max 3 R2 left", 0, params.mLeftKeys);
+        assertEquals("4 key max 3 R2 right", 2, params.mRightKeys);
+        assertEquals("4 key max 3 R2 <1>", 0, params.getColumnPos(0));
+        assertEquals("4 key max 3 R2 [2]", 1, params.getColumnPos(1));
+        assertEquals("4 key max 3 R2 [3]", 0, params.getColumnPos(2));
+        assertEquals("4 key max 3 R2 [4]", 1, params.getColumnPos(3));
+        assertEquals("4 key max 3 R2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key max 3 R2 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // [3] <1> [2] [4]
+    public void testLayout4KeyMax4M0() {
+        MoreKeysKeyboardParams params = createParams(4, 4, XPOS_M0);
+        assertEquals("4 key max 4 M0 columns", 4, params.mNumColumns);
+        assertEquals("4 key max 4 M0 rows", 1, params.mNumRows);
+        assertEquals("4 key max 4 M0 left", 1, params.mLeftKeys);
+        assertEquals("4 key max 4 M0 right", 3, params.mRightKeys);
+        assertEquals("4 key max 4 M0 <1>", 0, params.getColumnPos(0));
+        assertEquals("4 key max 4 M0 [2]", 1, params.getColumnPos(1));
+        assertEquals("4 key max 4 M0 [3]", -1, params.getColumnPos(2));
+        assertEquals("4 key max 4 M0 [4]", 2, params.getColumnPos(3));
+        assertEquals("4 key max 4 M0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key max 4 M0 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // |<1> [2] [3] [4]
+    public void testLayout4KeyMax4L0() {
+        MoreKeysKeyboardParams params = createParams(4, 4, XPOS_L0);
+        assertEquals("4 key max 4 L0 columns", 4, params.mNumColumns);
+        assertEquals("4 key max 4 L0 rows", 1, params.mNumRows);
+        assertEquals("4 key max 4 L0 left", 0, params.mLeftKeys);
+        assertEquals("4 key max 4 L0 right", 4, params.mRightKeys);
+        assertEquals("4 key max 4 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("4 key max 4 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("4 key max 4 L0 [3]", 2, params.getColumnPos(2));
+        assertEquals("4 key max 4 L0 [4]", 3, params.getColumnPos(3));
+        assertEquals("4 key max 4 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key max 4 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ <1> [2] [3] [4]
+    public void testLayout4KeyMax4L1() {
+        MoreKeysKeyboardParams params = createParams(4, 4, XPOS_L1);
+        assertEquals("4 key max 4 L1 columns", 4, params.mNumColumns);
+        assertEquals("4 key max 4 L1 rows", 1, params.mNumRows);
+        assertEquals("4 key max 4 L1 left", 0, params.mLeftKeys);
+        assertEquals("4 key max 4 L1 right", 4, params.mRightKeys);
+        assertEquals("4 key max 4 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("4 key max 4 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("4 key max 4 L1 [3]", 2, params.getColumnPos(2));
+        assertEquals("4 key max 4 L1 [4]", 3, params.getColumnPos(3));
+        assertEquals("4 key max 4 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key max 4 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [3] <1> [2] [4]
+    public void testLayout4KeyMax4L2() {
+        MoreKeysKeyboardParams params = createParams(4, 4, XPOS_L2);
+        assertEquals("4 key max 4 L2 columns", 4, params.mNumColumns);
+        assertEquals("4 key max 4 L2 rows", 1, params.mNumRows);
+        assertEquals("4 key max 4 L2 left", 1, params.mLeftKeys);
+        assertEquals("4 key max 4 L2 right", 3, params.mRightKeys);
+        assertEquals("4 key max 4 L2 <1>", 0, params.getColumnPos(0));
+        assertEquals("4 key max 4 L2 [2]", 1, params.getColumnPos(1));
+        assertEquals("4 key max 4 L2 [3]", -1, params.getColumnPos(2));
+        assertEquals("4 key max 4 L2 [4]", 2, params.getColumnPos(3));
+        assertEquals("4 key max 4 L2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key max 4 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // [4] [3] [2] <1>|
+    public void testLayout4KeyMax4R0() {
+        MoreKeysKeyboardParams params = createParams(4, 4, XPOS_R0);
+        assertEquals("4 key max 4 R0 columns", 4, params.mNumColumns);
+        assertEquals("4 key max 4 R0 rows", 1, params.mNumRows);
+        assertEquals("4 key max 4 R0 left", 3, params.mLeftKeys);
+        assertEquals("4 key max 4 R0 right", 1, params.mRightKeys);
+        assertEquals("4 key max 4 R0 <1>", 0, params.getColumnPos(0));
+        assertEquals("4 key max 4 R0 [2]", -1, params.getColumnPos(1));
+        assertEquals("4 key max 4 R0 [3]", -2, params.getColumnPos(2));
+        assertEquals("4 key max 4 R0 [4]", -3, params.getColumnPos(3));
+        assertEquals("4 key max 4 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key max 4 R0 default", WIDTH * 3, params.getDefaultKeyCoordX());
+    }
+
+    // [4] [3] [2] <1> ___|
+    public void testLayout4KeyMax4R1() {
+        MoreKeysKeyboardParams params = createParams(4, 4, XPOS_R1);
+        assertEquals("4 key max 4 R1 columns", 4, params.mNumColumns);
+        assertEquals("4 key max 4 R1 rows", 1, params.mNumRows);
+        assertEquals("4 key max 4 R1 left", 3, params.mLeftKeys);
+        assertEquals("4 key max 4 R1 right", 1, params.mRightKeys);
+        assertEquals("4 key max 4 R1 <1>", 0, params.getColumnPos(0));
+        assertEquals("4 key max 4 R1 [2]", -1, params.getColumnPos(1));
+        assertEquals("4 key max 4 R1 [3]", -2, params.getColumnPos(2));
+        assertEquals("4 key max 4 R1 [4]", -3, params.getColumnPos(3));
+        assertEquals("4 key max 4 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key max 4 R1 default", WIDTH * 3, params.getDefaultKeyCoordX());
+    }
+
+    // [4] [3] <1> [2] ___|
+    public void testLayout4KeyMax4R2() {
+        MoreKeysKeyboardParams params = createParams(4, 4, XPOS_R2);
+        assertEquals("4 key max 4 R2 columns", 4, params.mNumColumns);
+        assertEquals("4 key max 4 R2 rows", 1, params.mNumRows);
+        assertEquals("4 key max 4 R2 left", 2, params.mLeftKeys);
+        assertEquals("4 key max 4 R2 right", 2, params.mRightKeys);
+        assertEquals("4 key max 4 R2 <1>", 0, params.getColumnPos(0));
+        assertEquals("4 key max 4 R2 [2]", 1, params.getColumnPos(1));
+        assertEquals("4 key max 4 R2 [3]", -1, params.getColumnPos(2));
+        assertEquals("4 key max 4 R2 [4]", -2, params.getColumnPos(3));
+        assertEquals("4 key max 4 R2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key max 4 R2 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    // [3] <1> [2] [4]
+    public void testLayout4KeyMax5M0() {
+        MoreKeysKeyboardParams params = createParams(4, 5, XPOS_M0);
+        assertEquals("4 key max 5 M0 columns", 4, params.mNumColumns);
+        assertEquals("4 key max 5 M0 rows", 1, params.mNumRows);
+        assertEquals("4 key max 5 M0 left", 1, params.mLeftKeys);
+        assertEquals("4 key max 5 M0 right", 3, params.mRightKeys);
+        assertEquals("4 key max 5 M0 <1>", 0, params.getColumnPos(0));
+        assertEquals("4 key max 5 M0 [2]", 1, params.getColumnPos(1));
+        assertEquals("4 key max 5 M0 [3]", -1, params.getColumnPos(2));
+        assertEquals("4 key max 5 M0 [4]", 2, params.getColumnPos(3));
+        assertEquals("4 key max 5 M0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("4 key max 5 M0 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // |<1> [2] [3] [4]
     public void testLayout4KeyMax5L0() {
         MoreKeysKeyboardParams params = createParams(4, 5, XPOS_L0);
         assertEquals("4 key max 5 L0 columns", 4, params.mNumColumns);
         assertEquals("4 key max 5 L0 rows", 1, params.mNumRows);
         assertEquals("4 key max 5 L0 left", 0, params.mLeftKeys);
         assertEquals("4 key max 5 L0 right", 4, params.mRightKeys);
-        assertEquals("4 key max 5 L0 [1]", 0, params.getColumnPos(0));
+        assertEquals("4 key max 5 L0 <1>", 0, params.getColumnPos(0));
         assertEquals("4 key max 5 L0 [2]", 1, params.getColumnPos(1));
         assertEquals("4 key max 5 L0 [3]", 2, params.getColumnPos(2));
         assertEquals("4 key max 5 L0 [4]", 3, params.getColumnPos(3));
@@ -471,14 +688,14 @@
         assertEquals("4 key max 5 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // |___ [1] [2] [3] [4]
+    // |___ <1> [2] [3] [4]
     public void testLayout4KeyMax5L1() {
         MoreKeysKeyboardParams params = createParams(4, 5, XPOS_L1);
         assertEquals("4 key max 5 L1 columns", 4, params.mNumColumns);
         assertEquals("4 key max 5 L1 rows", 1, params.mNumRows);
         assertEquals("4 key max 5 L1 left", 0, params.mLeftKeys);
         assertEquals("4 key max 5 L1 right", 4, params.mRightKeys);
-        assertEquals("4 key max 5 L1 [1]", 0, params.getColumnPos(0));
+        assertEquals("4 key max 5 L1 <1>", 0, params.getColumnPos(0));
         assertEquals("4 key max 5 L1 [2]", 1, params.getColumnPos(1));
         assertEquals("4 key max 5 L1 [3]", 2, params.getColumnPos(2));
         assertEquals("4 key max 5 L1 [4]", 3, params.getColumnPos(3));
@@ -486,14 +703,14 @@
         assertEquals("4 key max 5 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // |___ [3] [1] [2] [4]
+    // |___ [3] <1> [2] [4]
     public void testLayout4KeyMax5L2() {
         MoreKeysKeyboardParams params = createParams(4, 5, XPOS_L2);
         assertEquals("4 key max 5 L2 columns", 4, params.mNumColumns);
         assertEquals("4 key max 5 L2 rows", 1, params.mNumRows);
         assertEquals("4 key max 5 L2 left", 1, params.mLeftKeys);
         assertEquals("4 key max 5 L2 right", 3, params.mRightKeys);
-        assertEquals("4 key max 5 L2 [1]", 0, params.getColumnPos(0));
+        assertEquals("4 key max 5 L2 <1>", 0, params.getColumnPos(0));
         assertEquals("4 key max 5 L2 [2]", 1, params.getColumnPos(1));
         assertEquals("4 key max 5 L2 [3]", -1, params.getColumnPos(2));
         assertEquals("4 key max 5 L2 [4]", 2, params.getColumnPos(3));
@@ -501,14 +718,14 @@
         assertEquals("4 key max 5 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
     }
 
-    // [4] [3] [2] [1]|
+    // [4] [3] [2] <1>|
     public void testLayout4KeyMax5R0() {
         MoreKeysKeyboardParams params = createParams(4, 5, XPOS_R0);
         assertEquals("4 key max 5 R0 columns", 4, params.mNumColumns);
         assertEquals("4 key max 5 R0 rows", 1, params.mNumRows);
         assertEquals("4 key max 5 R0 left", 3, params.mLeftKeys);
         assertEquals("4 key max 5 R0 right", 1, params.mRightKeys);
-        assertEquals("4 key max 5 R0 [1]", 0, params.getColumnPos(0));
+        assertEquals("4 key max 5 R0 <1>", 0, params.getColumnPos(0));
         assertEquals("4 key max 5 R0 [2]", -1, params.getColumnPos(1));
         assertEquals("4 key max 5 R0 [3]", -2, params.getColumnPos(2));
         assertEquals("4 key max 5 R0 [4]", -3, params.getColumnPos(3));
@@ -516,14 +733,14 @@
         assertEquals("4 key max 5 R0 default", WIDTH * 3, params.getDefaultKeyCoordX());
     }
 
-    // [4] [3] [2] [1] ___|
+    // [4] [3] [2] <1> ___|
     public void testLayout4KeyMax5R1() {
         MoreKeysKeyboardParams params = createParams(4, 5, XPOS_R1);
         assertEquals("4 key max 5 R1 columns", 4, params.mNumColumns);
         assertEquals("4 key max 5 R1 rows", 1, params.mNumRows);
         assertEquals("4 key max 5 R1 left", 3, params.mLeftKeys);
         assertEquals("4 key max 5 R1 right", 1, params.mRightKeys);
-        assertEquals("4 key max 5 R1 [1]", 0, params.getColumnPos(0));
+        assertEquals("4 key max 5 R1 <1>", 0, params.getColumnPos(0));
         assertEquals("4 key max 5 R1 [2]", -1, params.getColumnPos(1));
         assertEquals("4 key max 5 R1 [3]", -2, params.getColumnPos(2));
         assertEquals("4 key max 5 R1 [4]", -3, params.getColumnPos(3));
@@ -531,14 +748,14 @@
         assertEquals("4 key max 5 R1 default", WIDTH * 3, params.getDefaultKeyCoordX());
     }
 
-    // [4] [3] [1] [2] ___|
+    // [4] [3] <1> [2] ___|
     public void testLayout4KeyMax5R2() {
         MoreKeysKeyboardParams params = createParams(4, 5, XPOS_R2);
         assertEquals("4 key max 5 R2 columns", 4, params.mNumColumns);
         assertEquals("4 key max 5 R2 rows", 1, params.mNumRows);
         assertEquals("4 key max 5 R2 left", 2, params.mLeftKeys);
         assertEquals("4 key max 5 R2 right", 2, params.mRightKeys);
-        assertEquals("4 key max 5 R2 [1]", 0, params.getColumnPos(0));
+        assertEquals("4 key max 5 R2 <1>", 0, params.getColumnPos(0));
         assertEquals("4 key max 5 R2 [2]", 1, params.getColumnPos(1));
         assertEquals("4 key max 5 R2 [3]", -1, params.getColumnPos(2));
         assertEquals("4 key max 5 R2 [4]", -2, params.getColumnPos(3));
@@ -546,30 +763,268 @@
         assertEquals("4 key max 5 R2 default", WIDTH * 2, params.getDefaultKeyCoordX());
     }
 
-    // [5] [3] [1] [2] [4]
-    public void testLayout5KeyMax5M0() {
-        MoreKeysKeyboardParams params = createParams(5, 5, XPOS_M0);
-        assertEquals("5 key columns", 5, params.mNumColumns);
-        assertEquals("5 key rows", 1, params.mNumRows);
-        assertEquals("5 key left", 2, params.mLeftKeys);
-        assertEquals("5 key right", 3, params.mRightKeys);
-        assertEquals("5 key [1]", 0, params.getColumnPos(0));
-        assertEquals("5 key [2]", 1, params.getColumnPos(1));
-        assertEquals("5 key [3]", -1, params.getColumnPos(2));
-        assertEquals("5 key [4]", 2, params.getColumnPos(3));
-        assertEquals("5 key [5]", -2, params.getColumnPos(4));
-        assertEquals("5 key adjust", 0, params.mTopRowAdjustment);
-        assertEquals("5 key default", WIDTH * 2, params.getDefaultKeyCoordX());
+    //   [4] [5]
+    // [3] <1> [2]
+    public void testLayout5KeyMax3M0() {
+        MoreKeysKeyboardParams params = createParams(5, 3, XPOS_M0);
+        assertEquals("5 key max 3 M0 columns", 3, params.mNumColumns);
+        assertEquals("5 key max 3 M0 rows", 2, params.mNumRows);
+        assertEquals("5 key max 3 M0 left", 1, params.mLeftKeys);
+        assertEquals("5 key max 3 M0 right", 2, params.mRightKeys);
+        assertEquals("5 key max 3 M0 <1>", 0, params.getColumnPos(0));
+        assertEquals("5 key max 3 M0 [2]", 1, params.getColumnPos(1));
+        assertEquals("5 key max 3 M0 [3]", -1, params.getColumnPos(2));
+        assertEquals("5 key max 3 M0 [4]", 0, params.getColumnPos(3));
+        assertEquals("5 key max 3 M0 [5]", 1, params.getColumnPos(4));
+        assertEquals("5 key max 3 M0 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("5 key max 3 M0 default", WIDTH * 1, params.getDefaultKeyCoordX());
     }
 
-    // |[1] [2] [3] [4] [5]
+    // |[4] [5]
+    // |<1> [2] [3]
+    public void testLayout5KeyMax3L0() {
+        MoreKeysKeyboardParams params = createParams(5, 3, XPOS_L0);
+        assertEquals("5 key max 3 L0 columns", 3, params.mNumColumns);
+        assertEquals("5 key max 3 L0 rows", 2, params.mNumRows);
+        assertEquals("5 key max 3 L0 left", 0, params.mLeftKeys);
+        assertEquals("5 key max 3 L0 right", 3, params.mRightKeys);
+        assertEquals("5 key max 3 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("5 key max 3 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("5 key max 3 L0 [3]", 2, params.getColumnPos(2));
+        assertEquals("5 key max 3 L0 [4]", 0, params.getColumnPos(3));
+        assertEquals("5 key max 3 L0 [5]", 1, params.getColumnPos(4));
+        assertEquals("5 key max 3 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key max 3 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [4] [5]
+    // |___ <1> [2] [3]
+    public void testLayout5KeyMax3L1() {
+        MoreKeysKeyboardParams params = createParams(5, 3, XPOS_L1);
+        assertEquals("5 key max 3 L1 columns", 3, params.mNumColumns);
+        assertEquals("5 key max 3 L1 rows", 2, params.mNumRows);
+        assertEquals("5 key max 3 L1 left", 0, params.mLeftKeys);
+        assertEquals("5 key max 3 L1 right", 3, params.mRightKeys);
+        assertEquals("5 key max 3 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("5 key max 3 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("5 key max 3 L1 [3]", 2, params.getColumnPos(2));
+        assertEquals("5 key max 3 L1 [4]", 0, params.getColumnPos(3));
+        assertEquals("5 key max 3 L1 [5]", 1, params.getColumnPos(4));
+        assertEquals("5 key max 3 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key max 3 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___   [4] [5]
+    // |___ [3] <1> [2]
+    public void testLayout5KeyMax3L2() {
+        MoreKeysKeyboardParams params = createParams(5, 3, XPOS_L2);
+        assertEquals("5 key max 3 L2 columns", 3, params.mNumColumns);
+        assertEquals("5 key max 3 L2 rows", 2, params.mNumRows);
+        assertEquals("5 key max 3 L2 left", 1, params.mLeftKeys);
+        assertEquals("5 key max 3 L2 right", 2, params.mRightKeys);
+        assertEquals("5 key max 3 L2 <1>", 0, params.getColumnPos(0));
+        assertEquals("5 key max 3 L2 [2]", 1, params.getColumnPos(1));
+        assertEquals("5 key max 3 L2 [3]", -1, params.getColumnPos(2));
+        assertEquals("5 key max 3 L2 [4]", 0, params.getColumnPos(3));
+        assertEquals("5 key max 3 L2 [5]", 1, params.getColumnPos(4));
+        assertEquals("5 key max 3 L2 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("5 key max 3 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    //     [5] [4]|
+    // [3] [2] <1>|
+    public void testLayout5KeyMax3R0() {
+        MoreKeysKeyboardParams params = createParams(5, 3, XPOS_R0);
+        assertEquals("5 key max 3 R0 columns", 3, params.mNumColumns);
+        assertEquals("5 key max 3 R0 rows", 2, params.mNumRows);
+        assertEquals("5 key max 3 R0 left", 2, params.mLeftKeys);
+        assertEquals("5 key max 3 R0 right", 1, params.mRightKeys);
+        assertEquals("5 key max 3 R0 <1>", 0, params.getColumnPos(0));
+        assertEquals("5 key max 3 R0 [2]", -1, params.getColumnPos(1));
+        assertEquals("5 key max 3 R0 [3]", -2, params.getColumnPos(2));
+        assertEquals("5 key max 3 R0 [4]", 0, params.getColumnPos(3));
+        assertEquals("5 key max 3 R0 [5]", -1, params.getColumnPos(4));
+        assertEquals("5 key max 3 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key max 3 R0 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    //     [5] [4] ___|
+    // [3] [2] <1> ___|
+    public void testLayout5KeyMax3R1() {
+        MoreKeysKeyboardParams params = createParams(5, 3, XPOS_R1);
+        assertEquals("5 key max 3 R1 columns", 3, params.mNumColumns);
+        assertEquals("5 key max 3 R1 rows", 2, params.mNumRows);
+        assertEquals("5 key max 3 R1 left", 2, params.mLeftKeys);
+        assertEquals("5 key max 3 R1 right", 1, params.mRightKeys);
+        assertEquals("5 key max 3 R1 <1>", 0, params.getColumnPos(0));
+        assertEquals("5 key max 3 R1 [2]", -1, params.getColumnPos(1));
+        assertEquals("5 key max 3 R1 [3]", -2, params.getColumnPos(2));
+        assertEquals("5 key max 3 R1 [4]", 0, params.getColumnPos(3));
+        assertEquals("5 key max 3 R1 [5]", -1, params.getColumnPos(4));
+        assertEquals("5 key max 3 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key max 3 R1 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    //   [4] [5]   ___|
+    // [3] <1> [2] ___|
+    public void testLayout5KeyMax3R2() {
+        MoreKeysKeyboardParams params = createParams(5, 3, XPOS_R2);
+        assertEquals("5 key max 3 R2 columns", 3, params.mNumColumns);
+        assertEquals("5 key max 3 R2 rows", 2, params.mNumRows);
+        assertEquals("5 key max 3 R2 left", 1, params.mLeftKeys);
+        assertEquals("5 key max 3 R2 right", 2, params.mRightKeys);
+        assertEquals("5 key max 3 R2 <1>", 0, params.getColumnPos(0));
+        assertEquals("5 key max 3 R2 [2]", 1, params.getColumnPos(1));
+        assertEquals("5 key max 3 R2 [3]", -1, params.getColumnPos(2));
+        assertEquals("5 key max 3 R2 [4]", 0, params.getColumnPos(3));
+        assertEquals("5 key max 3 R2 [5]", 1, params.getColumnPos(4));
+        assertEquals("5 key max 3 R2 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("5 key max 3 R2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    //   [4] [5]
+    // [3] <1> [2]
+    public void testLayout5KeyMax4M0() {
+        MoreKeysKeyboardParams params = createParams(5, 4, XPOS_M0);
+        assertEquals("5 key max 4 M0 columns", 3, params.mNumColumns);
+        assertEquals("5 key max 4 M0 rows", 2, params.mNumRows);
+        assertEquals("5 key max 4 M0 left", 1, params.mLeftKeys);
+        assertEquals("5 key max 4 M0 right", 2, params.mRightKeys);
+        assertEquals("5 key max 4 M0 <1>", 0, params.getColumnPos(0));
+        assertEquals("5 key max 4 M0 [2]", 1, params.getColumnPos(1));
+        assertEquals("5 key max 4 M0 [3]", -1, params.getColumnPos(2));
+        assertEquals("5 key max 4 M0 [4]", 0, params.getColumnPos(3));
+        assertEquals("5 key max 4 M0 [5]", 1, params.getColumnPos(4));
+        assertEquals("5 key max 4 M0 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("5 key max 4 M0 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // |[4] [5]
+    // |<1> [2] [3]
+    public void testLayout5KeyMax4L0() {
+        MoreKeysKeyboardParams params = createParams(5, 4, XPOS_L0);
+        assertEquals("5 key max 4 L0 columns", 3, params.mNumColumns);
+        assertEquals("5 key max 4 L0 rows", 2, params.mNumRows);
+        assertEquals("5 key max 4 L0 left", 0, params.mLeftKeys);
+        assertEquals("5 key max 4 L0 right", 3, params.mRightKeys);
+        assertEquals("5 key max 4 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("5 key max 4 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("5 key max 4 L0 [3]", 2, params.getColumnPos(2));
+        assertEquals("5 key max 4 L0 [4]", 0, params.getColumnPos(3));
+        assertEquals("5 key max 4 L0 [5]", 1, params.getColumnPos(4));
+        assertEquals("5 key max 4 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key max 4 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [4] [5]
+    // |___ <1> [2] [3]
+    public void testLayout5KeyMax4L1() {
+        MoreKeysKeyboardParams params = createParams(5, 4, XPOS_L1);
+        assertEquals("5 key max 4 L1 columns", 3, params.mNumColumns);
+        assertEquals("5 key max 4 L1 rows", 2, params.mNumRows);
+        assertEquals("5 key max 4 L1 left", 0, params.mLeftKeys);
+        assertEquals("5 key max 4 L1 right", 3, params.mRightKeys);
+        assertEquals("5 key max 4 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("5 key max 4 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("5 key max 4 L1 [3]", 2, params.getColumnPos(2));
+        assertEquals("5 key max 4 L1 [4]", 0, params.getColumnPos(3));
+        assertEquals("5 key max 4 L1 [5]", 1, params.getColumnPos(4));
+        assertEquals("5 key max 4 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key max 4 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___   [4] [5]
+    // |___ [3] <1> [2]
+    public void testLayout5KeyMax4L2() {
+        MoreKeysKeyboardParams params = createParams(5, 4, XPOS_L2);
+        assertEquals("5 key max 4 L2 columns", 3, params.mNumColumns);
+        assertEquals("5 key max 4 L2 rows", 2, params.mNumRows);
+        assertEquals("5 key max 4 L2 left", 1, params.mLeftKeys);
+        assertEquals("5 key max 4 L2 right", 2, params.mRightKeys);
+        assertEquals("5 key max 4 L2 <1>", 0, params.getColumnPos(0));
+        assertEquals("5 key max 4 L2 [2]", 1, params.getColumnPos(1));
+        assertEquals("5 key max 4 L2 [3]", -1, params.getColumnPos(2));
+        assertEquals("5 key max 4 L2 [4]", 0, params.getColumnPos(3));
+        assertEquals("5 key max 4 L2 [5]", 1, params.getColumnPos(4));
+        assertEquals("5 key max 4 L2 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("5 key max 4 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    //     [5] [4]|
+    // [3] [2] <1>|
+    public void testLayout5KeyMax4R0() {
+        MoreKeysKeyboardParams params = createParams(5, 4, XPOS_R0);
+        assertEquals("5 key max 4 R0 columns", 3, params.mNumColumns);
+        assertEquals("5 key max 4 R0 rows", 2, params.mNumRows);
+        assertEquals("5 key max 4 R0 left", 2, params.mLeftKeys);
+        assertEquals("5 key max 4 R0 right", 1, params.mRightKeys);
+        assertEquals("5 key max 4 R0 <1>", 0, params.getColumnPos(0));
+        assertEquals("5 key max 4 R0 [2]", -1, params.getColumnPos(1));
+        assertEquals("5 key max 4 R0 [3]", -2, params.getColumnPos(2));
+        assertEquals("5 key max 4 R0 [4]", 0, params.getColumnPos(3));
+        assertEquals("5 key max 4 R0 [5]", -1, params.getColumnPos(4));
+        assertEquals("5 key max 4 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key max 4 R0 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    //     [5] [4] ___|
+    // [3] [2] <1> ___|
+    public void testLayout5KeyMax4R1() {
+        MoreKeysKeyboardParams params = createParams(5, 4, XPOS_R1);
+        assertEquals("5 key max 4 R1 columns", 3, params.mNumColumns);
+        assertEquals("5 key max 4 R1 rows", 2, params.mNumRows);
+        assertEquals("5 key max 4 R1 left", 2, params.mLeftKeys);
+        assertEquals("5 key max 4 R1 right", 1, params.mRightKeys);
+        assertEquals("5 key max 4 R1 <1>", 0, params.getColumnPos(0));
+        assertEquals("5 key max 4 R1 [2]", -1, params.getColumnPos(1));
+        assertEquals("5 key max 4 R1 [3]", -2, params.getColumnPos(2));
+        assertEquals("5 key max 4 R1 [4]", 0, params.getColumnPos(3));
+        assertEquals("5 key max 4 R1 [5]", -1, params.getColumnPos(4));
+        assertEquals("5 key max 4 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key max 4 R1 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    //   [4] [5]   ___|
+    // [3] <1> [2] ___|
+    public void testLayout5KeyMax4R2() {
+        MoreKeysKeyboardParams params = createParams(5, 4, XPOS_R2);
+        assertEquals("5 key max 4 R2 columns", 3, params.mNumColumns);
+        assertEquals("5 key max 4 R2 rows", 2, params.mNumRows);
+        assertEquals("5 key max 4 R2 left", 1, params.mLeftKeys);
+        assertEquals("5 key max 4 R2 right", 2, params.mRightKeys);
+        assertEquals("5 key max 4 R2 <1>", 0, params.getColumnPos(0));
+        assertEquals("5 key max 4 R2 [2]", 1, params.getColumnPos(1));
+        assertEquals("5 key max 4 R2 [3]", -1, params.getColumnPos(2));
+        assertEquals("5 key max 4 R2 [4]", 0, params.getColumnPos(3));
+        assertEquals("5 key max 4 R2 [5]", 1, params.getColumnPos(4));
+        assertEquals("5 key max 4 R2 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("5 key max 4 R2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // [5] [3] <1> [2] [4]
+    public void testLayout5KeyMax5M0() {
+        MoreKeysKeyboardParams params = createParams(5, 5, XPOS_M0);
+        assertEquals("5 key max 5 M0 columns", 5, params.mNumColumns);
+        assertEquals("5 key max 5 M0 rows", 1, params.mNumRows);
+        assertEquals("5 key max 5 M0 left", 2, params.mLeftKeys);
+        assertEquals("5 key max 5 M0 right", 3, params.mRightKeys);
+        assertEquals("5 key max 5 M0 <1>", 0, params.getColumnPos(0));
+        assertEquals("5 key max 5 M0 [2]", 1, params.getColumnPos(1));
+        assertEquals("5 key max 5 M0 [3]", -1, params.getColumnPos(2));
+        assertEquals("5 key max 5 M0 [4]", 2, params.getColumnPos(3));
+        assertEquals("5 key max 5 M0 [5]", -2, params.getColumnPos(4));
+        assertEquals("5 key max 5 M0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("5 key max 5 M0 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    // |<1> [2] [3] [4] [5]
     public void testLayout5KeyMax5L0() {
         MoreKeysKeyboardParams params = createParams(5, 5, XPOS_L0);
         assertEquals("5 key max 5 L0 columns", 5, params.mNumColumns);
         assertEquals("5 key max 5 L0 rows", 1, params.mNumRows);
         assertEquals("5 key max 5 L0 left", 0, params.mLeftKeys);
         assertEquals("5 key max 5 L0 right", 5, params.mRightKeys);
-        assertEquals("5 key max 5 L0 [1]", 0, params.getColumnPos(0));
+        assertEquals("5 key max 5 L0 <1>", 0, params.getColumnPos(0));
         assertEquals("5 key max 5 L0 [2]", 1, params.getColumnPos(1));
         assertEquals("5 key max 5 L0 [3]", 2, params.getColumnPos(2));
         assertEquals("5 key max 5 L0 [4]", 3, params.getColumnPos(3));
@@ -578,14 +1033,14 @@
         assertEquals("5 key max 5 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // |___ [1] [2] [3] [4] [5]
+    // |___ <1> [2] [3] [4] [5]
     public void testLayout5KeyMax5L1() {
         MoreKeysKeyboardParams params = createParams(5, 5, XPOS_L1);
         assertEquals("5 key max 5 L1 columns", 5, params.mNumColumns);
         assertEquals("5 key max 5 L1 rows", 1, params.mNumRows);
         assertEquals("5 key max 5 L1 left", 0, params.mLeftKeys);
         assertEquals("5 key max 5 L1 right", 5, params.mRightKeys);
-        assertEquals("5 key max 5 L1 [1]", 0, params.getColumnPos(0));
+        assertEquals("5 key max 5 L1 <1>", 0, params.getColumnPos(0));
         assertEquals("5 key max 5 L1 [2]", 1, params.getColumnPos(1));
         assertEquals("5 key max 5 L1 [3]", 2, params.getColumnPos(2));
         assertEquals("5 key max 5 L1 [4]", 3, params.getColumnPos(3));
@@ -594,14 +1049,14 @@
         assertEquals("5 key max 5 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // |___ [3] [1] [2] [4] [5]
+    // |___ [3] <1> [2] [4] [5]
     public void testLayout5KeyMax5L2() {
         MoreKeysKeyboardParams params = createParams(5, 5, XPOS_L2);
         assertEquals("5 key max 5 L2 columns", 5, params.mNumColumns);
         assertEquals("5 key max 5 L2 rows", 1, params.mNumRows);
         assertEquals("5 key max 5 L2 left", 1, params.mLeftKeys);
         assertEquals("5 key max 5 L2 right", 4, params.mRightKeys);
-        assertEquals("5 key max 5 L2 [1]", 0, params.getColumnPos(0));
+        assertEquals("5 key max 5 L2 <1>", 0, params.getColumnPos(0));
         assertEquals("5 key max 5 L2 [2]", 1, params.getColumnPos(1));
         assertEquals("5 key max 5 L2 [3]", -1, params.getColumnPos(2));
         assertEquals("5 key max 5 L2 [4]", 2, params.getColumnPos(3));
@@ -610,14 +1065,14 @@
         assertEquals("5 key max 5 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
     }
 
-    // [5] [4] [3] [2] [1]|
+    // [5] [4] [3] [2] <1>|
     public void testLayout5KeyMax5R0() {
         MoreKeysKeyboardParams params = createParams(5, 5, XPOS_R0);
         assertEquals("5 key max 5 R0 columns", 5, params.mNumColumns);
         assertEquals("5 key max 5 R0 rows", 1, params.mNumRows);
         assertEquals("5 key max 5 R0 left", 4, params.mLeftKeys);
         assertEquals("5 key max 5 R0 right", 1, params.mRightKeys);
-        assertEquals("5 key max 5 R0 [1]", 0, params.getColumnPos(0));
+        assertEquals("5 key max 5 R0 <1>", 0, params.getColumnPos(0));
         assertEquals("5 key max 5 R0 [2]", -1, params.getColumnPos(1));
         assertEquals("5 key max 5 R0 [3]", -2, params.getColumnPos(2));
         assertEquals("5 key max 5 R0 [4]", -3, params.getColumnPos(3));
@@ -626,14 +1081,14 @@
         assertEquals("5 key max 5 R0 default", WIDTH * 4, params.getDefaultKeyCoordX());
     }
 
-    // [5] [4] [3] [2] [1] ___|
+    // [5] [4] [3] [2] <1> ___|
     public void testLayout5KeyMax5R1() {
         MoreKeysKeyboardParams params = createParams(5, 5, XPOS_R1);
         assertEquals("5 key max 5 R1 columns", 5, params.mNumColumns);
         assertEquals("5 key max 5 R1 rows", 1, params.mNumRows);
         assertEquals("5 key max 5 R1 left", 4, params.mLeftKeys);
         assertEquals("5 key max 5 R1 right", 1, params.mRightKeys);
-        assertEquals("5 key max 5 R1 [1]", 0, params.getColumnPos(0));
+        assertEquals("5 key max 5 R1 <1>", 0, params.getColumnPos(0));
         assertEquals("5 key max 5 R1 [2]", -1, params.getColumnPos(1));
         assertEquals("5 key max 5 R1 [3]", -2, params.getColumnPos(2));
         assertEquals("5 key max 5 R1 [4]", -3, params.getColumnPos(3));
@@ -642,14 +1097,14 @@
         assertEquals("5 key max 5 R1 default", WIDTH * 4, params.getDefaultKeyCoordX());
     }
 
-    // [5] [4] [3] [1] [2] ___|
+    // [5] [4] [3] <1> [2] ___|
     public void testLayout5KeyMax5R2() {
         MoreKeysKeyboardParams params = createParams(5, 5, XPOS_R2);
         assertEquals("5 key max 5 R2 columns", 5, params.mNumColumns);
         assertEquals("5 key max 5 R2 rows", 1, params.mNumRows);
         assertEquals("5 key max 5 R2 left", 3, params.mLeftKeys);
         assertEquals("5 key max 5 R2 right", 2, params.mRightKeys);
-        assertEquals("5 key max 5 R2 [1]", 0, params.getColumnPos(0));
+        assertEquals("5 key max 5 R2 <1>", 0, params.getColumnPos(0));
         assertEquals("5 key max 5 R2 [2]", 1, params.getColumnPos(1));
         assertEquals("5 key max 5 R2 [3]", -1, params.getColumnPos(2));
         assertEquals("5 key max 5 R2 [4]", -2, params.getColumnPos(3));
@@ -659,32 +1114,158 @@
     }
 
     // [6] [4] [5]
-    // [3] [1] [2]
-    public void testLayout6KeyMax5M0() {
-        MoreKeysKeyboardParams params = createParams(6, 5, XPOS_M0);
-        assertEquals("6 key columns", 3, params.mNumColumns);
-        assertEquals("6 key rows", 2, params.mNumRows);
-        assertEquals("6 key left", 1, params.mLeftKeys);
-        assertEquals("6 key right", 2, params.mRightKeys);
-        assertEquals("6 key [1]", 0, params.getColumnPos(0));
-        assertEquals("6 key [2]", 1, params.getColumnPos(1));
-        assertEquals("6 key [3]", -1, params.getColumnPos(2));
-        assertEquals("6 key [4]", 0, params.getColumnPos(3));
-        assertEquals("6 key [5]", 1, params.getColumnPos(4));
-        assertEquals("6 key [6]", -1, params.getColumnPos(5));
-        assertEquals("6 key adjust", 0, params.mTopRowAdjustment);
-        assertEquals("6 key default", WIDTH * 1, params.getDefaultKeyCoordX());
+    // [3] <1> [2]
+    public void testLayout6KeyMax4M0() {
+        MoreKeysKeyboardParams params = createParams(6, 4, XPOS_M0);
+        assertEquals("6 key max 4 M0 columns", 3, params.mNumColumns);
+        assertEquals("6 key max 4 M0 rows", 2, params.mNumRows);
+        assertEquals("6 key max 4 M0 left", 1, params.mLeftKeys);
+        assertEquals("6 key max 4 M0 right", 2, params.mRightKeys);
+        assertEquals("6 key max 4 M0 <1>", 0, params.getColumnPos(0));
+        assertEquals("6 key max 4 M0 [2]", 1, params.getColumnPos(1));
+        assertEquals("6 key max 4 M0 [3]", -1, params.getColumnPos(2));
+        assertEquals("6 key max 4 M0 [4]", 0, params.getColumnPos(3));
+        assertEquals("6 key max 4 M0 [5]", 1, params.getColumnPos(4));
+        assertEquals("6 key max 4 M0 [6]", -1, params.getColumnPos(5));
+        assertEquals("6 key max 4 M0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key max 4 M0 default", WIDTH * 1, params.getDefaultKeyCoordX());
     }
 
     // |[4] [5] [6]
-    // |[1] [2] [3]
+    // |<1> [2] [3]
+    public void testLayout6KeyMax4L0() {
+        MoreKeysKeyboardParams params = createParams(6, 4, XPOS_L0);
+        assertEquals("6 key max 4 L0 columns", 3, params.mNumColumns);
+        assertEquals("6 key max 4 L0 rows", 2, params.mNumRows);
+        assertEquals("6 key max 4 L0 left", 0, params.mLeftKeys);
+        assertEquals("6 key max 4 L0 right", 3, params.mRightKeys);
+        assertEquals("6 key max 4 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("6 key max 4 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("6 key max 4 L0 [3]", 2, params.getColumnPos(2));
+        assertEquals("6 key max 4 L0 [4]", 0, params.getColumnPos(3));
+        assertEquals("6 key max 4 L0 [5]", 1, params.getColumnPos(4));
+        assertEquals("6 key max 4 L0 [6]", 2, params.getColumnPos(5));
+        assertEquals("6 key max 4 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key max 4 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [4] [5] [6]
+    // |___ <1> [2] [3]
+    public void testLayout6KeyMax4L1() {
+        MoreKeysKeyboardParams params = createParams(6, 4, XPOS_L1);
+        assertEquals("6 key max 4 L1 columns", 3, params.mNumColumns);
+        assertEquals("6 key max 4 L1 rows", 2, params.mNumRows);
+        assertEquals("6 key max 4 L1 left", 0, params.mLeftKeys);
+        assertEquals("6 key max 4 L1 right", 3, params.mRightKeys);
+        assertEquals("6 key max 4 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("6 key max 4 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("6 key max 4 L1 [3]", 2, params.getColumnPos(2));
+        assertEquals("6 key max 4 L1 [4]", 0, params.getColumnPos(3));
+        assertEquals("6 key max 4 L1 [5]", 1, params.getColumnPos(4));
+        assertEquals("6 key max 4 L1 [6]", 2, params.getColumnPos(5));
+        assertEquals("6 key max 4 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key max 4 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [6] [4] [5]
+    // |___ [3] <1> [2]
+    public void testLayout6KeyMax4L2() {
+        MoreKeysKeyboardParams params = createParams(6, 4, XPOS_L2);
+        assertEquals("6 key max 4 L2 columns", 3, params.mNumColumns);
+        assertEquals("6 key max 4 L2 rows", 2, params.mNumRows);
+        assertEquals("6 key max 4 L2 left", 1, params.mLeftKeys);
+        assertEquals("6 key max 4 L2 right", 2, params.mRightKeys);
+        assertEquals("6 key max 4 L2 <1>", 0, params.getColumnPos(0));
+        assertEquals("6 key max 4 L2 [2]", 1, params.getColumnPos(1));
+        assertEquals("6 key max 4 L2 [3]", -1, params.getColumnPos(2));
+        assertEquals("6 key max 4 L2 [4]", 0, params.getColumnPos(3));
+        assertEquals("6 key max 4 L2 [5]", 1, params.getColumnPos(4));
+        assertEquals("6 key max 4 L2 [6]", -1, params.getColumnPos(5));
+        assertEquals("6 key max 4 L2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key max 4 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // [6] [5] [4]|
+    // [3] [2] <1>|
+    public void testLayout6KeyMax4R0() {
+        MoreKeysKeyboardParams params = createParams(6, 4, XPOS_R0);
+        assertEquals("6 key max 4 R0 columns", 3, params.mNumColumns);
+        assertEquals("6 key max 4 R0 rows", 2, params.mNumRows);
+        assertEquals("6 key max 4 R0 left", 2, params.mLeftKeys);
+        assertEquals("6 key max 4 R0 right", 1, params.mRightKeys);
+        assertEquals("6 key max 4 R0 <1>", 0, params.getColumnPos(0));
+        assertEquals("6 key max 4 R0 [2]", -1, params.getColumnPos(1));
+        assertEquals("6 key max 4 R0 [3]", -2, params.getColumnPos(2));
+        assertEquals("6 key max 4 R0 [4]", 0, params.getColumnPos(3));
+        assertEquals("6 key max 4 R0 [5]", -1, params.getColumnPos(4));
+        assertEquals("6 key max 4 R0 [6]", -2, params.getColumnPos(5));
+        assertEquals("6 key max 4 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key max 4 R0 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    // [6] [5] [4] ___|
+    // [3] [2] <1> ___|
+    public void testLayout6KeyMax4R1() {
+        MoreKeysKeyboardParams params = createParams(6, 4, XPOS_R1);
+        assertEquals("6 key max 4 R1 columns", 3, params.mNumColumns);
+        assertEquals("6 key max 4 R1 rows", 2, params.mNumRows);
+        assertEquals("6 key max 4 R1 left", 2, params.mLeftKeys);
+        assertEquals("6 key max 4 R1 right", 1, params.mRightKeys);
+        assertEquals("6 key max 4 R1 <1>", 0, params.getColumnPos(0));
+        assertEquals("6 key max 4 R1 [2]", -1, params.getColumnPos(1));
+        assertEquals("6 key max 4 R1 [3]", -2, params.getColumnPos(2));
+        assertEquals("6 key max 4 R1 [4]", 0, params.getColumnPos(3));
+        assertEquals("6 key max 4 R1 [5]", -1, params.getColumnPos(4));
+        assertEquals("6 key max 4 R1 [6]", -2, params.getColumnPos(5));
+        assertEquals("6 key max 4 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key max 4 R1 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    // [6] [4] [5] ___|
+    // [3] <1> [2] ___|
+    public void testLayout6KeyMax4R2() {
+        MoreKeysKeyboardParams params = createParams(6, 4, XPOS_R2);
+        assertEquals("6 key max 4 R2 columns", 3, params.mNumColumns);
+        assertEquals("6 key max 4 R2 rows", 2, params.mNumRows);
+        assertEquals("6 key max 4 R2 left", 1, params.mLeftKeys);
+        assertEquals("6 key max 4 R2 right", 2, params.mRightKeys);
+        assertEquals("6 key max 4 R2 <1>", 0, params.getColumnPos(0));
+        assertEquals("6 key max 4 R2 [2]", 1, params.getColumnPos(1));
+        assertEquals("6 key max 4 R2 [3]", -1, params.getColumnPos(2));
+        assertEquals("6 key max 4 R2 [4]", 0, params.getColumnPos(3));
+        assertEquals("6 key max 4 R2 [5]", 1, params.getColumnPos(4));
+        assertEquals("6 key max 4 R2 [6]", -1, params.getColumnPos(5));
+        assertEquals("6 key max 4 R2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key max 4 R2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // [6] [4] [5]
+    // [3] <1> [2]
+    public void testLayout6KeyMax5M0() {
+        MoreKeysKeyboardParams params = createParams(6, 5, XPOS_M0);
+        assertEquals("6 key max 5 M0 columns", 3, params.mNumColumns);
+        assertEquals("6 key max 5 M0 rows", 2, params.mNumRows);
+        assertEquals("6 key max 5 M0 left", 1, params.mLeftKeys);
+        assertEquals("6 key max 5 M0 right", 2, params.mRightKeys);
+        assertEquals("6 key max 5 M0 <1>", 0, params.getColumnPos(0));
+        assertEquals("6 key max 5 M0 [2]", 1, params.getColumnPos(1));
+        assertEquals("6 key max 5 M0 [3]", -1, params.getColumnPos(2));
+        assertEquals("6 key max 5 M0 [4]", 0, params.getColumnPos(3));
+        assertEquals("6 key max 5 M0 [5]", 1, params.getColumnPos(4));
+        assertEquals("6 key max 5 M0 [6]", -1, params.getColumnPos(5));
+        assertEquals("6 key max 5 M0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("6 key max 5 M0 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // |[4] [5] [6]
+    // |<1> [2] [3]
     public void testLayout6KeyMax5L0() {
         MoreKeysKeyboardParams params = createParams(6, 5, XPOS_L0);
         assertEquals("6 key max 5 L0 columns", 3, params.mNumColumns);
         assertEquals("6 key max 5 L0 rows", 2, params.mNumRows);
         assertEquals("6 key max 5 L0 left", 0, params.mLeftKeys);
         assertEquals("6 key max 5 L0 right", 3, params.mRightKeys);
-        assertEquals("6 key max 5 L0 [1]", 0, params.getColumnPos(0));
+        assertEquals("6 key max 5 L0 <1>", 0, params.getColumnPos(0));
         assertEquals("6 key max 5 L0 [2]", 1, params.getColumnPos(1));
         assertEquals("6 key max 5 L0 [3]", 2, params.getColumnPos(2));
         assertEquals("6 key max 5 L0 [4]", 0, params.getColumnPos(3));
@@ -695,14 +1276,14 @@
     }
 
     // |___ [4] [5] [6]
-    // |___ [1] [2] [3]
+    // |___ <1> [2] [3]
     public void testLayout6KeyMax5L1() {
         MoreKeysKeyboardParams params = createParams(6, 5, XPOS_L1);
         assertEquals("6 key max 5 L1 columns", 3, params.mNumColumns);
         assertEquals("6 key max 5 L1 rows", 2, params.mNumRows);
         assertEquals("6 key max 5 L1 left", 0, params.mLeftKeys);
         assertEquals("6 key max 5 L1 right", 3, params.mRightKeys);
-        assertEquals("6 key max 5 L1 [1]", 0, params.getColumnPos(0));
+        assertEquals("6 key max 5 L1 <1>", 0, params.getColumnPos(0));
         assertEquals("6 key max 5 L1 [2]", 1, params.getColumnPos(1));
         assertEquals("6 key max 5 L1 [3]", 2, params.getColumnPos(2));
         assertEquals("6 key max 5 L1 [4]", 0, params.getColumnPos(3));
@@ -713,14 +1294,14 @@
     }
 
     // |___ [6] [4] [5]
-    // |___ [3] [1] [2]
+    // |___ [3] <1> [2]
     public void testLayout6KeyMax5L2() {
         MoreKeysKeyboardParams params = createParams(6, 5, XPOS_L2);
         assertEquals("6 key max 5 L2 columns", 3, params.mNumColumns);
         assertEquals("6 key max 5 L2 rows", 2, params.mNumRows);
         assertEquals("6 key max 5 L2 left", 1, params.mLeftKeys);
         assertEquals("6 key max 5 L2 right", 2, params.mRightKeys);
-        assertEquals("6 key max 5 L2 [1]", 0, params.getColumnPos(0));
+        assertEquals("6 key max 5 L2 <1>", 0, params.getColumnPos(0));
         assertEquals("6 key max 5 L2 [2]", 1, params.getColumnPos(1));
         assertEquals("6 key max 5 L2 [3]", -1, params.getColumnPos(2));
         assertEquals("6 key max 5 L2 [4]", 0, params.getColumnPos(3));
@@ -731,14 +1312,14 @@
     }
 
     // [6] [5] [4]|
-    // [3] [2] [1]|
+    // [3] [2] <1>|
     public void testLayout6KeyMax5R0() {
         MoreKeysKeyboardParams params = createParams(6, 5, XPOS_R0);
         assertEquals("6 key max 5 R0 columns", 3, params.mNumColumns);
         assertEquals("6 key max 5 R0 rows", 2, params.mNumRows);
         assertEquals("6 key max 5 R0 left", 2, params.mLeftKeys);
         assertEquals("6 key max 5 R0 right", 1, params.mRightKeys);
-        assertEquals("6 key max 5 R0 [1]", 0, params.getColumnPos(0));
+        assertEquals("6 key max 5 R0 <1>", 0, params.getColumnPos(0));
         assertEquals("6 key max 5 R0 [2]", -1, params.getColumnPos(1));
         assertEquals("6 key max 5 R0 [3]", -2, params.getColumnPos(2));
         assertEquals("6 key max 5 R0 [4]", 0, params.getColumnPos(3));
@@ -749,14 +1330,14 @@
     }
 
     // [6] [5] [4] ___|
-    // [3] [2] [1] ___|
+    // [3] [2] <1> ___|
     public void testLayout6KeyMax5R1() {
         MoreKeysKeyboardParams params = createParams(6, 5, XPOS_R1);
         assertEquals("6 key max 5 R1 columns", 3, params.mNumColumns);
         assertEquals("6 key max 5 R1 rows", 2, params.mNumRows);
         assertEquals("6 key max 5 R1 left", 2, params.mLeftKeys);
         assertEquals("6 key max 5 R1 right", 1, params.mRightKeys);
-        assertEquals("6 key max 5 R1 [1]", 0, params.getColumnPos(0));
+        assertEquals("6 key max 5 R1 <1>", 0, params.getColumnPos(0));
         assertEquals("6 key max 5 R1 [2]", -1, params.getColumnPos(1));
         assertEquals("6 key max 5 R1 [3]", -2, params.getColumnPos(2));
         assertEquals("6 key max 5 R1 [4]", 0, params.getColumnPos(3));
@@ -767,14 +1348,14 @@
     }
 
     // [6] [4] [5] ___|
-    // [3] [1] [2] ___|
+    // [3] <1> [2] ___|
     public void testLayout6KeyMax5R2() {
         MoreKeysKeyboardParams params = createParams(6, 5, XPOS_R2);
         assertEquals("6 key max 5 R2 columns", 3, params.mNumColumns);
         assertEquals("6 key max 5 R2 rows", 2, params.mNumRows);
         assertEquals("6 key max 5 R2 left", 1, params.mLeftKeys);
         assertEquals("6 key max 5 R2 right", 2, params.mRightKeys);
-        assertEquals("6 key max 5 R2 [1]", 0, params.getColumnPos(0));
+        assertEquals("6 key max 5 R2 <1>", 0, params.getColumnPos(0));
         assertEquals("6 key max 5 R2 [2]", 1, params.getColumnPos(1));
         assertEquals("6 key max 5 R2 [3]", -1, params.getColumnPos(2));
         assertEquals("6 key max 5 R2 [4]", 0, params.getColumnPos(3));
@@ -784,147 +1365,14 @@
         assertEquals("6 key max 5 R2 default", WIDTH * 1, params.getDefaultKeyCoordX());
     }
 
-    //   [7] [5] [6]
-    // [3] [1] [2] [4]
-    public void testLayout7KeyMax5M0() {
-        MoreKeysKeyboardParams params = createParams(7, 5, XPOS_M0);
-        assertEquals("7 key columns", 4, params.mNumColumns);
-        assertEquals("7 key rows", 2, params.mNumRows);
-        assertEquals("7 key left", 1, params.mLeftKeys);
-        assertEquals("7 key right", 3, params.mRightKeys);
-        assertEquals("7 key [1]", 0, params.getColumnPos(0));
-        assertEquals("7 key [2]", 1, params.getColumnPos(1));
-        assertEquals("7 key [3]", -1, params.getColumnPos(2));
-        assertEquals("7 key [4]", 2, params.getColumnPos(3));
-        assertEquals("7 key [5]", 0, params.getColumnPos(4));
-        assertEquals("7 key [6]", 1, params.getColumnPos(5));
-        assertEquals("7 key [7]", -1, params.getColumnPos(6));
-        assertEquals("7 key adjust", 1, params.mTopRowAdjustment);
-        assertEquals("7 key default", WIDTH * 1, params.getDefaultKeyCoordX());
-    }
-
-    // |  [5] [6] [7]
-    // |[1] [2] [3] [4]
-    public void testLayout7KeyMax5L0() {
-        MoreKeysKeyboardParams params = createParams(7, 5, XPOS_L0);
-        assertEquals("7 key max 5 L0 columns", 4, params.mNumColumns);
-        assertEquals("7 key max 5 L0 rows", 2, params.mNumRows);
-        assertEquals("7 key max 5 L0 left", 0, params.mLeftKeys);
-        assertEquals("7 key max 5 L0 right", 4, params.mRightKeys);
-        assertEquals("7 key max 5 L0 [1]", 0, params.getColumnPos(0));
-        assertEquals("7 key max 5 L0 [2]", 1, params.getColumnPos(1));
-        assertEquals("7 key max 5 L0 [3]", 2, params.getColumnPos(2));
-        assertEquals("7 key max 5 L0 [4]", 3, params.getColumnPos(3));
-        assertEquals("7 key max 5 L0 [5]", 0, params.getColumnPos(4));
-        assertEquals("7 key max 5 L0 [6]", 1, params.getColumnPos(5));
-        assertEquals("7 key max 5 L0 [7]", 2, params.getColumnPos(6));
-        assertEquals("7 key max 5 L0 adjust", 1, params.mTopRowAdjustment);
-        assertEquals("7 key max 5 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
-    }
-
-    // |___   [5] [6] [7]
-    // |___ [1] [2] [3] [4]
-    public void testLayout7KeyMax5L1() {
-        MoreKeysKeyboardParams params = createParams(7, 5, XPOS_L1);
-        assertEquals("7 key max 5 L1 columns", 4, params.mNumColumns);
-        assertEquals("7 key max 5 L1 rows", 2, params.mNumRows);
-        assertEquals("7 key max 5 L1 left", 0, params.mLeftKeys);
-        assertEquals("7 key max 5 L1 right", 4, params.mRightKeys);
-        assertEquals("7 key max 5 L1 [1]", 0, params.getColumnPos(0));
-        assertEquals("7 key max 5 L1 [2]", 1, params.getColumnPos(1));
-        assertEquals("7 key max 5 L1 [3]", 2, params.getColumnPos(2));
-        assertEquals("7 key max 5 L1 [4]", 3, params.getColumnPos(3));
-        assertEquals("7 key max 5 L1 [5]", 0, params.getColumnPos(4));
-        assertEquals("7 key max 5 L1 [6]", 1, params.getColumnPos(5));
-        assertEquals("7 key max 5 L1 [7]", 2, params.getColumnPos(6));
-        assertEquals("7 key max 5 L1 adjust", 1, params.mTopRowAdjustment);
-        assertEquals("7 key max 5 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
-    }
-
-    // |___   [7] [5] [6]
-    // |___ [3] [1] [2] [4]
-    public void testLayout7KeyMax5L2() {
-        MoreKeysKeyboardParams params = createParams(7, 5, XPOS_L2);
-        assertEquals("7 key max 5 L2 columns", 4, params.mNumColumns);
-        assertEquals("7 key max 5 L2 rows", 2, params.mNumRows);
-        assertEquals("7 key max 5 L2 left", 1, params.mLeftKeys);
-        assertEquals("7 key max 5 L2 right", 3, params.mRightKeys);
-        assertEquals("7 key max 5 L2 [1]", 0, params.getColumnPos(0));
-        assertEquals("7 key max 5 L2 [2]", 1, params.getColumnPos(1));
-        assertEquals("7 key max 5 L2 [3]", -1, params.getColumnPos(2));
-        assertEquals("7 key max 5 L2 [4]", 2, params.getColumnPos(3));
-        assertEquals("7 key max 5 L2 [5]", 0, params.getColumnPos(4));
-        assertEquals("7 key max 5 L2 [6]", 1, params.getColumnPos(5));
-        assertEquals("7 key max 5 L2 [7]", -1, params.getColumnPos(6));
-        assertEquals("7 key max 5 L2 adjust", 1, params.mTopRowAdjustment);
-        assertEquals("7 key max 5 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
-    }
-
-    //   [7] [6] [5]  |
-    // [4] [3] [2] [1]|
-    public void testLayout7KeyMax5R0() {
-        MoreKeysKeyboardParams params = createParams(7, 5, XPOS_R0);
-        assertEquals("7 key max 5 R0 columns", 4, params.mNumColumns);
-        assertEquals("7 key max 5 R0 rows", 2, params.mNumRows);
-        assertEquals("7 key max 5 R0 left", 3, params.mLeftKeys);
-        assertEquals("7 key max 5 R0 right", 1, params.mRightKeys);
-        assertEquals("7 key max 5 R0 [1]", 0, params.getColumnPos(0));
-        assertEquals("7 key max 5 R0 [2]", -1, params.getColumnPos(1));
-        assertEquals("7 key max 5 R0 [3]", -2, params.getColumnPos(2));
-        assertEquals("7 key max 5 R0 [4]", -3, params.getColumnPos(3));
-        assertEquals("7 key max 5 R0 [5]", 0, params.getColumnPos(4));
-        assertEquals("7 key max 5 R0 [6]", -1, params.getColumnPos(5));
-        assertEquals("7 key max 5 R0 [7]", -2, params.getColumnPos(6));
-        assertEquals("7 key max 5 R0 adjust", -1, params.mTopRowAdjustment);
-        assertEquals("7 key max 5 R0 default", WIDTH * 3, params.getDefaultKeyCoordX());
-    }
-
-    //   [7] [6] [5]   ___|
-    // [4] [3] [2] [1] ___|
-    public void testLayout7KeyMax5R1() {
-        MoreKeysKeyboardParams params = createParams(7, 5, XPOS_R1);
-        assertEquals("7 key max 5 R1 columns", 4, params.mNumColumns);
-        assertEquals("7 key max 5 R1 rows", 2, params.mNumRows);
-        assertEquals("7 key max 5 R1 left", 3, params.mLeftKeys);
-        assertEquals("7 key max 5 R1 right", 1, params.mRightKeys);
-        assertEquals("7 key max 5 R1 [1]", 0, params.getColumnPos(0));
-        assertEquals("7 key max 5 R1 [2]", -1, params.getColumnPos(1));
-        assertEquals("7 key max 5 R1 [3]", -2, params.getColumnPos(2));
-        assertEquals("7 key max 5 R1 [4]", -3, params.getColumnPos(3));
-        assertEquals("7 key max 5 R1 [5]", 0, params.getColumnPos(4));
-        assertEquals("7 key max 5 R1 [6]", -1, params.getColumnPos(5));
-        assertEquals("7 key max 5 R1 [7]", -2, params.getColumnPos(6));
-        assertEquals("7 key max 5 R1 adjust", -1, params.mTopRowAdjustment);
-        assertEquals("7 key max 5 R1 default", WIDTH * 3, params.getDefaultKeyCoordX());
-    }
-
-    //   [7] [5] [6]   ___|
-    // [4] [3] [1] [2] ___|
-    public void testLayout7KeyMax5R2() {
-        MoreKeysKeyboardParams params = createParams(7, 5, XPOS_R2);
-        assertEquals("7 key max 5 R2 columns", 4, params.mNumColumns);
-        assertEquals("7 key max 5 R2 rows", 2, params.mNumRows);
-        assertEquals("7 key max 5 R2 left", 2, params.mLeftKeys);
-        assertEquals("7 key max 5 R2 right", 2, params.mRightKeys);
-        assertEquals("7 key max 5 R2 [1]", 0, params.getColumnPos(0));
-        assertEquals("7 key max 5 R2 [2]", 1, params.getColumnPos(1));
-        assertEquals("7 key max 5 R2 [3]", -1, params.getColumnPos(2));
-        assertEquals("7 key max 5 R2 [4]", -2, params.getColumnPos(3));
-        assertEquals("7 key max 5 R2 [5]", 0, params.getColumnPos(4));
-        assertEquals("7 key max 5 R2 [6]", 1, params.getColumnPos(5));
-        assertEquals("7 key max 5 R2 [7]", -1, params.getColumnPos(6));
-        assertEquals("7 key max 5 R2 adjust", -1, params.mTopRowAdjustment);
-        assertEquals("7 key max 5 R2 default", WIDTH * 2, params.getDefaultKeyCoordX());
-    }
-
-    // |[1] [2] [3] [4] [5] [6] [7] ___ ___ ___|
+    // |<1> [2] [3] [4] [5] [6] [7] ___ ___ ___|
     public void testLayout7KeyMax7L0() {
         MoreKeysKeyboardParams params = createParams(7, 7, XPOS_L0);
         assertEquals("7 key max 7 L0 columns", 7, params.mNumColumns);
         assertEquals("7 key max 7 L0 rows", 1, params.mNumRows);
         assertEquals("7 key max 7 L0 left", 0, params.mLeftKeys);
         assertEquals("7 key max 7 L0 right", 7, params.mRightKeys);
-        assertEquals("7 key max 7 L0 [1]", 0, params.getColumnPos(0));
+        assertEquals("7 key max 7 L0 <1>", 0, params.getColumnPos(0));
         assertEquals("7 key max 7 L0 [2]", 1, params.getColumnPos(1));
         assertEquals("7 key max 7 L0 [3]", 2, params.getColumnPos(2));
         assertEquals("7 key max 7 L0 [4]", 3, params.getColumnPos(3));
@@ -935,14 +1383,14 @@
         assertEquals("7 key max 7 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // |___ [1] [2] [3] [4] [5] [6] [7] ___ ___|
+    // |___ <1> [2] [3] [4] [5] [6] [7] ___ ___|
     public void testLayout7KeyMax7L1() {
         MoreKeysKeyboardParams params = createParams(7, 7, XPOS_L1);
         assertEquals("7 key max 7 L1 columns", 7, params.mNumColumns);
         assertEquals("7 key max 7 L1 rows", 1, params.mNumRows);
         assertEquals("7 key max 7 L1 left", 0, params.mLeftKeys);
         assertEquals("7 key max 7 L1 right", 7, params.mRightKeys);
-        assertEquals("7 key max 7 L1 [1]", 0, params.getColumnPos(0));
+        assertEquals("7 key max 7 L1 <1>", 0, params.getColumnPos(0));
         assertEquals("7 key max 7 L1 [2]", 1, params.getColumnPos(1));
         assertEquals("7 key max 7 L1 [3]", 2, params.getColumnPos(2));
         assertEquals("7 key max 7 L1 [4]", 3, params.getColumnPos(3));
@@ -953,14 +1401,14 @@
         assertEquals("7 key max 7 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // |___ [3] [1] [2] [4] [5] [6] [7] ___ ___|
+    // |___ [3] <1> [2] [4] [5] [6] [7] ___ ___|
     public void testLayout7KeyMax7L2() {
         MoreKeysKeyboardParams params = createParams(7, 7, XPOS_L2);
         assertEquals("7 key max 7 L2 columns", 7, params.mNumColumns);
         assertEquals("7 key max 7 L2 rows", 1, params.mNumRows);
         assertEquals("7 key max 7 L2 left", 1, params.mLeftKeys);
         assertEquals("7 key max 7 L2 right", 6, params.mRightKeys);
-        assertEquals("7 key max 7 L2 [1]", 0, params.getColumnPos(0));
+        assertEquals("7 key max 7 L2 <1>", 0, params.getColumnPos(0));
         assertEquals("7 key max 7 L2 [2]", 1, params.getColumnPos(1));
         assertEquals("7 key max 7 L2 [3]", -1, params.getColumnPos(2));
         assertEquals("7 key max 7 L2 [4]", 2, params.getColumnPos(3));
@@ -971,14 +1419,14 @@
         assertEquals("7 key max 7 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
     }
 
-    // |___ [5] [3] [1] [2] [4] [6] [7] ___ ___|
+    // |___ [5] [3] <1> [2] [4] [6] [7] ___ ___|
     public void testLayout7KeyMax7L3() {
         MoreKeysKeyboardParams params = createParams(7, 7, XPOS_L3);
         assertEquals("7 key max 7 L3 columns", 7, params.mNumColumns);
         assertEquals("7 key max 7 L3 rows", 1, params.mNumRows);
         assertEquals("7 key max 7 L3 left", 2, params.mLeftKeys);
         assertEquals("7 key max 7 L3 right", 5, params.mRightKeys);
-        assertEquals("7 key max 7 L3 [1]", 0, params.getColumnPos(0));
+        assertEquals("7 key max 7 L3 <1>", 0, params.getColumnPos(0));
         assertEquals("7 key max 7 L3 [2]", 1, params.getColumnPos(1));
         assertEquals("7 key max 7 L3 [3]", -1, params.getColumnPos(2));
         assertEquals("7 key max 7 L3 [4]", 2, params.getColumnPos(3));
@@ -989,14 +1437,14 @@
         assertEquals("7 key max 7 L3 default", WIDTH * 2, params.getDefaultKeyCoordX());
     }
 
-    // |___ [7] [5] [3] [1] [2] [4] [6] ___ ___|
+    // |___ [7] [5] [3] <1> [2] [4] [6] ___ ___|
     public void testLayout7KeyMax7M0() {
         MoreKeysKeyboardParams params = createParams(7, 7, XPOS_M0);
         assertEquals("7 key max 7 M0 columns", 7, params.mNumColumns);
         assertEquals("7 key max 7 M0 rows", 1, params.mNumRows);
         assertEquals("7 key max 7 M0 left", 3, params.mLeftKeys);
         assertEquals("7 key max 7 M0 right", 4, params.mRightKeys);
-        assertEquals("7 key max 7 M0 [1]", 0, params.getColumnPos(0));
+        assertEquals("7 key max 7 M0 <1>", 0, params.getColumnPos(0));
         assertEquals("7 key max 7 M0 [2]", 1, params.getColumnPos(1));
         assertEquals("7 key max 7 M0 [3]", -1, params.getColumnPos(2));
         assertEquals("7 key max 7 M0 [4]", 2, params.getColumnPos(3));
@@ -1007,14 +1455,14 @@
         assertEquals("7 key max 7 M0 default", WIDTH * 3, params.getDefaultKeyCoordX());
     }
 
-    // |___ ___ [7] [5] [3] [1] [2] [4] [6] ___|
+    // |___ ___ [7] [5] [3] <1> [2] [4] [6] ___|
     public void testLayout7KeyMax7M1() {
         MoreKeysKeyboardParams params = createParams(7, 7, XPOS_M1);
         assertEquals("7 key max 7 M1 columns", 7, params.mNumColumns);
         assertEquals("7 key max 7 M1 rows", 1, params.mNumRows);
         assertEquals("7 key max 7 M1 left", 3, params.mLeftKeys);
         assertEquals("7 key max 7 M1 right", 4, params.mRightKeys);
-        assertEquals("7 key max 7 M1 [1]", 0, params.getColumnPos(0));
+        assertEquals("7 key max 7 M1 <1>", 0, params.getColumnPos(0));
         assertEquals("7 key max 7 M1 [2]", 1, params.getColumnPos(1));
         assertEquals("7 key max 7 M1 [3]", -1, params.getColumnPos(2));
         assertEquals("7 key max 7 M1 [4]", 2, params.getColumnPos(3));
@@ -1025,14 +1473,14 @@
         assertEquals("7 key max 7 M1 default", WIDTH * 3, params.getDefaultKeyCoordX());
     }
 
-    // |___ ___ [7] [6] [5] [3] [1] [2] [4] ___|
+    // |___ ___ [7] [6] [5] [3] <1> [2] [4] ___|
     public void testLayout7KeyMax7R3() {
         MoreKeysKeyboardParams params = createParams(7, 7, XPOS_R3);
         assertEquals("7 key max 7 R3 columns", 7, params.mNumColumns);
         assertEquals("7 key max 7 R3 rows", 1, params.mNumRows);
         assertEquals("7 key max 7 R3 left", 4, params.mLeftKeys);
         assertEquals("7 key max 7 R3 right", 3, params.mRightKeys);
-        assertEquals("7 key max 7 R3 [1]", 0, params.getColumnPos(0));
+        assertEquals("7 key max 7 R3 <1>", 0, params.getColumnPos(0));
         assertEquals("7 key max 7 R3 [2]", 1, params.getColumnPos(1));
         assertEquals("7 key max 7 R3 [3]", -1, params.getColumnPos(2));
         assertEquals("7 key max 7 R3 [4]", 2, params.getColumnPos(3));
@@ -1043,14 +1491,14 @@
         assertEquals("7 key max 7 R3 default", WIDTH * 4, params.getDefaultKeyCoordX());
     }
 
-    // |___ ___ [7] [6] [5] [4] [3] [1] [2] ___|
+    // |___ ___ [7] [6] [5] [4] [3] <1> [2] ___|
     public void testLayout7KeyMax7R2() {
         MoreKeysKeyboardParams params = createParams(7, 7, XPOS_R2);
         assertEquals("7 key max 7 R2 columns", 7, params.mNumColumns);
         assertEquals("7 key max 7 R2 rows", 1, params.mNumRows);
         assertEquals("7 key max 7 R2 left", 5, params.mLeftKeys);
         assertEquals("7 key max 7 R2 right", 2, params.mRightKeys);
-        assertEquals("7 key max 7 R2 [1]", 0, params.getColumnPos(0));
+        assertEquals("7 key max 7 R2 <1>", 0, params.getColumnPos(0));
         assertEquals("7 key max 7 R2 [2]", 1, params.getColumnPos(1));
         assertEquals("7 key max 7 R2 [3]", -1, params.getColumnPos(2));
         assertEquals("7 key max 7 R2 [4]", -2, params.getColumnPos(3));
@@ -1061,14 +1509,14 @@
         assertEquals("7 key max 7 R2 default", WIDTH * 5, params.getDefaultKeyCoordX());
     }
 
-    // |___ ___ [7] [6] [5] [4] [3] [2] [1] ___|
+    // |___ ___ [7] [6] [5] [4] [3] [2] <1> ___|
     public void testLayout7KeyMax7R1() {
         MoreKeysKeyboardParams params = createParams(7, 7, XPOS_R1);
         assertEquals("7 key max 7 R1 columns", 7, params.mNumColumns);
         assertEquals("7 key max 7 R1 rows", 1, params.mNumRows);
         assertEquals("7 key max 7 R1 left", 6, params.mLeftKeys);
         assertEquals("7 key max 7 R1 right", 1, params.mRightKeys);
-        assertEquals("7 key max 7 R1 [1]", 0, params.getColumnPos(0));
+        assertEquals("7 key max 7 R1 <1>", 0, params.getColumnPos(0));
         assertEquals("7 key max 7 R1 [2]", -1, params.getColumnPos(1));
         assertEquals("7 key max 7 R1 [3]", -2, params.getColumnPos(2));
         assertEquals("7 key max 7 R1 [4]", -3, params.getColumnPos(3));
@@ -1079,14 +1527,14 @@
         assertEquals("7 key max 7 R1 default", WIDTH * 6, params.getDefaultKeyCoordX());
     }
 
-    // |___ ___ [7] [6] [5] [4] [3] [2] [1]|
+    // |___ ___ [7] [6] [5] [4] [3] [2] <1>|
     public void testLayout7KeyMax7R0() {
         MoreKeysKeyboardParams params = createParams(7, 7, XPOS_R0);
         assertEquals("7 key max 7 R0 columns", 7, params.mNumColumns);
         assertEquals("7 key max 7 R0 rows", 1, params.mNumRows);
         assertEquals("7 key max 7 R0 left", 6, params.mLeftKeys);
         assertEquals("7 key max 7 R0 right", 1, params.mRightKeys);
-        assertEquals("7 key max 7 R0 [1]", 0, params.getColumnPos(0));
+        assertEquals("7 key max 7 R0 <1>", 0, params.getColumnPos(0));
         assertEquals("7 key max 7 R0 [2]", -1, params.getColumnPos(1));
         assertEquals("7 key max 7 R0 [3]", -2, params.getColumnPos(2));
         assertEquals("7 key max 7 R0 [4]", -3, params.getColumnPos(3));
@@ -1097,15 +1545,288 @@
         assertEquals("7 key max 7 R0 default", WIDTH * 6, params.getDefaultKeyCoordX());
     }
 
+    //   [5] [6] [7]
+    // [3] <1> [2] [4]
+    public void testLayout7KeyMax5M0() {
+        MoreKeysKeyboardParams params = createParams(7, 5, XPOS_M0);
+        assertEquals("7 key max 5 M0 columns", 4, params.mNumColumns);
+        assertEquals("7 key max 5 M0 rows", 2, params.mNumRows);
+        assertEquals("7 key max 5 M0 left", 1, params.mLeftKeys);
+        assertEquals("7 key max 5 M0 right", 3, params.mRightKeys);
+        assertEquals("7 key max 5 M0 <1>", 0, params.getColumnPos(0));
+        assertEquals("7 key max 5 M0 [2]", 1, params.getColumnPos(1));
+        assertEquals("7 key max 5 M0 [3]", -1, params.getColumnPos(2));
+        assertEquals("7 key max 5 M0 [4]", 2, params.getColumnPos(3));
+        assertEquals("7 key max 5 M0 [5]", 0, params.getColumnPos(4));
+        assertEquals("7 key max 5 M0 [6]", 1, params.getColumnPos(5));
+        assertEquals("7 key max 5 M0 [7]", 2, params.getColumnPos(6));
+        assertEquals("7 key max 5 M0 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("7 key max 5 M0 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // |[5] [6] [7]
+    // |<1> [2] [3] [4]
+    public void testLayout7KeyMax5L0() {
+        MoreKeysKeyboardParams params = createParams(7, 5, XPOS_L0);
+        assertEquals("7 key max 5 L0 columns", 4, params.mNumColumns);
+        assertEquals("7 key max 5 L0 rows", 2, params.mNumRows);
+        assertEquals("7 key max 5 L0 left", 0, params.mLeftKeys);
+        assertEquals("7 key max 5 L0 right", 4, params.mRightKeys);
+        assertEquals("7 key max 5 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("7 key max 5 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("7 key max 5 L0 [3]", 2, params.getColumnPos(2));
+        assertEquals("7 key max 5 L0 [4]", 3, params.getColumnPos(3));
+        assertEquals("7 key max 5 L0 [5]", 0, params.getColumnPos(4));
+        assertEquals("7 key max 5 L0 [6]", 1, params.getColumnPos(5));
+        assertEquals("7 key max 5 L0 [7]", 2, params.getColumnPos(6));
+        assertEquals("7 key max 5 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key max 5 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [5] [6] [7]
+    // |___ <1> [2] [3] [4]
+    public void testLayout7KeyMax5L1() {
+        MoreKeysKeyboardParams params = createParams(7, 5, XPOS_L1);
+        assertEquals("7 key max 5 L1 columns", 4, params.mNumColumns);
+        assertEquals("7 key max 5 L1 rows", 2, params.mNumRows);
+        assertEquals("7 key max 5 L1 left", 0, params.mLeftKeys);
+        assertEquals("7 key max 5 L1 right", 4, params.mRightKeys);
+        assertEquals("7 key max 5 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("7 key max 5 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("7 key max 5 L1 [3]", 2, params.getColumnPos(2));
+        assertEquals("7 key max 5 L1 [4]", 3, params.getColumnPos(3));
+        assertEquals("7 key max 5 L1 [5]", 0, params.getColumnPos(4));
+        assertEquals("7 key max 5 L1 [6]", 1, params.getColumnPos(5));
+        assertEquals("7 key max 5 L1 [7]", 2, params.getColumnPos(6));
+        assertEquals("7 key max 5 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key max 5 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___   [5] [6] [7]
+    // |___ [3] <1> [2] [4]
+    public void testLayout7KeyMax5L2() {
+        MoreKeysKeyboardParams params = createParams(7, 5, XPOS_L2);
+        assertEquals("7 key max 5 L2 columns", 4, params.mNumColumns);
+        assertEquals("7 key max 5 L2 rows", 2, params.mNumRows);
+        assertEquals("7 key max 5 L2 left", 1, params.mLeftKeys);
+        assertEquals("7 key max 5 L2 right", 3, params.mRightKeys);
+        assertEquals("7 key max 5 L2 <1>", 0, params.getColumnPos(0));
+        assertEquals("7 key max 5 L2 [2]", 1, params.getColumnPos(1));
+        assertEquals("7 key max 5 L2 [3]", -1, params.getColumnPos(2));
+        assertEquals("7 key max 5 L2 [4]", 2, params.getColumnPos(3));
+        assertEquals("7 key max 5 L2 [5]", 0, params.getColumnPos(4));
+        assertEquals("7 key max 5 L2 [6]", 1, params.getColumnPos(5));
+        assertEquals("7 key max 5 L2 [7]", 2, params.getColumnPos(6));
+        assertEquals("7 key max 5 L2 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("7 key max 5 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    //     [7] [6] [5]|
+    // [4] [3] [2] <1>|
+    public void testLayout7KeyMax5R0() {
+        MoreKeysKeyboardParams params = createParams(7, 5, XPOS_R0);
+        assertEquals("7 key max 5 R0 columns", 4, params.mNumColumns);
+        assertEquals("7 key max 5 R0 rows", 2, params.mNumRows);
+        assertEquals("7 key max 5 R0 left", 3, params.mLeftKeys);
+        assertEquals("7 key max 5 R0 right", 1, params.mRightKeys);
+        assertEquals("7 key max 5 R0 <1>", 0, params.getColumnPos(0));
+        assertEquals("7 key max 5 R0 [2]", -1, params.getColumnPos(1));
+        assertEquals("7 key max 5 R0 [3]", -2, params.getColumnPos(2));
+        assertEquals("7 key max 5 R0 [4]", -3, params.getColumnPos(3));
+        assertEquals("7 key max 5 R0 [5]", 0, params.getColumnPos(4));
+        assertEquals("7 key max 5 R0 [6]", -1, params.getColumnPos(5));
+        assertEquals("7 key max 5 R0 [7]", -2, params.getColumnPos(6));
+        assertEquals("7 key max 5 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key max 5 R0 default", WIDTH * 3, params.getDefaultKeyCoordX());
+    }
+
+    //     [7] [6] [5] ___|
+    // [4] [3] [2] <1> ___|
+    public void testLayout7KeyMax5R1() {
+        MoreKeysKeyboardParams params = createParams(7, 5, XPOS_R1);
+        assertEquals("7 key max 5 R1 columns", 4, params.mNumColumns);
+        assertEquals("7 key max 5 R1 rows", 2, params.mNumRows);
+        assertEquals("7 key max 5 R1 left", 3, params.mLeftKeys);
+        assertEquals("7 key max 5 R1 right", 1, params.mRightKeys);
+        assertEquals("7 key max 5 R1 <1>", 0, params.getColumnPos(0));
+        assertEquals("7 key max 5 R1 [2]", -1, params.getColumnPos(1));
+        assertEquals("7 key max 5 R1 [3]", -2, params.getColumnPos(2));
+        assertEquals("7 key max 5 R1 [4]", -3, params.getColumnPos(3));
+        assertEquals("7 key max 5 R1 [5]", 0, params.getColumnPos(4));
+        assertEquals("7 key max 5 R1 [6]", -1, params.getColumnPos(5));
+        assertEquals("7 key max 5 R1 [7]", -2, params.getColumnPos(6));
+        assertEquals("7 key max 5 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key max 5 R1 default", WIDTH * 3, params.getDefaultKeyCoordX());
+    }
+
+    //   [7] [5] [6]   ___|
+    // [4] [3] <1> [2] ___|
+    public void testLayout7KeyMax5R2() {
+        MoreKeysKeyboardParams params = createParams(7, 5, XPOS_R2);
+        assertEquals("7 key max 5 R2 columns", 4, params.mNumColumns);
+        assertEquals("7 key max 5 R2 rows", 2, params.mNumRows);
+        assertEquals("7 key max 5 R2 left", 2, params.mLeftKeys);
+        assertEquals("7 key max 5 R2 right", 2, params.mRightKeys);
+        assertEquals("7 key max 5 R2 <1>", 0, params.getColumnPos(0));
+        assertEquals("7 key max 5 R2 [2]", 1, params.getColumnPos(1));
+        assertEquals("7 key max 5 R2 [3]", -1, params.getColumnPos(2));
+        assertEquals("7 key max 5 R2 [4]", -2, params.getColumnPos(3));
+        assertEquals("7 key max 5 R2 [5]", 0, params.getColumnPos(4));
+        assertEquals("7 key max 5 R2 [6]", 1, params.getColumnPos(5));
+        assertEquals("7 key max 5 R2 [7]", -1, params.getColumnPos(6));
+        assertEquals("7 key max 5 R2 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("7 key max 5 R2 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    //     [7]
+    // [6] [4] [5]
+    // [3] <1> [2]
+    public void testLayout7KeyMax3M0() {
+        MoreKeysKeyboardParams params = createParams(7, 3, XPOS_M0);
+        assertEquals("7 key max 3 M0 columns", 3, params.mNumColumns);
+        assertEquals("7 key max 3 M0 rows", 3, params.mNumRows);
+        assertEquals("7 key max 3 M0 left", 1, params.mLeftKeys);
+        assertEquals("7 key max 3 M0 right", 2, params.mRightKeys);
+        assertEquals("7 key max 3 M0 <1>", 0, params.getColumnPos(0));
+        assertEquals("7 key max 3 M0 [2]", 1, params.getColumnPos(1));
+        assertEquals("7 key max 3 M0 [3]", -1, params.getColumnPos(2));
+        assertEquals("7 key max 3 M0 [4]", 0, params.getColumnPos(3));
+        assertEquals("7 key max 3 M0 [5]", 1, params.getColumnPos(4));
+        assertEquals("7 key max 3 M0 [6]", -1, params.getColumnPos(5));
+        assertEquals("7 key max 3 M0 [7]", 0, params.getColumnPos(6));
+        assertEquals("7 key max 3 M0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key max 3 M0 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    // |[7]
+    // |[4] [5] [6]
+    // |<1> [2] [3]
+    public void testLayout7KeyMax3L0() {
+        MoreKeysKeyboardParams params = createParams(7, 3, XPOS_L0);
+        assertEquals("7 key max 3 L0 columns", 3, params.mNumColumns);
+        assertEquals("7 key max 3 L0 rows", 3, params.mNumRows);
+        assertEquals("7 key max 3 L0 left", 0, params.mLeftKeys);
+        assertEquals("7 key max 3 L0 right", 3, params.mRightKeys);
+        assertEquals("7 key max 3 L0 <1>", 0, params.getColumnPos(0));
+        assertEquals("7 key max 3 L0 [2]", 1, params.getColumnPos(1));
+        assertEquals("7 key max 3 L0 [3]", 2, params.getColumnPos(2));
+        assertEquals("7 key max 3 L0 [4]", 0, params.getColumnPos(3));
+        assertEquals("7 key max 3 L0 [5]", 1, params.getColumnPos(4));
+        assertEquals("7 key max 3 L0 [6]", 2, params.getColumnPos(5));
+        assertEquals("7 key max 3 L0 [7]", 0, params.getColumnPos(6));
+        assertEquals("7 key max 3 L0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key max 3 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___ [7]
+    // |___ [4] [5] [6]
+    // |___ <1> [2] [3]
+    public void testLayout7KeyMax3L1() {
+        MoreKeysKeyboardParams params = createParams(7, 3, XPOS_L1);
+        assertEquals("7 key max 3 L1 columns", 3, params.mNumColumns);
+        assertEquals("7 key max 3 L1 rows", 3, params.mNumRows);
+        assertEquals("7 key max 3 L1 left", 0, params.mLeftKeys);
+        assertEquals("7 key max 3 L1 right", 3, params.mRightKeys);
+        assertEquals("7 key max 3 L1 <1>", 0, params.getColumnPos(0));
+        assertEquals("7 key max 3 L1 [2]", 1, params.getColumnPos(1));
+        assertEquals("7 key max 3 L1 [3]", 2, params.getColumnPos(2));
+        assertEquals("7 key max 3 L1 [4]", 0, params.getColumnPos(3));
+        assertEquals("7 key max 3 L1 [5]", 1, params.getColumnPos(4));
+        assertEquals("7 key max 3 L1 [6]", 2, params.getColumnPos(5));
+        assertEquals("7 key max 3 L1 [7]", 0, params.getColumnPos(6));
+        assertEquals("7 key max 3 L1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key max 3 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
+    }
+
+    // |___     [7]
+    // |___ [6] [4] [5]
+    // |___ [3] <1> [2]
+    public void testLayout7KeyMax3L2() {
+        MoreKeysKeyboardParams params = createParams(7, 3, XPOS_L2);
+        assertEquals("7 key max 3 L2 columns", 3, params.mNumColumns);
+        assertEquals("7 key max 3 L2 rows", 3, params.mNumRows);
+        assertEquals("7 key max 3 L2 left", 1, params.mLeftKeys);
+        assertEquals("7 key max 3 L2 right", 2, params.mRightKeys);
+        assertEquals("7 key max 3 L2 <1>", 0, params.getColumnPos(0));
+        assertEquals("7 key max 3 L2 [2]", 1, params.getColumnPos(1));
+        assertEquals("7 key max 3 L2 [3]", -1, params.getColumnPos(2));
+        assertEquals("7 key max 3 L2 [4]", 0, params.getColumnPos(3));
+        assertEquals("7 key max 3 L2 [5]", 1, params.getColumnPos(4));
+        assertEquals("7 key max 3 L2 [6]", -1, params.getColumnPos(5));
+        assertEquals("7 key max 3 L2 [7]", 0, params.getColumnPos(6));
+        assertEquals("7 key max 3 L2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key max 3 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
+    //         [7]|
+    // [6] [5] [4]|
+    // [3] [2] <1>|
+    public void testLayout7KeyMax3R0() {
+        MoreKeysKeyboardParams params = createParams(7, 3, XPOS_R0);
+        assertEquals("7 key max 3 R0 columns", 3, params.mNumColumns);
+        assertEquals("7 key max 3 R0 rows", 3, params.mNumRows);
+        assertEquals("7 key max 3 R0 left", 2, params.mLeftKeys);
+        assertEquals("7 key max 3 R0 right", 1, params.mRightKeys);
+        assertEquals("7 key max 3 R0 <1>", 0, params.getColumnPos(0));
+        assertEquals("7 key max 3 R0 [2]", -1, params.getColumnPos(1));
+        assertEquals("7 key max 3 R0 [3]", -2, params.getColumnPos(2));
+        assertEquals("7 key max 3 R0 [4]", 0, params.getColumnPos(3));
+        assertEquals("7 key max 3 R0 [5]", -1, params.getColumnPos(4));
+        assertEquals("7 key max 3 R0 [6]", -2, params.getColumnPos(5));
+        assertEquals("7 key max 3 R0 [7]", 0, params.getColumnPos(6));
+        assertEquals("7 key max 3 R0 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key max 3 R0 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    //         [7] ___|
+    // [6] [5] [4] ___|
+    // [3] [2] <1> ___|
+    public void testLayout7KeyMax3R1() {
+        MoreKeysKeyboardParams params = createParams(7, 3, XPOS_R1);
+        assertEquals("7 key max 3 R1 columns", 3, params.mNumColumns);
+        assertEquals("7 key max 3 R1 rows", 3, params.mNumRows);
+        assertEquals("7 key max 3 R1 left", 2, params.mLeftKeys);
+        assertEquals("7 key max 3 R1 right", 1, params.mRightKeys);
+        assertEquals("7 key max 3 R1 <1>", 0, params.getColumnPos(0));
+        assertEquals("7 key max 3 R1 [2]", -1, params.getColumnPos(1));
+        assertEquals("7 key max 3 R1 [3]", -2, params.getColumnPos(2));
+        assertEquals("7 key max 3 R1 [4]", 0, params.getColumnPos(3));
+        assertEquals("7 key max 3 R1 [5]", -1, params.getColumnPos(4));
+        assertEquals("7 key max 3 R1 [6]", -2, params.getColumnPos(5));
+        assertEquals("7 key max 3 R1 [7]", 0, params.getColumnPos(6));
+        assertEquals("7 key max 3 R1 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key max 3 R1 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
+
+    //     [7]     ___|
+    // [6] [4] [5] ___|
+    // [3] <1> [2] ___|
+    public void testLayout7KeyMax3R2() {
+        MoreKeysKeyboardParams params = createParams(7, 3, XPOS_R2);
+        assertEquals("7 key max 3 R2 columns", 3, params.mNumColumns);
+        assertEquals("7 key max 3 R2 rows", 3, params.mNumRows);
+        assertEquals("7 key max 3 R2 left", 1, params.mLeftKeys);
+        assertEquals("7 key max 3 R2 right", 2, params.mRightKeys);
+        assertEquals("7 key max 3 R2 <1>", 0, params.getColumnPos(0));
+        assertEquals("7 key max 3 R2 [2]", 1, params.getColumnPos(1));
+        assertEquals("7 key max 3 R2 [3]", -1, params.getColumnPos(2));
+        assertEquals("7 key max 3 R2 [4]", 0, params.getColumnPos(3));
+        assertEquals("7 key max 3 R2 [5]", 1, params.getColumnPos(4));
+        assertEquals("7 key max 3 R2 [6]", -1, params.getColumnPos(5));
+        assertEquals("7 key max 3 R2 [7]", 0, params.getColumnPos(6));
+        assertEquals("7 key max 3 R2 adjust", 0, params.mTopRowAdjustment);
+        assertEquals("7 key max 3 R2 default", WIDTH * 1, params.getDefaultKeyCoordX());
+    }
+
     // [7] [5] [6] [8]
-    // [3] [1] [2] [4]
+    // [3] <1> [2] [4]
     public void testLayout8KeyMax5M0() {
         MoreKeysKeyboardParams params = createParams(8, 5, XPOS_M0);
         assertEquals("8 key max 5 M0 columns", 4, params.mNumColumns);
         assertEquals("8 key max 5 M0 rows", 2, params.mNumRows);
         assertEquals("8 key max 5 M0 left", 1, params.mLeftKeys);
         assertEquals("8 key max 5 M0 right", 3, params.mRightKeys);
-        assertEquals("8 key max 5 M0 [1]", 0, params.getColumnPos(0));
+        assertEquals("8 key max 5 M0 <1>", 0, params.getColumnPos(0));
         assertEquals("8 key max 5 M0 [2]", 1, params.getColumnPos(1));
         assertEquals("8 key max 5 M0 [3]", -1, params.getColumnPos(2));
         assertEquals("8 key max 5 M0 [4]", 2, params.getColumnPos(3));
@@ -1118,14 +1839,14 @@
     }
 
     // |[5] [6] [7] [8]
-    // |[1] [2] [3] [4]
+    // |<1> [2] [3] [4]
     public void testLayout8KeyMax5L0() {
         MoreKeysKeyboardParams params = createParams(8, 5, XPOS_L0);
         assertEquals("8 key max 5 L0 columns", 4, params.mNumColumns);
         assertEquals("8 key max 5 L0 rows", 2, params.mNumRows);
         assertEquals("8 key max 5 L0 left", 0, params.mLeftKeys);
         assertEquals("8 key max 5 L0 right", 4, params.mRightKeys);
-        assertEquals("8 key max 5 L0 [1]", 0, params.getColumnPos(0));
+        assertEquals("8 key max 5 L0 <1>", 0, params.getColumnPos(0));
         assertEquals("8 key max 5 L0 [2]", 1, params.getColumnPos(1));
         assertEquals("8 key max 5 L0 [3]", 2, params.getColumnPos(2));
         assertEquals("8 key max 5 L0 [4]", 3, params.getColumnPos(3));
@@ -1138,14 +1859,14 @@
     }
 
     // |___ [5] [6] [7] [8]
-    // |___ [1] [2] [3] [4]
+    // |___ <1> [2] [3] [4]
     public void testLayout8KeyMax5L1() {
         MoreKeysKeyboardParams params = createParams(8, 5, XPOS_L1);
         assertEquals("8 key max 5 L1 columns", 4, params.mNumColumns);
         assertEquals("8 key max 5 L1 rows", 2, params.mNumRows);
         assertEquals("8 key max 5 L1 left", 0, params.mLeftKeys);
         assertEquals("8 key max 5 L1 right", 4, params.mRightKeys);
-        assertEquals("8 key max 5 L1 [1]", 0, params.getColumnPos(0));
+        assertEquals("8 key max 5 L1 <1>", 0, params.getColumnPos(0));
         assertEquals("8 key max 5 L1 [2]", 1, params.getColumnPos(1));
         assertEquals("8 key max 5 L1 [3]", 2, params.getColumnPos(2));
         assertEquals("8 key max 5 L1 [4]", 3, params.getColumnPos(3));
@@ -1158,14 +1879,14 @@
     }
 
     // |___ [7] [5] [6] [8]
-    // |___ [3] [1] [2] [4]
+    // |___ [3] <1> [2] [4]
     public void testLayout8KeyMax5L2() {
         MoreKeysKeyboardParams params = createParams(8, 5, XPOS_L2);
         assertEquals("8 key max 5 L2 columns", 4, params.mNumColumns);
         assertEquals("8 key max 5 L2 rows", 2, params.mNumRows);
         assertEquals("8 key max 5 L2 left", 1, params.mLeftKeys);
         assertEquals("8 key max 5 L2 right", 3, params.mRightKeys);
-        assertEquals("8 key max 5 L2 [1]", 0, params.getColumnPos(0));
+        assertEquals("8 key max 5 L2 <1>", 0, params.getColumnPos(0));
         assertEquals("8 key max 5 L2 [2]", 1, params.getColumnPos(1));
         assertEquals("8 key max 5 L2 [3]", -1, params.getColumnPos(2));
         assertEquals("8 key max 5 L2 [4]", 2, params.getColumnPos(3));
@@ -1178,14 +1899,14 @@
     }
 
     // [8] [7] [6] [5]|
-    // [4] [3] [2] [1]|
+    // [4] [3] [2] <1>|
     public void testLayout8KeyMax5R0() {
         MoreKeysKeyboardParams params = createParams(8, 5, XPOS_R0);
         assertEquals("8 key max 5 R0 columns", 4, params.mNumColumns);
         assertEquals("8 key max 5 R0 rows", 2, params.mNumRows);
         assertEquals("8 key max 5 R0 left", 3, params.mLeftKeys);
         assertEquals("8 key max 5 R0 right", 1, params.mRightKeys);
-        assertEquals("8 key max 5 R0 [1]", 0, params.getColumnPos(0));
+        assertEquals("8 key max 5 R0 <1>", 0, params.getColumnPos(0));
         assertEquals("8 key max 5 R0 [2]", -1, params.getColumnPos(1));
         assertEquals("8 key max 5 R0 [3]", -2, params.getColumnPos(2));
         assertEquals("8 key max 5 R0 [4]", -3, params.getColumnPos(3));
@@ -1198,14 +1919,14 @@
     }
 
     // [8] [7] [6] [5] ___|
-    // [4] [3] [2] [1] ___|
+    // [4] [3] [2] <1> ___|
     public void testLayout8KeyMax5R1() {
         MoreKeysKeyboardParams params = createParams(8, 5, XPOS_R1);
         assertEquals("8 key max 5 R1 columns", 4, params.mNumColumns);
         assertEquals("8 key max 5 R1 rows", 2, params.mNumRows);
         assertEquals("8 key max 5 R1 left", 3, params.mLeftKeys);
         assertEquals("8 key max 5 R1 right", 1, params.mRightKeys);
-        assertEquals("8 key max 5 R1 [1]", 0, params.getColumnPos(0));
+        assertEquals("8 key max 5 R1 <1>", 0, params.getColumnPos(0));
         assertEquals("8 key max 5 R1 [2]", -1, params.getColumnPos(1));
         assertEquals("8 key max 5 R1 [3]", -2, params.getColumnPos(2));
         assertEquals("8 key max 5 R1 [4]", -3, params.getColumnPos(3));
@@ -1218,14 +1939,14 @@
     }
 
     // [8] [7] [5] [6] ___|
-    // [4] [3] [1] [2] ___|
+    // [4] [3] <1> [2] ___|
     public void testLayout8KeyMax5R2() {
         MoreKeysKeyboardParams params = createParams(8, 5, XPOS_R2);
         assertEquals("8 key max 5 R2 columns", 4, params.mNumColumns);
         assertEquals("8 key max 5 R2 rows", 2, params.mNumRows);
         assertEquals("8 key max 5 R2 left", 2, params.mLeftKeys);
         assertEquals("8 key max 5 R2 right", 2, params.mRightKeys);
-        assertEquals("8 key max 5 R2 [1]", 0, params.getColumnPos(0));
+        assertEquals("8 key max 5 R2 <1>", 0, params.getColumnPos(0));
         assertEquals("8 key max 5 R2 [2]", 1, params.getColumnPos(1));
         assertEquals("8 key max 5 R2 [3]", -1, params.getColumnPos(2));
         assertEquals("8 key max 5 R2 [4]", -2, params.getColumnPos(3));
@@ -1238,14 +1959,14 @@
     }
 
     //   [8] [6] [7] [9]
-    // [5] [3] [1] [2] [4]
+    // [5] [3] <1> [2] [4]
     public void testLayout9KeyMax5M0() {
         MoreKeysKeyboardParams params = createParams(9, 5, XPOS_M0);
         assertEquals("9 key max 5 M0 columns", 5, params.mNumColumns);
         assertEquals("9 key max 5 M0 rows", 2, params.mNumRows);
         assertEquals("9 key max 5 M0 left", 2, params.mLeftKeys);
         assertEquals("9 key max 5 M0 right", 3, params.mRightKeys);
-        assertEquals("9 key max 5 M0 [1]", 0, params.getColumnPos(0));
+        assertEquals("9 key max 5 M0 <1>", 0, params.getColumnPos(0));
         assertEquals("9 key max 5 M0 [2]", 1, params.getColumnPos(1));
         assertEquals("9 key max 5 M0 [3]", -1, params.getColumnPos(2));
         assertEquals("9 key max 5 M0 [4]", 2, params.getColumnPos(3));
@@ -1258,15 +1979,15 @@
         assertEquals("9 key max 5 M0 default", WIDTH * 2, params.getDefaultKeyCoordX());
     }
 
-    // |  [6] [7] [8] [9]
-    // |[1] [2] [3] [4] [5]
+    // |[6] [7] [8] [9]
+    // |<1> [2] [3] [4] [5]
     public void testLayout9KeyMax5L0() {
         MoreKeysKeyboardParams params = createParams(9, 5, XPOS_L0);
         assertEquals("9 key max 5 L0 columns", 5, params.mNumColumns);
         assertEquals("9 key max 5 L0 rows", 2, params.mNumRows);
         assertEquals("9 key max 5 L0 left", 0, params.mLeftKeys);
         assertEquals("9 key max 5 L0 right", 5, params.mRightKeys);
-        assertEquals("9 key max 5 L0 [1]", 0, params.getColumnPos(0));
+        assertEquals("9 key max 5 L0 <1>", 0, params.getColumnPos(0));
         assertEquals("9 key max 5 L0 [2]", 1, params.getColumnPos(1));
         assertEquals("9 key max 5 L0 [3]", 2, params.getColumnPos(2));
         assertEquals("9 key max 5 L0 [4]", 3, params.getColumnPos(3));
@@ -1275,19 +1996,19 @@
         assertEquals("9 key max 5 L0 [7]", 1, params.getColumnPos(6));
         assertEquals("9 key max 5 L0 [8]", 2, params.getColumnPos(7));
         assertEquals("9 key max 5 L0 [9]", 3, params.getColumnPos(8));
-        assertEquals("9 key max 5 L0 adjust", 1, params.mTopRowAdjustment);
+        assertEquals("9 key max 5 L0 adjust", 0, params.mTopRowAdjustment);
         assertEquals("9 key max 5 L0 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // |___   [6] [7] [8] [9]
-    // |___ [1] [2] [3] [4] [5]
+    // |___ [6] [7] [8] [9]
+    // |___ <1> [2] [3] [4] [5]
     public void testLayout9KeyMax5L1() {
         MoreKeysKeyboardParams params = createParams(9, 5, XPOS_L1);
         assertEquals("9 key max 5 L1 columns", 5, params.mNumColumns);
         assertEquals("9 key max 5 L1 rows", 2, params.mNumRows);
         assertEquals("9 key max 5 L1 left", 0, params.mLeftKeys);
         assertEquals("9 key max 5 L1 right", 5, params.mRightKeys);
-        assertEquals("9 key max 5 L1 [1]", 0, params.getColumnPos(0));
+        assertEquals("9 key max 5 L1 <1>", 0, params.getColumnPos(0));
         assertEquals("9 key max 5 L1 [2]", 1, params.getColumnPos(1));
         assertEquals("9 key max 5 L1 [3]", 2, params.getColumnPos(2));
         assertEquals("9 key max 5 L1 [4]", 3, params.getColumnPos(3));
@@ -1296,40 +2017,40 @@
         assertEquals("9 key max 5 L1 [7]", 1, params.getColumnPos(6));
         assertEquals("9 key max 5 L1 [8]", 2, params.getColumnPos(7));
         assertEquals("9 key max 5 L1 [9]", 3, params.getColumnPos(8));
-        assertEquals("9 key max 5 L1 adjust",1, params.mTopRowAdjustment);
+        assertEquals("9 key max 5 L1 adjust",0, params.mTopRowAdjustment);
         assertEquals("9 key max 5 L1 default", WIDTH * 0, params.getDefaultKeyCoordX());
     }
 
-    // |___   [8] [6] [7] [9]
-    // |___ [3] [1] [2] [4] [5]
+    // |___   [6] [7] [8] [9]
+    // |___ [3] <1> [2] [4] [5]
     public void testLayout9KeyMax5L2() {
         MoreKeysKeyboardParams params = createParams(9, 5, XPOS_L2);
         assertEquals("9 key max 5 L2 columns", 5, params.mNumColumns);
         assertEquals("9 key max 5 L2 rows", 2, params.mNumRows);
         assertEquals("9 key max 5 L2 left", 1, params.mLeftKeys);
         assertEquals("9 key max 5 L2 right", 4, params.mRightKeys);
-        assertEquals("9 key max 5 L2 [1]", 0, params.getColumnPos(0));
+        assertEquals("9 key max 5 L2 <1>", 0, params.getColumnPos(0));
         assertEquals("9 key max 5 L2 [2]", 1, params.getColumnPos(1));
         assertEquals("9 key max 5 L2 [3]", -1, params.getColumnPos(2));
         assertEquals("9 key max 5 L2 [4]", 2, params.getColumnPos(3));
         assertEquals("9 key max 5 L2 [5]", 3, params.getColumnPos(4));
         assertEquals("9 key max 5 L2 [6]", 0, params.getColumnPos(5));
         assertEquals("9 key max 5 L2 [7]", 1, params.getColumnPos(6));
-        assertEquals("9 key max 5 L2 [8]", -1, params.getColumnPos(7));
-        assertEquals("9 key max 5 L2 [9]", 2, params.getColumnPos(8));
-        assertEquals("9 key max 5 L2 adjust", 1, params.mTopRowAdjustment);
+        assertEquals("9 key max 5 L2 [8]", 2, params.getColumnPos(7));
+        assertEquals("9 key max 5 L2 [9]", 3, params.getColumnPos(8));
+        assertEquals("9 key max 5 L2 adjust", -1, params.mTopRowAdjustment);
         assertEquals("9 key max 5 L2 default", WIDTH * 1, params.getDefaultKeyCoordX());
     }
 
-    //   [9] [8] [7] [6]  |
-    // [5] [4] [3] [2] [1]|
+    //     [9] [8] [7] [6]|
+    // [5] [4] [3] [2] <1>|
     public void testLayout9KeyMax5R0() {
         MoreKeysKeyboardParams params = createParams(9, 5, XPOS_R0);
         assertEquals("9 key max 5 R0 columns", 5, params.mNumColumns);
         assertEquals("9 key max 5 R0 rows", 2, params.mNumRows);
         assertEquals("9 key max 5 R0 left", 4, params.mLeftKeys);
         assertEquals("9 key max 5 R0 right", 1, params.mRightKeys);
-        assertEquals("9 key max 5 R0 [1]", 0, params.getColumnPos(0));
+        assertEquals("9 key max 5 R0 <1>", 0, params.getColumnPos(0));
         assertEquals("9 key max 5 R0 [2]", -1, params.getColumnPos(1));
         assertEquals("9 key max 5 R0 [3]", -2, params.getColumnPos(2));
         assertEquals("9 key max 5 R0 [4]", -3, params.getColumnPos(3));
@@ -1338,19 +2059,19 @@
         assertEquals("9 key max 5 R0 [7]", -1, params.getColumnPos(6));
         assertEquals("9 key max 5 R0 [8]", -2, params.getColumnPos(7));
         assertEquals("9 key max 5 R0 [9]", -3, params.getColumnPos(8));
-        assertEquals("9 key max 5 R0 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("9 key max 5 R0 adjust", 0, params.mTopRowAdjustment);
         assertEquals("9 key max 5 R0 default", WIDTH * 4, params.getDefaultKeyCoordX());
     }
 
-    //   [9] [8] [7] [6]   ___|
-    // [5] [4] [3] [2] [1] ___|
+    //     [9] [8] [7] [6] ___|
+    // [5] [4] [3] [2] <1> ___|
     public void testLayout9KeyMax5R1() {
         MoreKeysKeyboardParams params = createParams(9, 5, XPOS_R1);
         assertEquals("9 key max 5 R1 columns", 5, params.mNumColumns);
         assertEquals("9 key max 5 R1 rows", 2, params.mNumRows);
         assertEquals("9 key max 5 R1 left", 4, params.mLeftKeys);
         assertEquals("9 key max 5 R1 right", 1, params.mRightKeys);
-        assertEquals("9 key max 5 R1 [1]", 0, params.getColumnPos(0));
+        assertEquals("9 key max 5 R1 <1>", 0, params.getColumnPos(0));
         assertEquals("9 key max 5 R1 [2]", -1, params.getColumnPos(1));
         assertEquals("9 key max 5 R1 [3]", -2, params.getColumnPos(2));
         assertEquals("9 key max 5 R1 [4]", -3, params.getColumnPos(3));
@@ -1359,19 +2080,19 @@
         assertEquals("9 key max 5 R1 [7]", -1, params.getColumnPos(6));
         assertEquals("9 key max 5 R1 [8]", -2, params.getColumnPos(7));
         assertEquals("9 key max 5 R1 [9]", -3, params.getColumnPos(8));
-        assertEquals("9 key max 5 R1 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("9 key max 5 R1 adjust", 0, params.mTopRowAdjustment);
         assertEquals("9 key max 5 R1 default", WIDTH * 4, params.getDefaultKeyCoordX());
     }
 
     //   [9] [8] [6] [7]   ___|
-    // [5] [4] [3] [1] [2] ___|
+    // [5] [4] [3] <1> [2] ___|
     public void testLayout9KeyMax5R2() {
         MoreKeysKeyboardParams params = createParams(9, 5, XPOS_R2);
         assertEquals("9 key max 5 R2 columns", 5, params.mNumColumns);
         assertEquals("9 key max 5 R2 rows", 2, params.mNumRows);
         assertEquals("9 key max 5 R2 left", 3, params.mLeftKeys);
         assertEquals("9 key max 5 R2 right", 2, params.mRightKeys);
-        assertEquals("9 key max 5 R2 [1]", 0, params.getColumnPos(0));
+        assertEquals("9 key max 5 R2 <1>", 0, params.getColumnPos(0));
         assertEquals("9 key max 5 R2 [2]", 1, params.getColumnPos(1));
         assertEquals("9 key max 5 R2 [3]", -1, params.getColumnPos(2));
         assertEquals("9 key max 5 R2 [4]", -2, params.getColumnPos(3));
@@ -1385,14 +2106,14 @@
     }
 
     // [A] [8] [6] [7] [9]
-    // [5] [3] [1] [2] [4]
+    // [5] [3] <1> [2] [4]
     public void testLayout10KeyMax5M0() {
         MoreKeysKeyboardParams params = createParams(10, 5, XPOS_M0);
         assertEquals("10 key max 5 M0 columns", 5, params.mNumColumns);
         assertEquals("10 key max 5 M0 rows", 2, params.mNumRows);
         assertEquals("10 key max 5 M0 left", 2, params.mLeftKeys);
         assertEquals("10 key max 5 M0 right", 3, params.mRightKeys);
-        assertEquals("10 key max 5 M0 [1]", 0, params.getColumnPos(0));
+        assertEquals("10 key max 5 M0 <1>", 0, params.getColumnPos(0));
         assertEquals("10 key max 5 M0 [2]", 1, params.getColumnPos(1));
         assertEquals("10 key max 5 M0 [3]", -1, params.getColumnPos(2));
         assertEquals("10 key max 5 M0 [4]", 2, params.getColumnPos(3));
@@ -1407,14 +2128,14 @@
     }
 
     // |[6] [7] [8] [9] [A]
-    // |[1] [2] [3] [4] [5]
+    // |<1> [2] [3] [4] [5]
     public void testLayout10KeyMax5L0() {
         MoreKeysKeyboardParams params = createParams(10, 5, XPOS_L0);
         assertEquals("10 key max 5 L0 columns", 5, params.mNumColumns);
         assertEquals("10 key max 5 L0 rows", 2, params.mNumRows);
         assertEquals("10 key max 5 L0 left", 0, params.mLeftKeys);
         assertEquals("10 key max 5 L0 right", 5, params.mRightKeys);
-        assertEquals("10 key max 5 L0 [1]", 0, params.getColumnPos(0));
+        assertEquals("10 key max 5 L0 <1>", 0, params.getColumnPos(0));
         assertEquals("10 key max 5 L0 [2]", 1, params.getColumnPos(1));
         assertEquals("10 key max 5 L0 [3]", 2, params.getColumnPos(2));
         assertEquals("10 key max 5 L0 [4]", 3, params.getColumnPos(3));
@@ -1429,14 +2150,14 @@
     }
 
     // |___ [6] [7] [8] [9] [A]
-    // |___ [1] [2] [3] [4] [5]
+    // |___ <1> [2] [3] [4] [5]
     public void testLayout10KeyMax5L1() {
         MoreKeysKeyboardParams params = createParams(10, 5, XPOS_L1);
         assertEquals("10 key max 5 L1 columns", 5, params.mNumColumns);
         assertEquals("10 key max 5 L1 rows", 2, params.mNumRows);
         assertEquals("10 key max 5 L1 left", 0, params.mLeftKeys);
         assertEquals("10 key max 5 L1 right", 5, params.mRightKeys);
-        assertEquals("10 key max 5 L1 [1]", 0, params.getColumnPos(0));
+        assertEquals("10 key max 5 L1 <1>", 0, params.getColumnPos(0));
         assertEquals("10 key max 5 L1 [2]", 1, params.getColumnPos(1));
         assertEquals("10 key max 5 L1 [3]", 2, params.getColumnPos(2));
         assertEquals("10 key max 5 L1 [4]", 3, params.getColumnPos(3));
@@ -1451,14 +2172,14 @@
     }
 
     // |___ [8] [6] [7] [9] [A]
-    // |___ [3] [1] [2] [4] [5]
+    // |___ [3] <1> [2] [4] [5]
     public void testLayout10KeyMax5L2() {
         MoreKeysKeyboardParams params = createParams(10, 5, XPOS_L2);
         assertEquals("10 key max 5 L2 columns", 5, params.mNumColumns);
         assertEquals("10 key max 5 L2 rows", 2, params.mNumRows);
         assertEquals("10 key max 5 L2 left", 1, params.mLeftKeys);
         assertEquals("10 key max 5 L2 right", 4, params.mRightKeys);
-        assertEquals("10 key max 5 L2 [1]", 0, params.getColumnPos(0));
+        assertEquals("10 key max 5 L2 <1>", 0, params.getColumnPos(0));
         assertEquals("10 key max 5 L2 [2]", 1, params.getColumnPos(1));
         assertEquals("10 key max 5 L2 [3]", -1, params.getColumnPos(2));
         assertEquals("10 key max 5 L2 [4]", 2, params.getColumnPos(3));
@@ -1473,14 +2194,14 @@
     }
 
     // [A] [9] [8] [7] [6]|
-    // [5] [4] [3] [2] [1]|
+    // [5] [4] [3] [2] <1>|
     public void testLayout10KeyMax5R0() {
         MoreKeysKeyboardParams params = createParams(10, 5, XPOS_R0);
         assertEquals("10 key max 5 R0 columns", 5, params.mNumColumns);
         assertEquals("10 key max 5 R0 rows", 2, params.mNumRows);
         assertEquals("10 key max 5 R0 left", 4, params.mLeftKeys);
         assertEquals("10 key max 5 R0 right", 1, params.mRightKeys);
-        assertEquals("10 key max 5 R0 [1]", 0, params.getColumnPos(0));
+        assertEquals("10 key max 5 R0 <1>", 0, params.getColumnPos(0));
         assertEquals("10 key max 5 R0 [2]", -1, params.getColumnPos(1));
         assertEquals("10 key max 5 R0 [3]", -2, params.getColumnPos(2));
         assertEquals("10 key max 5 R0 [4]", -3, params.getColumnPos(3));
@@ -1495,14 +2216,14 @@
     }
 
     // [A] [9] [8] [7] [6] ___|
-    // [5] [4] [3] [2] [1] ___|
+    // [5] [4] [3] [2] <1> ___|
     public void testLayout10KeyMax5R1() {
         MoreKeysKeyboardParams params = createParams(10, 5, XPOS_R1);
         assertEquals("10 key max 5 R1 columns", 5, params.mNumColumns);
         assertEquals("10 key max 5 R1 rows", 2, params.mNumRows);
         assertEquals("10 key max 5 R1 left", 4, params.mLeftKeys);
         assertEquals("10 key max 5 R1 right", 1, params.mRightKeys);
-        assertEquals("10 key max 5 R1 [1]", 0, params.getColumnPos(0));
+        assertEquals("10 key max 5 R1 <1>", 0, params.getColumnPos(0));
         assertEquals("10 key max 5 R1 [2]", -1, params.getColumnPos(1));
         assertEquals("10 key max 5 R1 [3]", -2, params.getColumnPos(2));
         assertEquals("10 key max 5 R1 [4]", -3, params.getColumnPos(3));
@@ -1517,14 +2238,14 @@
     }
 
     // [A] [9] [8] [6] [7] ___|
-    // [5] [4] [3] [1] [2] ___|
+    // [5] [4] [3] <1> [2] ___|
     public void testLayout10KeyMax5R2() {
         MoreKeysKeyboardParams params = createParams(10, 5, XPOS_R2);
         assertEquals("10 key max 5 R2 columns", 5, params.mNumColumns);
         assertEquals("10 key max 5 R2 rows", 2, params.mNumRows);
         assertEquals("10 key max 5 R2 left", 3, params.mLeftKeys);
         assertEquals("10 key max 5 R2 right", 2, params.mRightKeys);
-        assertEquals("10 key max 5 R2 [1]", 0, params.getColumnPos(0));
+        assertEquals("10 key max 5 R2 <1>", 0, params.getColumnPos(0));
         assertEquals("10 key max 5 R2 [2]", 1, params.getColumnPos(1));
         assertEquals("10 key max 5 R2 [3]", -1, params.getColumnPos(2));
         assertEquals("10 key max 5 R2 [4]", -2, params.getColumnPos(3));
@@ -1538,16 +2259,16 @@
         assertEquals("10 key max 5 R2 default", WIDTH * 3, params.getDefaultKeyCoordX());
     }
 
-    //   [B] [9] [A]
+    //   [9] [A] [B]
     // [7] [5] [6] [8]
-    // [3] [1] [2] [4]
+    // [3] <1> [2] [4]
     public void testLayout11KeyMax5M0() {
         MoreKeysKeyboardParams params = createParams(11, 5, XPOS_M0);
         assertEquals("11 key max 5 M0 columns", 4, params.mNumColumns);
         assertEquals("11 key max 5 M0 rows", 3, params.mNumRows);
         assertEquals("11 key max 5 M0 left", 1, params.mLeftKeys);
         assertEquals("11 key max 5 M0 right", 3, params.mRightKeys);
-        assertEquals("11 key max 5 M0 [1]", 0, params.getColumnPos(0));
+        assertEquals("11 key max 5 M0 <1>", 0, params.getColumnPos(0));
         assertEquals("11 key max 5 M0 [2]", 1, params.getColumnPos(1));
         assertEquals("11 key max 5 M0 [3]", -1, params.getColumnPos(2));
         assertEquals("11 key max 5 M0 [4]", 2, params.getColumnPos(3));
@@ -1557,21 +2278,21 @@
         assertEquals("11 key max 5 M0 [8]", 2, params.getColumnPos(7));
         assertEquals("11 key max 5 M0 [9]", 0, params.getColumnPos(8));
         assertEquals("11 key max 5 M0 [A]", 1, params.getColumnPos(9));
-        assertEquals("11 key max 5 M0 [B]", -1, params.getColumnPos(10));
-        assertEquals("11 key max 5 M0 adjust", 1, params.mTopRowAdjustment);
+        assertEquals("11 key max 5 M0 [B]", 2, params.getColumnPos(10));
+        assertEquals("11 key max 5 M0 adjust", -1, params.mTopRowAdjustment);
         assertEquals("11 key max 5 M0 default", WIDTH * 1, params.getDefaultKeyCoordX());
     }
 
     // [B] [9] [A] [C]
     // [7] [5] [6] [8]
-    // [3] [1] [2] [4]
+    // [3] <1> [2] [4]
     public void testLayout12KeyMax5M0() {
         MoreKeysKeyboardParams params = createParams(12, 5, XPOS_M0);
         assertEquals("12 key max 5 M0 columns", 4, params.mNumColumns);
         assertEquals("12 key max 5 M0 rows", 3, params.mNumRows);
         assertEquals("12 key max 5 M0 left", 1, params.mLeftKeys);
         assertEquals("12 key max 5 M0 right", 3, params.mRightKeys);
-        assertEquals("12 key max 5 M0 [1]", 0, params.getColumnPos(0));
+        assertEquals("12 key max 5 M0 <1>", 0, params.getColumnPos(0));
         assertEquals("12 key max 5 M0 [2]", 1, params.getColumnPos(1));
         assertEquals("12 key max 5 M0 [3]", -1, params.getColumnPos(2));
         assertEquals("12 key max 5 M0 [4]", 2, params.getColumnPos(3));
@@ -1587,17 +2308,16 @@
         assertEquals("12 key max 5 M0 default", WIDTH * 1, params.getDefaultKeyCoordX());
     }
 
-
     //     [D] [B] [C]
     // [A] [8] [6] [7] [9]
-    // [5] [3] [1] [2] [4]
+    // [5] [3] <1> [2] [4]
     public void testLayout13KeyMax5M0() {
         MoreKeysKeyboardParams params = createParams(13, 5, XPOS_M0);
         assertEquals("13 key max 5 M0 columns", 5, params.mNumColumns);
         assertEquals("13 key max 5 M0 rows", 3, params.mNumRows);
         assertEquals("13 key max 5 M0 left", 2, params.mLeftKeys);
         assertEquals("13 key max 5 M0 right", 3, params.mRightKeys);
-        assertEquals("13 key max 5 M0 [1]", 0, params.getColumnPos(0));
+        assertEquals("13 key max 5 M0 <1>", 0, params.getColumnPos(0));
         assertEquals("13 key max 5 M0 [2]", 1, params.getColumnPos(1));
         assertEquals("13 key max 5 M0 [3]", -1, params.getColumnPos(2));
         assertEquals("13 key max 5 M0 [4]", 2, params.getColumnPos(3));
@@ -1613,4 +2333,31 @@
         assertEquals("13 key max 5 M0 adjust", 0, params.mTopRowAdjustment);
         assertEquals("13 key max 5 M0 default", WIDTH * 2, params.getDefaultKeyCoordX());
     }
+
+    //   [D] [B] [C] [E]
+    // [A] [8] [6] [7] [9]
+    // [5] [3] <1> [2] [4]
+    public void testLayout14KeyMax5M0() {
+        MoreKeysKeyboardParams params = createParams(14, 5, XPOS_M0);
+        assertEquals("13 key max 5 M0 columns", 5, params.mNumColumns);
+        assertEquals("13 key max 5 M0 rows", 3, params.mNumRows);
+        assertEquals("13 key max 5 M0 left", 2, params.mLeftKeys);
+        assertEquals("13 key max 5 M0 right", 3, params.mRightKeys);
+        assertEquals("13 key max 5 M0 <1>", 0, params.getColumnPos(0));
+        assertEquals("13 key max 5 M0 [2]", 1, params.getColumnPos(1));
+        assertEquals("13 key max 5 M0 [3]", -1, params.getColumnPos(2));
+        assertEquals("13 key max 5 M0 [4]", 2, params.getColumnPos(3));
+        assertEquals("13 key max 5 M0 [5]", -2, params.getColumnPos(4));
+        assertEquals("13 key max 5 M0 [6]", 0, params.getColumnPos(5));
+        assertEquals("13 key max 5 M0 [7]", 1, params.getColumnPos(6));
+        assertEquals("13 key max 5 M0 [8]", -1, params.getColumnPos(7));
+        assertEquals("13 key max 5 M0 [9]", 2, params.getColumnPos(8));
+        assertEquals("13 key max 5 M0 [A]", -2, params.getColumnPos(9));
+        assertEquals("13 key max 5 M0 [B]", 0, params.getColumnPos(10));
+        assertEquals("13 key max 5 M0 [C]", 1, params.getColumnPos(11));
+        assertEquals("13 key max 5 M0 [D]", -1, params.getColumnPos(12));
+        assertEquals("13 key max 5 M0 [E]", 2, params.getColumnPos(13));
+        assertEquals("13 key max 5 M0 adjust", -1, params.mTopRowAdjustment);
+        assertEquals("13 key max 5 M0 default", WIDTH * 2, params.getDefaultKeyCoordX());
+    }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java
index 07f5848..3fc2b02 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java
@@ -280,6 +280,34 @@
         }
     }
 
+    public void testEmptyEntry() {
+        assertMoreKeys("null more keys and null additons",
+                null,
+                null,
+                null);
+        assertMoreKeys("null more keys and empty additons",
+                null,
+                new String[0],
+                null);
+        assertMoreKeys("empty more keys and null additons",
+                new String[0],
+                null,
+                null);
+        assertMoreKeys("empty more keys and empty additons",
+                new String[0],
+                new String[0],
+                null);
+
+        assertMoreKeys("filter out empty more keys",
+                new String[] { null, "a", "", "b", null },
+                null,
+                new String[] { "a", "b" });
+        assertMoreKeys("filter out empty additons",
+                new String[] { "a", "%", "b", "%", "c", "%", "d" },
+                new String[] { null, "A", "", "B", null },
+                new String[] { "a", "A", "b", "B", "c", "d" });
+    }
+
     public void testInsertAdditionalMoreKeys() {
         // Escaped marker.
         assertMoreKeys("escaped marker",
@@ -289,11 +317,11 @@
 
         // 0 more key.
         assertMoreKeys("null & null", null, null, null);
-        assertMoreKeys("null & 1 additional",
+        assertMoreKeys("null & 1 additon",
                 null,
                 new String[] { "1" },
                 new String[] { "1" });
-        assertMoreKeys("null & 2 additionals",
+        assertMoreKeys("null & 2 additons",
                 null,
                 new String[] { "1", "2" },
                 new String[] { "1", "2" });
@@ -327,29 +355,29 @@
                 new String[] { "1", "2", "A", "B" });
 
         // 1 marker.
-        assertMoreKeys("1 more key & 1 additional & marker at head",
+        assertMoreKeys("1 more key & 1 additon & marker at head",
                 new String[] { "%", "A" },
                 new String[] { "1" },
                 new String[] { "1", "A" });
-        assertMoreKeys("1 more key & 1 additional & marker at tail",
+        assertMoreKeys("1 more key & 1 additon & marker at tail",
                 new String[] { "A", "%" },
                 new String[] { "1" },
                 new String[] { "A", "1" });
-        assertMoreKeys("2 more keys & 1 additional & marker at middle",
+        assertMoreKeys("2 more keys & 1 additon & marker at middle",
                 new String[] { "A", "%", "B" },
                 new String[] { "1" },
                 new String[] { "A", "1", "B" });
 
         // 1 marker & excess additional more keys.
-        assertMoreKeys("1 more key & 2 additionals & marker at head",
+        assertMoreKeys("1 more key & 2 additons & marker at head",
                 new String[] { "%", "A", "B" },
                 new String[] { "1", "2" },
                 new String[] { "1", "A", "B", "2" });
-        assertMoreKeys("1 more key & 2 additionals & marker at tail",
+        assertMoreKeys("1 more key & 2 additons & marker at tail",
                 new String[] { "A", "B", "%" },
                 new String[] { "1", "2" },
                 new String[] { "A", "B", "1", "2" });
-        assertMoreKeys("2 more keys & 2 additionals & marker at middle",
+        assertMoreKeys("2 more keys & 2 additons & marker at middle",
                 new String[] { "A", "%", "B" },
                 new String[] { "1", "2" },
                 new String[] { "A", "1", "B", "2" });
@@ -384,32 +412,32 @@
                 new String[] { "1", "2" },
                 new String[] { "A", "1", "B", "2" });
 
-        // 2 markers & excess additional keys.
-        assertMoreKeys("0 more key & 2 addtional & 2 markers",
+        // 2 markers & excess additional more keys.
+        assertMoreKeys("0 more key & 2 additons & 2 markers",
                 new String[] { "%", "%" },
                 new String[] { "1", "2", "3" },
                 new String[] { "1", "2", "3" });
-        assertMoreKeys("1 more key & 2 addtional & 2 markers at head",
+        assertMoreKeys("1 more key & 2 additons & 2 markers at head",
                 new String[] { "%", "%", "A" },
                 new String[] { "1", "2", "3" },
                 new String[] { "1", "2", "A", "3" });
-        assertMoreKeys("1 more key & 2 addtional & 2 markers at tail",
+        assertMoreKeys("1 more key & 2 additons & 2 markers at tail",
                 new String[] { "A", "%", "%" },
                 new String[] { "1", "2", "3" },
                 new String[] { "A", "1", "2", "3" });
-        assertMoreKeys("2 more keys & 2 addtional & 2 markers at middle",
+        assertMoreKeys("2 more keys & 2 additons & 2 markers at middle",
                 new String[] { "A", "%", "%", "B" },
                 new String[] { "1", "2", "3" },
                 new String[] { "A", "1", "2", "B", "3" });
-        assertMoreKeys("2 more keys & 2 addtional & 2 markers at head & middle",
+        assertMoreKeys("2 more keys & 2 additons & 2 markers at head & middle",
                 new String[] { "%", "A", "%", "B" },
                 new String[] { "1", "2", "3" },
                 new String[] { "1", "A", "2", "B", "3" });
-        assertMoreKeys("2 more keys & 2 addtional & 2 markers at head & tail",
+        assertMoreKeys("2 more keys & 2 additons & 2 markers at head & tail",
                 new String[] { "%", "A", "B", "%" },
                 new String[] { "1", "2", "3" },
                 new String[] { "1", "A", "B", "2", "3" });
-        assertMoreKeys("2 more keys & 2 addtional & 2 markers at middle & tail",
+        assertMoreKeys("2 more keys & 2 additons & 2 markers at middle & tail",
                 new String[] { "A", "%", "B", "%" },
                 new String[] { "1", "2", "3" },
                 new String[] { "A", "1", "B", "2", "3" });
@@ -437,31 +465,31 @@
                 new String[] { "A", "B" });
 
         // Excess markers.
-        assertMoreKeys("0 more key & 1 addtional & excess marker",
+        assertMoreKeys("0 more key & 1 additon & excess marker",
                 new String[] { "%", "%" },
                 new String[] { "1" },
                 new String[] { "1" });
-        assertMoreKeys("1 more key & 1 addtional & excess marker at head",
+        assertMoreKeys("1 more key & 1 additon & excess marker at head",
                 new String[] { "%", "%", "A" },
                 new String[] { "1" },
                 new String[] { "1", "A" });
-        assertMoreKeys("1 more key & 1 addtional & excess marker at tail",
+        assertMoreKeys("1 more key & 1 additon & excess marker at tail",
                 new String[] { "A", "%", "%" },
                 new String[] { "1" },
                 new String[] { "A", "1" });
-        assertMoreKeys("2 more keys & 1 addtional & excess marker at middle",
+        assertMoreKeys("2 more keys & 1 additon & excess marker at middle",
                 new String[] { "A", "%", "%", "B" },
                 new String[] { "1" },
                 new String[] { "A", "1", "B" });
-        assertMoreKeys("2 more keys & 1 addtional & excess markers",
+        assertMoreKeys("2 more keys & 1 additon & excess markers",
                 new String[] { "%", "A", "%", "B", "%" },
                 new String[] { "1" },
                 new String[] { "1", "A", "B" });
-        assertMoreKeys("2 more keys & 2 addtionals & excess markers",
+        assertMoreKeys("2 more keys & 2 additons & excess markers",
                 new String[] { "%", "A", "%", "B", "%" },
                 new String[] { "1", "2" },
                 new String[] { "1", "A", "2", "B" });
-        assertMoreKeys("2 more keys & 3 addtionals & excess markers",
+        assertMoreKeys("2 more keys & 3 additons & excess markers",
                 new String[] { "%", "A", "%", "%", "B", "%" },
                 new String[] { "1", "2", "3" },
                 new String[] { "1", "A", "2", "3", "B" });
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateMultiTouchTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateMultiTouchTests.java
index e9f37af..0e6caaf 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateMultiTouchTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateMultiTouchTests.java
@@ -227,4 +227,17 @@
         // Release "123?" key, switch back to alphabet.
         releaseKey(CODE_SYMBOL, ALPHABET_UNSHIFTED);
     }
+
+    // Chording letter key with shift key.
+    public void testChordingLetterAndShiftKey() {
+        // Press letter key and hold.
+        pressKey('z', ALPHABET_UNSHIFTED);
+        // Press shift key, {@link PointerTracker} will fire a phantom release letter key.
+        chordingReleaseKey('z', ALPHABET_UNSHIFTED);
+        chordingPressKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED);
+        // Press another letter key and hold.
+        chordingPressAndReleaseKey('J', ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
+        // Release shift key
+        releaseKey(CODE_SHIFT, ALPHABET_UNSHIFTED);
+    }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateSingleTouchTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateSingleTouchTests.java
index 8c53fb5..ef0facf 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateSingleTouchTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateSingleTouchTests.java
@@ -687,4 +687,67 @@
         // Press/release "?123" key, enter symbols (not symbols shifted).
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
     }
+
+    // Rapidly type shift key.
+    public void testRapidShiftTyping() {
+        // Press/release shift key
+        pressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
+        // Rapidly press/release letter key.
+        secondPressAndReleaseKey('J', ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
+        // Rapidly press/release shift key.
+        secondPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
+        // Rapidly press/release letter key.
+        secondPressAndReleaseKey('J', ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
+        // Rapidly press/release shift key.
+        secondPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
+        // Rapidly press/release letter key.
+        secondPressAndReleaseKey('J', ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
+
+        // Press/release shift key to enter alphabet manual shifted.
+        pressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
+        // Press/release shift key
+        pressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
+        // Rapidly press/release letter key.
+        secondPressAndReleaseKey('j', ALPHABET_UNSHIFTED, ALPHABET_UNSHIFTED);
+        // Rapidly press/release shift key.
+        secondPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
+        // Rapidly press/release letter key.
+        secondPressAndReleaseKey('J', ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
+        // Rapidly press/release shift key.
+        secondPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
+        // Rapidly press/release letter key.
+        secondPressAndReleaseKey('J', ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
+
+        // Long press shift key to enter alphabet shift locked.
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        // Press/release shift key
+        pressAndReleaseKey(CODE_SHIFT, ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
+        // Rapidly press/release letter key.
+        secondPressAndReleaseKey('j', ALPHABET_UNSHIFTED, ALPHABET_UNSHIFTED);
+        // Rapidly press/release shift key.
+        secondPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
+        // Rapidly press/release letter key.
+        secondPressAndReleaseKey('J', ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
+        // Rapidly press/release shift key.
+        secondPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
+        // Rapidly press/release letter key.
+        secondPressAndReleaseKey('J', ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
+
+        // Set auto caps mode on.
+        setAutoCapsMode(AUTO_CAPS);
+        // Press/release auto caps trigger letter to enter alphabet automatic shifted.
+        pressAndReleaseKey(CODE_AUTO_CAPS_TRIGGER, ALPHABET_UNSHIFTED, ALPHABET_AUTOMATIC_SHIFTED);
+        // Press/release shift key
+        pressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
+        // Rapidly press/release letter key.
+        secondPressAndReleaseKey('j', ALPHABET_UNSHIFTED, ALPHABET_UNSHIFTED);
+        // Rapidly press/release shift key.
+        secondPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
+        // Rapidly press/release letter key.
+        secondPressAndReleaseKey('J', ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
+        // Rapidly press/release shift key.
+        secondPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
+        // Rapidly press/release letter key.
+        secondPressAndReleaseKey('J', ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
+    }
 }
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java b/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java
index a01b69c..999e08a 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java
@@ -125,6 +125,11 @@
     }
 
     @Override
+    public void cancelDoubleTapTimer() {
+        mIsInDoubleTapTimeout = false;
+    }
+
+    @Override
     public boolean isInDoubleTapTimeout() {
         return mIsInDoubleTapTimeout;
     }
@@ -135,6 +140,11 @@
     }
 
     @Override
+    public void cancelLongPressTimer() {
+        mLongPressTimeoutCode = 0;
+    }
+
+    @Override
     public void hapticAndAudioFeedback(int code) {
         // Nothing to do.
     }