Merge "Add jni method to update entries for a word efficiently."
diff --git a/java-overridable/src/com/android/inputmethod/latin/utils/StatsUtils.java b/java-overridable/src/com/android/inputmethod/latin/utils/StatsUtils.java
index ad34dc2..fcaeca8 100644
--- a/java-overridable/src/com/android/inputmethod/latin/utils/StatsUtils.java
+++ b/java-overridable/src/com/android/inputmethod/latin/utils/StatsUtils.java
@@ -79,4 +79,7 @@
     public static void onWordCommitSuggestionPickedManually(
             final String commitWord, final boolean isBatchMode) {
     }
+
+    public static void onLoadSettings(SettingsValues settingsValues) {
+    }
 }
diff --git a/java/res/values/strings-talkback-descriptions.xml b/java/res/values/strings-talkback-descriptions.xml
index 80c7bdb..36fa7b3 100644
--- a/java/res/values/strings-talkback-descriptions.xml
+++ b/java/res/values/strings-talkback-descriptions.xml
@@ -139,6 +139,18 @@
     <string name="spoken_symbol_unknown">Unknown symbol</string>
     <!-- Spoken description for unknown emoji code point. -->
     <string name="spoken_emoji_unknown">Unknown emoji</string>
+    <!-- Spoken description for emoticons ":-!". -->
+    <string name="spoken_emoticon_3A_2D_21_20">Bored face</string>
+    <!-- Spoken description for emoticons ":-$". -->
+    <string name="spoken_emoticon_3A_2D_24_20">Embarrassed face</string>
+    <!-- Spoken description for emoticons "B-)". -->
+    <string name="spoken_emoticon_42_2D_29_20">Face wearing sunglasses</string>
+    <!-- Spoken description for emoticons ":O". -->
+    <string name="spoken_emoticon_3A_4F_20">Surprised face</string>
+    <!-- Spoken description for emoticons ":-*". -->
+    <string name="spoken_emoticon_3A_2D_2A_20">Kissing face</string>
+    <!-- Spoken description for emoticons ":-[". -->
+    <string name="spoken_emoticon_3A_2D_5B_20">Frowning face</string>
 
     <!-- Spoken descriptions when opening a more keys keyboard that has alternative characters. -->
     <string name="spoken_open_more_keys_keyboard">Alternative characters are available</string>
diff --git a/java/res/xml-sw600dp/rows_bengali_akkhor.xml b/java/res/xml-sw600dp/rows_bengali_akkhor.xml
new file mode 100644
index 0000000..3e81a14
--- /dev/null
+++ b/java/res/xml-sw600dp/rows_bengali_akkhor.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" >
+    <include latin:keyboardLayout="@xml/key_styles_common" />
+    <Row
+        latin:keyLabelFlags="fontNormal"
+        latin:keyWidth="8.182%p" >
+        <include latin:keyboardLayout="@xml/rowkeys_bengali_akkhor1" />
+        <Key
+            latin:keyStyle="deleteKeyStyle"
+            latin:keyWidth="fillRight" />
+    </Row>
+    <Row
+        latin:keyLabelFlags="fontNormal"
+        latin:keyWidth="8.182%p" >
+        <include latin:keyboardLayout="@xml/rowkeys_bengali_akkhor2" />
+        <Key
+            latin:keyStyle="enterKeyStyle"
+            latin:keyWidth="fillRight" />
+    </Row>
+    <Row
+        latin:keyLabelFlags="fontNormal"
+        latin:keyWidth="8.182%p" >
+        <Key
+            latin:keyStyle="shiftKeyStyle"
+            latin:keyWidth="10.0%p" />
+
+        <include latin:keyboardLayout="@xml/rowkeys_bengali_akkhor3" />
+        <include latin:keyboardLayout="@xml/keys_exclamation_question" />
+    </Row>
+    <include latin:keyboardLayout="@xml/row_qwerty4" />
+</merge>
diff --git a/java/res/xml/kbd_bengali_akkhor.xml b/java/res/xml/kbd_bengali_akkhor.xml
new file mode 100644
index 0000000..6c81d53
--- /dev/null
+++ b/java/res/xml/kbd_bengali_akkhor.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" >
+    <include latin:keyboardLayout="@xml/rows_bengali_akkhor" />
+</Keyboard>
diff --git a/java/res/xml/key_styles_currency.xml b/java/res/xml/key_styles_currency.xml
index 2ce6318..de5e6f2 100644
--- a/java/res/xml/key_styles_currency.xml
+++ b/java/res/xml/key_styles_currency.xml
@@ -98,8 +98,9 @@
             <include latin:keyboardLayout="@xml/key_styles_currency_generic" />
         </case>
         <!-- si_LK: Sinhala (Sri Lanka) (Sri Lanka Rupee)
-             ta_LK: Tamil (Sri Lanka) (Sri Lanka Rupee) -->
-        <case latin:countryCode="LK">
+             ta_LK: Tamil (Sri Lanka) (Sri Lanka Rupee)
+             bn_BD: Bengali (Bangladesh) (Taka) -->
+        <case latin:countryCode="LK|BD">
             <include latin:keyboardLayout="@xml/key_styles_currency_generic" />
         </case>
         <!-- bn_IN: Bengali (India) (Indian Rupee)
diff --git a/java/res/xml/keyboard_layout_set_bengali_akkhor.xml b/java/res/xml/keyboard_layout_set_bengali_akkhor.xml
new file mode 100644
index 0000000..b2b09b2
--- /dev/null
+++ b/java/res/xml/keyboard_layout_set_bengali_akkhor.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<KeyboardLayoutSet xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" >
+    <Feature latin:supportedScript="devanagari" />
+    <Element
+        latin:elementKeyboard="@xml/kbd_bengali_akkhor"
+        latin:elementName="alphabet"
+        latin:enableProximityCharsCorrection="true" />
+    <Element
+        latin:elementKeyboard="@xml/kbd_bengali_akkhor"
+        latin:elementName="alphabetAutomaticShifted"
+        latin:enableProximityCharsCorrection="true" />
+    <!-- On these shifted alphabet layouts the proximity characters correction should be disabled
+         because the letters on these layouts aren't the ones in different case of the above
+         unshifted layouts.-->
+    <Element
+        latin:elementKeyboard="@xml/kbd_bengali_akkhor"
+        latin:elementName="alphabetManualShifted" />
+    <Element
+        latin:elementKeyboard="@xml/kbd_bengali_akkhor"
+        latin:elementName="alphabetShiftLocked" />
+    <Element
+        latin:elementKeyboard="@xml/kbd_bengali_akkhor"
+        latin:elementName="alphabetShiftLockShifted" />
+    <Element
+        latin:elementKeyboard="@xml/kbd_symbols"
+        latin:elementName="symbols" />
+    <Element
+        latin:elementKeyboard="@xml/kbd_symbols_shift"
+        latin:elementName="symbolsShifted" />
+    <Element
+        latin:elementKeyboard="@xml/kbd_phone"
+        latin:elementName="phone" />
+    <Element
+        latin:elementKeyboard="@xml/kbd_phone_symbols"
+        latin:elementName="phoneSymbols" />
+    <Element
+        latin:elementKeyboard="@xml/kbd_number"
+        latin:elementName="number" />
+</KeyboardLayoutSet>
diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml
index 270f90c..f096ebd 100644
--- a/java/res/xml/method.xml
+++ b/java/res/xml/method.xml
@@ -28,6 +28,7 @@
     be_BY: Belarusian (Belarus)/east_slavic
     bg: Bulgarian/bulgarian
     bg: Bulgarian/bulgarian_bds
+    (bn_BD: Bengali (Bangladesh)/bengali_akkhor) # This is a preliminary keyboard layout.
     bn_IN: Bengali (India)/bengali
     ca: Catalan/spanish
     cs: Czech/qwertz
@@ -179,6 +180,16 @@
             android:imeSubtypeExtraValue="KeyboardLayoutSet=bulgarian_bds,EmojiCapable"
             android:isAsciiCapable="false"
     />
+    <!-- TODO: This Bengali (Bangladesh) keyboard is a preliminary layout.
+               This isn't based on the final specification. -->
+    <subtype android:icon="@drawable/ic_ime_switcher_dark"
+            android:label="@string/subtype_generic"
+            android:subtypeId="0xa2144b0c"
+            android:imeSubtypeLocale="bn_BD"
+            android:imeSubtypeMode="keyboard"
+            android:imeSubtypeExtraValue="KeyboardLayoutSet=bengali_akkhor,EmojiCapable"
+            android:isAsciiCapable="false"
+    />
     <subtype android:icon="@drawable/ic_ime_switcher_dark"
             android:label="@string/subtype_generic"
             android:subtypeId="0xbff5986c"
diff --git a/java/res/xml/rowkeys_bengali_akkhor1.xml b/java/res/xml/rowkeys_bengali_akkhor1.xml
new file mode 100644
index 0000000..bc612be
--- /dev/null
+++ b/java/res/xml/rowkeys_bengali_akkhor1.xml
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin">
+    <switch>
+        <case latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted">
+            <!-- U+09A2: "ঢ" BENGALI LETTER DDHA -->
+            <Key latin:keySpec="&#x09A2;" />
+            <!-- U+09A0: "ঠ" BENGALI LETTER TTHA -->
+            <Key latin:keySpec="&#x09A0;" />
+            <!-- U+09C8: "ৈ" BENGALI VOWEL SIGN AI
+                 U+0990: "ঐ" BENGALI LETTER AI -->
+            <Key
+                latin:keySpec="&#x09C8;"
+                latin:moreKeys="&#x0990;" />
+            <!-- U+09DC: "ড়" BENGALI LETTER RRA
+                 U+09BC: "়" BENGALI SIGN NUKTA -->
+            <Key
+                latin:keySpec="&#x09DC;"
+                latin:moreKeys="&#x09BC;" />
+            <!-- U+099F: "ট" BENGALI LETTER TTA
+                 U+09F3: "৳" BENGALI RUPEE SIGN
+                 U+099F/U+09CD/U+099F: "ট্ট" BENGALI LETTER TTA/BENGALI SIGN VIRAMA/BENGALI LETTER TTA
+                 U+099F/U+09CD/U+09AC: "ট্ব" BENGALI LETTER TTA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                 U+099F/U+09CD/U+09AE: "ট্ম" BENGALI LETTER TTA/BENGALI SIGN VIRAMA/BENGALI LETTER MA -->
+            <Key
+                latin:keySpec="&#x099F;"
+                latin:moreKeys="&#x09F3;,&#x099F;&#x09CD;&#x099F;,&#x099F;&#x09CD;&#x09AC;,&#x099F;&#x09CD;&#x09AE;" />
+            <!-- U+099E: "ঞ" BENGALI LETTER NYA
+                 U+099E/U+09CD/U+099A: "ঞ্চ" BENGALI LETTER NYA/BENGALI SIGN VIRAMA/BENGALI LETTER CA
+                 U+099E/U+09CD/U+099B: "ঞ্ছ" BENGALI LETTER NYA/BENGALI SIGN VIRAMA/BENGALI LETTER CHA
+                 U+099E/U+09CD/U+099C: "ঞ্জ" BENGALI LETTER NYA/BENGALI SIGN VIRAMA/BENGALI LETTER JA -->
+            <Key
+                latin:keySpec="&#x099E;"
+                latin:moreKeys="&#x099E;&#x09CD;&#x099A;,&#x099E;&#x09CD;&#x099B;,&#x099E;&#x09CD;&#x099C;" />
+            <!-- U+09C2: "ূ" BENGALI VOWEL SIGN UU
+                 U+098A: "ঊ" BENGALI LETTER UU -->
+            <Key
+                latin:keySpec="&#x09C2;"
+                latin:moreKeys="&#x098A;" />
+            <!-- U+09C0: "ী" BENGALI VOWEL SIGN II
+                 U+0988: "ঈ" BENGALI LETTER II -->
+            <Key
+                latin:keySpec="&#x09C0;"
+                latin:moreKeys="&#x0988;" />
+            <!-- U+09CC: "ৌ" BENGALI VOWEL SIGN AU
+                 U+099A: "ঔ" BENGALI LETTER CA
+                 U+09D7: "ৗ" BENGALI AU LENGTH MARK -->
+            <Key
+                latin:keySpec="&#x09CC;"
+                latin:moreKeys="&#x099A;,&#x09D7;" />
+            <!-- U+09AB: "ফ" BENGALI LETTER PHA
+                 U+09AB/U+09CD/U+099F: "ফ্ট" BENGALI LETTER PHA/BENGALI SIGN VIRAMA/BENGALI LETTER TTA
+                 U+09AB/U+09CD/U+09AF: "ফ্য" BENGALI LETTER PHA/BENGALI SIGN VIRAMA/BENGALI LETTER YA
+                 U+09AB/U+09CD/U+09B0: "ফ্র" BENGALI LETTER PHA/BENGALI SIGN VIRAMA/BENGALI LETTER RA
+                 U+09AB/U+09CD/U+09B2: "ফ্ল" BENGALI LETTER PHA/BENGALI SIGN VIRAMA/BENGALI LETTER LA -->
+            <Key
+                latin:keySpec="&#x09AB;"
+                latin:moreKeys="&#x09AB;&#x09CD;&#x099F;,&#x09AB;&#x09CD;&#x09AF;,&#x09AB;&#x09CD;&#x09B0;,&#x09AB;&#x09CD;&#x09B2;" />
+            <!-- U+098B: "ঋ" BENGALI LETTER VOCALIC R
+                 U+098C: "ঌ" BENGALI LETTER VOCALIC L
+                 U+09E1: "ৡ" BENGALI LETTER VOCALIC LL
+                 U+09F4: "৴" BENGALI CURRENCY NUMERATOR ONE
+                 U+09F5: "৵" BENGALI CURRENCY NUMERATOR TWO
+                 U+09F6: "৶" BENGALI CURRENCY NUMERATOR THREE
+                 U+09E2: " ৢ" BENGALI VOWEL SIGN VOCALIC L
+                 U+09E3: " ৣ" BENGALI VOWEL SIGN VOCALIC LL -->
+            <Key
+                latin:keySpec="&#x098B;"
+                latin:moreKeys="&#x098C;,&#x09E1;,&#x09F4;,&#x09F5;,&#x09F6;,&#x09E2;,&#x09E3;" />
+        </case>
+        <default>
+            <!-- U+09A7: "ধ" BENGALI LETTER DHA
+                 U+09E7: "১" BENGALI DIGIT ONE
+                 U+09A7/U+09CD/U+09AC: "ধ্ব্র" BENGALI LETTER DHA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                 U+09A7/U+09CD/U+09AF: "ধ্য্র" BENGALI LETTER DHA/BENGALI SIGN VIRAMA/BENGALI LETTER YA
+                 U+09A7/U+09CD/U+09B0: "ধ্র" BENGALI LETTER DHA/BENGALI SIGN VIRAMA/BENGALI LETTER RA -->
+            <Key
+                latin:keySpec="&#x09A7;"
+                latin:keyHintLabel="&#x09E7;"
+                latin:additionalMoreKeys="&#x09E7;"
+                latin:moreKeys="&#x09A7;&#x09CD;&#x09AC;,&#x09A7;&#x09CD;&#x09AF;,&#x09A7;&#x09CD;&#x09B0;" />
+            <!-- U+09A5: "থ" BENGALI LETTER THA
+                 U+09E8: "২" BENGALI DIGIT TWO
+                 U+09A5/U+09CD/U+09AF: "থ্য" BENGALI LETTER THA/BENGALI SIGN VIRAMA/BENGALI LETTER YA
+                 U+09A5/U+09CD/U+09B0: "থ্র" BENGALI LETTER THA/BENGALI SIGN VIRAMA/BENGALI LETTER RA -->
+            <Key
+                latin:keySpec="&#x09A5;"
+                latin:keyHintLabel="&#x09E8;"
+                latin:additionalMoreKeys="&#x09E8;"
+                latin:moreKeys="&#x09A5;&#x09CD;&#x09AF;,&#x09A5;&#x09CD;&#x09B0;" />
+            <!-- U+09C7: "ে" BENGALI VOWEL SIGN E
+                 U+09E9: "৩" BENGALI DIGIT THREE
+                 U+098F: "এ" BENGALI LETTER E -->
+            <Key
+                latin:keySpec="&#x09C7;"
+                latin:keyHintLabel="&#x09E9;"
+                latin:additionalMoreKeys="&#x09E9;"
+                latin:moreKeys="&#x098F;" />
+            <!-- U+09B0: "র" BENGALI LETTER RA
+                 U+09EA: "৪" BENGALI DIGIT FOUR -->
+            <Key
+                latin:keySpec="&#x09B0;"
+                latin:keyHintLabel="&#x09EA;"
+                latin:additionalMoreKeys="&#x09EA;" />
+            <!-- U+09A4: "ত" BENGALI LETTER TA
+                 U+09EB: "৫" BENGALI DIGIT FIVE
+                 U+09CE: "ৎ" BENGALI LETTER KHANDA TA
+                 U+09A4/U+09CD/U+09A4: "ত্ত" BENGALI LETTER TA/BENGALI SIGN VIRAMA/BENGALI LETTER TA
+                 U+09A4/U+09CD/U+09A8: "ত্ন" BENGALI LETTER TA/BENGALI SIGN VIRAMA/BENGALI LETTER NA
+                 U+09A4/U+09CD/U+09AC: "ত্ব" BENGALI LETTER TA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                 U+09A4/U+09CD/U+09AE: "ত্ম" BENGALI LETTER TA/BENGALI SIGN VIRAMA/BENGALI LETTER MA -->
+            <Key
+                latin:keySpec="&#x09A4;"
+                latin:keyHintLabel="&#x09EB;"
+                latin:additionalMoreKeys="&#x09EB;"
+                latin:moreKeys="&#x09CE;,&#x09A4;&#x09CD;&#x09A4;,&#x09A4;&#x09CD;&#x09A8;,&#x09A4;&#x09CD;&#x09AC;,&#x09A4;&#x09CD;&#x09AE;" />
+            <!-- U+09DF: "য়" BENGALI LETTER YYA
+                 U+09EC: "৬" BENGALI DIGIT SIX -->
+            <Key
+                latin:keySpec="&#x09DF;"
+                latin:keyHintLabel="&#x09EC;"
+                latin:additionalMoreKeys="&#x09EC;" />
+            <!-- U+09C1: "ু" BENGALI VOWEL SIGN U
+                 U+09ED: "৭" BENGALI DIGIT SEVEN
+                 U+0989: "উ" BENGALI LETTER U -->
+            <Key
+                latin:keySpec="&#x09C1;"
+                latin:keyHintLabel="&#x09ED;"
+                latin:additionalMoreKeys="&#x09ED;"
+                latin:moreKeys="&#x0989;" />
+            <!-- U+09BF: "ি" BENGALI VOWEL SIGN I
+                 U+09EE: "৮" BENGALI DIGIT EIGHT
+                 U+0987: "ই BENGALI LETTER I -->
+            <Key
+                latin:keySpec="&#x09BF;"
+                latin:keyHintLabel="&#x09EE;"
+                latin:additionalMoreKeys="&#x09EE;"
+                latin:moreKeys="&#x0987;" />
+            <!-- U+09CB: "ো" BENGALI VOWEL SIGN O
+                 U+09EF: "৯" BENGALI DIGIT NINE
+                 U+0993: "ও" BENGALI LETTER O -->
+            <Key
+                latin:keySpec="&#x09CB;"
+                latin:keyHintLabel="&#x09EF;"
+                latin:additionalMoreKeys="&#x09EF;"
+                latin:moreKeys="&#x0993;" />
+            <!-- U+09AA: "প" BENGALI LETTER PA
+                 U+09E6: "০" BENGALI DIGIT ZERO
+                 U+09AA/U+09CD/U+09A4: "প্ত" BENGALI LETTER PA/BENGALI SIGN VIRAMA/BENGALI LETTER TA
+                 U+09AA/U+09CD/U+09A8: "প্ন" BENGALI LETTER PA/BENGALI SIGN VIRAMA/BENGALI LETTER NA
+                 U+09AA/U+09CD/U+09AA: "প্প" BENGALI LETTER PA/BENGALI SIGN VIRAMA/BENGALI LETTER PA
+                 U+09AA/U+09CD/U+09AF: "প্য" BENGALI LETTER PA/BENGALI SIGN VIRAMA/BENGALI LETTER YA
+                 U+09AA/U+09CD/U+09B0: "প্র" BENGALI LETTER PA/BENGALI SIGN VIRAMA/BENGALI LETTER RA
+                 U+09AA/U+09CD/U+09B2: "প্ল" BENGALI LETTER PA/BENGALI SIGN VIRAMA/BENGALI LETTER LA
+                 U+09AA/U+09CD/U+09B8: "প্স" BENGALI LETTER PA/BENGALI SIGN VIRAMA/BENGALI LETTER SA -->
+            <Key
+                latin:keySpec="&#x09AA;"
+                latin:keyHintLabel="&#x09E6;"
+                latin:additionalMoreKeys="&#x09E6;"
+                latin:moreKeys="&#x09AA;&#x09CD;&#x09A4;,&#x09AA;&#x09CD;&#x09A8;,&#x09AA;&#x09CD;&#x09AA;,&#x09AA;&#x09CD;&#x09AF;,&#x09AA;&#x09CD;&#x09B0;,&#x09AA;&#x09CD;&#x09B2;,&#x09AA;&#x09CD;&#x09B8;" />
+            <!-- U+0986: "আ" BENGALI LETTER AA -->
+            <Key latin:keySpec="&#x0986;" />
+        </default>
+    </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_bengali_akkhor2.xml b/java/res/xml/rowkeys_bengali_akkhor2.xml
new file mode 100644
index 0000000..1dbab55
--- /dev/null
+++ b/java/res/xml/rowkeys_bengali_akkhor2.xml
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin">
+    <switch>
+        <case latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted">
+            <!-- U+0985: "অ" BENGALI LETTER A -->
+            <Key latin:keySpec="&#x0985;" />
+            <!-- U+09B6: "শ" BENGALI LETTER SHA
+                 U+09B6/U+09CD/U+099A: "শ্চ" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER CA
+                 U+09B6/U+09CD/U+099B: "শ্ছ" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER CHA
+                 U+09B6/U+09CD/U+09A4: "শ্ত" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER TA
+                 U+09B6/U+09CD/U+09A8: "শ্ন" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER NA
+                 U+09B6/U+09CD/U+09AC: "শ্ব" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                 U+09B6/U+09CD/U+09AE: "শ্ম" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER MA
+                 U+09B6/U+09CD/U+09B0: "শ্র" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER RA
+                 U+09B6/U+09CD/U+09B2: "শ্ল" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER LA -->
+            <Key
+                latin:keySpec="&#x09B6;"
+                latin:moreKeys="&#x09B6;&#x09CD;&#x099A;,&#x09B6;&#x09CD;&#x099B;,&#x09B6;&#x09CD;&#x09A4;,&#x09B6;&#x09CD;&#x09A8;,&#x09B6;&#x09CD;&#x09AC;,&#x09B6;&#x09CD;&#x09AE;,&#x09B6;&#x09CD;&#x09B0;,&#x09B6;&#x09CD;&#x09B2;" />
+            <!-- U+09A1: "ড" BENGALI LETTER DDA
+                 U+09A1/U+09CD/U+09A1: "ড্ড" BENGALI LETTER DDA/BENGALI SIGN VIRAMA/BENGALI LETTER DDA-->
+            <Key
+                latin:keySpec="&#x09A1;"
+                latin:moreKeys="&#x09A1;&#x09CD;&#x09A1;" />
+            <!-- U+09DD: "ঢ়" BENGALI LETTER RHA -->
+            <Key latin:keySpec="&#x09DD;" />
+            <!-- U+0998: "ঘ" BENGALI LETTER GHA -->
+            <Key latin:keySpec="&#x0998;" />
+            <!-- U+09B9: "হ" BENGALI LETTER HA
+                 U+09BD: "ঽ" BENGALI SIGN AVAGRAHA
+                 U+09B9/U+09CD/U+09A3: "হ্ণ" BENGALI LETTER HA/BENGALI SIGN VIRAMA/BENGALI LETTER NNA
+                 U+09B9/U+09CD/U+09A8: "হ্ন" BENGALI LETTER HA/BENGALI SIGN VIRAMA/BENGALI LETTER NA
+                 U+09B9/U+09CD/U+09AC: "হ্ব" BENGALI LETTER HA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                 U+09B9/U+09CD/U+09AE: "হ্ম" BENGALI LETTER HA/BENGALI SIGN VIRAMA/BENGALI LETTER MA
+                 U+09B9/U+09CD/U+09B0: "হ্র" BENGALI LETTER HA/BENGALI SIGN VIRAMA/BENGALI LETTER RA
+                 U+09B9/U+09CD/U+09B2: "হ্ল" BENGALI LETTER HA/BENGALI SIGN VIRAMA/BENGALI LETTER LA -->
+            <Key
+                latin:keySpec="&#x09B9;"
+                latin:moreKeys="&#x09BD;,&#x09B9;&#x09CD;&#x09A3;,&#x09B9;&#x09CD;&#x09A8;,&#x09B9;&#x09CD;&#x09AC;,&#x09B9;&#x09CD;&#x09AE;,&#x09B9;&#x09CD;&#x09B0;,&#x09B9;&#x09CD;&#x09B2;" />
+            <!-- U+099D: "ঝ" BENGALI LETTER JHA -->
+            <Key latin:keySpec="&#x099D;" />
+            <!-- U+0996: "খ" BENGALI LETTER KHA -->
+            <Key latin:keySpec="&#x0996;" />
+            <!-- U+09CE: "ৎ" BENGALI LETTER KHANDA TA -->
+            <Key latin:keySpec="&#x09CE;" />
+            <!-- U+0988: "ঈ" BENGALI LETTER II -->
+            <Key latin:keySpec="&#x0988;" />
+            <!-- U+098A: "ঊ" BENGALI LETTER UU -->
+            <Key latin:keySpec="&#x098A;" />
+        </case>
+        <default>
+            <!-- U+09BE: "া BENGALI VOWEL SIGN AA
+                 U+0986: "আ" BENGALI LETTER AA -->
+            <Key
+                latin:keySpec="&#x09BE;"
+                latin:moreKeys="&#x0986;" />
+            <!-- U+09B8: "স" BENGALI LETTER SA
+                 U+09B8/U+09CD/U+09AC: "স্ব" BENGALI LETTER SA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                 U+09B8/U+09CD/U+09A4: "স্ত" BENGALI LETTER SA/BENGALI SIGN VIRAMA/BENGALI LETTER TA
+                 U+09B8/U+09CD/U+099F: "স্ট" BENGALI LETTER SA/BENGALI SIGN VIRAMA/BENGALI LETTER TTA
+                 U+09B8/U+09CD/U+0995: "স্ক" BENGALI LETTER SA/BENGALI SIGN VIRAMA/BENGALI LETTER KA
+                 U+09B8/U+09CD/U+09AA: "স্প" BENGALI LETTER SA/BENGALI SIGN VIRAMA/BENGALI LETTER PA -->
+            <Key
+                latin:keySpec="&#x09B8;"
+                latin:moreKeys="&#x09B8;&#x09CD;&#x09AC;,&#x09B8;&#x09CD;&#x09A4;,&#x09B8;&#x09CD;&#x099F;,&#x09B8;&#x09CD;&#x0995;,&#x09B8;&#x09CD;&#x09AA;" />
+            <!-- U+09A6: "দ" BENGALI LETTER DA
+                 U+09A6/U+09CD/U+09A6: "দ্দ" BENGALI LETTER DA/BENGALI SIGN VIRAMA/BENGALI LETTER DA
+                 U+09A6/U+09CD/U+09A7: "দ্ধ" BENGALI LETTER DA/BENGALI SIGN VIRAMA/BENGALI LETTER DHA
+                 U+09A6/U+09CD/U+09AC: "দ্ব" BENGALI LETTER DA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                 U+09A6/U+09CD/U+09AD: "দ্ভ" BENGALI LETTER DA/BENGALI SIGN VIRAMA/BENGALI LETTER BHA
+                 U+09A6/U+09CD/U+09AE: "দ্ম" BENGALI LETTER DA/BENGALI SIGN VIRAMA/BENGALI LETTER MA
+                 U+09A6/U+09CD/U+09AF: "দ্য" BENGALI LETTER DA/BENGALI SIGN VIRAMA/BENGALI LETTER YA
+                 U+09A6/U+09CD/U+09B0: "দ্র" BENGALI LETTER DA/BENGALI SIGN VIRAMA/BENGALI LETTER RA -->
+            <Key
+                latin:keySpec="&#x09A6;"
+                latin:moreKeys="&#x09A6;&#x09CD;&#x09A6;,&#x09A6;&#x09CD;&#x09A7;,&#x09A6;&#x09CD;&#x09AC;,&#x09A6;&#x09CD;&#x09AD;,&#x09A6;&#x09CD;&#x09AE;,&#x09A6;&#x09CD;&#x09AF;,&#x09A6;&#x09CD;&#x09B0;" />
+            <!-- U+09C3: "ৃ" BENGALI VOWEL SIGN VOCALIC R
+                 U+098B: "ঋ" BENGALI LETTER VOCALIC R -->
+            <Key
+                latin:keySpec="&#x09C3;"
+                latin:moreKeys="&#x098B;" />
+            <!-- U+0997: "গ" BENGALI LETTER GA
+                 U+0997/U+09CD/U+09A7: "গ্ধ" BENGALI LETTER GA/BENGALI SIGN VIRAMA/BENGALI LETTER DHA
+                 U+0997/U+09CD/U+09B0: "গ্র" BENGALI LETTER GA/BENGALI SIGN VIRAMA/BENGALI LETTER RA
+                 U+0997/U+09CD/U+09B2: "গ্ল" BENGALI LETTER GA/BENGALI SIGN VIRAMA/BENGALI LETTER LA
+                 U+0997/U+09CD/U+09A8: "গ্ন" BENGALI LETTER GA/BENGALI SIGN VIRAMA/BENGALI LETTER NA -->
+            <Key
+                latin:keySpec="&#x0997;"
+                latin:moreKeys="&#x0997;&#x09CD;&#x09A7;,&#x0997;&#x09CD;&#x09B0;,&#x0997;&#x09CD;&#x09B2;,&#x0997;&#x09CD;&#x09A8;" />
+            <!-- U+09CD: "্" BENGALI SIGN VIRAMA -->
+            <Key latin:keySpec="&#x09CD;" />
+            <!-- U+099C: "জ" BENGALI LETTER JA
+                 U+099C/U+09CD/U+099E: "জ্ঞ" BENGALI LETTER JA/BENGALI SIGN VIRAMA/BENGALI LETTER NYA
+                 U+099C/U+09CD/U+099C: "জ্জ" BENGALI LETTER JA/BENGALI SIGN VIRAMA/BENGALI LETTER JA
+                 U+099C/U+09CD/U+09AF: "জ্ব" BENGALI LETTER JA/BENGALI SIGN VIRAMA/BENGALI LETTER YA
+                 U+099C/U+09CD/U+09AC: "জ্য" BENGALI LETTER JA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                 U+099C/U+09CD/U+09B0: "জ্র" BENGALI LETTER JA/BENGALI SIGN VIRAMA/BENGALI LETTER RA -->
+            <Key
+                latin:keySpec="&#x099C;"
+                latin:moreKeys="&#x099C;&#x09CD;&#x099E;,&#x099C;&#x09CD;&#x099C;,&#x099C;&#x09CD;&#x09AF;,&#x099C;&#x09CD;&#x09AC;,&#x099C;&#x09CD;&#x09B0;" />
+            <!-- U+0995: "ক" BENGALI LETTER KA
+                 U+0995/U+09CD/U+09B7: "ক্ষ" BENGALI LETTER KA/BENGALI SIGN VIRAMA/BENGALI LETTER SSA
+                 U+0995/U+09CD/U+0995: "ক্ক" BENGALI LETTER KA/BENGALI SIGN VIRAMA/BENGALI LETTER KA
+                 U+0995/U+09CD/U+099F: "ক্ট" BENGALI LETTER KA/BENGALI SIGN VIRAMA/BENGALI LETTER TTA
+                 U+0995/U+09CD/U+09A4: "ক্ত" BENGALI LETTER KA/BENGALI SIGN VIRAMA/BENGALI LETTER TA
+                 U+0995/U+09CD/U+09B0: "ক্র" BENGALI LETTER KA/BENGALI SIGN VIRAMA/BENGALI LETTER RA
+                 U+0995/U+09CD/U+09B8: "ক্স" BENGALI LETTER KA/BENGALI SIGN VIRAMA/BENGALI LETTER SA
+                 U+0995/U+09CD/U+09B2: "ক্ল" BENGALI LETTER KA/BENGALI SIGN VIRAMA/BENGALI LETTER LA -->
+            <Key
+                latin:keySpec="&#x0995;"
+                latin:moreKeys="&#x0995;&#x09CD;&#x09B7;,&#x0995;&#x09CD;&#x0995;,&#x0995;&#x09CD;&#x099F;,&#x0995;&#x09CD;&#x09A4;,&#x0995;&#x09CD;&#x09B0;,&#x0995;&#x09CD;&#x09B8;,&#x0995;&#x09CD;&#x09B2;" />
+            <!-- U+09B2: "ল" BENGALI LETTER LA
+                 U+09B2/U+09CD/U+0995: "ল্ক" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER KA
+                 U+09B2/U+09CD/U+0997: "ল্গ" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER GA
+                 U+09B2/U+09CD/U+099F: "ল্ট" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER TTA
+                 U+09B2/U+09CD/U+09A1: "ল্ড" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER DDA
+                 U+09B2/U+09CD/U+09A4: "ল্ত" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER TA
+                 U+09B2/U+09CD/U+09A6: "ল্দ" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER DA
+                 U+09B2/U+09CD/U+09A7: "ল্ধ" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER DHA
+                 U+09B2/U+09CD/U+09AA: "ল্প" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER PA
+                 U+09B2/U+09CD/U+09AB: "ল্ফ" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER PHA
+                 U+09B2/U+09CD/U+09AC: "ল্ব" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                 U+09B2/U+09CD/U+09AE: "ল্ম" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER MA
+                 U+09B2/U+09CD/U+09B2: "ল্ল" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER LA -->
+            <Key
+                latin:keySpec="&#x09B2;"
+                latin:moreKeys="&#x09B2;&#x09CD;&#x0995;,&#x09B2;&#x09CD;&#x0997;,&#x09B2;&#x09CD;&#x099F;,&#x09B2;&#x09CD;&#x09A1;,&#x09B2;&#x09CD;&#x09A4;,&#x09B2;&#x09CD;&#x09A6;,&#x09B2;&#x09CD;&#x09A7;,&#x09B2;&#x09CD;&#x09AA;,&#x09B2;&#x09CD;&#x09AB;,&#x09B2;&#x09CD;&#x09AC;,&#x09B2;&#x09CD;&#x09AE;,&#x09B2;&#x09CD;&#x09B2;" />
+            <!-- U+0987: "ই" BENGALI LETTER I -->
+            <Key latin:keySpec="&#x0987;" />
+            <!-- U+0989: "উ" BENGALI LETTER U -->
+            <Key latin:keySpec="&#x0989;" />
+        </default>
+    </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_bengali_akkhor3.xml b/java/res/xml/rowkeys_bengali_akkhor3.xml
new file mode 100644
index 0000000..eb9e836
--- /dev/null
+++ b/java/res/xml/rowkeys_bengali_akkhor3.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin">
+    <switch>
+        <case latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted">
+            <!-- U+0964: "।" DEVANAGARI DANDA
+                 U+0965: "॥" DEVANAGARI DOUBLE DANDA -->
+            <Key
+                 latin:keySpec="&#x0964;"
+                 latin:moreKeys="&#x0965;" />
+            <!-- U+0999: "ঙ BENGALI LETTER NGA
+                 U+0999/U+09CD/U+0995: "ঙ্ক"
+                 U+0999/U+09CD/U+0996: "ঙ্খ"
+                 U+0999/U+09CD/U+0997: "ঙ্গ" -->
+            <Key latin:keySpec="&#x0999;"
+                 latin:moreKeys="&#x0999;&#x09CD;&#x0995;,&#x0999;&#x09CD;&#x0996;,&#x0999;&#x09CD;&#x0997;" />
+            <!-- U+099B: "ছ" BENGALI LETTER CHA -->
+            <Key latin:keySpec="&#x099B;" />
+            <!-- U+0983: "ঃ" BENGALI SIGN VISARGA -->
+            <Key latin:keySpec="&#x0983;" />
+            <!-- U+0981: "ঁ" BENGALI SIGN CANDRABINDU -->
+            <Key latin:keySpec="&#x0981;" />
+            <!-- U+09A3: "ণ" BENGALI LETTER NNA
+                 U+09A3/U+09CD/U+099F: "ণ্ট" BENGALI LETTER NNA/BENGALI SIGN VIRAMA/BENGALI LETTER TTA
+                 U+09A3/U+09CD/U+09A1: "ণ্ড" BENGALI LETTER NNA/BENGALI SIGN VIRAMA/BENGALI LETTER DDA
+                 U+09A3/U+09CD/U+09A3: "ণ্ণ" BENGALI LETTER NNA/BENGALI SIGN VIRAMA/BENGALI LETTER NNA -->
+            <Key latin:keySpec="&#x09A3;"
+                 latin:moreKeys="&#x09A3;&#x09CD;&#x099F;,&#x09A3;&#x09CD;&#x09A1;,&#x09A3;&#x09CD;&#x09A3;" />
+            <!-- U+0982: "ং" BENGALI SIGN ANUSVARA -->
+            <Key latin:keySpec="&#x0982;" />
+            <!-- U+0990: "ঐ" BENGALI LETTER AI -->
+            <Key latin:keySpec="&#x0990;" />
+            <!-- U+0994: "ঔ" BENGALI LETTER AU -->
+            <Key latin:keySpec="&#x0994;" />
+        </case>
+        <default>
+            <!-- U+09AF: "য" BENGALI LETTER YA
+                 U+09CD/U+09AF: "্য" BENGALI SIGN VIRAMA/BENGALI LETTER YA -->
+            <Key
+                 latin:keySpec="&#x09AF;"
+                 latin:moreKeys="&#x09CD;&#x09AF;" />
+            <!-- U+09B7: "ষ" BENGALI LETTER SSA
+                 U+09B7/U+09CD/U+0995: "ষ্ক" BENGALI LETTER SSA/BENGALI SIGN VIRAMA/BENGALI LETTER KA
+                 U+09B7/U+09CD/U+099F: "ষ্ট" BENGALI LETTER SSA/BENGALI SIGN VIRAMA/BENGALI LETTER TTA
+                 U+09B7/U+09CD/U+09A0: "ষ্ঠ" BENGALI LETTER SSA/BENGALI SIGN VIRAMA/BENGALI LETTER TTHA
+                 U+09B7/U+09CD/U+09A3: "ষ্ণ" BENGALI LETTER SSA/BENGALI SIGN VIRAMA/BENGALI LETTER NNA
+                 U+09B7/U+09CD/U+09AA: "ষ্প" BENGALI LETTER SSA/BENGALI SIGN VIRAMA/BENGALI LETTER PA
+                 U+09B7/U+09CD/U+09AB: "ষ্ফ" BENGALI LETTER SSA/BENGALI SIGN VIRAMA/BENGALI LETTER PHA
+                 U+09B7/U+09CD/U+09AE: "ষ্ম" BENGALI LETTER SSA/BENGALI SIGN VIRAMA/BENGALI LETTER MA -->
+            <Key
+                 latin:keySpec="&#x09B7;"
+                 latin:moreKeys="&#x09B7;&#x09CD;&#x0995;,&#x09B7;&#x09CD;&#x099F;,&#x09B7;&#x09CD;&#x09A0;,&#x09B7;&#x09CD;&#x09A3;,&#x09B7;&#x09CD;&#x09AA;,&#x09B7;&#x09CD;&#x09AB;,&#x09B7;&#x09CD;&#x09AE;" />
+            <!-- U+099A: "চ" BENGALI LETTER CA
+                 U+099A/U+09CD/U+099A: "চ্চ" BENGALI LETTER CA/BENGALI SIGN VIRAMA/BENGALI LETTER CA
+                 U+099A/U+09CD/U+099B: "চ্ছ" BENGALI LETTER CA/BENGALI SIGN VIRAMA/BENGALI LETTER CHA -->
+            <Key
+                 latin:keySpec="&#x099A;"
+                 latin:moreKeys="&#x099A;&#x09CD;&#x099A;,&#x099A;&#x09CD;&#x099B;" />
+            <!-- U+09AD: "ভ" BENGALI LETTER BHA
+                 U+09AD/U+09CD/U+09AF: "ভ্" BENGALI LETTER BHA/BENGALI SIGN VIRAMA/BENGALI LETTER YA
+                 U+09AD/U+09CD/U+09B0: "ভ্র" BENGALI LETTER BHA/BENGALI SIGN VIRAMA/BENGALI LETTER RA
+                 U+09AD/U+09CD/U+09B2: "ভ্ল" BENGALI LETTER BHA/BENGALI SIGN VIRAMA/BENGALI LETTER LA -->
+            <Key
+                 latin:keySpec="&#x09AD;"
+                 latin:moreKeys="&#x09AD;&#x09CD;&#x09AF;,&#x09AD;&#x09CD;&#x09B0;,&#x09AD;&#x09CD;&#x09B2;" />
+            <!-- U+09AC: "ব" BENGALI LETTER BA
+                 U+09CD/U+09AC: "্ব" BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                 U+09AC/U+09CD/U+09B0: "ব্র" BENGALI LETTER BA/BENGALI SIGN VIRAMA/BENGALI LETTER RA
+                 U+09AC/U+09CD/U+099C: "ব্জ" BENGALI LETTER BA/BENGALI SIGN VIRAMA/BENGALI LETTER JA
+                 U+09AC/U+09CD/U+09A6: "ব্দ" BENGALI LETTER BA/BENGALI SIGN VIRAMA/BENGALI LETTER DA
+                 U+09AC/U+09CD/U+09A7: "ব্ধ" BENGALI LETTER BA/BENGALI SIGN VIRAMA/BENGALI LETTER DHA
+                 U+09AC/U+09CD/U+09AC: "ব্ব" BENGALI LETTER BA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                 U+09AC/U+09CD/U+09B2: "ব্ল" BENGALI LETTER BA/BENGALI SIGN VIRAMA/BENGALI LETTER LA
+                 U+09F1: "ৱ" BENGALI LETTER RA WITH MIDDLE DIAGONAL
+                 U+09F0: "ৰ" BENGALI LETTER RA WITH LOWER DIAGONAL -->
+            <Key
+                 latin:keySpec="&#x09AC;"
+                 latin:moreKeys="&#x09CD;&#x09AC;,&#x09AC;&#x09CD;&#x09B0;,&#x09AC;&#x09CD;&#x099C;,&#x09AC;&#x09CD;&#x09A6;,&#x09AC;&#x09CD;&#x09A7;,&#x09AC;&#x09CD;&#x09AC;,&#x09AC;&#x09CD;&#x09B2;,&#x09F1;,&#x09F0;" />
+            <!-- U+09A8: "ন" BENGALI LETTER NA
+                 U+09A8/U+09CD/U+09A4: "ন্ত" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER TA
+                 U+09A8/U+09CD/U+09A5: "ন্থ" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER THA
+                 U+09A8/U+09CD/U+099F: "ন্ট" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER TTA
+                 U+09A8/U+09CD/U+09A6: "ন্দ" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER DA
+                 U+09A8/U+09CD/U+09A7: "ন্ধ" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER DHA
+                 U+09A8/U+09CD/U+09A1: "ন্ড" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER DDA
+                 U+09A8/U+09CD/U+09A8: "ন্ন" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER NA
+                 U+09A8/U+09CD/U+09AC: "ন্ব" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                 U+09A8/U+09CD/U+09AE: "ন্ম" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER MA
+                 U+09A8/U+09CD/U+09B8: "ন্স" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER SA -->
+            <Key
+                 latin:keySpec="&#x09A8;"
+                 latin:moreKeys="&#x09A8;&#x09CD;&#x09A4;,&#x09A8;&#x09CD;&#x09A5;,&#x09A8;&#x09CD;&#x099F;,&#x09A8;&#x09CD;&#x09A6;,&#x09A8;&#x09CD;&#x09A7;,&#x09A8;&#x09CD;&#x09A1;,&#x09A8;&#x09CD;&#x09A8;,&#x09A8;&#x09CD;&#x09AC;,&#x09A8;&#x09CD;&#x09AE;,&#x09A8;&#x09CD;&#x09B8;" />
+            <!-- U+09AE: "ম" BENGALI LETTER MA
+                 U+09AE/U+09CD/U+09A8: "ম্ন" BENGALI LETTER MA/BENGALI SIGN VIRAMA/BENGALI LETTER NA
+                 U+09AE/U+09CD/U+09AA: "ম্প" BENGALI LETTER MA/BENGALI SIGN VIRAMA/BENGALI LETTER PA
+                 U+09AE/U+09CD/U+09AC: "ম্ব" BENGALI LETTER MA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                 U+09AE/U+09CD/U+09AD: "ম্ভ" BENGALI LETTER MA/BENGALI SIGN VIRAMA/BENGALI LETTER BHA
+                 U+09AE/U+09CD/U+09AE: "ম্ম" BENGALI LETTER MA/BENGALI SIGN VIRAMA/BENGALI LETTER MA
+                 U+09AE/U+09CD/U+09B0: "ম্র" BENGALI LETTER MA/BENGALI SIGN VIRAMA/BENGALI LETTER RA
+                 U+09AE/U+09CD/U+09B2: "ম্ল" BENGALI LETTER MA/BENGALI SIGN VIRAMA/BENGALI LETTER LA -->
+            <Key
+                 latin:keySpec="&#x09AE;"
+                 latin:moreKeys=",&#x09AE;&#x09CD;&#x09A8;,&#x09AE;&#x09CD;&#x09AA;,&#x09AE;&#x09CD;&#x09AC;,&#x09AE;&#x09CD;&#x09AD;,&#x09AE;&#x09CD;&#x09AE;,&#x09AE;&#x09CD;&#x09B0;,&#x09AE;&#x09CD;&#x09B2;" />
+            <!-- U+098F: "এ" BENGALI LETTER E -->
+            <Key latin:keySpec="&#x098F;" />
+            <!-- U+0993: "ও" BENGALI LETTER O -->
+            <Key latin:keySpec="&#x0993;" />
+        </default>
+    </switch>
+</merge>
diff --git a/java/res/xml/rows_bengali_akkhor.xml b/java/res/xml/rows_bengali_akkhor.xml
new file mode 100644
index 0000000..1c7e772
--- /dev/null
+++ b/java/res/xml/rows_bengali_akkhor.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" >
+    <include latin:keyboardLayout="@xml/key_styles_common" />
+    <Row
+        latin:keyLabelFlags="fontNormal"
+        latin:keyWidth="9.091%p" >
+        <include latin:keyboardLayout="@xml/rowkeys_bengali_akkhor1" />
+    </Row>
+    <Row
+        latin:keyLabelFlags="fontNormal"
+        latin:keyWidth="9.091%p" >
+        <include latin:keyboardLayout="@xml/rowkeys_bengali_akkhor2" />
+    </Row>
+    <Row
+        latin:keyLabelFlags="fontNormal"
+        latin:keyWidth="8.711%p" >
+        <Key
+            latin:keyStyle="shiftKeyStyle"
+            latin:keyWidth="10.8%p" />
+        <include latin:keyboardLayout="@xml/rowkeys_bengali_akkhor3" />
+        <Key
+            latin:keyStyle="deleteKeyStyle"
+            latin:keyWidth="fillRight" />
+    </Row>
+    <include latin:keyboardLayout="@xml/row_qwerty4" />
+</merge>
diff --git a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
index 7a3510e..edcdd4c 100644
--- a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
+++ b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
@@ -37,6 +37,8 @@
     private static final String SPOKEN_LETTER_RESOURCE_NAME_FORMAT = "spoken_accented_letter_%04X";
     private static final String SPOKEN_SYMBOL_RESOURCE_NAME_FORMAT = "spoken_symbol_%04X";
     private static final String SPOKEN_EMOJI_RESOURCE_NAME_FORMAT = "spoken_emoji_%04X";
+    private static final String SPOKEN_EMOTICON_RESOURCE_NAME_PREFIX = "spoken_emoticon";
+    private static final String SPOKEN_EMOTICON_CODE_POINT_FORMAT = "_%02X";
 
     // The resource ID of the string spoken for obscured keys
     private static final int OBSCURED_KEY_RES_ID = R.string.spoken_description_dot;
@@ -109,7 +111,9 @@
         }
 
         if (code == Constants.CODE_OUTPUT_TEXT) {
-            return key.getOutputText();
+            final String outputText = key.getOutputText();
+            final String description = getSpokenEmoticonDescription(context, outputText);
+            return TextUtils.isEmpty(description) ? outputText : description;
         }
 
         // Just attempt to speak the description.
@@ -340,4 +344,21 @@
         }
         return resId;
     }
+
+    // TODO: Remove this method once TTS supports emoticon verbalization.
+    private String getSpokenEmoticonDescription(final Context context, final String outputText) {
+        final StringBuilder sb = new StringBuilder(SPOKEN_EMOTICON_RESOURCE_NAME_PREFIX);
+        final int textLength = outputText.length();
+        for (int index = 0; index < textLength; index = outputText.offsetByCodePoints(index, 1)) {
+            final int codePoint = outputText.codePointAt(index);
+            sb.append(String.format(Locale.ROOT, SPOKEN_EMOTICON_CODE_POINT_FORMAT, codePoint));
+        }
+        final String resourceName = sb.toString();
+        final Resources resources = context.getResources();
+        // Note that the resource package name may differ from the context package name.
+        final String resourcePackageName = resources.getResourcePackageName(
+                R.string.spoken_description_unknown);
+        final int resId = resources.getIdentifier(resourceName, "string", resourcePackageName);
+        return (resId == 0) ? null : resources.getString(resId);
+    }
 }
diff --git a/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java b/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java
index c937eee..5af3179 100644
--- a/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java
+++ b/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java
@@ -84,8 +84,8 @@
     }
 
     @UsedForTesting
-    public static boolean isAvailable() {
-        return sCursorAnchorInfoClass.exists();
+    public boolean isAvailable() {
+        return sCursorAnchorInfoClass.exists() && mInstance != null;
     }
 
     private Object mInstance;
@@ -96,7 +96,7 @@
 
     @UsedForTesting
     public static CursorAnchorInfoCompatWrapper fromObject(final Object instance) {
-        if (!isAvailable()) {
+        if (!sCursorAnchorInfoClass.exists()) {
             return new CursorAnchorInfoCompatWrapper(null);
         }
         return new CursorAnchorInfoCompatWrapper(instance);
diff --git a/java/src/com/android/inputmethod/keyboard/TextDecorator.java b/java/src/com/android/inputmethod/keyboard/TextDecorator.java
index 6e4e328..c22717f 100644
--- a/java/src/com/android/inputmethod/keyboard/TextDecorator.java
+++ b/java/src/com/android/inputmethod/keyboard/TextDecorator.java
@@ -182,7 +182,7 @@
     private void layoutMain() {
         final CursorAnchorInfoCompatWrapper info = mCursorAnchorInfoWrapper;
 
-        if (info == null) {
+        if (info == null || !info.isAvailable()) {
             cancelLayoutInternalExpectedly("CursorAnchorInfo isn't available.");
             return;
         }
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
index 1e1188b..71ce768 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
@@ -27,6 +27,9 @@
 import java.util.SortedSet;
 import java.util.TreeSet;
 
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
 public class KeyboardParams {
     public KeyboardId mId;
     public int mThemeId;
@@ -67,7 +70,7 @@
     public final KeyboardTextsSet mTextsSet = new KeyboardTextsSet();
     public final KeyStylesSet mKeyStyles = new KeyStylesSet(mTextsSet);
 
-    public KeysCache mKeysCache;
+    @Nullable public KeysCache mKeysCache;
     public boolean mAllowRedundantMoreKeys;
 
     public int mMostCommonKeyHeight = 0;
@@ -96,7 +99,7 @@
         clearHistogram();
     }
 
-    public void onAddKey(final Key newKey) {
+    public void onAddKey(@Nonnull final Key newKey) {
         final Key key = (mKeysCache != null) ? mKeysCache.get(newKey) : newKey;
         final boolean isSpacer = key.isSpacer();
         if (isSpacer && key.getWidth() == 0) {
@@ -129,7 +132,10 @@
         mSortedKeys.clear();
         for (final Key key : allKeys) {
             final Key filteredKey = Key.removeRedundantMoreKeys(key, lettersOnBaseLayout);
-            mSortedKeys.add(mKeysCache.replace(key, filteredKey));
+            if (mKeysCache != null) {
+                mKeysCache.replace(key, filteredKey);
+            }
+            mSortedKeys.add(filteredKey);
         }
     }
 
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
index a778ee8..1fc4f6a 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
@@ -86,15 +86,15 @@
         /*   0:32 */ "morekeys_a",
         /*   1:32 */ "morekeys_o",
         /*   2:31 */ "morekeys_e",
-        /*   3:30 */ "morekeys_u",
-        /*   4:30 */ "keylabel_to_alpha",
+        /*   3:31 */ "keylabel_to_alpha",
+        /*   4:30 */ "morekeys_u",
         /*   5:29 */ "morekeys_i",
         /*   6:24 */ "morekeys_n",
         /*   7:24 */ "morekeys_c",
         /*   8:23 */ "double_quotes",
         /*   9:22 */ "single_quotes",
         /*  10:21 */ "morekeys_s",
-        /*  11:18 */ "keyspec_currency",
+        /*  11:19 */ "keyspec_currency",
         /*  12:16 */ "morekeys_y",
         /*  13:15 */ "morekeys_z",
         /*  14:14 */ "morekeys_d",
@@ -266,12 +266,12 @@
     /* Default texts */
     private static final String[] TEXTS_DEFAULT = {
         /* morekeys_a ~ */
-        EMPTY, EMPTY, EMPTY, EMPTY,
-        /* ~ morekeys_u */
+        EMPTY, EMPTY, EMPTY,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         /* keylabel_to_alpha */ "ABC",
-        /* morekeys_i ~ */
-        EMPTY, EMPTY, EMPTY,
+        /* morekeys_u ~ */
+        EMPTY, EMPTY, EMPTY, EMPTY,
         /* ~ morekeys_c */
         /* double_quotes */ "!text/double_lqm_rqm",
         /* single_quotes */ "!text/single_lqm_rqm",
@@ -511,13 +511,13 @@
         // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
         // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
         /* morekeys_e */ "\u00E9,\u00E8,\u00EA,\u00EB,\u0119,\u0117,\u0113",
+        /* keylabel_to_alpha */ null,
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         /* morekeys_u */ "\u00FA,\u00FB,\u00FC,\u00F9,\u016B",
-        /* keylabel_to_alpha */ null,
         // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
         // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
@@ -540,17 +540,17 @@
     /* Locale ar: Arabic */
     private static final String[] TEXTS_ar = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0623: "أ" ARABIC LETTER ALEF WITH HAMZA ABOVE
         // U+200C: ZERO WIDTH NON-JOINER
         // U+0628: "ب" ARABIC LETTER BEH
         // U+062C: "ج" ARABIC LETTER JEEM
         /* keylabel_to_alpha */ "\u0623\u200C\u0628\u200C\u062C",
-        /* morekeys_i ~ */
+        /* morekeys_u ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null, null, null, null, null, null,
         /* ~ morekeys_cyrillic_soft_sign */
         // U+0661: "١" ARABIC-INDIC DIGIT ONE
         /* keyspec_symbols_1 */ "\u0661",
@@ -687,13 +687,13 @@
         // U+0259: "ə" LATIN SMALL LETTER SCHWA
         // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
         /* morekeys_e */ "\u0259,\u00E9",
+        /* keylabel_to_alpha */ null,
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         /* morekeys_u */ "\u00FC,\u00FB,\u00F9,\u00FA,\u016B",
-        /* keylabel_to_alpha */ null,
         // U+0131: "ı" LATIN SMALL LETTER DOTLESS I
         // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
@@ -731,15 +731,15 @@
     /* Locale be_BY: Belarusian (Belarus) */
     private static final String[] TEXTS_be_BY = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0410: "А" CYRILLIC CAPITAL LETTER A
         // U+0411: "Б" CYRILLIC CAPITAL LETTER BE
         // U+0412: "В" CYRILLIC CAPITAL LETTER VE
         /* keylabel_to_alpha */ "\u0410\u0411\u0412",
-        /* morekeys_i ~ */
-        null, null, null,
+        /* morekeys_u ~ */
+        null, null, null, null,
         /* ~ morekeys_c */
         /* double_quotes */ "!text/double_9qm_lqm",
         /* single_quotes */ "!text/single_9qm_lqm",
@@ -766,32 +766,49 @@
     /* Locale bg: Bulgarian */
     private static final String[] TEXTS_bg = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0410: "А" CYRILLIC CAPITAL LETTER A
         // U+0411: "Б" CYRILLIC CAPITAL LETTER BE
         // U+0412: "В" CYRILLIC CAPITAL LETTER VE
         /* keylabel_to_alpha */ "\u0410\u0411\u0412",
-        /* morekeys_i ~ */
-        null, null, null,
+        /* morekeys_u ~ */
+        null, null, null, null,
         /* ~ morekeys_c */
         // single_quotes of Bulgarian is default single_quotes_right_left.
         /* double_quotes */ "!text/double_9qm_lqm",
     };
 
-    /* Locale bn_IN: Bengali (India) */
-    private static final String[] TEXTS_bn_IN = {
+    /* Locale bn_BD: Bengali (Bangladesh) */
+    private static final String[] TEXTS_bn_BD = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0995: "क" BENGALI LETTER KA
         // U+0996: "ख" BENGALI LETTER KHA
         // U+0997: "ग" BENGALI LETTER GA
         /* keylabel_to_alpha */ "\u0995\u0996\u0997",
-        /* morekeys_i ~ */
-        null, null, null, null, null, null,
+        /* morekeys_u ~ */
+        null, null, null, null, null, null, null,
+        /* ~ morekeys_s */
+        // U+09F3: "৳" BENGALI RUPEE SIGN
+        /* keyspec_currency */ "\u09F3",
+    };
+
+    /* Locale bn_IN: Bengali (India) */
+    private static final String[] TEXTS_bn_IN = {
+        /* morekeys_a ~ */
+        null, null, null,
+        /* ~ morekeys_e */
+        // Label for "switch to alphabetic" key.
+        // U+0995: "क" BENGALI LETTER KA
+        // U+0996: "ख" BENGALI LETTER KHA
+        // U+0997: "ग" BENGALI LETTER GA
+        /* keylabel_to_alpha */ "\u0995\u0996\u0997",
+        /* morekeys_u ~ */
+        null, null, null, null, null, null, null,
         /* ~ morekeys_s */
         // U+20B9: "₹" INDIAN RUPEE SIGN
         /* keyspec_currency */ "\u20B9",
@@ -828,13 +845,13 @@
         // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
         // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
         /* morekeys_e */ "\u00E8,\u00E9,\u00EB,\u00EA,\u0119,\u0117,\u0113",
+        /* keylabel_to_alpha */ null,
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         /* morekeys_u */ "\u00FA,\u00FC,\u00F9,\u00FB,\u016B",
-        /* keylabel_to_alpha */ null,
         // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
         // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
@@ -901,6 +918,7 @@
         // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
         // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
         /* morekeys_e */ "\u00E9,\u011B,\u00E8,\u00EA,\u00EB,\u0119,\u0117,\u0113",
+        /* keylabel_to_alpha */ null,
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
@@ -908,7 +926,6 @@
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         /* morekeys_u */ "\u00FA,\u016F,\u00FB,\u00FC,\u00F9,\u016B",
-        /* keylabel_to_alpha */ null,
         // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
         // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
@@ -973,13 +990,13 @@
         // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
         // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
         /* morekeys_e */ "\u00E9,\u00EB",
+        /* keylabel_to_alpha */ null,
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         /* morekeys_u */ "\u00FA,\u00FC,\u00FB,\u00F9,\u016B",
-        /* keylabel_to_alpha */ null,
         // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
         /* morekeys_i */ "\u00ED,\u00EF",
@@ -1051,13 +1068,13 @@
         // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
         // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
         /* morekeys_e */ "\u00E9,\u00E8,\u00EA,\u00EB,\u0117",
+        /* keylabel_to_alpha */ null,
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         /* morekeys_u */ "\u00FC,%,\u00FB,\u00F9,\u00FA,\u016B",
-        /* keylabel_to_alpha */ null,
         /* morekeys_i */ null,
         // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
         // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
@@ -1096,8 +1113,8 @@
     /* Locale el: Greek */
     private static final String[] TEXTS_el = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0391: "Α" GREEK CAPITAL LETTER ALPHA
         // U+0392: "Β" GREEK CAPITAL LETTER BETA
@@ -1131,13 +1148,13 @@
         // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
         // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
         /* morekeys_e */ "\u00E9,\u00E8,\u00EA,\u00EB,\u0113",
+        /* keylabel_to_alpha */ null,
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         /* morekeys_u */ "\u00FA,\u00FB,\u00FC,\u00F9,\u016B",
-        /* keylabel_to_alpha */ null,
         // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
         // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
@@ -1188,6 +1205,7 @@
         // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
         // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
         /* morekeys_e */ "\u00E9,\u011B,\u00E8,\u00EA,\u00EB,\u0119,\u0117,\u0113",
+        /* keylabel_to_alpha */ null,
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
@@ -1199,7 +1217,6 @@
         // U+0173: "ų" LATIN SMALL LETTER U WITH OGONEK
         // U+00B5: "µ" MICRO SIGN
         /* morekeys_u */ "\u00FA,\u016F,\u00FB,\u00FC,\u00F9,\u016B,\u0169,\u0171,\u0173,\u00B5",
-        /* keylabel_to_alpha */ null,
         // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
         // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
@@ -1334,13 +1351,13 @@
         // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
         // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
         /* morekeys_e */ "\u00E9,\u00E8,\u00EB,\u00EA,\u0119,\u0117,\u0113",
+        /* keylabel_to_alpha */ null,
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         /* morekeys_u */ "\u00FA,\u00FC,\u00F9,\u00FB,\u016B",
-        /* keylabel_to_alpha */ null,
         // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
         // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
@@ -1396,6 +1413,7 @@
         // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK
         // U+011B: "ě" LATIN SMALL LETTER E WITH CARON
         /* morekeys_e */ "\u0113,\u00E8,\u0117,\u00E9,\u00EA,\u00EB,\u0119,\u011B",
+        /* keylabel_to_alpha */ null,
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         // U+0173: "ų" LATIN SMALL LETTER U WITH OGONEK
@@ -1405,7 +1423,6 @@
         // U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE
         // U+0171: "ű" LATIN SMALL LETTER U WITH DOUBLE ACUTE
         /* morekeys_u */ "\u00FC,\u016B,\u0173,\u00F9,\u00FA,\u00FB,\u016F,\u0171",
-        /* keylabel_to_alpha */ null,
         // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
         // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
         // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
@@ -1500,13 +1517,13 @@
         // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
         // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
         /* morekeys_e */ "\u00E9,\u00E8,\u00EB,\u00EA,\u0119,\u0117,\u0113",
+        /* keylabel_to_alpha */ null,
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         /* morekeys_u */ "\u00FA,\u00FC,\u00F9,\u00FB,\u016B",
-        /* keylabel_to_alpha */ null,
         // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
         // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
@@ -1526,16 +1543,16 @@
     /* Locale fa: Persian */
     private static final String[] TEXTS_fa = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0627: "ا" ARABIC LETTER ALEF
         // U+200C: ZERO WIDTH NON-JOINER
         // U+0628: "ب" ARABIC LETTER BEH
         // U+067E: "پ" ARABIC LETTER PEH
         /* keylabel_to_alpha */ "\u0627\u200C\u0628\u200C\u067E",
-        /* morekeys_i ~ */
-        null, null, null, null, null, null,
+        /* morekeys_u ~ */
+        null, null, null, null, null, null, null,
         /* ~ morekeys_s */
         // U+FDFC: "﷼" RIAL SIGN
         /* keyspec_currency */ "\uFDFC",
@@ -1689,10 +1706,11 @@
         // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
         /* morekeys_o */ "\u00F6,\u00F8,\u00F4,\u00F2,\u00F3,\u00F5,\u0153,\u014D",
         /* morekeys_e */ null,
+        /* keylabel_to_alpha */ null,
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         /* morekeys_u */ "\u00FC",
-        /* keylabel_to_alpha ~ */
-        null, null, null, null, null, null,
+        /* morekeys_i ~ */
+        null, null, null, null, null,
         /* ~ single_quotes */
         // U+0161: "š" LATIN SMALL LETTER S WITH CARON
         // U+00DF: "ß" LATIN SMALL LETTER SHARP S
@@ -1753,13 +1771,13 @@
         // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
         // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
         /* morekeys_e */ "\u00E9,\u00E8,\u00EA,\u00EB,%,\u0119,\u0117,\u0113",
+        /* keylabel_to_alpha */ null,
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         /* morekeys_u */ "\u00F9,\u00FB,%,\u00FC,\u00FA,\u016B",
-        /* keylabel_to_alpha */ null,
         // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
         // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
@@ -1827,13 +1845,13 @@
         // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
         // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
         /* morekeys_e */ "\u00E9,\u00E8,\u00EB,\u00EA,\u0119,\u0117,\u0113",
+        /* keylabel_to_alpha */ null,
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         /* morekeys_u */ "\u00FA,\u00FC,\u00F9,\u00FB,\u016B",
-        /* keylabel_to_alpha */ null,
         // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
         // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
@@ -1853,15 +1871,15 @@
     /* Locale hi: Hindi */
     private static final String[] TEXTS_hi = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0915: "क" DEVANAGARI LETTER KA
         // U+0916: "ख" DEVANAGARI LETTER KHA
         // U+0917: "ग" DEVANAGARI LETTER GA
         /* keylabel_to_alpha */ "\u0915\u0916\u0917",
-        /* morekeys_i ~ */
-        null, null, null, null, null, null,
+        /* morekeys_u ~ */
+        null, null, null, null, null, null, null,
         /* ~ morekeys_s */
         // U+20B9: "₹" INDIAN RUPEE SIGN
         /* keyspec_currency */ "\u20B9",
@@ -1991,6 +2009,7 @@
         // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
         // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
         /* morekeys_e */ "\u00E9,\u00E8,\u00EA,\u00EB,\u0119,\u0117,\u0113",
+        /* keylabel_to_alpha */ null,
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         // U+0171: "ű" LATIN SMALL LETTER U WITH DOUBLE ACUTE
@@ -1998,7 +2017,6 @@
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         /* morekeys_u */ "\u00FA,\u00FC,\u0171,\u00FB,\u00F9,\u016B",
-        /* keylabel_to_alpha */ null,
         // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
         // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
@@ -2020,18 +2038,18 @@
     /* Locale hy_AM: Armenian (Armenia) */
     private static final String[] TEXTS_hy_AM = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0531: "Ա" ARMENIAN CAPITAL LETTER AYB
         // U+0532: "Բ" ARMENIAN CAPITAL LETTER BEN
         // U+0533: "Գ" ARMENIAN CAPITAL LETTER GIM
         /* keylabel_to_alpha */ "\u0531\u0532\u0533",
-        /* morekeys_i ~ */
+        /* morekeys_u ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null,
+        null, null, null, null, null,
         /* ~ morekeys_nordic_row2_11 */
         // U+055E: "՞" ARMENIAN QUESTION MARK
         // U+055C: "՜" ARMENIAN EXCLAMATION MARK
@@ -2106,13 +2124,13 @@
         // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
         // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
         /* morekeys_e */ "\u00E9,\u00EB,\u00E8,\u00EA,\u0119,\u0117,\u0113",
+        /* keylabel_to_alpha */ null,
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         /* morekeys_u */ "\u00FA,\u00FC,\u00FB,\u00F9,\u016B",
-        /* keylabel_to_alpha */ null,
         // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
         // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
@@ -2166,13 +2184,13 @@
         // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
         // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
         /* morekeys_e */ "\u00E8,\u00E9,\u00EA,\u00EB,\u0119,\u0117,\u0113",
+        /* keylabel_to_alpha */ null,
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         /* morekeys_u */ "\u00F9,\u00FA,\u00FB,\u00FC,\u016B",
-        /* keylabel_to_alpha */ null,
         // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
         // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
         // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
@@ -2203,15 +2221,15 @@
     /* Locale iw: Hebrew */
     private static final String[] TEXTS_iw = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+05D0: "א" HEBREW LETTER ALEF
         // U+05D1: "ב" HEBREW LETTER BET
         // U+05D2: "ג" HEBREW LETTER GIMEL
         /* keylabel_to_alpha */ "\u05D0\u05D1\u05D2",
-        /* morekeys_i ~ */
-        null, null, null,
+        /* morekeys_u ~ */
+        null, null, null, null,
         /* ~ morekeys_c */
         /* double_quotes */ "!text/double_rqm_9qm",
         /* single_quotes */ "!text/single_rqm_9qm",
@@ -2262,15 +2280,15 @@
     /* Locale ka_GE: Georgian (Georgia) */
     private static final String[] TEXTS_ka_GE = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+10D0: "ა" GEORGIAN LETTER AN
         // U+10D1: "ბ" GEORGIAN LETTER BAN
         // U+10D2: "გ" GEORGIAN LETTER GAN
         /* keylabel_to_alpha */ "\u10D0\u10D1\u10D2",
-        /* morekeys_i ~ */
-        null, null, null,
+        /* morekeys_u ~ */
+        null, null, null, null,
         /* ~ morekeys_c */
         /* double_quotes */ "!text/double_9qm_lqm",
         /* single_quotes */ "!text/single_9qm_lqm",
@@ -2279,16 +2297,16 @@
     /* Locale kk: Kazakh */
     private static final String[] TEXTS_kk = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0410: "А" CYRILLIC CAPITAL LETTER A
         // U+0411: "Б" CYRILLIC CAPITAL LETTER BE
         // U+0412: "В" CYRILLIC CAPITAL LETTER VE
         /* keylabel_to_alpha */ "\u0410\u0411\u0412",
-        /* morekeys_i ~ */
+        /* morekeys_u ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null,
+        null, null, null,
         /* ~ morekeys_k */
         // U+0451: "ё" CYRILLIC SMALL LETTER IO
         /* morekeys_cyrillic_ie */ "\u0451",
@@ -2338,14 +2356,14 @@
     /* Locale km_KH: Khmer (Cambodia) */
     private static final String[] TEXTS_km_KH = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+1780: "ក" KHMER LETTER KA
         // U+1781: "ខ" KHMER LETTER KHA
         // U+1782: "គ" KHMER LETTER KO
         /* keylabel_to_alpha */ "\u1780\u1781\u1782",
-        /* morekeys_i ~ */
+        /* morekeys_u ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
@@ -2354,7 +2372,7 @@
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null,
+        null, null, null, null, null,
         /* ~ morekeys_cyrillic_a */
         // U+17DB: "៛" KHMER CURRENCY SYMBOL RIEL
         /* morekeys_currency_dollar */ "\u17DB,\u00A2,\u00A3,\u20AC,\u00A5,\u20B1",
@@ -2363,15 +2381,15 @@
     /* Locale kn_IN: Kannada (India) */
     private static final String[] TEXTS_kn_IN = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0C85: "ಅ" KANNADA LETTER A
         // U+0C86: "ಆ" KANNADA LETTER AA
         // U+0C87: "ಇ" KANNADA LETTER I
         /* keylabel_to_alpha */ "\u0C85\u0C86\u0C87",
-        /* morekeys_i ~ */
-        null, null, null, null, null, null,
+        /* morekeys_u ~ */
+        null, null, null, null, null, null, null,
         /* ~ morekeys_s */
         // U+20B9: "₹" INDIAN RUPEE SIGN
         /* keyspec_currency */ "\u20B9",
@@ -2380,16 +2398,16 @@
     /* Locale ky: Kirghiz */
     private static final String[] TEXTS_ky = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0410: "А" CYRILLIC CAPITAL LETTER A
         // U+0411: "Б" CYRILLIC CAPITAL LETTER BE
         // U+0412: "В" CYRILLIC CAPITAL LETTER VE
         /* keylabel_to_alpha */ "\u0410\u0411\u0412",
-        /* morekeys_i ~ */
+        /* morekeys_u ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null,
+        null, null, null,
         /* ~ morekeys_k */
         // U+0451: "ё" CYRILLIC SMALL LETTER IO
         /* morekeys_cyrillic_ie */ "\u0451",
@@ -2424,15 +2442,15 @@
     /* Locale lo_LA: Lao (Laos) */
     private static final String[] TEXTS_lo_LA = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0E81: "ກ" LAO LETTER KO
         // U+0E82: "ຂ" LAO LETTER KHO SUNG
         // U+0E84: "ຄ" LAO LETTER KHO TAM
         /* keylabel_to_alpha */ "\u0E81\u0E82\u0E84",
-        /* morekeys_i ~ */
-        null, null, null, null, null, null,
+        /* morekeys_u ~ */
+        null, null, null, null, null, null, null,
         /* ~ morekeys_s */
         // U+20AD: "₭" KIP SIGN
         /* keyspec_currency */ "\u20AD",
@@ -2468,6 +2486,7 @@
         // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
         // U+011B: "ě" LATIN SMALL LETTER E WITH CARON
         /* morekeys_e */ "\u0117,\u0119,\u0113,\u00E8,\u00E9,\u00EA,\u00EB,\u011B",
+        /* keylabel_to_alpha */ null,
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         // U+0173: "ų" LATIN SMALL LETTER U WITH OGONEK
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
@@ -2478,7 +2497,6 @@
         // U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE
         // U+0171: "ű" LATIN SMALL LETTER U WITH DOUBLE ACUTE
         /* morekeys_u */ "\u016B,\u0173,\u00FC,\u016B,\u00F9,\u00FA,\u00FB,\u016F,\u0171",
-        /* keylabel_to_alpha */ null,
         // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
         // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
         // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
@@ -2563,6 +2581,7 @@
         // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK
         // U+011B: "ě" LATIN SMALL LETTER E WITH CARON
         /* morekeys_e */ "\u0113,\u0117,\u00E8,\u00E9,\u00EA,\u00EB,\u0119,\u011B",
+        /* keylabel_to_alpha */ null,
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         // U+0173: "ų" LATIN SMALL LETTER U WITH OGONEK
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
@@ -2572,7 +2591,6 @@
         // U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE
         // U+0171: "ű" LATIN SMALL LETTER U WITH DOUBLE ACUTE
         /* morekeys_u */ "\u016B,\u0173,\u00F9,\u00FA,\u00FB,\u00FC,\u016F,\u0171",
-        /* keylabel_to_alpha */ null,
         // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
         // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
         // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
@@ -2630,15 +2648,15 @@
     /* Locale mk: Macedonian */
     private static final String[] TEXTS_mk = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0410: "А" CYRILLIC CAPITAL LETTER A
         // U+0411: "Б" CYRILLIC CAPITAL LETTER BE
         // U+0412: "В" CYRILLIC CAPITAL LETTER VE
         /* keylabel_to_alpha */ "\u0410\u0411\u0412",
-        /* morekeys_i ~ */
-        null, null, null,
+        /* morekeys_u ~ */
+        null, null, null, null,
         /* ~ morekeys_c */
         /* double_quotes */ "!text/double_9qm_lqm",
         /* single_quotes */ "!text/single_9qm_lqm",
@@ -2669,13 +2687,13 @@
     /* Locale ml_IN: Malayalam (India) */
     private static final String[] TEXTS_ml_IN = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0D05: "അ" MALAYALAM LETTER A
         /* keylabel_to_alpha */ "\u0D05",
-        /* morekeys_i ~ */
-        null, null, null, null, null, null,
+        /* morekeys_u ~ */
+        null, null, null, null, null, null, null,
         /* ~ morekeys_s */
         // U+20B9: "₹" INDIAN RUPEE SIGN
         /* keyspec_currency */ "\u20B9",
@@ -2684,15 +2702,15 @@
     /* Locale mn_MN: Mongolian (Mongolia) */
     private static final String[] TEXTS_mn_MN = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0410: "А" CYRILLIC CAPITAL LETTER A
         // U+0411: "Б" CYRILLIC CAPITAL LETTER BE
         // U+0412: "В" CYRILLIC CAPITAL LETTER VE
         /* keylabel_to_alpha */ "\u0410\u0411\u0412",
-        /* morekeys_i ~ */
-        null, null, null, null, null, null,
+        /* morekeys_u ~ */
+        null, null, null, null, null, null, null,
         /* ~ morekeys_s */
         // U+20AE: "₮" TUGRIK SIGN
         /* keyspec_currency */ "\u20AE",
@@ -2701,15 +2719,15 @@
     /* Locale mr_IN: Marathi (India) */
     private static final String[] TEXTS_mr_IN = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0915: "क" DEVANAGARI LETTER KA
         // U+0916: "ख" DEVANAGARI LETTER KHA
         // U+0917: "ग" DEVANAGARI LETTER GA
         /* keylabel_to_alpha */ "\u0915\u0916\u0917",
-        /* morekeys_i ~ */
-        null, null, null, null, null, null,
+        /* morekeys_u ~ */
+        null, null, null, null, null, null, null,
         /* ~ morekeys_s */
         // U+20B9: "₹" INDIAN RUPEE SIGN
         /* keyspec_currency */ "\u20B9",
@@ -2754,18 +2772,18 @@
     /* Locale my_MM: Burmese (Myanmar) */
     private static final String[] TEXTS_my_MM = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+1000: "က" MYANMAR LETTER KA
         // U+1001: "ခ" MYANMAR LETTER KHA
         // U+1002: "ဂ" MYANMAR LETTER GA
         /* keylabel_to_alpha */ "\u1000\u1001\u1002",
-        /* morekeys_i ~ */
+        /* morekeys_u ~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
-        null, null, null, null,
+        null, null, null, null, null,
         /* ~ morekeys_nordic_row2_11 */
         /* morekeys_punctuation */ "!autoColumnOrder!9,\u104A,.,?,!,#,),(,/,;,...,',@,:,-,\",+,\\%,&",
         // U+104A: "၊" MYANMAR SIGN LITTLE SECTION
@@ -2817,14 +2835,15 @@
         // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
         // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
         /* morekeys_e */ "\u00E9,\u00E8,\u00EA,\u00EB,\u0119,\u0117,\u0113",
+        /* keylabel_to_alpha */ null,
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         /* morekeys_u */ "\u00FC,\u00FB,\u00F9,\u00FA,\u016B",
-        /* keylabel_to_alpha ~ */
-        null, null, null, null,
+        /* morekeys_i ~ */
+        null, null, null,
         /* ~ morekeys_c */
         /* double_quotes */ "!text/double_9qm_rqm",
         /* single_quotes */ "!text/single_9qm_rqm",
@@ -2850,15 +2869,15 @@
     /* Locale ne_NP: Nepali (Nepal) */
     private static final String[] TEXTS_ne_NP = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0915: "क" DEVANAGARI LETTER KA
         // U+0916: "ख" DEVANAGARI LETTER KHA
         // U+0917: "ग" DEVANAGARI LETTER GA
         /* keylabel_to_alpha */ "\u0915\u0916\u0917",
-        /* morekeys_i ~ */
-        null, null, null, null, null, null,
+        /* morekeys_u ~ */
+        null, null, null, null, null, null, null,
         /* ~ morekeys_s */
         // U+0930/U+0941/U+002E "रु." NEPALESE RUPEE SIGN
         /* keyspec_currency */ "\u0930\u0941.",
@@ -2928,13 +2947,13 @@
         // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
         // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
         /* morekeys_e */ "\u00E9,\u00EB,\u00EA,\u00E8,\u0119,\u0117,\u0113",
+        /* keylabel_to_alpha */ null,
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         /* morekeys_u */ "\u00FA,\u00FC,\u00FB,\u00F9,\u016B",
-        /* keylabel_to_alpha */ null,
         // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
         // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
@@ -2984,7 +3003,7 @@
         // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
         // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
         /* morekeys_e */ "\u0119,\u00E8,\u00E9,\u00EA,\u00EB,\u0117,\u0113",
-        /* morekeys_u ~ */
+        /* keylabel_to_alpha ~ */
         null, null, null,
         /* ~ morekeys_i */
         // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
@@ -3041,13 +3060,13 @@
         // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
         // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
         /* morekeys_e */ "\u00E9,\u00EA,\u00E8,\u0119,\u0117,\u0113,\u00EB",
+        /* keylabel_to_alpha */ null,
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         /* morekeys_u */ "\u00FA,\u00FC,\u00F9,\u00FB,\u016B",
-        /* keylabel_to_alpha */ null,
         // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
         // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
         // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
@@ -3089,7 +3108,7 @@
         /* morekeys_a */ "\u0103,\u00E2,\u00E3,\u00E0,\u00E1,\u00E4,\u00E6,\u00E5,\u0101",
         /* morekeys_o ~ */
         null, null, null, null,
-        /* ~ keylabel_to_alpha */
+        /* ~ morekeys_u */
         // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
         // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
@@ -3116,15 +3135,15 @@
     /* Locale ru: Russian */
     private static final String[] TEXTS_ru = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0410: "А" CYRILLIC CAPITAL LETTER A
         // U+0411: "Б" CYRILLIC CAPITAL LETTER BE
         // U+0412: "В" CYRILLIC CAPITAL LETTER VE
         /* keylabel_to_alpha */ "\u0410\u0411\u0412",
-        /* morekeys_i ~ */
-        null, null, null,
+        /* morekeys_u ~ */
+        null, null, null, null,
         /* ~ morekeys_c */
         /* double_quotes */ "!text/double_9qm_lqm",
         /* single_quotes */ "!text/single_9qm_lqm",
@@ -3151,14 +3170,14 @@
     /* Locale si_LK: Sinhalese (Sri Lanka) */
     private static final String[] TEXTS_si_LK = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0D85: "අ" SINHALA LETTER AYANNA
         // U+0D86: "ආ" SINHALA LETTER AAYANNA
         /* keylabel_to_alpha */ "\u0D85,\u0D86",
-        /* morekeys_i ~ */
-        null, null, null, null, null, null,
+        /* morekeys_u ~ */
+        null, null, null, null, null, null, null,
         /* ~ morekeys_s */
         // U+0DBB/U+0DD4: "රු" SINHALA LETTER RAYANNA/SINHALA VOWEL SIGN KETTI PAA-PILLA
         /* keyspec_currency */ "\u0DBB\u0DD4",
@@ -3194,6 +3213,7 @@
         // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
         // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK
         /* morekeys_e */ "\u00E9,\u011B,\u0113,\u0117,\u00E8,\u00EA,\u00EB,\u0119",
+        /* keylabel_to_alpha */ null,
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
@@ -3203,7 +3223,6 @@
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
         // U+0171: "ű" LATIN SMALL LETTER U WITH DOUBLE ACUTE
         /* morekeys_u */ "\u00FA,\u016F,\u00FC,\u016B,\u0173,\u00F9,\u00FB,\u0171",
-        /* keylabel_to_alpha */ null,
         // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
         // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
         // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK
@@ -3287,16 +3306,16 @@
     /* Locale sr: Serbian */
     private static final String[] TEXTS_sr = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // END: More keys definitions for Serbian (Cyrillic)
         // Label for "switch to alphabetic" key.
         // U+0410: "А" CYRILLIC CAPITAL LETTER A
         // U+0411: "Б" CYRILLIC CAPITAL LETTER BE
         // U+0412: "В" CYRILLIC CAPITAL LETTER VE
         /* keylabel_to_alpha */ "\u0410\u0411\u0412",
-        /* morekeys_i ~ */
-        null, null, null,
+        /* morekeys_u ~ */
+        null, null, null, null,
         /* ~ morekeys_c */
         /* double_quotes */ "!text/double_9qm_lqm",
         /* single_quotes */ "!text/single_9qm_lqm",
@@ -3352,8 +3371,8 @@
         /* morekeys_o */ null,
         // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
         /* morekeys_e */ "\u00E8",
-        /* morekeys_u */ null,
         /* keylabel_to_alpha */ null,
+        /* morekeys_u */ null,
         // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
         /* morekeys_i */ "\u00EC",
         /* morekeys_n */ null,
@@ -3415,13 +3434,13 @@
         // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
         // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK
         /* morekeys_e */ "\u00E9,\u00E8,\u00EA,\u00EB,\u0119",
+        /* keylabel_to_alpha */ null,
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         /* morekeys_u */ "\u00FC,\u00FA,\u00F9,\u00FB,\u016B",
-        /* keylabel_to_alpha */ null,
         // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
         // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
         // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
@@ -3509,13 +3528,13 @@
         // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
         // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
         /* morekeys_e */ "\u00E8,\u00E9,\u00EA,\u00EB,\u0113",
+        /* keylabel_to_alpha */ null,
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         /* morekeys_u */ "\u00FB,\u00FC,\u00F9,\u00FA,\u016B",
-        /* keylabel_to_alpha */ null,
         // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
         // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
@@ -3539,15 +3558,15 @@
     /* Locale ta_IN: Tamil (India) */
     private static final String[] TEXTS_ta_IN = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0BA4: "த" TAMIL LETTER TA
         // U+0BAE/U+0BBF: "மி" TAMIL LETTER MA/TAMIL VOWEL SIGN I
         // U+0BB4/U+0BCD: "ழ்" TAMIL LETTER LLLA/TAMIL SIGN VIRAMA
         /* keylabel_to_alpha */ "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD",
-        /* morekeys_i ~ */
-        null, null, null, null, null, null,
+        /* morekeys_u ~ */
+        null, null, null, null, null, null, null,
         /* ~ morekeys_s */
         // U+0BF9: "௹" TAMIL RUPEE SIGN
         /* keyspec_currency */ "\u0BF9",
@@ -3556,15 +3575,15 @@
     /* Locale ta_LK: Tamil (Sri Lanka) */
     private static final String[] TEXTS_ta_LK = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0BA4: "த" TAMIL LETTER TA
         // U+0BAE/U+0BBF: "மி" TAMIL LETTER MA/TAMIL VOWEL SIGN I
         // U+0BB4/U+0BCD: "ழ்" TAMIL LETTER LLLA/TAMIL SIGN VIRAMA
         /* keylabel_to_alpha */ "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD",
-        /* morekeys_i ~ */
-        null, null, null, null, null, null,
+        /* morekeys_u ~ */
+        null, null, null, null, null, null, null,
         /* ~ morekeys_s */
         // U+0DBB/U+0DD4: "රු" SINHALA LETTER RAYANNA/SINHALA VOWEL SIGN KETTI PAA-PILLA
         /* keyspec_currency */ "\u0DBB\u0DD4",
@@ -3573,8 +3592,8 @@
     /* Locale ta_SG: Tamil (Singapore) */
     private static final String[] TEXTS_ta_SG = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0BA4: "த" TAMIL LETTER TA
         // U+0BAE/U+0BBF: "மி" TAMIL LETTER MA/TAMIL VOWEL SIGN I
@@ -3585,15 +3604,15 @@
     /* Locale te_IN: Telugu (India) */
     private static final String[] TEXTS_te_IN = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0C05: "అ" TELUGU LETTER A
         // U+0C06: "ఆ" TELUGU LETTER AA
         // U+0C07: "ఇ" TELUGU LETTER I
         /* keylabel_to_alpha */ "\u0C05\u0C06\u0C07",
-        /* morekeys_i ~ */
-        null, null, null, null, null, null,
+        /* morekeys_u ~ */
+        null, null, null, null, null, null, null,
         /* ~ morekeys_s */
         // U+20B9: "₹" INDIAN RUPEE SIGN
         /* keyspec_currency */ "\u20B9",
@@ -3602,15 +3621,15 @@
     /* Locale th: Thai */
     private static final String[] TEXTS_th = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0E01: "ก" THAI CHARACTER KO KAI
         // U+0E02: "ข" THAI CHARACTER KHO KHAI
         // U+0E04: "ค" THAI CHARACTER KHO KHWAI
         /* keylabel_to_alpha */ "\u0E01\u0E02\u0E04",
-        /* morekeys_i ~ */
-        null, null, null, null, null, null,
+        /* morekeys_u ~ */
+        null, null, null, null, null, null, null,
         /* ~ morekeys_s */
         // U+0E3F: "฿" THAI CURRENCY SYMBOL BAHT
         /* keyspec_currency */ "\u0E3F",
@@ -3647,13 +3666,13 @@
         // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE
         // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
         /* morekeys_e */ "\u00E9,\u00E8,\u00EB,\u00EA,\u0119,\u0117,\u0113",
+        /* keylabel_to_alpha */ null,
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         /* morekeys_u */ "\u00FA,\u00FC,\u00F9,\u00FB,\u016B",
-        /* keylabel_to_alpha */ null,
         // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
         // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
@@ -3688,13 +3707,13 @@
         // U+0259: "ə" LATIN SMALL LETTER SCHWA
         // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
         /* morekeys_e */ "\u0259,\u00E9",
+        /* keylabel_to_alpha */ null,
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         /* morekeys_u */ "\u00FC,\u00FB,\u00F9,\u00FA,\u016B",
-        /* keylabel_to_alpha */ null,
         // U+0131: "ı" LATIN SMALL LETTER DOTLESS I
         // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
@@ -3732,15 +3751,15 @@
     /* Locale uk: Ukrainian */
     private static final String[] TEXTS_uk = {
         /* morekeys_a ~ */
-        null, null, null, null,
-        /* ~ morekeys_u */
+        null, null, null,
+        /* ~ morekeys_e */
         // Label for "switch to alphabetic" key.
         // U+0410: "А" CYRILLIC CAPITAL LETTER A
         // U+0411: "Б" CYRILLIC CAPITAL LETTER BE
         // U+0412: "В" CYRILLIC CAPITAL LETTER VE
         /* keylabel_to_alpha */ "\u0410\u0411\u0412",
-        /* morekeys_i ~ */
-        null, null, null,
+        /* morekeys_u ~ */
+        null, null, null, null,
         /* ~ morekeys_c */
         /* double_quotes */ "!text/double_9qm_lqm",
         /* single_quotes */ "!text/single_9qm_lqm",
@@ -3824,6 +3843,7 @@
         // U+1EC5: "ễ" LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE
         // U+1EC7: "ệ" LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW
         /* morekeys_e */ "\u00E8,\u00E9,\u1EBB,\u1EBD,\u1EB9,\u00EA,\u1EC1,\u1EBF,\u1EC3,\u1EC5,\u1EC7",
+        /* keylabel_to_alpha */ null,
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+1EE7: "ủ" LATIN SMALL LETTER U WITH HOOK ABOVE
@@ -3836,7 +3856,6 @@
         // U+1EEF: "ữ" LATIN SMALL LETTER U WITH HORN AND TILDE
         // U+1EF1: "ự" LATIN SMALL LETTER U WITH HORN AND DOT BELOW
         /* morekeys_u */ "\u00F9,\u00FA,\u1EE7,\u0169,\u1EE5,\u01B0,\u1EEB,\u1EE9,\u1EED,\u1EEF,\u1EF1",
-        /* keylabel_to_alpha */ null,
         // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
         // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
         // U+1EC9: "ỉ" LATIN SMALL LETTER I WITH HOOK ABOVE
@@ -3886,13 +3905,13 @@
         // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
         // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
         /* morekeys_e */ "\u00E9,\u00E8,\u00EA,\u00EB,\u0113",
+        /* keylabel_to_alpha */ null,
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
         // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
         /* morekeys_u */ "\u00FA,\u00FB,\u00FC,\u00F9,\u016B",
-        /* keylabel_to_alpha */ null,
         // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
         // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
         // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
@@ -3945,6 +3964,7 @@
         // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK
         // U+011B: "ě" LATIN SMALL LETTER E WITH CARON
         /* morekeys_e */ "\u00E8,\u00E9,\u00EA,\u00EB,\u0113,\u0115,\u0117,\u0119,\u011B",
+        /* keylabel_to_alpha */ null,
         // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
         // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
         // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
@@ -3956,7 +3976,6 @@
         // U+0171: "ű" LATIN SMALL LETTER U WITH DOUBLE ACUTE
         // U+0173: "ų" LATIN SMALL LETTER U WITH OGONEK
         /* morekeys_u */ "\u00F9,\u00FA,\u00FB,\u00FC,\u0169,\u016B,\u016D,\u016F,\u0171,\u0173",
-        /* keylabel_to_alpha */ null,
         // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
         // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
         // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
@@ -4056,12 +4075,13 @@
         "az_AZ"  , TEXTS_az_AZ, /*  11/ 18 Azerbaijani (Azerbaijan) */
         "be_BY"  , TEXTS_be_BY, /*   9/ 32 Belarusian (Belarus) */
         "bg"     , TEXTS_bg,    /*   2/  9 Bulgarian */
+        "bn_BD"  , TEXTS_bn_BD, /*   2/ 12 Bengali (Bangladesh) */
         "bn_IN"  , TEXTS_bn_IN, /*   2/ 12 Bengali (India) */
         "ca"     , TEXTS_ca,    /*  11/ 96 Catalan */
         "cs"     , TEXTS_cs,    /*  17/ 21 Czech */
         "da"     , TEXTS_da,    /*  19/ 54 Danish */
         "de"     , TEXTS_de,    /*  16/ 62 German */
-        "el"     , TEXTS_el,    /*   1/  5 Greek */
+        "el"     , TEXTS_el,    /*   1/  4 Greek */
         "en"     , TEXTS_en,    /*   8/ 11 English */
         "eo"     , TEXTS_eo,    /*  26/126 Esperanto */
         "es"     , TEXTS_es,    /*   8/ 55 Spanish */
@@ -4109,7 +4129,7 @@
         "sw"     , TEXTS_sw,    /*   9/ 18 Swahili */
         "ta_IN"  , TEXTS_ta_IN, /*   2/ 12 Tamil (India) */
         "ta_LK"  , TEXTS_ta_LK, /*   2/ 12 Tamil (Sri Lanka) */
-        "ta_SG"  , TEXTS_ta_SG, /*   1/  5 Tamil (Singapore) */
+        "ta_SG"  , TEXTS_ta_SG, /*   1/  4 Tamil (Singapore) */
         "te_IN"  , TEXTS_te_IN, /*   2/ 12 Telugu (India) */
         "th"     , TEXTS_th,    /*   2/ 12 Thai */
         "tl"     , TEXTS_tl,    /*   7/  8 Tagalog */
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 27af161..d7e1eba 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -1591,6 +1591,10 @@
         final String committedWordString = committedWord.toString();
         final int cancelLength = committedWord.length();
         final String separatorString = mLastComposedWord.mSeparatorString;
+        // If our separator is a space, we won't actually commit it,
+        // but set the space state to PHANTOM so that a space will be inserted
+        // on the next keypress
+        final boolean usePhantomSpace = separatorString.equals(Constants.STRING_SPACE);
         // We want java chars, not codepoints for the following.
         final int separatorLength = separatorString.length();
         // TODO: should we check our saved separator against the actual contents of the text view?
@@ -1611,7 +1615,8 @@
         if (!TextUtils.isEmpty(committedWord)) {
             mDictionaryFacilitator.removeWordFromPersonalizedDicts(committedWordString);
         }
-        final String stringToCommit = originallyTypedWord + separatorString;
+        final String stringToCommit = originallyTypedWord +
+                (usePhantomSpace ? "" : separatorString);
         final SpannableString textToCommit = new SpannableString(stringToCommit);
         if (committedWord instanceof SpannableString) {
             final SpannableString committedWordWithSuggestionSpans = (SpannableString)committedWord;
@@ -1663,6 +1668,9 @@
             } else {
                 mConnection.commitText(textToCommit, 1);
             }
+            if (usePhantomSpace) {
+                mSpaceState = SpaceState.PHANTOM;
+            }
         } else {
             // For languages without spaces, we revert the typed string but the cursor is flush
             // with the typed word, so we need to resume suggestions right away.
diff --git a/java/src/com/android/inputmethod/latin/makedict/DictionaryHeader.java b/java/src/com/android/inputmethod/latin/makedict/DictionaryHeader.java
index df447fd..3f9ffd2 100644
--- a/java/src/com/android/inputmethod/latin/makedict/DictionaryHeader.java
+++ b/java/src/com/android/inputmethod/latin/makedict/DictionaryHeader.java
@@ -47,6 +47,7 @@
     public static final String MAX_UNIGRAM_COUNT_KEY = "MAX_UNIGRAM_COUNT";
     public static final String MAX_BIGRAM_COUNT_KEY = "MAX_BIGRAM_COUNT";
     public static final String ATTRIBUTE_VALUE_TRUE = "1";
+    public static final String CODE_POINT_TABLE_KEY = "codePointTable";
 
     public DictionaryHeader(final int headerSize, final DictionaryOptions dictionaryOptions,
             final FormatOptions formatOptions) throws UnsupportedFormatException {
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index ec3c6e2..2661d5d 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -237,6 +237,8 @@
     static final int UINT16_MAX = 0xFFFF;
     static final int UINT24_MAX = 0xFFFFFF;
     static final int MSB8 = 0x80;
+    static final int MINIMAL_ONE_BYTE_CHARACTER_VALUE = 0x20;
+    static final int MAXIMAL_ONE_BYTE_CHARACTER_VALUE = 0xFF;
 
     /**
      * Options about file format.
diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java
index a171fc3..83adb1c 100644
--- a/java/src/com/android/inputmethod/latin/settings/Settings.java
+++ b/java/src/com/android/inputmethod/latin/settings/Settings.java
@@ -32,6 +32,7 @@
 import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
 import com.android.inputmethod.latin.utils.ResourceUtils;
 import com.android.inputmethod.latin.utils.RunInLocale;
+import com.android.inputmethod.latin.utils.StatsUtils;
 import com.android.inputmethod.latin.utils.StringUtils;
 
 import java.util.Collections;
@@ -169,6 +170,7 @@
                 return;
             }
             loadSettings(mContext, mSettingsValues.mLocale, mSettingsValues.mInputAttributes);
+            StatsUtils.onLoadSettings(mSettingsValues);
         } finally {
             mSettingsValuesLock.unlock();
         }
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
index 1e8df89..839fce0 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
@@ -365,17 +365,21 @@
                     (PunctuationSuggestions)suggestedWords, stripView);
         }
 
+        final boolean shouldShowUiToAcceptTypedWord = Settings.getInstance().getCurrent()
+                .mShouldShowUiToAcceptTypedWord;
+        final int suggestionsCount = suggestedWords.size()
+                - (shouldShowUiToAcceptTypedWord ? /* typed word */ 1 : 0);
         final int startIndexOfMoreSuggestions = setupWordViewsAndReturnStartIndexOfMoreSuggestions(
                 suggestedWords, mSuggestionsCountInStrip);
         final TextView centerWordView = mWordViews.get(mCenterPositionInStrip);
         final int stripWidth = stripView.getWidth();
         final int centerWidth = getSuggestionWidth(mCenterPositionInStrip, stripWidth);
-        if (suggestedWords.size() == 1 || getTextScaleX(centerWordView.getText(), centerWidth,
+        if (suggestionsCount == 1 || getTextScaleX(centerWordView.getText(), centerWidth,
                 centerWordView.getPaint()) < MIN_TEXT_XSCALE) {
             // Layout only the most relevant suggested word at the center of the suggestion strip
             // by consolidating all slots in the strip.
             final int countInStrip = 1;
-            mMoreSuggestionsAvailable = (suggestedWords.size() > countInStrip);
+            mMoreSuggestionsAvailable = (suggestionsCount > countInStrip);
             layoutWord(mCenterPositionInStrip, stripWidth - mPadding);
             stripView.addView(centerWordView);
             setLayoutWeight(centerWordView, 1.0f, ViewGroup.LayoutParams.MATCH_PARENT);
@@ -387,7 +391,7 @@
         }
 
         final int countInStrip = mSuggestionsCountInStrip;
-        mMoreSuggestionsAvailable = (suggestedWords.size() > countInStrip);
+        mMoreSuggestionsAvailable = (suggestionsCount > countInStrip);
         int x = 0;
         for (int positionInStrip = 0; positionInStrip < countInStrip; positionInStrip++) {
             if (positionInStrip != 0) {
diff --git a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetSubtypesCountTests.java b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetSubtypesCountTests.java
index 25bac9d..6daf071 100644
--- a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetSubtypesCountTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetSubtypesCountTests.java
@@ -25,7 +25,7 @@
 
 @SmallTest
 public class KeyboardLayoutSetSubtypesCountTests extends KeyboardLayoutSetTestsBase {
-    private static final int NUMBER_OF_SUBTYPES = 81;
+    private static final int NUMBER_OF_SUBTYPES = 82;
     private static final int NUMBER_OF_ASCII_CAPABLE_SUBTYPES = 49;
     private static final int NUMBER_OF_PREDEFINED_ADDITIONAL_SUBTYPES = 2;
 
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Bengali.java b/tests/src/com/android/inputmethod/keyboard/layout/Bengali.java
index 2101ddf..24852a0 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/Bengali.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Bengali.java
@@ -18,9 +18,6 @@
 
 import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
 import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
-import com.android.inputmethod.latin.Constants;
-
-import java.util.Locale;
 
 /**
  * The Bengali keyboard.
@@ -35,32 +32,6 @@
     @Override
     public String getName() { return LAYOUT_NAME; }
 
-    public static class BengaliCustomizer extends LayoutCustomizer {
-        public BengaliCustomizer(final Locale locale) { super(locale); }
-
-        @Override
-        public ExpectedKey getAlphabetKey() { return BENGALI_ALPHABET_KEY; }
-
-        @Override
-        public ExpectedKey[] getOtherCurrencyKeys() {
-            return SymbolsShifted.CURRENCIES_OTHER_GENERIC;
-        }
-
-        @Override
-        public ExpectedKey[] getLeftShiftKeys(final boolean isPhone) { return EMPTY_KEYS; }
-
-        @Override
-        public ExpectedKey[] getRightShiftKeys(final boolean isPhone) {
-            return isPhone ? EMPTY_KEYS : EXCLAMATION_AND_QUESTION_MARKS;
-        }
-
-        // U+0995: "क" BENGALI LETTER KA
-        // U+0996: "ख" BENGALI LETTER KHA
-        // U+0997: "ग" BENGALI LETTER GA
-        private static final ExpectedKey BENGALI_ALPHABET_KEY = key(
-                "\u0995\u0996\u0997", Constants.CODE_SWITCH_ALPHA_SYMBOL);
-    }
-
     @Override
     ExpectedKey[][] getCommonAlphabetLayout(boolean isPhone) { return ALPHABET_COMMON; }
 
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/BengaliAkkhor.java b/tests/src/com/android/inputmethod/keyboard/layout/BengaliAkkhor.java
new file mode 100644
index 0000000..4dc16cf
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/BengaliAkkhor.java
@@ -0,0 +1,496 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.keyboard.layout;
+
+import com.android.inputmethod.keyboard.KeyboardId;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+
+/**
+ * The Bengali Akkhor keyboard.
+ */
+public final class BengaliAkkhor extends LayoutBase {
+    private static final String LAYOUT_NAME = "bengali_akkhor";
+
+    public BengaliAkkhor(final LayoutCustomizer customizer) {
+        super(customizer, Symbols.class, SymbolsShifted.class);
+    }
+
+    @Override
+    public String getName() { return LAYOUT_NAME; }
+
+    @Override
+    ExpectedKey[][] getCommonAlphabetLayout(boolean isPhone) { return ALPHABET_COMMON; }
+
+    @Override
+    ExpectedKey[][] getCommonAlphabetShiftLayout(boolean isPhone, final int elementId) {
+        if (elementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED) {
+            return getCommonAlphabetLayout(isPhone);
+        }
+        return ALPHABET_SHIFTED_COMMON;
+    }
+
+    private static final ExpectedKey[][] ALPHABET_COMMON = new ExpectedKeyboardBuilder()
+            .setKeysOfRow(1,
+                    // U+09A7: "ধ" BENGALI LETTER DHA
+                    // U+09E7: "১" BENGALI DIGIT ONE
+                    // U+09A7/U+09CD/U+09AC:
+                    //     "ধ্ব্র" BENGALI LETTER DHA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                    // U+09A7/U+09CD/U+09AF:
+                    //     "ধ্য্র" BENGALI LETTER DHA/BENGALI SIGN VIRAMA/BENGALI LETTER YA
+                    // U+09A7/U+09CD/U+09B0:
+                    //     "ধ্র" BENGALI LETTER DHA/BENGALI SIGN VIRAMA/BENGALI LETTER RA
+                    key("\u09A7", joinMoreKeys("\u09E7", "\u09A7\u09CD\u09AC", "\u09A7\u09CD\u09AF",
+                            "\u09A7\u09CD\u09B0")),
+                    // U+09A5: "থ" BENGALI LETTER THA
+                    // U+09E8: "২" BENGALI DIGIT TWO
+                    // U+09A5/U+09CD/U+09AF:
+                    //     "থ্য" BENGALI LETTER THA/BENGALI SIGN VIRAMA/BENGALI LETTER YA
+                    // U+09A5/U+09CD/U+09B0:
+                    //     "থ্র" BENGALI LETTER THA/BENGALI SIGN VIRAMA/BENGALI LETTER RA
+                    key("\u09A5", joinMoreKeys("\u09E8", "\u09A5\u09CD\u09AF",
+                            "\u09A5\u09CD\u09B0")),
+                    // U+09C7: "ে" BENGALI VOWEL SIGN E
+                    // U+09E9: "৩" BENGALI DIGIT THREE
+                    // U+098F: "এ" BENGALI LETTER E
+                    key("\u09C7", joinMoreKeys("\u09E9", "\u098F")),
+                    // U+09B0: "র" BENGALI LETTER RA
+                    // U+09EA: "৪" BENGALI DIGIT FOUR
+                    key("\u09B0", joinMoreKeys("\u09EA")),
+                    // U+09A4: "ত" BENGALI LETTER TA
+                    // U+09EB: "৫" BENGALI DIGIT FIVE
+                    // U+09CE: "ৎ" BENGALI LETTER KHANDA TA
+                    // U+09A4/U+09CD/U+09A4:
+                    //     "ত্ত" BENGALI LETTER TA/BENGALI SIGN VIRAMA/BENGALI LETTER TA
+                    // U+09A4/U+09CD/U+09A8:
+                    //     "ত্ন" BENGALI LETTER TA/BENGALI SIGN VIRAMA/BENGALI LETTER NA
+                    // U+09A4/U+09CD/U+09AC:
+                    //     "ত্ব" BENGALI LETTER TA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                    // U+09A4/U+09CD/U+09AE:
+                    //     "ত্ম" BENGALI LETTER TA/BENGALI SIGN VIRAMA/BENGALI LETTER MA
+                    key("\u09A4", joinMoreKeys("\u09EB", "\u09CE", "\u09A4\u09CD\u09A4",
+                            "\u09A4\u09CD\u09A8", "\u09A4\u09CD\u09AC", "\u09A4\u09CD\u09AE")),
+                    // U+09DF: "য়" BENGALI LETTER YYA
+                    // U+09EC: "৬" BENGALI DIGIT SIX
+                    key("\u09DF", joinMoreKeys("\u09EC")),
+                    // U+09C1: "ু" BENGALI VOWEL SIGN U
+                    // U+09ED: "৭" BENGALI DIGIT SEVEN
+                    // U+0989: "উ" BENGALI LETTER U
+                    key("\u09C1", joinMoreKeys("\u09ED", "\u0989")),
+                    // U+09BF: "ি" BENGALI VOWEL SIGN I
+                    // U+09EE: "৮" BENGALI DIGIT EIGHT
+                    // U+0987: "ই BENGALI LETTER I
+                    key("\u09Bf", joinMoreKeys("\u09EE", "\u0987")),
+                    // U+09CB: "ো" BENGALI VOWEL SIGN O
+                    // U+09EF: "৯" BENGALI DIGIT NINE
+                    // U+0993: "ও" BENGALI LETTER O
+                    key("\u09CB", joinMoreKeys("\u09EF", "\u0993")),
+                    // U+09AA: "প" BENGALI LETTER PA
+                    // U+09E6: "০" BENGALI DIGIT ZERO
+                    // U+09AA/U+09CD/U+09A4:
+                    //     "প্ত" BENGALI LETTER PA/BENGALI SIGN VIRAMA/BENGALI LETTER TA
+                    // U+09AA/U+09CD/U+09A8:
+                    //     "প্ন" BENGALI LETTER PA/BENGALI SIGN VIRAMA/BENGALI LETTER NA
+                    // U+09AA/U+09CD/U+09AA:
+                    //     "প্প" BENGALI LETTER PA/BENGALI SIGN VIRAMA/BENGALI LETTER PA
+                    // U+09AA/U+09CD/U+09AF:
+                    //     "প্য" BENGALI LETTER PA/BENGALI SIGN VIRAMA/BENGALI LETTER YA
+                    // U+09AA/U+09CD/U+09B0:
+                    //     "প্র" BENGALI LETTER PA/BENGALI SIGN VIRAMA/BENGALI LETTER RA
+                    // U+09AA/U+09CD/U+09B2:
+                    //     "প্ল" BENGALI LETTER PA/BENGALI SIGN VIRAMA/BENGALI LETTER LA
+                    // U+09AA/U+09CD/U+09B8:
+                    //     "প্স" BENGALI LETTER PA/BENGALI SIGN VIRAMA/BENGALI LETTER SA
+                    key("\u09AA", joinMoreKeys("\u09E6", "\u09AA\u09CD\u09A4", "\u09AA\u09CD\u09A8",
+                            "\u09AA\u09CD\u09AA", "\u09AA\u09CD\u09AF", "\u09AA\u09CD\u09B0",
+                            "\u09AA\u09CD\u09B2", "\u09AA\u09CD\u09B8")),
+                    // U+0986: "আ" BENGALI LETTER AA
+                    key("\u0986"))
+            .setKeysOfRow(2,
+                    // U+09BE: "া BENGALI VOWEL SIGN AA
+                    // U+0986: "আ" BENGALI LETTER AA
+                    key("\u09BE", moreKey("\u0986")),
+                    // U+09B8: "স" BENGALI LETTER SA
+                    // U+09B8/U+09CD/U+09AC:
+                    //     "স্ব" BENGALI LETTER SA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                    // U+09B8/U+09CD/U+09A4:
+                    //     "স্ত" BENGALI LETTER SA/BENGALI SIGN VIRAMA/BENGALI LETTER TA
+                    // U+09B8/U+09CD/U+099F:
+                    //     "স্ট" BENGALI LETTER SA/BENGALI SIGN VIRAMA/BENGALI LETTER TTA
+                    // U+09B8/U+09CD/U+0995:
+                    //     "স্ক" BENGALI LETTER SA/BENGALI SIGN VIRAMA/BENGALI LETTER KA
+                    // U+09B8/U+09CD/U+09AA:
+                    //     "স্প" BENGALI LETTER SA/BENGALI SIGN VIRAMA/BENGALI LETTER PA
+                    key("\u09B8", joinMoreKeys("\u09B8\u09CD\u09AC", "\u09B8\u09CD\u09A4",
+                            "\u09B8\u09CD\u099F", "\u09B8\u09CD\u0995", "\u09B8\u09CD\u09AA")),
+                    // U+09A6: "দ" BENGALI LETTER DA
+                    // U+09A6/U+09CD/U+09A6:
+                    //     "দ্দ" BENGALI LETTER DA/BENGALI SIGN VIRAMA/BENGALI LETTER DA
+                    // U+09A6/U+09CD/U+09A7:
+                    //     "দ্ধ" BENGALI LETTER DA/BENGALI SIGN VIRAMA/BENGALI LETTER DHA
+                    // U+09A6/U+09CD/U+09AC:
+                    //     "দ্ব" BENGALI LETTER DA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                    // U+09A6/U+09CD/U+09AD:
+                    //     "দ্ভ" BENGALI LETTER DA/BENGALI SIGN VIRAMA/BENGALI LETTER BHA
+                    // U+09A6/U+09CD/U+09AE:
+                    //     "দ্ম" BENGALI LETTER DA/BENGALI SIGN VIRAMA/BENGALI LETTER MA
+                    // U+09A6/U+09CD/U+09AF:
+                    //     "দ্য" BENGALI LETTER DA/BENGALI SIGN VIRAMA/BENGALI LETTER YA
+                    // U+09A6/U+09CD/U+09B0:
+                    //     "দ্র" BENGALI LETTER DA/BENGALI SIGN VIRAMA/BENGALI LETTER RA
+                    key("\u09A6", joinMoreKeys("\u09A6\u09CD\u09A6", "\u09A6\u09CD\u09A7",
+                            "\u09A6\u09CD\u09AC", "\u09A6\u09CD\u09AD", "\u09A6\u09CD\u09AE",
+                            "\u09A6\u09CD\u09AF", "\u09A6\u09CD\u09B0")),
+                    // U+09C3: "ৃ" BENGALI VOWEL SIGN VOCALIC R
+                    // U+098B: "ঋ" BENGALI LETTER VOCALIC R
+                    key("\u09C3", moreKey("\u098B")),
+                    // U+0997: "গ" BENGALI LETTER GA
+                    // U+0997/U+09CD/U+09A7:
+                    //     "গ্ধ" BENGALI LETTER GA/BENGALI SIGN VIRAMA/BENGALI LETTER DH A
+                    // U+0997/U+09CD/U+09B0:
+                    //     "গ্র" BENGALI LETTER GA/BENGALI SIGN VIRAMA/BENGALI LETTER RA
+                    // U+0997/U+09CD/U+09B2:
+                    //     "গ্ল" BENGALI LETTER GA/BENGALI SIGN VIRAMA/BENGALI LETTER LA
+                    // U+0997/U+09CD/U+09A8:
+                    //     "গ্ন" BENGALI LETTER GA/BENGALI SIGN VIRAMA/BENGALI LETTER NA
+                    key("\u0997", joinMoreKeys("\u0997\u09CD\u09A7", "\u0997\u09CD\u09B0",
+                            "\u0997\u09CD\u09B2", "\u0997\u09CD\u09A8")),
+                    // U+09CD: "্" BENGALI SIGN VIRAMA
+                    key("\u09CD"),
+                    // U+099C: "জ" BENGALI LETTER JA
+                    // U+099C/U+09CD/U+099E:
+                    //     "জ্ঞ" BENGALI LETTER JA/BENGALI SIGN VIRAMA/BENGALI LETTER NYA
+                    // U+099C/U+09CD/U+099C:
+                    //     "জ্জ" BENGALI LETTER JA/BENGALI SIGN VIRAMA/BENGALI LETTER JA
+                    // U+099C/U+09CD/U+09AF:
+                    //     "জ্ব" BENGALI LETTER JA/BENGALI SIGN VIRAMA/BENGALI LETTER YA
+                    // U+099C/U+09CD/U+09AC:
+                    //     "জ্য" BENGALI LETTER JA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                    // U+099C/U+09CD/U+09B0:
+                    //     "জ্র" BENGALI LETTER JA/BENGALI SIGN VIRAMA/BENGALI LETTER RA
+                    key("\u099C", joinMoreKeys("\u099C\u09CD\u099E", "\u099C\u09CD\u099C",
+                            "\u099C\u09CD\u09AF", "\u099C\u09CD\u09AC", "\u099C\u09CD\u09B0")),
+                    // U+0995: "ক" BENGALI LETTER KA
+                    // U+0995/U+09CD/U+09B7:
+                    //     "ক্ষ" BENGALI LETTER KA/BENGALI SIGN VIRAMA/BENGALI LETTER SSA
+                    // U+0995/U+09CD/U+0995:
+                    //     "ক্ক" BENGALI LETTER KA/BENGALI SIGN VIRAMA/BENGALI LETTER KA
+                    // U+0995/U+09CD/U+099F:
+                    //     "ক্ট" BENGALI LETTER KA/BENGALI SIGN VIRAMA/BENGALI LETTER TTA
+                    // U+0995/U+09CD/U+09A4:
+                    //     "ক্ত" BENGALI LETTER KA/BENGALI SIGN VIRAMA/BENGALI LETTER TA
+                    // U+0995/U+09CD/U+09B0:
+                    //     "ক্র" BENGALI LETTER KA/BENGALI SIGN VIRAMA/BENGALI LETTER RA
+                    // U+0995/U+09CD/U+09B8:
+                    //     "ক্স" BENGALI LETTER KA/BENGALI SIGN VIRAMA/BENGALI LETTER SA
+                    // U+0995/U+09CD/U+09B2:
+                    //     "ক্ল" BENGALI LETTER KA/BENGALI SIGN VIRAMA/BENGALI LETTER LA
+                    key("\u0995", joinMoreKeys("\u0995\u09CD\u09B7", "\u0995\u09CD\u0995",
+                            "\u0995\u09CD\u099F", "\u0995\u09CD\u09A4", "\u0995\u09CD\u09B0",
+                            "\u0995\u09CD\u09B8", "\u0995\u09CD\u09B2")),
+                    // U+09B2: "ল" BENGALI LETTER LA
+                    // U+09B2/U+09CD/U+0995:
+                    //     "ল্ক" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER KA
+                    // U+09B2/U+09CD/U+0997:
+                    //     "ল্গ" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER GA
+                    // U+09B2/U+09CD/U+099F:
+                    //     "ল্ট" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER TTA
+                    // U+09B2/U+09CD/U+09A1:
+                    //     "ল্ড" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER DDA
+                    // U+09B2/U+09CD/U+09A4:
+                    //     "ল্ত" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER TA
+                    // U+09B2/U+09CD/U+09A6:
+                    //     "ল্দ" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER DA
+                    // U+09B2/U+09CD/U+09A7:
+                    //     "ল্ধ" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER DHA
+                    // U+09B2/U+09CD/U+09AA:
+                    //     "ল্প" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER PA
+                    // U+09B2/U+09CD/U+09AB:
+                    //     "ল্ফ" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER PHA
+                    // U+09B2/U+09CD/U+09AC:
+                    //     "ল্ব" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                    // U+09B2/U+09CD/U+09AE:
+                    //     "ল্ম" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER MA
+                    // U+09B2/U+09CD/U+09B2:
+                    //     "ল্ল" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER LA
+                    key("\u09B2", joinMoreKeys("\u09B2\u09CD\u0995", "\u09B2\u09CD\u0997",
+                            "\u09B2\u09CD\u099F", "\u09B2\u09CD\u09A1", "\u09B2\u09CD\u09A4",
+                            "\u09B2\u09CD\u09A6", "\u09B2\u09CD\u09A7", "\u09B2\u09CD\u09AA",
+                            "\u09B2\u09CD\u09AB", "\u09B2\u09CD\u09AC", "\u09B2\u09CD\u09AE",
+                            "\u09B2\u09CD\u09B2")),
+                    // U+0987: "ই" BENGALI LETTER I
+                    key("\u0987"),
+                    // U+0989: "উ" BENGALI LETTER U
+                    key("\u0989"))
+            .setKeysOfRow(3,
+                    // U+09AF: "য" BENGALI LETTER YA
+                    // U+09CD/U+09AF: "্য" BENGALI SIGN VIRAMA/BENGALI LETTER YA
+                    key("\u09AF", moreKey("\u09CD\u09AF")),
+                    // U+09B7: "ষ" BENGALI LETTER SSA
+                    // U+09B7/U+09CD/U+0995:
+                    //     "ষ্ক" BENGALI LETTER SSA/BENGALI SIGN VIRAMA/BENGALI LETTER KA
+                    // U+09B7/U+09CD/U+099F:
+                    //     "ষ্ট" BENGALI LETTER SSA/BENGALI SIGN VIRAMA/BENGALI LETTER TTA
+                    // U+09B7/U+09CD/U+09A0:
+                    //     "ষ্ঠ" BENGALI LETTER SSA/BENGALI SIGN VIRAMA/BENGALI LETTER TTHA
+                    // U+09B7/U+09CD/U+09A3:
+                    //     "ষ্ণ" BENGALI LETTER SSA/BENGALI SIGN VIRAMA/BENGALI LETTER NNA
+                    // U+09B7/U+09CD/U+09AA:
+                    //     "ষ্প" BENGALI LETTER SSA/BENGALI SIGN VIRAMA/BENGALI LETTER PA
+                    // U+09B7/U+09CD/U+09AB:
+                    //     "ষ্ফ" BENGALI LETTER SSA/BENGALI SIGN VIRAMA/BENGALI LETTER PHA
+                    // U+09B7/U+09CD/U+09AE:
+                    //     "ষ্ম" BENGALI LETTER SSA/BENGALI SIGN VIRAMA/BENGALI LETTER MA
+                    key("\u09B7", joinMoreKeys("\u09B7\u09CD\u0995", "\u09B7\u09CD\u099F",
+                            "\u09B7\u09CD\u09A0", "\u09B7\u09CD\u09A3", "\u09B7\u09CD\u09AA",
+                            "\u09B7\u09CD\u09AB", "\u09B7\u09CD\u09AE")),
+                    // U+099A: "চ" BENGALI LETTER CA
+                    // U+099A/U+09CD/U+099A:
+                    //     "চ্চ" BENGALI LETTER CA/BENGALI SIGN VIRAMA/BENGALI LETTER CA
+                    // U+099A/U+09CD/U+099B:
+                    //     "চ্ছ" BENGALI LETTER CA/BENGALI SIGN VIRAMA/BENGALI LETTER CHA
+                    key("\u099A", joinMoreKeys("\u099A\u09CD\u099A", "\u099A\u09CD\u099B")),
+                    // U+09AD: "ভ" BENGALI LETTER BHA
+                    // U+09AD/U+09CD/U+09AF:
+                    //     "ভ্" BENGALI LETTER BHA/BENGALI SIGN VIRAMA/BENGALI LETTER YA
+                    // U+09AD/U+09CD/U+09B0:
+                    //     "ভ্র" BENGALI LETTER BHA/BENGALI SIGN VIRAMA/BENGALI LETTER RA
+                    // U+09AD/U+09CD/U+09B2:
+                    //     "ভ্ল" BENGALI LETTER BHA/BENGALI SIGN VIRAMA/BENGALI LETTER LA
+                    key("\u09AD", joinMoreKeys("\u09AD\u09CD\u09AF", "\u09AD\u09CD\u09B0",
+                            "\u09AD\u09CD\u09B2")),
+                    // U+09AC: "ব" BENGALI LETTER BA
+                    // U+09CD/U+09AC: "্ব" BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                    // U+09AC/U+09CD/U+09B0:
+                    //     "ব্র" BENGALI LETTER BA/BENGALI SIGN VIRAMA/BENGALI LETTER RA
+                    // U+09AC/U+09CD/U+099C:
+                    //     "ব্জ" BENGALI LETTER BA/BENGALI SIGN VIRAMA/BENGALI LETTER JA
+                    // U+09AC/U+09CD/U+09A6:
+                    //     "ব্দ" BENGALI LETTER BA/BENGALI SIGN VIRAMA/BENGALI LETTER DA
+                    // U+09AC/U+09CD/U+09A7:
+                    //     "ব্ধ" BENGALI LETTER BA/BENGALI SIGN VIRAMA/BENGALI LETTER DHA
+                    // U+09AC/U+09CD/U+09AC:
+                    //     "ব্ব" BENGALI LETTER BA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                    // U+09AC/U+09CD/U+09B2:
+                    //     "ব্ল" BENGALI LETTER BA/BENGALI SIGN VIRAMA/BENGALI LETTER LA
+                    // U+09F1: "ৱ" BENGALI LETTER RA WITH MIDDLE DIAGONAL
+                    // U+09F0: "ৰ" BENGALI LETTER RA WITH LOWER DIAGONAL
+                    key("\u09AC", joinMoreKeys("\u09CD\u09AC", "\u09AC\u09CD\u09B0",
+                            "\u09AC\u09CD\u099C", "\u09AC\u09CD\u09A6", "\u09AC\u09CD\u09A7",
+                            "\u09AC\u09CD\u09AC", "\u09AC\u09CD\u09B2", "\u09F1", "\u09F0")),
+                    // U+09A8: "ন" BENGALI LETTER NA
+                    // U+09A8/U+09CD/U+09A4:
+                    //     "ন্ত" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER TA
+                    // U+09A8/U+09CD/U+09A5:
+                    //     "ন্থ" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER THA
+                    // U+09A8/U+09CD/U+099F:
+                    //     "ন্ট" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER TTA
+                    // U+09A8/U+09CD/U+09A6:
+                    //     "ন্দ" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER DA
+                    // U+09A8/U+09CD/U+09A7:
+                    //     "ন্ধ" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER DHA
+                    // U+09A8/U+09CD/U+09A1:
+                    //     "ন্ড" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER DDA
+                    // U+09A8/U+09CD/U+09A8:
+                    //     "ন্ন" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER NA
+                    // U+09A8/U+09CD/U+09AC:
+                    //     "ন্ব" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                    // U+09A8/U+09CD/U+09AE:
+                    //     "ন্ম" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER MA
+                    // U+09A8/U+09CD/U+09B8:
+                    //     "ন্স" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER SA
+                    key("\u09A8", joinMoreKeys("\u09A8\u09CD\u09A4", "\u09A8\u09CD\u09A5",
+                            "\u09A8\u09CD\u099F", "\u09A8\u09CD\u09A6", "\u09A8\u09CD\u09A7",
+                            "\u09A8\u09CD\u09A1", "\u09A8\u09CD\u09A8", "\u09A8\u09CD\u09AC",
+                            "\u09A8\u09CD\u09AE", "\u09A8\u09CD\u09B8")),
+                    // U+09AE: "ম" BENGALI LETTER MA
+                    // U+09AE/U+09CD/U+09A8:
+                    //     "ম্ন" BENGALI LETTER MA/BENGALI SIGN VIRAMA/BENGALI LETTER NA
+                    // U+09AE/U+09CD/U+09AA:
+                    //     "ম্প" BENGALI LETTER MA/BENGALI SIGN VIRAMA/BENGALI LETTER PA
+                    // U+09AE/U+09CD/U+09AC:
+                    //     "ম্ব" BENGALI LETTER MA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                    // U+09AE/U+09CD/U+09AD:
+                    //     "ম্ভ" BENGALI LETTER MA/BENGALI SIGN VIRAMA/BENGALI LETTER BHA
+                    // U+09AE/U+09CD/U+09AE:
+                    //     "ম্ম" BENGALI LETTER MA/BENGALI SIGN VIRAMA/BENGALI LETTER MA
+                    // U+09AE/U+09CD/U+09B0:
+                    //     "ম্র" BENGALI LETTER MA/BENGALI SIGN VIRAMA/BENGALI LETTER RA
+                    // U+09AE/U+09CD/U+09B2:
+                    //     "ম্ল" BENGALI LETTER MA/BENGALI SIGN VIRAMA/BENGALI LETTER LA
+                    key("\u09AE", joinMoreKeys("\u09AE\u09CD\u09A8", "\u09AE\u09CD\u09AA",
+                            "\u09AE\u09CD\u09AC", "\u09AE\u09CD\u09AD", "\u09AE\u09CD\u09AE",
+                            "\u09AE\u09CD\u09B0", "\u09AE\u09CD\u09B2")),
+                    // U+098F: "এ" BENGALI LETTER E
+                    key("\u098F"),
+                    // U+0993: "ও" BENGALI LETTER O
+                    key("\u0993"))
+            .build();
+
+    private static final ExpectedKey[][] ALPHABET_SHIFTED_COMMON = new ExpectedKeyboardBuilder()
+            .setKeysOfRow(1,
+                    // U+09A2: "ঢ" BENGALI LETTER DDHA
+                    key("\u09A2"),
+                    // U+09A0: "ঠ" BENGALI LETTER TTHA
+                    key("\u09A0"),
+                    // U+09C8: "ৈ" BENGALI VOWEL SIGN AI
+                    // U+0990: "ঐ" BENGALI LETTER AI
+                    key("\u09C8", moreKey("\u0990")),
+                    // U+09DC: "ড়" BENGALI LETTER RRA
+                    // U+09BC: "়" BENGALI SIGN NUKTA
+                    key("\u09DC", moreKey("\u09BC")),
+                    // U+099F: "ট" BENGALI LETTER TTA
+                    // U+09F3: "৳" BENGALI RUPEE SIGN
+                    // U+099F/U+09CD/U+099F:
+                    //     "ট্ট" BENGALI LETTER TTA/BENGALI SIGN VIRAMA/BENGALI LETTER TTA
+                    // U+099F/U+09CD/U+09AC:
+                    //     "ট্ব" BENGALI LETTER TTA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                    // U+099F/U+09CD/U+09AE:
+                    //     "ট্ম" BENGALI LETTER TTA/BENGALI SIGN VIRAMA/BENGALI LETTER MA
+                    key("\u099F", joinMoreKeys("\u09F3", "\u099F\u09CD\u099F", "\u099F\u09CD\u09AC",
+                            "\u099F\u09CD\u09AE")),
+                    // U+099E: "ঞ" BENGALI LETTER NYA
+                    // U+099E/U+09CD/U+099A:
+                    //     "ঞ্চ" BENGALI LETTER NYA/BENGALI SIGN VIRAMA/BENGALI LETTER CA
+                    // U+099E/U+09CD/U+099B:
+                    //     "ঞ্ছ" BENGALI LETTER NYA/BENGALI SIGN VIRAMA/BENGALI LETTER CHA
+                    // U+099E/U+09CD/U+099C:
+                    //     "ঞ্জ" BENGALI LETTER NYA/BENGALI SIGN VIRAMA/BENGALI LETTER JA
+                    key("\u099E", joinMoreKeys("\u099E\u09CD\u099A", "\u099E\u09CD\u099B",
+                            "\u099E\u09CD\u099C")),
+                    // U+09C2: "ূ" BENGALI VOWEL SIGN UU
+                    // U+098A: "ঊ" BENGALI LETTER UU
+                    key("\u09C2", moreKey("\u098A")),
+                    // U+09C0: "ী" BENGALI VOWEL SIGN II
+                    // U+0988: "ঈ" BENGALI LETTER II
+                    key("\u09C0", moreKey("\u0988")),
+                    // U+09CC: "ৌ" BENGALI VOWEL SIGN AU
+                    // U+099A: "ঔ" BENGALI LETTER CA
+                    // U+09D7: "ৗ" BENGALI AU LENGTH MARK
+                    key("\u09CC", joinMoreKeys("\u099A", "\u09D7")),
+                    // U+09AB: "ফ" BENGALI LETTER PHA
+                    // U+09AB/U+09CD/U+099F:
+                    //     "ফ্ট" BENGALI LETTER PHA/BENGALI SIGN VIRAMA/BENGALI LETTER TTA
+                    // U+09AB/U+09CD/U+09AF:
+                    //     "ফ্য" BENGALI LETTER PHA/BENGALI SIGN VIRAMA/BENGALI LETTER YA
+                    // U+09AB/U+09CD/U+09B0:
+                    //     "ফ্র" BENGALI LETTER PHA/BENGALI SIGN VIRAMA/BENGALI LETTER RA
+                    // U+09AB/U+09CD/U+09B2:
+                    //     "ফ্ল" BENGALI LETTER PHA/BENGALI SIGN VIRAMA/BENGALI LETTER LA
+                    key("\u09AB", joinMoreKeys("\u09AB\u09CD\u099F", "\u09AB\u09CD\u09AF",
+                            "\u09AB\u09CD\u09B0", "\u09AB\u09CD\u09B2")),
+                    // U+098B: "ঋ" BENGALI LETTER VOCALIC R
+                    // U+098C: "ঌ" BENGALI LETTER VOCALIC L
+                    // U+09E1: "ৡ" BENGALI LETTER VOCALIC LL
+                    // U+09F4: "৴" BENGALI CURRENCY NUMERATOR ONE
+                    // U+09F5: "৵" BENGALI CURRENCY NUMERATOR TWO
+                    // U+09F6: "৶" BENGALI CURRENCY NUMERATOR THREE
+                    // U+09E2: " ৢ" BENGALI VOWEL SIGN VOCALIC L
+                    // U+09E3: " ৣ" BENGALI VOWEL SIGN VOCALIC LL
+                    key("\u098B", joinMoreKeys("\u098C", "\u09E1", "\u09F4", "\u09F5", "\u09F6",
+                            "\u09E2", "\u09E3")))
+            .setKeysOfRow(2,
+                    // U+0985: "অ" BENGALI LETTER A
+                    key("\u0985"),
+                    // U+09B6: "শ" BENGALI LETTER SHA
+                    // U+09B6/U+09CD/U+099A:
+                    //     "শ্চ" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER CA
+                    // U+09B6/U+09CD/U+099B:
+                    //     "শ্ছ" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER CHA
+                    // U+09B6/U+09CD/U+09A4:
+                    //     "শ্ত" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER TA
+                    // U+09B6/U+09CD/U+09A8:
+                    //     "শ্ন" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER NA
+                    // U+09B6/U+09CD/U+09AC:
+                    //     "শ্ব" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                    // U+09B6/U+09CD/U+09AE:
+                    //     "শ্ম" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER MA
+                    // U+09B6/U+09CD/U+09B0:
+                    //     "শ্র" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER RA
+                    // U+09B6/U+09CD/U+09B2:
+                    //     "শ্ল" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER LA
+                    key("\u09B6", joinMoreKeys("\u09B6\u09CD\u099A", "\u09B6\u09CD\u099B",
+                            "\u09B6\u09CD\u09A4", "\u09B6\u09CD\u09A8", "\u09B6\u09CD\u09AC",
+                            "\u09B6\u09CD\u09AE", "\u09B6\u09CD\u09B0", "\u09B6\u09CD\u09B2")),
+                    // U+09A1: "ড" BENGALI LETTER DDA
+                    // U+09A1/U+09CD/U+09A1:
+                    //     "ড্ড" BENGALI LETTER DDA/BENGALI SIGN VIRAMA/BENGALI LETTER DDA
+                    key("\u09A1", moreKey("\u09A1\u09CD\u09A1")),
+                    // U+09DD: "ঢ়" BENGALI LETTER RHA
+                    key("\u09DD"),
+                    // U+0998: "ঘ" BENGALI LETTER GHA
+                    key("\u0998"),
+                    // U+09B9: "হ" BENGALI LETTER HA
+                    // U+09BD: "ঽ" BENGALI SIGN AVAGRAHA
+                    // U+09B9/U+09CD/U+09A3:
+                    //     "হ্ণ" BENGALI LETTER HA/BENGALI SIGN VIRAMA/BENGALI LETTER NNA
+                    // U+09B9/U+09CD/U+09A8:
+                    //     "হ্ন" BENGALI LETTER HA/BENGALI SIGN VIRAMA/BENGALI LETTER NA
+                    // U+09B9/U+09CD/U+09AC:
+                    //     "হ্ব" BENGALI LETTER HA/BENGALI SIGN VIRAMA/BENGALI LETTER BA
+                    // U+09B9/U+09CD/U+09AE:
+                    //     "হ্ম" BENGALI LETTER HA/BENGALI SIGN VIRAMA/BENGALI LETTER MA
+                    // U+09B9/U+09CD/U+09B0:
+                    //     "হ্র" BENGALI LETTER HA/BENGALI SIGN VIRAMA/BENGALI LETTER RA
+                    // U+09B9/U+09CD/U+09B2:
+                    //     "হ্ল" BENGALI LETTER HA/BENGALI SIGN VIRAMA/BENGALI LETTER LA
+                    key("\u09B9", joinMoreKeys("\u09BD", "\u09B9\u09CD\u09A3", "\u09B9\u09CD\u09A8",
+                            "\u09B9\u09CD\u09AC", "\u09B9\u09CD\u09AE", "\u09B9\u09CD\u09B0",
+                            "\u09B9\u09CD\u09B2")),
+                    // U+099D: "ঝ" BENGALI LETTER JHA
+                    key("\u099D"),
+                    // U+0996: "খ" BENGALI LETTER KHA
+                    key("\u0996"),
+                    // U+09CE: "ৎ" BENGALI LETTER KHANDA TA
+                    key("\u09CE"),
+                    // U+0988: "ঈ" BENGALI LETTER II
+                    key("\u0988"),
+                    // U+098A: "ঊ" BENGALI LETTER UU
+                    key("\u098A"))
+            .setKeysOfRow(3,
+                    // U+0964: "।" DEVANAGARI DANDA
+                    // U+0965: "॥" DEVANAGARI DOUBLE DANDA
+                    key("\u0964", moreKey("\u0965")),
+                    // U+0999: "ঙ BENGALI LETTER NGA
+                    // U+0999/U+09CD/U+0995: "ঙ্ক"
+                    // U+0999/U+09CD/U+0996: "ঙ্খ"
+                    // U+0999/U+09CD/U+0997: "ঙ্গ"
+                    key("\u0999", joinMoreKeys("\u0999\u09CD\u0995", "\u0999\u09CD\u0996",
+                            "\u0999\u09CD\u0997")),
+                    // U+099B: "ছ" BENGALI LETTER CHA
+                    key("\u099B"),
+                    // U+0983: "ঃ" BENGALI SIGN VISARGA
+                    key("\u0983"),
+                    // U+0981: "ঁ" BENGALI SIGN CANDRABINDU
+                    key("\u0981"),
+                    // U+09A3: "ণ" BENGALI LETTER NNA
+                    // U+09A3/U+09CD/U+099F:
+                    //     "ণ্ট" BENGALI LETTER NNA/BENGALI SIGN VIRAMA/BENGALI LETTER TT/A
+                    // U+09A3/U+09CD/U+09A1:
+                    //     "ণ্ড" BENGALI LETTER NNA/BENGALI SIGN VIRAMA/BENGALI LETTER DDA
+                    // U+09A3/U+09CD/U+09A3:
+                    //     "ণ্ণ" BENGALI LETTER NNA/BENGALI SIGN VIRAMA/BENGALI LETTER NN
+                    key("\u09A3", joinMoreKeys("\u09A3\u09CD\u099F", "\u09A3\u09CD\u09A1",
+                            "\u09A3\u09CD\u09A3")),
+                    // U+0982: "ং" BENGALI SIGN ANUSVARA
+                    key("\u0982"),
+                    // U+0990: "ঐ" BENGALI LETTER AI
+                    key("\u0990"),
+                    // U+0994: "ঔ" BENGALI LETTER AU
+                    key("\u0994"))
+            .build();
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/BengaliCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/BengaliCustomizer.java
new file mode 100644
index 0000000..7964b64
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/BengaliCustomizer.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.keyboard.layout.tests;
+
+import com.android.inputmethod.keyboard.layout.LayoutBase;
+import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer;
+import com.android.inputmethod.keyboard.layout.SymbolsShifted;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
+import com.android.inputmethod.latin.Constants;
+
+import java.util.Locale;
+
+public class BengaliCustomizer extends LayoutCustomizer {
+    public BengaliCustomizer(final Locale locale) { super(locale); }
+
+    @Override
+    public ExpectedKey getAlphabetKey() { return BENGALI_ALPHABET_KEY; }
+
+    @Override
+    public ExpectedKey[] getOtherCurrencyKeys() {
+        return SymbolsShifted.CURRENCIES_OTHER_GENERIC;
+    }
+
+    @Override
+    public ExpectedKey[] getRightShiftKeys(final boolean isPhone) {
+        return isPhone ? EMPTY_KEYS : LayoutBase.EXCLAMATION_AND_QUESTION_MARKS;
+    }
+
+    // U+0995: "क" BENGALI LETTER KA
+    // U+0996: "ख" BENGALI LETTER KHA
+    // U+0997: "ग" BENGALI LETTER GA
+    private static final ExpectedKey BENGALI_ALPHABET_KEY = LayoutBase.key(
+            "\u0995\u0996\u0997", Constants.CODE_SWITCH_ALPHA_SYMBOL);
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBengaliBD.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBengaliBD.java
new file mode 100644
index 0000000..0334d5d
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBengaliBD.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.keyboard.layout.tests;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.inputmethod.keyboard.layout.BengaliAkkhor;
+import com.android.inputmethod.keyboard.layout.LayoutBase;
+import com.android.inputmethod.keyboard.layout.Symbols;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
+
+import java.util.Locale;
+
+/**
+ * bn_BD: Bengali (Bangladesh)/bengali_akkhor
+ */
+@SmallTest
+public final class TestsBengaliBD extends LayoutTestsBase {
+    private static final Locale LOCALE = new Locale("bn", "BD");
+    private static final LayoutBase LAYOUT = new BengaliAkkhor(new BengaliBDCustomzier(LOCALE));
+
+    @Override
+    LayoutBase getLayout() { return LAYOUT; }
+
+    private static class BengaliBDCustomzier extends BengaliCustomizer {
+        public BengaliBDCustomzier(final Locale locale) { super(locale); }
+
+        @Override
+        public ExpectedKey[] getRightShiftKeys(final boolean isPhone) {
+            return isPhone ? EMPTY_KEYS : LayoutBase.EXCLAMATION_AND_QUESTION_MARKS;
+        }
+
+        @Override
+        public ExpectedKey getCurrencyKey() { return CURRENCY_RUPEE; }
+
+        // U+09F3: "৳" BENGALI RUPEE SIGN
+        private static final ExpectedKey CURRENCY_RUPEE = key("\u09F3",
+                Symbols.CURRENCY_GENERIC_MORE_KEYS);
+    }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBengaliIN.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBengaliIN.java
index d642632..91a976c 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBengaliIN.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBengaliIN.java
@@ -19,7 +19,6 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.keyboard.layout.Bengali;
-import com.android.inputmethod.keyboard.layout.Bengali.BengaliCustomizer;
 import com.android.inputmethod.keyboard.layout.LayoutBase;
 import com.android.inputmethod.keyboard.layout.Symbols;
 import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
@@ -41,6 +40,9 @@
         public BengaliINCustomzier(final Locale locale) { super(locale); }
 
         @Override
+        public ExpectedKey[] getLeftShiftKeys(final boolean isPhone) { return EMPTY_KEYS; }
+
+        @Override
         public ExpectedKey getCurrencyKey() { return CURRENCY_RUPEE; }
 
         // U+20B9: "₹" INDIAN RUPEE SIGN
diff --git a/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java b/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java
index 6e894de..30b0881 100644
--- a/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java
+++ b/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java
@@ -63,7 +63,7 @@
         final int typedLength = STRING_TO_TYPE.length();
         final int EXPECTED_SUGGESTION_SPAN_START = -1;
         final int EXPECTED_UNDERLINE_SPAN_START = 0;
-        final int EXPECTED_UNDERLINE_SPAN_END = 4;
+        final int EXPECTED_UNDERLINE_SPAN_END = 3;
         type(STRING_TO_TYPE);
         sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
         runMessages();
diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTests.java b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
index 59b858d..ec249da 100644
--- a/tests/src/com/android/inputmethod/latin/InputLogicTests.java
+++ b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
@@ -159,8 +159,11 @@
     }
 
     public void testAutoCorrectWithSpaceThenRevert() {
+        // Backspacing to cancel the "tgis"->"this" autocorrection should result in
+        // a "phantom space": if the user presses space immediately after,
+        // only one space will be inserted in total.
         final String STRING_TO_TYPE = "tgis ";
-        final String EXPECTED_RESULT = "tgis ";
+        final String EXPECTED_RESULT = "tgis";
         type(STRING_TO_TYPE);
         mLatinIME.onUpdateSelection(0, 0, STRING_TO_TYPE.length(), STRING_TO_TYPE.length(), -1, -1);
         type(Constants.CODE_DELETE);
@@ -168,6 +171,24 @@
                 mEditText.getText().toString());
     }
 
+    public void testAutoCorrectWithSpaceThenRevertThenTypeMore() {
+        final String STRING_TO_TYPE_FIRST = "tgis ";
+        final String STRING_TO_TYPE_SECOND = "a";
+        final String EXPECTED_RESULT = "tgis a";
+        type(STRING_TO_TYPE_FIRST);
+        mLatinIME.onUpdateSelection(0, 0,
+                STRING_TO_TYPE_FIRST.length(), STRING_TO_TYPE_FIRST.length(), -1, -1);
+        type(Constants.CODE_DELETE);
+
+        type(STRING_TO_TYPE_SECOND);
+        mLatinIME.onUpdateSelection(STRING_TO_TYPE_FIRST.length(), STRING_TO_TYPE_FIRST.length(),
+                STRING_TO_TYPE_FIRST.length() - 1 + STRING_TO_TYPE_SECOND.length(),
+                STRING_TO_TYPE_FIRST.length() - 1 + STRING_TO_TYPE_SECOND.length(),
+                -1, -1);
+        assertEquals("auto-correct with space then revert then type more", EXPECTED_RESULT,
+                mEditText.getText().toString());
+    }
+
     public void testAutoCorrectToSelfDoesNotRevert() {
         final String STRING_TO_TYPE = "this ";
         final String EXPECTED_RESULT = "this";
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
index 2b3fd89..12290e6 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
@@ -27,6 +27,8 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map.Entry;
 
 /**
  * Encodes binary files for a FusionDictionary.
@@ -791,10 +793,12 @@
      * @param destination the stream to write the file header to.
      * @param dict the dictionary to write.
      * @param formatOptions file format options.
+     * @param codePointOccurrenceArray code points ordered by occurrence count.
      * @return the size of the header.
      */
     /* package */ static int writeDictionaryHeader(final OutputStream destination,
-            final FusionDictionary dict, final FormatOptions formatOptions)
+            final FusionDictionary dict, final FormatOptions formatOptions,
+            final ArrayList<Entry<Integer, Integer>> codePointOccurrenceArray)
                     throws IOException, UnsupportedFormatException {
         final int version = formatOptions.mVersion;
         if (version < FormatSpec.MINIMUM_SUPPORTED_VERSION
@@ -833,6 +837,9 @@
             CharEncoding.writeString(headerBuffer, key);
             CharEncoding.writeString(headerBuffer, value);
         }
+
+        // TODO: Write out the code point table.
+
         final int size = headerBuffer.size();
         final byte[] bytes = headerBuffer.toByteArray();
         // Write out the header size.
@@ -845,4 +852,15 @@
         headerBuffer.close();
         return size;
     }
+
+    static final class CodePointTable {
+        final HashMap<Integer, Integer> mCodePointToOneByteCodeMap;
+        final ArrayList<Entry<Integer, Integer>> mCodePointOccurrenceArray;
+
+        CodePointTable(final HashMap<Integer, Integer> codePointToOneByteCodeMap,
+                final ArrayList<Entry<Integer, Integer>> codePointOccurrenceArray) {
+            mCodePointToOneByteCodeMap = codePointToOneByteCodeMap;
+            mCodePointOccurrenceArray = codePointOccurrenceArray;
+        }
+    }
 }
diff --git a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java
index 0fa75e8..c471901 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java
@@ -18,6 +18,7 @@
 
 import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding;
+import com.android.inputmethod.latin.makedict.BinaryDictEncoderUtils.CodePointTable;
 import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
 import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
 import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
@@ -28,7 +29,11 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Map.Entry;
 
 /**
  * An implementation of DictEncoder for version 2 binary dictionary.
@@ -73,6 +78,49 @@
         }
     }
 
+    // Package for testing
+    static CodePointTable makeCodePointTable(final FusionDictionary dict) {
+        final HashMap<Integer, Integer> codePointOccurrenceCounts = new HashMap<>();
+        for (final WordProperty word : dict) {
+            // Store per code point occurrence
+            final String wordString = word.mWord;
+            for (int i = 0; i < wordString.length(); ++i) {
+                final int codePoint = Character.codePointAt(wordString, i);
+                if (codePointOccurrenceCounts.containsKey(codePoint)) {
+                    codePointOccurrenceCounts.put(codePoint,
+                            codePointOccurrenceCounts.get(codePoint) + 1);
+                } else {
+                    codePointOccurrenceCounts.put(codePoint, 1);
+                }
+            }
+        }
+        final ArrayList<Entry<Integer, Integer>> codePointOccurrenceArray =
+                new ArrayList<>(codePointOccurrenceCounts.entrySet());
+        // Descending order sort by occurrence (value side)
+        Collections.sort(codePointOccurrenceArray, new Comparator<Entry<Integer, Integer>>() {
+            @Override
+            public int compare(final Entry<Integer, Integer> a, final Entry<Integer, Integer> b) {
+                if (a.getValue() != b.getValue()) {
+                    return b.getValue().compareTo(a.getValue());
+                }
+                return b.getKey().compareTo(a.getKey());
+            }
+        });
+        int currentCodePointTableIndex = FormatSpec.MINIMAL_ONE_BYTE_CHARACTER_VALUE;
+        // Temporary map for writing of nodes
+        final HashMap<Integer, Integer> codePointToOneByteCodeMap = new HashMap<>();
+        for (final Entry<Integer, Integer> entry : codePointOccurrenceArray) {
+            // Put a relation from the original code point to the one byte code.
+            codePointToOneByteCodeMap.put(entry.getKey(), currentCodePointTableIndex);
+            if (FormatSpec.MAXIMAL_ONE_BYTE_CHARACTER_VALUE < ++currentCodePointTableIndex) {
+                break;
+            }
+        }
+        // codePointToOneByteCodeMap for writing the trie
+        // codePointOccurrenceArray for writing the header
+        return new CodePointTable(codePointToOneByteCodeMap, codePointOccurrenceArray);
+    }
+
     @Override
     public void writeDictionary(final FusionDictionary dict, final FormatOptions formatOptions)
             throws IOException, UnsupportedFormatException {
@@ -85,7 +133,12 @@
         if (mOutStream == null) {
             openStream();
         }
-        BinaryDictEncoderUtils.writeDictionaryHeader(mOutStream, dict, formatOptions);
+
+        // Make code point conversion table ordered by occurrence of code points
+        final CodePointTable codePointTable = makeCodePointTable(dict);
+
+        BinaryDictEncoderUtils.writeDictionaryHeader(mOutStream, dict, formatOptions,
+                codePointTable.mCodePointOccurrenceArray);
 
         // Addresses are limited to 3 bytes, but since addresses can be relative to each node
         // array, the structure itself is not limited to 16MB. However, if it is over 16MB deciding
diff --git a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoderTests.java b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoderTests.java
new file mode 100644
index 0000000..9104c2f
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoderTests.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.makedict;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map.Entry;
+
+import com.android.inputmethod.latin.makedict.BinaryDictEncoderUtils.CodePointTable;
+import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+
+/**
+ * Unit tests for Ver2DictEncoder
+ */
+@LargeTest
+public class Ver2DictEncoderTests extends AndroidTestCase {
+    private static final String TAG = Ver2DictEncoderTests.class.getSimpleName();
+    private static final int UNIGRAM_FREQ = 10;
+
+    public void testCodePointTable() {
+        final String[] wordSource = {"words", "used", "for", "testing", "a", "code point", "table"};
+        final List<String> words = Arrays.asList(wordSource);
+        final String correctCodePointTable = "eotdsanirfg bclwup";
+        final String correctCodePointOccurrenceArrayString =
+                "11641114101411531003114211021052972119111711121108110311021991981321";
+        final String correctCodePointExpectedMapString = "343332363540383937464549484744414243";
+        final String dictName = "codePointTableTest";
+        final String dictVersion = Long.toString(System.currentTimeMillis());
+
+        final FormatSpec.FormatOptions formatOptions =
+                new FormatSpec.FormatOptions(FormatSpec.VERSION2);
+        final FusionDictionary sourcedict = new FusionDictionary(new PtNodeArray(),
+                BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion, formatOptions));
+        addUnigrams(sourcedict, words, null /* shortcutMap */);
+        final CodePointTable codePointTable = Ver2DictEncoder.makeCodePointTable(sourcedict);
+
+        // Check if mCodePointOccurrenceArray is correct
+        final StringBuilder codePointOccurrenceArrayString = new StringBuilder();
+        for (Entry<Integer, Integer> entry : codePointTable.mCodePointOccurrenceArray) {
+            codePointOccurrenceArrayString.append(entry.getKey());
+            codePointOccurrenceArrayString.append(entry.getValue());
+        }
+        assertEquals(correctCodePointOccurrenceArrayString,
+                codePointOccurrenceArrayString.toString());
+
+        // Check if mCodePointToOneByteCodeMap is correct
+        final StringBuilder codePointExpectedMapString = new StringBuilder();
+        for (int i = 0; i < correctCodePointTable.length(); ++i) {
+            codePointExpectedMapString.append(codePointTable.mCodePointToOneByteCodeMap.get(
+                    correctCodePointTable.codePointAt(i)));
+        }
+        assertEquals(correctCodePointExpectedMapString, codePointExpectedMapString.toString());
+    }
+
+    /**
+     * Adds unigrams to the dictionary.
+     */
+    private void addUnigrams(final FusionDictionary dict, final List<String> words,
+            final HashMap<String, List<String>> shortcutMap) {
+        for (final String word : words) {
+            final ArrayList<WeightedString> shortcuts = new ArrayList<>();
+            if (shortcutMap != null && shortcutMap.containsKey(word)) {
+                for (final String shortcut : shortcutMap.get(word)) {
+                    shortcuts.add(new WeightedString(shortcut, UNIGRAM_FREQ));
+                }
+            }
+            dict.add(word, new ProbabilityInfo(UNIGRAM_FREQ),
+                    (shortcutMap == null) ? null : shortcuts, false /* isNotAWord */);
+        }
+    }
+}
diff --git a/tools/make-keyboard-text/res/values-bn-rBD/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-bn-rBD/donottranslate-more-keys.xml
new file mode 100644
index 0000000..4955cd4
--- /dev/null
+++ b/tools/make-keyboard-text/res/values-bn-rBD/donottranslate-more-keys.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Label for "switch to alphabetic" key.
+         U+0995: "क" BENGALI LETTER KA
+         U+0996: "ख" BENGALI LETTER KHA
+         U+0997: "ग" BENGALI LETTER GA -->
+    <string name="keylabel_to_alpha">&#x0995;&#x0996;&#x0997;</string>
+    <!-- U+09F3: "৳" BENGALI RUPEE SIGN -->
+    <string name="keyspec_currency">&#x09F3;</string>
+</resources>