Introduce KeyboardCodesSet.java and remove keycodes.xml

Change-Id: Icfd6d06f47425aa037682d22c895548ba6f047d8
diff --git a/java/res/values-ar/keycodes.xml b/java/res/values-ar/keycodes.xml
deleted file mode 100644
index 1f65a7c..0000000
--- a/java/res/values-ar/keycodes.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- U+0029: ")" RIGHT PARENTHESIS -->
-    <integer name="keycode_for_left_parenthesis">0x0029</integer>
-    <!-- U+0028: "(" LEFT PARENTHESIS -->
-    <integer name="keycode_for_right_parenthesis">0x0028</integer>
-    <!-- U+003E: ">" GREATER-THAN SIGN -->
-    <integer name="keycode_for_less_than">0x003E</integer>
-    <!-- U+003C: "<" LESS-THAN SIGN -->
-    <integer name="keycode_for_greater_than">0x003C</integer>
-    <!-- U+005D: "]" RIGHT SQUARE BRACKET -->
-    <integer name="keycode_for_left_square_bracket">0x005D</integer>
-    <!-- U+005B: "[" LEFT SQUARE BRACKET -->
-    <integer name="keycode_for_right_square_bracket">0x005B</integer>
-    <!-- U+007D: "}" RIGHT CURLY BRACKET -->
-    <integer name="keycode_for_left_curly_bracket">0x007D</integer>
-    <!-- U+007B: "{" LEFT CURLY BRACKET -->
-    <integer name="keycode_for_right_curly_bracket">0x007B</integer>
-</resources>
diff --git a/java/res/values-fa/keycodes.xml b/java/res/values-fa/keycodes.xml
deleted file mode 100644
index 1f65a7c..0000000
--- a/java/res/values-fa/keycodes.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- U+0029: ")" RIGHT PARENTHESIS -->
-    <integer name="keycode_for_left_parenthesis">0x0029</integer>
-    <!-- U+0028: "(" LEFT PARENTHESIS -->
-    <integer name="keycode_for_right_parenthesis">0x0028</integer>
-    <!-- U+003E: ">" GREATER-THAN SIGN -->
-    <integer name="keycode_for_less_than">0x003E</integer>
-    <!-- U+003C: "<" LESS-THAN SIGN -->
-    <integer name="keycode_for_greater_than">0x003C</integer>
-    <!-- U+005D: "]" RIGHT SQUARE BRACKET -->
-    <integer name="keycode_for_left_square_bracket">0x005D</integer>
-    <!-- U+005B: "[" LEFT SQUARE BRACKET -->
-    <integer name="keycode_for_right_square_bracket">0x005B</integer>
-    <!-- U+007D: "}" RIGHT CURLY BRACKET -->
-    <integer name="keycode_for_left_curly_bracket">0x007D</integer>
-    <!-- U+007B: "{" LEFT CURLY BRACKET -->
-    <integer name="keycode_for_right_curly_bracket">0x007B</integer>
-</resources>
diff --git a/java/res/values-iw/keycodes.xml b/java/res/values-iw/keycodes.xml
deleted file mode 100644
index 1f65a7c..0000000
--- a/java/res/values-iw/keycodes.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- U+0029: ")" RIGHT PARENTHESIS -->
-    <integer name="keycode_for_left_parenthesis">0x0029</integer>
-    <!-- U+0028: "(" LEFT PARENTHESIS -->
-    <integer name="keycode_for_right_parenthesis">0x0028</integer>
-    <!-- U+003E: ">" GREATER-THAN SIGN -->
-    <integer name="keycode_for_less_than">0x003E</integer>
-    <!-- U+003C: "<" LESS-THAN SIGN -->
-    <integer name="keycode_for_greater_than">0x003C</integer>
-    <!-- U+005D: "]" RIGHT SQUARE BRACKET -->
-    <integer name="keycode_for_left_square_bracket">0x005D</integer>
-    <!-- U+005B: "[" LEFT SQUARE BRACKET -->
-    <integer name="keycode_for_right_square_bracket">0x005B</integer>
-    <!-- U+007D: "}" RIGHT CURLY BRACKET -->
-    <integer name="keycode_for_left_curly_bracket">0x007D</integer>
-    <!-- U+007B: "{" LEFT CURLY BRACKET -->
-    <integer name="keycode_for_right_curly_bracket">0x007B</integer>
-</resources>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index 39d50e3..d574b9e 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -229,10 +229,14 @@
     </declare-styleable>
 
     <declare-styleable name="Keyboard_Key">
-        <!-- The unicode value that this key outputs. -->
-        <attr name="code" format="integer" />
-        <!-- The alternate unicode value that this key outputs while typing. -->
-        <attr name="altCode" format="integer" />
+        <!-- The unicode value that this key outputs.
+             Code value represented in hexadecimal prefixed with "0x" or code value reference using
+             "!code/<code_name>" notation. -->
+        <attr name="code" format="string" />
+        <!-- The alternate unicode value that this key outputs while typing.
+             Code value represented in hexadecimal prefixed with "0x" or code value reference using
+             "!code/<code_name>" notation. -->
+        <attr name="altCode" format="string" />
         <!-- The keys to display in the more keys keyboard. -->
         <attr name="moreKeys" format="string" />
         <!-- The keys to display in the more keys keyboard in addition to moreKeys.
diff --git a/java/res/values/donottranslate-more-keys.xml b/java/res/values/donottranslate-more-keys.xml
index f50dd4f..5e97edc 100644
--- a/java/res/values/donottranslate-more-keys.xml
+++ b/java/res/values/donottranslate-more-keys.xml
@@ -120,11 +120,11 @@
          U+2205: "∅" EMPTY SET -->
     <string name="more_keys_for_symbols_0">&#x207F;,&#x2205;</string>
     <string name="more_keys_for_am_pm">!fixedColumnOrder!2,!hasLabels!,\@string/label_time_am,\@string/label_time_pm</string>
-    <string name="settings_as_more_key">\@icon/settingsKey|\@integer/key_settings</string>
+    <string name="settings_as_more_key">\@icon/settingsKey|!code/key_settings</string>
     <string name="keylabel_for_comma">,</string>
     <string name="more_keys_for_comma"></string>
-    <string name="action_next_as_more_key">!hasLabels!,\@string/label_next_key|\@integer/key_action_next</string>
-    <string name="action_previous_as_more_key">!hasLabels!,\@string/label_previous_key|\@integer/key_action_previous</string>
+    <string name="action_next_as_more_key">!hasLabels!,\@string/label_next_key|!code/key_action_next</string>
+    <string name="action_previous_as_more_key">!hasLabels!,\@string/label_previous_key|!code/key_action_previous</string>
     <string name="keylabel_for_symbols_question">\?</string>
     <string name="keylabel_for_symbols_semicolon">;</string>
     <string name="keylabel_for_symbols_percent">%</string>
diff --git a/java/res/values/keycodes.xml b/java/res/values/keycodes.xml
deleted file mode 100644
index f42495a..0000000
--- a/java/res/values/keycodes.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* 
-**
-** Copyright 2009, 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>
-    <!-- These code should be aligned with Keyboard.CODE_*. -->
-    <integer name="key_tab">9</integer>
-    <integer name="key_enter">10</integer>
-    <integer name="key_space">32</integer>
-    <integer name="key_shift">-1</integer>
-    <integer name="key_switch_alpha_symbol">-2</integer>
-    <integer name="key_output_text">-3</integer>
-    <integer name="key_delete">-4</integer>
-    <integer name="key_settings">-5</integer>
-    <integer name="key_shortcut">-6</integer>
-    <integer name="key_action_enter">-7</integer>
-    <integer name="key_action_next">-8</integer>
-    <integer name="key_action_previous">-9</integer>
-    <integer name="key_language_switch">-10</integer>
-    <integer name="key_unspecified">-11</integer>
-    <!-- U+0028: "(" LEFT PARENTHESIS -->
-    <integer name="keycode_for_left_parenthesis">0x0028</integer>
-    <!-- U+0029: ")" RIGHT PARENTHESIS -->
-    <integer name="keycode_for_right_parenthesis">0x0029</integer>
-    <!-- U+003C: "<" LESS-THAN SIGN -->
-    <integer name="keycode_for_less_than">0x003C</integer>
-    <!-- U+003E: ">" GREATER-THAN SIGN -->
-    <integer name="keycode_for_greater_than">0x003E</integer>
-    <!-- U+005B: "[" LEFT SQUARE BRACKET -->
-    <integer name="keycode_for_left_square_bracket">0x005B</integer>
-    <!-- U+005D: "]" RIGHT SQUARE BRACKET -->
-    <integer name="keycode_for_right_square_bracket">0x005D</integer>
-    <!-- U+007B: "{" LEFT CURLY BRACKET -->
-    <integer name="keycode_for_left_curly_bracket">0x007B</integer>
-    <!-- U+007D: "}" RIGHT CURLY BRACKET -->
-    <integer name="keycode_for_right_curly_bracket">0x007D</integer>
-</resources>
diff --git a/java/res/xml-sw600dp/key_styles_common.xml b/java/res/xml-sw600dp/key_styles_common.xml
index 45e22fc..3cec9aa 100644
--- a/java/res/xml-sw600dp/key_styles_common.xml
+++ b/java/res/xml-sw600dp/key_styles_common.xml
@@ -42,7 +42,7 @@
         >
             <key-style
                 latin:styleName="shiftKeyStyle"
-                latin:code="@integer/key_shift"
+                latin:code="!code/key_shift"
                 latin:keyIcon="iconShiftKeyShifted"
                 latin:keyActionFlags="noKeyPreview"
                 latin:backgroundType="stickyOff" />
@@ -52,7 +52,7 @@
         >
             <key-style
                 latin:styleName="shiftKeyStyle"
-                latin:code="@integer/key_shift"
+                latin:code="!code/key_shift"
                 latin:keyIcon="iconShiftKeyShifted"
                 latin:keyActionFlags="noKeyPreview"
                 latin:backgroundType="stickyOn" />
@@ -60,7 +60,7 @@
         <default>
             <key-style
                 latin:styleName="shiftKeyStyle"
-                latin:code="@integer/key_shift"
+                latin:code="!code/key_shift"
                 latin:keyIcon="iconShiftKey"
                 latin:keyActionFlags="noKeyPreview"
                 latin:backgroundType="stickyOff" />
@@ -68,7 +68,7 @@
     </switch>
     <key-style
         latin:styleName="deleteKeyStyle"
-        latin:code="@integer/key_delete"
+        latin:code="!code/key_delete"
         latin:keyIcon="iconDeleteKey"
         latin:keyActionFlags="isRepeatable|noKeyPreview"
         latin:backgroundType="functional" />
@@ -76,7 +76,7 @@
         latin:keyboardLayout="@xml/key_styles_enter" />
     <key-style
         latin:styleName="spaceKeyStyle"
-        latin:code="@integer/key_space"
+        latin:code="!code/key_space"
         latin:keyActionFlags="noKeyPreview" />
     <!-- U+200C: ZERO WIDTH NON-JOINER
          U+200D: ZERO WIDTH JOINER -->
@@ -95,7 +95,7 @@
         latin:moreKeys="@string/more_keys_for_smiley" />
     <key-style
         latin:styleName="shortcutKeyStyle"
-        latin:code="@integer/key_shortcut"
+        latin:code="!code/key_shortcut"
         latin:keyIcon="iconShortcutKey"
         latin:keyIconDisabled="iconDisabledShortcutKey"
         latin:keyLabelFlags="preserveCase"
@@ -103,7 +103,7 @@
         latin:backgroundType="functional" />
     <key-style
         latin:styleName="settingsKeyStyle"
-        latin:code="@integer/key_settings"
+        latin:code="!code/key_settings"
         latin:keyIcon="iconSettingsKey"
         latin:keyActionFlags="noKeyPreview|altCodeWhileTyping"
         latin:backgroundType="functional" />
@@ -114,7 +114,7 @@
         >
             <key-style
                 latin:styleName="tabKeyStyle"
-                latin:code="@integer/key_action_previous"
+                latin:code="!code/key_action_previous"
                 latin:keyIcon="iconTabKey"
                 latin:keyIconPreview="iconPreviewTabKey"
                 latin:backgroundType="functional" />
@@ -122,7 +122,7 @@
         <default>
             <key-style
                 latin:styleName="tabKeyStyle"
-                latin:code="@integer/key_tab"
+                latin:code="!code/key_tab"
                 latin:keyIcon="iconTabKey"
                 latin:keyIconPreview="iconPreviewTabKey"
                 latin:backgroundType="functional" />
@@ -130,28 +130,28 @@
     </switch>
     <key-style
         latin:styleName="toSymbolKeyStyle"
-        latin:code="@integer/key_switch_alpha_symbol"
+        latin:code="!code/key_switch_alpha_symbol"
         latin:keyLabel="@string/label_to_symbol_key"
         latin:keyLabelFlags="preserveCase"
         latin:keyActionFlags="noKeyPreview"
         latin:backgroundType="functional" />
     <key-style
         latin:styleName="toAlphaKeyStyle"
-        latin:code="@integer/key_switch_alpha_symbol"
+        latin:code="!code/key_switch_alpha_symbol"
         latin:keyLabel="@string/label_to_alpha_key"
         latin:keyLabelFlags="preserveCase"
         latin:keyActionFlags="noKeyPreview"
         latin:backgroundType="functional" />
     <key-style
         latin:styleName="toMoreSymbolKeyStyle"
-        latin:code="@integer/key_shift"
+        latin:code="!code/key_shift"
         latin:keyLabel="@string/label_to_more_symbol_for_tablet_key"
         latin:keyLabelFlags="preserveCase"
         latin:keyActionFlags="noKeyPreview"
         latin:backgroundType="functional" />
     <key-style
         latin:styleName="backFromMoreSymbolKeyStyle"
-        latin:code="@integer/key_shift"
+        latin:code="!code/key_shift"
         latin:keyLabel="@string/label_to_symbol_key"
         latin:keyLabelFlags="preserveCase"
         latin:keyActionFlags="noKeyPreview"
diff --git a/java/res/xml-sw768dp/key_styles_common.xml b/java/res/xml-sw768dp/key_styles_common.xml
index e1c2369..c3ad195 100644
--- a/java/res/xml-sw768dp/key_styles_common.xml
+++ b/java/res/xml-sw768dp/key_styles_common.xml
@@ -41,7 +41,7 @@
         >
             <key-style
                 latin:styleName="shiftKeyStyle"
-                latin:code="@integer/key_shift"
+                latin:code="!code/key_shift"
                 latin:keyIcon="iconShiftKeyShifted"
                 latin:keyActionFlags="noKeyPreview"
                 latin:backgroundType="stickyOff" />
@@ -51,7 +51,7 @@
         >
             <key-style
                 latin:styleName="shiftKeyStyle"
-                latin:code="@integer/key_shift"
+                latin:code="!code/key_shift"
                 latin:keyIcon="iconShiftKeyShifted"
                 latin:keyActionFlags="noKeyPreview"
                 latin:backgroundType="stickyOn" />
@@ -59,7 +59,7 @@
         <default>
             <key-style
                 latin:styleName="shiftKeyStyle"
-                latin:code="@integer/key_shift"
+                latin:code="!code/key_shift"
                 latin:keyIcon="iconShiftKey"
                 latin:keyActionFlags="noKeyPreview"
                 latin:backgroundType="stickyOff" />
@@ -67,7 +67,7 @@
     </switch>
     <key-style
         latin:styleName="deleteKeyStyle"
-        latin:code="@integer/key_delete"
+        latin:code="!code/key_delete"
         latin:keyIcon="iconDeleteKey"
         latin:keyActionFlags="isRepeatable|noKeyPreview"
         latin:backgroundType="functional" />
@@ -75,7 +75,7 @@
         latin:keyboardLayout="@xml/key_styles_enter" />
     <key-style
         latin:styleName="spaceKeyStyle"
-        latin:code="@integer/key_space"
+        latin:code="!code/key_space"
         latin:keyActionFlags="noKeyPreview" />
     <!-- U+200C: ZERO WIDTH NON-JOINER
          U+200D: ZERO WIDTH JOINER -->
@@ -94,7 +94,7 @@
         latin:moreKeys="@string/more_keys_for_smiley" />
     <key-style
         latin:styleName="shortcutKeyStyle"
-        latin:code="@integer/key_shortcut"
+        latin:code="!code/key_shortcut"
         latin:keyIcon="iconShortcutKey"
         latin:keyIconDisabled="iconDisabledShortcutKey"
         latin:keyLabelFlags="preserveCase"
@@ -102,7 +102,7 @@
         latin:backgroundType="functional" />
     <key-style
         latin:styleName="settingsKeyStyle"
-        latin:code="@integer/key_settings"
+        latin:code="!code/key_settings"
         latin:keyIcon="iconSettingsKey"
         latin:keyActionFlags="noKeyPreview|altCodeWhileTyping"
         latin:backgroundType="functional" />
@@ -113,7 +113,7 @@
         >
             <key-style
                 latin:styleName="tabKeyStyle"
-                latin:code="@integer/key_action_previous"
+                latin:code="!code/key_action_previous"
                 latin:keyLabel="@string/label_tab_key"
                 latin:keyLabelFlags="fontNormal|preserveCase"
                 latin:backgroundType="functional" />
@@ -121,7 +121,7 @@
         <default>
             <key-style
                 latin:styleName="tabKeyStyle"
-                latin:code="@integer/key_tab"
+                latin:code="!code/key_tab"
                 latin:keyLabel="@string/label_tab_key"
                 latin:keyLabelFlags="fontNormal|preserveCase"
                 latin:backgroundType="functional" />
@@ -129,28 +129,28 @@
     </switch>
     <key-style
         latin:styleName="toSymbolKeyStyle"
-        latin:code="@integer/key_switch_alpha_symbol"
+        latin:code="!code/key_switch_alpha_symbol"
         latin:keyLabel="@string/label_to_symbol_key"
         latin:keyLabelFlags="fontNormal|preserveCase"
         latin:keyActionFlags="noKeyPreview"
         latin:backgroundType="functional" />
     <key-style
         latin:styleName="toAlphaKeyStyle"
-        latin:code="@integer/key_switch_alpha_symbol"
+        latin:code="!code/key_switch_alpha_symbol"
         latin:keyLabel="@string/label_to_alpha_key"
         latin:keyLabelFlags="fontNormal|preserveCase"
         latin:keyActionFlags="noKeyPreview"
         latin:backgroundType="functional" />
     <key-style
         latin:styleName="toMoreSymbolKeyStyle"
-        latin:code="@integer/key_shift"
+        latin:code="!code/key_shift"
         latin:keyLabel="@string/label_to_more_symbol_for_tablet_key"
         latin:keyLabelFlags="fontNormal|preserveCase"
         latin:keyActionFlags="noKeyPreview"
         latin:backgroundType="functional" />
     <key-style
         latin:styleName="backFromMoreSymbolKeyStyle"
-        latin:code="@integer/key_shift"
+        latin:code="!code/key_shift"
         latin:keyLabel="@string/label_to_symbol_key"
         latin:keyLabelFlags="fontNormal|preserveCase"
         latin:keyActionFlags="noKeyPreview"
diff --git a/java/res/xml/key_styles_common.xml b/java/res/xml/key_styles_common.xml
index 8d01091..bd002fd 100644
--- a/java/res/xml/key_styles_common.xml
+++ b/java/res/xml/key_styles_common.xml
@@ -46,7 +46,7 @@
         >
             <key-style
                 latin:styleName="shiftKeyStyle"
-                latin:code="@integer/key_shift"
+                latin:code="!code/key_shift"
                 latin:keyIcon="iconShiftKeyShifted"
                 latin:keyActionFlags="noKeyPreview"
                 latin:backgroundType="stickyOff" />
@@ -56,7 +56,7 @@
         >
             <key-style
                 latin:styleName="shiftKeyStyle"
-                latin:code="@integer/key_shift"
+                latin:code="!code/key_shift"
                 latin:keyIcon="iconShiftKeyShifted"
                 latin:keyActionFlags="noKeyPreview"
                 latin:backgroundType="stickyOn" />
@@ -64,7 +64,7 @@
         <default>
             <key-style
                 latin:styleName="shiftKeyStyle"
-                latin:code="@integer/key_shift"
+                latin:code="!code/key_shift"
                 latin:keyIcon="iconShiftKey"
                 latin:keyActionFlags="noKeyPreview"
                 latin:backgroundType="stickyOff" />
@@ -72,7 +72,7 @@
     </switch>
     <key-style
         latin:styleName="deleteKeyStyle"
-        latin:code="@integer/key_delete"
+        latin:code="!code/key_delete"
         latin:keyIcon="iconDeleteKey"
         latin:keyActionFlags="isRepeatable|noKeyPreview"
         latin:backgroundType="functional" />
@@ -104,7 +104,7 @@
     </switch>
     <key-style
         latin:styleName="spaceKeyStyle"
-        latin:code="@integer/key_space"
+        latin:code="!code/key_space"
         latin:keyActionFlags="noKeyPreview|enableLongPress"
         latin:backgroundType="functional" />
     <!-- U+200C: ZERO WIDTH NON-JOINER
@@ -119,23 +119,23 @@
         latin:backgroundType="functional" />
     <key-style
         latin:styleName="shortcutKeyStyle"
-        latin:code="@integer/key_shortcut"
+        latin:code="!code/key_shortcut"
         latin:keyIcon="iconShortcutKey"
         latin:keyIconDisabled="iconDisabledShortcutKey"
         latin:keyLabelFlags="preserveCase"
         latin:keyActionFlags="noKeyPreview|altCodeWhileTyping"
-        latin:altCode="@integer/key_space"
+        latin:altCode="!code/key_space"
         latin:parentStyle="f1MoreKeysStyle" />
     <key-style
         latin:styleName="languageSwitchKeyStyle"
-        latin:code="@integer/key_language_switch"
+        latin:code="!code/key_language_switch"
         latin:keyIcon="iconLanguageSwitchKey"
         latin:keyActionFlags="noKeyPreview|altCodeWhileTyping|enableLongPress"
-        latin:altCode="@integer/key_space"
+        latin:altCode="!code/key_space"
         latin:backgroundType="functional" />
     <key-style
         latin:styleName="tabKeyStyle"
-        latin:code="@integer/key_tab"
+        latin:code="!code/key_tab"
         latin:keyIcon="iconTabKey"
         latin:keyIconPreview="iconPreviewTabKey"
         latin:backgroundType="functional" />
@@ -143,7 +143,7 @@
          laid out as normal letter key. -->
     <key-style
         latin:styleName="nonSpecialBackgroundTabKeyStyle"
-        latin:code="@integer/key_tab"
+        latin:code="!code/key_tab"
         latin:keyIcon="iconTabKey"
         latin:keyIconPreview="iconPreviewTabKey" />
     <switch>
@@ -156,7 +156,7 @@
         >
             <key-style
                 latin:styleName="toSymbolKeyStyle"
-                latin:code="@integer/key_switch_alpha_symbol"
+                latin:code="!code/key_switch_alpha_symbol"
                 latin:keyIcon="iconShortcutForLabel"
                 latin:keyLabel="@string/label_to_symbol_with_microphone_key"
                 latin:keyLabelFlags="withIconRight|preserveCase"
@@ -166,7 +166,7 @@
         <default>
             <key-style
                 latin:styleName="toSymbolKeyStyle"
-                latin:code="@integer/key_switch_alpha_symbol"
+                latin:code="!code/key_switch_alpha_symbol"
                 latin:keyLabel="@string/label_to_symbol_key"
                 latin:keyLabelFlags="preserveCase"
                 latin:keyActionFlags="noKeyPreview"
@@ -175,21 +175,21 @@
     </switch>
     <key-style
         latin:styleName="toAlphaKeyStyle"
-        latin:code="@integer/key_switch_alpha_symbol"
+        latin:code="!code/key_switch_alpha_symbol"
         latin:keyLabel="@string/label_to_alpha_key"
         latin:keyLabelFlags="preserveCase"
         latin:keyActionFlags="noKeyPreview"
         latin:backgroundType="functional" />
     <key-style
         latin:styleName="toMoreSymbolKeyStyle"
-        latin:code="@integer/key_shift"
+        latin:code="!code/key_shift"
         latin:keyLabel="@string/label_to_more_symbol_key"
         latin:keyLabelFlags="preserveCase"
         latin:keyActionFlags="noKeyPreview"
         latin:backgroundType="functional" />
     <key-style
         latin:styleName="backFromMoreSymbolKeyStyle"
-        latin:code="@integer/key_shift"
+        latin:code="!code/key_shift"
         latin:keyLabel="@string/label_to_symbol_key"
         latin:keyLabelFlags="preserveCase"
         latin:keyActionFlags="noKeyPreview"
diff --git a/java/res/xml/key_styles_enter.xml b/java/res/xml/key_styles_enter.xml
index e15a0be..49759c4 100644
--- a/java/res/xml/key_styles_enter.xml
+++ b/java/res/xml/key_styles_enter.xml
@@ -92,7 +92,7 @@
     <!-- Enter key style -->
     <key-style
         latin:styleName="defaultEnterKeyStyle"
-        latin:code="@integer/key_enter"
+        latin:code="!code/key_enter"
         latin:keyIcon="iconReturnKey"
         latin:keyLabelFlags="autoXScale|preserveCase"
         latin:keyActionFlags="noKeyPreview"
@@ -100,7 +100,7 @@
         latin:parentStyle="navigateMoreKeysStyle" />
     <key-style
         latin:styleName="defaultActionKeyStyle"
-        latin:code="@integer/key_action_enter"
+        latin:code="!code/key_action_enter"
         latin:keyIcon="iconUndefined"
         latin:backgroundType="action"
         latin:parentStyle="defaultEnterKeyStyle" />
diff --git a/java/res/xml/key_styles_number.xml b/java/res/xml/key_styles_number.xml
index 1fc2169..e1c5e5b 100644
--- a/java/res/xml/key_styles_number.xml
+++ b/java/res/xml/key_styles_number.xml
@@ -99,12 +99,12 @@
     <!-- Only for non-tablet device -->
     <key-style
         latin:styleName="numPhoneToSymbolKeyStyle"
-        latin:code="@integer/key_switch_alpha_symbol"
+        latin:code="!code/key_switch_alpha_symbol"
         latin:keyLabel="@string/label_to_phone_symbols_key"
         latin:parentStyle="numModeKeyStyle" />
     <key-style
         latin:styleName="numPhoneToNumericKeyStyle"
-        latin:code="@integer/key_switch_alpha_symbol"
+        latin:code="!code/key_switch_alpha_symbol"
         latin:keyLabel="@string/label_to_phone_numeric_key"
         latin:parentStyle="numModeKeyStyle" />
     <!-- U+002C: "," COMMA -->
@@ -127,7 +127,7 @@
         latin:parentStyle="tabKeyStyle" />
     <key-style
         latin:styleName="numSpaceKeyStyle"
-        latin:code="@integer/key_space"
+        latin:code="!code/key_space"
         latin:keyIcon="iconSpaceKeyForNumberLayout"
         latin:keyActionFlags="enableLongPress"
         latin:parentStyle="numKeyBaseStyle" />
diff --git a/java/res/xml/keys_curly_brackets.xml b/java/res/xml/keys_curly_brackets.xml
index d21a092..6a4b1a9 100644
--- a/java/res/xml/keys_curly_brackets.xml
+++ b/java/res/xml/keys_curly_brackets.xml
@@ -23,8 +23,8 @@
 >
     <Key
         latin:keyLabel="{"
-        latin:code="@integer/keycode_for_left_curly_bracket" />
+        latin:code="!code/key_left_curly_bracket" />
     <Key
         latin:keyLabel="}"
-        latin:code="@integer/keycode_for_right_curly_bracket" />
+        latin:code="!code/key_right_curly_bracket" />
 </merge>
diff --git a/java/res/xml/keys_less_greater.xml b/java/res/xml/keys_less_greater.xml
index 8961d9c..831f2dd 100644
--- a/java/res/xml/keys_less_greater.xml
+++ b/java/res/xml/keys_less_greater.xml
@@ -23,10 +23,10 @@
 >
     <Key
         latin:keyLabel="&lt;"
-        latin:code="@integer/keycode_for_less_than"
+        latin:code="!code/key_less_than"
         latin:moreKeys="@string/more_keys_for_less_than" />
     <Key
         latin:keyLabel="&gt;"
-        latin:code="@integer/keycode_for_greater_than"
+        latin:code="!code/key_greater_than"
         latin:moreKeys="@string/more_keys_for_greater_than" />
 </merge>
diff --git a/java/res/xml/keys_parentheses.xml b/java/res/xml/keys_parentheses.xml
index 6853bf1..502a84e 100644
--- a/java/res/xml/keys_parentheses.xml
+++ b/java/res/xml/keys_parentheses.xml
@@ -23,10 +23,10 @@
 >
     <Key
         latin:keyLabel="("
-        latin:code="@integer/keycode_for_left_parenthesis"
+        latin:code="!code/key_left_parenthesis"
         latin:moreKeys="@string/more_keys_for_left_parenthesis" />
     <Key
         latin:keyLabel=")"
-        latin:code="@integer/keycode_for_right_parenthesis"
+        latin:code="!code/key_right_parenthesis"
         latin:moreKeys="@string/more_keys_for_right_parenthesis" />
 </merge>
diff --git a/java/res/xml/keys_square_brackets.xml b/java/res/xml/keys_square_brackets.xml
index 44387c3..5c128fd 100644
--- a/java/res/xml/keys_square_brackets.xml
+++ b/java/res/xml/keys_square_brackets.xml
@@ -23,8 +23,8 @@
 >
     <Key
         latin:keyLabel="["
-        latin:code="@integer/keycode_for_left_square_bracket" />
+        latin:code="!code/key_left_square_bracket" />
     <Key
         latin:keyLabel="]"
-        latin:code="@integer/keycode_for_right_square_bracket" />
+        latin:code="!code/key_right_square_bracket" />
 </merge>
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 0a2b010..fbb13c2 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -26,6 +26,7 @@
 import android.util.Xml;
 
 import com.android.inputmethod.keyboard.internal.KeySpecParser;
+import com.android.inputmethod.keyboard.internal.KeySpecParser.MoreKeySpec;
 import com.android.inputmethod.keyboard.internal.KeyStyles;
 import com.android.inputmethod.keyboard.internal.KeyStyles.KeyStyle;
 import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
@@ -104,7 +105,7 @@
     /** Text to output when pressed. This can be multiple characters, like ".com" */
     public final CharSequence mOutputText;
     /** More keys */
-    public final String[] mMoreKeys;
+    public final MoreKeySpec[] mMoreKeys;
     /** More keys column number and flags */
     private final int mMoreKeysColumnAndFlags;
     private static final int MORE_KEYS_COLUMN_MASK = 0x000000ff;
@@ -140,15 +141,12 @@
     private boolean mEnabled = true;
 
     /**
-     * This constructor is being used only for key in more keys keyboard.
+     * This constructor is being used only for keys in more keys keyboard.
      */
-    public Key(Resources res, Keyboard.Params params, String moreKeySpec,
-            int x, int y, int width, int height, int labelFlags) {
-        this(params, KeySpecParser.getLabel(moreKeySpec), null,
-                KeySpecParser.getIconId(moreKeySpec),
-                KeySpecParser.getCode(res, moreKeySpec),
-                KeySpecParser.getOutputText(moreKeySpec),
-                x, y, width, height, labelFlags);
+    public Key(Keyboard.Params params, MoreKeySpec moreKeySpec, int x, int y, int width, int height,
+            int labelFlags) {
+        this(params, moreKeySpec.mLabel, null, moreKeySpec.mIconId, moreKeySpec.mCode,
+                moreKeySpec.mOutputText, x, y, width, height, labelFlags);
     }
 
     /**
@@ -278,13 +276,15 @@
         moreKeys = KeySpecParser.insertAddtionalMoreKeys(moreKeys, additionalMoreKeys);
         if (moreKeys != null) {
             actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS;
+            mMoreKeys = new MoreKeySpec[moreKeys.length];
             for (int i = 0; i < moreKeys.length; i++) {
-                moreKeys[i] = adjustCaseOfStringForKeyboardId(
-                        moreKeys[i], preserveCase, params.mId);
+                mMoreKeys[i] = new MoreKeySpec(adjustCaseOfStringForKeyboardId(
+                        moreKeys[i], preserveCase, params.mId), params.mCodesSet);
             }
+        } else {
+            mMoreKeys = null;
         }
         mActionFlags = actionFlags;
-        mMoreKeys = moreKeys;
 
         if ((mLabelFlags & LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL) != 0) {
             mLabel = params.mId.mCustomActionLabel;
@@ -300,8 +300,9 @@
         }
         String outputText = adjustCaseOfStringForKeyboardId(style.getString(
                 keyAttr, R.styleable.Keyboard_Key_keyOutputText), preserveCase, params.mId);
-        final int code = style.getInt(
-                keyAttr, R.styleable.Keyboard_Key_code, Keyboard.CODE_UNSPECIFIED);
+        final int code = KeySpecParser.parseCode(style.getString(
+                keyAttr, R.styleable.Keyboard_Key_code),
+                params.mCodesSet, Keyboard.CODE_UNSPECIFIED);
         // Choose the first letter of the label as primary code if not specified.
         if (code == Keyboard.CODE_UNSPECIFIED && TextUtils.isEmpty(outputText)
                 && !TextUtils.isEmpty(mLabel)) {
@@ -331,9 +332,10 @@
             mCode = adjustCaseOfCodeForKeyboardId(code, preserveCase, params.mId);
         }
         mOutputText = outputText;
-        mAltCode = adjustCaseOfCodeForKeyboardId(style.getInt(keyAttr,
-                R.styleable.Keyboard_Key_altCode, Keyboard.CODE_UNSPECIFIED), preserveCase,
-                params.mId);
+        mAltCode = adjustCaseOfCodeForKeyboardId(KeySpecParser.parseCode(style.getString(
+                keyAttr, R.styleable.Keyboard_Key_altCode),
+                params.mCodesSet, Keyboard.CODE_UNSPECIFIED),
+                preserveCase, params.mId);
         mHashCode = computeHashCode(this);
 
         keyAttr.recycle();
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 950b5e9..4b9ff28 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -28,6 +28,7 @@
 import android.view.InflateException;
 
 import com.android.inputmethod.keyboard.internal.KeyStyles;
+import com.android.inputmethod.keyboard.internal.KeyboardCodesSet;
 import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
 import com.android.inputmethod.latin.LatinImeLogger;
 import com.android.inputmethod.latin.R;
@@ -238,6 +239,7 @@
         public final ArrayList<Key> mShiftKeys = new ArrayList<Key>();
         public final ArrayList<Key> mAltCodeKeysWhileTyping = new ArrayList<Key>();
         public final KeyboardIconsSet mIconsSet = new KeyboardIconsSet();
+        public final KeyboardCodesSet mCodesSet = new KeyboardCodesSet();
 
         public KeyboardLayoutSet.KeysCache mKeysCache;
 
@@ -775,6 +777,7 @@
 
                 params.mThemeId = keyboardAttr.getInt(R.styleable.Keyboard_themeId, 0);
                 params.mIconsSet.loadIcons(keyboardAttr);
+                params.mCodesSet.setLocale(params.mId.mLocale);
 
                 final int resourceId = keyboardAttr.getResourceId(
                         R.styleable.Keyboard_touchPositionCorrectionData, 0);
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index 98da1eb..5ebf92c 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -41,7 +41,6 @@
 import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
 import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy;
 import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
-import com.android.inputmethod.keyboard.internal.KeySpecParser;
 import com.android.inputmethod.latin.LatinIME;
 import com.android.inputmethod.latin.LatinImeLogger;
 import com.android.inputmethod.latin.R;
@@ -560,7 +559,7 @@
         }
         final int primaryCode = parentKey.mCode;
         if (parentKey.hasEmbeddedMoreKey()) {
-            final int embeddedCode = KeySpecParser.getCode(getResources(), parentKey.mMoreKeys[0]);
+            final int embeddedCode = parentKey.mMoreKeys[0].mCode;
             tracker.onLongPressed();
             invokeCodeInput(embeddedCode);
             invokeReleaseKey(primaryCode);
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
index 72a5d0f..f8682d8 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
@@ -19,7 +19,7 @@
 import android.graphics.Paint;
 import android.graphics.drawable.Drawable;
 
-import com.android.inputmethod.keyboard.internal.KeySpecParser;
+import com.android.inputmethod.keyboard.internal.KeySpecParser.MoreKeySpec;
 import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.StringUtils;
@@ -301,8 +301,8 @@
                     ? view.mKeyDrawParams.mKeyLabelSize
                     : view.mKeyDrawParams.mKeyLetterSize);
             int maxWidth = minKeyWidth;
-            for (String moreKeySpec : parentKey.mMoreKeys) {
-                final String label = KeySpecParser.getLabel(moreKeySpec);
+            for (final MoreKeySpec spec : parentKey.mMoreKeys) {
+                final String label = spec.mLabel;
                 // If the label is single letter, minKeyWidth is enough to hold the label.
                 if (label != null && StringUtils.codePointCount(label) > 1) {
                     final int width = (int)view.getLabelWidth(label, paint) + padding;
@@ -336,13 +336,13 @@
             // label's code point count.
             final int moreKeyFlags = mParentKey.hasLabelsInMoreKeys() ? 0
                     : Key.LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO;
-            final String[] moreKeys = mParentKey.mMoreKeys;
+            final MoreKeySpec[] moreKeys = mParentKey.mMoreKeys;
             for (int n = 0; n < moreKeys.length; n++) {
-                final String moreKeySpec = moreKeys[n];
+                final MoreKeySpec moreKeySpec = moreKeys[n];
                 final int row = n / params.mNumColumns;
                 final int x = params.getX(n, row);
                 final int y = params.getY(row);
-                final Key key = new Key(mResources, params, moreKeySpec, x, y,
+                final Key key = new Key(params, moreKeySpec, x, y,
                         params.mDefaultKeyWidth, params.mDefaultRowHeight, moreKeyFlags);
                 params.markAsEdgeKey(key, row);
                 params.onAddKey(key);
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
index 4abd887..84965bf 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
@@ -21,7 +21,6 @@
 
 import com.android.inputmethod.keyboard.Keyboard;
 import com.android.inputmethod.latin.LatinImeLogger;
-import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.StringUtils;
 
 import java.util.ArrayList;
@@ -35,7 +34,8 @@
  * Each "more key" specification is one of the following:
  * - A single letter (Letter)
  * - Label optionally followed by keyOutputText or code (keyLabel|keyOutputText).
- * - Icon followed by keyOutputText or code (@icon/icon_name|@integer/key_code)
+ * - Icon followed by keyOutputText or a string representation of codes
+ *   (@icon/icon_name|!code/key_code)
  * Special character, comma ',' backslash '\', and bar '|' can be escaped by '\' character.
  * Note that the character '@' and '\' are also parsed by XML parser and CSV parser as well.
  * See {@link KeyboardIconsSet} about icon_name.
@@ -53,9 +53,24 @@
     private static final String PREFIX_STRING = PREFIX_AT + "string" + SUFFIX_SLASH;
     private static final char LABEL_END = '|';
     private static final String PREFIX_ICON = PREFIX_AT + "icon" + SUFFIX_SLASH;
-    private static final String PREFIX_CODE = PREFIX_AT + "integer" + SUFFIX_SLASH;
+    private static final String PREFIX_CODE = "!code/";
+    private static final String PREFIX_HEX = "0x";
     private static final String ADDITIONAL_MORE_KEY_MARKER = "%";
 
+    public static class MoreKeySpec {
+        public final int mCode;
+        public final String mLabel;
+        public final String mOutputText;
+        public final int mIconId;
+
+        public MoreKeySpec(final String moreKeySpec, final KeyboardCodesSet codesSet) {
+            mCode = getCode(moreKeySpec, codesSet);
+            mLabel = getLabel(moreKeySpec);
+            mOutputText = getOutputText(moreKeySpec);
+            mIconId = getIconId(moreKeySpec);
+        }
+    }
+
     private KeySpecParser() {
         // Intentional empty constructor for utility class.
     }
@@ -144,7 +159,7 @@
         return parseEscape(moreKeySpec.substring(end + /* LABEL_END */1));
     }
 
-    public static String getOutputText(String moreKeySpec) {
+    private static String getOutputText(String moreKeySpec) {
         if (hasCode(moreKeySpec)) {
             return null;
         }
@@ -168,17 +183,13 @@
         return (StringUtils.codePointCount(label) == 1) ? null : label;
     }
 
-    public static int getCode(Resources res, String moreKeySpec) {
+    private static int getCode(String moreKeySpec, KeyboardCodesSet codesSet) {
         if (hasCode(moreKeySpec)) {
             final int end = indexOfLabelEnd(moreKeySpec, 0);
             if (indexOfLabelEnd(moreKeySpec, end + 1) >= 0) {
                 throw new KeySpecParserError("Multiple " + LABEL_END + ": " + moreKeySpec);
             }
-            final int resId = getResourceId(res,
-                    moreKeySpec.substring(end + /* LABEL_END */1 + /* PREFIX_AT */1),
-                    R.string.english_ime_name);
-            final int code = res.getInteger(resId);
-            return code;
+            return parseCode(moreKeySpec.substring(end + 1), codesSet, Keyboard.CODE_UNSPECIFIED);
         }
         final String outputText = getOutputTextInternal(moreKeySpec);
         if (outputText != null) {
@@ -197,7 +208,18 @@
         return Keyboard.CODE_OUTPUT_TEXT;
     }
 
-    public static int getIconId(String moreKeySpec) {
+    public static int parseCode(String text, KeyboardCodesSet codesSet, int defCode) {
+        if (text == null) return defCode;
+        if (text.startsWith(PREFIX_CODE)) {
+            return codesSet.getCode(text.substring(PREFIX_CODE.length()));
+        } else if (text.startsWith(PREFIX_HEX)) {
+            return Integer.parseInt(text.substring(PREFIX_HEX.length()), 16);
+        } else {
+            return Integer.parseInt(text);
+        }
+    }
+
+    private static int getIconId(String moreKeySpec) {
         if (hasIcon(moreKeySpec)) {
             final int end = moreKeySpec.indexOf(LABEL_END, PREFIX_ICON.length());
             final String name = moreKeySpec.substring(PREFIX_ICON.length(), end);
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
index 9e5c227..405b7ad 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
@@ -102,8 +102,8 @@
 
         void readKeyAttributes(TypedArray keyAttr) {
             // TODO: Currently not all Key attributes can be declared as style.
-            readInt(keyAttr, R.styleable.Keyboard_Key_code);
-            readInt(keyAttr, R.styleable.Keyboard_Key_altCode);
+            readString(keyAttr, R.styleable.Keyboard_Key_code);
+            readString(keyAttr, R.styleable.Keyboard_Key_altCode);
             readString(keyAttr, R.styleable.Keyboard_Key_keyLabel);
             readString(keyAttr, R.styleable.Keyboard_Key_keyOutputText);
             readString(keyAttr, R.styleable.Keyboard_Key_keyHintLabel);
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java
new file mode 100644
index 0000000..964c8ca
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.keyboard.internal;
+
+import com.android.inputmethod.keyboard.Keyboard;
+
+import java.util.HashMap;
+import java.util.Locale;
+
+public class KeyboardCodesSet {
+    private static final HashMap<Locale, int[]> sLocaleToCodesMap =
+            new HashMap<Locale, int[]>();
+    private static final HashMap<String, Integer> sNameToIdMap = new HashMap<String, Integer>();
+
+    private int[] mCodes = DEFAULT;
+
+    public void setLocale(final Locale locale) {
+        final int[] codes = sLocaleToCodesMap.get(locale);
+        mCodes = (codes != null) ? codes : DEFAULT;
+    }
+
+    public int getCode(final String name) {
+        final Integer id = sNameToIdMap.get(name);
+        if (id == null) throw new RuntimeException("Unknown key code: " + name);
+        return mCodes[id];
+    }
+
+    private static final String[] ID_TO_NAME = {
+        "key_tab",
+        "key_enter",
+        "key_space",
+        "key_shift",
+        "key_switch_alpha_symbol",
+        "key_output_text",
+        "key_delete",
+        "key_settings",
+        "key_shortcut",
+        "key_action_enter",
+        "key_action_next",
+        "key_action_previous",
+        "key_language_switch",
+        "key_unspecified",
+        "key_left_parenthesis",
+        "key_right_parenthesis",
+        "key_less_than",
+        "key_greater_than",
+        "key_left_square_bracket",
+        "key_right_square_bracket",
+        "key_left_curly_bracket",
+        "key_right_curly_bracket",
+    };
+
+    private static final int CODE_LEFT_PARENTHESIS = '(';
+    private static final int CODE_RIGHT_PARENTHESIS = ')';
+    private static final int CODE_LESS_THAN_SIGN = '<';
+    private static final int CODE_GREATER_THAN_SIGN = '>';
+    private static final int CODE_LEFT_SQUARE_BRACKET = '[';
+    private static final int CODE_RIGHT_SQUARE_BRACKET = ']';
+    private static final int CODE_LEFT_CURLY_BRACKET = '{';
+    private static final int CODE_RIGHT_CURLY_BRACKET = '}';
+
+    private static final int[] DEFAULT = {
+        Keyboard.CODE_TAB,
+        Keyboard.CODE_ENTER,
+        Keyboard.CODE_SPACE,
+        Keyboard.CODE_SHIFT,
+        Keyboard.CODE_SWITCH_ALPHA_SYMBOL,
+        Keyboard.CODE_OUTPUT_TEXT,
+        Keyboard.CODE_DELETE,
+        Keyboard.CODE_SETTINGS,
+        Keyboard.CODE_SHORTCUT,
+        Keyboard.CODE_ACTION_ENTER,
+        Keyboard.CODE_ACTION_NEXT,
+        Keyboard.CODE_LANGUAGE_SWITCH,
+        Keyboard.CODE_UNSPECIFIED,
+        CODE_LEFT_PARENTHESIS,
+        CODE_RIGHT_PARENTHESIS,
+        CODE_LESS_THAN_SIGN,
+        CODE_GREATER_THAN_SIGN,
+        CODE_LEFT_SQUARE_BRACKET,
+        CODE_RIGHT_SQUARE_BRACKET,
+        CODE_LEFT_CURLY_BRACKET,
+        CODE_RIGHT_CURLY_BRACKET,
+    };
+
+    private static final int[] RTL = {
+        DEFAULT[0],
+        DEFAULT[1],
+        DEFAULT[2],
+        DEFAULT[3],
+        DEFAULT[4],
+        DEFAULT[5],
+        DEFAULT[6],
+        DEFAULT[7],
+        DEFAULT[8],
+        DEFAULT[9],
+        DEFAULT[10],
+        DEFAULT[11],
+        DEFAULT[12],
+        CODE_RIGHT_PARENTHESIS,
+        CODE_LEFT_PARENTHESIS,
+        CODE_GREATER_THAN_SIGN,
+        CODE_LESS_THAN_SIGN,
+        CODE_RIGHT_SQUARE_BRACKET,
+        CODE_LEFT_SQUARE_BRACKET,
+        CODE_RIGHT_CURLY_BRACKET,
+        CODE_LEFT_CURLY_BRACKET,
+    };
+
+    private static final String LANGUAGE_DEFAULT = null;
+    private static final String LANGUAGE_ARABIC = "ar";
+    private static final String LANGUAGE_PERSIAN = "fa";
+    private static final String LANGUAGE_HEBREW = "iw";
+
+    private static final Object[] LOCALE_AND_CODES = {
+        LANGUAGE_DEFAULT, DEFAULT,
+        LANGUAGE_ARABIC, RTL,
+        LANGUAGE_PERSIAN, RTL,
+        LANGUAGE_HEBREW, RTL,
+    };
+
+    static {
+        for (int i = 0; i < ID_TO_NAME.length; i++) {
+            sNameToIdMap.put(ID_TO_NAME[i], i);
+        }
+
+        for (int i = 0; i < LOCALE_AND_CODES.length; i += 2) {
+            final String localeString = (String)LOCALE_AND_CODES[i];
+            final int[] codes = (int[])LOCALE_AND_CODES[i + 1];
+            final Locale locale = (localeString == LANGUAGE_DEFAULT)
+                    ? null : new Locale(localeString);
+            sLocaleToCodesMap.put(locale, codes);
+        }
+    }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java
index 3fc2b02..856bc10 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java
@@ -16,25 +16,25 @@
 
 package com.android.inputmethod.keyboard.internal;
 
-import android.content.res.Resources;
 import android.test.AndroidTestCase;
 
 import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.latin.R;
+import com.android.inputmethod.keyboard.internal.KeySpecParser.MoreKeySpec;
 
 import java.util.Arrays;
+import java.util.Locale;
 
 public class KeySpecParserTests extends AndroidTestCase {
-    private Resources mRes;
+    private final KeyboardCodesSet mCodesSet = new KeyboardCodesSet();
 
     private static final int ICON_UNDEFINED = KeyboardIconsSet.ICON_UNDEFINED;
 
-    private static final String CODE_SETTINGS_RES = "integer/key_settings";
+    private static final String CODE_SETTINGS_NAME = "key_settings";
     private static final String ICON_SETTINGS_NAME = "settingsKey";
 
-    private static final String CODE_SETTINGS = "@" + CODE_SETTINGS_RES;
+    private static final String CODE_SETTINGS = "!code/" + CODE_SETTINGS_NAME;
     private static final String ICON_SETTINGS = "@icon/" + ICON_SETTINGS_NAME;
-    private static final String CODE_NON_EXISTING = "@integer/non_existing";
+    private static final String CODE_NON_EXISTING = "!code/non_existing";
     private static final String ICON_NON_EXISTING = "@icon/non_existing";
 
     private int mCodeSettings;
@@ -42,28 +42,18 @@
 
     @Override
     protected void setUp() {
-        Resources res = getContext().getResources();
-        mRes = res;
-
-        final String packageName = res.getResourcePackageName(R.string.english_ime_name);
-        final int codeId = res.getIdentifier(CODE_SETTINGS_RES, null, packageName);
-        mCodeSettings = res.getInteger(codeId);
+        mCodesSet.setLocale(Locale.US);
+        mCodeSettings = mCodesSet.getCode(CODE_SETTINGS_NAME);
         mSettingsIconId = KeyboardIconsSet.getIconId(ICON_SETTINGS_NAME);
     }
 
     private void assertParser(String message, String moreKeySpec, String expectedLabel,
             String expectedOutputText, int expectedIcon, int expectedCode) {
-        String actualLabel = KeySpecParser.getLabel(moreKeySpec);
-        assertEquals(message + ": label:", expectedLabel, actualLabel);
-
-        String actualOutputText = KeySpecParser.getOutputText(moreKeySpec);
-        assertEquals(message + ": ouptputText:", expectedOutputText, actualOutputText);
-
-        int actualIcon = KeySpecParser.getIconId(moreKeySpec);
-        assertEquals(message + ": icon:", expectedIcon, actualIcon);
-
-        int actualCode = KeySpecParser.getCode(mRes, moreKeySpec);
-        assertEquals(message + ": codes value:", expectedCode, actualCode);
+        final MoreKeySpec spec = new MoreKeySpec(moreKeySpec, mCodesSet);
+        assertEquals(message + ": label:", expectedLabel, spec.mLabel);
+        assertEquals(message + ": ouptputText:", expectedOutputText, spec.mOutputText);
+        assertEquals(message + ": icon:", expectedIcon, spec.mIconId);
+        assertEquals(message + ": codes value:", expectedCode, spec.mCode);
     }
 
     private void assertParserError(String message, String moreKeySpec, String expectedLabel,