Merge "Binary bigram lookup checks both uppercase and lowercase when previous word is uppercase."
diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml
index 99b80d0..37f0736 100644
--- a/java/res/values/donottranslate.xml
+++ b/java/res/values/donottranslate.xml
@@ -153,6 +153,7 @@
         <item>qwertz</item>
         <item>azerty</item>
         <item>dvorak</item>
+        <item>colemak</item>
     </string-array>
     <!-- Predefined keyboard layout display names -->
     <string-array name="predefined_layout_display_names">
@@ -160,6 +161,7 @@
         <item>QWERTZ</item>
         <item>AZERTY</item>
         <item>Dvorak</item>
+        <item>Colemak</item>
     </string-array>
     <!-- Description for generic subtype that has predefined layout.
          The string resource name must be "subtype_generic_<layout name>". -->
@@ -167,6 +169,7 @@
     <string name="subtype_generic_qwertz">%s (QWERTZ)</string>
     <string name="subtype_generic_azerty">%s (AZERTY)</string>
     <string name="subtype_generic_dvorak">%s (Dvorak)</string>
+    <string name="subtype_generic_colemak">%s (Colemak)</string>
 
     <!-- dictionary pack package name /settings activity (for shared prefs and settings) -->
     <string name="dictionary_pack_package_name">com.google.android.inputmethod.latin.dictionarypack</string>
diff --git a/java/res/xml-sw600dp/key_colemak_semicolon.xml b/java/res/xml-sw600dp/key_colemak_semicolon.xml
new file mode 100644
index 0000000..a5a6e95
--- /dev/null
+++ b/java/res/xml-sw600dp/key_colemak_semicolon.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <Key
+        latin:keyLabel=":"
+        latin:keyHintLabel=";"
+        latin:moreKeys=";"
+        latin:keyStyle="hasShiftedLetterHintStyle" />
+</merge>
diff --git a/java/res/xml-sw600dp/row_hebrew4.xml b/java/res/xml-sw600dp/row_hebrew4.xml
new file mode 100644
index 0000000..e44d7d2
--- /dev/null
+++ b/java/res/xml-sw600dp/row_hebrew4.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <Row
+        latin:keyWidth="8.9%p"
+    >
+        <Key
+            latin:keyStyle="toSymbolKeyStyle"
+            latin:keyWidth="13.0%p" />
+        <Key
+            latin:keyStyle="tabKeyStyle" />
+        <include
+            latin:keyboardLayout="@xml/key_f1" />
+        <include
+            latin:keyboardLayout="@xml/key_space" />
+        <include
+            latin:keyboardLayout="@xml/keys_comma_period" />
+        <Spacer
+            latin:keyXPos="-10.00%p"
+            latin:keyWidth="0%p" />
+        <include
+            latin:keyboardLayout="@xml/key_shortcut" />
+    </Row>
+</merge>
diff --git a/java/res/xml-sw600dp/row_qwerty4.xml b/java/res/xml-sw600dp/row_qwerty4.xml
index 95b328b..58610ae 100644
--- a/java/res/xml-sw600dp/row_qwerty4.xml
+++ b/java/res/xml-sw600dp/row_qwerty4.xml
@@ -33,21 +33,10 @@
             latin:keyboardLayout="@xml/key_f1" />
         <include
             latin:keyboardLayout="@xml/key_space" />
-        <switch>
-            <case
-                latin:languageCode="iw"
-            >
-                <include
-                    latin:keyboardLayout="@xml/keys_comma_period" />
-            </case>
-            <!-- not languageCode="iw" -->
-            <default>
-                <include
-                    latin:keyboardLayout="@xml/key_apostrophe" />
-                <include
-                    latin:keyboardLayout="@xml/key_dash" />
-            </default>
-        </switch>
+        <include
+            latin:keyboardLayout="@xml/key_apostrophe" />
+        <include
+            latin:keyboardLayout="@xml/key_dash" />
         <Spacer
             latin:keyXPos="-10.00%p"
             latin:keyWidth="0%p" />
diff --git a/java/res/xml-sw600dp/rows_colemak.xml b/java/res/xml-sw600dp/rows_colemak.xml
new file mode 100644
index 0000000..6c88e65
--- /dev/null
+++ b/java/res/xml-sw600dp/rows_colemak.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <include
+        latin:keyboardLayout="@xml/key_styles_common" />
+    <Row
+        latin:keyWidth="8.5%p"
+    >
+        <include
+            latin:keyboardLayout="@xml/rowkeys_colemak1"
+            latin:keyLabelFlags="disableAdditionalMoreKeys|disableKeyHintLabel" />
+        <include
+            latin:keyboardLayout="@xml/key_colemak_semicolon" />
+        <Key
+            latin:keyStyle="deleteKeyStyle"
+            latin:keyWidth="fillBoth" />
+    </Row>
+    <Row
+        latin:keyWidth="8.5%p"
+    >
+        <include
+            latin:keyboardLayout="@xml/rowkeys_colemak2"
+            latin:keyXPos="4.5%p" />
+        <Key
+            latin:keyStyle="enterKeyStyle"
+            latin:keyWidth="fillBoth" />
+    </Row>
+    <Row
+        latin:keyWidth="8.5%p"
+    >
+        <Key
+            latin:keyStyle="shiftKeyStyle"
+            latin:keyWidth="10.0%p" />
+        <include
+            latin:keyboardLayout="@xml/rowkeys_colemak3" />
+        <include
+            latin:keyboardLayout="@xml/keys_comma_period" />
+        <include
+            latin:keyboardLayout="@xml/key_smiley"
+            latin:keyXPos="-8.5%p"
+            latin:keyWidth="fillRight" />
+    </Row>
+    <include
+        latin:keyboardLayout="@xml/row_qwerty4" />
+</merge>
diff --git a/java/res/xml-sw600dp/rows_hebrew.xml b/java/res/xml-sw600dp/rows_hebrew.xml
index d6861e8..521473f 100644
--- a/java/res/xml-sw600dp/rows_hebrew.xml
+++ b/java/res/xml-sw600dp/rows_hebrew.xml
@@ -58,5 +58,5 @@
             latin:keyWidth="fillRight" />
     </Row>
     <include
-        latin:keyboardLayout="@xml/row_qwerty4" />
+        latin:keyboardLayout="@xml/row_hebrew4" />
 </merge>
diff --git a/java/res/xml-sw768dp/key_shortcut.xml b/java/res/xml-sw768dp/key_shortcut.xml
new file mode 100644
index 0000000..1e367a9
--- /dev/null
+++ b/java/res/xml-sw768dp/key_shortcut.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <switch>
+        <case
+            latin:shortcutKeyEnabled="true"
+        >
+            <Key
+                latin:keyStyle="shortcutKeyStyle"
+                latin:keyXPos="-8.047%p"
+                latin:keyWidth="fillRight" />
+        </case>
+    </switch>
+</merge>
diff --git a/java/res/xml-sw768dp/row_dvorak4.xml b/java/res/xml-sw768dp/row_dvorak4.xml
index b98ce84..f95661f 100644
--- a/java/res/xml-sw768dp/row_dvorak4.xml
+++ b/java/res/xml-sw768dp/row_dvorak4.xml
@@ -37,15 +37,7 @@
             latin:keyboardLayout="@xml/key_question_exclamation" />
         <include
             latin:keyboardLayout="@xml/key_dash" />
-        <switch>
-            <case
-                latin:shortcutKeyEnabled="true"
-            >
-                <Key
-                    latin:keyStyle="shortcutKeyStyle"
-                    latin:keyXPos="-8.047%p"
-                    latin:keyWidth="fillRight" />
-            </case>
-        </switch>
+        <include
+            latin:keyboardLayout="@xml/key_shortcut" />
     </Row>
 </merge>
diff --git a/java/res/xml-sw768dp/row_hebrew4.xml b/java/res/xml-sw768dp/row_hebrew4.xml
new file mode 100644
index 0000000..e95d5fb
--- /dev/null
+++ b/java/res/xml-sw768dp/row_hebrew4.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <Row
+        latin:keyWidth="8.047%p"
+    >
+        <include
+            latin:keyboardLayout="@xml/key_settings" />
+        <Spacer
+            latin:keyXPos="15.157%p"
+            latin:keyWidth="0%p" />
+        <include
+            latin:keyboardLayout="@xml/keys_f1f2" />
+        <include
+            latin:keyboardLayout="@xml/key_space" />
+        <include
+            latin:keyboardLayout="@xml/keys_comma_period" />
+        <include
+            latin:keyboardLayout="@xml/key_shortcut" />
+    </Row>
+</merge>
diff --git a/java/res/xml-sw768dp/row_qwerty4.xml b/java/res/xml-sw768dp/row_qwerty4.xml
index f6ad3fd..b902d03 100644
--- a/java/res/xml-sw768dp/row_qwerty4.xml
+++ b/java/res/xml-sw768dp/row_qwerty4.xml
@@ -33,29 +33,11 @@
             latin:keyboardLayout="@xml/keys_f1f2" />
         <include
             latin:keyboardLayout="@xml/key_space" />
-        <switch>
-            <case
-                latin:languageCode="iw"
-            >
-                <include
-                    latin:keyboardLayout="@xml/keys_comma_period" />
-            </case>
-            <default>
-                <include
-                    latin:keyboardLayout="@xml/key_apostrophe" />
-                <include
-                    latin:keyboardLayout="@xml/key_dash" />
-            </default>
-        </switch>
-        <switch>
-            <case
-                latin:shortcutKeyEnabled="true"
-            >
-                <Key
-                    latin:keyStyle="shortcutKeyStyle"
-                    latin:keyXPos="-8.047%p"
-                    latin:keyWidth="fillRight" />
-            </case>
-        </switch>
+        <include
+            latin:keyboardLayout="@xml/key_apostrophe" />
+        <include
+            latin:keyboardLayout="@xml/key_dash" />
+        <include
+            latin:keyboardLayout="@xml/key_shortcut" />
     </Row>
 </merge>
diff --git a/java/res/xml-sw768dp/rows_colemak.xml b/java/res/xml-sw768dp/rows_colemak.xml
new file mode 100644
index 0000000..e004480
--- /dev/null
+++ b/java/res/xml-sw768dp/rows_colemak.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2010, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <include
+        latin:keyboardLayout="@xml/key_styles_common" />
+    <Row
+        latin:keyWidth="8.282%p"
+    >
+        <Key
+            latin:keyStyle="tabKeyStyle"
+            latin:keyLabelFlags="alignLeft"
+            latin:keyWidth="7.969%p" />
+        <include
+            latin:keyboardLayout="@xml/rowkeys_colemak1"
+            latin:keyLabelFlags="disableAdditionalMoreKeys|disableKeyHintLabel" />
+        <include
+            latin:keyboardLayout="@xml/key_colemak_semicolon" />
+        <Key
+            latin:keyStyle="deleteKeyStyle"
+            latin:keyWidth="fillBoth" />
+    </Row>
+    <Row
+        latin:keyWidth="8.125%p"
+    >
+        <Key
+            latin:keyStyle="toSymbolKeyStyle"
+            latin:keyLabelFlags="alignLeft"
+            latin:keyWidth="10.167%p" />
+        <include
+            latin:keyboardLayout="@xml/rowkeys_colemak2" />
+        <Key
+            latin:keyStyle="enterKeyStyle"
+            latin:keyWidth="fillBoth" />
+    </Row>
+    <Row
+        latin:keyWidth="8.047%p"
+    >
+        <Key
+            latin:keyStyle="shiftKeyStyle"
+            latin:keyWidth="13.829%p" />
+        <include
+            latin:keyboardLayout="@xml/rowkeys_colemak3" />
+        <include
+            latin:keyboardLayout="@xml/keys_comma_period" />
+        <Key
+            latin:keyStyle="shiftKeyStyle"
+            latin:keyWidth="fillBoth" />
+    </Row>
+    <include
+        latin:keyboardLayout="@xml/row_qwerty4" />
+</merge>
diff --git a/java/res/xml-sw768dp/rows_hebrew.xml b/java/res/xml-sw768dp/rows_hebrew.xml
index e70f450..beb59b4 100644
--- a/java/res/xml-sw768dp/rows_hebrew.xml
+++ b/java/res/xml-sw768dp/rows_hebrew.xml
@@ -61,5 +61,5 @@
             latin:keyXPos="13.829%p" />
     </Row>
     <include
-        latin:keyboardLayout="@xml/row_qwerty4" />
+        latin:keyboardLayout="@xml/row_hebrew4" />
 </merge>
diff --git a/java/res/xml/kbd_colemak.xml b/java/res/xml/kbd_colemak.xml
new file mode 100644
index 0000000..ee1d5e8
--- /dev/null
+++ b/java/res/xml/kbd_colemak.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <include
+        latin:keyboardLayout="@xml/rows_colemak" />
+</Keyboard>
diff --git a/java/res/xml/key_colemak_semicolon.xml b/java/res/xml/key_colemak_semicolon.xml
new file mode 100644
index 0000000..307b4eb
--- /dev/null
+++ b/java/res/xml/key_colemak_semicolon.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <switch>
+        <case
+            latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLockShifted"
+        >
+            <Key
+                latin:keyLabel=";"
+                latin:keyHintLabel="0"
+                latin:additionalMoreKeys="0" />
+        </case>
+        <default>
+            <Key
+                latin:keyLabel=":"
+                latin:keyHintLabel="0"
+                latin:additionalMoreKeys="0"
+                latin:moreKeys=";" />
+        </default>
+    </switch>
+</merge>
diff --git a/java/res/xml/keyboard_layout_set_colemak.xml b/java/res/xml/keyboard_layout_set_colemak.xml
new file mode 100644
index 0000000..c18f132
--- /dev/null
+++ b/java/res/xml/keyboard_layout_set_colemak.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<KeyboardLayoutSet
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin">
+    <Element
+        latin:elementName="alphabet"
+        latin:elementKeyboard="@xml/kbd_colemak"
+        latin:enableProximityCharsCorrection="true" />
+    <Element
+        latin:elementName="symbols"
+        latin:elementKeyboard="@xml/kbd_10_10_7_symbols" />
+    <Element
+        latin:elementName="symbolsShifted"
+        latin:elementKeyboard="@xml/kbd_10_10_7_symbols_shift" />
+    <Element
+        latin:elementName="phone"
+        latin:elementKeyboard="@xml/kbd_phone" />
+    <Element
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
+    <Element
+        latin:elementName="number"
+        latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardLayoutSet>
diff --git a/java/res/xml/rowkeys_colemak1.xml b/java/res/xml/rowkeys_colemak1.xml
new file mode 100644
index 0000000..f1c3075
--- /dev/null
+++ b/java/res/xml/rowkeys_colemak1.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <Key
+        latin:keyLabel="q"
+        latin:keyHintLabel="1"
+        latin:additionalMoreKeys="1" />
+    <Key
+        latin:keyLabel="w"
+        latin:keyHintLabel="2"
+        latin:additionalMoreKeys="2"
+        latin:moreKeys="!text/more_keys_for_w" />
+    <Key
+        latin:keyLabel="f"
+        latin:keyHintLabel="3"
+        latin:additionalMoreKeys="3" />
+    <Key
+        latin:keyLabel="p"
+        latin:keyHintLabel="4"
+        latin:additionalMoreKeys="4" />
+    <Key
+        latin:keyLabel="g"
+        latin:keyHintLabel="5"
+        latin:additionalMoreKeys="5"
+        latin:moreKeys="!text/more_keys_for_g" />
+    <Key
+        latin:keyLabel="j"
+        latin:keyHintLabel="6"
+        latin:additionalMoreKeys="6"
+        latin:moreKeys="!text/more_keys_for_j" />
+    <Key
+        latin:keyLabel="l"
+        latin:keyHintLabel="7"
+        latin:additionalMoreKeys="7"
+        latin:moreKeys="!text/more_keys_for_l" />
+    <Key
+        latin:keyLabel="u"
+        latin:keyHintLabel="8"
+        latin:additionalMoreKeys="8"
+        latin:moreKeys="!text/more_keys_for_u" />
+    <Key
+        latin:keyLabel="y"
+        latin:keyHintLabel="9"
+        latin:additionalMoreKeys="9"
+        latin:moreKeys="!text/more_keys_for_y" />
+</merge>
diff --git a/java/res/xml/rowkeys_colemak2.xml b/java/res/xml/rowkeys_colemak2.xml
new file mode 100644
index 0000000..f73d7e9
--- /dev/null
+++ b/java/res/xml/rowkeys_colemak2.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <Key
+        latin:keyLabel="a"
+        latin:moreKeys="!text/more_keys_for_a" />
+    <Key
+        latin:keyLabel="r"
+        latin:moreKeys="!text/more_keys_for_r" />
+    <Key
+        latin:keyLabel="s"
+        latin:moreKeys="!text/more_keys_for_s" />
+    <Key
+        latin:keyLabel="t"
+        latin:moreKeys="!text/more_keys_for_t" />
+    <Key
+        latin:keyLabel="d"
+        latin:moreKeys="!text/more_keys_for_d" />
+    <Key
+        latin:keyLabel="h"
+        latin:moreKeys="!text/more_keys_for_h" />
+    <Key
+        latin:keyLabel="n"
+        latin:moreKeys="!text/more_keys_for_n" />
+    <Key
+        latin:keyLabel="e"
+        latin:moreKeys="!text/more_keys_for_e" />
+    <Key
+        latin:keyLabel="i"
+        latin:moreKeys="!text/more_keys_for_i" />
+    <Key
+        latin:keyLabel="o"
+        latin:moreKeys="!text/more_keys_for_o" />
+</merge>
diff --git a/java/res/xml/rowkeys_colemak3.xml b/java/res/xml/rowkeys_colemak3.xml
new file mode 100644
index 0000000..f0f9151
--- /dev/null
+++ b/java/res/xml/rowkeys_colemak3.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <Key
+        latin:keyLabel="z"
+        latin:moreKeys="!text/more_keys_for_z" />
+    <Key
+        latin:keyLabel="x" />
+    <Key
+        latin:keyLabel="c"
+        latin:moreKeys="!text/more_keys_for_c" />
+    <Key
+        latin:keyLabel="v"
+        latin:moreKeys="!text/more_keys_for_v" />
+    <Key
+        latin:keyLabel="b" />
+    <Key
+        latin:keyLabel="k"
+        latin:moreKeys="!text/more_keys_for_k" />
+    <Key
+        latin:keyLabel="m" />
+</merge>
diff --git a/java/res/xml/rows_colemak.xml b/java/res/xml/rows_colemak.xml
new file mode 100644
index 0000000..a159965
--- /dev/null
+++ b/java/res/xml/rows_colemak.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <include
+        latin:keyboardLayout="@xml/key_styles_common" />
+    <Row
+        latin:keyWidth="10%p"
+    >
+        <include
+            latin:keyboardLayout="@xml/rowkeys_colemak1" />
+        <include
+            latin:keyboardLayout="@xml/key_colemak_semicolon" />
+    </Row>
+    <Row
+        latin:keyWidth="10%p"
+    >
+        <include
+            latin:keyboardLayout="@xml/rowkeys_colemak2" />
+    </Row>
+    <Row
+        latin:keyWidth="10%p"
+    >
+        <Key
+            latin:keyStyle="shiftKeyStyle"
+            latin:keyWidth="15%p"
+            latin:visualInsetsRight="1%p" />
+        <include
+            latin:keyboardLayout="@xml/rowkeys_colemak3" />
+        <Key
+            latin:keyStyle="deleteKeyStyle"
+            latin:keyWidth="fillRight"
+            latin:visualInsetsLeft="1%p" />
+    </Row>
+    <include
+        latin:keyboardLayout="@xml/row_qwerty4" />
+</merge>
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 38e6d5a..d5bd7fd 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -880,18 +880,19 @@
         final KeyPreviewDrawParams params = mKeyPreviewDrawParams;
         final int keyDrawX = key.mX + key.mVisualInsetsLeft;
         final int keyDrawWidth = key.mWidth - key.mVisualInsetsLeft - key.mVisualInsetsRight;
+        final String label = key.isShiftedLetterActivated() ? key.mHintLabel : key.mLabel;
         // What we show as preview should match what we show on a key top in onBufferDraw().
-        if (key.mLabel != null) {
+        if (label != null) {
             // TODO Should take care of temporaryShiftLabel here.
             previewText.setCompoundDrawables(null, null, null, null);
-            if (StringUtils.codePointCount(key.mLabel) > 1) {
+            if (StringUtils.codePointCount(label) > 1) {
                 previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, params.mKeyLetterSize);
                 previewText.setTypeface(Typeface.DEFAULT_BOLD);
             } else {
                 previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, params.mPreviewTextSize);
                 previewText.setTypeface(params.mKeyTextStyle);
             }
-            previewText.setText(key.mLabel);
+            previewText.setText(label);
         } else {
             previewText.setCompoundDrawables(null, null, null,
                     key.getPreviewIcon(mKeyboard.mIconsSet));
diff --git a/java/src/com/android/inputmethod/latin/AdditionalSubtypeSettings.java b/java/src/com/android/inputmethod/latin/AdditionalSubtypeSettings.java
index b67f327..613c203 100644
--- a/java/src/com/android/inputmethod/latin/AdditionalSubtypeSettings.java
+++ b/java/src/com/android/inputmethod/latin/AdditionalSubtypeSettings.java
@@ -109,18 +109,15 @@
     }
 
     static class KeyboardLayoutSetItem extends Pair<String, String> {
-        public KeyboardLayoutSetItem(String keyboardLayoutSetName) {
-            super(keyboardLayoutSetName, getDisplayName(keyboardLayoutSetName));
+        public KeyboardLayoutSetItem(InputMethodSubtype subtype) {
+            super(SubtypeLocale.getKeyboardLayoutSetName(subtype),
+                    SubtypeLocale.getKeyboardLayoutSetDisplayName(subtype));
         }
 
         @Override
         public String toString() {
             return second;
         }
-
-        private static String getDisplayName(String keyboardLayoutSetName) {
-            return keyboardLayoutSetName.toUpperCase();
-        }
     }
 
     static class KeyboardLayoutSetAdapter extends ArrayAdapter<KeyboardLayoutSetItem> {
@@ -130,7 +127,10 @@
 
             // TODO: Should filter out already existing combinations of locale and layout.
             for (final String layout : SubtypeLocale.getPredefinedKeyboardLayoutSet()) {
-                add(new KeyboardLayoutSetItem(layout));
+                // This is a dummy subtype with NO_LANGUAGE, only for display.
+                final InputMethodSubtype subtype = AdditionalSubtype.createAdditionalSubtype(
+                        SubtypeLocale.NO_LANGUAGE, layout, null);
+                add(new KeyboardLayoutSetItem(subtype));
             }
         }
     }
@@ -196,8 +196,7 @@
                         .setNegativeButton(R.string.remove, this);
                 final SubtypeLocaleItem localeItem = SubtypeLocaleAdapter.createItem(
                         context, mSubtype.getLocale());
-                final KeyboardLayoutSetItem layoutItem = new KeyboardLayoutSetItem(
-                        SubtypeLocale.getKeyboardLayoutSetName(mSubtype));
+                final KeyboardLayoutSetItem layoutItem = new KeyboardLayoutSetItem(mSubtype);
                 setSpinnerPosition(mSubtypeLocaleSpinner, localeItem);
                 setSpinnerPosition(mKeyboardLayoutSetSpinner, layoutItem);
             }
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
index 072dec9..5acd629 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
@@ -24,6 +24,7 @@
 
 import java.io.File;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.Locale;
 
 /**
@@ -46,6 +47,10 @@
      */
     private static final String COMMON_PREFERENCES_NAME = "LatinImeDictPrefs";
 
+    // Name of the category for the main dictionary
+    private static final String MAIN_DICTIONARY_CATEGORY = "main";
+    public static final String ID_CATEGORY_SEPARATOR = ":";
+
     // Prevents this from being instantiated
     private BinaryDictionaryGetter() {}
 
@@ -206,7 +211,40 @@
     }
 
     /**
-     * Returns the list of cached files for a specific locale.
+     * Returns the category for a given file name.
+     *
+     * This parses the file name, extracts the category, and returns it. See
+     * {@link #getMainDictId(Locale)} and {@link #isMainWordListId(String)}.
+     * @return The category as a string or null if it can't be found in the file name.
+     */
+    private static String getCategoryFromFileName(final String fileName) {
+        final String id = getWordListIdFromFileName(fileName);
+        final String[] idArray = id.split(ID_CATEGORY_SEPARATOR);
+        if (2 != idArray.length) return null;
+        return idArray[0];
+    }
+
+    /**
+     * Utility class for the {@link #getCachedWordLists} method
+     */
+    private static class FileAndMatchLevel {
+        final File mFile;
+        final int mMatchLevel;
+        public FileAndMatchLevel(final File file, final int matchLevel) {
+            mFile = file;
+            mMatchLevel = matchLevel;
+        }
+    }
+
+    /**
+     * Returns the list of cached files for a specific locale, one for each category.
+     *
+     * This will return exactly one file for each word list category that matches
+     * the passed locale. If several files match the locale for any given category,
+     * this returns the file with the closest match to the locale. For example, if
+     * the passed word list is en_US, and for a category we have an en and an en_US
+     * word list available, we'll return only the en_US one.
+     * Thus, the list will contain as many files as there are categories.
      *
      * @param locale the locale to find the dictionary files for, as a string.
      * @param context the context on which to open the files upon.
@@ -216,21 +254,32 @@
             final Context context) {
         final File[] directoryList = getCachedDirectoryList(context);
         if (null == directoryList) return EMPTY_FILE_ARRAY;
-        final ArrayList<File> cacheFiles = new ArrayList<File>();
+        final HashMap<String, FileAndMatchLevel> cacheFiles =
+                new HashMap<String, FileAndMatchLevel>();
         for (File directory : directoryList) {
             if (!directory.isDirectory()) continue;
             final String dirLocale = getWordListIdFromFileName(directory.getName());
-            if (LocaleUtils.isMatch(LocaleUtils.getMatchLevel(dirLocale, locale))) {
+            final int matchLevel = LocaleUtils.getMatchLevel(dirLocale, locale);
+            if (LocaleUtils.isMatch(matchLevel)) {
                 final File[] wordLists = directory.listFiles();
                 if (null != wordLists) {
                     for (File wordList : wordLists) {
-                        cacheFiles.add(wordList);
+                        final String category = getCategoryFromFileName(wordList.getName());
+                        final FileAndMatchLevel currentBestMatch = cacheFiles.get(category);
+                        if (null == currentBestMatch || currentBestMatch.mMatchLevel < matchLevel) {
+                            cacheFiles.put(category, new FileAndMatchLevel(wordList, matchLevel));
+                        }
                     }
                 }
             }
         }
         if (cacheFiles.isEmpty()) return EMPTY_FILE_ARRAY;
-        return cacheFiles.toArray(EMPTY_FILE_ARRAY);
+        final File[] result = new File[cacheFiles.size()];
+        int index = 0;
+        for (final FileAndMatchLevel entry : cacheFiles.values()) {
+            result[index++] = entry.mFile;
+        }
+        return result;
     }
 
     /**
@@ -245,7 +294,13 @@
         // This works because we don't include by default different dictionaries for
         // different countries. This actually needs to return the id that we would
         // like to use for word lists included in resources, and the following is okay.
-        return locale.getLanguage().toString();
+        return MAIN_DICTIONARY_CATEGORY + ID_CATEGORY_SEPARATOR + locale.getLanguage().toString();
+    }
+
+    private static boolean isMainWordListId(final String id) {
+        final String[] idArray = id.split(ID_CATEGORY_SEPARATOR);
+        if (2 != idArray.length) return false;
+        return MAIN_DICTIONARY_CATEGORY.equals(idArray[0]);
     }
 
     /**
@@ -270,9 +325,7 @@
         BinaryDictionaryFileDumper.cacheWordListsFromContentProvider(locale, context,
                 hasDefaultWordList);
         final File[] cachedWordLists = getCachedWordLists(locale.toString(), context);
-
         final String mainDictId = getMainDictId(locale);
-
         final DictPackSettings dictPackSettings = new DictPackSettings(context);
 
         boolean foundMainDict = false;
@@ -280,7 +333,7 @@
         // cachedWordLists may not be null, see doc for getCachedDictionaryList
         for (final File f : cachedWordLists) {
             final String wordListId = getWordListIdFromFileName(f.getName());
-            if (wordListId.equals(mainDictId)) {
+            if (isMainWordListId(wordListId)) {
                 foundMainDict = true;
             }
             if (!dictPackSettings.isWordListActive(wordListId)) continue;